Skip to content

Commit b5d44db

Browse files
committed
Auto merge of #13947 - tweag:package-workspace, r=epage
Package workspaces Adds support for packaging an entire workspace, even when there are dependencies between the crates. The generated packages should be identical to the ones produced by packaging and publishing the crates one-by-one in dependency order, but the main benefit of this PR is that the packages can be created and verified locally before anything is published. The main mechanism is the one in #13926, where we create a temporary local registry that "overlays" the true registry. We "publish" the crates in the local registry, which enables lockfile generation and verification of the dependent crates. This adds `--registry` and `--index` flags to `cargo package`. They act much like the same arguments to `cargo publish`, except that of course we are not actually publishing to the specified registry. Instead, these arguments affect lock-file generation for intra-workspace dependencies: when simultaneously packaging a crate and one of its dependencies, the lock-file will be generated under the assumption that the dependency will be published to the specified registry. You can also publish a subset of a workspace using `-p` arguments. In this case, there will be an error unless the chosen subset contains all of the dependencies of everything in the subset. Fixes #10948. Based on #13926. ### Compatibility issue This PR introduces a case where `cargo package` will fail where it did not before: if you have a workspace containing two packages, `main` and `[email protected]`, where `main` depends on `[email protected]` and `[email protected]` is already published in crates.io then attempting to package the whole workspace will fail. To be specific, it will package `[email protected]` successfully and then fail when trying to package `main` because it will see the two different packages for `[email protected]`. Note that `cargo publish` will already fail in this scenario. This shouldn't interfere with crates.io running `cargo package` for each package to diff the `.crate` files - This might interfere if someone tried to verify their "published" MSRV by running `cargo package`. The failure could be avoided by changing the local overlay source to not error out if there's a duplicate package; see [here](#13926 (comment)). However, failing early has the advantage of catching errors early.
2 parents b9e432a + a2f0a9e commit b5d44db

File tree

17 files changed

+1389
-163
lines changed

17 files changed

+1389
-163
lines changed

src/bin/cargo/commands/package.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use cargo::ops::{self, PackageOpts};
55
pub fn cli() -> Command {
66
subcommand("package")
77
.about("Assemble the local package into a distributable tarball")
8+
.arg_index("Registry index URL to prepare the package for (unstable)")
9+
.arg_registry("Registry to prepare the package for (unstable)")
810
.arg(
911
flag(
1012
"list",
@@ -41,6 +43,23 @@ pub fn cli() -> Command {
4143
}
4244

4345
pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
46+
if args._value_of("registry").is_some() {
47+
gctx.cli_unstable().fail_if_stable_opt_custom_z(
48+
"--registry",
49+
13947,
50+
"package-workspace",
51+
gctx.cli_unstable().package_workspace,
52+
)?;
53+
}
54+
if args._value_of("index").is_some() {
55+
gctx.cli_unstable().fail_if_stable_opt_custom_z(
56+
"--index",
57+
13947,
58+
"package-workspace",
59+
gctx.cli_unstable().package_workspace,
60+
)?;
61+
}
62+
let reg_or_index = args.registry_or_index(gctx)?;
4463
let ws = args.workspace(gctx)?;
4564
if ws.root_maybe().is_embedded() {
4665
return Err(anyhow::format_err!(
@@ -64,6 +83,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
6483
jobs: args.jobs()?,
6584
keep_going: args.keep_going(),
6685
cli_features: args.cli_features()?,
86+
reg_or_index,
6787
},
6888
)?;
6989

src/cargo/core/features.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,7 @@ unstable_cli_options!(
774774
mtime_on_use: bool = ("Configure Cargo to update the mtime of used files"),
775775
next_lockfile_bump: bool,
776776
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
777+
package_workspace: bool = ("Handle intra-workspace dependencies when packaging"),
777778
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
778779
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
779780
public_dependency: bool = ("Respect a dependency's `public` field in Cargo.toml to control public/private dependencies"),
@@ -1276,6 +1277,7 @@ impl CliUnstable {
12761277
// can also be set in .cargo/config or with and ENV
12771278
"mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?,
12781279
"no-index-update" => self.no_index_update = parse_empty(k, v)?,
1280+
"package-workspace" => self.package_workspace= parse_empty(k, v)?,
12791281
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
12801282
"public-dependency" => self.public_dependency = parse_empty(k, v)?,
12811283
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,

0 commit comments

Comments
 (0)