@@ -16,6 +16,7 @@ use std::os::unix::{fs::PermissionsExt, process::CommandExt};
16
16
use std:: {
17
17
fs:: { self , File } ,
18
18
path:: { Path , PathBuf } ,
19
+ process,
19
20
} ;
20
21
use tracing:: { debug, error, info, info_span, instrument, trace, warn, Instrument } ;
21
22
@@ -42,14 +43,25 @@ pub static DIRENVRC_VERSION: Lazy<u8> = Lazy::new(|| {
42
43
// project vars
43
44
const DEVENV_FLAKE : & str = ".devenv.flake.nix" ;
44
45
45
- #[ derive( Default ) ]
46
+ #[ derive( Default , Debug ) ]
46
47
pub struct DevenvOptions {
47
48
pub config : config:: Config ,
48
49
pub global_options : Option < cli:: GlobalOptions > ,
49
50
pub devenv_root : Option < PathBuf > ,
50
51
pub devenv_dotfile : Option < PathBuf > ,
51
52
}
52
53
54
+ #[ derive( Default , Debug ) ]
55
+ pub struct ProcessOptions < ' a > {
56
+ /// An optional environment map to pass to the process.
57
+ /// If not provided, the process will be executed inside a freshly evaluated shell.
58
+ pub envs : Option < & ' a HashMap < String , String > > ,
59
+ /// Whether the process should be detached from the current process.
60
+ pub detach : bool ,
61
+ /// Whether the process should be logged to a file.
62
+ pub log_to_file : bool ,
63
+ }
64
+
53
65
pub struct Devenv {
54
66
pub config : config:: Config ,
55
67
pub global_options : cli:: GlobalOptions ,
@@ -683,7 +695,7 @@ impl Devenv {
683
695
. expect ( "Failed to wait for script" ) ;
684
696
685
697
// Parse the environment variables
686
- let file = File :: open ( & script_path ) . into_diagnostic ( ) ?;
698
+ let file = File :: open ( & env_path ) . into_diagnostic ( ) ?;
687
699
let reader = BufReader :: new ( file) ;
688
700
let shell_envs = reader
689
701
. lines ( )
@@ -716,7 +728,12 @@ impl Devenv {
716
728
}
717
729
718
730
if self . has_processes ( ) . await ? {
719
- self . launch_processes ( vec ! [ ] , & envs, & true , & false ) . await ?;
731
+ let options = ProcessOptions {
732
+ envs : Some ( & envs) ,
733
+ detach : true ,
734
+ log_to_file : false ,
735
+ } ;
736
+ self . up ( vec ! [ ] , & options) . await ?;
720
737
}
721
738
722
739
let span = info_span ! ( "test" , devenv. user_message = "Running tests" ) ;
@@ -746,96 +763,6 @@ impl Devenv {
746
763
}
747
764
}
748
765
749
- pub async fn launch_processes (
750
- & mut self ,
751
- processes : Vec < String > ,
752
- envs : & std:: collections:: HashMap < String , String > ,
753
- detach : & bool ,
754
- log_to_file : & bool ,
755
- ) -> Result < ( ) > {
756
- self . assemble ( false ) . await ?;
757
- if !self . has_processes ( ) . await ? {
758
- error ! ( "No 'processes' option defined: https://devenv.sh/processes/" ) ;
759
- bail ! ( "No processes defined" ) ;
760
- }
761
-
762
- let span = info_span ! (
763
- "build_processes" ,
764
- devenv. user_message = "Building processes"
765
- ) ;
766
- let proc_script_string = async {
767
- let proc_script = self . nix . build ( & [ "procfileScript" ] , None ) . await ?;
768
- let proc_script_string = proc_script[ 0 ]
769
- . to_str ( )
770
- . expect ( "Failed to get proc script path" )
771
- . to_string ( ) ;
772
- self . nix . add_gc ( "procfilescript" , & proc_script[ 0 ] ) . await ?;
773
- Ok :: < String , miette:: Report > ( proc_script_string)
774
- }
775
- . instrument ( span)
776
- . await ?;
777
-
778
- let span = info_span ! ( "up" , devenv. user_message = "Starting processes" ) ;
779
- async {
780
- let processes = processes. join ( "" ) ;
781
-
782
- let processes_script = self . devenv_dotfile . join ( "processes" ) ;
783
- // we force disable process compose tui if detach is enabled
784
- let tui = if * detach {
785
- "export PC_TUI_ENABLED=0"
786
- } else {
787
- ""
788
- } ;
789
- fs:: write (
790
- & processes_script,
791
- indoc:: formatdoc! { "
792
- #!/usr/bin/env bash
793
- {tui}
794
- exec {proc_script_string} {processes}
795
- " } ,
796
- )
797
- . expect ( "Failed to write PROCESSES_SCRIPT" ) ;
798
-
799
- std:: fs:: set_permissions ( & processes_script, std:: fs:: Permissions :: from_mode ( 0o755 ) )
800
- . expect ( "Failed to set permissions" ) ;
801
-
802
- let mut cmd = std:: process:: Command :: new ( "bash" ) ;
803
- cmd. arg ( processes_script. to_string_lossy ( ) . to_string ( ) )
804
- . env_clear ( )
805
- . envs ( envs) ;
806
-
807
- if * detach {
808
- let log_file = std:: fs:: File :: create ( self . processes_log ( ) )
809
- . expect ( "Failed to create PROCESSES_LOG" ) ;
810
- let process = if !* log_to_file {
811
- cmd. stdout ( std:: process:: Stdio :: inherit ( ) )
812
- . stderr ( std:: process:: Stdio :: inherit ( ) )
813
- . spawn ( )
814
- . expect ( "Failed to spawn process" )
815
- } else {
816
- cmd. stdout ( log_file. try_clone ( ) . expect ( "Failed to clone Stdio" ) )
817
- . stderr ( log_file)
818
- . spawn ( )
819
- . expect ( "Failed to spawn process" )
820
- } ;
821
-
822
- std:: fs:: write ( self . processes_pid ( ) , process. id ( ) . to_string ( ) )
823
- . expect ( "Failed to write PROCESSES_PID" ) ;
824
- info ! ( "PID is {}" , process. id( ) ) ;
825
- if * log_to_file {
826
- info ! ( "See logs: $ tail -f {}" , self . processes_log( ) . display( ) ) ;
827
- }
828
- info ! ( "Stop: $ devenv processes stop" ) ;
829
- } else {
830
- let err = cmd. exec ( ) ;
831
- bail ! ( err) ;
832
- }
833
- Ok ( ( ) )
834
- }
835
- . instrument ( span)
836
- . await
837
- }
838
-
839
766
pub async fn info ( & mut self ) -> Result < ( ) > {
840
767
self . assemble ( false ) . await ?;
841
768
let output = self . nix . metadata ( ) . await ?;
@@ -892,11 +819,10 @@ impl Devenv {
892
819
. await
893
820
}
894
821
895
- pub async fn up (
822
+ pub async fn up < ' a > (
896
823
& mut self ,
897
824
processes : Vec < String > ,
898
- detach : & bool ,
899
- log_to_file : & bool ,
825
+ options : & ' a ProcessOptions < ' a > ,
900
826
) -> Result < ( ) > {
901
827
self . assemble ( false ) . await ?;
902
828
if !self . has_processes ( ) . await ? {
@@ -926,7 +852,7 @@ impl Devenv {
926
852
927
853
let processes_script = self . devenv_dotfile . join ( "processes" ) ;
928
854
// we force disable process compose tui if detach is enabled
929
- let tui = if * detach {
855
+ let tui = if options . detach {
930
856
"export PC_TUI_ENABLED=0"
931
857
} else {
932
858
""
@@ -941,21 +867,26 @@ impl Devenv {
941
867
)
942
868
. expect ( "Failed to write PROCESSES_SCRIPT" ) ;
943
869
944
- std :: fs:: set_permissions ( & processes_script, std:: fs:: Permissions :: from_mode ( 0o755 ) )
870
+ fs:: set_permissions ( & processes_script, std:: fs:: Permissions :: from_mode ( 0o755 ) )
945
871
. expect ( "Failed to set permissions" ) ;
946
872
947
- let span = info_span ! ( "Entering shell" ) ;
948
- let mut cmd = self
949
- . prepare_shell ( & Some ( processes_script. to_string_lossy ( ) . to_string ( ) ) , & [ ] )
950
- . instrument ( span)
951
- . await ?;
873
+ let mut cmd = if let Some ( envs) = options. envs {
874
+ let mut cmd = process:: Command :: new ( "bash" ) ;
875
+ cmd. arg ( processes_script. to_string_lossy ( ) . to_string ( ) )
876
+ . env_clear ( )
877
+ . envs ( envs) ;
878
+ cmd
879
+ } else {
880
+ self . prepare_shell ( & Some ( processes_script. to_string_lossy ( ) . to_string ( ) ) , & [ ] )
881
+ . await ?
882
+ } ;
952
883
953
- if * detach {
954
- let log_file = std :: fs :: File :: create ( self . processes_log ( ) )
955
- . expect ( "Failed to create PROCESSES_LOG" ) ;
956
- let process = if !* log_to_file {
957
- cmd. stdout ( std :: process:: Stdio :: inherit ( ) )
958
- . stderr ( std :: process:: Stdio :: inherit ( ) )
884
+ if options . detach {
885
+ let log_file =
886
+ fs :: File :: create ( self . processes_log ( ) ) . expect ( "Failed to create PROCESSES_LOG" ) ;
887
+ let process = if !options . log_to_file {
888
+ cmd. stdout ( process:: Stdio :: inherit ( ) )
889
+ . stderr ( process:: Stdio :: inherit ( ) )
959
890
. spawn ( )
960
891
. expect ( "Failed to spawn process" )
961
892
} else {
@@ -965,10 +896,10 @@ impl Devenv {
965
896
. expect ( "Failed to spawn process" )
966
897
} ;
967
898
968
- std :: fs:: write ( self . processes_pid ( ) , process. id ( ) . to_string ( ) )
899
+ fs:: write ( self . processes_pid ( ) , process. id ( ) . to_string ( ) )
969
900
. expect ( "Failed to write PROCESSES_PID" ) ;
970
901
info ! ( "PID is {}" , process. id( ) ) ;
971
- if * log_to_file {
902
+ if options . log_to_file {
972
903
info ! ( "See logs: $ tail -f {}" , self . processes_log( ) . display( ) ) ;
973
904
}
974
905
info ! ( "Stop: $ devenv processes stop" ) ;
0 commit comments