From 24438a4134149e3a985a802e76ce9a7804d9e66a Mon Sep 17 00:00:00 2001 From: bors Date: Thu, 12 Nov 2020 19:04:56 +0000 Subject: [PATCH] Auto merge of #8853 - ehuss:fix-namespaced-publish, r=Eh2406 Fix publishing with optional dependencies. In #8799, I neglected to update the `publish` code to use the correct features when generating the JSON to upload to the registry. The `Cargo.toml` file was correctly updated, but the JSON was not. This caused Cargo to send the implicit `dep:` feature syntax in the JSON blob, which crates.io rejects. The solution here is to use the original feature map before the implicit features have been added. --- src/cargo/ops/registry.rs | 23 ++--- tests/testsuite/features_namespaced.rs | 111 ++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 12 deletions(-) diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index de583392b62..a96151fcd5a 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -267,17 +267,18 @@ fn transmit( return Ok(()); } - let summary = pkg.summary(); - let string_features = summary - .features() - .iter() - .map(|(feat, values)| { - ( - feat.to_string(), - values.iter().map(|fv| fv.to_string()).collect(), - ) - }) - .collect::>>(); + let string_features = match manifest.original().features() { + Some(features) => features + .iter() + .map(|(feat, values)| { + ( + feat.to_string(), + values.iter().map(|fv| fv.to_string()).collect(), + ) + }) + .collect::>>(), + None => BTreeMap::new(), + }; let publish = registry.publish( &NewCrate { diff --git a/tests/testsuite/features_namespaced.rs b/tests/testsuite/features_namespaced.rs index c5206865ec2..55078f1c28e 100644 --- a/tests/testsuite/features_namespaced.rs +++ b/tests/testsuite/features_namespaced.rs @@ -1,7 +1,7 @@ //! Tests for namespaced features. -use cargo_test_support::project; use cargo_test_support::registry::{Dependency, Package}; +use cargo_test_support::{project, publish}; #[cargo_test] fn gated() { @@ -997,3 +997,112 @@ bar v1.0.0 ) .run(); } + +#[cargo_test] +fn publish_no_implicit() { + // Does not include implicit features or dep: syntax on publish. + Package::new("opt-dep1", "1.0.0").publish(); + Package::new("opt-dep2", "1.0.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + description = "foo" + license = "MIT" + homepage = "https://example.com/" + + [dependencies] + opt-dep1 = { version = "1.0", optional = true } + opt-dep2 = { version = "1.0", optional = true } + + [features] + feat = ["opt-dep1"] + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("publish --no-verify --token sekrit") + .with_stderr( + "\ +[UPDATING] [..] +[PACKAGING] foo v0.1.0 [..] +[UPLOADING] foo v0.1.0 [..] +", + ) + .run(); + + publish::validate_upload_with_contents( + r#" + { + "authors": [], + "badges": {}, + "categories": [], + "deps": [ + { + "default_features": true, + "features": [], + "kind": "normal", + "name": "opt-dep1", + "optional": true, + "registry": "https://github.com/rust-lang/crates.io-index", + "target": null, + "version_req": "^1.0" + }, + { + "default_features": true, + "features": [], + "kind": "normal", + "name": "opt-dep2", + "optional": true, + "registry": "https://github.com/rust-lang/crates.io-index", + "target": null, + "version_req": "^1.0" + } + ], + "description": "foo", + "documentation": null, + "features": { + "feat": ["opt-dep1"] + }, + "homepage": "https://example.com/", + "keywords": [], + "license": "MIT", + "license_file": null, + "links": null, + "name": "foo", + "readme": null, + "readme_file": null, + "repository": null, + "vers": "0.1.0" + } + "#, + "foo-0.1.0.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"], + &[( + "Cargo.toml", + r#"[..] +[package] +name = "foo" +version = "0.1.0" +description = "foo" +homepage = "https://example.com/" +license = "MIT" +[dependencies.opt-dep1] +version = "1.0" +optional = true + +[dependencies.opt-dep2] +version = "1.0" +optional = true + +[features] +feat = ["opt-dep1"] +"#, + )], + ); +}