-
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 to share versions of dependencies between unrelated Cargo packages #5332
Comments
Thanks.
To be clear, we at Facebook use Cargo to build our third-party dependencies and Buck to build Facebook-internal code. |
4 will be solved by Xargo integration / rust-lang/rfcs#1133 successor. The other three are solved in other build systems by "constraint" files which can be shared by multiple solving units. Sort of like an imported lockfile. So I'd say do that, and don't make |
FWIW, in Firefox we only just finally switched to using a workspace last month after getting a number of issues sorted out. Prior to that we simply called |
Comments on strawman:
I don't see how this follows? Wouldn't the resolution change as crates.io changes? |
My idea was that you explicitly define the set of vendored packages, which is fixed by some configuration file. The config file is basically a global lockfile, so it lists exact versions, and not version requirements. Then, the resolution of dependencies runs against this set of packages, and not against crates.io. In a sense, this creates a local subset of crates.io ecosystem, restricting the set of packages/versions in the registry.
Interesting! To unpacking this, another source of duplication, besides duplicated versions, is packages with different sets of features available. So we may want to forcibly enable features at the global level. Interestingly, rust-lang/rust has this problem and, to hack around it, we had to add a synthetic dependency to Cargo to just enable some features: 841f20a#diff-80398c5faae3c069e4e6aa2ed11b28c0 |
How would one determine what exact version to put in there, and make sure its consistent with everything else? I think we'd want cargo to do that resolution via the existing requirements/lock model.
In principle, features are always additive so simply unioning all features should work. But in practice this isn't enforced, and I know some crates use features for exclusive A vs B choices. (I think this is a whole other discussion which needs resolution.) We're mostly using them to enable optional features and dependencies (like "bytes" dependency on "serde"). |
Do you think designing a new format for this would have significant advantages compared to making cargo able to generate a single lockfile for multiple crates as if they were in a single workspace (likely overriding any existing workspace definitions)? If you could do something like Hand-authoring this file doesn't sound great since you'd wind up having to iterate over transitive dependencies. It would force developers to do a bunch of work that cargo already knows how to do. If your concern is auditing the list of packages then presumably looking at the diff of Cargo.lock after making changes to the set of crates involved would be a suitable way to do that. I've reviewed a series of Firefox patches that changed versions of vendored crates (here's a recent example) and they're generally pretty easy to reason about. |
I personally don't really have value judgements here, because I am not too familiar with all use-cases here :) So looks like, if we forget about features, we really just need a way to generate a lockfile for several workspaces simultaneously. Basically, this loop in cargo-vendor should somehow be inside the version-resolution process. |
Is this equivalent to nested workspaces? |
@jsgf it depends on the definition of a nested workspace :-) However, I would say that at least for Debian's case of packaging existing crates it does not seem to be the case. One of the fundamental properties of workspaces is that children are aware of the parent workspace (there's |
Another good use case for this would be to able to ease development in a monorepo. If there are two unrelated Cargo packages that are maintained separately, it is inconvenient to have to keep shared dependencies between them in sync even though the packages aren't related. |
Workspaces as a concept may be an abuse in itself. If you use a monorepo or metarepo, you may alternatively leverage |
See also #4353 |
Several users of Cargo want the ability to build a set of unrelated Cargo packages (i.e., not a workspace) with a tight control over crates.io dependencies. Tight control, in particular, means:
Currently, it is possible to achieve a similar effect by abusing workspace, but there's a feeling that a more first-class solution is required.
Case studies
Strawman proposal
We can imagine a tool to enable this use-case, which works similar to
cargo-vendor
, but with a slightly different flavor. Today,cargo-vendor
looks at the existing Cargo project, collects all of its dependencies from crates.io and packages them as a directory source.The proposed tool would start with an explicit "dependencies to vendor" specification file (
vendor.toml
), which lists a set of packages. This file is the point of audit, and the place to make sure that no duplicate packages are allowed. Then, all other packages would be resolved against these dependencies selection. Corollary: in this system, there's no need for Cargo.locks, because the set of packages is fixed and the resolution is deterministic.Bonus points:
foo 1.0.0
, it is not vendored, but exists on crates.io"vendor.toml
from a set of leaf Cargo packages.The text was updated successfully, but these errors were encountered: