Skip to content

Commit

Permalink
Auto merge of #13947 - tweag:package-workspace, r=epage
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jul 26, 2024
2 parents b9e432a + a2f0a9e commit b5d44db
Show file tree
Hide file tree
Showing 17 changed files with 1,389 additions and 163 deletions.
20 changes: 20 additions & 0 deletions src/bin/cargo/commands/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use cargo::ops::{self, PackageOpts};
pub fn cli() -> Command {
subcommand("package")
.about("Assemble the local package into a distributable tarball")
.arg_index("Registry index URL to prepare the package for (unstable)")
.arg_registry("Registry to prepare the package for (unstable)")
.arg(
flag(
"list",
Expand Down Expand Up @@ -41,6 +43,23 @@ pub fn cli() -> Command {
}

pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
if args._value_of("registry").is_some() {
gctx.cli_unstable().fail_if_stable_opt_custom_z(
"--registry",
13947,
"package-workspace",
gctx.cli_unstable().package_workspace,
)?;
}
if args._value_of("index").is_some() {
gctx.cli_unstable().fail_if_stable_opt_custom_z(
"--index",
13947,
"package-workspace",
gctx.cli_unstable().package_workspace,
)?;
}
let reg_or_index = args.registry_or_index(gctx)?;
let ws = args.workspace(gctx)?;
if ws.root_maybe().is_embedded() {
return Err(anyhow::format_err!(
Expand All @@ -64,6 +83,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
jobs: args.jobs()?,
keep_going: args.keep_going(),
cli_features: args.cli_features()?,
reg_or_index,
},
)?;

Expand Down
2 changes: 2 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,7 @@ unstable_cli_options!(
mtime_on_use: bool = ("Configure Cargo to update the mtime of used files"),
next_lockfile_bump: bool,
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
package_workspace: bool = ("Handle intra-workspace dependencies when packaging"),
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
public_dependency: bool = ("Respect a dependency's `public` field in Cargo.toml to control public/private dependencies"),
Expand Down Expand Up @@ -1276,6 +1277,7 @@ impl CliUnstable {
// can also be set in .cargo/config or with and ENV
"mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?,
"no-index-update" => self.no_index_update = parse_empty(k, v)?,
"package-workspace" => self.package_workspace= parse_empty(k, v)?,
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
"public-dependency" => self.public_dependency = parse_empty(k, v)?,
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,
Expand Down
Loading

0 comments on commit b5d44db

Please sign in to comment.