summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSeth Flynn <[email protected]>2025-03-13 20:32:42 -0400
committerSeth Flynn <[email protected]>2025-03-13 20:33:06 -0400
commit7443543d8b672dc8053f3a4dde5e9bde040672cc (patch)
tree743d5c1b029b65e817228b3fece5c7780b263245 /src
parent910585c5f1de6ad3c750f3a023cf17ae4381341a (diff)
feat: home-manager configuration support
Closes https://github.com/getchoo/nix-forecast/issues/59
Diffstat (limited to 'src')
-rw-r--r--src/cli.rs9
-rw-r--r--src/command.rs5
-rw-r--r--src/nix.rs46
3 files changed, 46 insertions, 14 deletions
diff --git a/src/cli.rs b/src/cli.rs
index edfba5d..da8635b 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -11,6 +11,15 @@ pub struct Cli {
#[arg(short, long, conflicts_with("installables"))]
pub configuration: Option<String>,
+ /// Flake reference pointing to a standalone home-manager configuration
+ #[arg(
+ short = 'o',
+ long,
+ conflicts_with("configuration"),
+ conflicts_with("installables")
+ )]
+ pub home: Option<String>,
+
/// URLs of the substituters to check (can be passed more than once)
#[arg(
alias = "binary-cache",
diff --git a/src/command.rs b/src/command.rs
index be1dd4c..3d630ca 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -19,7 +19,10 @@ impl Run for crate::Cli {
resolve_installables(installables).await?
} else if let Some(configuration) = &self.configuration {
println!("❓ Indexing requisites of configuration closure");
- nix::configuration_closure_paths(configuration)?
+ nix::system_configuration_closure_paths(configuration)?
+ } else if let Some(home) = &self.home {
+ println!("❓ Indexing requisites of home configuration closure");
+ nix::home_configuration_closure_paths(home)?
} else {
println!("❓ Indexing all installables of flake `{}`", self.flake);
let installables = nix::all_flake_installables(&self.flake)?;
diff --git a/src/nix.rs b/src/nix.rs
index 99e7f96..7132e8d 100644
--- a/src/nix.rs
+++ b/src/nix.rs
@@ -24,6 +24,18 @@ struct PathInfo {
path: String,
}
+/// Strip derivations from a list of store paths
+fn strip_drvs(paths: Vec<String>) -> Vec<String> {
+ paths
+ .into_iter()
+ .filter(|path| {
+ std::path::Path::new(path)
+ .extension()
+ .is_some_and(|ext| !ext.eq_ignore_ascii_case("drv"))
+ })
+ .collect()
+}
+
#[instrument(skip(installable))]
pub fn dry_build_output(installable: &str) -> Result<Vec<u8>> {
event!(Level::TRACE, "Running command `nix build --extra-experimental-features 'nix-command flakes' --dry-run --json {installable}`");
@@ -105,22 +117,30 @@ pub fn closure_paths(store_path: &str, with_outputs: bool) -> Result<Vec<String>
}
}
+/// Get all paths in an installable's closure
+#[instrument(skip(installable))]
+fn installable_closure_paths(installable: &str) -> Result<Vec<String>> {
+ let store_path = drv_path(&installable)?;
+ let paths = closure_paths(&store_path, true)?;
+ let out_paths = strip_drvs(paths);
+
+ Ok(out_paths)
+}
+
/// Get all paths in a NixOS or nix-darwin configuration's closure
#[instrument(skip(configuration_ref))]
-pub fn configuration_closure_paths(configuration_ref: &str) -> Result<Vec<String>> {
+pub fn system_configuration_closure_paths(configuration_ref: &str) -> Result<Vec<String>> {
let installable = format!("{configuration_ref}.config.system.build.toplevel");
- let store_path = drv_path(&installable)?;
- let paths = closure_paths(&store_path, true)?;
- // Operate only on the out paths of requisites of the closure
- let out_paths = paths
- .iter()
- .filter(|path| {
- std::path::Path::new(path)
- .extension()
- .is_some_and(|ext| !ext.eq_ignore_ascii_case("drv"))
- })
- .map(ToString::to_string)
- .collect();
+ let out_paths = installable_closure_paths(&installable)?;
+
+ Ok(out_paths)
+}
+
+/// Get all paths in a home-manager configuration's closure
+#[instrument(skip(configuration_ref))]
+pub fn home_configuration_closure_paths(configuration_ref: &str) -> Result<Vec<String>> {
+ let installable = format!("{configuration_ref}.activationPackage");
+ let out_paths = installable_closure_paths(&installable)?;
Ok(out_paths)
}