Skip to content

Commit 7870f6b

Browse files
committed
treewide: consolidate logic in platform-specific commands
1 parent 9bbd963 commit 7870f6b

File tree

8 files changed

+568
-642
lines changed

8 files changed

+568
-642
lines changed

src/darwin.rs

Lines changed: 60 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
use std::env;
1+
use color_eyre::eyre::Context;
2+
use tracing::{debug, warn};
23

3-
use color_eyre::eyre::{bail, Context};
4-
use tracing::{debug, info, warn};
5-
6-
use crate::commands;
74
use crate::commands::Command;
8-
use crate::installable::Installable;
95
use crate::interface::{DarwinArgs, DarwinRebuildArgs, DarwinReplArgs, DarwinSubcommand};
10-
use crate::nixos::toplevel_for;
116
use crate::update::update;
12-
use crate::util::get_hostname;
7+
use crate::util::platform;
138
use crate::Result;
149

1510
const SYSTEM_PROFILE: &str = "/nix/var/nix/profiles/system";
@@ -40,85 +35,65 @@ impl DarwinRebuildArgs {
4035
fn rebuild(self, variant: DarwinRebuildVariant) -> Result<()> {
4136
use DarwinRebuildVariant::{Build, Switch};
4237

43-
if nix::unistd::Uid::effective().is_root() {
44-
bail!("Don't run nh os as root. I will call sudo internally as needed");
45-
}
38+
// Ensure we're not running as root
39+
platform::check_not_root(false)?;
4640

4741
if self.update_args.update {
4842
update(&self.common.installable, self.update_args.update_input)?;
4943
}
5044

51-
let hostname = self.hostname.ok_or(()).or_else(|()| get_hostname())?;
52-
53-
let out_path: Box<dyn crate::util::MaybeTempPath> = match self.common.out_link {
54-
Some(ref p) => Box::new(p.clone()),
55-
None => Box::new({
56-
let dir = tempfile::Builder::new().prefix("nh-os").tempdir()?;
57-
(dir.as_ref().join("result"), dir)
58-
}),
59-
};
45+
let hostname = self
46+
.hostname
47+
.ok_or(())
48+
.or_else(|()| crate::util::get_hostname())?;
6049

50+
// Set up temporary directory for build results
51+
let out_path = platform::create_output_path(self.common.out_link, "nh-os")?;
6152
debug!(?out_path);
6253

63-
// Use NH_DARWIN_FLAKE if available, otherwise use the provided installable
64-
let installable = if let Ok(darwin_flake) = env::var("NH_DARWIN_FLAKE") {
65-
debug!("Using NH_DARWIN_FLAKE: {}", darwin_flake);
66-
67-
let mut elems = darwin_flake.splitn(2, '#');
68-
let reference = elems.next().unwrap().to_owned();
69-
let attribute = elems
70-
.next()
71-
.map(crate::installable::parse_attribute)
72-
.unwrap_or_default();
73-
74-
Installable::Flake {
75-
reference,
76-
attribute,
77-
}
78-
} else {
79-
self.common.installable.clone()
80-
};
81-
82-
let mut processed_installable = installable;
83-
if let Installable::Flake {
84-
ref mut attribute, ..
85-
} = processed_installable
86-
{
87-
// If user explicitly selects some other attribute, don't push darwinConfigurations
88-
if attribute.is_empty() {
89-
attribute.push(String::from("darwinConfigurations"));
90-
attribute.push(hostname.clone());
91-
}
92-
}
93-
94-
let toplevel = toplevel_for(hostname, processed_installable, "toplevel");
95-
96-
commands::Build::new(toplevel)
97-
.extra_arg("--out-link")
98-
.extra_arg(out_path.get_path())
99-
.extra_args(&self.extra_args)
100-
.message("Building Darwin configuration")
101-
.nom(!self.common.no_nom)
102-
.run()?;
54+
// Check for environment variable override for flake path
55+
let installable =
56+
platform::resolve_env_installable("NH_DARWIN_FLAKE", self.common.installable.clone());
57+
58+
// Configure the installable for Darwin
59+
let toplevel = platform::extend_installable_for_platform(
60+
installable,
61+
"darwinConfigurations",
62+
&["toplevel"],
63+
Some(hostname),
64+
true,
65+
&self
66+
.extra_args
67+
.iter()
68+
.map(std::convert::Into::into)
69+
.collect::<Vec<_>>(),
70+
)?;
71+
72+
// Build the nix-darwin configuration
73+
platform::build_configuration(
74+
toplevel,
75+
out_path.as_ref(),
76+
&self.extra_args,
77+
None,
78+
"Building Darwin configuration",
79+
self.common.no_nom,
80+
)?;
10381

10482
let target_profile = out_path.get_path().to_owned();
105-
10683
target_profile.try_exists().context("Doesn't exist")?;
10784

108-
Command::new("nvd")
109-
.arg("diff")
110-
.arg(CURRENT_PROFILE)
111-
.arg(&target_profile)
112-
.message("Comparing changes")
113-
.run()?;
114-
115-
if self.common.ask && !self.common.dry && !matches!(variant, Build) {
116-
info!("Apply the config?");
117-
let confirmation = dialoguer::Confirm::new().default(false).interact()?;
85+
// Show diff between current and new configuration
86+
platform::compare_configurations(
87+
CURRENT_PROFILE,
88+
&target_profile,
89+
false,
90+
"Comparing changes",
91+
)?;
11892

119-
if !confirmation {
120-
bail!("User rejected the new config");
121-
}
93+
// Ask for confirmation if needed
94+
if !platform::confirm_action(self.common.ask, self.common.dry)? && !matches!(variant, Build)
95+
{
96+
return Ok(());
12297
}
12398

12499
if matches!(variant, Switch) {
@@ -159,46 +134,16 @@ impl DarwinRebuildArgs {
159134

160135
impl DarwinReplArgs {
161136
fn run(self) -> Result<()> {
162-
// Use NH_DARWIN_FLAKE if available, otherwise use the provided installable
163-
let mut target_installable = if let Ok(darwin_flake) = env::var("NH_DARWIN_FLAKE") {
164-
debug!("Using NH_DARWIN_FLAKE: {}", darwin_flake);
165-
166-
let mut elems = darwin_flake.splitn(2, '#');
167-
let reference = elems.next().unwrap().to_owned();
168-
let attribute = elems
169-
.next()
170-
.map(crate::installable::parse_attribute)
171-
.unwrap_or_default();
172-
173-
Installable::Flake {
174-
reference,
175-
attribute,
176-
}
177-
} else {
178-
self.installable
179-
};
180-
181-
if matches!(target_installable, Installable::Store { .. }) {
182-
bail!("Nix doesn't support nix store installables.");
183-
}
184-
185-
let hostname = self.hostname.ok_or(()).or_else(|()| get_hostname())?;
186-
187-
if let Installable::Flake {
188-
ref mut attribute, ..
189-
} = target_installable
190-
{
191-
if attribute.is_empty() {
192-
attribute.push(String::from("darwinConfigurations"));
193-
attribute.push(hostname);
194-
}
195-
}
196-
197-
Command::new("nix")
198-
.arg("repl")
199-
.args(target_installable.to_args())
200-
.run()?;
201-
202-
Ok(())
137+
// Check for environment variable override for flake path
138+
let installable = platform::resolve_env_installable("NH_DARWIN_FLAKE", self.installable);
139+
140+
// Launch the nix REPL with the Darwin configuration
141+
platform::run_repl(
142+
installable,
143+
"darwinConfigurations",
144+
&["toplevel"],
145+
self.hostname,
146+
&[],
147+
)
203148
}
204149
}

src/generations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn from_dir(generation_dir: &Path) -> Option<u64> {
4343
})
4444
}
4545

46-
pub fn describe(generation_dir: &Path, current_profile: &Path) -> Option<GenerationInfo> {
46+
pub fn describe(generation_dir: &Path, _current_profile: &Path) -> Option<GenerationInfo> {
4747
let generation_number = from_dir(generation_dir)?;
4848

4949
// Get metadata once and reuse for both date and existence checks

0 commit comments

Comments
 (0)