From 35b029c2ce5d8d047454653d2524251df004dca1 Mon Sep 17 00:00:00 2001 From: Franz-Xaver Geiger Date: Mon, 23 Nov 2020 12:49:52 +0100 Subject: [PATCH] Start searching git config at path of the new project This lets `cargo new` follow `includeIf` blocks inside .gitignore. Fixes #8882 --- src/cargo/ops/cargo_new.rs | 23 +++++++++---------- tests/testsuite/new.rs | 46 +++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index 6108e30fd6d..5e994f1faf7 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -645,7 +645,7 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> { init_vcs(path, vcs, config)?; write_ignore_file(path, &ignore, vcs)?; - let (author_name, email) = discover_author()?; + let (author_name, email) = discover_author(path)?; let author = match (cfg.name, cfg.email, author_name, email) { (Some(name), Some(email), _, _) | (Some(name), None, _, Some(email)) @@ -781,8 +781,8 @@ fn get_environment_variable(variables: &[&str]) -> Option { variables.iter().filter_map(|var| env::var(var).ok()).next() } -fn discover_author() -> CargoResult<(String, Option)> { - let git_config = find_git_config(); +fn discover_author(path: &Path) -> CargoResult<(String, Option)> { + let git_config = find_git_config(path); let git_config = git_config.as_ref(); let name_variables = [ @@ -833,10 +833,10 @@ fn discover_author() -> CargoResult<(String, Option)> { Ok((name, email)) } -fn find_git_config() -> Option { +fn find_git_config(path: &Path) -> Option { match env::var("__CARGO_TEST_ROOT") { Ok(test_root) => find_tests_git_config(test_root), - Err(_) => find_real_git_config(), + Err(_) => find_real_git_config(path), } } @@ -851,12 +851,9 @@ fn find_tests_git_config(cargo_test_root: String) -> Option { } } -fn find_real_git_config() -> Option { - match env::current_dir() { - Ok(cwd) => GitRepository::discover(cwd) - .and_then(|repo| repo.config()) - .or_else(|_| GitConfig::open_default()) - .ok(), - Err(_) => GitConfig::open_default().ok(), - } +fn find_real_git_config(path: &Path) -> Option { + GitRepository::discover(path) + .and_then(|repo| repo.config()) + .or_else(|_| GitConfig::open_default()) + .ok() } diff --git a/tests/testsuite/new.rs b/tests/testsuite/new.rs index 6ea777eeaa8..b1122d5ea52 100644 --- a/tests/testsuite/new.rs +++ b/tests/testsuite/new.rs @@ -1,6 +1,6 @@ //! Tests for the `cargo new` command. -use cargo_test_support::paths; +use cargo_test_support::paths::{self, CargoPathExt}; use cargo_test_support::{cargo_process, git_process}; use std::env; use std::fs::{self, File}; @@ -305,6 +305,50 @@ fn finds_git_author() { assert!(contents.contains(r#"authors = ["foo "]"#), contents); } +#[cargo_test] +fn finds_git_author_in_included_config() { + let included_gitconfig = paths::root().join("foo").join(".gitconfig"); + included_gitconfig.parent().unwrap().mkdir_p(); + fs::write( + &included_gitconfig, + r#" + [user] + name = foo + email = bar + "#, + ) + .unwrap(); + + let gitconfig = paths::home().join(".gitconfig"); + fs::write( + &gitconfig, + format!( + r#" + [includeIf "gitdir/i:{}"] + path = {} + "#, + included_gitconfig + .parent() + .unwrap() + .join("") + .display() + .to_string() + .replace("\\", "/"), + included_gitconfig.display().to_string().replace("\\", "/"), + ) + .as_bytes(), + ) + .unwrap(); + + cargo_process("new foo/bar") + // Avoid the special treatment of tests to find git configuration + .env_remove("__CARGO_TEST_ROOT") + .run(); + let toml = paths::root().join("foo/bar/Cargo.toml"); + let contents = fs::read_to_string(&toml).unwrap(); + assert!(contents.contains(r#"authors = ["foo "]"#), contents,); +} + #[cargo_test] fn finds_git_committer() { create_empty_gitconfig();