mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +00:00
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:
parent
39d9413ca2
commit
c685eb322b
@ -3,12 +3,9 @@ use crate::util::errors::{CargoResult, CargoResultExt};
|
|||||||
use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
|
use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
|
||||||
use crate::util::{restricted_names, Config};
|
use crate::util::{restricted_names, Config};
|
||||||
use cargo_util::paths;
|
use cargo_util::paths;
|
||||||
use git2::Config as GitConfig;
|
|
||||||
use git2::Repository as GitRepository;
|
|
||||||
use serde::de;
|
use serde::de;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::env;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{BufRead, BufReader, ErrorKind};
|
use std::io::{BufRead, BufReader, ErrorKind};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
@ -129,8 +126,6 @@ impl NewOptions {
|
|||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct CargoNewConfig {
|
struct CargoNewConfig {
|
||||||
name: Option<String>,
|
|
||||||
email: Option<String>,
|
|
||||||
#[serde(rename = "vcs")]
|
#[serde(rename = "vcs")]
|
||||||
version_control: Option<VersionControl>,
|
version_control: Option<VersionControl>,
|
||||||
}
|
}
|
||||||
@ -666,32 +661,6 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
|
|||||||
init_vcs(path, vcs, config)?;
|
init_vcs(path, vcs, config)?;
|
||||||
write_ignore_file(path, &ignore, vcs)?;
|
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();
|
let mut cargotoml_path_specifier = String::new();
|
||||||
|
|
||||||
// Calculate what `[lib]` and `[[bin]]`s we need to append to `Cargo.toml`.
|
// Calculate what `[lib]` and `[[bin]]`s we need to append to `Cargo.toml`.
|
||||||
@ -730,7 +699,6 @@ path = {}
|
|||||||
r#"[package]
|
r#"[package]
|
||||||
name = "{}"
|
name = "{}"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = [{}]
|
|
||||||
edition = {}
|
edition = {}
|
||||||
{}
|
{}
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
@ -738,10 +706,6 @@ edition = {}
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
{}"#,
|
{}"#,
|
||||||
name,
|
name,
|
||||||
match author {
|
|
||||||
Some(value) => format!("{}", toml::Value::String(value)),
|
|
||||||
None => format!(""),
|
|
||||||
},
|
|
||||||
match opts.edition {
|
match opts.edition {
|
||||||
Some(edition) => toml::Value::String(edition.to_string()),
|
Some(edition) => toml::Value::String(edition.to_string()),
|
||||||
None => toml::Value::String(Edition::LATEST_STABLE.to_string()),
|
None => toml::Value::String(Edition::LATEST_STABLE.to_string()),
|
||||||
@ -811,76 +775,3 @@ mod tests {
|
|||||||
|
|
||||||
Ok(())
|
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()
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Tests for the `cargo new` command.
|
//! Tests for the `cargo new` command.
|
||||||
|
|
||||||
use cargo_test_support::paths::{self, CargoPathExt};
|
use cargo_test_support::cargo_process;
|
||||||
use cargo_test_support::{cargo_process, git_process};
|
use cargo_test_support::paths;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
|
|
||||||
@ -226,256 +226,6 @@ or change the name in Cargo.toml with:
|
|||||||
.run();
|
.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]
|
#[cargo_test]
|
||||||
fn git_prefers_command_line() {
|
fn git_prefers_command_line() {
|
||||||
let root = paths::root();
|
let root = paths::root();
|
||||||
@ -632,17 +382,6 @@ fn new_with_bad_edition() {
|
|||||||
.run();
|
.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]
|
#[cargo_test]
|
||||||
fn new_with_reference_link() {
|
fn new_with_reference_link() {
|
||||||
cargo_process("new foo").env("USER", "foo").run();
|
cargo_process("new foo").env("USER", "foo").run();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user