diff --git a/src/bin/bench.rs b/src/bin/bench.rs index 67fefb66e1c..ac591a677b2 100644 --- a/src/bin/bench.rs +++ b/src/bin/bench.rs @@ -63,7 +63,8 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult features: options.flag_features.as_slice(), no_default_features: options.flag_no_default_features, spec: options.flag_package.as_ref().map(|s| s.as_slice()), - lib_only: false + lib_only: false, + exec_engine: None, }, }; diff --git a/src/bin/build.rs b/src/bin/build.rs index edd100685ec..aafd93bff90 100644 --- a/src/bin/build.rs +++ b/src/bin/build.rs @@ -64,7 +64,8 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult features: options.flag_features.as_slice(), no_default_features: options.flag_no_default_features, spec: options.flag_package.as_ref().map(|s| s.as_slice()), - lib_only: options.flag_lib + lib_only: options.flag_lib, + exec_engine: None, }; ops::compile(&root, &mut opts).map(|_| None).map_err(|err| { diff --git a/src/bin/doc.rs b/src/bin/doc.rs index 78be4718377..28c27338080 100644 --- a/src/bin/doc.rs +++ b/src/bin/doc.rs @@ -58,7 +58,8 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult features: options.flag_features.as_slice(), no_default_features: options.flag_no_default_features, spec: options.flag_package.as_ref().map(|s| s.as_slice()), - lib_only: false + lib_only: false, + exec_engine: None, }, }; diff --git a/src/bin/run.rs b/src/bin/run.rs index 29265d49d3a..9883e5c044a 100644 --- a/src/bin/run.rs +++ b/src/bin/run.rs @@ -67,7 +67,8 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult features: options.flag_features.as_slice(), no_default_features: options.flag_no_default_features, spec: None, - lib_only: false + lib_only: false, + exec_engine: None, }; let (target_kind, name) = match (options.flag_bin, options.flag_example) { diff --git a/src/bin/test.rs b/src/bin/test.rs index 7f4e950c12d..26a3346dc0f 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -65,7 +65,8 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult features: options.flag_features.as_slice(), no_default_features: options.flag_no_default_features, spec: options.flag_package.as_ref().map(|s| s.as_slice()), - lib_only: false + lib_only: false, + exec_engine: None, }, }; diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index ec30b63ba3a..1646b651755 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -25,11 +25,12 @@ use std::os; use std::collections::HashMap; use std::default::Default; +use std::sync::Arc; use core::registry::PackageRegistry; use core::{MultiShell, Source, SourceId, PackageSet, Package, Target, PackageId}; use core::resolver::Method; -use ops::{mod, BuildOutput}; +use ops::{mod, BuildOutput, ExecEngine}; use sources::{PathSource}; use util::config::{Config, ConfigValue}; use util::{CargoResult, config, internal, human, ChainError, profile}; @@ -47,7 +48,8 @@ pub struct CompileOptions<'a> { pub features: &'a [String], pub no_default_features: bool, pub spec: Option<&'a str>, - pub lib_only: bool + pub lib_only: bool, + pub exec_engine: Option>>, } pub fn compile(manifest_path: &Path, @@ -72,7 +74,8 @@ pub fn compile_pkg(package: &Package, options: &mut CompileOptions) -> CargoResult { let CompileOptions { env, ref mut shell, jobs, target, spec, dev_deps, features, no_default_features, - lib_only } = *options; + lib_only, ref mut exec_engine } = *options; + let target = target.map(|s| s.to_string()); let features = features.iter().flat_map(|s| { s.as_slice().split(' ') @@ -149,7 +152,7 @@ pub fn compile_pkg(package: &Package, options: &mut CompileOptions) try!(ops::compile_targets(env.as_slice(), targets.as_slice(), to_build, &PackageSet::new(packages.as_slice()), &resolve_with_overrides, &sources, - &config, lib_overrides)) + &config, lib_overrides, exec_engine.clone())) }; return Ok(ret); diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index f97224b54e5..0ff3d8760fd 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -180,6 +180,7 @@ fn run_verify(pkg: &Package, shell: &mut MultiShell, tar: &Path) no_default_features: false, spec: None, lib_only: false, + exec_engine: None, })); Ok(()) diff --git a/src/cargo/ops/cargo_run.rs b/src/cargo/ops/cargo_run.rs index f1d37644366..6293ec800bb 100644 --- a/src/cargo/ops/cargo_run.rs +++ b/src/cargo/ops/cargo_run.rs @@ -1,6 +1,6 @@ use std::os; -use ops; +use ops::{mod, ExecEngine}; use util::{CargoResult, human, process, ProcessError, ChainError}; use core::manifest::TargetKind; use core::source::Source; @@ -49,7 +49,8 @@ pub fn run(manifest_path: &Path, Some(path) => path, None => exe, }; - let process = try!(compile.process(exe, &root)) + let process = try!(try!(compile.target_process(exe, &root)) + .into_process_builder()) .args(args) .cwd(try!(os::getcwd())); diff --git a/src/cargo/ops/cargo_rustc/compilation.rs b/src/cargo/ops/cargo_rustc/compilation.rs index 1d6688f9a69..fce3bdcbc22 100644 --- a/src/cargo/ops/cargo_rustc/compilation.rs +++ b/src/cargo/ops/cargo_rustc/compilation.rs @@ -5,6 +5,8 @@ use semver::Version; use core::{PackageId, Package}; use util::{mod, CargoResult}; +use super::{CommandType, CommandPrototype}; + /// A structure returning the result of a compilation. pub struct Compilation { /// All libraries which were built for a package. @@ -54,13 +56,35 @@ impl Compilation { } } + /// See `process`. + pub fn rustc_process(&self, pkg: &Package) -> CargoResult { + self.process(CommandType::Rustc, pkg) + } + + /// See `process`. + pub fn rustdoc_process(&self, pkg: &Package) -> CargoResult { + self.process(CommandType::Rustdoc, pkg) + } + + /// See `process`. + pub fn target_process(&self, cmd: T, pkg: &Package) + -> CargoResult { + self.process(CommandType::Target(cmd.to_c_str()), pkg) + } + + /// See `process`. + pub fn host_process(&self, cmd: T, pkg: &Package) + -> CargoResult { + self.process(CommandType::Host(cmd.to_c_str()), pkg) + } + /// Prepares a new process with an appropriate environment to run against /// the artifacts produced by the build process. /// /// The package argument is also used to configure environment variables as /// well as the working directory of the child process. - pub fn process(&self, cmd: T, pkg: &Package) - -> CargoResult { + pub fn process(&self, cmd: CommandType, pkg: &Package) + -> CargoResult { let mut search_path = DynamicLibrary::search_path(); for dir in self.native_dirs.values() { search_path.push(dir.clone()); @@ -69,7 +93,7 @@ impl Compilation { search_path.push(self.deps_output.clone()); let search_path = try!(util::join_paths(search_path.as_slice(), DynamicLibrary::envvar())); - let mut cmd = try!(util::process(cmd)).env( + let mut cmd = try!(CommandPrototype::new(cmd)).env( DynamicLibrary::envvar(), Some(search_path.as_slice())); for (k, v) in self.extra_env.iter() { cmd = cmd.env(k.as_slice(), v.as_ref().map(|s| s.as_slice())); diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 8bcd5d72089..1a45a0911f9 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -11,6 +11,7 @@ use super::{Kind, Compilation, BuildConfig}; use super::TargetConfig; use super::layout::{Layout, LayoutProxy}; use super::custom_build::BuildState; +use super::{ProcessEngine, ExecEngine}; #[deriving(Show, Copy)] pub enum Platform { @@ -25,6 +26,7 @@ pub struct Context<'a, 'b: 'a> { pub sources: &'a SourceMap<'b>, pub compilation: Compilation, pub build_state: Arc, + pub exec_engine: Arc>, env: &'a str, host: Layout, @@ -73,6 +75,7 @@ impl<'a, 'b: 'a> Context<'a, 'b> { compilation: Compilation::new(root_pkg), build_state: Arc::new(BuildState::new(build_config.clone(), deps)), build_config: build_config, + exec_engine: Arc::new(box ProcessEngine as Box), }) } diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index 08d5f0429d3..fcbc8b9d6d0 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -11,6 +11,7 @@ use util::{internal, ChainError}; use super::job::Work; use super::{fingerprint, process, Kind, Context, Platform}; +use super::CommandType; use util::Freshness; /// Contains the parsed output of a custom build script. @@ -49,7 +50,7 @@ pub fn prepare(pkg: &Package, target: &Target, req: Platform, // Start preparing the process to execute, starting out with some // environment variables. let profile = target.get_profile(); - let mut p = try!(super::process(to_exec, pkg, target, cx)) + let mut p = try!(super::process(CommandType::Host(to_exec.to_c_str()), pkg, target, cx)) .env("OUT_DIR", Some(&build_output)) .env("CARGO_MANIFEST_DIR", Some(pkg.get_manifest_path() .dir_path() @@ -101,6 +102,8 @@ pub fn prepare(pkg: &Package, target: &Target, req: Platform, try!(fs::mkdir_recursive(&cx.layout(pkg, Kind::Target).build(pkg), USER_RWX)); try!(fs::mkdir_recursive(&cx.layout(pkg, Kind::Host).build(pkg), USER_RWX)); + let exec_engine = cx.exec_engine.clone(); + // Prepare the unit of "dirty work" which will actually run the custom build // command. // @@ -136,7 +139,7 @@ pub fn prepare(pkg: &Package, target: &Target, req: Platform, // And now finally, run the build command itself! desc_tx.send_opt(p.to_string()).ok(); - let output = try!(p.exec_with_output().map_err(|mut e| { + let output = try!(exec_engine.exec_with_output(p).map_err(|mut e| { e.desc = format!("failed to run custom build command for `{}`\n{}", pkg_name, e.desc); Human(e) diff --git a/src/cargo/ops/cargo_rustc/engine.rs b/src/cargo/ops/cargo_rustc/engine.rs new file mode 100644 index 00000000000..7b043b43bff --- /dev/null +++ b/src/cargo/ops/cargo_rustc/engine.rs @@ -0,0 +1,138 @@ +use std::collections::HashMap; +use std::c_str::CString; +use std::io::process::ProcessOutput; +use std::fmt::{mod, Show, Formatter}; + +use util::{mod, CargoResult, ProcessError, ProcessBuilder}; + +/// Trait for objects that can execute commands. +pub trait ExecEngine: Send + Sync { + fn exec(&self, CommandPrototype) -> Result<(), ProcessError>; + fn exec_with_output(&self, CommandPrototype) -> Result; +} + +/// Default implementation of `ExecEngine`. +#[deriving(Copy)] +pub struct ProcessEngine; + +impl ExecEngine for ProcessEngine { + fn exec(&self, command: CommandPrototype) -> Result<(), ProcessError> { + command.into_process_builder().unwrap().exec() + } + + fn exec_with_output(&self, command: CommandPrototype) + -> Result { + command.into_process_builder().unwrap().exec_with_output() + } +} + +/// Prototype for a command that must be executed. +#[deriving(Clone)] +pub struct CommandPrototype { + ty: CommandType, + args: Vec, + env: HashMap>, + cwd: Path, +} + +impl CommandPrototype { + pub fn new(ty: CommandType) -> CargoResult { + use std::os; + + Ok(CommandPrototype { + ty: ty, + args: Vec::new(), + env: HashMap::new(), + cwd: try!(os::getcwd()), + }) + } + + pub fn get_type(&self) -> &CommandType { + &self.ty + } + + pub fn arg(mut self, arg: T) -> CommandPrototype { + self.args.push(arg.to_c_str()); + self + } + + pub fn args(mut self, arguments: &[T]) -> CommandPrototype { + self.args.extend(arguments.iter().map(|t| t.to_c_str())); + self + } + + pub fn get_args(&self) -> &[CString] { + self.args.as_slice() + } + + pub fn cwd(mut self, path: Path) -> CommandPrototype { + self.cwd = path; + self + } + + pub fn get_cwd(&self) -> &Path { + &self.cwd + } + + pub fn env(mut self, key: &str, val: Option) -> CommandPrototype { + self.env.insert(key.to_string(), val.map(|t| t.to_c_str())); + self + } + + pub fn get_envs(&self) -> &HashMap> { + &self.env + } + + pub fn into_process_builder(self) -> CargoResult { + let mut builder = try!(match self.ty { + CommandType::Rustc => util::process("rustc"), + CommandType::Rustdoc => util::process("rustdoc"), + CommandType::Target(ref cmd) | CommandType::Host(ref cmd) => { + util::process(cmd.as_bytes_no_nul()) + }, + }); + + for arg in self.args.into_iter() { + builder = builder.arg(arg.as_bytes_no_nul()); + } + + for (key, val) in self.env.into_iter() { + builder = builder.env(key.as_slice(), val.as_ref().map(|v| v.as_bytes_no_nul())); + } + + builder = builder.cwd(self.cwd); + + Ok(builder) + } +} + +impl Show for CommandPrototype { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self.ty { + CommandType::Rustc => try!(write!(f, "`rustc")), + CommandType::Rustdoc => try!(write!(f, "`rustdoc")), + CommandType::Target(ref cmd) | CommandType::Host(ref cmd) => { + let cmd = String::from_utf8_lossy(cmd.as_bytes_no_nul()); + try!(write!(f, "`{}", cmd)); + }, + } + + for arg in self.args.iter() { + try!(write!(f, " {}", String::from_utf8_lossy(arg.as_bytes_no_nul()))); + } + + write!(f, "`") + } +} + +#[deriving(Clone, Show)] +pub enum CommandType { + Rustc, + Rustdoc, + + /// The command is to be executed for the target architecture. + Target(CString), + + /// The command is to be executed for the host architecture. + Host(CString), +} diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index f563f1e28dd..5919615b5a8 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -2,9 +2,10 @@ use std::collections::{HashSet, HashMap}; use std::dynamic_lib::DynamicLibrary; use std::io::{fs, USER_RWX}; use std::io::fs::PathExtensions; +use std::sync::Arc; use core::{SourceMap, Package, PackageId, PackageSet, Target, Resolve}; -use util::{mod, CargoResult, ProcessBuilder, human, caused_human}; +use util::{mod, CargoResult, human, caused_human}; use util::{Config, internal, ChainError, Fresh, profile, join_paths, Human}; use self::job::{Job, Work}; @@ -13,12 +14,14 @@ use self::job_queue::{JobQueue, Stage}; pub use self::compilation::Compilation; pub use self::context::Context; pub use self::context::Platform; +pub use self::engine::{CommandPrototype, CommandType, ExecEngine, ProcessEngine}; pub use self::layout::{Layout, LayoutProxy}; pub use self::custom_build::BuildOutput; mod context; mod compilation; mod custom_build; +mod engine; mod fingerprint; mod job; mod job_queue; @@ -112,7 +115,8 @@ pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package, deps: &PackageSet, resolve: &'a Resolve, sources: &'a SourceMap, config: &'a Config<'a>, - build_config: BuildConfig) + build_config: BuildConfig, + exec_engine: Option>>) -> CargoResult { if targets.is_empty() { return Ok(Compilation::new(pkg)) @@ -136,6 +140,10 @@ pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package, let mut cx = try!(Context::new(env, resolve, sources, deps, config, host_layout, target_layout, pkg, build_config)); + if let Some(exec_engine) = exec_engine { + cx.exec_engine = exec_engine.clone(); + } + let mut queue = JobQueue::new(cx.resolve, deps, cx.config); // First ensure that the destination directory exists @@ -365,7 +373,8 @@ fn compile_custom_old(pkg: &Package, cmd: &str, // may be building a C lib for a plugin let layout = cx.layout(pkg, Kind::Target); let output = layout.native(pkg); - let mut p = try!(process(cmd.next().unwrap(), pkg, target, cx)) + let mut p = try!(process(CommandType::Host(cmd.next().unwrap().to_c_str()), pkg, + target, cx)) .env("OUT_DIR", Some(&output)) .env("DEPS_DIR", Some(&output)) .env("TARGET", Some(cx.target_triple())) @@ -400,6 +409,8 @@ fn compile_custom_old(pkg: &Package, cmd: &str, } let pkg = pkg.to_string(); + let exec_engine = cx.exec_engine.clone(); + Ok(Work::new(move |desc_tx: Sender| { desc_tx.send_opt(p.to_string()).ok(); if first && !output.exists() { @@ -407,7 +418,7 @@ fn compile_custom_old(pkg: &Package, cmd: &str, internal("failed to create output directory for build command") })) } - try!(p.exec_with_output().map(|_| ()).map_err(|mut e| { + try!(exec_engine.exec_with_output(p).map(|_| ()).map_err(|mut e| { e.desc = format!("Failed to run custom build command for `{}`\n{}", pkg, e.desc); Human(e) @@ -428,6 +439,7 @@ fn rustc(package: &Package, target: &Target, let show_warnings = package.get_package_id() == cx.resolve.root() || is_path_source; let rustc = if show_warnings {rustc} else {rustc.arg("-Awarnings")}; + let exec_engine = cx.exec_engine.clone(); let filenames = try!(cx.target_filenames(target)); let root = cx.out_dir(package, kind, target); @@ -505,7 +517,7 @@ fn rustc(package: &Package, target: &Target, } desc_tx.send_opt(rustc.to_string()).ok(); - try!(rustc.exec().chain_error(|| { + try!(exec_engine.exec(rustc).chain_error(|| { human(format!("Could not compile `{}`.", name)) })); @@ -519,8 +531,8 @@ fn rustc(package: &Package, target: &Target, fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>, cx: &Context, req: Platform) - -> CargoResult> { - let base = try!(process("rustc", package, target, cx)); + -> CargoResult> { + let base = try!(process(CommandType::Rustc, package, target, cx)); let base = build_base_args(cx, base, package, target, crate_types.as_slice()); let target_cmd = build_plugin_args(base.clone(), cx, package, target, Kind::Target); @@ -546,7 +558,8 @@ fn rustdoc(package: &Package, target: &Target, let kind = Kind::Target; let pkg_root = package.get_root(); let cx_root = cx.layout(package, kind).proxy().dest().join("doc"); - let rustdoc = try!(process("rustdoc", package, target, cx)).cwd(pkg_root.clone()); + let rustdoc = try!(process(CommandType::Rustdoc, package, target, cx)) + .cwd(pkg_root.clone()); let mut rustdoc = rustdoc.arg(target.get_src_path()) .arg("-o").arg(cx_root) .arg("--crate-name").arg(target.get_name()); @@ -573,14 +586,16 @@ fn rustdoc(package: &Package, target: &Target, let primary = package.get_package_id() == cx.resolve.root(); let name = package.get_name().to_string(); let desc = rustdoc.to_string(); + let exec_engine = cx.exec_engine.clone(); + Ok(Work::new(move |desc_tx: Sender| { desc_tx.send(desc); if primary { - try!(rustdoc.exec().chain_error(|| { + try!(exec_engine.exec(rustdoc).chain_error(|| { human(format!("Could not document `{}`.", name)) })) } else { - try!(rustdoc.exec_with_output().and(Ok(())).map_err(|err| { + try!(exec_engine.exec_with_output(rustdoc).and(Ok(())).map_err(|err| { match err.exit { Some(..) => { caused_human(format!("Could not document `{}`.", @@ -597,10 +612,10 @@ fn rustdoc(package: &Package, target: &Target, } fn build_base_args(cx: &Context, - mut cmd: ProcessBuilder, + mut cmd: CommandPrototype, pkg: &Package, target: &Target, - crate_types: &[&str]) -> ProcessBuilder { + crate_types: &[&str]) -> CommandPrototype { let metadata = target.get_metadata(); // TODO: Handle errors in converting paths into args @@ -680,16 +695,16 @@ fn build_base_args(cx: &Context, } -fn build_plugin_args(mut cmd: ProcessBuilder, cx: &Context, pkg: &Package, - target: &Target, kind: Kind) -> ProcessBuilder { +fn build_plugin_args(mut cmd: CommandPrototype, cx: &Context, pkg: &Package, + target: &Target, kind: Kind) -> CommandPrototype { cmd = cmd.arg("--out-dir"); cmd = cmd.arg(cx.out_dir(pkg, kind, target)); cmd = cmd.arg("--emit=dep-info,link"); if kind == Kind::Target { - fn opt(cmd: ProcessBuilder, key: &str, prefix: &str, - val: Option<&str>) -> ProcessBuilder { + fn opt(cmd: CommandPrototype, key: &str, prefix: &str, + val: Option<&str>) -> CommandPrototype { match val { Some(val) => { cmd.arg(key) @@ -707,9 +722,9 @@ fn build_plugin_args(mut cmd: ProcessBuilder, cx: &Context, pkg: &Package, return cmd; } -fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, +fn build_deps_args(mut cmd: CommandPrototype, target: &Target, package: &Package, cx: &Context, - kind: Kind) -> CargoResult { + kind: Kind) -> CargoResult { let layout = cx.layout(package, kind); cmd = cmd.arg("-L").arg(layout.root()); cmd = cmd.arg("-L").arg(layout.deps()); @@ -749,8 +764,8 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, return Ok(cmd); - fn link_to(mut cmd: ProcessBuilder, pkg: &Package, target: &Target, - cx: &Context, kind: Kind) -> CargoResult { + fn link_to(mut cmd: CommandPrototype, pkg: &Package, target: &Target, + cx: &Context, kind: Kind) -> CargoResult { // If this target is itself a plugin *or* if it's being linked to a // plugin, then we want the plugin directory. Otherwise we want the // target directory (hence the || here). @@ -773,8 +788,8 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, } } -pub fn process(cmd: T, pkg: &Package, target: &Target, - cx: &Context) -> CargoResult { +pub fn process(cmd: CommandType, pkg: &Package, target: &Target, + cx: &Context) -> CargoResult { // When invoking a tool, we need the *host* deps directory in the dynamic // library search path for plugins and such which have dynamic dependencies. let layout = cx.layout(pkg, Kind::Host); diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 5181b364278..888538a32ec 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -2,7 +2,7 @@ use std::os; use core::Source; use sources::PathSource; -use ops; +use ops::{mod, ExecEngine, ProcessEngine}; use util::{CargoResult, ProcessError}; pub struct TestOptions<'a> { @@ -32,14 +32,15 @@ pub fn run_tests(manifest_path: &Path, Some(path) => path, None => exe.clone(), }; - let cmd = try!(compile.process(exe, &compile.package)).args(test_args); + let cmd = try!(compile.target_process(exe, &compile.package)) + .args(test_args); try!(options.compile_opts.shell.concise(|shell| { shell.status("Running", to_display.display().to_string()) })); try!(options.compile_opts.shell.verbose(|shell| { shell.status("Running", cmd.to_string()) })); - match cmd.exec() { + match ExecEngine::exec(&mut ProcessEngine, cmd) { Ok(()) => {} Err(e) => return Ok(Some(e)) } @@ -58,7 +59,7 @@ pub fn run_tests(manifest_path: &Path, for (lib, name) in libs { try!(options.compile_opts.shell.status("Doc-tests", name)); - let mut p = try!(compile.process("rustdoc", &compile.package)) + let mut p = try!(compile.rustdoc_process(&compile.package)) .arg("--test").arg(lib) .arg("--crate-name").arg(name) .arg("-L").arg(&compile.root_output) @@ -82,7 +83,7 @@ pub fn run_tests(manifest_path: &Path, try!(options.compile_opts.shell.verbose(|shell| { shell.status("Running", p.to_string()) })); - match p.exec() { + match ExecEngine::exec(&mut ProcessEngine, p) { Ok(()) => {} Err(e) => return Ok(Some(e)), } diff --git a/src/cargo/ops/mod.rs b/src/cargo/ops/mod.rs index 53ade356e9f..ae28b4befc2 100644 --- a/src/cargo/ops/mod.rs +++ b/src/cargo/ops/mod.rs @@ -5,6 +5,7 @@ pub use self::cargo_rustc::{compile_targets, Compilation, Layout, Kind, rustc_ve pub use self::cargo_rustc::{Context, LayoutProxy}; pub use self::cargo_rustc::Platform; pub use self::cargo_rustc::{BuildOutput, BuildConfig, TargetConfig}; +pub use self::cargo_rustc::{CommandType, CommandPrototype, ExecEngine, ProcessEngine}; pub use self::cargo_run::run; pub use self::cargo_new::{new, NewOptions}; pub use self::cargo_doc::{doc, DocOptions};