diff --git a/Cargo.lock b/Cargo.lock index e20f5c2..82447c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,9 +166,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.2.7" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" dependencies = [ "clap_builder", "clap_derive", @@ -177,31 +177,30 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.7" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", ] [[package]] name = "clap_complete" -version = "4.2.3" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1594fe2312ec4abf402076e407628f5c313e54c32ade058521df4ee34ecac8a8" +checksum = "5fc443334c81a804575546c5a8a79b4913b50e28d69232903604cada1de817ce" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", @@ -211,9 +210,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "clicolors-control" diff --git a/Cargo.toml b/Cargo.toml index 7699ca2..745af53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ edition = "2021" async-stream = "0.3.5" async-trait = "0.1.68" atty = "0.2" -clap = { version = "4.2.7", features = ["derive"] } -clap_complete = "4.2.3" +clap = { version = "4.3", features = ["derive"] } +clap_complete = "4.3" clicolors-control = "1" console = "0.15.5" const_format = "0.2.30" diff --git a/src/cli.rs b/src/cli.rs index a5d9b83..4e83b18 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,15 +2,16 @@ use std::env; -use clap::{ - builder::PossibleValue, value_parser, Arg, ArgAction, ArgMatches, ColorChoice, - Command as ClapCommand, ValueEnum, -}; +use clap::{CommandFactory, Parser, Subcommand, ValueEnum}; use clap_complete::Shell; use const_format::{concatcp, formatcp}; use env_logger::fmt::WriteStyle; -use crate::{command, nix::HivePath}; +use crate::{ + command, + error::ColmenaResult, + nix::{Hive, HivePath}, +}; /// Base URL of the manual, without the trailing slash. const MANUAL_URL_BASE: &str = "https://colmena.cli.rs"; @@ -66,33 +67,11 @@ const HELP_ORDER_FIRST: usize = 100; /// Display order in `--help` for arguments that are not very important. const HELP_ORDER_LOW: usize = 2000; -macro_rules! register_command { - ($module:ident, $app:ident) => { - $app = $app.subcommand(command::$module::subcommand()); - }; -} - -macro_rules! handle_command { - ($module:ident, $matches:ident) => { - if let Some(sub_matches) = $matches.subcommand_matches(stringify!($module)) { - crate::troubleshooter::run_wrapped(&$matches, &sub_matches, command::$module::run) - .await; - return; - } - }; - ($name:expr, $module:ident, $matches:ident) => { - if let Some(sub_matches) = $matches.subcommand_matches($name) { - crate::troubleshooter::run_wrapped(&$matches, &sub_matches, command::$module::run) - .await; - return; - } - }; -} - /// When to display color. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, ValueEnum)] enum ColorWhen { /// Detect automatically. + #[default] Auto, /// Always display colors. @@ -102,149 +81,199 @@ enum ColorWhen { Never, } -impl ValueEnum for ColorWhen { - fn value_variants<'a>() -> &'a [Self] { - &[Self::Auto, Self::Always, Self::Never] - } - - fn to_possible_value<'a>(&self) -> Option { - match self { - Self::Auto => Some(PossibleValue::new("auto")), - Self::Always => Some(PossibleValue::new("always")), - Self::Never => Some(PossibleValue::new("never")), - } +impl std::fmt::Display for ColorWhen { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + Self::Auto => "auto", + Self::Always => "always", + Self::Never => "never", + }) } } -pub fn build_cli(include_internal: bool) -> ClapCommand { - let version = env!("CARGO_PKG_VERSION"); - let mut app = ClapCommand::new("Colmena") - .bin_name("colmena") - .version(version) - .author("Zhaofeng Li ") - .about("NixOS deployment tool") - .long_about(LONG_ABOUT) - .arg_required_else_help(true) - .arg(Arg::new("config") - .short('f') - .long("config") - .value_name("CONFIG") - .help("Path to a Hive expression, a flake.nix, or a Nix Flake URI") - .long_help(Some(CONFIG_HELP)) - .display_order(HELP_ORDER_FIRST) - .global(true) - .value_parser(value_parser!(HivePath))) - .arg(Arg::new("show-trace") - .long("show-trace") - .help("Show debug information for Nix commands") - .long_help("Passes --show-trace to Nix commands") - .global(true) - .num_args(0)) - .arg(Arg::new("impure") - .long("impure") - .help("Allow impure expressions") - .long_help("Passes --impure to Nix commands") - .global(true) - .num_args(0)) - .arg(Arg::new("nix-option") - .long("nix-option") - .help("Passes an arbitrary option to Nix commands") - .long_help(r#"Passes arbitrary options to Nix commands +#[derive(Parser)] +#[command( + name = "Colmena", + bin_name = "colmena", + author = "Zhaofeng Li ", + version = env!("CARGO_PKG_VERSION"), + about = "NixOS deployment tool", + long_about = LONG_ABOUT, +)] +struct Opts { + #[arg( + short = 'f', + long, + value_name = "CONFIG", + help = "Path to a Hive expression, a flake.nix, or a Nix Flake URI", + long_help = CONFIG_HELP, + display_order = HELP_ORDER_FIRST, + global = true, + )] + config: Option, + #[arg( + long, + help = "Show debug information for Nix commands", + long_help = "Passes --show-trace to Nix commands", + global = true + )] + show_trace: bool, + #[arg( + long, + help = "Allow impure expressions", + long_help = "Passes --impure to Nix commands", + global = true + )] + impure: bool, + #[arg( + long, + value_parser = crate::util::parse_key_val::, + help = "Passes an arbitrary option to Nix commands", + long_help = r#"Passes arbitrary options to Nix commands This only works when building locally. -"#) - .global(true) - .num_args(2) - .value_names(["NAME", "VALUE"]) - .action(ArgAction::Append)) - .arg(Arg::new("color") - .long("color") - .help("When to colorize the output") - .long_help(r#"When to colorize the output. By default, Colmena enables colorized output when the terminal supports it. +"#, + global = true, + num_args = 2, + value_names = ["NAME, VALUE"], + )] + nix_option: Vec<(String, String)>, + #[arg( + long, + value_name = "WHEN", + default_value_t, + global = true, + display_order = HELP_ORDER_LOW, + help = "When to colorize the output", + long_help = r#"When to colorize the output. By default, Colmena enables colorized output when the terminal supports it. It's also possible to specify the preference using environment variables. See . -"#) - .display_order(HELP_ORDER_LOW) - .value_name("WHEN") - .value_parser(value_parser!(ColorWhen)) - .default_value("auto") - .global(true)); +"#, + )] + color: ColorWhen, + #[command(subcommand)] + command: Command, +} - if include_internal { - app = app.subcommand( - ClapCommand::new("gen-completions") - .about("Generate shell auto-completion files (Internal)") - .hide(true) - .arg( - Arg::new("shell") - .index(1) - .value_parser(value_parser!(Shell)) - .required(true) - .num_args(1), - ), - ); - - // TODO: handle deprecated alias - - #[cfg(debug_assertions)] - register_command!(test_progress, app); - } - - register_command!(apply, app); +#[derive(Subcommand)] +enum Command { + Apply(command::apply::Opts), #[cfg(target_os = "linux")] - register_command!(apply_local, app); - register_command!(build, app); - register_command!(eval, app); - register_command!(upload_keys, app); - register_command!(exec, app); - register_command!(repl, app); - register_command!(nix_info, app); + ApplyLocal(command::apply_local::Opts), + Build(command::build::Opts), + Eval(command::eval::Opts), + UploadKeys(command::upload_keys::Opts), + Exec(command::exec::Opts), + Repl(command::repl::Opts), + NixInfo(command::nix_info::Opts), + #[cfg(debug_assertions)] + #[command(about = "Run progress spinner tests", hide = true)] + TestProgress, + #[command(about = "Generate shell auto-completion files (Internal)", hide = true)] + GenCompletions { + shell: Shell, + }, +} - // This does _not_ take the --color flag into account (haven't - // parsed yet), only the CLICOLOR environment variable. - if clicolors_control::colors_enabled() { - app.color(ColorChoice::Always) - } else { - app +async fn get_hive(opts: &Opts) -> ColmenaResult { + let path = match &opts.config { + Some(path) => path.clone(), + None => { + // traverse upwards until we find hive.nix + let mut cur = std::env::current_dir()?; + let mut file_path = None; + + loop { + let flake = cur.join("flake.nix"); + if flake.is_file() { + file_path = Some(flake); + break; + } + + let legacy = cur.join("hive.nix"); + if legacy.is_file() { + file_path = Some(legacy); + break; + } + + match cur.parent() { + Some(parent) => { + cur = parent.to_owned(); + } + None => { + break; + } + } + } + + if file_path.is_none() { + log::error!( + "Could not find `hive.nix` or `flake.nix` in {:?} or any parent directory", + std::env::current_dir()? + ); + } + + HivePath::from_path(file_path.unwrap()).await? + } + }; + + match &path { + HivePath::Legacy(p) => { + log::info!("Using configuration: {}", p.to_string_lossy()); + } + HivePath::Flake(flake) => { + log::info!("Using flake: {}", flake.uri()); + } } + + let mut hive = Hive::new(path).await?; + + if opts.show_trace { + hive.set_show_trace(true); + } + + if opts.impure { + hive.set_impure(true); + } + + for (name, value) in opts.nix_option.iter().cloned() { + hive.add_nix_option(name, value); + } + + Ok(hive) } pub async fn run() { - let mut app = build_cli(true); - let matches = app.clone().get_matches(); + let opts = Opts::parse(); - set_color_pref(matches.get_one("color").unwrap()); + set_color_pref(&opts.color); init_logging(); - handle_command!(apply, matches); - #[cfg(target_os = "linux")] - handle_command!("apply-local", apply_local, matches); - handle_command!(build, matches); - handle_command!(eval, matches); - handle_command!("upload-keys", upload_keys, matches); - handle_command!(exec, matches); - handle_command!(repl, matches); - handle_command!("nix-info", nix_info, matches); + let hive = get_hive(&opts).await.expect("Failed to get flake or hive"); - #[cfg(debug_assertions)] - handle_command!("test-progress", test_progress, matches); + use crate::troubleshooter::run_wrapped as r; - if let Some(args) = matches.subcommand_matches("gen-completions") { - return gen_completions(args); + match opts.command { + Command::Apply(args) => r(command::apply::run(hive, args)).await, + Command::ApplyLocal(args) => r(command::apply_local::run(hive, args)).await, + Command::Eval(args) => r(command::eval::run(hive, args)).await, + Command::Exec(args) => r(command::exec::run(hive, args)).await, + Command::NixInfo(args) => r(command::nix_info::run(args)).await, + Command::Repl(args) => r(command::repl::run(hive, args)).await, + Command::TestProgress => r(command::test_progress::run()).await, + Command::Build(_args) => todo!("This is an alias for `colmena apply build`"), + Command::UploadKeys(_opts) => todo!("This is an alias for `colmena apply upload-keys`"), + Command::GenCompletions { shell } => print_completions(shell, &mut Opts::command()), } - - // deprecated alias - handle_command!("introspect", eval, matches); - - app.print_long_help().unwrap(); - println!(); } -fn gen_completions(args: &ArgMatches) { - let mut app = build_cli(false); - let shell = args.get_one::("shell").unwrap().to_owned(); - - clap_complete::generate(shell, &mut app, "colmena", &mut std::io::stdout()); +fn print_completions(shell: Shell, cmd: &mut clap::Command) { + clap_complete::generate( + shell, + cmd, + cmd.get_name().to_string(), + &mut std::io::stdout(), + ); } fn set_color_pref(when: &ColorWhen) { @@ -273,13 +302,3 @@ fn init_logging() { .write_style(style) .init(); } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_cli_debug_assert() { - build_cli(true).debug_assert() - } -} diff --git a/src/command/apply.rs b/src/command/apply.rs index b81768f..54fa256 100644 --- a/src/command/apply.rs +++ b/src/command/apply.rs @@ -1,16 +1,16 @@ use std::env; use std::path::PathBuf; -use clap::{builder::ArgPredicate, ArgMatches, Args, Command as ClapCommand, FromArgMatches}; +use clap::{builder::ArgPredicate, Args}; +use crate::error::ColmenaError; use crate::nix::{ deployment::{Deployment, EvaluationNodeLimit, EvaluatorType, Goal, Options, ParallelismLimit}, node_filter::NodeFilterOpts, + Hive, }; use crate::progress::SimpleProgressOutput; -use crate::{error::ColmenaError, nix::hive::HiveArgs}; - #[derive(Debug, Args)] pub struct DeployOpts { #[arg( @@ -117,7 +117,7 @@ This is an experimental feature."# #[derive(Debug, Args)] #[command(name = "apply", about = "Apply configurations on remote machines")] -struct Opts { +pub struct Opts { #[arg( help = "Deployment goal", long_help = r#"The goal of the deployment. @@ -139,17 +139,7 @@ Same as the targets for switch-to-configuration, with the following extra pseudo node_filter: NodeFilterOpts, } -pub fn subcommand() -> ClapCommand { - Opts::augment_args(ClapCommand::new("apply")) -} - -pub async fn run(_global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> { - let hive = HiveArgs::from_arg_matches(local_args) - .unwrap() - .into_hive() - .await - .unwrap(); - +pub async fn run(hive: Hive, opts: Opts) -> Result<(), ColmenaError> { let ssh_config = env::var("SSH_CONFIG_FILE").ok().map(PathBuf::from); let Opts { @@ -170,7 +160,7 @@ pub async fn run(_global_args: &ArgMatches, local_args: &ArgMatches) -> Result<( evaluator, }, node_filter, - } = Opts::from_arg_matches(local_args).expect("Failed to parse `apply` args"); + } = opts; if node_filter.on.is_none() && goal != Goal::Build { // User did not specify node, we should check meta and see rules diff --git a/src/command/apply_local.rs b/src/command/apply_local.rs index 29e5df9..9ec38dc 100644 --- a/src/command/apply_local.rs +++ b/src/command/apply_local.rs @@ -1,13 +1,13 @@ use regex::Regex; use std::collections::HashMap; -use clap::{ArgMatches, Args, Command as ClapCommand, FromArgMatches}; +use clap::Args; use tokio::fs; use crate::error::ColmenaError; use crate::nix::deployment::{Deployment, Goal, Options, TargetNode}; -use crate::nix::hive::HiveArgs; +use crate::nix::Hive; use crate::nix::{host::Local as LocalHost, NodeName}; use crate::progress::SimpleProgressOutput; @@ -51,25 +51,19 @@ By default, Colmena will deploy keys set in `deployment.keys` before activating help = "Removed: Configure deployment.privilegeEscalationCommand in node configuration" )] sudo_command: Option, - #[command(flatten)] - hive_args: HiveArgs, } -pub fn subcommand() -> ClapCommand { - Opts::augment_args(ClapCommand::new("apply-local")) -} - -pub async fn run(_global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> { - let Opts { +pub async fn run( + hive: Hive, + Opts { goal, sudo, verbose, no_keys, node, sudo_command, - hive_args, - } = Opts::from_arg_matches(local_args).expect("Failed to parse `apply-local` options."); - + }: Opts, +) -> Result<(), ColmenaError> { if sudo_command.is_some() { log::error!("--sudo-command has been removed. Please configure it in deployment.privilegeEscalationCommand in the node configuration."); quit::with_code(1); @@ -97,10 +91,6 @@ pub async fn run(_global_args: &ArgMatches, local_args: &ArgMatches) -> Result<( } } - let hive = hive_args - .into_hive() - .await - .expect("Failed to get hive from arguments"); let hostname = NodeName::new(node.unwrap_or_else(|| { hostname::get() .expect("Could not get hostname") diff --git a/src/command/build.rs b/src/command/build.rs index 170c435..d8682a2 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -1,4 +1,4 @@ -use clap::{Args, Command as ClapCommand}; +use clap::Args; use crate::nix::Goal; @@ -19,7 +19,3 @@ pub struct Opts { #[arg(hide = true, default_value_t = Goal::Build)] goal: Goal, } - -pub fn subcommand() -> ClapCommand { - Opts::augment_args(ClapCommand::new("build")) -} diff --git a/src/command/eval.rs b/src/command/eval.rs index b9bfa5d..e5d42c5 100644 --- a/src/command/eval.rs +++ b/src/command/eval.rs @@ -1,9 +1,9 @@ use std::path::PathBuf; -use clap::{ArgMatches, Args, Command as ClapCommand, FromArgMatches}; +use clap::Args; use crate::error::ColmenaError; -use crate::nix::hive::HiveArgs; +use crate::nix::Hive; #[derive(Debug, Args)] #[command( @@ -32,29 +32,15 @@ pub struct Opts { expression_file: Option, } -pub fn subcommand() -> ClapCommand { - Opts::augment_args(ClapCommand::new("eval")) -} - -pub async fn run(global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> { - if let Some("introspect") = global_args.subcommand_name() { - log::warn!( - "`colmena introspect` has been renamed to `colmena eval`. Please update your scripts." - ); - } - - let hive = HiveArgs::from_arg_matches(local_args) - .unwrap() - .into_hive() - .await - .unwrap(); - - let Opts { - instantiate, +pub async fn run( + hive: Hive, + Opts { expression, + instantiate, expression_file, - } = Opts::from_arg_matches(local_args).expect("Failed to parse args"); - + }: Opts, +) -> Result<(), ColmenaError> { + // TODO: check for deprecated alias let expression = expression_file .map(|path| { format!( diff --git a/src/command/exec.rs b/src/command/exec.rs index 6410966..a2b8d38 100644 --- a/src/command/exec.rs +++ b/src/command/exec.rs @@ -2,20 +2,20 @@ use std::env; use std::path::PathBuf; use std::sync::Arc; -use clap::{ArgMatches, Args, Command as ClapCommand, FromArgMatches}; +use clap::Args; use futures::future::join_all; use tokio::sync::Semaphore; use crate::error::ColmenaError; use crate::job::{JobMonitor, JobState, JobType}; -use crate::nix::hive::HiveArgs; use crate::nix::node_filter::NodeFilterOpts; +use crate::nix::Hive; use crate::progress::SimpleProgressOutput; use crate::util; #[derive(Debug, Args)] #[command(name = "exec", about = "Run a command on remote machines")] -struct Opts { +pub struct Opts { #[arg( short, long, @@ -52,24 +52,16 @@ It's recommended to use -- to separate Colmena options from the command to run. command: Vec, } -pub fn subcommand() -> ClapCommand { - Opts::augment_args(ClapCommand::new("exec")) -} - -pub async fn run(_global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> { - let hive = HiveArgs::from_arg_matches(local_args) - .unwrap() - .into_hive() - .await - .unwrap(); - let ssh_config = env::var("SSH_CONFIG_FILE").ok().map(PathBuf::from); - - let Opts { +pub async fn run( + hive: Hive, + Opts { parallel, verbose, nodes, command, - } = Opts::from_arg_matches(local_args).unwrap(); + }: Opts, +) -> Result<(), ColmenaError> { + let ssh_config = env::var("SSH_CONFIG_FILE").ok().map(PathBuf::from); let mut targets = hive.select_nodes(nodes.on, ssh_config, true).await?; diff --git a/src/command/nix_info.rs b/src/command/nix_info.rs index 5a54fb8..ea0b240 100644 --- a/src/command/nix_info.rs +++ b/src/command/nix_info.rs @@ -1,4 +1,4 @@ -use clap::{ArgMatches, Args, Command, FromArgMatches}; +use clap::Args; use crate::error::ColmenaError; use crate::nix::evaluator::nix_eval_jobs::get_pinned_nix_eval_jobs; @@ -11,12 +11,7 @@ use crate::nix::NixCheck; )] pub struct Opts {} -pub fn subcommand() -> Command { - Opts::augment_args(Command::new("nix-info")) -} - -pub async fn run(_global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> { - let Opts {} = Opts::from_arg_matches(local_args).unwrap(); +pub async fn run(_: Opts) -> Result<(), ColmenaError> { let check = NixCheck::detect().await; check.print_version_info(); check.print_flakes_info(false); diff --git a/src/command/repl.rs b/src/command/repl.rs index 5a3e25c..a9240d7 100644 --- a/src/command/repl.rs +++ b/src/command/repl.rs @@ -1,12 +1,12 @@ use std::io::Write; -use clap::{ArgMatches, Args, Command as ClapCommand, FromArgMatches}; +use clap::Args; use tempfile::Builder as TempFileBuilder; use tokio::process::Command; use crate::error::ColmenaError; -use crate::nix::hive::HiveArgs; use crate::nix::info::NixCheck; +use crate::nix::Hive; #[derive(Debug, Args)] #[command( @@ -20,22 +20,10 @@ attribute set."# )] pub struct Opts {} -pub fn subcommand() -> ClapCommand { - Opts::augment_args(ClapCommand::new("repl")) -} - -pub async fn run(_global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> { - let Opts {} = Opts::from_arg_matches(local_args).unwrap(); - +pub async fn run(hive: Hive, _: Opts) -> Result<(), ColmenaError> { let nix_check = NixCheck::detect().await; let nix_version = nix_check.version().expect("Could not detect Nix version"); - let hive = HiveArgs::from_arg_matches(local_args) - .unwrap() - .into_hive() - .await - .unwrap(); - let expr = hive.get_repl_expression(); let mut expr_file = TempFileBuilder::new() diff --git a/src/command/test_progress.rs b/src/command/test_progress.rs index df21980..9cba556 100644 --- a/src/command/test_progress.rs +++ b/src/command/test_progress.rs @@ -1,6 +1,5 @@ use std::time::Duration; -use clap::{ArgMatches, Command as ClapCommand}; use tokio::time; use crate::error::{ColmenaError, ColmenaResult}; @@ -14,13 +13,7 @@ macro_rules! node { }; } -pub fn subcommand() -> ClapCommand { - ClapCommand::new("test-progress") - .about("Run progress spinner tests") - .hide(true) -} - -pub async fn run(_global_args: &ArgMatches, _local_args: &ArgMatches) -> Result<(), ColmenaError> { +pub async fn run() -> Result<(), ColmenaError> { let mut output = SpinnerOutput::new(); let (monitor, meta) = JobMonitor::new(output.get_sender()); diff --git a/src/command/upload_keys.rs b/src/command/upload_keys.rs index 43f42b9..9cc6e3e 100644 --- a/src/command/upload_keys.rs +++ b/src/command/upload_keys.rs @@ -1,4 +1,4 @@ -use clap::{Args, Command as ClapCommand}; +use clap::Args; use crate::nix::Goal; @@ -19,7 +19,3 @@ pub struct Opts { #[arg(hide = true, default_value_t = Goal::Build)] goal: Goal, } - -pub fn subcommand() -> ClapCommand { - Opts::augment_args(ClapCommand::new("upload-keys")) -} diff --git a/src/nix/hive/mod.rs b/src/nix/hive/mod.rs index 2989806..f9d9227 100644 --- a/src/nix/hive/mod.rs +++ b/src/nix/hive/mod.rs @@ -8,7 +8,6 @@ use std::convert::AsRef; use std::path::{Path, PathBuf}; use std::str::FromStr; -use clap::Args; use tokio::process::Command; use tokio::sync::OnceCell; use validator::Validate; @@ -23,88 +22,6 @@ use crate::job::JobHandle; use crate::util::{CommandExecution, CommandExt}; use assets::Assets; -#[derive(Debug, Args)] -pub struct HiveArgs { - #[arg(short = 'f', long, value_name = "CONFIG")] - config: Option, - #[arg(long)] - show_trace: bool, - #[arg(long)] - impure: bool, - #[arg(long, value_parser = crate::util::parse_key_val::)] - nix_option: Vec<(String, String)>, -} - -impl HiveArgs { - pub async fn into_hive(self) -> ColmenaResult { - let path = match self.config { - Some(path) => path, - None => { - // traverse upwards until we find hive.nix - let mut cur = std::env::current_dir()?; - let mut file_path = None; - - loop { - let flake = cur.join("flake.nix"); - if flake.is_file() { - file_path = Some(flake); - break; - } - - let legacy = cur.join("hive.nix"); - if legacy.is_file() { - file_path = Some(legacy); - break; - } - - match cur.parent() { - Some(parent) => { - cur = parent.to_owned(); - } - None => { - break; - } - } - } - - if file_path.is_none() { - log::error!( - "Could not find `hive.nix` or `flake.nix` in {:?} or any parent directory", - std::env::current_dir()? - ); - } - - HivePath::from_path(file_path.unwrap()).await? - } - }; - - match &path { - HivePath::Legacy(p) => { - log::info!("Using configuration: {}", p.to_string_lossy()); - } - HivePath::Flake(flake) => { - log::info!("Using flake: {}", flake.uri()); - } - } - - let mut hive = Hive::new(path).await?; - - if self.show_trace { - hive.set_show_trace(true); - } - - if self.impure { - hive.set_impure(true); - } - - for (name, value) in self.nix_option { - hive.add_nix_option(name, value); - } - - Ok(hive) - } -} - #[derive(Debug, Clone)] pub enum HivePath { /// A Nix Flake. diff --git a/src/troubleshooter.rs b/src/troubleshooter.rs index f185421..58a2ec3 100644 --- a/src/troubleshooter.rs +++ b/src/troubleshooter.rs @@ -11,27 +11,23 @@ use snafu::ErrorCompat; use crate::error::ColmenaError; /// Runs a closure and tries to troubleshoot if it returns an error. -pub async fn run_wrapped<'a, F, U, T>( - global_args: &'a ArgMatches, - local_args: &'a ArgMatches, - f: U, -) -> T +pub async fn run_wrapped<'a, F, T>(f: F) -> T where - U: FnOnce(&'a ArgMatches, &'a ArgMatches) -> F, F: Future>, { - match f(global_args, local_args).await { + match f.await { Ok(r) => r, Err(error) => { log::error!("-----"); log::error!("Operation failed with error: {}", error); - if let Err(own_error) = troubleshoot(global_args, local_args, &error) { - log::error!( - "Error occurred while trying to troubleshoot another error: {}", - own_error - ); - } + // TODO: support troubleshooting + // if let Err(own_error) = troubleshoot(hive, &error) { + // log::error!( + // "Error occurred while trying to troubleshoot another error: {}", + // own_error + // ); + // } // Ensure we exit with a code quit::with_code(1);