Skip to content

Commit

Permalink
Add cargo.extraEnv setting
Browse files Browse the repository at this point in the history
  • Loading branch information
dpaoliello committed Sep 13, 2022
1 parent f64c956 commit c407cc5
Show file tree
Hide file tree
Showing 18 changed files with 155 additions and 43 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/flycheck/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ doctest = false
crossbeam-channel = "0.5.5"
tracing = "0.1.35"
cargo_metadata = "0.15.0"
rustc-hash = "1.1.0"
serde = { version = "1.0.137", features = ["derive"] }
serde_json = "1.0.81"
jod-thread = "0.1.2"
Expand Down
10 changes: 8 additions & 2 deletions crates/flycheck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::{

use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
use paths::AbsPathBuf;
use rustc_hash::FxHashMap;
use serde::Deserialize;
use stdx::{process::streaming_output, JodChild};

Expand All @@ -30,18 +31,20 @@ pub enum FlycheckConfig {
all_features: bool,
features: Vec<String>,
extra_args: Vec<String>,
extra_env: FxHashMap<String, String>,
},
CustomCommand {
command: String,
args: Vec<String>,
extra_env: FxHashMap<String, String>,
},
}

impl fmt::Display for FlycheckConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FlycheckConfig::CargoCommand { command, .. } => write!(f, "cargo {}", command),
FlycheckConfig::CustomCommand { command, args } => {
FlycheckConfig::CustomCommand { command, args, .. } => {
write!(f, "{} {}", command, args.join(" "))
}
}
Expand Down Expand Up @@ -256,6 +259,7 @@ impl FlycheckActor {
all_features,
extra_args,
features,
extra_env,
} => {
let mut cmd = Command::new(toolchain::cargo());
cmd.arg(command);
Expand All @@ -281,11 +285,13 @@ impl FlycheckActor {
}
}
cmd.args(extra_args);
cmd.envs(extra_env);
cmd
}
FlycheckConfig::CustomCommand { command, args } => {
FlycheckConfig::CustomCommand { command, args, extra_env } => {
let mut cmd = Command::new(command);
cmd.args(args);
cmd.envs(extra_env);
cmd
}
};
Expand Down
2 changes: 2 additions & 0 deletions crates/project-model/src/build_scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ impl WorkspaceBuildScripts {
if let Some([program, args @ ..]) = config.run_build_script_command.as_deref() {
let mut cmd = Command::new(program);
cmd.args(args);
cmd.envs(&config.extra_env);
return cmd;
}

let mut cmd = Command::new(toolchain::cargo());
cmd.envs(&config.extra_env);

cmd.args(&["check", "--quiet", "--workspace", "--message-format=json"]);

Expand Down
36 changes: 30 additions & 6 deletions crates/project-model/src/cargo_workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::iter;
use std::path::PathBuf;
use std::str::from_utf8;
use std::{ops, process::Command};

use anyhow::{Context, Result};
Expand Down Expand Up @@ -98,6 +99,8 @@ pub struct CargoConfig {
pub wrap_rustc_in_build_scripts: bool,

pub run_build_script_command: Option<Vec<String>>,

pub extra_env: FxHashMap<String, String>,
}

impl CargoConfig {
Expand Down Expand Up @@ -263,8 +266,8 @@ impl CargoWorkspace {
let target = config
.target
.clone()
.or_else(|| cargo_config_build_target(cargo_toml))
.or_else(|| rustc_discover_host_triple(cargo_toml));
.or_else(|| cargo_config_build_target(cargo_toml, config))
.or_else(|| rustc_discover_host_triple(cargo_toml, config));

let mut meta = MetadataCommand::new();
meta.cargo_path(toolchain::cargo());
Expand Down Expand Up @@ -292,8 +295,27 @@ impl CargoWorkspace {
// unclear whether cargo itself supports it.
progress("metadata".to_string());

let meta =
meta.exec().with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))?;
fn exec_with_env(
command: &cargo_metadata::MetadataCommand,
extra_env: &FxHashMap<String, String>,
) -> Result<cargo_metadata::Metadata, cargo_metadata::Error> {
let mut command = command.cargo_command();
command.envs(extra_env);
let output = command.output()?;
if !output.status.success() {
return Err(cargo_metadata::Error::CargoMetadata {
stderr: String::from_utf8(output.stderr)?,
});
}
let stdout = from_utf8(&output.stdout)?
.lines()
.find(|line| line.starts_with('{'))
.ok_or(cargo_metadata::Error::NoJson)?;
cargo_metadata::MetadataCommand::parse(stdout)
}

let meta = exec_with_env(&meta, &config.extra_env)
.with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))?;

