Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/bin/cargo/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
if let Some(path) = args.value_of_path("path", config) {
config.reload_rooted_at(path)?;
} else {
// TODO: Consider calling set_search_stop_path(home).
config.reload_rooted_at(config.home().clone().into_path_unlocked())?;
}

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ impl<'cfg> Workspace<'cfg> {
}
}

for path in paths::ancestors(manifest_path).skip(2) {
for path in paths::ancestors(manifest_path, None).skip(2) {
if path.ends_with("target/package") {
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ fn find_tests_git_config(path: &Path) -> Option<GitConfig> {
// Don't escape the test sandbox when looking for a git repository.
// NOTE: libgit2 has support to define the path ceiling in
// git_repository_discover, but the git2 bindings do not expose that.
for path in paths::ancestors(path) {
for path in paths::ancestors(path, None) {
if let Ok(repo) = GitRepository::open(path) {
return Some(repo.config().expect("test repo should have valid config"));
}
Expand Down
13 changes: 12 additions & 1 deletion src/cargo/util/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ pub struct Config {
cli_config: Option<Vec<String>>,
/// The current working directory of cargo
cwd: PathBuf,
/// Directory where config file searching should stop (inclusive).
search_stop_path: Option<PathBuf>,
/// The location of the cargo executable (path to current process)
cargo_exe: LazyCell<PathBuf>,
/// The location of the rustdoc executable
Expand Down Expand Up @@ -218,6 +220,7 @@ impl Config {
home_path: Filesystem::new(homedir),
shell: RefCell::new(shell),
cwd,
search_stop_path: None,
values: LazyCell::new(),
cli_config: None,
cargo_exe: LazyCell::new(),
Expand Down Expand Up @@ -422,6 +425,14 @@ impl Config {
}
}

/// Sets the path where ancestor config file searching will stop. The
/// given path is included, but its ancestors are not.
pub fn set_search_stop_path<P: Into<PathBuf>>(&mut self, path: P) {
let path = path.into();
debug_assert!(self.cwd.starts_with(&path));
self.search_stop_path = Some(path);
}

/// Reloads on-disk configuration values, starting at the given path and
/// walking up its ancestors.
pub fn reload_rooted_at<P: AsRef<Path>>(&mut self, path: P) -> CargoResult<()> {
Expand Down Expand Up @@ -1028,7 +1039,7 @@ impl Config {
{
let mut stash: HashSet<PathBuf> = HashSet::new();

for current in paths::ancestors(pwd) {
for current in paths::ancestors(pwd, self.search_stop_path.as_deref()) {
if let Some(path) = self.get_file_path(&current.join(".cargo"), "config", true)? {
walk(&path)?;
stash.insert(path);
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/util/important_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
/// Finds the root `Cargo.toml`.
pub fn find_root_manifest_for_wd(cwd: &Path) -> CargoResult<PathBuf> {
let file = "Cargo.toml";
for current in paths::ancestors(cwd) {
for current in paths::ancestors(cwd, None) {
let manifest = current.join(file);
if manifest.exists() {
return Ok(manifest);
Expand Down
12 changes: 8 additions & 4 deletions src/cargo/util/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ pub fn bytes2path(bytes: &[u8]) -> CargoResult<PathBuf> {
}
}

pub fn ancestors(path: &Path) -> PathAncestors<'_> {
PathAncestors::new(path)
pub fn ancestors<'a>(path: &'a Path, stop_root_at: Option<&Path>) -> PathAncestors<'a> {
PathAncestors::new(path, stop_root_at)
}

pub struct PathAncestors<'a> {
Expand All @@ -316,11 +316,15 @@ pub struct PathAncestors<'a> {
}

impl<'a> PathAncestors<'a> {
fn new(path: &Path) -> PathAncestors<'_> {
fn new(path: &'a Path, stop_root_at: Option<&Path>) -> PathAncestors<'a> {
let stop_at = env::var("__CARGO_TEST_ROOT")
.ok()
.map(PathBuf::from)
.or_else(|| stop_root_at.map(|p| p.to_path_buf()));
PathAncestors {
current: Some(path),
//HACK: avoid reading `~/.cargo/config` when testing Cargo itself.
stop_at: env::var("__CARGO_TEST_ROOT").ok().map(PathBuf::from),
stop_at,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions tests/testsuite/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ impl ConfigBuilder {
let homedir = paths::home();
let mut config = Config::new(shell, cwd, homedir);
config.set_env(self.env.clone());
config.set_search_stop_path(paths::root());
config.configure(
0,
false,
Expand Down