diff --git a/src/nix/hive/mod.rs b/src/nix/hive/mod.rs index 2ebf4c1..565ca89 100644 --- a/src/nix/hive/mod.rs +++ b/src/nix/hive/mod.rs @@ -15,6 +15,7 @@ use super::{ NodeName, NodeConfig, NodeFilter, + NixExpression, ProfileDerivation, StorePath, }; @@ -74,6 +75,12 @@ struct SerializedNixExpression { json_file: TempPath, } +/// An expression to evaluate the system profiles of selected nodes. +struct EvalSelectedExpression<'hive> { + hive: &'hive Hive, + nodes_expr: SerializedNixExpression, +} + impl HivePath { pub async fn from_path>(path: P) -> ColmenaResult { let path = path.as_ref(); @@ -290,6 +297,16 @@ impl Hive { .collect() } + /// Returns the expression to evaluate selected nodes. + pub fn eval_selected_expr(&self, nodes: &[NodeName]) -> ColmenaResult { + let nodes_expr = SerializedNixExpression::new(nodes)?; + + Ok(EvalSelectedExpression { + hive: self, + nodes_expr, + }) + } + /// Evaluates an expression using values from the configuration. pub async fn introspect(&self, expression: String, instantiate: bool) -> ColmenaResult { if instantiate { @@ -419,8 +436,24 @@ impl SerializedNixExpression { json_file: tmp.into_temp_path(), }) } +} - pub fn expression(&self) -> String { +impl NixExpression for SerializedNixExpression { + fn expression(&self) -> String { format!("(builtins.fromJSON (builtins.readFile {}))", self.json_file.to_str().unwrap()) } } + +impl<'hive> NixExpression for EvalSelectedExpression<'hive> { + fn expression(&self) -> String { + format!( + "{} hive.evalSelected {}", + self.hive.get_base_expression(), + self.nodes_expr.expression(), + ) + } + + fn requires_flakes(&self) -> bool { + self.hive.is_flake() + } +} diff --git a/src/nix/mod.rs b/src/nix/mod.rs index e539d5f..90066a7 100644 --- a/src/nix/mod.rs +++ b/src/nix/mod.rs @@ -97,6 +97,17 @@ pub struct NixOptions { builders: Option, } +/// A Nix expression. +pub trait NixExpression : Send + Sync { + /// Returns the full Nix expression to be evaluated. + fn expression(&self) -> String; + + /// Returns whether this expression requires the use of flakes. + fn requires_flakes(&self) -> bool { + false + } +} + impl NodeName { /// Returns the string. pub fn as_str(&self) -> &str { @@ -203,6 +214,12 @@ impl NixOptions { } } +impl NixExpression for String { + fn expression(&self) -> String { + self.clone() + } +} + fn validate_keys(keys: &HashMap) -> Result<(), ValidationErrorType> { // Bad secret names: // - /etc/passwd