1+ use crate :: command_executor:: CommandExecutor ;
12use std:: path:: Path ;
2- use zed_extension_api:: { process:: Output , Command , Result } ;
3-
4- pub trait CommandExecutor {
5- fn execute_bundle (
6- & self ,
7- sub_command : String ,
8- args : Vec < String > ,
9- envs : Vec < ( String , String ) > ,
10- bundle_gemfile_path : & str ,
11- ) -> Result < Output > ;
12- }
13-
14- pub struct RealCommandExecutor ;
15-
16- impl CommandExecutor for RealCommandExecutor {
17- fn execute_bundle (
18- & self ,
19- sub_command : String ,
20- args : Vec < String > ,
21- envs : Vec < ( String , String ) > ,
22- bundle_gemfile_path : & str ,
23- ) -> Result < Output > {
24- Command :: new ( "bundle" )
25- . arg ( sub_command)
26- . args ( args)
27- . envs ( envs)
28- . env ( "BUNDLE_GEMFILE" , bundle_gemfile_path)
29- . output ( )
30- }
31- }
3+ use zed_extension_api:: Result ;
324
335/// A simple wrapper around the `bundle` command.
346pub struct Bundler {
@@ -74,8 +46,19 @@ impl Bundler {
7446 . to_str ( )
7547 . ok_or_else ( || "Invalid path to Gemfile" . to_string ( ) ) ?;
7648
49+ let full_args: Vec < String > = std:: iter:: once ( cmd) . chain ( args) . collect ( ) ;
50+ let command_envs: Vec < ( String , String ) > = self
51+ . envs
52+ . iter ( )
53+ . cloned ( )
54+ . chain ( std:: iter:: once ( (
55+ "BUNDLE_GEMFILE" . to_string ( ) ,
56+ bundle_gemfile. to_string ( ) ,
57+ ) ) )
58+ . collect ( ) ;
59+
7760 self . command_executor
78- . execute_bundle ( cmd , args , self . envs . clone ( ) , bundle_gemfile )
61+ . execute ( "bundle" , full_args , command_envs )
7962 . and_then ( |output| match output. status {
8063 Some ( 0 ) => Ok ( String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) ) ,
8164 Some ( status) => {
@@ -96,14 +79,15 @@ impl Bundler {
9679#[ cfg( test) ]
9780mod tests {
9881 use super :: * ;
82+ use crate :: command_executor:: CommandExecutor ;
9983 use std:: cell:: RefCell ;
84+ use zed_extension_api:: process:: Output ;
10085
10186 struct MockExecutorConfig {
10287 output_to_return : Option < Result < Output > > ,
103- expected_sub_command : Option < String > ,
88+ expected_command_name : Option < String > ,
10489 expected_args : Option < Vec < String > > ,
10590 expected_envs : Option < Vec < ( String , String ) > > ,
106- expected_bundle_gemfile_path : Option < String > ,
10791 }
10892
10993 struct MockCommandExecutor {
@@ -115,64 +99,55 @@ mod tests {
11599 MockCommandExecutor {
116100 config : RefCell :: new ( MockExecutorConfig {
117101 output_to_return : None ,
118- expected_sub_command : None ,
102+ expected_command_name : None ,
119103 expected_args : None ,
120104 expected_envs : None ,
121- expected_bundle_gemfile_path : None ,
122105 } ) ,
123106 }
124107 }
125108
126109 fn expect (
127110 & self ,
128- sub_command : & str ,
129- args : & [ & str ] ,
130- envs : & [ ( & str , & str ) ] ,
131- bundle_gemfile_path : & str ,
132- output : super :: Result < Output > ,
111+ command_name : & str ,
112+ full_args : & [ & str ] ,
113+ final_envs : & [ ( & str , & str ) ] ,
114+ output : Result < Output > ,
133115 ) {
134116 let mut config = self . config . borrow_mut ( ) ;
135- config. expected_sub_command = Some ( sub_command . to_string ( ) ) ;
136- config. expected_args = Some ( args . iter ( ) . map ( |s| s. to_string ( ) ) . collect ( ) ) ;
117+ config. expected_command_name = Some ( command_name . to_string ( ) ) ;
118+ config. expected_args = Some ( full_args . iter ( ) . map ( |s| s. to_string ( ) ) . collect ( ) ) ;
137119 config. expected_envs = Some (
138- envs. iter ( )
120+ final_envs
121+ . iter ( )
139122 . map ( |& ( k, v) | ( k. to_string ( ) , v. to_string ( ) ) )
140123 . collect ( ) ,
141124 ) ;
142- config. expected_bundle_gemfile_path = Some ( bundle_gemfile_path. to_string ( ) ) ;
143125 config. output_to_return = Some ( output) ;
144126 }
145127 }
146128
147129 impl CommandExecutor for MockCommandExecutor {
148- fn execute_bundle (
130+ fn execute (
149131 & self ,
150- sub_command : String ,
132+ command_name : & str ,
151133 args : Vec < String > ,
152134 envs : Vec < ( String , String ) > ,
153- bundle_gemfile_path : & str ,
154- ) -> super :: Result < Output > {
135+ ) -> Result < Output > {
155136 let mut config = self . config . borrow_mut ( ) ;
156137
157- if let Some ( expected_cmd ) = & config. expected_sub_command {
158- assert_eq ! ( & sub_command , expected_cmd , "Mock: Sub-command mismatch" ) ;
138+ if let Some ( expected_name ) = & config. expected_command_name {
139+ assert_eq ! ( command_name , expected_name , "Mock: Command name mismatch" ) ;
159140 }
160141 if let Some ( expected_args) = & config. expected_args {
161142 assert_eq ! ( & args, expected_args, "Mock: Args mismatch" ) ;
162143 }
163144 if let Some ( expected_envs) = & config. expected_envs {
164145 assert_eq ! ( & envs, expected_envs, "Mock: Env mismatch" ) ;
165146 }
166- if let Some ( expected_path) = & config. expected_bundle_gemfile_path {
167- assert_eq ! (
168- bundle_gemfile_path, expected_path,
169- "Mock: Gemfile path mismatch"
170- ) ;
171- }
172147
173148 config. output_to_return . take ( ) . expect (
174- "MockCommandExecutor: output_to_return was not set or already consumed for the test" ,
175- )
149+ "MockCommandExecutor: output_to_return was not set or already consumed for the test" ,
150+ )
176151 }
177152 }
178153
@@ -182,11 +157,11 @@ mod tests {
182157 gem : & str ,
183158 ) -> MockCommandExecutor {
184159 let mock = MockCommandExecutor :: new ( ) ;
160+ let gemfile_path = format ! ( "{}/Gemfile" , dir) ;
185161 mock. expect (
186- "info" ,
187- & [ "--version" , gem] ,
188- & [ ] ,
189- & format ! ( "{}/Gemfile" , dir) ,
162+ "bundle" ,
163+ & [ "info" , "--version" , gem] ,
164+ & [ ( "BUNDLE_GEMFILE" , & gemfile_path) ] ,
190165 Ok ( Output {
191166 status : Some ( 0 ) ,
192167 stdout : version. as_bytes ( ) . to_vec ( ) ,
@@ -211,12 +186,12 @@ mod tests {
211186 let mock_executor = MockCommandExecutor :: new ( ) ;
212187 let gem_name = "unknown_gem" ;
213188 let error_output = "Could not find gem 'unknown_gem'." ;
189+ let gemfile_path = "test_dir/Gemfile" ;
214190
215191 mock_executor. expect (
216- "info" ,
217- & [ "--version" , gem_name] ,
218- & [ ] ,
219- "test_dir/Gemfile" ,
192+ "bundle" ,
193+ & [ "info" , "--version" , gem_name] ,
194+ & [ ( "BUNDLE_GEMFILE" , gemfile_path) ] ,
220195 Ok ( Output {
221196 status : Some ( 1 ) ,
222197 stdout : Vec :: new ( ) ,
@@ -247,12 +222,12 @@ mod tests {
247222 let mock_executor = MockCommandExecutor :: new ( ) ;
248223 let gem_name = "critical_gem" ;
249224 let specific_error_msg = "Mocked execution failure" ;
225+ let gemfile_path = "test_dir/Gemfile" ;
250226
251227 mock_executor. expect (
252- "info" ,
253- & [ "--version" , gem_name] ,
254- & [ ] ,
255- "test_dir/Gemfile" ,
228+ "bundle" ,
229+ & [ "info" , "--version" , gem_name] ,
230+ & [ ( "BUNDLE_GEMFILE" , gemfile_path) ] ,
256231 Err ( specific_error_msg. to_string ( ) ) ,
257232 ) ;
258233
0 commit comments