278 Commits

Author SHA1 Message Date
Ed Page
19f1d1561c fix: Switch from --nocapture to --no-capture
`--no-capture` was added in 1.88, with `--nocapture` being
soft-deprecated.
2025-09-05 10:33:00 -05:00
Scott Schafer
022dc5b381
chore: Address most typos 2025-09-02 18:15:50 -06:00
Ross Sullivan
81f119d45a
fix(package): Fixed inconsistent build cache behavior during package verify
When running `cargo package` the verify the build cache
(target-dir/build-dir) will not be used and all dependencies will be
recompiled.

This is inconsistent as setting target dir (via `CARGO_TARGET_DIR` for
example) will cause `cargo package` to reuse the build cache.

This commit changes the default behavior to always use the build cache,
matching the behavior of having target-dir set.
2025-07-29 21:59:18 +09:00
Ross Sullivan
84e4277dc4
test(package): Add test to verify package build cache behavior 2025-07-29 21:46:25 +09:00
Sebastian Thiel
d3b85cd96a
Provide a package implementation with gix-status.
This should also help fixing these spurious "cannot package because
some excluded file is untracked" issues.

Remove the respective `git2` implementation at the same time
as there seems to be no need for it.
2025-07-23 04:36:07 +02:00
Ed Page
c8bf4096de feat(publish): Stabilize multi-package publishing
A user will now be able to use flags like `--workspace` with `cargo
publish`.
`cargo package` will now also work with those flags without having to
pass `--no-verify --exclude-lockfile`.

Many release tools have come out that solve this problem.
They will still need a lot of the logic that went into that for other
parts of the release process.
However, a cargo-native solution allows for:
- Verification during dry-run
- Better strategies for waiting for the publish timeout

