From 6878bc368e03915680dc1cfc929dc825bf5b7ca1 Mon Sep 17 00:00:00 2001 From: Fernando Ayats Date: Sun, 18 Aug 2024 17:17:13 +0200 Subject: [PATCH] Add --out-link flag Closes #137 --- src/home.rs | 24 +++++++++++++++--------- src/interface.rs | 4 ++++ src/nixos.rs | 30 +++++++++++++++++++----------- src/util.rs | 18 ++++++++++++++++++ 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/home.rs b/src/home.rs index 436eb92..725da11 100644 --- a/src/home.rs +++ b/src/home.rs @@ -34,11 +34,15 @@ impl NHRunnable for HomeArgs { impl HomeRebuildArgs { fn rebuild(&self, action: &HomeSubcommand) -> Result<()> { - let out_dir = tempfile::Builder::new().prefix("nh-home-").tempdir()?; - let out_link = out_dir.path().join("result"); - let out_link_str = out_link.to_str().unwrap(); - debug!("out_dir: {:?}", out_dir); - debug!("out_link {:?}", out_link); + let out_path: Box = match self.common.out_link { + Some(ref p) => Box::new(p.clone()), + None => Box::new({ + let dir = tempfile::Builder::new().prefix("nh-home").tempdir()?; + (dir.as_ref().join("result"), dir) + }), + }; + + debug!(?out_path); let username = std::env::var("USER").expect("Couldn't get username"); @@ -91,7 +95,8 @@ impl HomeRebuildArgs { commands::BuildCommandBuilder::default() .flakeref(&flakeref) - .extra_args(["--out-link", out_link_str]) + .extra_args(["--out-link"]) + .extra_args([out_path.get_path()]) .extra_args(&self.extra_args) .message("Building home configuration") .nom(!self.common.no_nom) @@ -115,7 +120,8 @@ impl HomeRebuildArgs { if let Some(prev_gen) = prev_generation { commands::CommandBuilder::default() .args(self.common.diff_provider.split_ascii_whitespace()) - .args([(prev_gen.to_str().unwrap()), out_link_str]) + .args([(prev_gen.to_str().unwrap())]) + .args([out_path.get_path()]) .message("Comparing changes") .build()? .exec()?; @@ -140,13 +146,13 @@ impl HomeRebuildArgs { } commands::CommandBuilder::default() - .args([&format!("{}/activate", out_link_str)]) + .args([out_path.get_path().join("activate")]) .message("Activating configuration") .build()? .exec()?; // Drop the out dir *only* when we are finished - drop(out_dir); + drop(out_path); Ok(()) } diff --git a/src/interface.rs b/src/interface.rs index a215771..351d7de 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -146,6 +146,10 @@ pub struct CommonRebuildArgs { default_value = "nvd diff" )] pub diff_provider: String, + + /// Path to save the result link. Defaults to using a temporary directory. + #[arg(long, short)] + pub out_link: Option } #[derive(Args, Debug)] diff --git a/src/nixos.rs b/src/nixos.rs index 1be0ac1..9fe82eb 100644 --- a/src/nixos.rs +++ b/src/nixos.rs @@ -36,11 +36,15 @@ impl OsRebuildArgs { None => hostname::get().context("Failed to get hostname")?, }; - let out_dir = tempfile::Builder::new().prefix("nh-os-").tempdir()?; - let out_link = out_dir.path().join("result"); - let out_link_str = out_link.to_str().unwrap(); - debug!("out_dir: {:?}", out_dir); - debug!("out_link {:?}", out_link); + let out_path: Box = match self.common.out_link { + Some(ref p) => Box::new(p.clone()), + None => Box::new({ + let dir = tempfile::Builder::new().prefix("nh-os").tempdir()?; + (dir.as_ref().join("result"), dir) + }), + }; + + debug!(?out_path); let flake_output = format!( "{}#nixosConfigurations.\"{:?}\".config.system.build.toplevel", @@ -79,7 +83,8 @@ impl OsRebuildArgs { commands::BuildCommandBuilder::default() .flakeref(flake_output) .message("Building NixOS configuration") - .extra_args(["--out-link", out_link_str]) + .extra_args(["--out-link"]) + .extra_args([out_path.get_path()]) .extra_args(&self.extra_args) .nom(!self.common.no_nom) .build()? @@ -96,8 +101,8 @@ impl OsRebuildArgs { debug!("target_specialisation: {target_specialisation:?}"); let target_profile = match &target_specialisation { - None => out_link.to_owned(), - Some(spec) => out_link.join("specialisation").join(spec), + None => out_path.get_path().to_owned(), + Some(spec) => out_path.get_path().join("specialisation").join(spec), }; target_profile.try_exists().context("Doesn't exist")?; @@ -143,13 +148,16 @@ impl OsRebuildArgs { "--profile", SYSTEM_PROFILE, "--set", - out_link_str, ]) + .args([out_path.get_path()]) .build()? .exec()?; // !! Use the base profile aka no spec-namespace - let switch_to_configuration = out_link.join("bin").join("switch-to-configuration"); + let switch_to_configuration = out_path + .get_path() + .join("bin") + .join("switch-to-configuration"); let switch_to_configuration = switch_to_configuration.to_str().unwrap(); commands::CommandBuilder::default() @@ -160,7 +168,7 @@ impl OsRebuildArgs { } // Drop the out dir *only* when we are finished - drop(out_dir); + drop(out_path); Ok(()) } diff --git a/src/util.rs b/src/util.rs index 6a4c950..1cbee66 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,7 +2,9 @@ extern crate semver; use color_eyre::{eyre, Result}; use semver::Version; +use tempfile::TempDir; +use std::path::{Path, PathBuf}; use std::process::Command; use std::str; @@ -56,3 +58,19 @@ pub fn get_nix_version() -> Result { Err(eyre::eyre!("Failed to extract version")) } + +pub trait MaybeTempPath: std::fmt::Debug { + fn get_path(&self) -> &Path; +} + +impl MaybeTempPath for PathBuf { + fn get_path(&self) -> &Path { + self.as_ref() + } +} + +impl MaybeTempPath for (PathBuf, TempDir) { + fn get_path(&self) -> &Path { + self.0.as_ref() + } +}