Skip to content
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

Let Cargo put data into platform-specific directories #1615

Closed
wants to merge 8 commits into from
102 changes: 102 additions & 0 deletions text/1615-cargo-platform-standards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
- Feature Name: N/A
- Start Date: 2016-05-14
- RFC PR:
[rust-lang/rfcs#1615](https://github.com/rust-lang/rfcs/pull/1615)
- Cargo Issues:
[rust-lang/cargo#1734](https://github.com/rust-lang/cargo/issues/1734)
[rust-lang/cargo#1976](https://github.com/rust-lang/cargo/issues/1976)

# Summary

Improve Cargo's integration into the host operating system by using
platform-specific paths for config files, temporary files and caches, so it
interacts well with other tools on that platform.

# Motivation

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. Using standard directories is the best way
to go unless there are concrete reasons for not doing so, otherwise Cargo just
adds complexity to all systems that try to interoperate with it. Benefits
include:

* Using a standard directory for binary outputs can allow the user to execute
Cargo-installed binaries without modifying their `PATH` variable. E.g. on
Fedora this is apparantly already the case, in Debian there's a ticket to
include it.
* Putting caches in designated cache directories allows backup tools to ignore
them.
* Using a `.cargo` directory on Windows is not idiomatic at all, no programs
for Windows would such a directory.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "no programs for Windows would such a directory".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

* Platform specific clean-up tools such as the Disk Cleanup Wizard work with
Cargo (it wouldn't be very useful to try to modify the Wizard instead of
Cargo to make this work).

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".

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ish. Rustup did move away from Appdata\Local back in 2016 to line up with Cargo, but rustup has its own .rustup directory, and will need to migrate independently - and any migration of cargo bin directories will need to be coordinated with rustup as well. I don't think it makes it easier for rustup to follow XDG for rustups own files, but it would make it easier for the files that live in CARGO_HOME/bin, which is effectively the only intersection point.


There seems to prior art for this in pip, the Python package manager.

# Detailed design

In order to maintain backward compatibility, the old directory locations will
be checked if the new ones don't exist. In detail, this means:

1. If there is an override for the Cargo directory, using `CARGO_HOME`, use
that for all files.
2. Otherwise, if the platform-specific directories exist, use them.
3. If that's not the case, check whether the legacy directory exists (`.cargo`)
and use it in that case.
4. 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.

## Windows

We'll obtain each of the following directories using the correct API.

```
cache: AppData\Local\Temp\Cargo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be %LOCALAPPDATA%\Cargo as I think %TEMP% is more for things that will be deleted by the time the program closes but the Cargo cache is useful for subsequent executions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using %TEMP% has the advantage that disk cleaners know about this directory.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true but I would hope that Cargo can manage it's own cache. Do you have any examples of other software using %TEMP% like this? For example Firefox and pip both store their caches in %LOCALAPPDATA%.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dunno, maybe look at Internet Explorer or Edge.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IE's cache is in %LOCALAPPDATA%\Microsoft\Windows\INetCache and Edge's is in %LOCALAPPDATA%\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it sounds like LOCALAPPDATA is the directory of choice here? Should the RFC be updated?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a .cargo directory is violating the recommendations/rules on most operating systems.

This isn't true, at least not on Linux, per the FHS. See my other comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RFC definitely needs an update yes; %LOCALAPPDATA%\Cargo\Cache would be my suggestion

config: AppData\Roaming\Cargo
binaries: AppData\Local\Programs\Cargo

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%LOCALAPPDATA%\Cargo\Programs would be better - the convention in AppData is to own the subdirectory, not to create a generic space under it and then claim a subspace under that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect.
FOLDERID_UserProgramFiles is what we want, and it defaults to %LOCALAPPDATA%\Programs which AppData\Local\Programs\Cargo falls under. Probably would be good to update the text to specify the known folder id constants specifically.

Copy link

@rbtcollins rbtcollins Jul 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, documented https://docs.microsoft.com/en-us/windows/win32/msi/installation-context - thanks. Which also points out that we should use ShGetKnownFolderPath to work with this.

```

## OS X

```
cache: Library/Caches/Cargo
config: Library/Cargo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm currently using OS X, and the config for all of the CLI tools I have any interest in configuring are stored somewhere under my home directory. I've never touched a config file under Library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know a lot about OS X. Isn't there a Library folder in the home directory as well?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Others may disagree but in my experience the unwritten rule of OSX is that GUI apps use ~/Library and CLI apps use unixy locations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My CLI tools configs and caches are all at the same location as they'd be on Linux, including some that are following XDG.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Homebrew uses /Library/Caches/Homebrew/ and pip ~/Library/Caches/pip/, so I guess both could be valid.
On the other hand, configuration should definitely use XDG.

binaries: Library/Cargo/bin
```

## Other unixy systems (Linux, BSDs)

Here, we're following the XDG spec:

```
cache: .cache/cargo
config .config/cargo
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should use the XDG_CONFIG_HOME and XDG_CACHE_HOME environment variables

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are, perhaps I should clarify that a little. We're following the XDG spec, and by default it's these directories.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on clarification.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

binaries: .local/bin
```
# Drawbacks

* 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not just this though; it's also things like documentation, explaining how cargo works to the user, etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, added to the section.


# Alternatives

* OS X could also use the XDG specification. This would remove the difference
between OS X and other unixy OSs. This is also done by Python's pip.

* One could only change the Windows paths, as the Windows integration is
currently the worst.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most notable thing about the Windows integration is probably the non-hiddenness of the folders, I should have that fixed in a release or two at most now it has been pointed out.


# Unresolved questions

* None so far.