33// SPDX-License-Identifier: MPL-2.0
44
55use log:: { debug, info, warn} ;
6- use std:: collections:: HashMap ;
76use std:: path:: Path ;
87use std:: process:: Stdio ;
98use thiserror:: Error ;
@@ -19,6 +18,8 @@ pub enum PushProfileError {
1918 ShowDerivationUtf8 ( std:: str:: Utf8Error ) ,
2019 #[ error( "Failed to parse the output of nix show-derivation: {0}" ) ]
2120 ShowDerivationParse ( serde_json:: Error ) ,
21+ #[ error( "Nix show derivation output is not an object" ) ]
22+ ShowDerivationInvalid ,
2223 #[ error( "Nix show-derivation output is empty" ) ]
2324 ShowDerivationEmpty ,
2425 #[ error( "Failed to run Nix build command: {0}" ) ]
@@ -218,13 +219,10 @@ pub async fn build_profile(data: PushProfileData<'_>) -> Result<(), PushProfileE
218219 ) ;
219220
220221 // `nix-store --query --deriver` doesn't work on invalid paths, so we parse output of show-derivation :(
221- let mut show_derivation_command = Command :: new ( "nix" ) ;
222-
223- show_derivation_command
222+ let show_derivation_output = Command :: new ( "nix" )
223+ . arg ( "--experimental-features" ) . arg ( "nix-command" )
224224 . arg ( "show-derivation" )
225- . arg ( & data. deploy_data . profile . profile_settings . path ) ;
226-
227- let show_derivation_output = show_derivation_command
225+ . arg ( & data. deploy_data . profile . profile_settings . path )
228226 . output ( )
229227 . await
230228 . map_err ( PushProfileError :: ShowDerivation ) ?;
@@ -234,12 +232,19 @@ pub async fn build_profile(data: PushProfileData<'_>) -> Result<(), PushProfileE
234232 a => return Err ( PushProfileError :: ShowDerivationExit ( a) ) ,
235233 } ;
236234
237- let derivation_info : HashMap < & str , serde_json:: value:: Value > = serde_json:: from_str (
235+ let show_derivation_json : serde_json:: value:: Value = serde_json:: from_str (
238236 std:: str:: from_utf8 ( & show_derivation_output. stdout )
239237 . map_err ( PushProfileError :: ShowDerivationUtf8 ) ?,
240238 )
241239 . map_err ( PushProfileError :: ShowDerivationParse ) ?;
242240
241+ // Nix 2.33+ nests derivations under a "derivations" key, so try to get that first
242+ let derivation_info = show_derivation_json
243+ . get ( "derivations" )
244+ . unwrap_or ( & show_derivation_json)
245+ . as_object ( )
246+ . ok_or ( PushProfileError :: ShowDerivationInvalid ) ?;
247+
243248 let deriver_key = derivation_info
244249 . keys ( )
245250 . next ( )
0 commit comments