From 10f423f62a2ef617c11a76a90c72378f8031ebc6 Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Sun, 20 Dec 2015 00:24:02 -0500 Subject: [PATCH] Add --license-file option --- src/bin/new.rs | 33 ++++++++++-------- src/cargo/ops/cargo_new.rs | 61 +++++++++++++++++++++++---------- src/doc/config.md | 10 ++++-- src/etc/_cargo | 1 + src/etc/cargo.bashcomp.sh | 2 +- tests/test_cargo_new.rs | 70 ++++++++++++++++++++++++++++++++++++-- 6 files changed, 140 insertions(+), 37 deletions(-) diff --git a/src/bin/new.rs b/src/bin/new.rs index 0c5f31bdabd..acdb9a5a3f7 100644 --- a/src/bin/new.rs +++ b/src/bin/new.rs @@ -14,6 +14,7 @@ struct Options { flag_name: Option, flag_vcs: Option, flag_license: Option, + flag_license_file: Option, } pub const USAGE: &'static str = r#" @@ -24,19 +25,20 @@ Usage: cargo new -h | --help Options: - -h, --help Print this message - --vcs VCS Initialize a new repository for the given version - control system (git or hg) or do not initialize any version - control at all (none) overriding a global configuration. - --bin Use a binary instead of a library template - --name NAME Set the resulting package name - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout - --color WHEN Coloring: auto, always, never - --license LICENSES License(s) to add to a project - Multiple licenses should be separated by a '/' character - (Supported values, case insensitive: "MIT", "BSD-3-Clause", "APACHE-2.0", - "GPL-3.0", "MPL-2.0") + -h, --help Print this message + --vcs VCS Initialize a new repository for the given version + control system (git or hg) or do not initialize any version + control at all (none) overriding a global configuration. + --bin Use a binary instead of a library template + --name NAME Set the resulting package name + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never + --license LICENSES License(s) to add to a project + Multiple licenses should be separated by a '/' character + (Supported values, case insensitive: "MIT", "BSD-3-Clause", + "APACHE-2.0", "GPL-3.0", "MPL-2.0") + --license-file FILE Adds the 'license-file' parameter to your Cargo.toml "#; pub fn execute(options: Options, config: &Config) -> CliResult> { @@ -44,7 +46,9 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); - let Options { flag_bin, arg_path, flag_name, flag_vcs, flag_license, .. } = options; + let Options { flag_bin, arg_path, + flag_name, flag_vcs, + flag_license, flag_license_file, .. } = options; let opts = ops::NewOptions { version_control: flag_vcs, @@ -67,6 +71,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { }, None => None }, + license_file: flag_license_file.as_ref().map(|s| s.as_ref()), }; try!(ops::new(opts, config)); diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index 9629057748d..6436eeedfc8 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -27,6 +27,7 @@ pub struct NewOptions<'a> { pub path: &'a str, pub name: Option<&'a str>, pub license: Option>, + pub license_file: Option<&'a str>, } impl Decodable for VersionControl { @@ -107,6 +108,7 @@ struct CargoNewConfig { email: Option, version_control: Option, license: Option>, + license_file: Option } pub fn new(opts: NewOptions, config: &Config) -> CargoResult<()> { @@ -220,21 +222,41 @@ fn mk(config: &Config, path: &Path, name: &str, (&_, Some(lic)) => Some(lic.clone()), }; + let license_file: Option = match (&opts.license_file, cfg.license_file) { + (&None, None) => None, + (&Some(ref lic_file), _) => Some(lic_file.to_string()), + (&_, Some(lic_file)) => Some(lic_file.to_string()), + }; + + let license_options: String = match (license.clone(), license_file) { + (Some(license), Some(license_file)) => { + let license = join_licenses(license.iter() + .map(|l| format!("{}", l)) + .collect::>()); + format!(r#"license = "{}" +license-file = "{}" +"#, license, license_file) + }, + (Some(license), None) => { + let license = join_licenses(license.iter() + .map(|l| format!("{}", l)) + .collect::>()); + format!(r#"license = "{}" +"#, license) + }, + (None, Some(license_file)) => { + format!(r#"license-file = "{}" +"#, license_file) + }, + (None, None) => { + "".to_owned() + } + }; + + // If there is more than one license, we suffix the filename + // with the name of the license if license.is_some() { let license = license.unwrap(); - let license_string = join_licenses(license.iter() - .map(|l| format!("{}", l)) - .collect::>()); - try!(file(&path.join("Cargo.toml"), format!( -r#"[package] -name = "{}" -version = "0.1.0" -authors = [{}] -license = "{}" -"#, name, toml::Value::String(author.clone()), license_string).as_bytes())); - - // If there is more than one license, we suffix the filename - // with the name of the license if license.len() > 1 { for l in &license { let upper = format!("{}", l).to_uppercase(); @@ -244,16 +266,16 @@ license = "{}" let license = license.get(0).unwrap(); try!(license.write_file(&path.join("LICENSE"), &author)) } - } else { - try!(file(&path.join("Cargo.toml"), format!( + } + + try!(file(&path.join("Cargo.toml"), format!( r#"[package] name = "{}" version = "0.1.0" authors = [{}] - +{} [dependencies] -"#, name, toml::Value::String(author.clone())).as_bytes())); - } +"#, name, toml::Value::String(author.clone()), license_options).as_bytes())); try!(fs::create_dir(&path.join("src"))); @@ -303,6 +325,7 @@ fn global_config(config: &Config) -> CargoResult { let email = try!(config.get_string("cargo-new.email")).map(|s| s.0); let vcs = try!(config.get_string("cargo-new.vcs")); let license = try!(config.get_string("cargo-new.license")); + let license_file = try!(config.get_string("cargo-new.license-file")); let vcs = match vcs.as_ref().map(|p| (&p.0[..], &p.1)) { Some(("git", _)) => Some(VersionControl::Git), @@ -326,11 +349,13 @@ fn global_config(config: &Config) -> CargoResult { }, _ => None, }; + let license_file: Option = license_file.as_ref().map(|p| p.0.to_owned()); Ok(CargoNewConfig { name: name, email: email, version_control: vcs, license: license, + license_file: license_file, }) } diff --git a/src/doc/config.md b/src/doc/config.md index a480ee073bb..4b24aa4e6f9 100644 --- a/src/doc/config.md +++ b/src/doc/config.md @@ -56,8 +56,9 @@ email = "..." vcs = "none" # By default, no license is added to a new project, but by specifying -# one here, `cargo` will add the correct entry to `Cargo.toml`, as well as -# a `LICENSE` file (or multiple LICENSE-* files). Currently this supports: +# one or more here, `cargo` will add the correct entry to `Cargo.toml`, as +# well as a `LICENSE` file (or multiple LICENSE-* files). Currently this +# supports: # # * MIT # * Apache-2.0 @@ -67,6 +68,11 @@ vcs = "none" license = "MIT/Apache-2.0" +# Whenever a new `cargo` project is generated, it's `Cargo.toml` will +# specify that there is a license file located at "..." + +license-file = "..." + # For the following sections, $triple refers to any valid target triple, not the # literal string "$triple", and it will apply whenever that target triple is # being compiled to. diff --git a/src/etc/_cargo b/src/etc/_cargo index 33c1025aad2..e71bc0129f9 100644 --- a/src/etc/_cargo +++ b/src/etc/_cargo @@ -147,6 +147,7 @@ case $state in '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ '--color=:colorization option:(auto always never)' \ '--license=[license choice]' \ + '--license-file=[license file location]' \ ;; owner) diff --git a/src/etc/cargo.bashcomp.sh b/src/etc/cargo.bashcomp.sh index 5cdab04d5de..612440f8a0c 100644 --- a/src/etc/cargo.bashcomp.sh +++ b/src/etc/cargo.bashcomp.sh @@ -33,7 +33,7 @@ _cargo() local opt__install="$opt_common $opt_feat $opt_jobs --bin --branch --debug --example --git --list --path --rev --root --tag --vers" local opt__locate_project="$opt_mani -h --help" local opt__login="$opt_common --host" - local opt__new="$opt_common --vcs --bin --name --license" + local opt__new="$opt_common --vcs --bin --name --license --license-file" local opt__owner="$opt_common -a --add -r --remove -l --list --index --token" local opt__package="$opt_common $opt_mani -l --list --no-verify --no-metadata" local opt__pkgid="${opt__fetch}" diff --git a/tests/test_cargo_new.rs b/tests/test_cargo_new.rs index b2d29acb48d..c1e41f07ace 100644 --- a/tests/test_cargo_new.rs +++ b/tests/test_cargo_new.rs @@ -301,7 +301,6 @@ test!(simple_lib_with_known_license { let mut toml_contents = String::new(); File::open(&toml).unwrap().read_to_string(&mut toml_contents).unwrap(); - println!("toml_contents: {}", toml_contents); assert!(toml_contents.contains(r#"license = "MIT""#)); assert_that(cargo_process("build").cwd(&paths::root().join("foo")), @@ -323,7 +322,6 @@ test!(simple_lib_with_known_license_case_insensitive { let mut toml_contents = String::new(); File::open(&toml).unwrap().read_to_string(&mut toml_contents).unwrap(); - println!("toml_contents: {}", toml_contents); assert!(toml_contents.contains(r#"license = "MPL-2.0""#)); assert_that(cargo_process("build").cwd(&paths::root().join("foo")), @@ -410,3 +408,71 @@ test!(license_prefers_command_line { File::open(&toml).unwrap().read_to_string(&mut contents).unwrap(); assert!(contents.contains(r#"license = "GPL-3.0""#)); }); + +test!(simple_lib_with_license_file { + assert_that(cargo_process("new").arg("foo") + .arg("--license-file").arg("LICENSE") + .env("USER", "foo"), + execs().with_status(0)); + let toml = paths::root().join("foo/Cargo.toml"); + + assert_that(&paths::root().join("foo"), existing_dir()); + assert_that(&paths::root().join("foo/src/lib.rs"), existing_file()); + assert_that(&toml, existing_file()); + + let mut toml_contents = String::new(); + File::open(&toml).unwrap().read_to_string(&mut toml_contents).unwrap(); + assert!(toml_contents.contains(r#"license-file = "LICENSE""#)); + + assert_that(cargo_process("build").cwd(&paths::root().join("foo")), + execs().with_status(0)); +}); + +test!(license_file_from_config { + let root = paths::root(); + fs::create_dir(&root.join(".cargo")).unwrap(); + File::create(&root.join(".cargo/config")).unwrap().write_all(br#" + [cargo-new] + vcs = "none" + name = "foo" + email = "bar" + license-file = "LICENSE" + "#).unwrap(); + + assert_that(cargo_process("new").arg("foo") + .env("USER", "foo"), + execs().with_status(0)); + + let toml = root.join("foo/Cargo.toml"); + assert_that(&root.join("foo"), existing_dir()); + assert_that(&toml, existing_file()); + + let mut contents = String::new(); + File::open(&toml).unwrap().read_to_string(&mut contents).unwrap(); + assert!(contents.contains(r#"license-file = "LICENSE""#)); +}); + +test!(license_file_prefers_command_line { + let root = paths::root(); + fs::create_dir(&root.join(".cargo")).unwrap(); + File::create(&root.join(".cargo/config")).unwrap().write_all(br#" + [cargo-new] + vcs = "none" + name = "foo" + email = "bar" + license-file = "LICENSE-from-config" + "#).unwrap(); + + assert_that(cargo_process("new").arg("foo") + .arg("--license-file").arg("LICENSE-from-command-line") + .env("USER", "foo"), + execs().with_status(0)); + + let toml = root.join("foo/Cargo.toml"); + assert_that(&root.join("foo"), existing_dir()); + assert_that(&toml, existing_file()); + + let mut contents = String::new(); + File::open(&toml).unwrap().read_to_string(&mut contents).unwrap(); + assert!(contents.contains(r#"license-file = "LICENSE-from-command-line""#)); +});