@@ -7,7 +7,7 @@ use std::path::Path;
77use std:: process:: { Command , CommandArgs , CommandEnvs } ;
88use std:: { env, iter} ;
99
10- use anyhow:: Context ;
10+ use anyhow:: { Context , Result } ;
1111
1212use crate :: CargoCommandExt ;
1313use crate :: cargo:: { CargoCmd as _, cargo} ;
@@ -28,10 +28,10 @@ use crate::cargo::{CargoCmd as _, cargo};
2828///
2929/// Basic usage:
3030///
31- /// ```rust
31+ /// ```rust,no_run
3232/// use cargo_hyperlight::CargoCommand;
3333///
34- /// let mut command = CargoCommand::new();
34+ /// let mut command = CargoCommand::new().unwrap() ;
3535/// command.arg("build").arg("--release");
3636/// command.exec(); // This will replace the current process
3737/// ```
@@ -41,7 +41,7 @@ use crate::cargo::{CargoCmd as _, cargo};
4141/// ```rust
4242/// use cargo_hyperlight::CargoCommand;
4343///
44- /// let mut command = CargoCommand::new();
44+ /// let mut command = CargoCommand::new().unwrap() ;
4545/// command
4646/// .current_dir("/path/to/project")
4747/// .env("CARGO_TARGET_DIR", "/custom/target")
@@ -58,17 +58,11 @@ impl Debug for CargoCommand {
5858 }
5959}
6060
61- impl Default for CargoCommand {
62- fn default ( ) -> Self {
63- Self :: new ( )
64- }
65- }
66-
6761impl CargoCommand {
6862 /// Constructs a new `CargoCommand` for launching the cargo program.
6963 ///
7064 /// The value of the `CARGO` environment variable is used if it is set; otherwise, the
71- /// default `cargo` from binary ` PATH` is used.
65+ /// default `cargo` from the system PATH is used.
7266 /// If `RUSTUP_TOOLCHAIN` is set in the environment, it is also propagated to the
7367 /// child process to ensure correct functioning of the rustup wrappers.
7468 ///
@@ -77,34 +71,42 @@ impl CargoCommand {
7771 /// - Inherits the current process's environment
7872 /// - Inherits the current process's working directory
7973 ///
74+ /// # Errors
75+ ///
76+ /// This function will return an error if:
77+ /// - If the `CARGO` environment variable is set but it specifies an invalid path
78+ /// - If the `CARGO` environment variable is not set and the `cargo` program cannot be found in the system PATH
79+ ///
8080 /// # Examples
8181 ///
8282 /// Basic usage:
8383 ///
8484 /// ```rust
8585 /// use cargo_hyperlight::CargoCommand;
8686 ///
87- /// let command = CargoCommand::new();
87+ /// let command = CargoCommand::new().unwrap() ;
8888 /// ```
89- pub fn new ( ) -> Self {
90- CargoCommand {
91- command : cargo ( ) ,
89+ pub fn new ( ) -> Result < Self > {
90+ Ok ( CargoCommand {
91+ command : cargo ( ) ? ,
9292 clear_env : false ,
93- }
93+ } )
9494 }
9595
9696 /// Adds an argument to pass to the cargo program.
9797 ///
9898 /// Only one argument can be passed per use. So instead of:
9999 ///
100100 /// ```no_run
101- /// command.arg("-C /path/to/repo");
101+ /// # let mut command = cargo_hyperlight::CargoCommand::new().unwrap();
102+ /// command.arg("--features some_feature");
102103 /// ```
103104 ///
104105 /// usage would be:
105106 ///
106107 /// ```no_run
107- /// command.arg("-C").arg("/path/to/repo");
108+ /// # let mut command = cargo_hyperlight::CargoCommand::new().unwrap();
109+ /// command.arg("--features").arg("some_feature");
108110 /// ```
109111 ///
110112 /// To pass multiple arguments see [`args`].
@@ -123,9 +125,10 @@ impl CargoCommand {
123125 /// use cargo_hyperlight::CargoCommand;
124126 ///
125127 /// CargoCommand::new()
126- /// .arg("build")
127- /// .arg("--release")
128- /// .exec();
128+ /// .unwrap()
129+ /// .arg("build")
130+ /// .arg("--release")
131+ /// .exec();
129132 /// ```
130133 pub fn arg ( & mut self , arg : impl AsRef < OsStr > ) -> & mut Self {
131134 self . command . arg ( arg. as_ref ( ) ) ;
@@ -150,16 +153,9 @@ impl CargoCommand {
150153 /// use cargo_hyperlight::CargoCommand;
151154 ///
152155 /// CargoCommand::new()
153- /// .args(["build", "--release"])
154- /// .exec();
155- /// ```
156- ///
157- /// ```no_run
158- /// use cargo_hyperlight::CargoCommand;
159- ///
160- /// CargoCommand::new()
161- /// .args(&["build", "--release"])
162- /// .exec();
156+ /// .unwrap()
157+ /// .args(["build", "--release"])
158+ /// .exec();
163159 /// ```
164160 pub fn args ( & mut self , args : impl IntoIterator < Item = impl AsRef < OsStr > > ) -> & mut Self {
165161 self . command . args ( args) ;
@@ -168,14 +164,6 @@ impl CargoCommand {
168164
169165 /// Sets the working directory for the child process.
170166 ///
171- /// # Platform-specific behavior
172- ///
173- /// If the program path is relative (e.g., `"./script.sh"`), it's ambiguous
174- /// whether it should be interpreted relative to the parent's working
175- /// directory or relative to `current_dir`. The behavior in this case is
176- /// platform specific and unstable, and it's recommended to use
177- /// [`canonicalize`] to get an absolute program path instead.
178- ///
179167 /// # Examples
180168 ///
181169 /// Basic usage:
@@ -184,9 +172,10 @@ impl CargoCommand {
184172 /// use cargo_hyperlight::CargoCommand;
185173 ///
186174 /// CargoCommand::new()
187- /// .current_dir("/bin")
188- /// .arg("build")
189- /// .exec();
175+ /// .unwrap()
176+ /// .current_dir("path/to/project")
177+ /// .arg("build")
178+ /// .exec();
190179 /// ```
191180 ///
192181 /// [`canonicalize`]: std::fs::canonicalize
@@ -201,9 +190,9 @@ impl CargoCommand {
201190 /// or overwrite a variable if it already exists.
202191 ///
203192 /// Child processes will inherit environment variables from their parent process by
204- /// default (unless [`env_clear`] is used), including variables set with this method.
205- /// Environment variable mappings added or updated with this method will take
206- /// precedence over inherited variables .
193+ /// default. Environment variables explicitly set using [`env`] take precedence
194+ /// over inherited variables. You can disable environment variable inheritance entirely
195+ /// using [`env_clear`] or for a single key using [`env_remove`] .
207196 ///
208197 /// Note that environment variable names are case-insensitive (but
209198 /// case-preserving) on Windows and case-sensitive on all other platforms.
@@ -216,12 +205,15 @@ impl CargoCommand {
216205 /// use cargo_hyperlight::CargoCommand;
217206 ///
218207 /// CargoCommand::new()
219- /// .env("PATH", "/bin")
220- /// .arg("build")
221- /// .exec();
208+ /// .unwrap()
209+ /// .env("CARGO_TARGET_DIR", "/path/to/target")
210+ /// .arg("build")
211+ /// .exec();
222212 /// ```
223213 ///
214+ /// [`env`]: CargoCommand::env
224215 /// [`env_clear`]: CargoCommand::env_clear
216+ /// [`env_remove`]: CargoCommand::env_remove
225217 pub fn env ( & mut self , key : impl AsRef < OsStr > , value : impl AsRef < OsStr > ) -> & mut Self {
226218 self . command . env ( key, value) ;
227219 self
@@ -232,6 +224,8 @@ impl CargoCommand {
232224 /// This method will remove all environment variables from the child process,
233225 /// including those that would normally be inherited from the parent process.
234226 /// Environment variables can be added back individually using [`env`].
227+ ///
228+ /// If `RUSTUP_TOOLCHAIN` was set in the parent process, it will be preserved.
235229 ///
236230 /// # Examples
237231 ///
@@ -241,10 +235,11 @@ impl CargoCommand {
241235 /// use cargo_hyperlight::CargoCommand;
242236 ///
243237 /// CargoCommand::new()
244- /// .env_clear()
245- /// .env("PATH", "/bin")
246- /// .arg("build")
247- /// .exec();
238+ /// .unwrap()
239+ /// .env_clear()
240+ /// .env("CARGO_TARGET_DIR", "/path/to/target")
241+ /// .arg("build")
242+ /// .exec();
248243 /// ```
249244 ///
250245 /// [`env`]: CargoCommand::env
@@ -280,9 +275,10 @@ impl CargoCommand {
280275 /// use cargo_hyperlight::CargoCommand;
281276 ///
282277 /// CargoCommand::new()
283- /// .env_remove("PATH")
284- /// .arg("build")
285- /// .exec();
278+ /// .unwrap()
279+ /// .env_remove("CARGO_TARGET_DIR")
280+ /// .arg("build")
281+ /// .exec();
286282 /// ```
287283 pub fn env_remove ( & mut self , key : impl AsRef < OsStr > ) -> & mut Self {
288284 self . command . env_remove ( key) ;
@@ -297,9 +293,9 @@ impl CargoCommand {
297293 /// implementing `IntoIterator` with the appropriate item type.
298294 ///
299295 /// Child processes will inherit environment variables from their parent process by
300- /// default (unless [`env_clear`] is used), including variables set with this method.
301- /// Environment variable mappings added or updated with this method will take
302- /// precedence over inherited variables .
296+ /// default. Environment variables explicitly set using [`env`] take precedence
297+ /// over inherited variables. You can disable environment variable inheritance entirely
298+ /// using [`env_clear`] or for a single key using [`env_remove`] .
303299 ///
304300 /// Note that environment variable names are case-insensitive (but
305301 /// case-preserving) on Windows and case-sensitive on all other platforms.
@@ -313,25 +309,32 @@ impl CargoCommand {
313309 /// use cargo_hyperlight::CargoCommand;
314310 ///
315311 /// let mut envs = HashMap::new();
316- /// envs.insert("PATH ", "/bin ");
317- /// envs.insert("CARGO_HOME", "/tmp/ cargo");
312+ /// envs.insert("CARGO_TARGET_DIR ", "/path/to/target ");
313+ /// envs.insert("CARGO_HOME", "/path/to/. cargo");
318314 ///
319315 /// CargoCommand::new()
320- /// .envs(&envs)
321- /// .arg("build")
322- /// .exec();
316+ /// .unwrap()
317+ /// .envs(&envs)
318+ /// .arg("build")
319+ /// .exec();
323320 /// ```
324321 ///
325322 /// ```no_run
326323 /// use cargo_hyperlight::CargoCommand;
327324 ///
328325 /// CargoCommand::new()
329- /// .envs([("PATH", "/bin"), ("CARGO_HOME", "/tmp/cargo")])
330- /// .arg("build")
331- /// .exec();
326+ /// .unwrap()
327+ /// .envs([
328+ /// ("CARGO_TARGET_DIR", "/path/to/target"),
329+ /// ("CARGO_HOME", "/path/to/.cargo"),
330+ /// ])
331+ /// .arg("build")
332+ /// .exec();
332333 /// ```
333334 ///
335+ /// [`env`]: CargoCommand::env
334336 /// [`env_clear`]: CargoCommand::env_clear
337+ /// [`env_remove`]: CargoCommand::env_remove
335338 pub fn envs (
336339 & mut self ,
337340 envs : impl IntoIterator < Item = ( impl AsRef < OsStr > , impl AsRef < OsStr > ) > ,
@@ -350,7 +353,7 @@ impl CargoCommand {
350353 /// ```no_run
351354 /// use cargo_hyperlight::CargoCommand;
352355 ///
353- /// let mut command = CargoCommand::new();
356+ /// let mut command = CargoCommand::new().unwrap() ;
354357 /// command.arg("build").arg("--release");
355358 ///
356359 /// let args: Vec<&std::ffi::OsStr> = command.get_args().collect();
@@ -373,11 +376,11 @@ impl CargoCommand {
373376 /// use std::path::Path;
374377 /// use cargo_hyperlight::CargoCommand;
375378 ///
376- /// let mut command = CargoCommand::new();
379+ /// let mut command = CargoCommand::new().unwrap() ;
377380 /// assert_eq!(command.get_current_dir(), None);
378381 ///
379- /// command.current_dir("/bin ");
380- /// assert_eq!(command.get_current_dir(), Some(Path::new("/bin ")));
382+ /// command.current_dir("/tmp ");
383+ /// assert_eq!(command.get_current_dir(), Some(Path::new("/tmp ")));
381384 /// ```
382385 pub fn get_current_dir ( & self ) -> Option < & Path > {
383386 self . command . get_current_dir ( )
@@ -400,9 +403,9 @@ impl CargoCommand {
400403 /// use std::ffi::OsStr;
401404 /// use cargo_hyperlight::CargoCommand;
402405 ///
403- /// let mut command = CargoCommand::new();
404- /// command.env("CARGO_HOME", "/tmp/ cargo");
405- /// command.env_remove("PATH ");
406+ /// let mut command = CargoCommand::new().unwrap() ;
407+ /// command.env("CARGO_HOME", "/path/to/. cargo");
408+ /// command.env_remove("CARGO_TARGET_DIR ");
406409 ///
407410 /// for (key, value) in command.get_envs() {
408411 /// println!("{key:?} => {value:?}");
@@ -444,8 +447,8 @@ impl CargoCommand {
444447 /// ```no_run
445448 /// use cargo_hyperlight::CargoCommand;
446449 ///
447- /// let command = CargoCommand::new();
448- /// println!("Program: {}", command.get_program().to_string_lossy ());
450+ /// let command = CargoCommand::new().unwrap() ;
451+ /// println!("Program: {:? }", command.get_program());
449452 /// ```
450453 pub fn get_program ( & self ) -> & OsStr {
451454 self . command . get_program ( )
@@ -463,7 +466,7 @@ impl CargoCommand {
463466 /// Executes a cargo command as a child process, waiting for it to finish and
464467 /// collecting its exit status.
465468 ///
466- /// By default, stdin, stdout and stderr are inherited from the parent.
469+ /// The process stdin, stdout and stderr are inherited from the parent.
467470 ///
468471 /// # Examples
469472 ///
@@ -473,6 +476,7 @@ impl CargoCommand {
473476 /// use cargo_hyperlight::CargoCommand;
474477 ///
475478 /// let result = CargoCommand::new()
479+ /// .unwrap()
476480 /// .arg("build")
477481 /// .status();
478482 ///
@@ -510,6 +514,7 @@ impl CargoCommand {
510514 /// use cargo_hyperlight::CargoCommand;
511515 ///
512516 /// CargoCommand::new()
517+ /// .unwrap()
513518 /// .arg("build")
514519 /// .exec(); // This will never return
515520 /// ```
0 commit comments