diff --git a/src/cli.rs b/src/cli.rs index 0b8b9d9..2741032 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -3,8 +3,8 @@ use std::env; use clap::{ - builder::PossibleValue, value_parser, Arg, ArgMatches, ColorChoice, Command as ClapCommand, - ValueEnum, + builder::PossibleValue, value_parser, Arg, ArgAction, ArgMatches, ColorChoice, + Command as ClapCommand, ValueEnum, }; use clap_complete::Shell; use const_format::concatcp; @@ -160,6 +160,17 @@ pub fn build_cli(include_internal: bool) -> ClapCommand { .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 + +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") diff --git a/src/nix/hive/mod.rs b/src/nix/hive/mod.rs index 26d0556..1aae906 100644 --- a/src/nix/hive/mod.rs +++ b/src/nix/hive/mod.rs @@ -52,6 +52,9 @@ pub struct Hive { /// Whether to pass --impure in Nix commands. impure: bool, + /// Options to pass as --option name value. + nix_options: HashMap, + meta_config: OnceCell, } @@ -104,6 +107,7 @@ impl Hive { assets, show_trace: false, impure: false, + nix_options: HashMap::new(), meta_config: OnceCell::new(), }) } @@ -131,12 +135,17 @@ impl Hive { self.impure = impure; } + pub fn add_nix_option(&mut self, name: String, value: String) { + self.nix_options.insert(name, value); + } + /// Returns Nix options to set for this Hive. pub fn nix_options(&self) -> NixOptions { let mut options = NixOptions::default(); options.set_show_trace(self.show_trace); options.set_pure_eval(self.path.is_flake()); options.set_impure(self.impure); + options.set_options(self.nix_options.clone()); options } diff --git a/src/nix/mod.rs b/src/nix/mod.rs index 4bf2d40..18cc353 100644 --- a/src/nix/mod.rs +++ b/src/nix/mod.rs @@ -111,6 +111,9 @@ pub struct NixOptions { /// - `@/path/to/machines` /// - `builder@host.tld riscv64-linux /home/nix/.ssh/keys/builder.key 8 1 kvm` builders: Option, + + /// Options to pass as --option name value. + options: HashMap, } impl NodeName { @@ -205,6 +208,10 @@ impl NixOptions { self.builders = builders; } + pub fn set_options(&mut self, options: HashMap) { + self.options = options; + } + pub fn to_args(&self) -> Vec { let mut options = Vec::new(); @@ -228,6 +235,12 @@ impl NixOptions { options.push("--impure".to_string()); } + for (name, value) in self.options.iter() { + options.push("--option".to_string()); + options.push(name.to_string()); + options.push(value.to_string()); + } + options } } diff --git a/src/util.rs b/src/util.rs index e72c0aa..ac17ad2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -244,17 +244,8 @@ pub async fn hive_from_args(args: &ArgMatches) -> ColmenaResult { log::info!("Using flake: {}", flake.uri()); let hive_path = HivePath::Flake(flake); - let mut hive = Hive::new(hive_path).await?; - if args.get_flag("show-trace") { - hive.set_show_trace(true); - } - - if args.get_flag("impure") { - hive.set_impure(true); - } - - return Ok(hive); + return hive_from_path(hive_path, args).await; } fpath @@ -263,6 +254,11 @@ pub async fn hive_from_args(args: &ArgMatches) -> ColmenaResult { }; let hive_path = HivePath::from_path(path).await?; + + hive_from_path(hive_path, args).await +} + +pub async fn hive_from_path(hive_path: HivePath, args: &ArgMatches) -> ColmenaResult { match &hive_path { HivePath::Legacy(p) => { log::info!("Using configuration: {}", p.to_string_lossy()); @@ -282,6 +278,17 @@ pub async fn hive_from_args(args: &ArgMatches) -> ColmenaResult { hive.set_impure(true); } + if let Some(opts) = args.get_many::("nix-option") { + let iter = opts.into_iter(); + + let names = iter.clone().step_by(2); + let values = iter.clone().skip(1).step_by(2); + + for (name, value) in names.zip(values) { + hive.add_nix_option(name.to_owned(), value.to_owned()); + } + } + Ok(hive) }