Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit a9eefca

Browse files
committed
Simplify ProcessBuilder modification
1 parent 1838f1b commit a9eefca

File tree

2 files changed

+43
-61
lines changed

2 files changed

+43
-61
lines changed

Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/build/cargo.rs

Lines changed: 35 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use cargo::core::{PackageId, Shell, Target, Workspace, Verbosity};
11+
use cargo::core::{PackageId, Shell, Target, TargetKind, Workspace, Verbosity};
1212
use cargo::ops::{compile_with_exec, Executor, Context, Packages, CompileOptions, CompileMode, CompileFilter, Unit};
13-
use cargo::util::{Config as CargoConfig, process_builder, ProcessBuilder, homedir, important_paths, ConfigValue, CargoResult};
14-
use cargo::util::errors::{CargoErrorKind, process_error};
13+
use cargo::util::{Config as CargoConfig, ProcessBuilder, homedir, important_paths, ConfigValue, CargoResult};
1514
use serde_json;
1615

1716
use data::Analysis;
@@ -296,38 +295,36 @@ impl Executor for RlsExecutor {
296295
}
297296
}
298297

299-
let rustc_exe = env::var("RUSTC").unwrap_or(env::args().next().unwrap());
300-
let mut cmd = Command::new(&rustc_exe);
298+
// Prepare our own call to `rustc` as follows:
299+
// 1. Use $RUSTC wrapper if specified, otherwise use RLS executable
300+
// as an rustc shim (needed to distribute via the stable channel)
301+
// 2. For non-primary packages or build scripts, execute the call
302+
// 3. Otherwise, we'll want to use the compilation to drive the analysis:
303+
// i. Modify arguments to account for the RLS settings (e.g.
304+
// compiling under cfg(test) mode or passing a custom sysroot)
305+
// ii. Execute the call and store the final args/envs to be used for
306+
// later in-process execution of the compiler
307+
let mut cmd = cargo_cmd.clone();
308+
let rls_executable = env::args().next().unwrap();
309+
cmd.program(env::var("RUSTC").unwrap_or(rls_executable));
301310
cmd.env(::RUSTC_SHIM_ENV_VAR_NAME, "1");
302311

303312
// We only want to intercept rustc call targeting current crate to cache
304313
// args/envs generated by cargo so we can run only rustc later ourselves
305314
// Currently we don't cache nor modify build script args
306-
let is_build_script = crate_name == "build_script_build";
315+
let is_build_script = *target.kind() == TargetKind::CustomBuild;
307316
if !self.is_primary_crate(id) || is_build_script {
308317
let mut cmd = Command::new(&env::var("RUSTC").unwrap_or("rustc".to_owned()));
309318
let build_script_notice = if is_build_script {" (build script)"} else {""};
310319
trace!("rustc not intercepted - {}{}", id.name(), build_script_notice);
311320

321+
// Recreate the command, minus -Zsave-analysis.
312322
if ::CRATE_BLACKLIST.contains(&&*crate_name) {
313-
// Recreate the command, minus -Zsave-analysis.
314-
for a in cargo_args {
315-
if a != "-Zsave-analysis" {
316-
cmd.arg(a);
317-
}
318-
}
319-
cmd.envs(cargo_cmd.get_envs().iter().filter_map(|(k, v)| v.as_ref().map(|v| (k, v))));
320-
if let Some(cwd) = cargo_cmd.get_cwd() {
321-
cmd.current_dir(cwd);
322-
}
323-
return match cmd.status() {
324-
Ok(ref e) if e.success() => Ok(()),
325-
_ => Err(CargoErrorKind::ProcessErrorKind(process_error(
326-
"process didn't exit successfully", None, None)).into()),
327-
};
328-
} else {
329-
return cargo_cmd.exec();
323+
let args: Vec<_> = cmd.get_args().iter().cloned()
324+
.filter(|x| x != "Zsave-analysis").collect();
325+
cmd.args_replace(&args);
330326
}
327+
return cmd.exec();
331328
}
332329

333330
trace!("rustc intercepted - args: {:?} envs: {:?}", cargo_args, cargo_cmd.get_envs());
@@ -370,43 +367,28 @@ impl Executor for RlsExecutor {
370367
// so the dep-info is ready by the time we return from this callback.
371368
// NB: In `workspace_mode` regular compilation is performed here (and we don't
372369
// only calculate dep-info) so it should fix the problem mentioned above.
373-
// Since ProcessBuilder doesn't allow to modify args, we need to create
374-
// our own command here from scratch here.
375-
for a in &args {
376-
// Emitting only dep-info is possible only for final crate type, as
377-
// as others may emit required metadata for dependent crate types
378-
if a.starts_with("--emit") && is_final_crate_type && !self.workspace_mode {
379-
cmd.arg("--emit=dep-info");
380-
} else if a != "-Zsave-analysis" {
381-
cmd.arg(a);
382-
}
383-
}
384-
cmd.envs(cargo_cmd.get_envs().iter().filter_map(|(k, v)| v.as_ref().map(|v| (k, v))));
385-
if let Some(cwd) = cargo_cmd.get_cwd() {
386-
cmd.current_dir(cwd);
387-
}
370+
let modified = args.iter()
371+
.filter(|a| *a != "-Zsave-analysis")
372+
.map(|a| {
373+
// Emitting only dep-info is possible only for final crate type, as
374+
// as others may emit required metadata for dependent crate types
375+
if a.starts_with("--emit") && is_final_crate_type && !self.workspace_mode {
376+
"--emit=dep-info"
377+
} else { a }
378+
})
379+
.collect::<Vec<_>>();
380+
cmd.args_replace(&modified);
388381
}
389382

390383
// Cache executed command for the build plan
391384
{
392385
let mut cx = self.compilation_cx.lock().unwrap();
393-
394-
let mut store_cmd = process_builder::process(&rustc_exe);
395-
store_cmd.args(&args.iter().map(OsString::from).collect::<Vec<_>>());
396-
for (k, v) in cargo_cmd.get_envs().clone() {
397-
if let Some(v) = v {
398-
store_cmd.env(&k, v);
399-
}
400-
}
401-
if let Some(cwd) = cargo_cmd.get_cwd() {
402-
cmd.current_dir(cwd);
403-
}
404-
405-
cx.build_plan.cache_compiler_job(id, target, &store_cmd);
386+
cx.build_plan.cache_compiler_job(id, target, &cmd);
406387
}
407388

408389
// Prepare modified cargo-generated args/envs for future rustc calls
409-
args.insert(0, rustc_exe);
390+
let rustc = cargo_cmd.get_program().to_owned().into_string().unwrap();
391+
args.insert(0, rustc);
410392
let envs = cargo_cmd.get_envs().clone();
411393

412394
if self.workspace_mode {
@@ -426,7 +408,7 @@ impl Executor for RlsExecutor {
426408
_ => {}
427409
}
428410
} else {
429-
cmd.status().expect("Couldn't execute rustc");
411+
cmd.exec()?;
430412
}
431413

432414
// Finally, store the modified cargo-generated args/envs for future rustc calls

0 commit comments

Comments
 (0)