RFC 3052: Stop including authors field in manifests made by cargo new

See https://github.com/rust-lang/rust/issues/83227
This commit is contained in:
Jade 2021-03-17 11:56:34 -07:00 committed by Eric Huss
parent 39d9413ca2
commit c685eb322b
2 changed files with 2 additions and 372 deletions

View File

@ -3,12 +3,9 @@ use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
use crate::util::{restricted_names, Config};
use cargo_util::paths;
use git2::Config as GitConfig;
use git2::Repository as GitRepository;
use serde::de;
use serde::Deserialize;
use std::collections::BTreeMap;
use std::env;
use std::fmt;
use std::io::{BufRead, BufReader, ErrorKind};
use std::path::{Path, PathBuf};
@ -129,8 +126,6 @@ impl NewOptions {
#[derive(Deserialize)]
struct CargoNewConfig {
name: Option<String>,
email: Option<String>,
#[serde(rename = "vcs")]
version_control: Option<VersionControl>,
}
@ -666,32 +661,6 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
init_vcs(path, vcs, config)?;
write_ignore_file(path, &ignore, vcs)?;
let (discovered_name, discovered_email) = discover_author(path);
// "Name <email>" or "Name" or "<email>" or None if neither name nor email is obtained
// cfg takes priority over the discovered ones
let author_name = cfg.name.or(discovered_name);
let author_email = cfg.email.or(discovered_email);
let author = match (author_name, author_email) {
(Some(name), Some(email)) => {
if email.is_empty() {
Some(name)
} else {
Some(format!("{} <{}>", name, email))
}
}
(Some(name), None) => Some(name),
(None, Some(email)) => {
if email.is_empty() {
None
} else {
Some(format!("<{}>", email))
}
}
(None, None) => None,
};
let mut cargotoml_path_specifier = String::new();
// Calculate what `[lib]` and `[[bin]]`s we need to append to `Cargo.toml`.
@ -730,7 +699,6 @@ path = {}
r#"[package]
name = "{}"
version = "0.1.0"
authors = [{}]
edition = {}
{}
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -738,10 +706,6 @@ edition = {}
[dependencies]
{}"#,
name,
match author {
Some(value) => format!("{}", toml::Value::String(value)),
None => format!(""),
},
match opts.edition {
Some(edition) => toml::Value::String(edition.to_string()),
None => toml::Value::String(Edition::LATEST_STABLE.to_string()),
@ -811,76 +775,3 @@ mod tests {
Ok(())
}
fn get_environment_variable(variables: &[&str]) -> Option<String> {
variables.iter().filter_map(|var| env::var(var).ok()).next()
}
fn discover_author(path: &Path) -> (Option<String>, Option<String>) {
let git_config = find_git_config(path);
let git_config = git_config.as_ref();
let name_variables = [
"CARGO_NAME",
"GIT_AUTHOR_NAME",
"GIT_COMMITTER_NAME",
"USER",
"USERNAME",
"NAME",
];
let name = get_environment_variable(&name_variables[0..3])
.or_else(|| git_config.and_then(|g| g.get_string("user.name").ok()))
.or_else(|| get_environment_variable(&name_variables[3..]));
let name = name.map(|namestr| namestr.trim().to_string());
let email_variables = [
"CARGO_EMAIL",
"GIT_AUTHOR_EMAIL",
"GIT_COMMITTER_EMAIL",
"EMAIL",
];
let email = get_environment_variable(&email_variables[0..3])
.or_else(|| git_config.and_then(|g| g.get_string("user.email").ok()))
.or_else(|| get_environment_variable(&email_variables[3..]));
let email = email.map(|s| {
let mut s = s.trim();
// In some cases emails will already have <> remove them since they
// are already added when needed.
if s.starts_with('<') && s.ends_with('>') {
s = &s[1..s.len() - 1];
}
s.to_string()
});
(name, email)
}
fn find_git_config(path: &Path) -> Option<GitConfig> {
match env::var("__CARGO_TEST_ROOT") {
Ok(_) => find_tests_git_config(path),
Err(_) => find_real_git_config(path),
}
}
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, None) {
if let Ok(repo) = GitRepository::open(path) {
return Some(repo.config().expect("test repo should have valid config"));
}
}
GitConfig::open_default().ok()
}
fn find_real_git_config(path: &Path) -> Option<GitConfig> {
GitRepository::discover(path)
.and_then(|repo| repo.config())
.or_else(|_| GitConfig::open_default())
.ok()
}

View File

