- Feature Name: N/A
- Start Date: 2016-05-14
- RFC PR: rust-lang/rfcs#1615
- Cargo Issues: rust-lang/cargo#1734 rust-lang/cargo#1976 rust-lang/cargo#2127
- Rustup Issues: rust-lang-nursery/rustup.rs#247 rust-lang-nursery/rustup.rs#473
Improve Cargo's integration into the host operating system by using platform-specific paths for config files, cache files and executables, so it interacts well with other tools on that platform.
Currently, Cargo puts all its files in a directory named .cargo
below the
home directory of the user. Using this proposal, it would reuse existing
standard directories of the host platform. This allows other tools oblivious to
Cargo to function in the best way.
Benefits include:
- Using a
.cargo
directory is violating the recommendations/rules on most operating systems. (Linux, Windows, macOS. Especially painful on Windows, where dotfiles are not hidden.) - Putting caches in designated cache directories allows backup tools to ignore them. (Linux, Windows, macOS. Example: Time Machine ignores the cache directory on macOS.)
- It makes it easier for users to manage, share and version-control their configuraton files, as configuration files from different applications end up in the same place, instead of being intermingled with cache files. (Linux and macOS.)
- Cargo contributes to the slow cleanup of the
$HOME
directory by stopping to add its application-private clutter to it. (Linux.) - Using a standard directory for binary outputs can allow the user to execute
Cargo-installed binaries without modifying their
PATH
variable. (Linux)
Solving this problem will likely also solve the same problem in Cargo-related
tools such as rustup
as their strategy is "do what Cargo does".
This seems to be implemented in pip, the Python package manager, already.
We are going to introduce new environment variables:
CARGO_BIN_DIR
CARGO_CACHE_DIR
CARGO_CONFIG_DIR
For the default values of these variables if they are set to the empty string or not set (which will be the common case), see below.
These will be used to split the current .cargo
(CARGO_HOME
) directory up:
The cached packages (.cargo/git
, .cargo/registry
) will go into
CARGO_CACHE_DIR
, binaries (.cargo/bin
) installed by Cargo will go into
CARGO_BIN_DIR
and the config (.cargo/config
) will go into
CARGO_CONFIG_DIR
.
In order to maintain backward compatibility, the old directory locations will be checked if the new ones don't exist. In detail, this means:
- If any of the new variables
CARGO_BIN_DIR
,CARGO_CACHE_DIR
,CARGO_CONFIG_DIR
are set and nonempty, use the new directory structure. - Else, if there is an override for the legacy Cargo directory, using
CARGO_HOME
, the directories for cache, configuration and executables are placed inside this directory. - Otherwise, if the Cargo-specfic platform-specific directories exist, use them. What constitutes a Cargo-specific directory is laid out below, for each platform.
- If that's not the case, check whether the legacy directory exists (
.cargo
) and use it in that case. - If everything else fails, create the platform-specific directories and use them.
This makes Cargo use platform-specific directories for new installs while retaining compatibility for the old directory layout. It also allows one to keep all Cargo related data in one place if one wishes to.
We'll obtain each of the following directories using the correct API.
cache: AppData\Local\Temp\Cargo
config: AppData\Roaming\Cargo
binaries: AppData\Local\Programs\Cargo
Here, we're following the XDG specification. By default, if no further variables are set, this means that we'll be using the following subdirectories of the home directory.
cache: .cache/cargo
config .config/cargo
binaries: .local/bin
There is currently an on-going discussion about standardizing the location of
.local/bin
together with a new XDG variable XDG_BIN_HOME
. The
implementation of this RFC should be delayed until that discussion has finished
and use the result. This RFC will be amended with that result.
Rustup will replicate Cargo's priorisation algorithm. If the results differ
from what the executed version of Cargo will do, Rustup will add environment
variables CARGO_BIN_DIR
, CARGO_CACHE_DIR
, CARGO_CONFIG_DIR
for the new
versions of Cargo, and add symlinks for the old versions of Cargo.
Cargo (and Rustup) are going to gain a new subcommand, cargo dirs
. It will
display the directories currently in use, in a human-readable format. In order
to support other programs and scripts, this subcommand will also have switches
to print the data in machine-readable form, at least --json
for JSON output
and maybe --shell
for env-compatible output.
Example JSON (specifics left to the implementation):
{
"bin_dir": "C:\\Users\\User\\AppData\\Local\\Programs\\Cargo",
"cache_dir": "C:\\Users\\User\\AppData\\Local\\Temp\\Cargo",
"config_dir": "C:\\Users\\User\\AppData\\Roaming\\Cargo"
}
Example (env-compatible):
CARGO_BIN_DIR=/home/user/.local/bin
CARGO_CACHE_DIR=/home/user/.cache/cargo
CARGO_CONFIG_DIR=/home/user/.config/cargo
-
This increases the complexity of where to find the files Cargo uses. This can be alleviated by providing library functions for Cargo related tools and a command line to tell which paths are in use.
-
It can also complicate tutorials that tell users how Cargo works. The tutorials should probably reference the Cargo subcommand that displays the used locations. However it's still more complicated than static directory name (it's in a weird location for Windows users though).
-
macOS could also use the
Library
folder for storing its data. This is mostly done by UI applications. -
One could only change the Windows paths, as the Windows integration is currently the worst.
- None so far.