@@ -3,18 +3,18 @@ use clap::crate_version;
3
3
use cli_table:: Table ;
4
4
use cli_table:: { print_stderr, WithTitle } ;
5
5
use include_dir:: { include_dir, Dir } ;
6
- use miette:: { bail, IntoDiagnostic , Result } ;
6
+ use miette:: { bail, Context , IntoDiagnostic , Result } ;
7
7
use nix:: sys:: signal;
8
8
use nix:: unistd:: Pid ;
9
9
use once_cell:: sync:: Lazy ;
10
10
use serde:: Deserialize ;
11
11
use sha2:: Digest ;
12
12
use similar:: { ChangeTag , TextDiff } ;
13
- use std:: collections:: BTreeMap ;
14
- use std:: io:: Write ;
13
+ use std:: collections:: { BTreeMap , HashMap } ;
14
+ use std:: io:: { BufRead , BufReader , Write } ;
15
15
use std:: os:: unix:: { fs:: PermissionsExt , process:: CommandExt } ;
16
16
use std:: {
17
- fs,
17
+ fs:: { self , File } ,
18
18
path:: { Path , PathBuf } ,
19
19
} ;
20
20
use tracing:: { debug, error, info, info_span, instrument, trace, warn, Instrument } ;
@@ -301,17 +301,18 @@ impl Devenv {
301
301
302
302
let config_clean = self . config . clean . clone ( ) . unwrap_or_default ( ) ;
303
303
if self . global_options . clean . is_some ( ) || config_clean. enabled {
304
- shell_cmd. env_clear ( ) ;
305
-
306
304
let keep = match & self . global_options . clean {
307
305
Some ( clean) => clean,
308
306
None => & config_clean. keep ,
309
307
} ;
310
308
311
309
let filtered_env = std:: env:: vars ( ) . filter ( |( k, _) | keep. contains ( k) ) ;
312
310
313
- shell_cmd. envs ( filtered_env) ;
314
- shell_cmd. arg ( "--norc" ) . arg ( "--noprofile" ) ;
311
+ shell_cmd
312
+ . env_clear ( )
313
+ . envs ( filtered_env)
314
+ . arg ( "--norc" )
315
+ . arg ( "--noprofile" ) ;
315
316
}
316
317
317
318
shell_cmd. env ( "SHELL" , & bash) ;
@@ -655,43 +656,75 @@ impl Devenv {
655
656
} ;
656
657
let test_script = test_script[ 0 ] . to_string_lossy ( ) . to_string ( ) ;
657
658
659
+ let temp_dir = tempfile:: TempDir :: with_prefix ( "devenv-test" ) . into_diagnostic ( ) ?;
660
+
661
+ let script_path = temp_dir. path ( ) . join ( "script" ) ;
662
+ let env_path = temp_dir. path ( ) . join ( "env" ) ;
663
+
664
+ let script = format ! ( "env > {}" , env_path. to_string_lossy( ) ) ;
665
+ fs:: write ( & script_path, script)
666
+ . into_diagnostic ( )
667
+ . wrap_err ( format ! (
668
+ "Failed to write script to {}" ,
669
+ script_path. display( )
670
+ ) ) ?;
671
+ fs:: set_permissions ( & script_path, fs:: Permissions :: from_mode ( 0o755 ) )
672
+ . into_diagnostic ( )
673
+ . wrap_err ( "Change permissions" ) ?;
674
+
658
675
// Run script and capture its environment exports
659
- let output = self
660
- . prepare_shell ( & Some ( "env" . to_string ( ) ) , & [ ] )
676
+ self . prepare_shell ( & Some ( script_path. to_string_lossy ( ) . into ( ) ) , & [ ] )
661
677
. await ?
662
- . env ( "CLICOLOR_FORCE" , "1" )
663
678
. stderr ( std:: process:: Stdio :: inherit ( ) )
664
- . stdout ( std:: process:: Stdio :: piped ( ) )
679
+ . stdout ( std:: process:: Stdio :: inherit ( ) )
665
680
. spawn ( )
666
681
. expect ( "Failed to execute script" )
667
- . wait_with_output ( )
682
+ . wait ( )
668
683
. expect ( "Failed to wait for script" ) ;
669
684
670
- let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
671
685
// Parse the environment variables
672
- let env_vars = stdout. lines ( ) . filter_map ( |line| {
673
- let parts: Vec < & str > = line. splitn ( 2 , '=' ) . collect ( ) ;
674
- if parts. len ( ) == 2 {
675
- Some ( ( parts[ 0 ] , parts[ 1 ] ) )
686
+ let file = File :: open ( & script_path) . into_diagnostic ( ) ?;
687
+ let reader = BufReader :: new ( file) ;
688
+ let shell_envs = reader
689
+ . lines ( )
690
+ . map_while ( Result :: ok)
691
+ . filter_map ( |line| {
692
+ let mut parts = line. splitn ( 2 , '=' ) ;
693
+ match ( parts. next ( ) , parts. next ( ) ) {
694
+ ( Some ( key) , Some ( value) ) => Some ( ( key. to_string ( ) , value. to_string ( ) ) ) ,
695
+ _ => None ,
696
+ }
697
+ } )
698
+ . collect :: < Vec < _ > > ( ) ;
699
+
700
+ let config_clean = self . config . clean . clone ( ) . unwrap_or_default ( ) ;
701
+ let mut envs: HashMap < String , String > = {
702
+ let vars = std:: env:: vars ( ) ;
703
+ if self . global_options . clean . is_some ( ) || config_clean. enabled {
704
+ let keep = match & self . global_options . clean {
705
+ Some ( clean) => clean,
706
+ None => & config_clean. keep ,
707
+ } ;
708
+ vars. filter ( |( key, _) | !keep. contains ( key) ) . collect ( )
676
709
} else {
677
- None
710
+ vars . collect ( )
678
711
}
679
- } ) ;
712
+ } ;
680
713
681
- // TODO: clean && keep
682
- // Set environment variables for current process
683
- for ( key, value) in env_vars {
684
- std:: env:: set_var ( key, value) ;
714
+ for ( key, value) in shell_envs {
715
+ envs. insert ( key, value) ;
685
716
}
686
717
687
718
if self . has_processes ( ) . await ? {
688
- self . launch_processes ( vec ! [ ] , & true , & false ) . await ?;
719
+ self . launch_processes ( vec ! [ ] , & envs , & true , & false ) . await ?;
689
720
}
690
721
691
722
let span = info_span ! ( "test" , devenv. user_message = "Running tests" ) ;
692
723
let result = async {
693
724
debug ! ( "Running command: {test_script}" ) ;
694
725
std:: process:: Command :: new ( test_script)
726
+ . env_clear ( )
727
+ . envs ( envs)
695
728
. spawn ( )
696
729
. unwrap ( )
697
730
. wait_with_output ( )
@@ -716,6 +749,7 @@ impl Devenv {
716
749
pub async fn launch_processes (
717
750
& mut self ,
718
751
processes : Vec < String > ,
752
+ envs : & std:: collections:: HashMap < String , String > ,
719
753
detach : & bool ,
720
754
log_to_file : & bool ,
721
755
) -> Result < ( ) > {
@@ -765,9 +799,10 @@ impl Devenv {
765
799
std:: fs:: set_permissions ( & processes_script, std:: fs:: Permissions :: from_mode ( 0o755 ) )
766
800
. expect ( "Failed to set permissions" ) ;
767
801
768
- // let span = info_span!("Entering shell");
769
802
let mut cmd = std:: process:: Command :: new ( "bash" ) ;
770
- cmd. arg ( processes_script. to_string_lossy ( ) . to_string ( ) ) ;
803
+ cmd. arg ( processes_script. to_string_lossy ( ) . to_string ( ) )
804
+ . env_clear ( )
805
+ . envs ( envs) ;
771
806
772
807
if * detach {
773
808
let log_file = std:: fs:: File :: create ( self . processes_log ( ) )
0 commit comments