Skip to content

Commit 8881003

Browse files
committed
Move ProcessBuilder to cargo-util.
1 parent 6693403 commit 8881003

36 files changed

+347
-294
lines changed

.github/workflows/main.yml

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ jobs:
6666
- run: cargo test --features 'deny-warnings'
6767
- run: cargo test --features 'deny-warnings' -p cargo-test-support
6868
- run: cargo test -p cargo-platform
69+
- run: cargo test -p cargo-util
6970
- run: cargo test --manifest-path crates/mdman/Cargo.toml
7071
- run: cargo build --manifest-path crates/credential/cargo-credential-1password/Cargo.toml
7172
- run: cargo build --manifest-path crates/credential/cargo-credential-gnome-secret/Cargo.toml

Cargo.toml

-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ semver = { version = "0.10", features = ["serde"] }
5656
serde = { version = "1.0.123", features = ["derive"] }
5757
serde_ignored = "0.1.0"
5858
serde_json = { version = "1.0.30", features = ["raw_value"] }
59-
shell-escape = "0.1.4"
6059
strip-ansi-escapes = "0.1.0"
6160
tar = { version = "0.4.26", default-features = false }
6261
tempfile = "3.0"
@@ -80,7 +79,6 @@ rand = "0.8.3"
8079
core-foundation = { version = "0.9.0", features = ["mac_os_10_7_support"] }
8180

8281
[target.'cfg(windows)'.dependencies]
83-
miow = "0.3.6"
8482
fwdansi = "1.1.0"
8583

8684
[target.'cfg(windows)'.dependencies.winapi]

crates/cargo-test-support/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ doctest = false
1111
[dependencies]
1212
cargo = { path = "../.." }
1313
cargo-test-macro = { path = "../cargo-test-macro" }
14+
cargo-util = { path = "../cargo-util" }
1415
filetime = "0.2"
1516
flate2 = { version = "1.0", default-features = false, features = ["zlib"] }
1617
git2 = "0.13.16"

crates/cargo-test-support/src/cross_compile.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
//! These tests are all disabled on rust-lang/rust's CI, but run in Cargo's CI.
1111
1212
use crate::{basic_manifest, main_file, project};
13-
use cargo::util::ProcessError;
1413
use cargo::CargoResult;
14+
use cargo_util::ProcessError;
1515
use std::env;
1616
use std::fmt::Write;
1717
use std::process::{Command, Output};

crates/cargo-test-support/src/lib.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use std::process::{Command, Output};
1515
use std::str;
1616
use std::time::{self, Duration};
1717

18-
use cargo::util::{is_ci, CargoResult, ProcessBuilder, ProcessError, Rustc};
18+
use cargo::util::{is_ci, CargoResult, Rustc};
19+
use cargo_util::{ProcessBuilder, ProcessError};
1920
use serde_json::{self, Value};
2021
use url::Url;
2122

@@ -1569,12 +1570,12 @@ pub fn is_nightly() -> bool {
15691570
.with(|r| r.verbose_version.contains("-nightly") || r.verbose_version.contains("-dev"))
15701571
}
15711572