@ -1,7 +1,7 @@
//! Tests for the `cargo new` command.
use cargo_test_support::paths::{self, CargoPathExt};
use cargo_test_support::{cargo_process, git_process};
use cargo_test_support::cargo_process;
use cargo_test_support::paths;
use std::env;
use std::fs::{self, File};
@ -226,256 +226,6 @@ or change the name in Cargo.toml with:
.run();
}
#[cargo_test]
fn finds_author_user() {
create_empty_gitconfig();
cargo_process("new foo").env("USER", "foo").run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["foo"]"#));
}
#[cargo_test]
fn author_without_user_or_email() {
create_empty_gitconfig();
cargo_process("new foo")
.env_remove("USER")
.env_remove("USERNAME")
.env_remove("NAME")
.env_remove("EMAIL")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = []"#));
}
#[cargo_test]
fn finds_author_email_only() {
create_empty_gitconfig();
cargo_process("new foo")
.env_remove("USER")
.env_remove("USERNAME")
.env_remove("NAME")
.env_remove("EMAIL")
.env("EMAIL", "baz")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["<baz>"]"#));
}
#[cargo_test]
fn finds_author_user_escaped() {
create_empty_gitconfig();
cargo_process("new foo").env("USER", "foo \"bar\"").run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["foo \"bar\""]"#));
}
#[cargo_test]
fn finds_author_username() {
create_empty_gitconfig();
cargo_process("new foo")
.env_remove("USER")
.env("USERNAME", "foo")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["foo"]"#));
}
#[cargo_test]
fn finds_author_name() {
create_empty_gitconfig();
cargo_process("new foo")
.env_remove("USERNAME")
.env("NAME", "foo")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["foo"]"#));
}
#[cargo_test]
fn finds_author_priority() {
cargo_process("new foo")
.env("USER", "bar2")
.env("EMAIL", "baz2")
.env("CARGO_NAME", "bar")
.env("CARGO_EMAIL", "baz")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[cargo_test]
fn finds_author_email() {
create_empty_gitconfig();
cargo_process("new foo")
.env("USER", "bar")
.env("EMAIL", "baz")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[cargo_test]
fn finds_author_git() {
git_process("config --global user.name bar").exec().unwrap();
git_process("config --global user.email baz")
.exec()
.unwrap();
cargo_process("new foo").env("USER", "foo").run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[cargo_test]
fn finds_local_author_git() {
git_process("init").exec_with_output().unwrap();
git_process("config --global user.name foo").exec().unwrap();
git_process("config --global user.email foo@bar")
.exec()
.unwrap();
// Set local git user config
git_process("config user.name bar").exec().unwrap();
git_process("config user.email baz").exec().unwrap();
cargo_process("init").env("USER", "foo").run();
let toml = paths::root().join("Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[cargo_test]
fn finds_git_author() {
cargo_process("new foo")
.env("GIT_AUTHOR_NAME", "foo")
.env("GIT_AUTHOR_EMAIL", "gitfoo")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(
contents.contains(r#"authors = ["foo <gitfoo>"]"#),
"{}",
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").run();
let toml = paths::root().join("foo/bar/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(
contents.contains(r#"authors = ["foo <bar>"]"#),
"{}",
contents
);
}
#[cargo_test]
fn finds_git_committer() {
create_empty_gitconfig();
cargo_process("new foo")
.env_remove("USER")
.env("GIT_COMMITTER_NAME", "foo")
.env("GIT_COMMITTER_EMAIL", "gitfoo")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["foo <gitfoo>"]"#));
}
#[cargo_test]
fn author_prefers_cargo() {
git_process("config --global user.name foo").exec().unwrap();
git_process("config --global user.email bar")
.exec()
.unwrap();
let root = paths::root();
fs::create_dir(&root.join(".cargo")).unwrap();
fs::write(
&root.join(".cargo/config"),
r#"
[cargo-new]
name = "new-foo"
email = "new-bar"
vcs = "none"
"#,
)
.unwrap();
cargo_process("new foo").env("USER", "foo").run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["new-foo <new-bar>"]"#));
assert!(!root.join("foo/.gitignore").exists());
}
#[cargo_test]
fn strip_angle_bracket_author_email() {
create_empty_gitconfig();
cargo_process("new foo")
.env("USER", "bar")
.env("EMAIL", "<baz>")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let contents = fs::read_to_string(&toml).unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[cargo_test]
fn git_prefers_command_line() {
let root = paths::root();
@ -632,17 +382,6 @@ fn new_with_bad_edition() {
.run();
}
#[cargo_test]
fn new_with_blank_email() {
cargo_process("new foo")
.env("CARGO_NAME", "Sen")
.env("CARGO_EMAIL", "")
.run();
let contents = fs::read_to_string(paths::root().join("foo/Cargo.toml")).unwrap();
assert!(contents.contains(r#"authors = ["Sen"]"#), "{}", contents);
}
#[cargo_test]
fn new_with_reference_link() {
cargo_process("new foo").env("USER", "foo").run();