feat(toml): Allow versionless packages

This defaults the version to `0.0.0` for most of cargo.

It is an error to lack a version and have a package publishable.
That means you have to add `publish = false`.
This commit is contained in:
Ed Page 2023-10-04 12:33:35 -05:00
parent 0b5ebd445b
commit 1923b5b862
6 changed files with 290 additions and 45 deletions

View File

@ -550,11 +550,17 @@ impl TomlManifest {
let version = package
.version
.clone()
.resolve("version", || inherit()?.version())?;
.map(|version| version.resolve("version", || inherit()?.version()))
.transpose()?;
package.version = MaybeWorkspace::Defined(version.clone());
package.version = version.clone().map(MaybeWorkspace::Defined);
let pkgid = package.to_package_id(source_id, version)?;
let pkgid = package.to_package_id(
source_id,
version
.clone()
.unwrap_or_else(|| semver::Version::new(0, 0, 0)),
)?;
let edition = if let Some(edition) = package.edition.clone() {
let edition: Edition = edition
@ -1009,6 +1015,10 @@ impl TomlManifest {
None | Some(VecStringOrBool::Bool(true)) => None,
};
if version.is_none() && publish != Some(vec![]) {
bail!("`package.publish` requires `package.version` be specified");
}
if summary.features().contains_key("default-features") {
warnings.push(
"`default-features = [\"..\"]` was found in [features]. \
@ -1659,7 +1669,7 @@ pub struct TomlPackage {
edition: Option<MaybeWorkspaceString>,
rust_version: Option<MaybeWorkspaceRustVersion>,
name: InternedString,
version: MaybeWorkspaceSemverVersion,
version: Option<MaybeWorkspaceSemverVersion>,
authors: Option<MaybeWorkspaceVecString>,
build: Option<StringOrBool>,
metabuild: Option<StringOrVec>,

View File

@ -109,6 +109,8 @@ resolve dependencies, and for guidelines on setting your own version. See the
[SemVer compatibility] chapter for more details on exactly what constitutes a
breaking change.
This field is optional and defaults to `0.0.0`.
[Resolver]: resolver.md
[SemVer compatibility]: semver.md

View File

@ -1506,22 +1506,17 @@ fn versionless_package() {
[package]
name = "foo"
description = "foo"
publish = false
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("check")
.with_stderr(
r#"error: failed to parse manifest at `[CWD]/Cargo.toml`
Caused by:
TOML parse error at line 2, column 17
|
2 | [package]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
missing field `version`
"#,
"\
[CHECKING] foo v0.0.0 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.with_status(101)
.run();
}

View File

@ -4273,6 +4273,7 @@ fn versionless_packages() {
r#"
[package]
name = "bar"
publish = false
[dependencies]
foobar = "0.0.1"
@ -4285,6 +4286,7 @@ fn versionless_packages() {
r#"
[package]
name = "baz"
publish = false
[dependencies]
foobar = "0.0.1"
@ -4295,20 +4297,247 @@ fn versionless_packages() {
Package::new("foobar", "0.0.1").publish();
p.cargo("metadata -q --format-version 1")
.with_stderr(
r#"error: failed to load manifest for workspace member `[CWD]/bar`
Caused by:
failed to parse manifest at `[CWD]/bar/Cargo.toml`
Caused by:
TOML parse error at line 2, column 17
|
2 | [package]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
missing field `version`
.with_json(
r#"
{
"packages": [
{
"name": "bar",
"version": "0.0.0",
"id": "bar 0.0.0 [..]",
"license": null,
"license_file": null,
"description": null,
"source": null,
"dependencies": [
{
"name": "baz",
"source": null,
"req": "*",
"kind": null,
"rename": null,
"optional": false,
"uses_default_features": true,
"features": [],
"target": null,
"registry": null,
"path": "[..]/baz"
},
{
"name": "foobar",
"source": "registry+https://github.com/rust-lang/crates.io-index",
"req": "^0.0.1",
"kind": null,
"rename": null,
"optional": false,
"uses_default_features": true,
"features": [],
"target": null,
"registry": null
}
],
"targets": [
{
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "bar",
"src_path": "[..]/bar/src/lib.rs",
"edition": "2015",
"doc": true,
"doctest": true,
"test": true
}
],
"features": {},
"manifest_path": "[..]/bar/Cargo.toml",
"metadata": null,
"publish": [],
"authors": [],
"categories": [],
"keywords": [],
"readme": null,
"repository": null,
"homepage": null,
"documentation": null,
"edition": "2015",
"links": null,
"default_run": null,
"rust_version": null
},
{
"name": "baz",
"version": "0.0.0",
"id": "baz 0.0.0 [..]",
"license": null,
"license_file": null,
"description": null,
"source": null,
"dependencies": [
{
"name": "foobar",
"source": "registry+https://github.com/rust-lang/crates.io-index",
"req": "^0.0.1",
"kind": null,
"rename": null,
"optional": false,
"uses_default_features": true,
"features": [],
"target": null,
"registry": null
}
],
"targets": [
{
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "baz",
"src_path": "[..]/baz/src/lib.rs",
"edition": "2015",
"doc": true,
"doctest": true,
"test": true
}
],
"features": {},
"manifest_path": "[..]/baz/Cargo.toml",
"metadata": null,
"publish": [],
"authors": [],
"categories": [],
"keywords": [],
"readme": null,
"repository": null,
"homepage": null,
"documentation": null,
"edition": "2015",
"links": null,
"default_run": null,
"rust_version": null
},
{
"name": "foobar",
"version": "0.0.1",
"id": "foobar 0.0.1 [..]",
"license": null,
"license_file": null,
"description": null,
"source": "registry+https://github.com/rust-lang/crates.io-index",
"dependencies": [],
"targets": [
{
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "foobar",
"src_path": "[..]/foobar-0.0.1/src/lib.rs",
"edition": "2015",
"doc": true,
"doctest": true,
"test": true
}
],
"features": {},
"manifest_path": "[..]/foobar-0.0.1/Cargo.toml",
"metadata": null,
"publish": null,
"authors": [],
"categories": [],
"keywords": [],
"readme": null,
"repository": null,
"homepage": null,
"documentation": null,
"edition": "2015",
"links": null,
"default_run": null,
"rust_version": null
}
],
"workspace_members": [
"bar 0.0.0 [..]",
"baz 0.0.0 [..]"
],
"workspace_default_members": [
"bar 0.0.0 [..]",
"baz 0.0.0 [..]"
],
"resolve": {
"nodes": [
{
"id": "bar 0.0.0 [..]",
"dependencies": [
"baz 0.0.0 [..]",
"foobar 0.0.1 [..]"
],
"deps": [
{
"name": "baz",
"pkg": "baz 0.0.0 [..]",
"dep_kinds": [
{
"kind": null,
"target": null
}
]
},
{
"name": "foobar",
"pkg": "foobar 0.0.1 [..]",
"dep_kinds": [
{
"kind": null,
"target": null
}
]
}
],
"features": []
},
{
"id": "baz 0.0.0 [..]",
"dependencies": [
"foobar 0.0.1 [..]"
],
"deps": [
{
"name": "foobar",
"pkg": "foobar 0.0.1 [..]",
"dep_kinds": [
{
"kind": null,
"target": null
}
]
}
],
"features": []
},
{
"id": "foobar 0.0.1 [..]",
"dependencies": [],
"deps": [],
"features": []
}
],
"root": null
},
"target_directory": "[..]/foo/target",
"version": 1,
"workspace_root": "[..]",
"metadata": null
}
"#,
)
.with_status(101)
.run();
}

View File

@ -3105,6 +3105,7 @@ fn versionless_package() {
[package]
name = "foo"
description = "foo"
publish = false
"#,
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
@ -3112,16 +3113,23 @@ fn versionless_package() {
p.cargo("package")
.with_stderr(
r#"error: failed to parse manifest at `[CWD]/Cargo.toml`
Caused by:
TOML parse error at line 2, column 17
|
2 | [package]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
missing field `version`
"#,
"\
warning: manifest has no license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
Packaging foo v0.0.0 ([CWD])
Verifying foo v0.0.0 ([CWD])
Compiling foo v0.0.0 ([CWD]/target/package/foo-0.0.0)
Finished dev [unoptimized + debuginfo] target(s) in [..]s
Packaged 4 files, [..]B ([..]B compressed)
",
)
.with_status(101)
.run();
let f = File::open(&p.root().join("target/package/foo-0.0.0.crate")).unwrap();
validate_crate_contents(
f,
"foo-0.0.0.crate",
&["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
&[],
);
}

View File

@ -3007,6 +3007,9 @@ Caused by:
#[cargo_test]
fn versionless_package() {
// Use local registry for faster test times since no publish will occur
let registry = registry::init();
let p = project()
.file(
"Cargo.toml",
@ -3020,17 +3023,15 @@ fn versionless_package() {
.build();
p.cargo("publish")
.replace_crates_io(registry.index_url())
.with_status(101)
.with_stderr(
r#"error: failed to parse manifest at `[CWD]/Cargo.toml`
"\
error: failed to parse manifest at `[CWD]/Cargo.toml`
Caused by:
TOML parse error at line 2, column 17
|
2 | [package]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
missing field `version`
"#,
`package.publish` requires `package.version` be specified
",
)
.with_status(101)
.run();
}