Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FIXME
Browse files Browse the repository at this point in the history
viperML committed Sep 7, 2024

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
1 parent 7650b37 commit 4bce116
Showing 7 changed files with 210 additions and 333 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nh"
version = "3.5.26"
version = "4.0.0-alpha.1"
edition = "2021"
license = "EUPL-1.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
206 changes: 0 additions & 206 deletions src/home.rs

This file was deleted.

97 changes: 97 additions & 0 deletions src/installables.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use core::fmt;
use std::fmt::Write;

#[derive(Debug, Clone)]
pub enum Installable {
Flake(FlakeInstallable),
}

#[derive(Debug, Clone)]
pub struct FlakeInstallable {
pub reference: String,
pub attribute: Vec<String>,
}

impl From<&str> for Installable {
fn from(value: &str) -> Self {
// FIXME
let x = value.split_once('#').unwrap();
Installable::flake(x.0, &x.1.split('.').collect::<Vec<_>>())
}
}

impl Installable {
pub fn flake<S>(reference: S, attribute: &[S]) -> Self
where
S: AsRef<str>,
{
Installable::Flake(FlakeInstallable {
reference: reference.as_ref().to_string(),
attribute: attribute.iter().map(|s| s.as_ref().to_string()).collect(),
})
}

pub fn to_args(&self) -> Vec<String> {
let mut res = Vec::new();

match &self {
Installable::Flake(flake) => {
let mut f = String::new();
write!(f, "{}", flake.reference).unwrap();

if !flake.attribute.is_empty() {
write!(f, "#").unwrap();

let mut first = true;

for elem in &flake.attribute {
if !first {
write!(f, ".").unwrap();
}

if elem.contains('.') {
write!(f, r#""{}""#, elem).unwrap();
} else {
write!(f, "{}", elem).unwrap();
}

first = false;
}

res.push(f);
}
}
}

return res;
}
}

impl fmt::Display for Installable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut first = true;

for elem in self.to_args() {
if !first {
write!(f, " ")?;
} else {
first = false;
}

write!(f, "{}", elem)?;
}

Ok(())
}
}

#[test]
fn test_display() {
let installable = Installable::flake(".", &["foo", "bar.local", "baz"]);

let args = installable.to_args();
assert_eq!(args, vec![String::from(".#foo.\"bar.local\".baz")]);

let displayed = format!("{}", installable);
assert_eq!(".#foo.\"bar.local\".baz", displayed);
}
5 changes: 3 additions & 2 deletions src/interface.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@ use clap::{builder::Styles, Args, Parser, Subcommand};
use color_eyre::Result;
use std::{ffi::OsString, ops::Deref, path::PathBuf};

use crate::installables::Installable;

