forked from DGNum/colmena
Convert eval arguments to type-safe clap derive
This commit is contained in:
parent
cdfc1f15a1
commit
5b8611744b
2 changed files with 45 additions and 53 deletions
|
@ -191,8 +191,7 @@ It's also possible to specify the preference using environment variables. See <h
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// deprecated alias
|
// TODO: handle deprecated alias
|
||||||
app = app.subcommand(command::eval::deprecated_alias());
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
register_command!(test_progress, app);
|
register_command!(test_progress, app);
|
||||||
|
|
|
@ -1,44 +1,39 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{value_parser, Arg, ArgMatches, Command as ClapCommand, FromArgMatches};
|
use clap::{ArgMatches, Args, Command as ClapCommand, FromArgMatches};
|
||||||
|
|
||||||
use crate::error::ColmenaError;
|
use crate::error::ColmenaError;
|
||||||
use crate::nix::hive::HiveArgs;
|
use crate::nix::hive::HiveArgs;
|
||||||
|
|
||||||
pub fn subcommand() -> ClapCommand {
|
#[derive(Debug, Args)]
|
||||||
subcommand_gen("eval")
|
#[command(
|
||||||
}
|
name = "eval",
|
||||||
|
alias = "introspect",
|
||||||
pub fn deprecated_alias() -> ClapCommand {
|
about = "Evaluate an expression using the complete configuration",
|
||||||
subcommand_gen("introspect").hide(true)
|
long_about = r#"Evaluate an expression using the complete configuration
|
||||||
}
|
|
||||||
|
|
||||||
fn subcommand_gen(name: &'static str) -> ClapCommand {
|
|
||||||
ClapCommand::new(name)
|
|
||||||
.about("Evaluate an expression using the complete configuration")
|
|
||||||
.long_about(r#"Evaluate an expression using the complete configuration
|
|
||||||
|
|
||||||
Your expression should take an attribute set with keys `pkgs`, `lib` and `nodes` (like a NixOS module) and return a JSON-serializable value.
|
Your expression should take an attribute set with keys `pkgs`, `lib` and `nodes` (like a NixOS module) and return a JSON-serializable value.
|
||||||
|
|
||||||
For example, to retrieve the configuration of one node, you may write something like:
|
For example, to retrieve the configuration of one node, you may write something like:
|
||||||
|
|
||||||
{ nodes, ... }: nodes.node-a.config.networking.hostName
|
{ nodes, ... }: nodes.node-a.config.networking.hostName
|
||||||
"#)
|
"#
|
||||||
.arg(Arg::new("expression_file")
|
)]
|
||||||
.index(1)
|
pub struct Opts {
|
||||||
.value_name("FILE")
|
#[arg(short = 'E', value_name = "EXPRESSION", help = "The Nix expression")]
|
||||||
.help("The .nix file containing the expression")
|
expression: Option<String>,
|
||||||
.num_args(1)
|
#[arg(long, help = "Actually instantiate the expression")]
|
||||||
.value_parser(value_parser!(PathBuf)))
|
instantiate: bool,
|
||||||
.arg(Arg::new("expression")
|
#[arg(
|
||||||
.short('E')
|
value_name = "FILE",
|
||||||
.value_name("EXPRESSION")
|
help = "The .nix file containing the expression",
|
||||||
.help("The Nix expression")
|
conflicts_with("expression")
|
||||||
.num_args(1))
|
)]
|
||||||
.arg(Arg::new("instantiate")
|
expression_file: Option<PathBuf>,
|
||||||
.long("instantiate")
|
}
|
||||||
.help("Actually instantiate the expression")
|
|
||||||
.num_args(0))
|
pub fn subcommand() -> ClapCommand {
|
||||||
|
Opts::augment_args(ClapCommand::new("eval"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> {
|
pub async fn run(global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> {
|
||||||
|
@ -54,21 +49,14 @@ pub async fn run(global_args: &ArgMatches, local_args: &ArgMatches) -> Result<()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if !(local_args.contains_id("expression") ^ local_args.contains_id("expression_file")) {
|
let Opts {
|
||||||
log::error!("Either an expression (-E) or a .nix file containing an expression should be specified, not both.");
|
instantiate,
|
||||||
quit::with_code(1);
|
expression,
|
||||||
}
|
expression_file,
|
||||||
|
} = Opts::from_arg_matches(local_args).expect("Failed to parse args");
|
||||||
|
|
||||||
let expression = if local_args.contains_id("expression") {
|
let expression = expression_file
|
||||||
local_args
|
.map(|path| {
|
||||||
.get_one::<String>("expression")
|
|
||||||
.unwrap()
|
|
||||||
.to_owned()
|
|
||||||
} else {
|
|
||||||
let path = local_args
|
|
||||||
.get_one::<PathBuf>("expression_file")
|
|
||||||
.unwrap()
|
|
||||||
.to_owned();
|
|
||||||
format!(
|
format!(
|
||||||
"import {}",
|
"import {}",
|
||||||
path.canonicalize()
|
path.canonicalize()
|
||||||
|
@ -76,9 +64,14 @@ pub async fn run(global_args: &ArgMatches, local_args: &ArgMatches) -> Result<()
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
|
})
|
||||||
|
.or(expression);
|
||||||
|
|
||||||
|
let Some(expression) = expression else {
|
||||||
|
log::error!("Provide either an expression (-E) or a .nix file containing an expression.");
|
||||||
|
quit::with_code(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
let instantiate = local_args.get_flag("instantiate");
|
|
||||||
let result = hive.introspect(expression, instantiate).await?;
|
let result = hive.introspect(expression, instantiate).await?;
|
||||||
|
|
||||||
if instantiate {
|
if instantiate {
|
||||||
|
|
Loading…
Reference in a new issue