Ok(meta)
}
Expand Down Expand Up @@ -463,8 +485,9 @@ impl CargoWorkspace {
}
}

fn rustc_discover_host_triple(cargo_toml: &ManifestPath) -> Option<String> {
fn rustc_discover_host_triple(cargo_toml: &ManifestPath, config: &CargoConfig) -> Option<String> {
let mut rustc = Command::new(toolchain::rustc());
rustc.envs(&config.extra_env);
rustc.current_dir(cargo_toml.parent()).arg("-vV");
tracing::debug!("Discovering host platform by {:?}", rustc);
match utf8_stdout(rustc) {
Expand All @@ -486,8 +509,9 @@ fn rustc_discover_host_triple(cargo_toml: &ManifestPath) -> Option<String> {
}
}

fn cargo_config_build_target(cargo_toml: &ManifestPath) -> Option<String> {
fn cargo_config_build_target(cargo_toml: &ManifestPath, config: &CargoConfig) -> Option<String> {
let mut cargo_config = Command::new(toolchain::cargo());
cargo_config.envs(&config.extra_env);
cargo_config
.current_dir(cargo_toml.parent())
.args(&["-Z", "unstable-options", "config", "get", "build.target"])
Expand Down
18 changes: 14 additions & 4 deletions crates/project-model/src/rustc_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ use std::process::Command;

use anyhow::Result;

use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath};
use crate::{cfg_flag::CfgFlag, utf8_stdout, CargoConfig, ManifestPath};

pub(crate) fn get(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Vec<CfgFlag> {
pub(crate) fn get(
cargo_toml: Option<&ManifestPath>,
target: Option<&str>,
config: &CargoConfig,
) -> Vec<CfgFlag> {
let _p = profile::span("rustc_cfg::get");
let mut res = Vec::with_capacity(6 * 2 + 1);

Expand All @@ -18,7 +22,7 @@ pub(crate) fn get(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Ve
}
}

match get_rust_cfgs(cargo_toml, target) {
match get_rust_cfgs(cargo_toml, target, config) {
Ok(rustc_cfgs) => {
tracing::debug!(
"rustc cfgs found: {:?}",
Expand All @@ -35,9 +39,14 @@ pub(crate) fn get(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Ve
res
}

fn get_rust_cfgs(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Result<String> {
fn get_rust_cfgs(
cargo_toml: Option<&ManifestPath>,
target: Option<&str>,
config: &CargoConfig,
) -> Result<String> {
if let Some(cargo_toml) = cargo_toml {
let mut cargo_config = Command::new(toolchain::cargo());
cargo_config.envs(&config.extra_env);
cargo_config
.current_dir(cargo_toml.parent())
.args(&["-Z", "unstable-options", "rustc", "--print", "cfg"])
Expand All @@ -52,6 +61,7 @@ fn get_rust_cfgs(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Res
}
// using unstable cargo features failed, fall back to using plain rustc
let mut cmd = Command::new(toolchain::rustc());
cmd.envs(&config.extra_env);
cmd.args(&["--print", "cfg", "-O"]);
if let Some(target) = target {
cmd.args(&["--target", target]);
Expand Down
19 changes: 12 additions & 7 deletions crates/project-model/src/sysroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use anyhow::{format_err, Result};
use la_arena::{Arena, Idx};
use paths::{AbsPath, AbsPathBuf};

use crate::{utf8_stdout, ManifestPath};
use crate::{utf8_stdout, CargoConfig, ManifestPath};

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Sysroot {
Expand Down Expand Up @@ -67,18 +67,20 @@ impl Sysroot {
self.crates.iter().map(|(id, _data)| id)
}

pub fn discover(dir: &AbsPath) -> Result<Sysroot> {
pub fn discover(dir: &AbsPath, config: &CargoConfig) -> Result<Sysroot> {
tracing::debug!("Discovering sysroot for {}", dir.display());
let sysroot_dir = discover_sysroot_dir(dir)?;
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, dir)?;
let sysroot_dir = discover_sysroot_dir(dir, config)?;
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, dir, config)?;
let res = Sysroot::load(sysroot_dir, sysroot_src_dir)?;
Ok(res)
}

pub fn discover_rustc(cargo_toml: &ManifestPath) -> Option<ManifestPath> {
pub fn discover_rustc(cargo_toml: &ManifestPath, config: &CargoConfig) -> Option<ManifestPath> {
tracing::debug!("Discovering rustc source for {}", cargo_toml.display());
let current_dir = cargo_toml.parent();
discover_sysroot_dir(current_dir).ok().and_then(|sysroot_dir| get_rustc_src(&sysroot_dir))
discover_sysroot_dir(current_dir, config)
.ok()
.and_then(|sysroot_dir| get_rustc_src(&sysroot_dir))
}

pub fn load(sysroot_dir: AbsPathBuf, sysroot_src_dir: AbsPathBuf) -> Result<Sysroot> {
Expand Down Expand Up @@ -144,8 +146,9 @@ impl Sysroot {
}
}

fn discover_sysroot_dir(current_dir: &AbsPath) -> Result<AbsPathBuf> {
fn discover_sysroot_dir(current_dir: &AbsPath, config: &CargoConfig) -> Result<AbsPathBuf> {
let mut rustc = Command::new(toolchain::rustc());
rustc.envs(&config.extra_env);
rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
tracing::debug!("Discovering sysroot by {:?}", rustc);
let stdout = utf8_stdout(rustc)?;
Expand All @@ -155,6 +158,7 @@ fn discover_sysroot_dir(current_dir: &AbsPath) -> Result<AbsPathBuf> {
fn discover_sysroot_src_dir(
sysroot_path: &AbsPathBuf,
current_dir: &AbsPath,
config: &CargoConfig,
) -> Result<AbsPathBuf> {
if let Ok(path) = env::var("RUST_SRC_PATH") {
let path = AbsPathBuf::try_from(path.as_str())
Expand All @@ -170,6 +174,7 @@ fn discover_sysroot_src_dir(
get_rust_src(sysroot_path)
.or_else(|| {
let mut rustup = Command::new(toolchain::rustup());
rustup.envs(&config.extra_env);
rustup.current_dir(current_dir).args(&["component", "add", "rust-src"]);
utf8_stdout(rustup).ok()?;
get_rust_src(sysroot_path)
Expand Down
22 changes: 13 additions & 9 deletions crates/project-model/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use paths::{AbsPath, AbsPathBuf};
use serde::de::DeserializeOwned;

use crate::{
CargoWorkspace, CfgOverrides, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot,
WorkspaceBuildScripts,
CargoConfig, CargoWorkspace, CfgOverrides, ProjectJson, ProjectJsonData, ProjectWorkspace,
Sysroot, WorkspaceBuildScripts,
};

fn load_cargo(file: &str) -> CrateGraph {
Expand Down Expand Up @@ -92,13 +92,17 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
}

fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph {
project_workspace.to_crate_graph(&mut |_, _| Ok(Vec::new()), &mut {
let mut counter = 0;
move |_path| {
counter += 1;
Some(FileId(counter))
}
})
project_workspace.to_crate_graph(
&mut |_, _| Ok(Vec::new()),
&mut {
let mut counter = 0;
move |_path| {
counter += 1;
Some(FileId(counter))
}
},
&CargoConfig::default(),
)
}

fn check_crate_graph(crate_graph: CrateGraph, expect: Expect) {
Expand Down
Loading

0 comments on commit c407cc5

Please sign in to comment.