mirror of
https://github.com/rust-lang/cargo
synced 2024-08-27 19:29:21 +00:00
Auto merge of #11727 - kylematsuda:config-env, r=ehuss
Read environment variables through `Config` instead of `std::env::var(_os)` ### What does this PR try to resolve? Adds two new methods `get_env` and `get_env_os` for reading environment variables from the `Config` and uses them to replace the many of the calls to `std::env::var` and `var_os` (see the discussion in #11588). Closes #11588
This commit is contained in:
commit
7b98113f6c
|
@ -235,7 +235,7 @@ fn is_executable<P: AsRef<Path>>(path: P) -> bool {
|
|||
}
|
||||
|
||||
fn search_directories(config: &Config) -> Vec<PathBuf> {
|
||||
let mut path_dirs = if let Some(val) = env::var_os("PATH") {
|
||||
let mut path_dirs = if let Some(val) = config.get_env_os("PATH") {
|
||||
env::split_paths(&val).collect()
|
||||
} else {
|
||||
vec![]
|
||||
|
|
|
@ -20,7 +20,6 @@ use cargo_util::{paths, ProcessBuilder};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::{Entry, HashMap};
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::{self, FromStr};
|
||||
|
||||
|
@ -731,7 +730,7 @@ fn extra_args(
|
|||
// NOTE: It is impossible to have a [host] section and reach this logic with kind.is_host(),
|
||||
// since [host] implies `target-applies-to-host = false`, which always early-returns above.
|
||||
|
||||
if let Some(rustflags) = rustflags_from_env(flags) {
|
||||
if let Some(rustflags) = rustflags_from_env(config, flags) {
|
||||
Ok(rustflags)
|
||||
} else if let Some(rustflags) =
|
||||
rustflags_from_target(config, host_triple, target_cfg, kind, flags)?
|
||||
|
@ -746,10 +745,10 @@ fn extra_args(
|
|||
|
||||
/// Gets compiler flags from environment variables.
|
||||
/// See [`extra_args`] for more.
|
||||
fn rustflags_from_env(flags: Flags) -> Option<Vec<String>> {
|
||||
fn rustflags_from_env(config: &Config, flags: Flags) -> Option<Vec<String>> {
|
||||
// First try CARGO_ENCODED_RUSTFLAGS from the environment.
|
||||
// Prefer this over RUSTFLAGS since it's less prone to encoding errors.
|
||||
if let Ok(a) = env::var(format!("CARGO_ENCODED_{}", flags.as_env())) {
|
||||
if let Ok(a) = config.get_env(format!("CARGO_ENCODED_{}", flags.as_env())) {
|
||||
if a.is_empty() {
|
||||
return Some(Vec::new());
|
||||
}
|
||||
|
@ -757,7 +756,7 @@ fn rustflags_from_env(flags: Flags) -> Option<Vec<String>> {
|
|||
}
|
||||
|
||||
// Then try RUSTFLAGS from the environment
|
||||
if let Ok(a) = env::var(flags.as_env()) {
|
||||
if let Ok(a) = config.get_env(flags.as_env()) {
|
||||
let args = a
|
||||
.split(' ')
|
||||
.map(str::trim)
|
||||
|
@ -855,7 +854,7 @@ pub struct RustcTargetData<'cfg> {
|
|||
pub rustc: Rustc,
|
||||
|
||||
/// Config
|
||||
config: &'cfg Config,
|
||||
pub config: &'cfg Config,
|
||||
requested_kinds: Vec<CompileKind>,
|
||||
|
||||
/// Build information for the "host", which is information about when
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//! Type definitions for the result of a compilation.
|
||||
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::env;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
@ -295,7 +294,7 @@ impl<'cfg> Compilation<'cfg> {
|
|||
// These are the defaults when DYLD_FALLBACK_LIBRARY_PATH isn't
|
||||
// set or set to an empty string. Since Cargo is explicitly setting
|
||||
// the value, make sure the defaults still work.
|
||||
if let Some(home) = env::var_os("HOME") {
|
||||
if let Some(home) = self.config.get_env_os("HOME") {
|
||||
search_path.push(PathBuf::from(home).join("lib"));
|
||||
}
|
||||
search_path.push(PathBuf::from("/usr/local/lib"));
|
||||
|
@ -362,7 +361,7 @@ impl<'cfg> Compilation<'cfg> {
|
|||
continue;
|
||||
}
|
||||
|
||||
if value.is_force() || env::var_os(key).is_none() {
|
||||
if value.is_force() || self.config.get_env_os(key).is_none() {
|
||||
cmd.env(key, value.resolve(self.config));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//! See [`CompilationFiles`].
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -628,7 +627,7 @@ fn compute_metadata(
|
|||
|
||||
// Seed the contents of `__CARGO_DEFAULT_LIB_METADATA` to the hasher if present.
|
||||
// This should be the release channel, to get a different hash for each channel.
|
||||
if let Ok(ref channel) = env::var("__CARGO_DEFAULT_LIB_METADATA") {
|
||||
if let Ok(ref channel) = cx.bcx.config.get_env("__CARGO_DEFAULT_LIB_METADATA") {
|
||||
channel.hash(&mut hasher);
|
||||
}
|
||||
|
||||
|
@ -717,7 +716,7 @@ fn should_use_metadata(bcx: &BuildContext<'_, '_>, unit: &Unit) -> bool {
|
|||
|| (unit.target.is_executable() && short_name == "wasm32-unknown-emscripten")
|
||||
|| (unit.target.is_executable() && short_name.contains("msvc")))
|
||||
&& unit.pkg.package_id().source_id().is_path()
|
||||
&& env::var("__CARGO_DEFAULT_LIB_METADATA").is_err()
|
||||
&& bcx.config.get_env("__CARGO_DEFAULT_LIB_METADATA").is_err()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use crate::ops::{self, Packages};
|
|||
use crate::util::errors::CargoResult;
|
||||
use crate::Config;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::BuildConfig;
|
||||
|
@ -222,7 +221,7 @@ pub fn generate_std_roots(
|
|||
}
|
||||
|
||||
fn detect_sysroot_src_path(target_data: &RustcTargetData<'_>) -> CargoResult<PathBuf> {
|
||||
if let Some(s) = env::var_os("__CARGO_TESTS_ONLY_SRC_ROOT") {
|
||||
if let Some(s) = target_data.config.get_env_os("__CARGO_TESTS_ONLY_SRC_ROOT") {
|
||||
return Ok(s.into());
|
||||
}
|
||||
|
||||
|
@ -241,7 +240,7 @@ fn detect_sysroot_src_path(target_data: &RustcTargetData<'_>) -> CargoResult<Pat
|
|||
library, try:\n rustup component add rust-src",
|
||||
lock
|
||||
);
|
||||
match env::var("RUSTUP_TOOLCHAIN") {
|
||||
match target_data.config.get_env("RUSTUP_TOOLCHAIN") {
|
||||
Ok(rustup_toolchain) => {
|
||||
anyhow::bail!("{} --toolchain {}", msg, rustup_toolchain);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ use crate::util::{closest_msg, config, CargoResult, Config};
|
|||
use anyhow::{bail, Context as _};
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::hash::Hash;
|
||||
use std::{cmp, env, fmt, hash};
|
||||
use std::{cmp, fmt, hash};
|
||||
|
||||
/// Collection of all profiles.
|
||||
///
|
||||
|
@ -62,7 +62,7 @@ pub struct Profiles {
|
|||
impl Profiles {
|
||||
pub fn new(ws: &Workspace<'_>, requested_profile: InternedString) -> CargoResult<Profiles> {
|
||||
let config = ws.config();
|
||||
let incremental = match env::var_os("CARGO_INCREMENTAL") {
|
||||
let incremental = match config.get_env_os("CARGO_INCREMENTAL") {
|
||||
Some(v) => Some(v == "1"),
|
||||
None => config.build_config()?.incremental,
|
||||
};
|
||||
|
|
|
@ -215,14 +215,14 @@ pub fn create_bcx<'a, 'cfg>(
|
|||
| CompileMode::Check { .. }
|
||||
| CompileMode::Bench
|
||||
| CompileMode::RunCustomBuild => {
|
||||
if std::env::var("RUST_FLAGS").is_ok() {
|
||||
if ws.config().get_env("RUST_FLAGS").is_ok() {
|
||||
config.shell().warn(
|
||||
"Cargo does not read `RUST_FLAGS` environment variable. Did you mean `RUSTFLAGS`?",
|
||||
)?;
|
||||
}
|
||||
}
|
||||
CompileMode::Doc { .. } | CompileMode::Doctest | CompileMode::Docscrape => {
|
||||
if std::env::var("RUSTDOC_FLAGS").is_ok() {
|
||||
if ws.config().get_env("RUSTDOC_FLAGS").is_ok() {
|
||||
config.shell().warn(
|
||||
"Cargo does not read `RUSTDOC_FLAGS` environment variable. Did you mean `RUSTDOCFLAGS`?"
|
||||
)?;
|
||||
|
|
|
@ -93,7 +93,7 @@ fn maybe_env<'config>(
|
|||
config: &'config Config,
|
||||
key: &ConfigKey,
|
||||
cv: &CV,
|
||||
) -> Option<Vec<(&'config String, &'config String)>> {
|
||||
) -> Option<Vec<(&'config str, &'config str)>> {
|
||||
// Only fetching a table is unable to load env values. Leaf entries should
|
||||
// work properly.
|
||||
match cv {
|
||||
|
@ -102,7 +102,6 @@ fn maybe_env<'config>(
|
|||
}
|
||||
let mut env: Vec<_> = config
|
||||
.env()
|
||||
.iter()
|
||||
.filter(|(env_key, _val)| env_key.starts_with(&format!("{}_", key.as_env_key())))
|
||||
.collect();
|
||||
env.sort_by_key(|x| x.0);
|
||||
|
@ -162,7 +161,7 @@ fn print_toml(config: &Config, opts: &GetOptions<'_>, key: &ConfigKey, cv: &CV)
|
|||
}
|
||||
}
|
||||
|
||||
fn print_toml_env(config: &Config, env: &[(&String, &String)]) {
|
||||
fn print_toml_env(config: &Config, env: &[(&str, &str)]) {
|
||||
drop_println!(
|
||||
config,
|
||||
"# The following environment variables may affect the loaded values."
|
||||
|
@ -173,7 +172,7 @@ fn print_toml_env(config: &Config, env: &[(&String, &String)]) {
|
|||
}
|
||||
}
|
||||
|
||||
fn print_json_env(config: &Config, env: &[(&String, &String)]) {
|
||||
fn print_json_env(config: &Config, env: &[(&str, &str)]) {
|
||||
drop_eprintln!(
|
||||
config,
|
||||
"note: The following environment variables may affect the loaded values."
|
||||
|
@ -287,7 +286,6 @@ fn print_toml_unmerged(config: &Config, opts: &GetOptions<'_>, key: &ConfigKey)
|
|||
// special, and will just naturally get loaded as part of the config.
|
||||
let mut env: Vec<_> = config
|
||||
.env()
|
||||
.iter()
|
||||
.filter(|(env_key, _val)| env_key.starts_with(key.as_env_key()))
|
||||
.collect();
|
||||
if !env.is_empty() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::core::{Shell, Workspace};
|
||||
use crate::ops;
|
||||
use crate::util::config::PathAndArgs;
|
||||
use crate::util::config::{Config, PathAndArgs};
|
||||
use crate::util::CargoResult;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
@ -37,7 +37,7 @@ pub fn doc(ws: &Workspace<'_>, options: &DocOptions) -> CargoResult<()> {
|
|||
|
||||
let mut shell = ws.config().shell();
|
||||
shell.status("Opening", path.display())?;
|
||||
open_docs(&path, &mut shell, config_browser)?;
|
||||
open_docs(&path, &mut shell, config_browser, ws.config())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,9 +48,10 @@ fn open_docs(
|
|||
path: &Path,
|
||||
shell: &mut Shell,
|
||||
config_browser: Option<(PathBuf, Vec<String>)>,
|
||||
config: &Config,
|
||||
) -> CargoResult<()> {
|
||||
let browser =
|
||||
config_browser.or_else(|| Some((PathBuf::from(std::env::var_os("BROWSER")?), Vec::new())));
|
||||
config_browser.or_else(|| Some((PathBuf::from(config.get_env_os("BROWSER")?), Vec::new())));
|
||||
|
||||
match browser {
|
||||
Some((browser, initial_args)) => {
|
||||
|
|
|
@ -704,7 +704,7 @@ pub fn install(
|
|||
if installed_anything {
|
||||
// Print a warning that if this directory isn't in PATH that they won't be
|
||||
// able to run these commands.
|
||||
let path = env::var_os("PATH").unwrap_or_default();
|
||||
let path = config.get_env_os("PATH").unwrap_or_default();
|
||||
let dst_in_path = env::split_paths(&path).any(|path| path == dst);
|
||||
|
||||
if !dst_in_path {
|
||||
|
|
|
@ -463,7 +463,7 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
|
|||
|
||||
pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<NewProjectKind> {
|
||||
// This is here just as a random location to exercise the internal error handling.
|
||||
if std::env::var_os("__CARGO_TEST_INTERNAL_ERROR").is_some() {
|
||||
if config.get_env_os("__CARGO_TEST_INTERNAL_ERROR").is_some() {
|
||||
return Err(crate::util::internal("internal error test"));
|
||||
}
|
||||
|
||||
|
|
|
@ -506,7 +506,7 @@ pub fn resolve_root(flag: Option<&str>, config: &Config) -> CargoResult<Filesyst
|
|||
let config_root = config.get_path("install.root")?;
|
||||
Ok(flag
|
||||
.map(PathBuf::from)
|
||||
.or_else(|| env::var_os("CARGO_INSTALL_ROOT").map(PathBuf::from))
|
||||
.or_else(|| config.get_env_os("CARGO_INSTALL_ROOT").map(PathBuf::from))
|
||||
.or_else(move || config_root.map(|v| v.val))
|
||||
.map(Filesystem::new)
|
||||
.unwrap_or_else(|| config.home().clone()))
|
||||
|
|
|
@ -354,7 +354,8 @@ pub fn fix_exec_rustc(config: &Config, lock_addr: &str) -> CargoResult<()> {
|
|||
let args = FixArgs::get()?;
|
||||
trace!("cargo-fix as rustc got file {:?}", args.file);
|
||||
|
||||
let workspace_rustc = std::env::var("RUSTC_WORKSPACE_WRAPPER")
|
||||
let workspace_rustc = config
|
||||
.get_env("RUSTC_WORKSPACE_WRAPPER")
|
||||
.map(PathBuf::from)
|
||||
.ok();
|
||||
let mut rustc = ProcessBuilder::new(&args.rustc).wrapped(workspace_rustc.as_ref());
|
||||
|
@ -388,7 +389,7 @@ pub fn fix_exec_rustc(config: &Config, lock_addr: &str) -> CargoResult<()> {
|
|||
file: path.clone(),
|
||||
fixes: file.fixes_applied,
|
||||
}
|
||||
.post()?;
|
||||
.post(config)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,7 +404,7 @@ pub fn fix_exec_rustc(config: &Config, lock_addr: &str) -> CargoResult<()> {
|
|||
// user's code with our changes. Back out everything and fall through
|
||||
// below to recompile again.
|
||||
if !output.status.success() {
|
||||
if env::var_os(BROKEN_CODE_ENV).is_none() {
|
||||
if config.get_env_os(BROKEN_CODE_ENV).is_none() {
|
||||
for (path, file) in fixes.files.iter() {
|
||||
debug!("reverting {:?} due to errors", path);
|
||||
paths::write(path, &file.original_code)?;
|
||||
|
@ -420,7 +421,7 @@ pub fn fix_exec_rustc(config: &Config, lock_addr: &str) -> CargoResult<()> {
|
|||
}
|
||||
krate
|
||||
};
|
||||
log_failed_fix(krate, &output.stderr, output.status)?;
|
||||
log_failed_fix(config, krate, &output.stderr, output.status)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,7 +511,8 @@ fn rustfix_crate(
|
|||
// definitely can't make progress, so bail out.
|
||||
let mut fixes = FixedCrate::default();
|
||||
let mut last_fix_counts = HashMap::new();
|
||||
let iterations = env::var("CARGO_FIX_MAX_RETRIES")
|
||||
let iterations = config
|
||||
.get_env("CARGO_FIX_MAX_RETRIES")
|
||||
.ok()
|
||||
.and_then(|n| n.parse().ok())
|
||||
.unwrap_or(4);
|
||||
|
@ -547,7 +549,7 @@ fn rustfix_crate(
|
|||
file: path.clone(),
|
||||
message: error,
|
||||
}
|
||||
.post()?;
|
||||
.post(config)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -576,7 +578,7 @@ fn rustfix_and_fix(
|
|||
// worse by applying fixes where a bug could cause *more* broken code.
|
||||
// Instead, punt upwards which will reexec rustc over the original code,
|
||||
// displaying pretty versions of the diagnostics we just read out.
|
||||
if !output.status.success() && env::var_os(BROKEN_CODE_ENV).is_none() {
|
||||
if !output.status.success() && config.get_env_os(BROKEN_CODE_ENV).is_none() {
|
||||
debug!(
|
||||
"rustfixing `{:?}` failed, rustc exited with {:?}",
|
||||
filename,
|
||||
|
@ -585,7 +587,8 @@ fn rustfix_and_fix(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let fix_mode = env::var_os("__CARGO_FIX_YOLO")
|
||||
let fix_mode = config
|
||||
.get_env_os("__CARGO_FIX_YOLO")
|
||||
.map(|_| rustfix::Filter::Everything)
|
||||
.unwrap_or(rustfix::Filter::MachineApplicableOnly);
|
||||
|
||||
|
@ -710,7 +713,12 @@ fn exit_with(status: ExitStatus) -> ! {
|
|||
process::exit(status.code().unwrap_or(3));
|
||||
}
|
||||
|
||||
fn log_failed_fix(krate: Option<String>, stderr: &[u8], status: ExitStatus) -> CargoResult<()> {
|
||||
fn log_failed_fix(
|
||||
config: &Config,
|
||||
krate: Option<String>,
|
||||
stderr: &[u8],
|
||||
status: ExitStatus,
|
||||
) -> CargoResult<()> {
|
||||
let stderr = str::from_utf8(stderr).context("failed to parse rustc stderr as utf-8")?;
|
||||
|
||||
let diagnostics = stderr
|
||||
|
@ -745,7 +753,7 @@ fn log_failed_fix(krate: Option<String>, stderr: &[u8], status: ExitStatus) -> C
|
|||
errors,
|
||||
abnormal_exit,
|
||||
}
|
||||
.post()?;
|
||||
.post(config)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -895,7 +903,7 @@ impl FixArgs {
|
|||
return Message::Fixing {
|
||||
file: self.file.display().to_string(),
|
||||
}
|
||||
.post()
|
||||
.post(config)
|
||||
.and(Ok(true));
|
||||
}
|
||||
};
|
||||
|
@ -922,7 +930,7 @@ impl FixArgs {
|
|||
message,
|
||||
edition: to_edition.previous().unwrap(),
|
||||
}
|
||||
.post()
|
||||
.post(config)
|
||||
.and(Ok(false)); // Do not run rustfix for this the edition.
|
||||
}
|
||||
let from_edition = self.enabled_edition.unwrap_or(Edition::Edition2015);
|
||||
|
@ -937,14 +945,14 @@ impl FixArgs {
|
|||
message,
|
||||
edition: to_edition,
|
||||
}
|
||||
.post()
|
||||
.post(config)
|
||||
} else {
|
||||
Message::Migrating {
|
||||
file: self.file.display().to_string(),
|
||||
from_edition,
|
||||
to_edition,
|
||||
}
|
||||
.post()
|
||||
.post(config)
|
||||
}
|
||||
.and(Ok(true))
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::cmp;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead};
|
||||
|
@ -6,7 +7,6 @@ use std::path::PathBuf;
|
|||
use std::str;
|
||||
use std::task::Poll;
|
||||
use std::time::Duration;
|
||||
use std::{cmp, env};
|
||||
|
||||
use anyhow::{anyhow, bail, format_err, Context as _};
|
||||
use cargo_util::paths;
|
||||
|
@ -596,7 +596,7 @@ pub fn http_handle_and_timeout(config: &Config) -> CargoResult<(Easy, HttpTimeou
|
|||
pub fn needs_custom_http_transport(config: &Config) -> CargoResult<bool> {
|
||||
Ok(http_proxy_exists(config)?
|
||||
|| *config.http_config()? != Default::default()
|
||||
|| env::var_os("HTTP_TIMEOUT").is_some())
|
||||
|| config.get_env_os("HTTP_TIMEOUT").is_some())
|
||||
}
|
||||
|
||||
/// Configure a libcurl http handle with the defaults options for Cargo
|
||||
|
@ -721,11 +721,16 @@ pub struct HttpTimeout {
|
|||
|
||||
impl HttpTimeout {
|
||||
pub fn new(config: &Config) -> CargoResult<HttpTimeout> {
|
||||
let config = config.http_config()?;
|
||||
let low_speed_limit = config.low_speed_limit.unwrap_or(10);
|
||||
let seconds = config
|
||||
let http_config = config.http_config()?;
|
||||
let low_speed_limit = http_config.low_speed_limit.unwrap_or(10);
|
||||
let seconds = http_config
|
||||
.timeout
|
||||
.or_else(|| env::var("HTTP_TIMEOUT").ok().and_then(|s| s.parse().ok()))
|
||||
.or_else(|| {
|
||||
config
|
||||
.get_env("HTTP_TIMEOUT")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
})
|
||||
.unwrap_or(30);
|
||||
Ok(HttpTimeout {
|
||||
dur: Duration::new(seconds, 0),
|
||||
|
@ -779,7 +784,7 @@ fn http_proxy_exists(config: &Config) -> CargoResult<bool> {
|
|||
} else {
|
||||
Ok(["http_proxy", "HTTP_PROXY", "https_proxy", "HTTPS_PROXY"]
|
||||
.iter()
|
||||
.any(|v| env::var(v).is_ok()))
|
||||
.any(|v| config.get_env(v).is_ok()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ impl<'cfg> SourceConfigMap<'cfg> {
|
|||
},
|
||||
)?;
|
||||
}
|
||||
if let Ok(url) = std::env::var("__CARGO_TEST_CRATES_IO_URL_DO_NOT_USE_THIS") {
|
||||
if let Ok(url) = config.get_env("__CARGO_TEST_CRATES_IO_URL_DO_NOT_USE_THIS") {
|
||||
base.add(
|
||||
CRATES_IO_REGISTRY,
|
||||
SourceConfig {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
//! added (it just adds a little complexity). For example, hostname patterns,
|
||||
//! and revoked markers. See "FIXME" comments littered in this file.
|
||||
|
||||
use crate::util::config::{Definition, Value};
|
||||
use crate::util::config::{Config, Definition, Value};
|
||||
use git2::cert::{Cert, SshHostKeyType};
|
||||
use git2::CertificateCheckStatus;
|
||||
use hmac::Mac;
|
||||
|
@ -111,6 +111,7 @@ impl Display for KnownHostLocation {
|
|||
|
||||
/// The git2 callback used to validate a certificate (only ssh known hosts are validated).
|
||||
pub fn certificate_check(
|
||||
config: &Config,
|
||||
cert: &Cert<'_>,
|
||||
host: &str,
|
||||
port: Option<u16>,
|
||||
|
@ -129,7 +130,12 @@ pub fn certificate_check(
|
|||
_ => host.to_string(),
|
||||
};
|
||||
// The error message must be constructed as a string to pass through the libgit2 C API.
|
||||
let err_msg = match check_ssh_known_hosts(host_key, &host_maybe_port, config_known_hosts) {
|
||||
let err_msg = match check_ssh_known_hosts(
|
||||
config,
|
||||
host_key,
|
||||
&host_maybe_port,
|
||||
config_known_hosts,
|
||||
) {
|
||||
Ok(()) => {
|
||||
return Ok(CertificateCheckStatus::CertificateOk);
|
||||
}
|
||||
|
@ -146,7 +152,7 @@ pub fn certificate_check(
|
|||
// Try checking without the port.
|
||||
if port.is_some()
|
||||
&& !matches!(port, Some(22))
|
||||
&& check_ssh_known_hosts(host_key, host, config_known_hosts).is_ok()
|
||||
&& check_ssh_known_hosts(config, host_key, host, config_known_hosts).is_ok()
|
||||
{
|
||||
return Ok(CertificateCheckStatus::CertificateOk);
|
||||
}
|
||||
|
@ -288,6 +294,7 @@ pub fn certificate_check(
|
|||
|
||||
/// Checks if the given host/host key pair is known.
|
||||
fn check_ssh_known_hosts(
|
||||
config: &Config,
|
||||
cert_host_key: &git2::cert::CertHostkey<'_>,
|
||||
host: &str,
|
||||
config_known_hosts: Option<&Vec<Value<String>>>,
|
||||
|
@ -299,7 +306,7 @@ fn check_ssh_known_hosts(
|
|||
|
||||
// Collect all the known host entries from disk.
|
||||
let mut known_hosts = Vec::new();
|
||||
for path in known_host_files() {
|
||||
for path in known_host_files(config) {
|
||||
if !path.exists() {
|
||||
continue;
|
||||
}
|
||||
|
@ -464,9 +471,12 @@ fn check_ssh_known_hosts_loaded(
|
|||
}
|
||||
|
||||
/// Returns a list of files to try loading OpenSSH-formatted known hosts.
|
||||
fn known_host_files() -> Vec<PathBuf> {
|
||||
fn known_host_files(config: &Config) -> Vec<PathBuf> {
|
||||
let mut result = Vec::new();
|
||||
if std::env::var_os("__CARGO_TEST_DISABLE_GLOBAL_KNOWN_HOST").is_some() {
|
||||
if config
|
||||
.get_env_os("__CARGO_TEST_DISABLE_GLOBAL_KNOWN_HOST")
|
||||
.is_some()
|
||||
{
|
||||
} else if cfg!(unix) {
|
||||
result.push(PathBuf::from("/etc/ssh/ssh_known_hosts"));
|
||||
} else if cfg!(windows) {
|
||||
|
@ -475,7 +485,7 @@ fn known_host_files() -> Vec<PathBuf> {
|
|||
// However, I do not know of a way to obtain that location from
|
||||
// Windows-land. The ProgramData version here is what the PowerShell
|
||||
// port of OpenSSH does.
|
||||
if let Some(progdata) = std::env::var_os("ProgramData") {
|
||||
if let Some(progdata) = config.get_env_os("ProgramData") {
|
||||
let mut progdata = PathBuf::from(progdata);
|
||||
progdata.push("ssh");
|
||||
progdata.push("ssh_known_hosts");
|
||||
|
|
|
@ -12,7 +12,6 @@ use log::{debug, info};
|
|||
use serde::ser;
|
||||
use serde::Serialize;
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::fmt;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
@ -472,7 +471,12 @@ impl<'a> GitCheckout<'a> {
|
|||
/// credentials until we give it a reason to not do so. To ensure we don't
|
||||
/// just sit here looping forever we keep track of authentications we've
|
||||
/// attempted and we don't try the same ones again.
|
||||
fn with_authentication<T, F>(url: &str, cfg: &git2::Config, mut f: F) -> CargoResult<T>
|
||||
fn with_authentication<T, F>(
|
||||
cargo_config: &Config,
|
||||
url: &str,
|
||||
cfg: &git2::Config,
|
||||
mut f: F,
|
||||
) -> CargoResult<T>
|
||||
where
|
||||
F: FnMut(&mut git2::Credentials<'_>) -> CargoResult<T>,
|
||||
{
|
||||
|
@ -577,7 +581,10 @@ where
|
|||
if ssh_username_requested {
|
||||
debug_assert!(res.is_err());
|
||||
let mut attempts = vec![String::from("git")];
|
||||
if let Ok(s) = env::var("USER").or_else(|_| env::var("USERNAME")) {
|
||||
if let Ok(s) = cargo_config
|
||||
.get_env("USER")
|
||||
.or_else(|_| cargo_config.get_env("USERNAME"))
|
||||
{
|
||||
attempts.push(s);
|
||||
}
|
||||
if let Some(ref s) = cred_helper.username {
|
||||
|
@ -730,7 +737,7 @@ pub fn with_fetch_options(
|
|||
let config_known_hosts = ssh_config.and_then(|ssh| ssh.known_hosts.as_ref());
|
||||
let diagnostic_home_config = config.diagnostic_home_config();
|
||||
network::with_retry(config, || {
|
||||
with_authentication(url, git_config, |f| {
|
||||
with_authentication(config, url, git_config, |f| {
|
||||
let port = Url::parse(url).ok().and_then(|url| url.port());
|
||||
let mut last_update = Instant::now();
|
||||
let mut rcb = git2::RemoteCallbacks::new();
|
||||
|
@ -740,6 +747,7 @@ pub fn with_fetch_options(
|
|||
rcb.credentials(f);
|
||||
rcb.certificate_check(|cert, host| {
|
||||
super::known_hosts::certificate_check(
|
||||
config,
|
||||
cert,
|
||||
host,
|
||||
port,
|
||||
|
@ -824,7 +832,7 @@ pub fn fetch(
|
|||
// repo check to see if it's a little too old and could benefit from a gc.
|
||||
// In theory this shouldn't be too expensive compared to the network
|
||||
// request we're about to issue.
|
||||
maybe_gc_repo(repo)?;
|
||||
maybe_gc_repo(repo, config)?;
|
||||
|
||||
clean_repo_temp_files(repo);
|
||||
|
||||
|
@ -978,7 +986,7 @@ fn fetch_with_cli(
|
|||
/// we may not even have `git` installed on the system! As a result we
|
||||
/// opportunistically try a `git gc` when the pack directory looks too big, and
|
||||
/// failing that we just blow away the repository and start over.
|
||||
fn maybe_gc_repo(repo: &mut git2::Repository) -> CargoResult<()> {
|
||||
fn maybe_gc_repo(repo: &mut git2::Repository, config: &Config) -> CargoResult<()> {
|
||||
// Here we arbitrarily declare that if you have more than 100 files in your
|
||||
// `pack` folder that we need to do a gc.
|
||||
let entries = match repo.path().join("objects/pack").read_dir() {
|
||||
|
@ -988,7 +996,8 @@ fn maybe_gc_repo(repo: &mut git2::Repository) -> CargoResult<()> {
|
|||
return Ok(());
|
||||
}
|
||||
};
|
||||
let max = env::var("__CARGO_PACKFILE_LIMIT")
|
||||
let max = config
|
||||
.get_env("__CARGO_PACKFILE_LIMIT")
|
||||
.ok()
|
||||
.and_then(|s| s.parse::<usize>().ok())
|
||||
.unwrap_or(100);
|
||||
|
|
|
@ -674,7 +674,7 @@ impl<'cfg> RegistrySource<'cfg> {
|
|||
}
|
||||
dst.create_dir()?;
|
||||
let mut tar = {
|
||||
let size_limit = max_unpack_size(tarball.metadata()?.len());
|
||||
let size_limit = max_unpack_size(self.config, tarball.metadata()?.len());
|
||||
let gz = GzDecoder::new(tarball);
|
||||
let gz = LimitErrorReader::new(gz, size_limit);
|
||||
Archive::new(gz)
|
||||
|
@ -918,21 +918,23 @@ impl<'cfg> Source for RegistrySource<'cfg> {
|
|||
/// * <https://cran.r-project.org/web/packages/brotli/vignettes/brotli-2015-09-22.pdf>
|
||||
/// * <https://blog.cloudflare.com/results-experimenting-brotli/>
|
||||
/// * <https://tukaani.org/lzma/benchmarks.html>
|
||||
fn max_unpack_size(size: u64) -> u64 {
|
||||
fn max_unpack_size(config: &Config, size: u64) -> u64 {
|
||||
const SIZE_VAR: &str = "__CARGO_TEST_MAX_UNPACK_SIZE";
|
||||
const RATIO_VAR: &str = "__CARGO_TEST_MAX_UNPACK_RATIO";
|
||||
let max_unpack_size = if cfg!(debug_assertions) && std::env::var(SIZE_VAR).is_ok() {
|
||||
let max_unpack_size = if cfg!(debug_assertions) && config.get_env(SIZE_VAR).is_ok() {
|
||||
// For integration test only.
|
||||
std::env::var(SIZE_VAR)
|
||||
config
|
||||
.get_env(SIZE_VAR)
|
||||
.unwrap()
|
||||
.parse()
|
||||
.expect("a max unpack size in bytes")
|
||||
} else {
|
||||
MAX_UNPACK_SIZE
|
||||
};
|
||||
let max_compression_ratio = if cfg!(debug_assertions) && std::env::var(RATIO_VAR).is_ok() {
|
||||
let max_compression_ratio = if cfg!(debug_assertions) && config.get_env(RATIO_VAR).is_ok() {
|
||||
// For integration test only.
|
||||
std::env::var(RATIO_VAR)
|
||||
config
|
||||
.get_env(RATIO_VAR)
|
||||
.unwrap()
|
||||
.parse()
|
||||
.expect("a max compression ratio in bytes")
|
||||
|
|
|
@ -182,7 +182,6 @@ pub fn registry_credential_config(
|
|||
let index = sid.canonical_url();
|
||||
let mut names: Vec<_> = config
|
||||
.env()
|
||||
.iter()
|
||||
.filter_map(|(k, v)| {
|
||||
Some((
|
||||
k.strip_prefix("CARGO_REGISTRIES_")?
|
||||
|
|
|
@ -215,7 +215,7 @@ impl<'config> ConfigMapAccess<'config> {
|
|||
if de.config.cli_unstable().advanced_env {
|
||||
// `CARGO_PROFILE_DEV_PACKAGE_`
|
||||
let env_prefix = format!("{}_", de.key.as_env_key());
|
||||
for env_key in de.config.env.keys() {
|
||||
for env_key in de.config.env_keys() {
|
||||
if env_key.starts_with(&env_prefix) {
|
||||
// `CARGO_PROFILE_DEV_PACKAGE_bar_OPT_LEVEL = 3`
|
||||
let rest = &env_key[env_prefix.len()..];
|
||||
|
@ -265,7 +265,7 @@ impl<'config> ConfigMapAccess<'config> {
|
|||
for field in given_fields {
|
||||
let mut field_key = de.key.clone();
|
||||
field_key.push(field);
|
||||
for env_key in de.config.env.keys() {
|
||||
for env_key in de.config.env_keys() {
|
||||
if env_key.starts_with(field_key.as_env_key()) {
|
||||
fields.insert(KeyKind::Normal(field.to_string()));
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ impl<'config> ValueDeserializer<'config> {
|
|||
let definition = {
|
||||
let env = de.key.as_env_key();
|
||||
let env_def = Definition::Environment(env.to_string());
|
||||
match (de.config.env.contains_key(env), de.config.get_cv(&de.key)?) {
|
||||
match (de.config.env_has_key(env), de.config.get_cv(&de.key)?) {
|
||||
(true, Some(cv)) => {
|
||||
// Both, pick highest priority.
|
||||
if env_def.is_higher_priority(cv.definition()) {
|
||||
|
|
|
@ -54,7 +54,7 @@ use std::cell::{RefCell, RefMut};
|
|||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt;
|
||||
use std::fs::{self, File};
|
||||
use std::io::prelude::*;
|
||||
|
@ -106,7 +106,7 @@ macro_rules! get_value_typed {
|
|||
/// Low-level private method for getting a config value as an OptValue.
|
||||
fn $name(&self, key: &ConfigKey) -> Result<OptValue<$ty>, ConfigError> {
|
||||
let cv = self.get_cv(key)?;
|
||||
let env = self.get_env::<$ty>(key)?;
|
||||
let env = self.get_config_env::<$ty>(key)?;
|
||||
match (cv, env) {
|
||||
(Some(CV::$variant(val, definition)), Some(env)) => {
|
||||
if definition.is_higher_priority(&env.definition) {
|
||||
|
@ -200,7 +200,7 @@ pub struct Config {
|
|||
/// Target Directory via resolved Cli parameter
|
||||
target_dir: Option<Filesystem>,
|
||||
/// Environment variables, separated to assist testing.
|
||||
env: HashMap<String, String>,
|
||||
env: HashMap<OsString, OsString>,
|
||||
/// Environment variables, converted to uppercase to check for case mismatch
|
||||
upper_case_env: HashMap<String, String>,
|
||||
/// Tracks which sources have been updated to avoid multiple updates.
|
||||
|
@ -260,23 +260,16 @@ impl Config {
|
|||
}
|
||||
});
|
||||
|
||||
let env: HashMap<_, _> = env::vars_os()
|
||||
.filter_map(|(k, v)| {
|
||||
// Ignore any key/values that are not valid Unicode.
|
||||
match (k.into_string(), v.into_string()) {
|
||||
(Ok(k), Ok(v)) => Some((k, v)),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let env: HashMap<_, _> = env::vars_os().collect();
|
||||
|
||||
let upper_case_env = env
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|(k, _)| (k.to_uppercase().replace("-", "_"), k))
|
||||
.iter()
|
||||
.filter_map(|(k, _)| k.to_str()) // Only keep valid UTF-8
|
||||
.map(|k| (k.to_uppercase().replace("-", "_"), k.to_owned()))
|
||||
.collect();
|
||||
|
||||
let cache_rustc_info = match env.get("CARGO_CACHE_RUSTC_INFO") {
|
||||
let cache_key: &OsStr = "CARGO_CACHE_RUSTC_INFO".as_ref();
|
||||
let cache_rustc_info = match env.get(cache_key) {
|
||||
Some(cache) => cache != "0",
|
||||
_ => true,
|
||||
};
|
||||
|
@ -440,17 +433,18 @@ impl Config {
|
|||
pub fn cargo_exe(&self) -> CargoResult<&Path> {
|
||||
self.cargo_exe
|
||||
.try_borrow_with(|| {
|
||||
fn from_env() -> CargoResult<PathBuf> {
|
||||
let from_env = || -> CargoResult<PathBuf> {
|
||||
// Try re-using the `cargo` set in the environment already. This allows
|
||||
// commands that use Cargo as a library to inherit (via `cargo <subcommand>`)
|
||||
// or set (by setting `$CARGO`) a correct path to `cargo` when the current exe
|
||||
// is not actually cargo (e.g., `cargo-*` binaries, Valgrind, `ld.so`, etc.).
|
||||
let exe = env::var_os(crate::CARGO_ENV)
|
||||
let exe = self
|
||||
.get_env_os(crate::CARGO_ENV)
|
||||
.map(PathBuf::from)
|
||||
.ok_or_else(|| anyhow!("$CARGO not set"))?
|
||||
.canonicalize()?;
|
||||
Ok(exe)
|
||||
}
|
||||
};
|
||||
|
||||
fn from_current_exe() -> CargoResult<PathBuf> {
|
||||
// Try fetching the path to `cargo` using `env::current_exe()`.
|
||||
|
@ -565,7 +559,7 @@ impl Config {
|
|||
pub fn target_dir(&self) -> CargoResult<Option<Filesystem>> {
|
||||
if let Some(dir) = &self.target_dir {
|
||||
Ok(Some(dir.clone()))
|
||||
} else if let Some(dir) = self.env.get("CARGO_TARGET_DIR") {
|
||||
} else if let Some(dir) = self.get_env_os("CARGO_TARGET_DIR") {
|
||||
// Check if the CARGO_TARGET_DIR environment variable is set to an empty string.
|
||||
if dir.is_empty() {
|
||||
bail!(
|
||||
|
@ -663,7 +657,7 @@ impl Config {
|
|||
// Root table can't have env value.
|
||||
return Ok(cv);
|
||||
}
|
||||
let env = self.env.get(key.as_env_key());
|
||||
let env = self.get_env_str(key.as_env_key());
|
||||
let env_def = Definition::Environment(key.as_env_key().to_string());
|
||||
let use_env = match (&cv, env) {
|
||||
// Lists are always merged.
|
||||
|
@ -734,20 +728,28 @@ impl Config {
|
|||
|
||||
/// Helper primarily for testing.
|
||||
pub fn set_env(&mut self, env: HashMap<String, String>) {
|
||||
self.env = env;
|
||||
self.env = env.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
|
||||
}
|
||||
|
||||
/// Returns all environment variables.
|
||||
pub(crate) fn env(&self) -> &HashMap<String, String> {
|
||||
&self.env
|
||||
/// Returns all environment variables as an iterator, filtering out entries
|
||||
/// that are not valid UTF-8.
|
||||
pub(crate) fn env(&self) -> impl Iterator<Item = (&str, &str)> {
|
||||
self.env
|
||||
.iter()
|
||||
.filter_map(|(k, v)| Some((k.to_str()?, v.to_str()?)))
|
||||
}
|
||||
|
||||
fn get_env<T>(&self, key: &ConfigKey) -> Result<OptValue<T>, ConfigError>
|
||||
/// Returns all environment variable keys, filtering out entries that are not valid UTF-8.
|
||||
fn env_keys(&self) -> impl Iterator<Item = &str> {
|
||||
self.env.iter().filter_map(|(k, _)| k.to_str())
|
||||
}
|
||||
|
||||
fn get_config_env<T>(&self, key: &ConfigKey) -> Result<OptValue<T>, ConfigError>
|
||||
where
|
||||
T: FromStr,
|
||||
<T as FromStr>::Err: fmt::Display,
|
||||
{
|
||||
match self.env.get(key.as_env_key()) {
|
||||
match self.get_env_str(key.as_env_key()) {
|
||||
Some(value) => {
|
||||
let definition = Definition::Environment(key.as_env_key().to_string());
|
||||
Ok(Some(Value {
|
||||
|
@ -764,16 +766,48 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the value of environment variable `key` through the `Config` snapshot.
|
||||
///
|
||||
/// This can be used similarly to `std::env::var`.
|
||||
pub fn get_env(&self, key: impl AsRef<OsStr>) -> CargoResult<String> {
|
||||
let key = key.as_ref();
|
||||
let s = match self.env.get(key) {
|
||||
Some(s) => s,
|
||||
None => bail!("{key:?} could not be found in the environment snapshot",),
|
||||
};
|
||||
match s.to_str() {
|
||||
Some(s) => Ok(s.to_owned()),
|
||||
None => bail!("environment variable value is not valid unicode: {s:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the value of environment variable `key` through the `Config` snapshot.
|
||||
///
|
||||
/// This can be used similarly to `std::env::var_os`.
|
||||
pub fn get_env_os(&self, key: impl AsRef<OsStr>) -> Option<OsString> {
|
||||
self.env.get(key.as_ref()).cloned()
|
||||
}
|
||||
|
||||
/// Get the value of environment variable `key`.
|
||||
/// Returns `None` if `key` is not in `self.env` or if the value is not valid UTF-8.
|
||||
fn get_env_str(&self, key: impl AsRef<OsStr>) -> Option<&str> {
|
||||
self.env.get(key.as_ref()).and_then(|s| s.to_str())
|
||||
}
|
||||
|
||||
fn env_has_key(&self, key: impl AsRef<OsStr>) -> bool {
|
||||
self.env.contains_key(key.as_ref())
|
||||
}
|
||||
|
||||
/// Check if the [`Config`] contains a given [`ConfigKey`].
|
||||
///
|
||||
/// See `ConfigMapAccess` for a description of `env_prefix_ok`.
|
||||
fn has_key(&self, key: &ConfigKey, env_prefix_ok: bool) -> CargoResult<bool> {
|
||||
if self.env.contains_key(key.as_env_key()) {
|
||||
if self.env_has_key(key.as_env_key()) {
|
||||
return Ok(true);
|
||||
}
|
||||
if env_prefix_ok {
|
||||
let env_prefix = format!("{}_", key.as_env_key());
|
||||
if self.env.keys().any(|k| k.starts_with(&env_prefix)) {
|
||||
if self.env_keys().any(|k| k.starts_with(&env_prefix)) {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
@ -885,7 +919,7 @@ impl Config {
|
|||
key: &ConfigKey,
|
||||
output: &mut Vec<(String, Definition)>,
|
||||
) -> CargoResult<()> {
|
||||
let env_val = match self.env.get(key.as_env_key()) {
|
||||
let env_val = match self.get_env_str(key.as_env_key()) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
self.check_environment_key_case_mismatch(key);
|
||||
|
@ -1616,12 +1650,9 @@ impl Config {
|
|||
) -> Option<PathBuf> {
|
||||
let var = tool.to_uppercase();
|
||||
|
||||
match env::var_os(&var) {
|
||||
match self.get_env_os(&var).as_ref().and_then(|s| s.to_str()) {
|
||||
Some(tool_path) => {
|
||||
let maybe_relative = match tool_path.to_str() {
|
||||
Some(s) => s.contains('/') || s.contains('\\'),
|
||||
None => false,
|
||||
};
|
||||
let maybe_relative = tool_path.contains('/') || tool_path.contains('\\');
|
||||
let path = if maybe_relative {
|
||||
self.cwd.join(tool_path)
|
||||
} else {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
//! cross-platform way for the `cargo fix` command.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::io::{BufReader, Read, Write};
|
||||
use std::net::{Shutdown, SocketAddr, TcpListener, TcpStream};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
@ -61,9 +60,10 @@ pub enum Message {
|
|||
}
|
||||
|
||||
impl Message {
|
||||
pub fn post(&self) -> Result<(), Error> {
|
||||
let addr =
|
||||
env::var(DIAGNOSTICS_SERVER_VAR).context("diagnostics collector misconfigured")?;
|
||||
pub fn post(&self, config: &Config) -> Result<(), Error> {
|
||||
let addr = config
|
||||
.get_env(DIAGNOSTICS_SERVER_VAR)
|
||||
.context("diagnostics collector misconfigured")?;
|
||||
let mut client =
|
||||
TcpStream::connect(&addr).context("failed to connect to parent diagnostics target")?;
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use std::cmp;
|
||||
use std::env;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::core::shell::Verbosity;
|
||||
|
@ -44,7 +43,7 @@ impl<'cfg> Progress<'cfg> {
|
|||
// report no progress when -q (for quiet) or TERM=dumb are set
|
||||
// or if running on Continuous Integration service like Travis where the
|
||||
// output logs get mangled.
|
||||
let dumb = match env::var("TERM") {
|
||||
let dumb = match cfg.get_env("TERM") {
|
||||
Ok(term) => term == "dumb",
|
||||
Err(_) => false,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue