Skip to content

Commit be5a562

Browse files
committed
Dummy commit.
1 parent 4e79118 commit be5a562

File tree

5 files changed

+139
-32
lines changed

5 files changed

+139
-32
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ directories = "4.0.1"
4848
walkdir = { version = "2", optional = true }
4949
tempfile = "3.3.0"
5050
owo-colors = { version = "3.4.0", features = ["supports-colors"] }
51+
once_cell = "1.12"
5152

5253
[target.'cfg(not(windows))'.dependencies]
5354
nix = { version = "0.24", default-features = false, features = ["user"] }

src/cargo_toml.rs renamed to src/cargo_config.rs

+132-18
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,44 @@ use std::path::Path;
44

55
use crate::errors::*;
66
use crate::file;
7+
use crate::shell::MessageInfo;
8+
use once_cell::sync::OnceCell;
79

810
type Table = toml::value::Table;
911
type Value = toml::value::Value;
1012

13+
pub const CARGO_NO_PREFIX_ENVVARS: &[&str] = &[
14+
"http_proxy",
15+
"TERM",
16+
"RUSTDOCFLAGS",
17+
"RUSTFLAGS",
18+
"BROWSER",
19+
"HTTPS_PROXY",
20+
"HTTP_TIMEOUT",
21+
"https_proxy",
22+
];
23+
24+
// TODO(ahuszagh) This should really be cargo_toml and cargo_env.
25+
// Should have it as a once_cell?
26+
27+
// CARGO_ALIAS_
28+
1129
// the strategy is to merge, with arrays merging together
1230
// and the deeper the config file is, the higher its priority.
1331
// arrays merge, numbers/strings get replaced, objects merge in.
1432
// we don't want to make any assumptions about the cargo
1533
// config data, in case we need to use it later.
1634
#[derive(Debug, Clone, Default)]
17-
pub struct CargoConfig(Table);
35+
pub struct CargoToml(Table);
1836

