1- use color_eyre:: eyre:: bail;
2- use color_eyre:: Result ;
3- use tracing:: { debug, info, warn} ;
1+ use color_eyre:: eyre:: { bail, Context } ;
2+ use tracing:: { debug, warn} ;
43
54use crate :: commands:: Command ;
5+ use crate :: installable:: Installable ;
66use crate :: interface:: { DarwinArgs , DarwinRebuildArgs , DarwinReplArgs , DarwinSubcommand } ;
77use crate :: update:: update;
8+ use crate :: util:: get_hostname;
89use crate :: util:: platform;
10+ use crate :: Result ;
911
1012const SYSTEM_PROFILE : & str = "/nix/var/nix/profiles/system" ;
1113const CURRENT_PROFILE : & str = "/run/current-system" ;
@@ -35,69 +37,70 @@ impl DarwinRebuildArgs {
3537 fn rebuild ( self , variant : DarwinRebuildVariant ) -> Result < ( ) > {
3638 use DarwinRebuildVariant :: { Build , Switch } ;
3739
38- // Check if we're running as root
40+ // Check if running as root
3941 platform:: check_not_root ( false ) ?;
4042
4143 if self . update_args . update {
4244 update ( & self . common . installable , self . update_args . update_input ) ?;
4345 }
4446
45- // Get the hostname
46- let ( hostname, _) = platform:: get_target_hostname ( self . hostname , false ) ?;
47+ let hostname = self . hostname . ok_or ( ( ) ) . or_else ( |( ) | get_hostname ( ) ) ?;
4748
48- // Create output path
49+ // Create temporary output path
4950 let out_path = platform:: create_output_path ( self . common . out_link , "nh-darwin" ) ?;
5051 debug ! ( ?out_path) ;
5152
52- // Use NH_DARWIN_FLAKE if available, otherwise use the provided installable
53+ // Resolve the installable from env var or from the provided argument
5354 let installable =
5455 platform:: resolve_env_installable ( "NH_DARWIN_FLAKE" , self . common . installable . clone ( ) ) ;
5556
56- // Build the configuration
57- let _target_profile = platform:: handle_rebuild_workflow (
57+ // Build the darwin configuration with proper attribute path handling
58+ let target_profile = platform:: handle_rebuild_workflow (
5859 installable,
5960 "darwinConfigurations" ,
6061 & [ "toplevel" ] ,
6162 Some ( hostname) ,
6263 out_path. as_ref ( ) ,
6364 & self . extra_args ,
64- None , // No builder
65+ None , // Darwin doesn't use remote builders
6566 "Building Darwin configuration" ,
6667 self . common . no_nom ,
67- "" , // No specialisation path for Darwin
68- false , // No specialisation
69- None , // No specialisation
68+ "" , // Darwin doesn't use specialisations like NixOS
69+ false ,
70+ None ,
7071 CURRENT_PROFILE ,
71- false , // Don't skip comparison
72+ false ,
7273 ) ?;
7374
74- if self . common . ask && !self . common . dry && !matches ! ( variant, Build ) {
75- info ! ( "Apply the config?" ) ;
76- let confirmation = dialoguer:: Confirm :: new ( ) . default ( false ) . interact ( ) ?;
77-
78- if !confirmation {
79- bail ! ( "User rejected the new config" ) ;
80- }
75+ // Allow users to confirm before applying changes
76+ if !platform:: confirm_action (
77+ self . common . ask && !matches ! ( variant, Build ) ,
78+ self . common . dry ,
79+ ) ? {
80+ return Ok ( ( ) ) ;
8181 }
8282
83- if matches ! ( variant, Switch ) && ! self . common . dry {
83+ if matches ! ( variant, Switch ) {
8484 Command :: new ( "nix" )
8585 . args ( [ "build" , "--no-link" , "--profile" , SYSTEM_PROFILE ] )
86- . arg ( out_path . get_path ( ) )
86+ . arg ( & target_profile )
8787 . elevate ( true )
8888 . dry ( self . common . dry )
8989 . run ( ) ?;
9090
91- let darwin_rebuild = out_path . get_path ( ) . join ( "sw/bin/darwin-rebuild" ) ;
92- let activate_user = out_path . get_path ( ) . join ( "activate-user" ) ;
91+ let darwin_rebuild = target_profile . join ( "sw/bin/darwin-rebuild" ) ;
92+ let activate_user = target_profile . join ( "activate-user" ) ;
9393
94- // Determine if we need to elevate privileges
95- let needs_elevation = !activate_user. try_exists ( ) . unwrap_or ( false )
94+ // Darwin activation may or may not need root privileges
95+ // This checks if we need elevation based on the activation-user script
96+ let needs_elevation = !activate_user
97+ . try_exists ( )
98+ . context ( "Failed to check if activate-user file exists" ) ?
9699 || std:: fs:: read_to_string ( & activate_user)
97- . unwrap_or_default ( )
100+ . context ( "Failed to read activate-user file" ) ?
98101 . contains ( "# nix-darwin: deprecated" ) ;
99102
100- // Create and run the activation command with or without elevation
103+ // Actually activate the configuration using darwin-rebuild
101104 Command :: new ( darwin_rebuild)
102105 . arg ( "activate" )
103106 . message ( "Activating configuration" )
@@ -108,30 +111,26 @@ impl DarwinRebuildArgs {
108111
109112 // Make sure out_path is not accidentally dropped
110113 // https://docs.rs/tempfile/3.12.0/tempfile/index.html#early-drop-pitfall
111- drop ( out_path) ;
112114
113115 Ok ( ( ) )
114116 }
115117}
116118
117119impl DarwinReplArgs {
118120 fn run ( self ) -> Result < ( ) > {
119- // Use NH_DARWIN_FLAKE if available, otherwise use the provided installable
120- let installable = platform:: resolve_env_installable ( "NH_DARWIN_FLAKE" , self . installable ) ;
121+ if let Installable :: Store { .. } = self . installable {
122+ bail ! ( "Nix doesn't support nix store installables." ) ;
123+ }
121124
122- // Get hostname for the configuration
123- let hostname = match self . hostname {
124- Some ( h) => h,
125- None => crate :: util:: get_hostname ( ) ?,
126- } ;
125+ let hostname = self . hostname . ok_or ( ( ) ) . or_else ( |( ) | get_hostname ( ) ) ?;
127126
128- // Start an interactive Nix REPL with the darwin configuration
127+ // Open an interactive REPL session for exploring darwin configurations
129128 platform:: run_repl (
130- installable,
129+ platform :: resolve_env_installable ( "NH_DARWIN_FLAKE" , self . installable ) ,
131130 "darwinConfigurations" ,
132- & [ ] , // No extra path needed
131+ & [ ] , // REPL doesn't need additional path elements
133132 Some ( hostname) ,
134- & [ ] , // No extra arguments
133+ & [ ] , // No extra REPL args
135134 )
136135 }
137136}
0 commit comments