`cargo publish` is non-atomic at this time.
If there is a server side error, network error, or rate limit during the publish,
the workspace will be left in a partially published state.
Verification is done before any publishing so that won't affect things.
There are multiple strategies we can employ for improving this over time,
including
- atomic publish
- `--idempotent` (#13397)
- leave this to release tools to manage

This includes support for `--dry-run` verification.
As release tools didn't have a way to do this before,
users may be surprised at how slow this is because a `cargo build` is
done instead of a `cargo check`.  This is being tracked in #14941.

This adds to `cargo package` the `--registry` and `--index` flags to
help with resolving dependencies when depending on a package being
packaged at that moment.
These flags are only needed when a `cargo package --workspace` operation
would have failed before due to inability to find a locally created
dependency.

Regarding the publish timeout, `cargo publish --workspace` publishes
packages in batches and we only timeout if nothing in the batch has
finished being published within the timeout, deferring the rest to the
next wait-for-publish. So for example, if you have packages `a`, `b`, `c` then
we'll wait up to 60 seconds and if only `a` and `b` were ready in that time,
we'll then wait another 60 seconds for `c`.

During testing, users ran into issues with `.crate` checksums that we've
not been able to reproduce since:
- https://github.com/rust-lang/cargo/issues/1169#issuecomment-2567995987
- #14396

By stabilizing this, Cargo's behavior becomes dependent on an overlay
registry.
When generating a lockfile or verifying a package, we overlay the
locally generated `.crate` files on top of the registry so the registry
appears as it would and everything works.
If there is a conflict with a version, the local version wins which is
important for the dry-run mode of release tools as they won't have
bumped the version yet.
Our concern for the overlay registry is dependency confusion attacks.
Considering this is not accessible for general user operations, this
should be fine.

Fixes #1169
Fixes #10948
2025-06-30 09:27:59 -05:00
Eric Huss
1ce8023626 Rustfmt 2024 2025-07-05 19:50:36 -07:00
Joe Neeman
95e961b4a0 Add a test showing the changed checksum. 2025-06-27 13:49:14 -05:00
Ed Page
4ac865d3d7
Rework cargo-test-support & testsuite to use CARGO_BIN_EXE_* for Cargo (#15692)
### What does this PR try to resolve?

This PR reworks `cargo-test-support` and `testsuite` to use Snapbox's
[`cargo_bin!()`](https://docs.rs/snapbox/latest/snapbox/cmd/macro.cargo_bin.html)
instead of
[`cargo_bin()`](https://docs.rs/snapbox/latest/snapbox/cmd/fn.cargo_bin.html)
which makes assumptions about the structure of Cargo's build directory.
`cargo_bin!()` uses `CARGO_BIN_EXE_*` for locating the `cargo` binary
which should be more resilient to directory/layout changes.

Linking a relevant Zulip discussion
[here](https://rust-lang.zulipchat.com/#narrow/channel/246057-t-cargo/topic/cargo_bin_exe.20and.20tests/with/513638220)[#t-cargo
> cargo_bin_exe and
tests](https://rust-lang.zulipchat.com/#narrow/channel/246057-t-cargo/topic/cargo_bin_exe.20and.20tests/with/513638220)

As shown in that link, we could make these variables available at
runtime and not need to do this. However, `cargo-test-support`, as an
API, is a bit weird in that it is baking in support for one specific
binary. This can be confusing for callers and makes it more annoying for
callers provide their own `fn cargo`, e.g. see crate-ci/cargo-fixit#7

### Implementation Notes

`cargo_bin!()` only works when being called from the `testsuite` as it's
only set when executing integration tests and `cargo-test-support` is a
regular crate.
To make this change, I introduced an extension trait `CargoProjectExt`
in `testsuite` for running `.cargo()` and implemented it on `Project`.

In `cargo-test-support` other functionality relies on `.cargo()` so
these also needed to be moved to `testsuite`
*
[`src/tools.rs`](https://github.com/rust-lang/cargo/blob/master/crates/cargo-test-support/src/tools.rs)
* Parts
[`src/cross_compile`](https://github.com/rust-lang/cargo/blob/master/crates/cargo-test-support/src/cross_compile.rs)
* I had to split this up unfortunately, as `disabled()` requires running
Cargo to check if we should disable cross compile tests.
* Other fns in `cross_compile` are used in `cargo-test-support` so
moving everything to `testsuite` would have ended up requiring moving
many things to test suite.

### How to test and review this PR?

I'd definitely recommend reviewing commit by commit.
There are a lot of diffs due to the nature of reorganizing things.
I did my best to split things things into smaller PRs but they still
contain a lot of `use` statement diffs.

r? @epage
2025-06-26 15:21:51 +00:00
motorailgun
8f4ae79cb5 fix: Expand error messages around path dependency on cargo package and cargo publish 2025-06-26 02:53:54 +00:00
Ross Sullivan
30b6707135
chore: Moved remaining cargo_exe logic to testsuite 2025-06-25 23:18:08 +09:00
Ross Sullivan
92d9a94d02
chore: Migrated testsuite to testsuite::prelude 2025-06-25 22:37:24 +09:00
Naman Garg
21c2f1615d
Add multi-build script support to cargo publish 2025-06-23 19:14:40 +05:30
Ed Page
a7be79bca8
refactor: clean up clippy::perf lint warnings (#15631)
### What does this PR try to resolve?

The `clippy::perf` lint group is fairly useful for catching bad
practices that might hurt performance marginally.

This PR fixes most of them except `clippy::large_enum_variant`, which
doesn't feel right at this moment and need more researches. And that is
why I didn't enable the lint group.

### How to test and review this PR?
2025-06-04 21:53:19 +00:00
Weihang Lo
c3409d5425
refactor: clean up clippy::perf lint warnings
The `clippy::perf` lint group is fairly useful for catching bad
practices that might hurt performance marginally.

This PR fixes most of them except `clippy::large_enum_variant`,
which doesn't feel right at this moment and need more researches.

Anyway, overall this PR should be good.
2025-06-04 14:23:12 -07:00
Ed Page
094ef50e94 fix(package): Skip registry check if its not needed
I believe this brings makes it so `cargo package -Zpackage-workspace` no longer has a
behavior change compared to `cargo package`.
2025-06-04 13:21:12 -05:00
Ed Page
4a92ad1241 test(package): Better characterize the -Zpackage-workspace behavior change 2025-06-04 13:08:59 -05:00
Ed Page
68f0c653ca test(package): Show stable behavior for -Zpackage-workspace 2025-06-04 12:59:10 -05:00
Ed Page
d6cc0fb192 test(package): Prep for forking tests for stable 2025-06-04 12:46:35 -05:00
Ed Page
876c9fb802 fix(package): Allow packaging of self-cycles with -Zpackage-workspace 2025-06-03 20:03:02 -05:00
Ed Page
27c39b6597 test(package): Show nightly self-dep behavior 2025-06-03 19:58:18 -05:00
Joe Neeman
faf7329c4f Only ignore dev-dependencies in dependency order if they have no version 2025-05-01 13:41:00 +07:00
Joe Neeman
efb300775a Add a failing test 2025-05-01 13:18:40 +07:00
Weihang Lo
314df11c74
Revert "fix(package): detect dirtiness for symlinks to submodule"
This reverts commit 71ea2e5c5fa285e8e0336d51fd03ba4a427154bf.

`Repository::discover` and `Repository::status_file` are too expenstive
to run inside a loop. And `cargo package` are doing a lot of duplicate
works for checking submodule VCS status.

The possible fix might look like

* Let `status_submodules` function returns a path entry set, so
  Cargo can check whether a source file is dirty based on that.
* When listing files in `PathSource`, attach the VCS status of a
  path entry assoicated with. Then subsequent operations can skip
  status check entirely.

The above solutions are not trivial, and the dirtiness check is
informational only based on T-cargo conclusion, so we should be
good just reverting the change now.

Again, the caveat of this is that we can't really detect
dirty symlinks that links into a Git submodule.
2025-04-11 14:04:38 -04:00
Weihang Lo
71ea2e5c5f
fix(package): detect dirtiness for symlinks to submodule
If a there is a symlink into a git repository/submodule,
when checking its git status with the wrong outer repo,
we'll get an NotFound error,
as the object doesn't belong to the outer repository.
This kind of error blocked the entire `cargo package` operation.

This fix additionally discovers the nearest Git repository,
and then checks status with that,
assuming the repo is the parent of the source file of the symlink.
This is a best effort solution, so if the check fails we ignore.
2025-04-10 12:43:10 -04:00
Weihang Lo
d760263afb
fix(package): ignore status check failure
Dirtiness check for symlinks is mostly informational.
And changes in submodule would fail git-status as well (see #15384).
To avoid adding complicated logic to handle that,
for now we ignore the status check failure.
2025-04-10 11:11:51 -04:00
Weihang Lo
79473988e5
test(package): show symlink to submodule failed the check 2025-04-10 11:11:44 -04:00
Sebastian Poeplau
aa1b353d64 Prevent undeclared public network access
Stop a few tests which aren't marked with `public_network_test` from
trying to access crates.io. While doing so, also make sure that other
`cargo_add` and `cargo_info` tests initialize the registry.
2025-04-01 11:41:30 +02:00
Weihang Lo
259128d270
fix: revert the behavior checking lockfile's VCS
Lockfile might be gitignore'd,
So it never shows up in `git status`.

However, `cargo packag` vcs checks actually performs
`git status --untracked --ignored`.
It is a bit confusing that lockfile is ignored but still counts as dirty
from the report of `cargo package`.

There are some more nuances:
We check lockfile's VCS status if the lockfile is ouside the current
package root. That means a non-workspace Cargo package will not have
this VCS check. I don't think it is good that we have diverged behaviors
Hence this revert.

We can always re-evaluate later,
as we've reserved rooms for doing more dirty checks.

https://github.com/rust-lang/cargo/issues/14967#issuecomment-2651329783
2025-03-25 13:15:34 -04:00
Ed Page
6cf8267012
feat(package): add --exclude-lockfile flag (#15234)
### What does this PR try to resolve?

Fixes #15059
Fixes #15159

This provides an escape hatch `--exclude-lockfile`for uncommon workflows
that don't verify (`--no-verify` is passed) the build with their
unpublished packages
In effect, this takes the heuristic removed in #14815 and replaces it
with a flag

When `--exclude-lockfile` is enabled,
`cargo package` will not verify the lock file if present,
nor will it generate a new one if absent.
Cargo.lock will not be included in the resulting tarball.

Together with `--no-verify`,
this flag decouples packaging from checking the registry index.
While this is useful for some non-normal workflows that requires
to assemble packages having unpublished dependencies.
It is recommended to use `-Zpackage-workspace` to package the entire
workspace, instead of opting out lockfile.

### How should we test and review this PR?

The first commit was stolen from
<1a104b5444>
(credit to @NoisyCoil!)

The second added two failing cases we observed in #15059.

### Additional information
2025-03-14 15:25:36 +00:00
Weihang Lo
f0907fca16
fix(package): report if the lockfile is dirty
Lockfile might not be under the package root, but its entries
may be outdated and get packaged into the `.crate` tarball.
We take a conservative action that if the lockfile is dirty,
then all workspace members are considered dirty.
2025-03-07 08:45:49 -05:00
Weihang Lo
d9908b14f7
test(package): dirty lockfile isn't considered dirty but should 2025-03-06 23:42:49 -05:00
Weihang Lo
1b94e1b27c
fix(package): report if workspace manifest is dirty
Workspace manifest might not be under the package root, but
workspace inheritance may still affect what is packaged into
the `.crate.` tarball. We take a conservative action that if
the workspace manifest is dirty, then all workspace members
are considered dirty.
2025-03-06 23:42:49 -05:00
Ed Page
8686e24c72
refactor: control byte display precision with std::fmt options (#15246)
### What does this PR try to resolve?

Just found we can simplify `human_readable_bytes` a bit.
This also remove the `bytesize` dependency,
since we already have a hand-rolled function.
(It is a good crate, though)

### How should we test and review this PR?

Should have no real functional difference.
`cargo package` starts reporting IEC (KiB) instead of SI (KB).
So do some thresholds of `cargo package`.

Could also switch entirely to `bytesize` if that is preferred.

### Additional information
2025-02-28 14:32:42 +00:00
Weihang Lo
425858c742
refactor: control byte display precision with std::fmt options 2025-02-28 08:56:28 -05:00
Ed Page
730348ada9 fix(package): Ensure we can package directories ending with '.rs'
This might have also broken dependencies whose path ends with `.rs` as
well

This broke in #14961
2025-02-27 14:50:56 -06:00
Ed Page
45da135dba test(package): Show cargo script mistaken identity 2025-02-27 14:46:05 -06:00
NoisyCoil
4e8b337eb3
feat(package): add --exclude-lockfile flag
When `--exclude-lockfile` is enabled,
`cargo package` will not verify the lock file if present,
nor will it generate a new one if absent.
Cargo.lock will not be included in the resulting tarball.

Together with `--no-verify`,
this flag decouples packaging from checking the registry index.
While this is useful for some non-normal workflows that requires
to assemble packages having unpublished dependencies.
It is recommended to use `-Zpackage-workspace` to package the entire
workspace, instead of opting out lockfile.
2025-02-26 12:48:48 -05:00
Weihang Lo
b7002ffd5e
test(package): fail with unpublished cyclic/transitive deps
After dd698ff0483bda065d1f78968e70ee86fb116a72,
`cargo package --no-verify` at least fails in three different cases:

* An unpublished package depending on itself as a dev-dependency (cyclic self-referential dev-dependencies).
  * Can be resolved by removing the `version` field from the affected dev-dependency.
  * `-Zpackage-workspace` doesn't help with it.
* Existing `cargo package` has `--package <pkg>` specifying certain unpublished packages.
  * Can be resolved by specifying all unpublished packages in one `cargo` call.
  * `-Zpackage-workspace` also requires all dependency versions available in the target registry when calling, so doesn't help.
* `cargo package --no-verify` has been used as a kind of “plumbing commands” to create tarballs without considering dependency orders. The use cases include:
  * Preparing tarballs for other package managers.
  * Integrating into custom develop workflows for unpublished/internal crates.
  * Constructing custom/private registries.

This commit shows the former two cases.
2025-02-26 12:45:45 -05:00
Ed Page
e1d61b8080 fix(package): Register workspace member renames in overlay
This was reported at https://github.com/rust-lang/cargo/issues/10948#issuecomment-2674289330

I suspect there is a second bug here because my debugging only showed us
doing this for `val-json` and not `concepts` and only when building `utils`.

For the exact mapping between the publish payload and the index,
see
https://doc.rust-lang.org/cargo/reference/registry-index.html#json-schema,
particularly the note about differences.
2025-02-24 11:27:37 -06:00
Ed Page
4213e921ca test(package): Show behavior with renamed members 2025-02-21 08:39:40 -06:00
Ed Page
19d307170f fix(package): Fix lookups to capitalized workspace member's index entry 2025-02-21 08:25:23 -06:00
Ed Page
258db04176 test(package): Show behavior with capitalized member 2025-02-21 08:25:23 -06:00
Weihang Lo
24dd205d5a
fix(package): deduplicate dirty symlink detection
metdata path fields may point to a dirty symlilnk and cause
duplicate report. This commit combines `dirty_metadata_paths`
and `dirty_symlinks` into one so is able to de-duplicate them.
2024-12-31 16:25:31 -05:00
Weihang Lo
de39f59e26
fix(package): check dirtiness of symlink source files
This adds a special case for checking source files are symlinks
and have been modified when under a VCS control

This is required because those paths may link to a file outside the
current package root, but still under the git workdir, affecting the
final packaged `.crate` file.

This may have potential performance issue. If a package contains
thousands of symlinks, Cargo will fire `git status` for each of them.
2024-12-31 16:25:31 -05:00
Weihang Lo
014e516e74
test(package): symlink dirty also under dirtiness check
This show that a regular file under a symlink directory
is also not tarcked by the current vcs dirtiness check.
2024-12-31 16:25:31 -05:00
Weihang Lo
059fe16085
fix(package): warn if symlinks checked out as plain text files
`cargo package` will warn users when git `core.symlinks` is `false`
and some symlinks were checked out as plain files during packaging.

Git config [`core.symlinks`] defaults to true when unset.
In git-for-windows (and git as well),
the config should be set to false explicitly when the repo was created,
if symlink support wasn't detected [^1].

We assume the config was always set at creation time and never changed.
So, if it is true, we don't bother users with any warning.

[^1]: <f1241afcc7/setup.c (L2394-L2403)>

[`core.symlinks`]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coresymlinks
2024-12-31 14:19:55 -05:00
Weihang Lo
871b17f59a
test(package): show behavior with core.symlinks=false 2024-12-31 11:52:44 -05:00
Weihang Lo
863e1f40de
fix(package): check dirtiness of path fields in manifest
This adds a special case for `package.{readme,license-file}`
to Git VCS status check.
If they were specified with paths outside the current package root,
but still under git workdir, Cargo checks git status of those files
to determine if they were dirty.

We don't need to take care of other fields with path values because

* `PathSource` only list files under the package root.
  Things like `target.path` works for `cargo build`, but won't be
  included in `.crate` file from `cargo publish`.
* The only exceptions are `package.readme`/`package.license-file`.
  Cargo would copy files over if they are outside package root.
2024-12-24 11:59:21 -05:00
Weihang Lo
a991a7dd98
test(package): show corner cases of vcs dirtiness check
This is a test showing corner cases that dirty files outside
the package being packaging actually made the `.crate` file dirty.
However, `cargo package` and `.cargo_vcs_info.json` didn't capture it.
2024-12-24 11:57:40 -05:00