mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
Auto merge of #13058 - dpaoliello:extraenv, r=Veykril
Add a new configuration settings to set env vars when running cargo, rustc, etc. commands: cargo.extraEnv and checkOnSave.extraEnv It can be extremely useful to be able to set environment variables when rust-analyzer is running various cargo or rustc commands (such as `cargo check`, `cargo --print cfg` or `cargo metadata`): users may want to set custom `RUSTFLAGS`, change `PATH` to use a custom toolchain or set a different `CARGO_HOME`. There is the existing `server.extraEnv` setting that allows env vars to be set when the rust-analyzer server is launched, but using this as the recommended mechanism to also configure cargo/rust has some drawbacks: - It convolutes configuring the rust-analyzer server with configuring cargo/rustc (one may want to change the `PATH` for cargo/rustc without affecting the rust-analyzer server). - The name `server.extraEnv` doesn't indicate that cargo/rustc will be affected but renaming it to `cargo.extraEnv` doesn't indicate that the rust-analyzer server would be affected. - To make the setting useful, it needs to be dynamically reloaded without requiring that the entire extension is reloaded. It might be possible to do this, but it would require the client communicating to the server what the overwritten env vars were at first launch, which isn't easy to do. This change adds two new configuration settings: `cargo.extraEnv` and `checkOnSave.extraEnv` that can be used to change the environment for the rust-analyzer server after launch (thus affecting any process that rust-analyzer invokes) and the `cargo check` command respectively. `cargo.extraEnv` supports dynamic changes by keeping track of the pre-change values of environment variables, thus it can undo changes made previously before applying the new configuration (and then requesting a workspace reload).
This commit is contained in:
commit
11bf2e7ffb
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -394,6 +394,7 @@ dependencies = [
|
||||
"crossbeam-channel",
|
||||
"jod-thread",
|
||||
"paths",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"stdx",
|
||||
|
@ -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"
|
||||
|
@ -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};
|
||||
|
||||
@ -30,10 +31,12 @@ 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>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -41,7 +44,7 @@ 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(" "))
|
||||
}
|
||||
}
|
||||
@ -256,6 +259,7 @@ impl FlycheckActor {
|
||||
all_features,
|
||||
extra_args,
|
||||
features,
|
||||
extra_env,
|
||||
} => {
|
||||
let mut cmd = Command::new(toolchain::cargo());
|
||||
cmd.arg(command);
|
||||
@ -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
|
||||
}
|
||||
};
|
||||
|
@ -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"]);
|
||||
|
||||
|
@ -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};
|
||||
@ -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 {
|
||||
@ -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());
|
||||
@ -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)
|
||||
}
|
||||
@ -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) {
|
||||
@ -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"])
|
||||
|
@ -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);
|
||||
|
||||
@ -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: {:?}",
|
||||
@ -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"])
|
||||
@ -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]);
|
||||
|
@ -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 {
|
||||
@ -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> {
|
||||
@ -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)?;
|
||||
@ -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())
|
||||
@ -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)
|
||||
|
@ -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 {
|
||||
@ -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) {
|
||||
|
@ -156,11 +156,12 @@ impl ProjectWorkspace {
|
||||
})?;
|
||||
let project_location = project_json.parent().to_path_buf();
|
||||
let project_json = ProjectJson::new(&project_location, data);
|
||||
ProjectWorkspace::load_inline(project_json, config.target.as_deref())?
|
||||
ProjectWorkspace::load_inline(project_json, config.target.as_deref(), config)?
|
||||
}
|
||||
ProjectManifest::CargoToml(cargo_toml) => {
|
||||
let cargo_version = utf8_stdout({
|
||||
let mut cmd = Command::new(toolchain::cargo());
|
||||
cmd.envs(&config.extra_env);
|
||||
cmd.arg("--version");
|
||||
cmd
|
||||
})?;
|
||||
@ -186,7 +187,7 @@ impl ProjectWorkspace {
|
||||
let sysroot = if config.no_sysroot {
|
||||
None
|
||||
} else {
|
||||
Some(Sysroot::discover(cargo_toml.parent()).with_context(|| {
|
||||
Some(Sysroot::discover(cargo_toml.parent(), config).with_context(|| {
|
||||
format!(
|
||||
"Failed to find sysroot for Cargo.toml file {}. Is rust-src installed?",
|
||||
cargo_toml.display()
|
||||
@ -196,7 +197,7 @@ impl ProjectWorkspace {
|
||||
|
||||
let rustc_dir = match &config.rustc_source {
|
||||
Some(RustcSource::Path(path)) => ManifestPath::try_from(path.clone()).ok(),
|
||||
Some(RustcSource::Discover) => Sysroot::discover_rustc(&cargo_toml),
|
||||
Some(RustcSource::Discover) => Sysroot::discover_rustc(&cargo_toml, config),
|
||||
None => None,
|
||||
};
|
||||
|
||||
@ -216,7 +217,7 @@ impl ProjectWorkspace {
|
||||
None => None,
|
||||
};
|
||||
|
||||
let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref());
|
||||
let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref(), config);
|
||||
|
||||
let cfg_overrides = config.cfg_overrides();
|
||||
ProjectWorkspace::Cargo {
|
||||
@ -237,6 +238,7 @@ impl ProjectWorkspace {
|
||||
pub fn load_inline(
|
||||
project_json: ProjectJson,
|
||||
target: Option<&str>,
|
||||
config: &CargoConfig,
|
||||
) -> Result<ProjectWorkspace> {
|
||||
let sysroot = match (project_json.sysroot.clone(), project_json.sysroot_src.clone()) {
|
||||
(Some(sysroot), Some(sysroot_src)) => Some(Sysroot::load(sysroot, sysroot_src)?),
|
||||
@ -258,7 +260,7 @@ impl ProjectWorkspace {
|
||||
(None, None) => None,
|
||||
};
|
||||
|
||||
let rustc_cfg = rustc_cfg::get(None, target);
|
||||
let rustc_cfg = rustc_cfg::get(None, target, config);
|
||||
Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg })
|
||||
}
|
||||
|
||||
@ -268,8 +270,9 @@ impl ProjectWorkspace {
|
||||
.first()
|
||||
.and_then(|it| it.parent())
|
||||
.ok_or_else(|| format_err!("No detached files to load"))?,
|
||||
&CargoConfig::default(),
|
||||
)?;
|
||||
let rustc_cfg = rustc_cfg::get(None, None);
|
||||
let rustc_cfg = rustc_cfg::get(None, None, &CargoConfig::default());
|
||||
Ok(ProjectWorkspace::DetachedFiles { files: detached_files, sysroot, rustc_cfg })
|
||||
}
|
||||
|
||||
@ -416,6 +419,7 @@ impl ProjectWorkspace {
|
||||
&self,
|
||||
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
config: &CargoConfig,
|
||||
) -> CrateGraph {
|
||||
let _p = profile::span("ProjectWorkspace::to_crate_graph");
|
||||
|
||||
@ -426,6 +430,7 @@ impl ProjectWorkspace {
|
||||
load,
|
||||
project,
|
||||
sysroot,
|
||||
config,
|
||||
),
|
||||
ProjectWorkspace::Cargo {
|
||||
cargo,
|
||||
@ -464,6 +469,7 @@ fn project_json_to_crate_graph(
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
project: &ProjectJson,
|
||||
sysroot: &Option<Sysroot>,
|
||||
config: &CargoConfig,
|
||||
) -> CrateGraph {
|
||||
let mut crate_graph = CrateGraph::default();
|
||||
let sysroot_deps = sysroot
|
||||
@ -489,9 +495,9 @@ fn project_json_to_crate_graph(
|
||||
};
|
||||
|
||||
let target_cfgs = match krate.target.as_deref() {
|
||||
Some(target) => {
|
||||
cfg_cache.entry(target).or_insert_with(|| rustc_cfg::get(None, Some(target)))
|
||||
}
|
||||
Some(target) => cfg_cache
|
||||
.entry(target)
|
||||
.or_insert_with(|| rustc_cfg::get(None, Some(target), config)),
|
||||
None => &rustc_cfg,
|
||||
};
|
||||
|
||||
|
@ -80,7 +80,8 @@ impl flags::AnalysisStats {
|
||||
Some(build_scripts_sw.elapsed())
|
||||
};
|
||||
|
||||
let (host, vfs, _proc_macro) = load_workspace(workspace, &load_cargo_config)?;
|
||||
let (host, vfs, _proc_macro) =
|
||||
load_workspace(workspace, &cargo_config, &load_cargo_config)?;
|
||||
let db = host.raw_database();
|
||||
eprint!("{:<20} {}", "Database loaded:", db_load_sw.elapsed());
|
||||
eprint!(" (metadata {}", metadata_time);
|
||||
|
@ -38,7 +38,7 @@ pub fn load_workspace_at(
|
||||
workspace.set_build_scripts(build_scripts)
|
||||
}
|
||||
|
||||
load_workspace(workspace, load_config)
|
||||
load_workspace(workspace, cargo_config, load_config)
|
||||
}
|
||||
|
||||
// Note: Since this function is used by external tools that use rust-analyzer as a library
|
||||
@ -48,6 +48,7 @@ pub fn load_workspace_at(
|
||||
// these tools need access to `ProjectWorkspace`, too, which `load_workspace_at` hides.
|
||||
pub fn load_workspace(
|
||||
ws: ProjectWorkspace,
|
||||
cargo_config: &CargoConfig,
|
||||
load_config: &LoadCargoConfig,
|
||||
) -> Result<(AnalysisHost, vfs::Vfs, Option<ProcMacroServer>)> {
|
||||
let (sender, receiver) = unbounded();
|
||||
@ -75,6 +76,7 @@ pub fn load_workspace(
|
||||
vfs.set_file_contents(path.clone(), contents);
|
||||
vfs.file_id(&path)
|
||||
},
|
||||
cargo_config,
|
||||
);
|
||||
|
||||
let project_folders = ProjectFolders::new(&[ws], &[]);
|
||||
|
@ -299,7 +299,8 @@ impl flags::Lsif {
|
||||
|
||||
let workspace = ProjectWorkspace::load(manifest, &cargo_config, no_progress)?;
|
||||
|
||||
let (host, vfs, _proc_macro) = load_workspace(workspace, &load_cargo_config)?;
|
||||
let (host, vfs, _proc_macro) =
|
||||
load_workspace(workspace, &cargo_config, &load_cargo_config)?;
|
||||
let db = host.raw_database();
|
||||
let analysis = host.analysis();
|
||||
|
||||
|
@ -40,7 +40,7 @@ impl flags::Scip {
|
||||
|
||||
let workspace = ProjectWorkspace::load(manifest, &cargo_config, no_progress)?;
|
||||
|
||||
let (host, vfs, _) = load_workspace(workspace, &load_cargo_config)?;
|
||||
let (host, vfs, _) = load_workspace(workspace, &cargo_config, &load_cargo_config)?;
|
||||
let db = host.raw_database();
|
||||
let analysis = host.analysis();
|
||||
|
||||
|
@ -84,6 +84,9 @@ config_data! {
|
||||
/// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
|
||||
/// avoid checking unnecessary things.
|
||||
cargo_buildScripts_useRustcWrapper: bool = "true",
|
||||
/// Extra environment variables that will be set when running cargo, rustc
|
||||
/// or other commands within the workspace. Useful for setting RUSTFLAGS.
|
||||
cargo_extraEnv: FxHashMap<String, String> = "{}",
|
||||
/// List of features to activate.
|
||||
///
|
||||
/// Set this to `"all"` to pass `--all-features` to cargo.
|
||||
@ -105,6 +108,8 @@ config_data! {
|
||||
checkOnSave_enable: bool = "true",
|
||||
/// Extra arguments for `cargo check`.
|
||||
checkOnSave_extraArgs: Vec<String> = "[]",
|
||||
/// Extra environment variables that will be set when running `cargo check`.
|
||||
checkOnSave_extraEnv: FxHashMap<String, String> = "{}",
|
||||
/// List of features to activate. Defaults to
|
||||
/// `#rust-analyzer.cargo.features#`.
|
||||
///
|
||||
@ -956,6 +961,16 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extra_env(&self) -> &FxHashMap<String, String> {
|
||||
&self.data.cargo_extraEnv
|
||||
}
|
||||
|
||||
pub fn check_on_save_extra_env(&self) -> FxHashMap<String, String> {
|
||||
let mut extra_env = self.data.cargo_extraEnv.clone();
|
||||
extra_env.extend(self.data.checkOnSave_extraEnv.clone());
|
||||
extra_env
|
||||
}
|
||||
|
||||
pub fn lru_capacity(&self) -> Option<usize> {
|
||||
self.data.lru_capacity
|
||||
}
|
||||
@ -1025,6 +1040,7 @@ impl Config {
|
||||
unset_test_crates: UnsetTestCrates::Only(self.data.cargo_unsetTest.clone()),
|
||||
wrap_rustc_in_build_scripts: self.data.cargo_buildScripts_useRustcWrapper,
|
||||
run_build_script_command: self.data.cargo_buildScripts_overrideCommand.clone(),
|
||||
extra_env: self.data.cargo_extraEnv.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1050,7 +1066,11 @@ impl Config {
|
||||
Some(args) if !args.is_empty() => {
|
||||
let mut args = args.clone();
|
||||
let command = args.remove(0);
|
||||
FlycheckConfig::CustomCommand { command, args }
|
||||
FlycheckConfig::CustomCommand {
|
||||
command,
|
||||
args,
|
||||
extra_env: self.check_on_save_extra_env(),
|
||||
}
|
||||
}
|
||||
Some(_) | None => FlycheckConfig::CargoCommand {
|
||||
command: self.data.checkOnSave_command.clone(),
|
||||
@ -1078,6 +1098,7 @@ impl Config {
|
||||
CargoFeatures::Listed(it) => it,
|
||||
},
|
||||
extra_args: self.data.checkOnSave_extraArgs.clone(),
|
||||
extra_env: self.check_on_save_extra_env(),
|
||||
},
|
||||
};
|
||||
Some(flycheck_config)
|
||||
|
@ -1789,6 +1789,7 @@ fn run_rustfmt(
|
||||
let mut command = match snap.config.rustfmt() {
|
||||
RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
|
||||
let mut cmd = process::Command::new(toolchain::rustfmt());
|
||||
cmd.envs(snap.config.extra_env());
|
||||
cmd.args(extra_args);
|
||||
// try to chdir to the file so we can respect `rustfmt.toml`
|
||||
// FIXME: use `rustfmt --config-path` once
|
||||
@ -1846,6 +1847,7 @@ fn run_rustfmt(
|
||||
}
|
||||
RustfmtConfig::CustomCommand { command, args } => {
|
||||
let mut cmd = process::Command::new(command);
|
||||
cmd.envs(snap.config.extra_env());
|
||||
cmd.args(args);
|
||||
cmd
|
||||
}
|
||||
|
@ -143,6 +143,7 @@ impl GlobalState {
|
||||
project_model::ProjectWorkspace::load_inline(
|
||||
it.clone(),
|
||||
cargo_config.target.as_deref(),
|
||||
&cargo_config,
|
||||
)
|
||||
}
|
||||
})
|
||||
@ -398,7 +399,11 @@ impl GlobalState {
|
||||
dummy_replacements.get(crate_name).map(|v| &**v).unwrap_or_default(),
|
||||
)
|
||||
};
|
||||
crate_graph.extend(ws.to_crate_graph(&mut load_proc_macro, &mut load));
|
||||
crate_graph.extend(ws.to_crate_graph(
|
||||
&mut load_proc_macro,
|
||||
&mut load,
|
||||
&self.config.cargo(),
|
||||
));
|
||||
}
|
||||
crate_graph
|
||||
};
|
||||
|
@ -46,6 +46,12 @@ cargo check --quiet --workspace --message-format=json --all-targets
|
||||
Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
|
||||
avoid checking unnecessary things.
|
||||
--
|
||||
[[rust-analyzer.cargo.extraEnv]]rust-analyzer.cargo.extraEnv (default: `{}`)::
|
||||
+
|
||||
--
|
||||
Extra environment variables that will be set when running cargo, rustc
|
||||
or other commands within the workspace. Useful for setting RUSTFLAGS.
|
||||
--
|
||||
[[rust-analyzer.cargo.features]]rust-analyzer.cargo.features (default: `[]`)::
|
||||
+
|
||||
--
|
||||
@ -93,6 +99,11 @@ Run specified `cargo check` command for diagnostics on save.
|
||||
--
|
||||
Extra arguments for `cargo check`.
|
||||
--
|
||||
[[rust-analyzer.checkOnSave.extraEnv]]rust-analyzer.checkOnSave.extraEnv (default: `{}`)::
|
||||
+
|
||||
--
|
||||
Extra environment variables that will be set when running `cargo check`.
|
||||
--
|
||||
[[rust-analyzer.checkOnSave.features]]rust-analyzer.checkOnSave.features (default: `null`)::
|
||||
+
|
||||
--
|
||||
|
@ -437,6 +437,11 @@
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"rust-analyzer.cargo.extraEnv": {
|
||||
"markdownDescription": "Extra environment variables that will be set when running cargo, rustc\nor other commands within the workspace. Useful for setting RUSTFLAGS.",
|
||||
"default": {},
|
||||
"type": "object"
|
||||
},
|
||||
"rust-analyzer.cargo.features": {
|
||||
"markdownDescription": "List of features to activate.\n\nSet this to `\"all\"` to pass `--all-features` to cargo.",
|
||||
"default": [],
|
||||
@ -509,6 +514,11 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"rust-analyzer.checkOnSave.extraEnv": {
|
||||
"markdownDescription": "Extra environment variables that will be set when running `cargo check`.",
|
||||
"default": {},
|
||||
"type": "object"
|
||||
},
|
||||
"rust-analyzer.checkOnSave.features": {
|
||||
"markdownDescription": "List of features to activate. Defaults to\n`#rust-analyzer.cargo.features#`.\n\nSet to `\"all\"` to pass `--all-features` to Cargo.",
|
||||
"default": null,
|
||||
|
Loading…
Reference in New Issue
Block a user