1- use std:: env;
2-
3- use color_eyre:: eyre:: { bail, Context } ;
1+ use color_eyre:: eyre:: bail;
2+ use color_eyre:: Result ;
43use tracing:: { debug, info, warn} ;
54
6- use crate :: commands;
75use crate :: commands:: Command ;
8- use crate :: installable:: Installable ;
96use crate :: interface:: { DarwinArgs , DarwinRebuildArgs , DarwinReplArgs , DarwinSubcommand } ;
10- use crate :: nixos:: toplevel_for;
117use crate :: update:: update;
12- use crate :: util:: get_hostname;
13- use crate :: Result ;
8+ use crate :: util:: platform;
149
1510const SYSTEM_PROFILE : & str = "/nix/var/nix/profiles/system" ;
1611const CURRENT_PROFILE : & str = "/run/current-system" ;
@@ -40,77 +35,40 @@ 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+ // Check if we're 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+ // Get the hostname
46+ let ( hostname, _) = platform:: get_target_hostname ( self . hostname , false ) ?;
6047
48+ // Create output path
49+ let out_path = platform:: create_output_path ( self . common . out_link , "nh-darwin" ) ?;
6150 debug ! ( ?out_path) ;
6251
6352 // 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 ( ) ?;
103-
104- let target_profile = out_path. get_path ( ) . to_owned ( ) ;
105-
106- target_profile. try_exists ( ) . context ( "Doesn't exist" ) ?;
107-
108- Command :: new ( "nvd" )
109- . arg ( "diff" )
110- . arg ( CURRENT_PROFILE )
111- . arg ( & target_profile)
112- . message ( "Comparing changes" )
113- . run ( ) ?;
53+ let installable = platform:: resolve_env_installable ( "NH_DARWIN_FLAKE" , self . common . installable . clone ( ) ) ;
54+
55+ // Build the configuration
56+ let _target_profile = platform:: handle_rebuild_workflow (
57+ installable,
58+ "darwinConfigurations" ,
59+ & [ "toplevel" ] ,
60+ Some ( hostname) ,
61+ out_path. as_ref ( ) ,
62+ & self . extra_args ,
63+ None , // No builder
64+ "Building Darwin configuration" ,
65+ self . common . no_nom ,
66+ "" , // No specialisation path for Darwin
67+ false , // No specialisation
68+ None , // No specialisation
69+ CURRENT_PROFILE ,
70+ false , // Don't skip comparison
71+ ) ?;
11472
11573 if self . common . ask && !self . common . dry && !matches ! ( variant, Build ) {
11674 info ! ( "Apply the config?" ) ;
@@ -121,7 +79,7 @@ impl DarwinRebuildArgs {
12179 }
12280 }
12381
124- if matches ! ( variant, Switch ) {
82+ if matches ! ( variant, Switch ) && ! self . common . dry {
12583 Command :: new ( "nix" )
12684 . args ( [ "build" , "--no-link" , "--profile" , SYSTEM_PROFILE ] )
12785 . arg ( out_path. get_path ( ) )
@@ -135,9 +93,9 @@ impl DarwinRebuildArgs {
13593 // Determine if we need to elevate privileges
13694 let needs_elevation = !activate_user
13795 . try_exists ( )
138- . context ( "Failed to check if activate-user file exists" ) ?
96+ . unwrap_or ( false )
13997 || std:: fs:: read_to_string ( & activate_user)
140- . context ( "Failed to read activate-user file" ) ?
98+ . unwrap_or_default ( )
14199 . contains ( "# nix-darwin: deprecated" ) ;
142100
143101 // Create and run the activation command with or without elevation
@@ -160,45 +118,21 @@ impl DarwinRebuildArgs {
160118impl DarwinReplArgs {
161119 fn run ( self ) -> Result < ( ) > {
162120 // 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- }
121+ let installable = platform:: resolve_env_installable ( "NH_DARWIN_FLAKE" , self . installable ) ;
184122
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 ( ) ?;
123+ // Get hostname for the configuration
124+ let hostname = match self . hostname {
125+ Some ( h) => h,
126+ None => crate :: util:: get_hostname ( ) ?,
127+ } ;
201128
202- Ok ( ( ) )
129+ // Start an interactive Nix REPL with the darwin configuration
130+ platform:: run_repl (
131+ installable,
132+ "darwinConfigurations" ,
133+ & [ ] , // No extra path needed
134+ Some ( hostname) ,
135+ & [ ] , // No extra arguments
136+ )
203137 }
204138}
0 commit comments