From 256fc3949257bf7cc4b7355a4ed8b2ca70c6ab61 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Mon, 17 Dec 2018 12:28:30 +0100 Subject: [PATCH 1/5] Adding feature-flags to `cargo publish` and `cargo package` This change adds the `--features` and `--all-features` flags to the above mentioned commands. This is to allow publishing of crates that have certain feature requirements for compilation, without having to rely on `--no-verify` which isn't good practise. This PR adds two new fields `features` and `all_features` to both the `PackageOpts` and `PublishOpts` and also adds the argument options to the CLI commands. Merging this feature will allow people to publish crates on crates.io that require some feature flag to compile (or all?) without needing to rely on not checking the package before uploading, potentially resulting in less packaging errors and broken packages. --- src/bin/cargo/commands/package.rs | 4 ++++ src/bin/cargo/commands/publish.rs | 3 +++ src/cargo/ops/cargo_package.rs | 7 +++++-- src/cargo/ops/registry.rs | 5 +++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/bin/cargo/commands/package.rs b/src/bin/cargo/commands/package.rs index a1ef4793cea..3d0c020efa6 100644 --- a/src/bin/cargo/commands/package.rs +++ b/src/bin/cargo/commands/package.rs @@ -26,6 +26,7 @@ pub fn cli() -> App { )) .arg_target_triple("Build for the target triple") .arg_target_dir() + .arg_features() .arg_manifest_path() .arg_jobs() } @@ -42,6 +43,9 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { allow_dirty: args.is_present("allow-dirty"), target: args.target(), jobs: args.jobs()?, + registry: None, + features: args._values_of("features"), + all_features: args.is_present("all-features"), }, )?; Ok(()) diff --git a/src/bin/cargo/commands/publish.rs b/src/bin/cargo/commands/publish.rs index 69845d033da..2c9f132d6aa 100644 --- a/src/bin/cargo/commands/publish.rs +++ b/src/bin/cargo/commands/publish.rs @@ -18,6 +18,7 @@ pub fn cli() -> App { .arg_target_triple("Build for the target triple") .arg_target_dir() .arg_manifest_path() + .arg_features() .arg_jobs() .arg_dry_run("Perform all checks without uploading") .arg(opt("registry", "Registry to publish to").value_name("REGISTRY")) @@ -40,6 +41,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { jobs: args.jobs()?, dry_run: args.is_present("dry-run"), registry, + features: args._values_of("features"), + all_features: args.is_present("all-features"), }, )?; Ok(()) diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index c0200197a89..27ffca66be9 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -26,6 +26,9 @@ pub struct PackageOpts<'cfg> { pub verify: bool, pub jobs: Option, pub target: Option, + pub registry: Option, + pub features: Vec, + pub all_features: bool, } static VCS_INFO_FILE: &'static str = ".cargo_vcs_info.json"; @@ -447,9 +450,9 @@ fn run_verify(ws: &Workspace<'_>, tar: &FileLock, opts: &PackageOpts<'_>) -> Car &ops::CompileOptions { config, build_config: BuildConfig::new(config, opts.jobs, &opts.target, CompileMode::Build)?, - features: Vec::new(), + features: opts.features.clone(), no_default_features: false, - all_features: false, + all_features: opts.all_features, spec: ops::Packages::Packages(Vec::new()), filter: ops::CompileFilter::Default { required_features_filterable: true, diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index dbb95fc5168..9c464a81384 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -39,6 +39,8 @@ pub struct PublishOpts<'cfg> { pub target: Option, pub dry_run: bool, pub registry: Option, + pub features: Vec, + pub all_features: bool } pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { @@ -82,6 +84,9 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { allow_dirty: opts.allow_dirty, target: opts.target.clone(), jobs: opts.jobs, + registry: opts.registry.clone(), + features: opts.features.clone(), + all_features: opts.all_features, }, )? .unwrap(); From 142bafb7e62bb66cc7fe08a709a528f625eb1952 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Wed, 26 Dec 2018 14:48:25 +0100 Subject: [PATCH 2/5] Adding feature tests to `publish` and `package` --- tests/testsuite/package.rs | 64 ++++++++++++++ tests/testsuite/publish.rs | 176 +++++++++++++++++++++++-------------- 2 files changed, 176 insertions(+), 64 deletions(-) diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index 34a707c271f..ef01032124c 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1298,3 +1298,67 @@ To proceed despite this, pass the `--no-verify` flag.", p.cargo("package --no-verify").run(); } + +#[test] +fn package_with_select_features() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [features] + required = [] + optional = [] + "#, + ).file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ).build(); + + p.cargo("package --features required") + .masquerade_as_nightly_cargo() + .with_status(0) + .run(); +} + +#[test] +fn package_with_all_features() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [features] + required = [] + optional = [] + "#, + ).file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ).build(); + + p.cargo("package --all-features") + .masquerade_as_nightly_cargo() + .with_status(0) + .run(); +} diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index 05bbdfb6788..fd59a925b71 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -23,8 +23,7 @@ fn simple() { license = "MIT" description = "foo" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --index") @@ -38,8 +37,7 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) ", reg = publish::registry_path().to_str().unwrap() - )) - .run(); + )).run(); let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); // Skip the metadata payload and the size of the tarball @@ -98,8 +96,7 @@ fn old_token_location() { license = "MIT" description = "foo" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --index") @@ -113,8 +110,7 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) ", reg = publish::registry_path().to_str().unwrap() - )) - .run(); + )).run(); let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); // Skip the metadata payload and the size of the tarball @@ -166,8 +162,7 @@ fn simple_with_host() { license = "MIT" description = "foo" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --host") @@ -190,8 +185,7 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) ", reg = publish::registry_path().to_str().unwrap() - )) - .run(); + )).run(); let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); // Skip the metadata payload and the size of the tarball @@ -243,8 +237,7 @@ fn simple_with_index_and_host() { license = "MIT" description = "foo" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --index") @@ -269,8 +262,7 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) ", reg = publish::registry_path().to_str().unwrap() - )) - .run(); + )).run(); let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); // Skip the metadata payload and the size of the tarball @@ -323,8 +315,7 @@ fn git_deps() { [dependencies.foo] git = "git://path/to/nowhere" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish -v --no-verify --index") @@ -339,8 +330,7 @@ specify a crates.io version as a dependency or pull it into this \ repository and specify it with a path and version\n\ (crate `foo` has repository path `git://path/to/nowhere`)\ ", - ) - .run(); + ).run(); } #[test] @@ -361,8 +351,7 @@ fn path_dependency_no_version() { [dependencies.bar] path = "bar" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); @@ -376,8 +365,7 @@ fn path_dependency_no_version() { [ERROR] all path dependencies must have a version specified when publishing. dependency `bar` does not specify a version ", - ) - .run(); + ).run(); } #[test] @@ -396,8 +384,7 @@ fn unpublishable_crate() { description = "foo" publish = false "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") @@ -408,8 +395,7 @@ fn unpublishable_crate() { [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ) - .run(); + ).run(); } #[test] @@ -431,8 +417,7 @@ fn dont_publish_dirty() { homepage = "foo" repository = "foo" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") @@ -448,8 +433,7 @@ bar to proceed despite this, pass the `--allow-dirty` flag ", - ) - .run(); + ).run(); } #[test] @@ -472,8 +456,7 @@ fn publish_clean() { homepage = "foo" repository = "foo" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") @@ -501,8 +484,7 @@ fn publish_in_sub_repo() { homepage = "foo" repository = "foo" "#, - ) - .file("bar/src/main.rs", "fn main() {}") + ).file("bar/src/main.rs", "fn main() {}") .build(); p.cargo("publish") @@ -532,8 +514,7 @@ fn publish_when_ignored() { homepage = "foo" repository = "foo" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .file(".gitignore", "baz") .build(); @@ -563,8 +544,7 @@ fn ignore_when_crate_ignored() { homepage = "foo" repository = "foo" "#, - ) - .nocommit_file("bar/src/main.rs", "fn main() {}"); + ).nocommit_file("bar/src/main.rs", "fn main() {}"); p.cargo("publish") .cwd(p.root().join("bar")) .arg("--index") @@ -592,8 +572,7 @@ fn new_crate_rejected() { homepage = "foo" repository = "foo" "#, - ) - .nocommit_file("src/main.rs", "fn main() {}"); + ).nocommit_file("src/main.rs", "fn main() {}"); p.cargo("publish --index") .arg(publish::registry().to_string()) .with_status(101) @@ -615,8 +594,7 @@ fn dry_run() { license = "MIT" description = "foo" "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --dry-run --index") @@ -633,8 +611,7 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) [WARNING] aborting upload due to dry run ", - ) - .run(); + ).run(); // Ensure the API request wasn't actually made assert!(!publish::upload_path().join("api/v1/crates/new").exists()); @@ -658,8 +635,7 @@ fn block_publish_feature_not_enabled() { "test" ] "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --registry alternative -Zunstable-options") @@ -677,8 +653,7 @@ Caused by: consider adding `cargo-features = [\"alternative-registries\"]` to the manifest ", - ) - .run(); + ).run(); } #[test] @@ -701,8 +676,7 @@ fn registry_not_in_publish_list() { "test" ] "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish") @@ -716,8 +690,7 @@ fn registry_not_in_publish_list() { [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ) - .run(); + ).run(); } #[test] @@ -738,8 +711,7 @@ fn publish_empty_list() { description = "foo" publish = [] "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --registry alternative -Zunstable-options") @@ -750,8 +722,7 @@ fn publish_empty_list() { [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ) - .run(); + ).run(); } #[test] @@ -776,8 +747,7 @@ fn publish_allowed_registry() { homepage = "foo" publish = ["alternative"] "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --registry alternative -Zunstable-options") @@ -803,8 +773,7 @@ fn block_publish_no_registry() { description = "foo" publish = [] "#, - ) - .file("src/main.rs", "fn main() {}") + ).file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --registry alternative -Zunstable-options") @@ -815,6 +784,85 @@ fn block_publish_no_registry() { [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ) - .run(); + ).run(); +} + +#[test] +fn publish_with_select_features() { + publish::setup(); + + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + publish = [] + + [features] + required = [] + optional = [] + "#, + ).file( + "src/main.rs", + "#[cfg(not(required))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ).build(); + + p.cargo("publish --registry alternative -Zunstable-options --features required") + .masquerade_as_nightly_cargo() + .with_status(101) + .with_stderr( + "\ +[ERROR] some crates cannot be published. +`foo` is marked as unpublishable +", + ).run(); +} + +#[test] +fn publish_with_all_features() { + publish::setup(); + + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + publish = [] + + [features] + required = [] + optional = [] + "#, + ).file( + "src/main.rs", + "#[cfg(not(required))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ).build(); + + p.cargo("publish --registry alternative -Zunstable-options --all-features") + .masquerade_as_nightly_cargo() + .with_status(101) + .with_stderr( + "\ +[ERROR] some crates cannot be published. +`foo` is marked as unpublishable +", + ).run(); } From 40cca8058d1126cf4ec89feb08c9bf317662dd8f Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Sat, 29 Dec 2018 16:33:20 +0100 Subject: [PATCH 3/5] Undoing bad formatting changes and removing redundant struct fields --- src/bin/cargo/commands/package.rs | 1 - src/cargo/ops/cargo_package.rs | 1 - src/cargo/ops/registry.rs | 1 - tests/testsuite/package.rs | 4 --- tests/testsuite/publish.rs | 57 ++++++++++++++++++++----------- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/bin/cargo/commands/package.rs b/src/bin/cargo/commands/package.rs index 3d0c020efa6..32bc431dbfe 100644 --- a/src/bin/cargo/commands/package.rs +++ b/src/bin/cargo/commands/package.rs @@ -43,7 +43,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { allow_dirty: args.is_present("allow-dirty"), target: args.target(), jobs: args.jobs()?, - registry: None, features: args._values_of("features"), all_features: args.is_present("all-features"), }, diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 27ffca66be9..47601667a2e 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -26,7 +26,6 @@ pub struct PackageOpts<'cfg> { pub verify: bool, pub jobs: Option, pub target: Option, - pub registry: Option, pub features: Vec, pub all_features: bool, } diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 9c464a81384..9777394ba7c 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -84,7 +84,6 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { allow_dirty: opts.allow_dirty, target: opts.target.clone(), jobs: opts.jobs, - registry: opts.registry.clone(), features: opts.features.clone(), all_features: opts.all_features, }, diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index ef01032124c..ba4d3e7aec3 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1305,8 +1305,6 @@ fn package_with_select_features() { .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -1337,8 +1335,6 @@ fn package_with_all_features() { .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index fd59a925b71..dca4e92c9ac 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -23,7 +23,8 @@ fn simple() { license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --index") @@ -96,7 +97,8 @@ fn old_token_location() { license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --index") @@ -162,7 +164,8 @@ fn simple_with_host() { license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --host") @@ -237,7 +240,8 @@ fn simple_with_index_and_host() { license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --index") @@ -315,7 +319,8 @@ fn git_deps() { [dependencies.foo] git = "git://path/to/nowhere" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish -v --no-verify --index") @@ -351,7 +356,8 @@ fn path_dependency_no_version() { [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); @@ -384,7 +390,8 @@ fn unpublishable_crate() { description = "foo" publish = false "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") @@ -417,7 +424,8 @@ fn dont_publish_dirty() { homepage = "foo" repository = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") @@ -456,7 +464,8 @@ fn publish_clean() { homepage = "foo" repository = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") @@ -484,7 +493,8 @@ fn publish_in_sub_repo() { homepage = "foo" repository = "foo" "#, - ).file("bar/src/main.rs", "fn main() {}") + ) + .file("bar/src/main.rs", "fn main() {}") .build(); p.cargo("publish") @@ -514,7 +524,8 @@ fn publish_when_ignored() { homepage = "foo" repository = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file(".gitignore", "baz") .build(); @@ -594,7 +605,8 @@ fn dry_run() { license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --dry-run --index") @@ -635,7 +647,8 @@ fn block_publish_feature_not_enabled() { "test" ] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --registry alternative -Zunstable-options") @@ -676,7 +689,8 @@ fn registry_not_in_publish_list() { "test" ] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish") @@ -711,7 +725,8 @@ fn publish_empty_list() { description = "foo" publish = [] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --registry alternative -Zunstable-options") @@ -747,7 +762,8 @@ fn publish_allowed_registry() { homepage = "foo" publish = ["alternative"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --registry alternative -Zunstable-options") @@ -773,7 +789,8 @@ fn block_publish_no_registry() { description = "foo" publish = [] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --registry alternative -Zunstable-options") @@ -809,7 +826,8 @@ fn publish_with_select_features() { required = [] optional = [] "#, - ).file( + ) + .file( "src/main.rs", "#[cfg(not(required))] compile_error!(\"This crate requires `required` feature!\"); @@ -849,7 +867,8 @@ fn publish_with_all_features() { required = [] optional = [] "#, - ).file( + ) + .file( "src/main.rs", "#[cfg(not(required))] compile_error!(\"This crate requires `required` feature!\"); From 8c3bf82f8e4704e8ed7d3105e1f5c0ca69f1e615 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Wed, 9 Jan 2019 17:41:03 +0100 Subject: [PATCH 4/5] Fixing the publish tests --- tests/testsuite/publish.rs | 42 +++++++++++++------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index dca4e92c9ac..caec99db1a8 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -812,15 +812,12 @@ fn publish_with_select_features() { .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" authors = [] license = "MIT" description = "foo" - publish = [] [features] required = [] @@ -829,20 +826,16 @@ fn publish_with_select_features() { ) .file( "src/main.rs", - "#[cfg(not(required))] + "#[cfg(not(feature = \"required\"))] compile_error!(\"This crate requires `required` feature!\"); fn main() {}", - ).build(); + ) + .build(); - p.cargo("publish --registry alternative -Zunstable-options --features required") - .masquerade_as_nightly_cargo() - .with_status(101) - .with_stderr( - "\ -[ERROR] some crates cannot be published. -`foo` is marked as unpublishable -", - ).run(); + p.cargo("publish --features required --index") + .arg(publish::registry().to_string()) + .with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])") + .run(); } #[test] @@ -853,15 +846,12 @@ fn publish_with_all_features() { .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" authors = [] license = "MIT" description = "foo" - publish = [] [features] required = [] @@ -870,18 +860,14 @@ fn publish_with_all_features() { ) .file( "src/main.rs", - "#[cfg(not(required))] + "#[cfg(not(feature = \"required\"))] compile_error!(\"This crate requires `required` feature!\"); fn main() {}", - ).build(); + ) + .build(); - p.cargo("publish --registry alternative -Zunstable-options --all-features") - .masquerade_as_nightly_cargo() - .with_status(101) - .with_stderr( - "\ -[ERROR] some crates cannot be published. -`foo` is marked as unpublishable -", - ).run(); + p.cargo("publish --all-features --index") + .arg(publish::registry().to_string()) + .with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])") + .run(); } From b29e37968ab478d740afdfe72e1ad54d72ad608f Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Wed, 9 Jan 2019 18:25:36 +0100 Subject: [PATCH 5/5] Adding support for `no-default-features` to package and publish --- src/bin/cargo/commands/package.rs | 1 + src/bin/cargo/commands/publish.rs | 1 + src/cargo/ops/cargo_package.rs | 3 +- src/cargo/ops/registry.rs | 4 +- tests/testsuite/package.rs | 31 ++++++++++++ tests/testsuite/publish.rs | 80 +++++++++++++++++++++++++------ 6 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/bin/cargo/commands/package.rs b/src/bin/cargo/commands/package.rs index 32bc431dbfe..1964e138cd9 100644 --- a/src/bin/cargo/commands/package.rs +++ b/src/bin/cargo/commands/package.rs @@ -45,6 +45,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { jobs: args.jobs()?, features: args._values_of("features"), all_features: args.is_present("all-features"), + no_default_features: args.is_present("no-default-features"), }, )?; Ok(()) diff --git a/src/bin/cargo/commands/publish.rs b/src/bin/cargo/commands/publish.rs index 2c9f132d6aa..67b4ed2d2a8 100644 --- a/src/bin/cargo/commands/publish.rs +++ b/src/bin/cargo/commands/publish.rs @@ -43,6 +43,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { registry, features: args._values_of("features"), all_features: args.is_present("all-features"), + no_default_features: args.is_present("no-default-features"), }, )?; Ok(()) diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 47601667a2e..a8f92ad2fe3 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -28,6 +28,7 @@ pub struct PackageOpts<'cfg> { pub target: Option, pub features: Vec, pub all_features: bool, + pub no_default_features: bool, } static VCS_INFO_FILE: &'static str = ".cargo_vcs_info.json"; @@ -450,7 +451,7 @@ fn run_verify(ws: &Workspace<'_>, tar: &FileLock, opts: &PackageOpts<'_>) -> Car config, build_config: BuildConfig::new(config, opts.jobs, &opts.target, CompileMode::Build)?, features: opts.features.clone(), - no_default_features: false, + no_default_features: opts.no_default_features, all_features: opts.all_features, spec: ops::Packages::Packages(Vec::new()), filter: ops::CompileFilter::Default { diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 9777394ba7c..71bd0e2cbae 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -40,7 +40,8 @@ pub struct PublishOpts<'cfg> { pub dry_run: bool, pub registry: Option, pub features: Vec, - pub all_features: bool + pub all_features: bool, + pub no_default_features: bool, } pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { @@ -86,6 +87,7 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { jobs: opts.jobs, features: opts.features.clone(), all_features: opts.all_features, + no_default_features: opts.no_default_features, }, )? .unwrap(); diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index ba4d3e7aec3..768b51f04f0 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1358,3 +1358,34 @@ fn package_with_all_features() { .with_status(0) .run(); } + +#[test] +fn package_no_default_features() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [features] + default = ["required"] + required = [] + "#, + ).file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ).build(); + + p.cargo("package --no-default-features") + .masquerade_as_nightly_cargo() + .with_stderr_contains("error: This crate requires `required` feature!") + .with_status(101) + .run(); +} diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index caec99db1a8..628499a86ea 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -38,7 +38,8 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) ", reg = publish::registry_path().to_str().unwrap() - )).run(); + )) + .run(); let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); // Skip the metadata payload and the size of the tarball @@ -112,7 +113,8 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) ", reg = publish::registry_path().to_str().unwrap() - )).run(); + )) + .run(); let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); // Skip the metadata payload and the size of the tarball @@ -188,7 +190,8 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) ", reg = publish::registry_path().to_str().unwrap() - )).run(); + )) + .run(); let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); // Skip the metadata payload and the size of the tarball @@ -266,7 +269,8 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) ", reg = publish::registry_path().to_str().unwrap() - )).run(); + )) + .run(); let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); // Skip the metadata payload and the size of the tarball @@ -335,7 +339,8 @@ specify a crates.io version as a dependency or pull it into this \ repository and specify it with a path and version\n\ (crate `foo` has repository path `git://path/to/nowhere`)\ ", - ).run(); + ) + .run(); } #[test] @@ -371,7 +376,8 @@ fn path_dependency_no_version() { [ERROR] all path dependencies must have a version specified when publishing. dependency `bar` does not specify a version ", - ).run(); + ) + .run(); } #[test] @@ -402,7 +408,8 @@ fn unpublishable_crate() { [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ).run(); + ) + .run(); } #[test] @@ -441,7 +448,8 @@ bar to proceed despite this, pass the `--allow-dirty` flag ", - ).run(); + ) + .run(); } #[test] @@ -555,7 +563,8 @@ fn ignore_when_crate_ignored() { homepage = "foo" repository = "foo" "#, - ).nocommit_file("bar/src/main.rs", "fn main() {}"); + ) + .nocommit_file("bar/src/main.rs", "fn main() {}"); p.cargo("publish") .cwd(p.root().join("bar")) .arg("--index") @@ -583,7 +592,8 @@ fn new_crate_rejected() { homepage = "foo" repository = "foo" "#, - ).nocommit_file("src/main.rs", "fn main() {}"); + ) + .nocommit_file("src/main.rs", "fn main() {}"); p.cargo("publish --index") .arg(publish::registry().to_string()) .with_status(101) @@ -623,7 +633,8 @@ See [..] [UPLOADING] foo v0.0.1 ([CWD]) [WARNING] aborting upload due to dry run ", - ).run(); + ) + .run(); // Ensure the API request wasn't actually made assert!(!publish::upload_path().join("api/v1/crates/new").exists()); @@ -666,7 +677,8 @@ Caused by: consider adding `cargo-features = [\"alternative-registries\"]` to the manifest ", - ).run(); + ) + .run(); } #[test] @@ -704,7 +716,8 @@ fn registry_not_in_publish_list() { [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ).run(); + ) + .run(); } #[test] @@ -737,7 +750,8 @@ fn publish_empty_list() { [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ).run(); + ) + .run(); } #[test] @@ -801,7 +815,8 @@ fn block_publish_no_registry() { [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ).run(); + ) + .run(); } #[test] @@ -871,3 +886,38 @@ fn publish_with_all_features() { .with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])") .run(); } + +#[test] +fn publish_with_no_default_features() { + publish::setup(); + + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [features] + default = ["required"] + required = [] + "#, + ) + .file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ) + .build(); + + p.cargo("publish --no-default-features --index") + .arg(publish::registry().to_string()) + .with_stderr_contains("error: This crate requires `required` feature!") + .with_status(101) + .run(); +}