-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Suppress metadata warnings for non–crates.io publishable packages #16241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| if !missing.is_empty() { | ||
| let mut things = missing[..missing.len() - 1].join(", "); | ||
| // `things` will be empty if and only if its length is 1 (i.e., the only case | ||
| // to have no `or`). | ||
| if !things.is_empty() { | ||
| things.push_str(" or "); | ||
| let should_warn = match pkg.publish() { | ||
| Some(registries) if registries.is_empty() => true, // publish = false, still warn | ||
| Some(registries) => { | ||
| // Only warn if crates.io is allowed | ||
| registries.iter().any(|r| r == CRATES_IO_REGISTRY) | ||
| } | ||
| None => true, // No publish field means can publish anywhere, including crates.io | ||
| }; | ||
|
|
||
| if should_warn { | ||
| let mut things = missing[..missing.len() - 1].join(", "); | ||
| // `things` will be empty if and only if its length is 1 (i.e., the only case | ||
| // to have no `or`). | ||
| if !things.is_empty() { | ||
| things.push_str(" or "); | ||
| } | ||
| things.push_str(missing.last().unwrap()); | ||
|
|
||
| gctx.shell().print_report(&[ | ||
| Level::WARNING.secondary_title(format!("manifest has no {things}")) | ||
| .element(Level::NOTE.message("see https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info")) | ||
| ], | ||
| false | ||
| )? | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is checking against what we can publish to. I was assuming we'd check against what we are publishing to (PackageOpts::reg_or_index). Is there a reason you went this direction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI the following code is where that gets evaluated to something useful
cargo/src/cargo/ops/cargo_package/mod.rs
Lines 281 to 298 in 4b0e263
| let mut local_reg = { | |
| // The publish registry doesn't matter unless there are local dependencies that will be | |
| // resolved, | |
| // so only try to get one if we need it. If they explicitly passed a | |
| // registry on the CLI, we check it no matter what. | |
| let sid = if (deps.has_dependencies() && (opts.include_lockfile || opts.verify)) | |
| || opts.reg_or_index.is_some() | |
| { | |
| let sid = get_registry(ws.gctx(), &just_pkgs, opts.reg_or_index.clone())?; | |
| debug!("packaging for registry {}", sid); | |
| Some(sid) | |
| } else { | |
| None | |
| }; | |
| let reg_dir = ws.build_dir().join("package").join("tmp-registry"); | |
| sid.map(|sid| TmpRegistry::new(ws.gctx(), reg_dir, sid)) | |
| .transpose()? | |
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the pointer! I can see that PackageOpts::reg_or_index is accessible for both publish and package, but the resolution from the code you shared is what publish uses to determine where to upload. For cargo package, this field is typically None (unless a resolved SourceId is present).
Since check_metadata runs for both package and publish, I chose the manifest's package.publish field so the behavior remains consistent when there isn't an actual target registry.
I was following this suggestion but I see there's another approach here that checks the SourceId to determine if it's crates.io.
How about a hybrid approach:
- when running
publish(a resolved target exists): ask the resolvedSourceId: is this crates.io? If so emit warnings, otherwise suppress. - when
package(no target exists): fall back to checking the manifest’spublishfield to see if crates.io is allowed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The suggestion for package.publish was in the context of moving the warning to cargo check where we don't know where it will be published to in practice. Here, we know where the user is actively publishing to. For the [name1, name2] case, that is less important because the user showed intent for what registry they intend to publish to. for the publish = true case, we don't know the users intent and they may never publish to crates.io. We could say "but when we get to cargo check, we'll display it anyways" but for us to emit this for cargo check, we'd need to have #12235, allowing users to disable it.
when package (no target exists): fall back to checking the manifest’s publish field to see if crates.io is allowed.
I think the question here is about workflows. The warning is intended for crates.io. When is someone using cargo package and while still intending it for crates.io. It could be as a dry-run but we have cargo publish --dry-run. However, it was specifically added with an opt-out, so that shows intent for it to be displayed. In the end, this is a reverseable decision, so let's keep things simple and have just one approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for clarifying! That makes sense, I’ll simplify the logic to check only the resolved SourceId when publishing.
This comment has been minimized.
This comment has been minimized.
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
| let should_warn = match reg_or_index { | ||
| Some(RegistryOrIndex::Registry(reg_name)) => reg_name == CRATES_IO_REGISTRY, | ||
| None => true, // Default is crates.io | ||
| Some(RegistryOrIndex::Index(_)) => false, // Custom index, not crates.io |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually with --index "https://github.com/rust-lang/crates.io-index", this could also be crates.io registry (see #16231). Unsure if we want to check that or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can probably have a separate PR resolving that issue.
|
Looks like other tests need to be updated for this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Thanks for all the communication and bearing with the back and forth! |
What does this PR try to resolve?
Related issue: #4840
With this change, Cargo still performs full metadata checks for all packages to preserve validation consistency, but it suppresses warnings for crates that are not publishable to crates.io, such as those with
publish = falseor custom registries (publish = ["my-registry"]).How to test and review this PR?
Unit tests added in
tests/testsuite/package.rs, can be tested locally by runningcargo test --test package.