Can we also allow configuring a global substitute for per-project target directories? Cargo stores a lot of cached / runtime files in cache directories instead of the corresponding XDG directories.
I hit a "storage full" situation yesterday, and cargo was taking up 100GB of temporary files littered across dozens of projects (this is about 40% of total storage). Ideally these would all be in a single place and easy to clear out.
There is the build.target-dir config which can be pointed at a shared path (I use ~/.cache/cargo/target/shared). That has the downside of causing locking issues between different workspaces as only one cargo invocation can use the target-dir at a time, what would be nice is some kind of target-base-dir config that behaves similar to the -Zscript's usage of $CARGO_HOME/target and creates subdirectories automatically for each workspace.
By looking at the usages of CARGO_HOME rustup codebase, I think the most difficult part might be keeping both rustup and cargo in sync and agree with the same home directory configurations.
The precedence of the current proposal (epage/rfcs@80a2341) might not work in the following situations:
When rustup recognizes new vars but cargo doesn't, then cargo may still install bins into ~/.cargo/ and they will become leftover after running rustup self uninstall.
Both of the situation could happen anytime because 1) users usually don't catch up to latest rustup release faster than Rust toolchain releases, and 2) even they does, switching back to an older Rust toolchain is still pretty common.
Alternatively, we adopt the proposed new precedence from proposal. Since rustup should know which version of toolchains it has installed, it can conditionally delete ~/.cargo/home when older cargoes have been detected. On the other side, we could implement a way for cargo to know if it is invoked from a new-enough rustup proxy, and decide if it should respect CARGO_*_HOME or the old default.
Unfortunately it is common for third-party cargo commands to create this directory even when youâre using a custom CARGO_HOME. I have to go delete it again every few weeks (I should really track down which command is doing it and open an issue, but I havenât yet).
AFAIK the whole point of this proposal is to provide a smooth transition towards using the XDG conventions by default in the future. Switching it all at once would be massively disrupting.
I disagree. This sort of a non-transitions does nothing. Most people won't change their configuration until forced to, and so we will still have the same "breaking point" when eventually XDG support becomes the default.
Still supporting CARGO_HOME is the solution to backcompat. If separate tool chain dirs break your workflow, you can just set a single env var.
This Pre-RFC has a C++ vibe of "introduce a good thing, make the bad thing easier to do".
I've added some constraints to the Motivations section:
Cargo's compatibility guarantees: while most of CARGO_HOME is not specified, we still need to deal with upgrade, downgrade, concurrent versions, and providing a transition for tools that rely on implementation details
Rustup shares some paths with Cargo (CARGO_HOME/bin) and we need to maintain compatibility between these tools
Rustup also sets CARGO_HOME for Cargo, regardless of whether the user has set it
Rustup and Cargo ship independently of each other
Rustup has to work with every Cargo version
We can't just make a clean break without investigating each part and evaluating the impact and how to handle it. Upgrading Cargo should not break someone's environment. Users can have multiple versions of Cargo running concurrently and that needs to work.
Cargo cannot just infer what to do based on the presence of CARGO_HOME. We'll need to work across Cargo and Rustup, including working through the motivations for setting CARGO_HOME, to find a design here.
Unsure if its this or something else but I figure our solution will rely on
Rustup not supporting concurrent installs
(afaik) Rustup not supporting downgrades
Rustup knowing the toolchain version
(maybe) Old Rustups being incompatible with newer Cargos. I expect distributions that ship Rustup would have the biggest problem with this though maybe long enough transition windows would make this ok.
And not to forget non-rustup installations too. I personally don't use rustup anymore, using oxalica/rust-overlay to manage per-project toolchains through nix-shell instead. AFAIK the only constraint that places is that whatever the solution is it shouldn't be enabled through rustup, but it avoids a lot of the problems too (no CARGO_HOME/bin required, no default-set CARGO_HOME).
Users can have multiple versions of Cargo running concurrently and that needs to work.
This is by far the biggest issue in my mind, I assume at this point I'm going to have to have my CARGO_HOME symlink-tree pointing out to the XDG dirs for many years after native support is added, as I commonly run very old toolchains to test stuff.
Assuming we want to support stable-N (stable minus N) release then it sounds to me it sounds like we need to:
Ship a new version, X, which uses XDG paths if they exist, otherwise the current paths. This allows users to opt-in, but is mostly for forward-compatibility with future versions.
Ship version X+N as thee last version that default to the old path; this version defaults to the XDG locations.
Ship version X+N+1, which moves data from the current locations into the XDG locations. At this time, the oldest supported version uses the XDG locations if they exist.
Ship version > X+2N, which stops reading from the current locations, dropping legacy code.
How far back do we need to support downgrading? E.g.: how many intermediate release would need to happen need before the transitory implementation is dropped?
I don't think we can drop legacy code. And for the exact timeline I feel like it is a bit out of scope of this pre-RFC. We can leave it for future RFCs.
With the several rustup characteristics combined, there are few compatibility guarantees that need to be upheld. Rustup could do one-way conversions on upgrade, for example.
I was wondering about rustup signaling to cargo (via an env variable?) that a new behavior is in use. Less brittle than version parsing and much easier to experiment with and test.