Skip to content

Provide a flag for package to avoid regenerating/generating Cargo.lock, thus decoupling packaging from the registry #15159

Open
@NoisyCoil

Description

Problem

I would like to work on adding a new flag to cargo package to avoid regenerating Cargo.lock when packaging, or to avoid generating it at all in case there is none.

The main use-case I have in mind for this flag is the packaging work we do in Debian. In Debian we adopt two main approaches when it comes to rust packaging. The first is packaging single crates, with source code obtained from crates.io. The second is packaging from upstream sources (usually git repos), which is particularly useful for multi-crate projects, cross-language projects, or projects that simply don't publish to crates.io. Now, the latter may contain crates with rust libraries, and these rust libraries must be packaged as librust-$CRATENAME-dev Debian packages in order for them to be used by other packages as build dependencies. When it comes to this, cargo package (used either as a command line tool or via the cargo library) is extremely useful in that it creates a canonicalized version of the crate, with the desired included/excluded files, which can then be simply copied to the desired directory and packaged as a .deb. Before this is done (regardless of whether one uses cargo package or not), Cargo.lock is removed from the directory because there is no use for it in Debian (verification is done at the level of the Debian archive -- that is, by verifying .debs themselves -- and versioning is locked to whatever we have in the archive at a certain point in time).

Unfortunately, the way cargo package currently works -- especially after 1.84 which started regenerating/generating lock files for all crates -- couples the packaging process to the registry in a way that makes it quite hard for us to use it in practice the way we would like. Specifically, if Cargo.lock needs to be regenerated/generated, then all the crates' dependencies must be in the registry in order to use cargo package. This causes some notable issues:

  1. it forces us to deal with ordering. Namely, we need to install packages in the local registry in the correct order, so that they can be found by packages that depend on them. At this time I've only seen evidence of ordering issues between crates, but my guess is this will extend to ordering issues between crate features, which will be much harder to solve

  2. due to the above, it forces us to deal with circular dependencies. An example of this was already reported for cargo publish in publishing a crate that depends on itself as a dev dependency #15151, pointing to the same underlying issue I'm reporting here (but possibly needing a different solution). I have a strong feeling that the issue of circular dependencies will not be solved easily

  3. in general, it prevents us from packaging crates unless all dependencies are installed in the local registry (this was also reported in cargo package --no-verify fails if a package's version req is too high for the registry (but works locally) #15059). This is not a logic necessity since, were it not for Cargo.lock, canonicalization and file inclusion/exclusion could proceed with no input from the registry. Packaging crates without dependencies being present locally saves us from downloading and installing dependencies unless they are really needed.

Proposed Solution

Since as I said we don't care about Cargo.lock in Debian (again, we actually remove it from the final package), all of this would be solved for us if one could just skip lock file regeneration/generation. I've already tested that, when used together with --no-verify, a new --no-gen-lockfile flag that implements such skipping would decouple cargo package from the registry: in practice one can purge the registry from all crates and use cargo package with no dependencies present locally at all. This way the issue of dependency ordering/cyles obviously never arises.

A proof of concept is at https://github.com/NoisyCoil/cargo/tree/no-lockfile, but I would like to hear your thoughts before submitting an actual PR.

Notes

I am not sure this proposal is suitable for solving #15151, since publish should probably have different requirements than package. Indeed, in my proof of concept, the no-gen-lockfile flag is turned off for the (internal) use that publish makes of package. On the other hand, it may help (or even completely solve) #15059.

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`Command-packageS-triageStatus: This issue is waiting on initial triage.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions