diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index e80f9edb6cf..83ad42ca876 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -645,19 +645,30 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> { init_vcs(path, vcs, config)?; write_ignore_file(path, &ignore, vcs)?; - 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)) - | (None, Some(email), name, _) - | (None, None, name, Some(email)) => { + let (discovered_name, discovered_email) = discover_author(path); + + // "Name " or "Name" or "" 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() { - name + Some(name) } else { - format!("{} <{}>", name, email) + Some(format!("{} <{}>", name, email)) } } - (Some(name), None, _, None) | (None, None, name, None) => name, + (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(); @@ -706,7 +717,10 @@ edition = {} [dependencies] {}"#, name, - toml::Value::String(author), + 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("2018".to_string()), @@ -781,7 +795,7 @@ fn get_environment_variable(variables: &[&str]) -> Option { variables.iter().filter_map(|var| env::var(var).ok()).next() } -fn discover_author(path: &Path) -> CargoResult<(String, Option)> { +fn discover_author(path: &Path) -> (Option, Option) { let git_config = find_git_config(path); let git_config = git_config.as_ref(); @@ -798,15 +812,10 @@ fn discover_author(path: &Path) -> CargoResult<(String, Option)> { .or_else(|| get_environment_variable(&name_variables[3..])); let name = match name { - Some(name) => name, - None => { - let username_var = if cfg!(windows) { "USERNAME" } else { "USER" }; - anyhow::bail!( - "could not determine the current user, please set ${}", - username_var - ) - } + Some(namestr) => Some(namestr.trim().to_string()), + None => None, }; + let email_variables = [ "CARGO_EMAIL", "GIT_AUTHOR_EMAIL", @@ -817,7 +826,6 @@ fn discover_author(path: &Path) -> CargoResult<(String, Option)> { .or_else(|| git_config.and_then(|g| g.get_string("user.email").ok())) .or_else(|| get_environment_variable(&email_variables[3..])); - let name = name.trim().to_string(); let email = email.map(|s| { let mut s = s.trim(); @@ -830,7 +838,7 @@ fn discover_author(path: &Path) -> CargoResult<(String, Option)> { s.to_string() }); - Ok((name, email)) + (name, email) } fn find_git_config(path: &Path) -> Option { diff --git a/tests/testsuite/new.rs b/tests/testsuite/new.rs index 1146183195f..039fd9eb876 100644 --- a/tests/testsuite/new.rs +++ b/tests/testsuite/new.rs @@ -199,6 +199,37 @@ fn finds_author_user() { 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 = [""]"#)); +} + #[cargo_test] fn finds_author_user_escaped() { create_empty_gitconfig();