-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
[experiment] patch
with patch files
#13779
Conversation
b8bb3e5
to
74c61c6
Compare
/// A file indicates that if present, the patched source is ready to use. | ||
const READY_LOCK: &str = ".cargo-ok"; | ||
|
||
/// `PatchedSource` is a source that, when fetching, it patches a paticular |
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.
See this doc comment for some design decisions.
b77a914
to
2b15782
Compare
@weihanglo how would you like this reviewer? As this is unstable and we previously agreed to the idea of experiments, in theory the bar is fairly low. I will admit some hesitance on this experiment. In adding a new source kind, I'm assuming this can be a bit invasive (to be fair, I've not yet looked at the code). I'm also a bit surprised at the design direction described in the PR description. So how much design discussion should we work out vs get in, try it out, and then iterate on alternative design ideas as we see needed? |
a46ced8
to
ef73e26
Compare
@epage, This is not intended to merge as-is. It's more like a proof of concept that this approach does works but with a not okay user experience. About reviewing the pull request, I would recommend starting from tests to get an idea of how it looks like. I would suggest not getting into details until we feel better with the UI. We could probably open a Zulip topic on t-cargo for design discussions. |
☔ The latest upstream changes (presumably #13778) made this pull request unmergeable. Please resolve the merge conflicts. |
☔ The latest upstream changes (presumably #13783) made this pull request unmergeable. Please resolve the merge conflicts. |
Having look this over it seems pretty reasonable. If you would prefer to experiment with a "resolution loop" I'd be happy to compare cost-benefits, but I suspect this is simpler.
I don't understand why the equals requirement is needed. Say the patch was for I'm not remembering the API at the moment, it may be that we need to return them all up front instead of "as they turn out to be needed"? If that's the problem, we could think about making a lazier API. (PubGrub would be happy with the lazy API, I'm not sure how much churn would be involved in moving the current resolver.)
I don't think I follow, what ends up stuck in time?
This seems to be an important point. Especially as it's across "different versions" with the current |
Oh, I should capture some office hour thoughts In my mind, no matter the type of In my mind, I see this PR introducing two things:
I think we should decouple these conversations so we can make sure we are getting the right semantics for each or, at minimum, defer non- A thought of mine that didn't come up during office hours is me worrying that pluggable patch tools might be generalizing too much. I'd want to see a better explanation of why that extra complexity is needed and what the alternatives are. |
Regular patches can also affect resolution. It is |
Reply to #13779 (comment):
We could have lazy mechanism, but I would like to avoid patching “during resolution” at this moment. Patching before or after resolution is less complicated I believe.
The exact requirement issue. Reply to #13779 (comment):
Actually this PR intentionally touches nothing in The one major thing to explore is the semantic of the new patched source kind when being in Just talked to Jacob earlier. There are at least three timing for patching:
(By registering |
☔ The latest upstream changes (presumably #13813) made this pull request unmergeable. Please resolve the merge conflicts. |
266a9cf
to
8d8fade
Compare
Thank you for starting work on this, I eagerly await this feature.
This isn't too hard to change, right? Specifying a
I mean, the only formats people really use are the unified format and git's additions to that. Maybe it'd be better to just pull in a rust parser for patches? There's the
Currently, the Alex Crichton raised a concern in the RFC thread that I'd like to bring up:
Another person gave an answer to the issue of getting the source for crates.io crates, what I want to mention is that it's probably acceptable to tell people to patch git dependencies if they modify |
Thanks for being enthusiastic about this!
Personally, I will hold off this. If one is able to use git dependencies, it is assumed that they are also able to fork Git repoistories. To me, supporting Git dependencies is not the main purpose.
The ideas behind this are:
Have you tried #14055? I haven't read
Yeah you're right. Agree with you. Workspace crates may be broken. A published crate has run through an amount of normalization. It is not only Cargo.toml that was edited, but also some other files got copied cover. And yes we should provide tools helping that. I pretty much lean toward a 3rd party plugin, which is more flexible and isn't tied to Rust strict compatibility guarantee. |
I really appreciate if we can have this issue, from the big project perspective, we even need to workaround some 3rd-party crate.. |
☔ The latest upstream changes (presumably #14026) made this pull request unmergeable. Please resolve the merge conflicts. |
Yes, but personally I'd much prefer having a In a project I'm a part of, we currently have around 8 or so forked git repositories belonging to community members. Some of these forks might only have 1, maybe a handful of commits on top of the upstream repository. In the process of updating some of our fundamental dependencies, I've found myself needing to make some additions to some of these forks. This means forking the fork again, pushing my changes, making a PR on the original fork and pinging the owner to merge. We could probably handle this better, but I think it'd be nicer to be able to maintain a patchset on a git repository than to fiddle with forks (though my fellow project members may disagree). And if it might be useful, why not?
That's true. I'm interested in pijul myself, though I haven't looked at it close enough to see how the patches are actually stored, or if you can convert them to the unified format. I wouldn't mind getting my hands dirty with a crate for patching, but I understand if having some random person write/maintain the crate (and the risk of it being abandoned) doesn't meet project standards. I'd probably agree with trying to avoid maintenance costs associated with VCS support.
Thanks for the link, didn't know that existed. I've recreated the issue with the cargo feature on that branch, and will explain it to hopefully make it more clear. On a new project, I have a cargo-features = ["patch-files"]
[package]
name = "test-patch"
version = "0.1.0"
edition = "2021"
[dependencies]
wgpu = "0.18"
egui_wgpu_backend = "0.28"
[patch.crates-io]
wgpu = { version = "0.18", patches = [
"./0001-fix-wgpu.diff",
] } The contents of diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml
index 343ed2b05..a82c99f58 100644
--- a/wgpu/Cargo.toml
+++ b/wgpu/Cargo.toml
@@ -159,7 +159,7 @@ web-sys = { workspace = true, features = [
"GpuCompilationMessageType",
"GpuComputePassDescriptor",
"GpuComputePassEncoder",
- "GpuComputePassTimestampWrite",
+ "GpuComputePassTimestampWrites",
"GpuComputePipeline",
"GpuComputePipelineDescriptor",
"GpuCullMode", If I apply the diff to a local clone of the wgpu repository checked out at tag But simply running it with the file contents as above using your cargo branch from #14055 spits out this error:
And cargo then terminates. This happens because, while wgpu 0.18.0 depends on web-sys ^0.3.64, egui_wgpu_backend 0.28 depends on wgpu 0.19, which depends on web-sys ^0.3.67, and the listed cargo feature got renamed from Mind you, this example is kind of contrived, as you wouldn't really want to pull in two different versions of wgpu at once. But the problem itself can still happen in the real world; in the project I'm a part of, we currently patch wgpu to include some changes from newer versions, and if the patch section is commented out cargo produces the same error. Also, this patch wouldn't apply if it were applied to the actual registry source, but you could pretty easily make one that does if you went and grabbed that. The error wouldn't change. This isn't necessarily to say that your approach is untenable, though. You could just tighten restrictions for what can be done with (I'm also wondering now if this is a bug in dependency resolution that could actually just be fixed...) Edit: I also forgot to add a |
Since `[patch]` section exists also in config, so have it inboth cargo-features and -Z flag.
`SourceKind::Patched` represents a source patched by local patch files.
One thing left out here is a consistent/stable hash for patches, The are absolute local paths that might introduces unnecessary changes in lockfile. To mitigate this, patches under the current workspace root will be relative.
☔ The latest upstream changes (presumably #13947) made this pull request unmergeable. Please resolve the merge conflicts. |
@NeuralModder thanks for your sharing.
I think that is possibly a bug in my implementation. #14055 has a better user experience in my opinion, though I don't think both of the pull requests are in a good state in terms of code complexity and usability. Also, myself currently have no time in pursuing this feature, so going to close this. Don't worry the PR diff is always here so if somebody or myself want to pick it up later, we can always do that. Thank you all. |
Something we discussed in the Cargo team meeting was whether we could expedite this by preventing patches that touched |
What does this PR try to resolve?
An unstable
-Zpatch-files
flag is added to support patching your dependencies with patch files, with the patchtool you configure in[patchtool]
config table.This is one experiment based on rust-lang/rfcs#3177 that the team maybe be interested in.
See also #4648.
How should we test and review this PR?
Apparently commit by commit. You could start from test to understand the current user experience of it.
Some design decisions in this implementation:
This is currently done by requiring an exact version requirement
=
,so Cargo knows what to download.
we could patch whatever we want including dependencies and
package.version
.Summary
registered toPacakgeRegistry
is the source after patching.{ patches = [<path>] }
field is only available for dependencies under[patch]
table,and only allows patching registry dependencies for now.
PatchedSource
that fetches and applies patches to the original source code duringblock_until_ready
.patched+
, which compose the SourceId to patched.[patchtool]
table in Config to control.I imagine it would be something like git
mergetool
for registering tools,though at this moment it only accepts one via
path
.$CARGO_HOME/patched-src/<hash-of-original-source>/<pkg>-<version>/<cksum-of-patches>
.Patched source rebuilds whenever content of patch files or the underlying source change.
You can find some more documentation under
src/cargo/sources/patched.rs
.Additional information
I don't think patching before dependency resolution is ergonomic.
Your patched source code would be stuck in time and you need to eagerly update and rebuild them.
Some patches may be safely applied across major versions.
However with the current design you need to specify the same patch twice.
We may like to revisit patching during the resolution,
and reconsider the work of re-resolving dependencies.
That is a more user-friendly way for patching with patch files.