Auto-switch to multi-sources vendor directory layout#10344
Auto-switch to multi-sources vendor directory layout#10344weihanglo wants to merge 3 commits intorust-lang:masterfrom
Conversation
|
r? @ehuss (rust-highfive has picked a reviewer for you, use r? to override) |
|
If we're not ready to accept this flag, the alternative way to make # This is NOT recommended. Use at your own risk.
cargo +1.34.2 install --git https://github.com/alexcrichton/cargo-vendor#0.1.23
cargo-vendor vendor --no-merge-sourcesNot recommended because old toolchains might not work as expected and contain possible security issues. |
alexcrichton
left a comment
There was a problem hiding this comment.
From a ux perspective I would personally prefer to avoid the need for this flag at all. In some sense cargo vendor should "just work" and it shouldn't require a flag to be passed to avoid an error. We try to put the vendor directory into a "nice" configuration where it's flat and easy to read, but if duplicate versions and/or sources make that invalid then I think it's reasonable to just automatically switch the behavior of cargo vendor.
Or, in other words, for any particular crate graph I think we can roughly infer what the "best looking" vendor directory looks like and try to produce that rather than requiring this option to succeed.
|
☔ The latest upstream changes (presumably #10348) made this pull request unmergeable. Please resolve the merge conflicts. |
e8f2670 to
509049c
Compare
cargo vendor|
Great idea! Auto-switching is more friendly. I've just updated the PR. Thanks for the advice! |
|
r? alexcrichton |
bcb91bc to
88a81a0
Compare
alexcrichton
left a comment
There was a problem hiding this comment.
I realize now by accident that the request to switch behavior automatically still doesn't leave an option for users to force enable this behavior even if the old behavior would work. That may be a use case desired where we would have an option to force-enable this different layout, even if not necessary.
@YellowOnion as the original requester of this, do you have thoughts on this? I have proposed not actually adding a --no-merge-sources flag and instead having cargo vendor "just work" by using a different layout if necessary. For your vendoring use case, however, do you specifically always want to use the --no-merge-sources layout even if a merged layout would suffice?
There was a problem hiding this comment.
I'm a bit confused still on what's going on here. My current impression is that cargo vendor gets to blow away the entire vendor directory unless you pass --no-delete, and in that situation it simply just appends what's being added. Is that model still accurate?
If so, how come this is removing contents plus the block below handling no_delete?
There was a problem hiding this comment.
Sorry about I haven't explained it too much. This piece was copied from https://github.com/alexcrichton/cargo-vendor/blob/07570e23d0841936cea8af2a125484f4d10ccdfa/src/main.rs#L147-L152.
The merged and no-merged layout are not compatible with each other, so cargo must delete something to make it work. For example, we have a crate with log and serde vendored,
vendor/
├── log/
└── serde/
If we add the other log deps from git and vendor it, the directory tree would look like:
vendor/
├── registry-1ecc6299db9ec823/ # from crates.io
│ ├── log/
│ └── serde/
└── git-1936cea8af2a1111/ # from git
└── serde/
Since both registry-1ecc6299db9ec823 and git-1936cea8af2a1111 are valid package names, we need to delete them all to avoid ambiguity or even errors.
Off the top of my head, one solution is that cargo can put crates from crates.io source at the first level, and duplicate version crate from other sources at the second level with folder names contains special characters which make them not valid package names. For instances, prefix sources with ~:
vendor/
├── log/ # from crates.io
├── serde/ # from crates.io
└── ~git-1936cea8af2a1111/ # git source
└── serde/
With this solution, the vendored crates becomes appendable and can respect no-delete again. Also, the use of vendor/.sources file are not necessary anymore. One caveat is that someone vendoring crates mostly from their own registry might contain far less crates at the first level of the vendor dir than the second level separate registry source dir.
|
Ok sorry for taking awhile to get back to this, but I'm back to it now! Thanks for your comments as well, they definitely help clarify things! I actually quite like your suggestion here -- #10344 (comment) -- to have top-level crates stay the same way and moving conflicts to their own directory. One way perhaps to solve the custom registry problem is to choose the source with the most crates and put that at the top, relegating all other sources to Also sorry I clearly have lost all memory of the old |
88a81a0 to
a72574a
Compare
Part of the code is copied from https://github.com/alexcrichton/cargo-vendor When duplicate versions detected. `cargo vendor` keeps the source of majority at the top of vendor directory, crates from other sources go into separate directories in order to prevent name collisions. To avoid name conflicts with valid crate names, the separate source directories are prefixed with `@`, so that they can co-exist at the top of the vendor directory.
a72574a to
5063633
Compare
|
This all looks great to me, thanks again! Since this is a meaningful change I'm gonna ping some other folks here as well to ensure that everyone's ok with this: @rfcbot fcp merge For those being cc'd this is fixing an issue in Ideally this shouldn't impact any users today since we're just making cases that previously error'd start to work now. |
|
Team member @alexcrichton has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
|
I like this idea, and how automatic it is. One concern, though: doesn't cargo's "directory source" support only look one directory down, not two or more? So, if someone was using a directory source to point to the directory maintained by I think we should either make directory sources work with this layout, or require an explicit option to enable this layout. @rfcbot concern directory-source |
|
Some possible options, in rough order of preference:
|
|
I'm not sure I understand your concern, the generated Basically that sounds like a sort of edge-use-case which may not necessarily affect this. |
|
@alexcrichton Directory sources are commonly used by folks trying to do fully offline builds. |
That happens today if people try to add new git dependencies but forget to update
If I understand your proposal correctly, let me extend it. The "auto-search-subdirectory" fix contains two parts:
For example, we have a package with log and serde vendored, With the "auto-search-subdirectory" fix, If we add a dep serde with the same version from alternatvie registry and vendor it, the directory tree would look like: Since crates under subdirectories are added to directory source, the two source-replacement configs are happy to point to the same directory without modification. [source.crates-io]
replace-with = "vendored-sources"
[source."http://alt-registry"]
registry = "http://alt-registry"
replace-with = "vendored-sources"
[source.vendored-sources]
directory = "vendor"If I didn't misunderstand your intent, this solution also seems reasonable and less intrusive. One flaw is that the search logic of directory source changes, old toolchain might not be able to recognize the new vendor layout if there is a version conflict. |
|
Sorry for late reply, I'm not familiar with the internals of |
|
I am not sure which solution is better. Let me summarize them: Move minority sources into
|
|
I don't really have a great sense for what the best choice is here. I don't know how directory sources are used and it sounds like that question is better for @joshtriplett perhaps? |
|
We discussed this in today's @rust-lang/cargo meeting, and settled on the second solution, but with some further nuance: Cargo directory sources shouldn't look at all |
|
rust-lang/rfcs#3243 is proposing namespace package name as |
|
@rfcbot cancel I'm going to close this due to the current solution might not be compatible with future syntax of rust-lang/rfcs#3243. Feel free to take it if coming up with a better solution. |
|
@weihanglo proposal cancelled. |
What does this PR try to resolve?
External command
cargo-vendorhas been broken for a while, there is no a clear alternative way to solve the situation described in #10310. This PR tries to do what--no-merge-sourcesdoes but automatically switching to multi-sources layout instead of introducing the flag. (see #10344 (review) and #10344 (comment))Fixes #10310
How should we test and review this PR?
Part of the logic is copied from https://github.com/alexcrichton/cargo-vendor.
Several tests are updated and added:
vendor::duplicate_version_from_multiple_sources: Auto-switch between non-merged and merged sources.vendor::git_duplicate: Removed. cargo-vendor now can auto-switch.vendor::vendor_sample_config: Merged intovendor::vendor_simple.Additional information
There are somethings I am uncertain:
cargo-vendorremoves the entire vendor directory. Should cargo emit a warning or just error out and tell user the incompatibility between merged and non-merged? Generally removing the vendor dir should not be a destructive operation but thing not always goes as we thought 😆Solved: See Auto-switch to multi-sources vendor directory layout #10344 (comment)
cargo::util::short_hashis not compatible with the one in cargo-vendor. I personally prefer to useutil::short_hashinstead, but if the compatibility is more important I am also ok to copy it over.Solved: See Auto-switch to multi-sources vendor directory layout #10344 (comment)