1572-
pub fn process<T: AsRef<OsStr>>(t: T) -> cargo::util::ProcessBuilder {
1573+
pub fn process<T: AsRef<OsStr>>(t: T) -> ProcessBuilder {
15731574
_process(t.as_ref())
15741575
}
15751576

1576-
fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
1577-
let mut p = cargo::util::process(t);
1577+
fn _process(t: &OsStr) -> ProcessBuilder {
1578+
let mut p = ProcessBuilder::new(t);
15781579

15791580
// In general just clear out all cargo-specific configuration already in the
15801581
// environment. Our tests all assume a "default configuration" unless
@@ -1643,7 +1644,7 @@ pub trait ChannelChanger: Sized {
16431644
fn masquerade_as_nightly_cargo(&mut self) -> &mut Self;
16441645
}
16451646

1646-
impl ChannelChanger for cargo::util::ProcessBuilder {
1647+
impl ChannelChanger for ProcessBuilder {
16471648
fn masquerade_as_nightly_cargo(&mut self) -> &mut Self {
16481649
self.env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "nightly")
16491650
}

crates/cargo-util/Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,11 @@ repository = "https://github.com/rust-lang/cargo"
99
description = "Miscellaneous support code used by Cargo."
1010

1111
[dependencies]
12+
anyhow = "1.0"
13+
jobserver = "0.1.21"
14+
libc = "0.2"
15+
shell-escape = "0.1.4"
16+
17+
[target.'cfg(windows)'.dependencies]
18+
miow = "0.3.6"
19+
winapi = { version = "0.3", features = ["consoleapi", "minwindef"] }

crates/cargo-util/LICENSE-APACHE

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE-APACHE

crates/cargo-util/LICENSE-MIT

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE-MIT

crates/cargo-util/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
11
//! Miscellaneous support code used by Cargo.
2+
3+
pub use self::read2::read2;
4+
pub use process_builder::ProcessBuilder;
5+
pub use process_error::{exit_status_to_string, is_simple_exit_code, ProcessError};
6+
7+
mod process_builder;
8+
mod process_error;
9+
mod read2;

src/cargo/util/process_builder.rs crates/cargo-util/src/process_builder.rs

+45-42
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use crate::util::{process_error, read2, CargoResult, CargoResultExt};
2-
use anyhow::bail;
1+
use crate::process_error::ProcessError;
2+
use crate::read2;
3+
use anyhow::{bail, Context, Result};
34
use jobserver::Client;
45
use shell_escape::escape;
56
use std::collections::BTreeMap;
@@ -10,7 +11,7 @@ use std::iter::once;
1011
use std::path::Path;
1112
use std::process::{Command, Output, Stdio};
1213

13-
/// A builder object for an external process, similar to `std::process::Command`.
14+
/// A builder object for an external process, similar to [`std::process::Command`].
1415
#[derive(Clone, Debug)]
1516
pub struct ProcessBuilder {
1617
/// The program to execute.
@@ -21,10 +22,10 @@ pub struct ProcessBuilder {
2122
env: BTreeMap<String, Option<OsString>>,
2223
/// The directory to run the program from.
2324
cwd: Option<OsString>,
24-
/// The `make` jobserver. See the [jobserver crate][jobserver_docs] for
25+
/// The `make` jobserver. See the [jobserver crate] for
2526
/// more information.
2627
///
27-
/// [jobserver_docs]: https://docs.rs/jobserver/0.1.6/jobserver/
28+
/// [jobserver crate]: https://docs.rs/jobserver/
2829
jobserver: Option<Client>,
2930
/// `true` to include environment variable in display.
3031
display_env_vars: bool,
@@ -58,6 +59,18 @@ impl fmt::Display for ProcessBuilder {
5859
}
5960

6061
impl ProcessBuilder {
62+
/// Creates a new [`ProcessBuilder`] with the given executable path.
63+
pub fn new<T: AsRef<OsStr>>(cmd: T) -> ProcessBuilder {
64+
ProcessBuilder {
65+
program: cmd.as_ref().to_os_string(),
66+
args: Vec::new(),
67+
cwd: None,
68+
env: BTreeMap::new(),
69+
jobserver: None,
70+
display_env_vars: false,
71+
}
72+
}
73+
6174
/// (chainable) Sets the executable for the process.
6275
pub fn program<T: AsRef<OsStr>>(&mut self, program: T) -> &mut ProcessBuilder {
6376
self.program = program.as_ref().to_os_string();
@@ -149,16 +162,16 @@ impl ProcessBuilder {
149162
}
150163

151164
/// Runs the process, waiting for completion, and mapping non-success exit codes to an error.
152-
pub fn exec(&self) -> CargoResult<()> {
165+
pub fn exec(&self) -> Result<()> {
153166
let mut command = self.build_command();
154-
let exit = command.status().chain_err(|| {
155-
process_error(&format!("could not execute process {}", self), None, None)
167+
let exit = command.status().with_context(|| {
168+
ProcessError::new(&format!("could not execute process {}", self), None, None)
156169
})?;
157170

158171
if exit.success() {
159172
Ok(())
160173
} else {
161-
Err(process_error(
174+
Err(ProcessError::new(
162175
&format!("process didn't exit successfully: {}", self),
163176
Some(exit),
164177
None,
@@ -182,22 +195,22 @@ impl ProcessBuilder {
182195
/// include our child process. If the child terminates then we'll reap them in Cargo
183196
/// pretty quickly, and if the child handles the signal then we won't terminate
184197
/// (and we shouldn't!) until the process itself later exits.
185-
pub fn exec_replace(&self) -> CargoResult<()> {
198+
pub fn exec_replace(&self) -> Result<()> {
186199
imp::exec_replace(self)
187200
}
188201

189202
/// Executes the process, returning the stdio output, or an error if non-zero exit status.
190-
pub fn exec_with_output(&self) -> CargoResult<Output> {
203+
pub fn exec_with_output(&self) -> Result<Output> {
191204
let mut command = self.build_command();
192205

193-
let output = command.output().chain_err(|| {
194-
process_error(&format!("could not execute process {}", self), None, None)
206+
let output = command.output().with_context(|| {
207+
ProcessError::new(&format!("could not execute process {}", self), None, None)
195208
})?;
196209

197210
if output.status.success() {
198211
Ok(output)
199212
} else {
200-
Err(process_error(
213+
Err(ProcessError::new(
201214
&format!("process didn't exit successfully: {}", self),
202215
Some(output.status),
203216
Some(&output),
@@ -217,10 +230,10 @@ impl ProcessBuilder {
217230
/// output.
218231
pub fn exec_with_streaming(
219232
&self,
220-
on_stdout_line: &mut dyn FnMut(&str) -> CargoResult<()>,
221-
on_stderr_line: &mut dyn FnMut(&str) -> CargoResult<()>,
233+
on_stdout_line: &mut dyn FnMut(&str) -> Result<()>,
234+
on_stderr_line: &mut dyn FnMut(&str) -> Result<()>,
222235
capture_output: bool,
223-
) -> CargoResult<Output> {
236+
) -> Result<Output> {
224237
let mut stdout = Vec::new();
225238
let mut stderr = Vec::new();
226239

@@ -274,7 +287,9 @@ impl ProcessBuilder {
274287
})?;
275288
child.wait()
276289
})()
277-
.chain_err(|| process_error(&format!("could not execute process {}", self), None, None))?;
290+
.with_context(|| {
291+
ProcessError::new(&format!("could not execute process {}", self), None, None)
292+
})?;
278293
let output = Output {
279294
status,
280295
stdout,
@@ -284,14 +299,14 @@ impl ProcessBuilder {
284299
{
285300
let to_print = if capture_output { Some(&output) } else { None };
286301
if let Some(e) = callback_error {
287-
let cx = process_error(
302+
let cx = ProcessError::new(
288303
&format!("failed to parse process output: {}", self),
289304
Some(output.status),
290305
to_print,
291306
);
292307
bail!(anyhow::Error::new(cx).context(e));
293308
} else if !output.status.success() {
294-
bail!(process_error(
309+
bail!(ProcessError::new(
295310
&format!("process didn't exit successfully: {}", self),
296311
Some(output.status),
297312
to_print,
@@ -333,9 +348,9 @@ impl ProcessBuilder {
333348
/// # Examples
334349
///
335350
/// ```rust
336-
/// use cargo::util::{ProcessBuilder, process};
351+
/// use cargo_util::ProcessBuilder;
337352
/// // Running this would execute `rustc`
338-
/// let cmd: ProcessBuilder = process("rustc");
353+
/// let cmd = ProcessBuilder::new("rustc");
339354
///
340355
/// // Running this will execute `sccache rustc`
341356
/// let cmd = cmd.wrapped(Some("sccache"));
@@ -360,28 +375,16 @@ impl ProcessBuilder {
360375
}
361376
}
362377

363-
/// A helper function to create a `ProcessBuilder`.
364-
pub fn process<T: AsRef<OsStr>>(cmd: T) -> ProcessBuilder {
365-
ProcessBuilder {
366-
program: cmd.as_ref().to_os_string(),
367-
args: Vec::new(),
368-
cwd: None,
369-
env: BTreeMap::new(),
370-
jobserver: None,
371-
display_env_vars: false,
372-
}
373-
}
374-
375378
#[cfg(unix)]
376379
mod imp {
377-
use crate::util::{process_error, ProcessBuilder};
378-
use crate::CargoResult;
380+
use super::{ProcessBuilder, ProcessError};
381+
use anyhow::Result;
379382
use std::os::unix::process::CommandExt;
380383

381-
pub fn exec_replace(process_builder: &ProcessBuilder) -> CargoResult<()> {
384+
pub fn exec_replace(process_builder: &ProcessBuilder) -> Result<()> {
382385
let mut command = process_builder.build_command();
383386
let error = command.exec();
384-
Err(anyhow::Error::from(error).context(process_error(
387+
Err(anyhow::Error::from(error).context(ProcessError::new(
385388
&format!("could not execute process {}", process_builder),
386389
None,
387390
None,
@@ -391,8 +394,8 @@ mod imp {
391394

392395
#[cfg(windows)]
393396
mod imp {
394-
use crate::util::{process_error, ProcessBuilder};
395-
use crate::CargoResult;
397+
use super::{ProcessBuilder, ProcessError};
398+
use anyhow::Result;
396399
use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE};
397400
use winapi::um::consoleapi::SetConsoleCtrlHandler;
398401

@@ -401,10 +404,10 @@ mod imp {
401404
TRUE
402405
}
403406

404-
pub fn exec_replace(process_builder: &ProcessBuilder) -> CargoResult<()> {
407+
pub fn exec_replace(process_builder: &ProcessBuilder) -> Result<()> {
405408
unsafe {
406409
if SetConsoleCtrlHandler(Some(ctrlc_handler), TRUE) == FALSE {
407-
return Err(process_error("Could not set Ctrl-C handler.", None, None).into());
410+
return Err(ProcessError::new("Could not set Ctrl-C handler.", None, None).into());
408411
}
409412
}
410413

0 commit comments

Comments
 (0)