feat(step): nix-helper (#1045)

This commit is contained in:
Tom van Dijk
2025-07-15 11:05:46 +02:00
committed by GitHub
parent 85c8bd2277
commit 6b8327faad
4 changed files with 99 additions and 1 deletions

View File

@@ -1304,3 +1304,19 @@ _version: 2
zh_CN: "<省略了 `deb-get clean` 的输出>"
zh_TW: "<省略了 `deb-get clean` 的輸出>"
de: "<Ausgabe von `deb-get clean` ausgelassen>"
"You have a flake inside of $FLAKE. This is deprecated for nh.":
en: "You have a flake inside of $FLAKE. This is deprecated for nh."
lt: "Jūs turite flake viduje $FLAKE. Tai yra pasenę nh."
es: "Tienes un flake dentro de $FLAKE. Esto está en desuso para nh."
fr: "Vous avez un flake à l'intérieur de $FLAKE. Ça c'est obsolète pour nh."
zh_TW: "你在 $FLAKE 裡有一個 flake。這在 nh 中已被棄用。"
zh_CN: "你在 $FLAKE 里有一个 flake。这在 nh 中已被弃用。"
de: "Sie haben ein flake in $FLAKE. Dies ist für nh veraltet."
"nh cannot find any configured flakes":
en: "nh cannot find any configured flakes"
lt: "nh nepavyksta rasti jokių sukonfigūruotų flake"
es: "nh no puede encontrar ningún flake configurado"
fr: "nh ne peut trouver aucun flake configuré"
zh_TW: "nh 找不到任何已設定的 flake"
zh_CN: "nh 无法找到任何已配置的 flake"
de: "nh kann keine konfigurierten flakes finden"

View File

@@ -134,6 +134,7 @@ pub enum Step {
Mise,
Myrepos,
Nix,
NixHelper,
Node,
Opam,
Pacdef,

View File

@@ -314,6 +314,7 @@ fn run() -> Result<()> {
runner.execute(Step::Yadm, "yadm", || unix::run_yadm(&ctx))?;
runner.execute(Step::Nix, "nix", || unix::run_nix(&ctx))?;
runner.execute(Step::Nix, "nix upgrade-nix", || unix::run_nix_self_upgrade(&ctx))?;
runner.execute(Step::NixHelper, "nh", || unix::run_nix_helper(&ctx))?;
runner.execute(Step::Guix, "guix", || unix::run_guix(&ctx))?;
runner.execute(Step::HomeManager, "home-manager", || unix::run_home_manager(&ctx))?;
runner.execute(Step::Asdf, "asdf", || unix::run_asdf(&ctx))?;

View File

@@ -18,7 +18,7 @@ use std::path::PathBuf;
use std::process::Command;
use std::sync::LazyLock;
use std::{env::var, path::Path};
use tracing::debug;
use tracing::{debug, warn};
#[cfg(target_os = "linux")]
use super::linux::Distribution;
@@ -622,6 +622,86 @@ fn nix_profile_dir(nix: &Path) -> Result<Option<PathBuf>> {
)
}
/// Returns a directory from an environment variable, if and only if it is a directory which
/// contains a flake.nix
fn flake_dir(var: &'static str) -> Option<PathBuf> {
std::env::var_os(var)
.map(PathBuf::from)
.take_if(|x| std::fs::exists(x.join("flake.nix")).is_ok_and(|x| x))
}
/// Update NixOS and home-manager through a flake using `nh`
///
/// See: https://github.com/viperML/nh
pub fn run_nix_helper(ctx: &ExecutionContext) -> Result<()> {
let run_type = ctx.run_type();
require("nix")?;
let nix_helper = require("nh")?;
let fallback_flake_path = flake_dir("NH_FLAKE");
let darwin_flake_path = flake_dir("NH_DARWIN_FLAKE");
let home_flake_path = flake_dir("NH_HOME_FLAKE");
let nixos_flake_path = flake_dir("NH_OS_FLAKE");
let all_flake_paths: Vec<_> = [
fallback_flake_path.as_ref(),
darwin_flake_path.as_ref(),
home_flake_path.as_ref(),
nixos_flake_path.as_ref(),
]
.into_iter()
.flatten()
.collect();
// if none of the paths exist AND contain a `flake.nix`, skip
if all_flake_paths.is_empty() {
if flake_dir("FLAKE").is_some() {
warn!(
"{}",
t!("You have a flake inside of $FLAKE. This is deprecated for nh.")
);
}
return Err(SkipStep(t!("nh cannot find any configured flakes").into()).into());
}
let nh_switch = |ty: &'static str| -> Result<()> {
print_separator(format!("nh {ty}"));
let mut cmd = run_type.execute(&nix_helper);
cmd.arg(ty);
cmd.arg("switch");
cmd.arg("-u");
if !ctx.config().yes(Step::NixHelper) {
cmd.arg("--ask");
}
cmd.status_checked()?;
Ok(())
};
// We assume that if the user has set these variables, we can throw an error if nh cannot find
// a flake there. So we do not anymore perform an eval check to find out wether we should skip
// or not.
#[cfg(target_os = "macos")]
if darwin_flake_path.is_some() || fallback_flake_path.is_some() {
nh_switch("darwin")?;
}
if home_flake_path.is_some() || fallback_flake_path.is_some() {
nh_switch("home")?;
}
#[cfg(target_os = "linux")]
if matches!(Distribution::detect(), Ok(Distribution::NixOS))
&& (nixos_flake_path.is_some() || fallback_flake_path.is_some())
{
nh_switch("os")?;
}
Ok(())
}
fn nix_args() -> [&'static str; 2] {
["--extra-experimental-features", "nix-command"]
}