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

Commit 60a2e87

Browse files
committed
Simplify ProcessBuilder modification
1 parent b7f42dc commit 60a2e87

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,37 +295,35 @@ 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 build_script_notice = if is_build_script {" (build script)"} else {""};
309318
trace!("rustc not intercepted - {}{}", id.name(), build_script_notice);
310319

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

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

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

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

411393
if self.workspace_mode {
@@ -425,7 +407,7 @@ impl Executor for RlsExecutor {
425407
_ => {}
426408
}
427409
} else {
428-
cmd.status().expect("Couldn't execute rustc");
410+
cmd.exec()?;
429411
}
430412

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

0 commit comments

Comments
 (0)