Skip to content

Commit 2af662e

Browse files
committed
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.
2 parents 770f403 + 2a07061 commit 2af662e

File tree

2 files changed

+122
-12
lines changed

2 files changed

+122
-12
lines changed

src/cargo/ops/registry.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -267,17 +267,18 @@ fn transmit(
267267
return Ok(());
268268
}
269269

270-
let summary = pkg.summary();
271-
let string_features = summary
272-
.features()
273-
.iter()
274-
.map(|(feat, values)| {
275-
(
276-
feat.to_string(),
277-
values.iter().map(|fv| fv.to_string()).collect(),
278-
)
279-
})
280-
.collect::<BTreeMap<String, Vec<String>>>();
270+
let string_features = match manifest.original().features() {
271+
Some(features) => features
272+
.iter()
273+
.map(|(feat, values)| {
274+
(
275+
feat.to_string(),
276+
values.iter().map(|fv| fv.to_string()).collect(),
277+
)
278+
})
279+
.collect::<BTreeMap<String, Vec<String>>>(),
280+
None => BTreeMap::new(),
281+
};
281282

282283
let publish = registry.publish(
283284
&NewCrate {

tests/testsuite/features_namespaced.rs

+110-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Tests for namespaced features.
22
3-
use cargo_test_support::project;
43
use cargo_test_support::registry::{Dependency, Package};
4+
use cargo_test_support::{project, publish};
55

66
#[cargo_test]
77
fn gated() {
@@ -997,3 +997,112 @@ bar v1.0.0
997997
)
998998
.run();
999999
}
1000+
1001+
#[cargo_test]
1002+
fn publish_no_implicit() {
1003+
// Does not include implicit features or dep: syntax on publish.
1004+
Package::new("opt-dep1", "1.0.0").publish();
1005+
Package::new("opt-dep2", "1.0.0").publish();
1006+
1007+
let p = project()
1008+
.file(
1009+
"Cargo.toml",
1010+
r#"
1011+
[package]
1012+
name = "foo"
1013+
version = "0.1.0"
1014+
description = "foo"
1015+
license = "MIT"
1016+
homepage = "https://example.com/"
1017+
1018+
[dependencies]
1019+
opt-dep1 = { version = "1.0", optional = true }
1020+
opt-dep2 = { version = "1.0", optional = true }
1021+
1022+
[features]
1023+
feat = ["opt-dep1"]
1024+
"#,
1025+
)
1026+
.file("src/lib.rs", "")
1027+
.build();
1028+
1029+
p.cargo("publish --no-verify --token sekrit")
1030+
.with_stderr(
1031+
"\
1032+
[UPDATING] [..]
1033+
[PACKAGING] foo v0.1.0 [..]
1034+
[UPLOADING] foo v0.1.0 [..]
1035+
",
1036+
)
1037+
.run();
1038+
1039+
publish::validate_upload_with_contents(
1040+
r#"
1041+
{
1042+
"authors": [],
1043+
"badges": {},
1044+
"categories": [],
1045+
"deps": [
1046+
{
1047+
"default_features": true,
1048+
"features": [],
1049+
"kind": "normal",
1050+
"name": "opt-dep1",
1051+
"optional": true,
1052+
"registry": "https://github.com/rust-lang/crates.io-index",
1053+
"target": null,
1054+
"version_req": "^1.0"
1055+
},
1056+
{
1057+
"default_features": true,
1058+
"features": [],
1059+
"kind": "normal",
1060+
"name": "opt-dep2",
1061+
"optional": true,
1062+
"registry": "https://github.com/rust-lang/crates.io-index",
1063+
"target": null,
1064+
"version_req": "^1.0"
1065+
}
1066+
],
1067+
"description": "foo",
1068+
"documentation": null,
1069+
"features": {
1070+
"feat": ["opt-dep1"]
1071+
},
1072+
"homepage": "https://example.com/",
1073+
"keywords": [],
1074+
"license": "MIT",
1075+
"license_file": null,
1076+
"links": null,
1077+
"name": "foo",
1078+
"readme": null,
1079+
"readme_file": null,
1080+
"repository": null,
1081+
"vers": "0.1.0"
1082+
}
1083+
"#,
1084+
"foo-0.1.0.crate",
1085+
&["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"],
1086+
&[(
1087+
"Cargo.toml",
1088+
r#"[..]
1089+
[package]
1090+
name = "foo"
1091+
version = "0.1.0"
1092+
description = "foo"
1093+
homepage = "https://example.com/"
1094+
license = "MIT"
1095+
[dependencies.opt-dep1]
1096+
version = "1.0"
1097+
optional = true
1098+
1099+
[dependencies.opt-dep2]
1100+
version = "1.0"
1101+
optional = true
1102+
1103+
[features]
1104+
feat = ["opt-dep1"]
1105+
"#,
1106+
)],
1107+
);
1108+
}

0 commit comments

Comments
 (0)