19-
impl CargoConfig {
20-
fn merge(&mut self, parent: &CargoConfig) -> Result<()> {
37+
impl CargoToml {
38+
fn parse(path: &Path) -> Result<CargoToml> {
39+
let contents = file::read(&path)
40+
.wrap_err_with(|| format!("could not read cargo config file at `{path:?}`"))?;
41+
Ok(CargoToml(toml::from_str(&contents)?))
42+
}
43+
44+
fn merge(&mut self, parent: &CargoToml) -> Result<()> {
2145
// can error on mismatched-data
2246

2347
fn validate_types(x: &Value, y: &Value) -> Option<()> {
@@ -66,6 +90,8 @@ impl CargoConfig {
6690
}
6791

6892
// get all the aliases from the map
93+
// TODO(ahuszagh) This needs to be an result of an option.
94+
// If we don't have as_str, needs to fail as a result
6995
pub fn alias<'a>(&'a self) -> Option<BTreeMap<&'a str, Vec<&'a str>>> {
7096
let parse_alias = |v: &'a Value| -> Option<Vec<&'a str>> {
7197
if let Some(s) = v.as_str() {
@@ -86,35 +112,99 @@ impl CargoConfig {
86112
}
87113
}
88114

89-
fn parse_config_file(path: &Path) -> Result<CargoConfig> {
90-
let contents = file::read(&path)
91-
.wrap_err_with(|| format!("could not read cargo config file `{path:?}`"))?;
92-
Ok(CargoConfig(toml::from_str(&contents)?))
115+
// wrapper for all the cargo environment variables.
116+
#[derive(Debug, Clone, Default)]
117+
pub struct CargoEnv(BTreeMap<String, String>);
118+
119+
impl CargoEnv {
120+
fn create() -> CargoEnv {
121+
let mut result = BTreeMap::new();
122+
for (key, value) in env::vars() {
123+
if key.starts_with("CARGO_") || CARGO_NO_PREFIX_ENVVARS.contains(&key.as_str()) {
124+
result.insert(key, value);
125+
}
126+
}
127+
128+
CargoEnv(result)
129+
}
130+
131+
// get all the aliases from the map
132+
pub fn alias<'a>(&'a self) -> Result<BTreeMap<String, Vec<&'a str>>> {
133+
let mut result = BTreeMap::new();
134+
for (key, value) in &self.0 {
135+
if let Some(alias) = key.strip_prefix("CARGO_ALIAS_") {
136+
// cargo skips empty aliases
137+
match alias.chars().all(char::is_uppercase) {
138+
true if !alias.is_empty() => {
139+
let value = value.split_whitespace().collect();
140+
result.insert(key.to_lowercase(), value);
141+
}
142+
false => {
143+
MessageInfo::default().warn(format_args!(
144+
"Environment variables are expected to use uppercase letters and underscores, the variable `{key}` will be ignored and have no effect"
145+
))?;
146+
}
147+
// `CARGO_ALIAS_` is ignored
148+
_ => (),
149+
}
150+
}
151+
}
152+
153+
Ok(result)
154+
}
155+
}
156+
157+
// merged result of cargo TOML config and environment variables
158+
// we use a toml setting here, since it abstracts the types
159+
#[derive(Debug, Clone, Default)]
160+
pub struct CargoConfig(BTreeMap<String, Value>);
161+
162+
impl CargoConfig {
163+
fn create(config_toml: &CargoToml, config_env: &CargoEnv) -> Result<CargoConfig> {
164+
let mut result = BTreeMap::new();
165+
let toml_aliases = config_toml.alias(); // TODO(ahuszagh) Must be used
166+
let env_aliases = config_env.alias()?;
167+
// TODO(ahuszagh) Here...
168+
// We only care about values we actually know.
169+
170+
171+
// for (key, value) in env::vars() {
172+
// if key.starts_with("CARGO_") || CARGO_NO_PREFIX_ENVVARS.contains(&key.as_str()) {
173+
// result.insert(key, value);
174+
// }
175+
// }
176+
177+
Ok(CargoConfig(result))
178+
}
179+
180+
fn alias(&self) -> BTreeMap<String, Vec<String>> {
181+
todo!();
182+
}
93183
}
94184

95185
// finding cargo config files actually runs from the
96186
// current working directory the command is invoked,
97187
// not from the project root. same is true with work
98188
// spaces: the project layout does not matter.
99-
pub fn read_config_files() -> Result<CargoConfig> {
189+
pub fn read_config_files() -> Result<CargoToml> {
100190
// note: cargo supports both `config` and `config.toml`
101191
// `config` exists for compatibility reasons, but if
102192
// present, only it will be read.
103-
let read_and_merge = |result: &mut CargoConfig, dir: &Path| -> Result<()> {
193+
let read_and_merge = |result: &mut CargoToml, dir: &Path| -> Result<()> {
104194
let noext = dir.join("config");
105195
let ext = dir.join("config.toml");
106196
if noext.exists() {
107-
let parent = parse_config_file(&noext)?;
197+
let parent = CargoToml::parse(&noext)?;
108198
result.merge(&parent)?;
109199
} else if ext.exists() {
110-
let parent = parse_config_file(&ext)?;
200+
let parent = CargoToml::parse(&ext)?;
111201
result.merge(&parent)?;
112202
}
113203

114204
Ok(())
115205
};
116206

117-
let mut result = CargoConfig::default();
207+
let mut result = CargoToml::default();
118208
let cwd = env::current_dir()?;
119209
let mut dir: &Path = &cwd;
120210
loop {
@@ -131,14 +221,40 @@ pub fn read_config_files() -> Result<CargoConfig> {
131221
Ok(result)
132222
}
133223

224+
static CARGO_TOML: OnceCell<CargoToml> = OnceCell::new();
225+
226+
pub fn get_cargo_toml() -> &'static CargoToml {
227+
CARGO_TOML
228+
.get_or_try_init::<_, eyre::Report>(|| {
229+
read_config_files()
230+
})
231+
.unwrap()
232+
}
233+
234+
static CARGO_ENV: OnceCell<CargoEnv> = OnceCell::new();
235+
236+
pub fn get_cargo_env() -> &'static CargoEnv {
237+
CARGO_ENV.get_or_init(|| CargoEnv::create())
238+
}
239+
240+
static CARGO_CONFIG: OnceCell<CargoConfig> = OnceCell::new();
241+
242+
pub fn get_cargo_config() -> &'static CargoConfig {
243+
CARGO_CONFIG
244+
.get_or_try_init::<_, eyre::Report>(|| {
245+
CargoConfig::create(get_cargo_toml(), get_cargo_env())
246+
})
247+
.unwrap()
248+
}
249+
134250
#[cfg(test)]
135251
mod tests {
136252
use super::*;
137253

138254
#[test]
139255
fn test_parse() -> Result<()> {
140-
let config1 = CargoConfig(toml::from_str(CARGO_TOML1)?);
141-
let config2 = CargoConfig(toml::from_str(CARGO_TOML2)?);
256+
let config1 = CargoToml(toml::from_str(CARGO_TOML1)?);
257+
let config2 = CargoToml(toml::from_str(CARGO_TOML2)?);
142258
let alias1 = config1.alias().expect("unable to get aliases.");
143259
let alias2 = config2.alias().expect("unable to get aliases.");
144260
assert_eq!(
@@ -184,9 +300,9 @@ mod tests {
184300
}
185301

186302
#[test]
187-
fn test_read_config() -> Result<()> {
303+
fn test_read_config() {
188304
// cross contains a few aliases, so test those
189-
let config = read_config_files()?;
305+
let config = get_cargo_toml();
190306
let aliases = config.alias().expect("must have aliases");
191307
assert_eq!(
192308
aliases.get("build-docker-image"),
@@ -196,8 +312,6 @@ mod tests {
196312
aliases.get("xtask"),
197313
Some(&vec!["run", "-p", "xtask", "--"]),
198314
);
199-
200-
Ok(())
201315
}
202316

203317
const CARGO_TOML1: &str = r#"

src/cli.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::{env, path::PathBuf};
22

33
use crate::cargo::Subcommand;
4-
use crate::cargo_toml::read_config_files;
4+
// TODO(ahuszagh) Change to get_cargo_config
5+
use crate::cargo_config::get_cargo_toml;
56
use crate::errors::Result;
67
use crate::rustc::TargetList;
78
use crate::shell::{self, MessageInfo};
@@ -150,7 +151,7 @@ fn parse_subcommand(
150151
}
151152
let subcommand = Subcommand::from(arg.as_ref());
152153
if subcommand == Subcommand::Other {
153-
let config = read_config_files()?;
154+
let config = get_cargo_toml();
154155
if let Some(aliases) = config.alias() {
155156
if let Some(alias) = aliases.get(arg.as_str()) {
156157
let mut iter = alias.iter().cloned().map(|x| x.to_owned());

src/docker/shared.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::{env, fs};
66
use super::custom::{Dockerfile, PreBuild};
77
use super::engine::*;
88
use crate::cargo::{cargo_metadata_with_args, CargoMetadata};
9+
use crate::cargo_config::CARGO_NO_PREFIX_ENVVARS;
910
use crate::config::{bool_from_envvar, Config};
1011
use crate::errors::*;
1112
use crate::extensions::{CommandExt, SafeCommand};
@@ -425,16 +426,6 @@ pub(crate) fn cargo_safe_command(uses_xargo: bool) -> SafeCommand {
425426
}
426427

427428
fn add_cargo_configuration_envvars(docker: &mut Command) {
428-
let non_cargo_prefix = &[
429-
"http_proxy",
430-
"TERM",
431-
"RUSTDOCFLAGS",
432-
"RUSTFLAGS",
433-
"BROWSER",
434-
"HTTPS_PROXY",
435-
"HTTP_TIMEOUT",
436-
"https_proxy",
437-
];
438429
let cargo_prefix_skip = &[
439430
"CARGO_HOME",
440431
"CARGO_TARGET_DIR",
@@ -445,7 +436,7 @@ fn add_cargo_configuration_envvars(docker: &mut Command) {
445436
"CARGO_BUILD_RUSTDOC",
446437
];
447438
let is_cargo_passthrough = |key: &str| -> bool {
448-
non_cargo_prefix.contains(&key)
439+
CARGO_NO_PREFIX_ENVVARS.contains(&key)
449440
|| key.starts_with("CARGO_") && !cargo_prefix_skip.contains(&key)
450441
};
451442

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
mod tests;
3232

3333
mod cargo;
34-
mod cargo_toml;
34+
mod cargo_config;
3535
mod cli;
3636
mod config;
3737
mod cross_toml;

0 commit comments

Comments
 (0)