#[derive(Debug, Clone, Default)]
pub struct FlakeRef(String);
impl From<&str> for FlakeRef {
@@ -68,7 +70,6 @@ pub trait NHRunnable {
#[command(disable_help_subcommand = true)]
pub enum NHCommand {
Os(OsArgs),
Home(HomeArgs),
Search(SearchArgs),
Clean(CleanProxy),
Completions(CompletionArgs),
@@ -137,7 +138,7 @@ pub struct CommonRebuildArgs {

/// Flake reference to build
#[arg(env = "FLAKE", value_hint = clap::ValueHint::DirPath)]
pub flakeref: FlakeRef,
pub installable: Installable,

/// Update flake inputs before building specified configuration
#[arg(long, short = 'u')]
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod clean;
mod commands;
mod completion;
mod home;
mod installables;
mod interface;
mod json;
mod logging;
229 changes: 107 additions & 122 deletions src/nixos.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ use color_eyre::Result;

use tracing::{debug, info, warn};

use crate::installables::Installable;
use crate::interface::NHRunnable;
use crate::interface::OsRebuildType::{self, Boot, Build, Switch, Test};
use crate::interface::{self, OsRebuildArgs};
@@ -57,128 +58,112 @@ impl OsRebuildArgs {

debug!(?out_path);

let flake_output = format!(
"{}#nixosConfigurations.\"{:?}\".config.system.build.toplevel",
&self.common.flakeref.deref(),
hostname
);

if self.common.update {
// Get the Nix version
let nix_version = get_nix_version().unwrap_or_else(|_| {
panic!("Failed to get Nix version. Custom Nix fork?");
});

// Default interface for updating flake inputs
let mut update_args = vec!["nix", "flake", "update"];

// If user is on Nix 2.19.0 or above, --flake must be passed
if let Ok(ordering) = compare_semver(&nix_version, "2.19.0") {
if ordering == std::cmp::Ordering::Greater {
update_args.push("--flake");
}
}

update_args.push(&self.common.flakeref);

debug!("nix_version: {:?}", nix_version);
debug!("update_args: {:?}", update_args);

commands::CommandBuilder::default()
.args(&update_args)
.message("Updating flake")
.build()?
.exec()?;
}

commands::BuildCommandBuilder::default()
.flakeref(flake_output)
.message("Building NixOS configuration")
.extra_args(["--out-link"])
.extra_args([out_path.get_path()])
.extra_args(&self.extra_args)
.nom(!self.common.no_nom)
.build()?
.exec()?;

let current_specialisation = std::fs::read_to_string(SPEC_LOCATION).ok();

let target_specialisation = if self.no_specialisation {
None
} else {
current_specialisation.or_else(|| self.specialisation.to_owned())
};

debug!("target_specialisation: {target_specialisation:?}");

let target_profile = match &target_specialisation {
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")?;

commands::CommandBuilder::default()
.args(self.common.diff_provider.split_ascii_whitespace())
.args([CURRENT_PROFILE, target_profile.to_str().unwrap()])
.message("Comparing changes")
.build()?
.exec()?;

if self.common.dry || matches!(rebuild_type, OsRebuildType::Build(_)) {
return Ok(());
}

if self.common.ask {
info!("Apply the config?");
let confirmation = dialoguer::Confirm::new().default(false).interact()?;

if !confirmation {
bail!("User rejected the new config");
}
}

if let Test(_) | Switch(_) = rebuild_type {
// !! Use the target profile aka spec-namespaced
let switch_to_configuration =
target_profile.join("bin").join("switch-to-configuration");
let switch_to_configuration = switch_to_configuration.to_str().unwrap();

commands::CommandBuilder::default()
.args(sudo_args)
.args([switch_to_configuration, "test"])
.message("Activating configuration")
.build()?
.exec()?;
}

if let Boot(_) | Switch(_) = rebuild_type {
commands::CommandBuilder::default()
.args(sudo_args)
.args(["nix-env", "--profile", SYSTEM_PROFILE, "--set"])
.args([out_path.get_path()])
.build()?
.exec()?;

// !! Use the base profile aka no spec-namespace
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()
.args(sudo_args)
.args([switch_to_configuration, "boot"])
.message("Adding configuration to bootloader")
.build()?
.exec()?;
}

// Make sure out_path is not accidentally dropped
// https://docs.rs/tempfile/3.12.0/tempfile/index.html#early-drop-pitfall
drop(out_path);

// let target_installable = match self.common.installable {
// installables::Installable::Flake(flake) => {
// // FIXME
// let mut flake = flake.clone();
// flake.attribute = vec![];
// flake.attribute.push(String::from("nixosConfigurations"));
// flake.attribute.push(hostname.into_string().unwrap());
//
// flake.attribute.push(String::from("config"));
// flake.attribute.push(String::from("build"));
// flake.attribute.push(String::from("system"));
// flake.attribute.push(String::from("toplevel"));
//
// Installable::Flake(flake)
// }
// };
//
// commands::BuildCommandBuilder::default()
// .flakeref(format!("{}", target_installable)) // FIXME
// // .flakeref(flake_output)
// .message("Building NixOS configuration")
// .extra_args(["--out-link"])
// .extra_args([out_path.get_path()])
// .extra_args(&self.extra_args)
// .nom(!self.common.no_nom)
// .build()?
// .exec()?;
//
// let current_specialisation = std::fs::read_to_string(SPEC_LOCATION).ok();
//
// let target_specialisation = if self.no_specialisation {
// None
// } else {
// current_specialisation.or_else(|| self.specialisation.to_owned())
// };
//
// debug!("target_specialisation: {target_specialisation:?}");
//
// let target_profile = match &target_specialisation {
// 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")?;
//
// commands::CommandBuilder::default()
// .args(self.common.diff_provider.split_ascii_whitespace())
// .args([CURRENT_PROFILE, target_profile.to_str().unwrap()])
// .message("Comparing changes")
// .build()?
// .exec()?;
//
// if self.common.dry || matches!(rebuild_type, OsRebuildType::Build(_)) {
// return Ok(());
// }
//
// if self.common.ask {
// info!("Apply the config?");
// let confirmation = dialoguer::Confirm::new().default(false).interact()?;
//
// if !confirmation {
// bail!("User rejected the new config");
// }
// }
//
// if let Test(_) | Switch(_) = rebuild_type {
// // !! Use the target profile aka spec-namespaced
// let switch_to_configuration =
// target_profile.join("bin").join("switch-to-configuration");
// let switch_to_configuration = switch_to_configuration.to_str().unwrap();
//
// commands::CommandBuilder::default()
// .args(sudo_args)
// .args([switch_to_configuration, "test"])
// .message("Activating configuration")
// .build()?
// .exec()?;
// }
//
// if let Boot(_) | Switch(_) = rebuild_type {
// commands::CommandBuilder::default()
// .args(sudo_args)
// .args(["nix-env", "--profile", SYSTEM_PROFILE, "--set"])
// .args([out_path.get_path()])
// .build()?
// .exec()?;
//
// // !! Use the base profile aka no spec-namespace
// 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()
// .args(sudo_args)
// .args([switch_to_configuration, "boot"])
// .message("Adding configuration to bootloader")
// .build()?
// .exec()?;
// }
//
// // Make sure out_path is not accidentally dropped
// // https://docs.rs/tempfile/3.12.0/tempfile/index.html#early-drop-pitfall
// drop(out_path);
//
Ok(())
}
}

0 comments on commit 4bce116

Please sign in to comment.