-
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
Auto-switch to multi-sources vendor directory layout #10344
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-sources Not recommended because old toolchains might not work as expected and contain possible security issues. |
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.
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
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.
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?
src/cargo/ops/vendor.rs
Outdated
// The layout of the vendor directory depends on if there is any duplicate | ||
// version. cargo-vendor auto switches between the two layouts and deletes | ||
// the old vendor directory before vendoring crates. | ||
match (sources_file.exists(), contains_duplicate_versions) { |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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-vendor
has 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-sources
does 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-vendor
removes 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_hash
is not compatible with the one in cargo-vendor. I personally prefer to useutil::short_hash
instead, 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)