Skip to content

Commit 204c8d7

Browse files
committed
Base relative cargo configs onto the manifest
This is not correct, but should be equivalent in most cases
1 parent 551a91a commit 204c8d7

File tree

1 file changed

+35
-14
lines changed
  • src/tools/rust-analyzer/crates/project-model/src

1 file changed

+35
-14
lines changed

src/tools/rust-analyzer/crates/project-model/src/env.rs

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Cargo-like environment variables injection.
22
use base_db::Env;
3+
use paths::Utf8Path;
34
use rustc_hash::FxHashMap;
45
use toolchain::Tool;
56

@@ -85,7 +86,7 @@ pub(crate) fn cargo_config_env(
8586
// if successful we receive `env.key.value = "value" per entry
8687
tracing::debug!("Discovering cargo config env by {:?}", cargo_config);
8788
utf8_stdout(&mut cargo_config)
88-
.map(parse_output_cargo_config_env)
89+
.map(|stdout| parse_output_cargo_config_env(manifest, stdout))
8990
.inspect(|env| {
9091
tracing::debug!("Discovered cargo config env: {:?}", env);
9192
})
@@ -95,18 +96,38 @@ pub(crate) fn cargo_config_env(
9596
.unwrap_or_default()
9697
}
9798

98-
fn parse_output_cargo_config_env(stdout: String) -> Env {
99-
stdout
100-
.lines()
101-
.filter_map(|l| l.strip_prefix("env."))
102-
.filter_map(|l| l.split_once(" = "))
103-
.filter_map(|(k, v)| {
104-
if k.contains('.') {
105-
k.strip_suffix(".value").zip(Some(v))
106-
} else {
107-
Some((k, v))
99+
fn parse_output_cargo_config_env(manifest: &ManifestPath, stdout: String) -> Env {
100+
let mut env = Env::default();
101+
let mut relatives = vec![];
102+
for (key, val) in
103+
stdout.lines().filter_map(|l| l.strip_prefix("env.")).filter_map(|l| l.split_once(" = "))
104+
{
105+
let val = val.trim_matches('"').to_owned();
106+
if let Some((key, modifier)) = key.split_once('.') {
107+
match modifier {
108+
"relative" => relatives.push((key, val)),
109+
"value" => _ = env.insert(key, val),
110+
_ => {
111+
tracing::warn!(
112+
"Unknown modifier in cargo config env: {}, expected `relative` or `value`",
113+
modifier
114+
);
115+
continue;
116+
}
108117
}
109-
})
110-
.map(|(key, value)| (key.to_owned(), value.trim_matches('"').to_owned()))
111-
.collect()
118+
} else {
119+
env.insert(key, val);
120+
}
121+
}
122+
// FIXME: The base here should be the parent of the `.cargo/config` file, not the manifest.
123+
// But cargo does not provide this information.
124+
let base = <_ as AsRef<Utf8Path>>::as_ref(manifest.parent());
125+
for (key, val) in relatives {
126+
if let Some(val) = env.get(&val) {
127+
env.insert(key, base.join(val).to_string());
128+
} else {
129+
env.insert(key, base.to_string());
130+
}
131+
}
132+
env
112133
}

0 commit comments

Comments
 (0)