Skip to content

Commit

Permalink
Add --license-file option
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Woolcock committed Dec 20, 2015
1 parent 8f3bed0 commit 10f423f
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 37 deletions.
33 changes: 19 additions & 14 deletions src/bin/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct Options {
flag_name: Option<String>,
flag_vcs: Option<ops::VersionControl>,
flag_license: Option<String>,
flag_license_file: Option<String>,
}

pub const USAGE: &'static str = r#"
Expand All @@ -24,27 +25,30 @@ 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<Option<()>> {
debug!("executing; cmd=cargo-new; args={:?}", env::args().collect::<Vec<_>>());
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,
Expand All @@ -67,6 +71,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
},
None => None
},
license_file: flag_license_file.as_ref().map(|s| s.as_ref()),
};

try!(ops::new(opts, config));
Expand Down
61 changes: 43 additions & 18 deletions src/cargo/ops/cargo_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct NewOptions<'a> {
pub path: &'a str,
pub name: Option<&'a str>,
pub license: Option<Vec<License>>,
pub license_file: Option<&'a str>,
}

impl Decodable for VersionControl {
Expand Down Expand Up @@ -107,6 +108,7 @@ struct CargoNewConfig {
email: Option<String>,
version_control: Option<VersionControl>,
license: Option<Vec<License>>,
license_file: Option<String>
}

pub fn new(opts: NewOptions, config: &Config) -> CargoResult<()> {
Expand Down Expand Up @@ -220,21 +222,41 @@ fn mk(config: &Config, path: &Path, name: &str,
(&_, Some(lic)) => Some(lic.clone()),
};

let license_file: Option<String> = 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::<Vec<_>>());
format!(r#"license = "{}"
license-file = "{}"
"#, license, license_file)
},
(Some(license), None) => {
let license = join_licenses(license.iter()
.map(|l| format!("{}", l))
.collect::<Vec<_>>());
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::<Vec<_>>());
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();
Expand All @@ -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")));

Expand Down Expand Up @@ -303,6 +325,7 @@ fn global_config(config: &Config) -> CargoResult<CargoNewConfig> {
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),
Expand All @@ -326,11 +349,13 @@ fn global_config(config: &Config) -> CargoResult<CargoNewConfig> {
},
_ => None,
};
let license_file: Option<String> = 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,
})
}

Expand Down
10 changes: 8 additions & 2 deletions src/doc/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/etc/_cargo
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/etc/cargo.bashcomp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down
70 changes: 68 additions & 2 deletions tests/test_cargo_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")),
Expand All @@ -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")),
Expand Down Expand Up @@ -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""#));
});

0 comments on commit 10f423f

Please sign in to comment.