-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Allow patching dependencies with patch files #4648
Comments
FWIW, I think applying patches is beyond Cargo's rational. Besides the intricacies of successfully applying patches (see the wilderness of |
@lukaslueg I see where you're coming from but that would eliminate the primary purpose of Cargo; that is dependency management. Having build systems re-implement the crates.io dependecy tree and try to keep it in sync with upstream would be so onerous I don't think anyone would bother. There is however an alternative to this proposal. Keep the behaviour of Cargo as it is now but expose more of the internal behaviour to outside build systems so they can have more control over the process. For example, what I'm picturing might be something like the following:
The above is probably just one approach and someone more familiar with Cargo's internals might have a better suggestion, however the core idea here is a way for external build systems to hook into any part of the Cargo build process to make it easier to integrate into their own build process. |
+1 |
Hello, Here i use Rocket for a project. There is an issue for this on Rocket, but i can't open an issue for this on Hyper as latest versions of hyper already has the patch (but Rocket isn't compatible with latest Hyper). So, as long as Rocket doesnt use latest Hyper, i am stuck at forking both projects, to add my patches to them, while @hetmankp's proposal would allow me to store only 2 diff files of around 10 lines each. That's why i +1 this issue. |
Another case where it might be useful, is when you need to provide a mini test project that expose a bug. I like the idea. |
Hey folks, |
I've posted an implementation PR. Currently in draft. |
On the road to publishing an RFC for this, there's another use case I'd like to present - dealing with trivially broken dependencies upon a
Case studyCurrently for my ptytest crate, if I recreate The patching process with this feature can work as follows: I take or rebase an already existing fix for version
With a full implementation of proposed change, patching over
Discovery of patchesIf anyone uses Patch files vs a user-provided patching programAn alternative to patch files is providing an external program that would patch the crate, for example like with This approach is much thicker than |
@da-x Did you ever get around to publishing that RFC? I don't see it on https://rust-lang.github.io/rfcs/ |
@PanopticaRising not yet, you can go ahead and work on it if you'd like (just let me know). |
I see there was an implementation, as well as good idea and good usecases. I just wanted to add my own support for this feature with an example, that actually harms the entire ecosystem a bit. So basically this is what triggered it: willcrichton/winit@5fac5af I also use a few libraries, "bevy_mod_picking", "bevy_web_fullscreen" and other small but useful crates, they are all pointing towards bevy 0.5. What ended up happening, is that I need to download winit, apply that patch to winit. I then proceeded to download bevy, patch that so that it points to my newly pathched winit. Now bevy is a custom version and I need all the different bevy libraries to use the same bevy installation. I did not get the [patch.crates-io] to work as intended. So i vendored all the libraries i use, changed one line in the Cargo.toml file of each of the libraries to point to my patched bevy, that points to my patched winit. I dont want to maintain or have a fork in my github that only changes one line of the Cargo toml file, to point to a file on my local disk. So what I ended up doing was removing the .git repo information, and are now keeping all of the bevy libraries I use as a local copy with all git history scrubbed. The harm is basically that any fixes or changes I now do the subrepos, are not in any kind of git structure, and I cannot send a merge request in a simple way anymore. Had i been able to just store some git patches to the crates in question, I would have had an easier time to contribute back to the ecosystem, I suspect there are more silent vendoring, with bugfixes that never see the light of day because of this. TLDR: wanted to apply one patch to a subdependency, ended up needing to vendor 10 different libraries to in total change maybe 20 lines of code, and removing the individual git history of each of those. |
@TotalKrill But wouldn't that concrete and probably common problem be better fixed with some way to pin/override dependencies of dependencies? |
@mohe2015 yeah, but a way to apply patches would mean i get a way to do just that, and in the same way maybe fix some name change or other very minor, bit still breaking change in that library. patches are also a nice way of keeping your own project tidy. It would be a lot easier for someone to test a patch from a merge request and similar as well. I would however limit this cargo feature to work on only binaries, with the assumption that binaries are the final step in these deeply nested dependency trees we are seeing in projects. |
@da-x @PanopticaRising @mettke @gfriloux @nhynes @hetmankp I started on a draft of this RFC proposal, this is my first attempt at creating such a proposal, and I based it upon my example in this case. Feel free to help out, extend or comment on this RFC draft, as well as to recommend other interested parties to take a look. You can find it here: |
I really just wanted to comment on this thread as it was something that I really, badly need right now, so I was hoping that by fervently posting nice things in this thread, it would magically appear. At the very least, I'm expressing my support for this feature. Whoever implements this, thank you so much. |
Same. Seems like a pretty useful feature. I need it myself and I'm trying to figure out a way around it. |
I'll second these. Kind of desired feature! |
So I agree that it goes against the soul of cargo. However, this world isn't perfect; plenty of crates have things in them that need to be fixed, at least temporarily until the depended upon crate is updated. I think we all understand and are okay with the fact that a patching system would be unstable, but sometimes it's just necessary. |
Absolutely. Not to mention it's common practice for projects that aggregate a large number of other projects. I'm thinking of build systems like Buildroot or OpenWRT. Needing to get something working quickly in production while you also kick off the lengthier process of updating the upstream project can often be very important. Sometimes you can also be stuck having to use a given crate version due to a web of dependencies within your system and an update to the fixed upstream version may not be possible until some future point. Having to create repository clones for every package that needs a small two line fix can become arduous when you're managing hundreds of packages. I guess the short of it is, many developers are often engaged in plumbing work to interconnect many upstream pieces and while plumbing work can be dirty and unpleasant it's still vital to keep our society going. It would be nice to make that work just a little less unpleasant. |
See also rust-lang/rfcs#3177 |
Found some time writing an experimental feature for this: #13779. |
+1 -- this would be extremely helpful, as it would obviate the necessity of forking and/or checking third-party source code into a given project. |
Its been a while and there has been no status update. Would someone mind letting me know if this is planned or not? |
@sakgoyal See #13779 (comment). |
Summary
This proposes to add an ability for Cargo to patch dependencies with patch files.
Problem description
The addition of the [patch] manifest section has made making localised changes to crates used by an individual project much easier. However, this still requires checking out the source code for the entire crate even if only a few lines of the source actually need to be modified.
This approach is fairly reasonable for individual Rust projects, however when embedded in a much larger build system that pulls hundreds of various projects together this can quickly become unwieldy (e.g. Buildroot, OpenWrt build system, etc). Rather than storing the entire source for any packages requiring modification, these build system instead store a set of patch files against a specific release version for the package in question.
Possible solution
This proposes adding an ability to let Cargo apply a set of patch files to a create after it is retrieved and extracted and before it is compiled. It would probably make sense to use the unified diff format given its popularity with tools like Git etc.
A previous proposal #3830 similar to this one, suggested the following syntax:
That syntax seems like a good starting point although someone with more Cargo experience might have a better idea.
Final remarks
One of the stated 2017 roadmap goals was for better integration with large build systems and I believe this would help further that goal.
The text was updated successfully, but these errors were encountered: