Skip to content

Commit d709c10

Browse files
committed
Allow publishing with dev-dependencies without a version.
1 parent fe0e5a4 commit d709c10

File tree

7 files changed

+98
-12
lines changed

7 files changed

+98
-12
lines changed

src/cargo/ops/cargo_package.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> {
206206
// Checks that the package dependencies are safe to deploy.
207207
fn verify_dependencies(pkg: &Package) -> CargoResult<()> {
208208
for dep in pkg.dependencies() {
209-
if dep.source_id().is_path() && !dep.specified_req() {
209+
if dep.source_id().is_path() && !dep.specified_req() && dep.is_transitive() {
210210
failure::bail!(
211211
"all path dependencies must have a version specified \
212212
when packaging.\ndependency `{}` does not specify \

src/cargo/ops/registry.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ fn verify_dependencies(
116116
for dep in pkg.dependencies().iter() {
117117
if dep.source_id().is_path() || dep.source_id().is_git() {
118118
if !dep.specified_req() {
119+
if !dep.is_transitive() {
120+
// dev-dependencies will be stripped in TomlManifest::prepare_for_publish
121+
continue;
122+
}
119123
let which = if dep.source_id().is_path() {
120124
"path"
121125
} else {
@@ -172,6 +176,10 @@ fn transmit(
172176
let deps = pkg
173177
.dependencies()
174178
.iter()
179+
.filter(|dep| {
180+
// Skip dev-dependency without version.
181+
dep.is_transitive() || dep.specified_req()
182+
})
175183
.map(|dep| {
176184
// If the dependency is from a different registry, then include the
177185
// registry in the dependency.

src/cargo/util/toml/mod.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ impl TomlManifest {
722722
.unwrap()
723723
.clone();
724724
package.workspace = None;
725+
let all = |_d: &TomlDependency| true;
725726
return Ok(TomlManifest {
726727
package: Some(package),
727728
project: None,
@@ -731,19 +732,21 @@ impl TomlManifest {
731732
example: self.example.clone(),
732733
test: self.test.clone(),
733734
bench: self.bench.clone(),
734-
dependencies: map_deps(config, self.dependencies.as_ref())?,
735+
dependencies: map_deps(config, self.dependencies.as_ref(), all)?,
735736
dev_dependencies: map_deps(
736737
config,
737738
self.dev_dependencies
738739
.as_ref()
739740
.or_else(|| self.dev_dependencies2.as_ref()),
741+
TomlDependency::is_version_specified,
740742
)?,
741743
dev_dependencies2: None,
742744
build_dependencies: map_deps(
743745
config,
744746
self.build_dependencies
745747
.as_ref()
746748
.or_else(|| self.build_dependencies2.as_ref()),
749+
all,
747750
)?,
748751
build_dependencies2: None,
749752
features: self.features.clone(),
@@ -754,19 +757,21 @@ impl TomlManifest {
754757
Ok((
755758
k.clone(),
756759
TomlPlatform {
757-
dependencies: map_deps(config, v.dependencies.as_ref())?,
760+
dependencies: map_deps(config, v.dependencies.as_ref(), all)?,
758761
dev_dependencies: map_deps(
759762
config,
760763
v.dev_dependencies
761764
.as_ref()
762765
.or_else(|| v.dev_dependencies2.as_ref()),
766+
TomlDependency::is_version_specified,
763767
)?,
764768
dev_dependencies2: None,
765769
build_dependencies: map_deps(
766770
config,
767771
v.build_dependencies
768772
.as_ref()
769773
.or_else(|| v.build_dependencies2.as_ref()),
774+
all,
770775
)?,
771776
build_dependencies2: None,
772777
},
@@ -788,13 +793,15 @@ impl TomlManifest {
788793
fn map_deps(
789794
config: &Config,
790795
deps: Option<&BTreeMap<String, TomlDependency>>,
796+
filter: impl Fn(&TomlDependency) -> bool,
791797
) -> CargoResult<Option<BTreeMap<String, TomlDependency>>> {
792798
let deps = match deps {
793799
Some(deps) => deps,
794800
None => return Ok(None),
795801
};
796802
let deps = deps
797803
.iter()
804+
.filter(|(_k, v)| filter(v))
798805
.map(|(k, v)| Ok((k.clone(), map_dependency(config, v)?)))
799806
.collect::<CargoResult<BTreeMap<_, _>>>()?;
800807
Ok(Some(deps))
@@ -1221,11 +1228,7 @@ impl TomlManifest {
12211228
spec.set_url(CRATES_IO_INDEX.parse().unwrap());
12221229
}
12231230

1224-
let version_specified = match *replacement {
1225-
TomlDependency::Detailed(ref d) => d.version.is_some(),
1226-
TomlDependency::Simple(..) => true,
1227-
};
1228-
if version_specified {
1231+
if replacement.is_version_specified() {
12291232
bail!(
12301233
"replacements cannot specify a version \
12311234
requirement, but found one for `{}`",
@@ -1330,6 +1333,13 @@ impl TomlDependency {
13301333
TomlDependency::Detailed(ref details) => details.to_dependency(name, cx, kind),
13311334
}
13321335
}
1336+
1337+
fn is_version_specified(&self) -> bool {
1338+
match self {
1339+
TomlDependency::Detailed(d) => d.version.is_some(),
1340+
TomlDependency::Simple(..) => true,
1341+
}
1342+
}
13331343
}
13341344

13351345
impl DetailedTomlDependency {

src/doc/man/cargo-package.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ steps:
2121
. Load and check the current workspace, performing some basic checks.
2222
- Path dependencies are not allowed unless they have a version key. Cargo
2323
will ignore the path key for dependencies in published packages.
24+
`dev-dependencies` do not have this restriction.
2425
. Create the compressed `.crate` file.
2526
- The original `Cargo.toml` file is rewritten and normalized.
2627
- `[patch]`, `[replace]`, and `[workspace]` sections are removed from the

src/doc/man/generated/cargo-package.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ <h2 id="cargo_package_description">DESCRIPTION</h2>
2727
<ul>
2828
<li>
2929
<p>Path dependencies are not allowed unless they have a version key. Cargo
30-
will ignore the path key for dependencies in published packages.</p>
30+
will ignore the path key for dependencies in published packages.
31+
<code>dev-dependencies</code> do not have this restriction.</p>
3132
</li>
3233
</ul>
3334
</div>

src/etc/man/cargo-package.1

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
'\" t
22
.\" Title: cargo-package
33
.\" Author: [see the "AUTHOR(S)" section]
4-
.\" Generator: Asciidoctor 2.0.8
5-
.\" Date: 2019-07-15
4+
.\" Generator: Asciidoctor 2.0.10
5+
.\" Date: 2019-09-05
66
.\" Manual: \ \&
77
.\" Source: \ \&
88
.\" Language: English
99
.\"
10-
.TH "CARGO\-PACKAGE" "1" "2019-07-15" "\ \&" "\ \&"
10+
.TH "CARGO\-PACKAGE" "1" "2019-09-05" "\ \&" "\ \&"
1111
.ie \n(.g .ds Aq \(aq
1212
.el .ds Aq '
1313
.ss \n[.ss] 0
@@ -59,6 +59,7 @@ Load and check the current workspace, performing some basic checks.
5959
.\}
6060
Path dependencies are not allowed unless they have a version key. Cargo
6161
will ignore the path key for dependencies in published packages.
62+
\fBdev\-dependencies\fP do not have this restriction.
6263
.RE
6364
.RE
6465
.sp

tests/testsuite/publish.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,3 +1178,68 @@ fn publish_git_with_version() {
11781178
],
11791179
);
11801180
}
1181+
1182+
#[cargo_test]
1183+
fn publish_dev_dep_no_version() {
1184+
registry::init();
1185+
1186+
let p = project()
1187+
.file(
1188+
"Cargo.toml",
1189+
r#"
1190+
[package]
1191+
name = "foo"
1192+
version = "0.1.0"
1193+
authors = []
1194+
license = "MIT"
1195+
description = "foo"
1196+
documentation = "foo"
1197+
homepage = "foo"
1198+
repository = "foo"
1199+
1200+
[dev-dependencies]
1201+
bar = { path = "bar" }
1202+
"#,
1203+
)
1204+
.file("src/lib.rs", "")
1205+
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
1206+
.file("bar/src/lib.rs", "")
1207+
.build();
1208+
1209+
p.cargo("publish --no-verify --index")
1210+
.arg(registry_url().to_string())
1211+
.with_stderr(
1212+
"\
1213+
[UPDATING] [..]
1214+
[PACKAGING] foo v0.1.0 [..]
1215+
[UPLOADING] foo v0.1.0 [..]
1216+
",
1217+
)
1218+
.run();
1219+
1220+
publish::validate_upload(
1221+
r#"
1222+
{
1223+
"authors": [],
1224+
"badges": {},
1225+
"categories": [],
1226+
"deps": [],
1227+
"description": "foo",
1228+
"documentation": "foo",
1229+
"features": {},
1230+
"homepage": "foo",
1231+
"keywords": [],
1232+
"license": "MIT",
1233+
"license_file": null,
1234+
"links": null,
1235+
"name": "foo",
1236+
"readme": null,
1237+
"readme_file": null,
1238+
"repository": "foo",
1239+
"vers": "0.1.0"
1240+
}
1241+
"#,
1242+
"foo-0.1.0.crate",
1243+
&["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"],
1244+
);
1245+
}

0 commit comments

Comments
 (0)