Make Cargo obey platform-specific directory standards #2127
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @huonw (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. The way Github handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
|
Probably doesn't compile on Windows, because the |
|
Since XDG is higher priority than the original one, isn't that going to cause issues? People who work on systems which follow XDG are gonna see their existing |
|
The XDG only has higher priority if it exists (~/.cache/cargo). This could help with deprecating ~/.cargo completely in the future. EDIT: Systems which follow XDG might have ~/.cache, but they won't have ~/.cache/cargo. |
|
Thanks for the PR @tbu-! It looks like there was also quite a bit of legwork in getting everything to work across all platforms, so thanks for that as well! Some thoughts of mine:
I wonder if it would be possible to have this still be opt-in, but perhaps have the opt-in to be very easy to set? |
|
Thanks for looking over the pull request!
I suppose, but I don't have a Windows machine right now.
Yea, the points about OS X and *BSD are fair, I haven't researched the situation there yet.
Fragmentation isn't really worse, you can find the configuration in ~/.config/cargo and the cache in ~/.cache/cargo, unless you set environment values, like before.
Update the tutorials to point to ~/.config/cargo instead of ~/.cargo/config (With a mention that the legacy location ~/.cargo/config is still supported).
I think making standard compliance an opt-in is basically not having standard compliance at all. The standards exist to give common behavior across many different programs, and if you have to configure each of them anyway, then the benefit of having that standard is lost. The issues with the XDG crate ( |
I can't tell you about BSD, but for OSX: https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html TL;DR: very much not XDG. |
|
Ah yeah sorry to be clear I'm not worried about fragmentation within a platform, but rather across platforms. For example we can't really just update the tutorials to list different paths because now it's a different path for every platform. In that sense I think the fragmentation gets worse because as someone who works across OSX/Windows/Linux I've now got to always be conscious of where I'm at if I want to find these directories. |
|
|
|
So, I researched a little and found out that the BSDs should probably get XDG handling, OS X caches go into |
|
I'm personally still worried about the fragmentation problem. It looks like this is basically going to end up with almost a different location for directories per OS rather than "windows" and "non windows", and at some point it seems like the benefit perhaps isn't that large? This is why I was thinking that an opt-in may suffice for now in some form. |
|
@alexcrichton I guess if we want non-fragmentation, we should probably go for XDG on unixy systems (including Mac), and for AppData on Windows. This would give us a pretty consistent story that interacts well with the OSs, as well as separating caches from configs. |
|
That seems like not a great situation to be in though, unfortunately. There's still fragmentation between Windows and non-Windows, and Cargo would be favoring Linux/Windows over all other OSes by saying they need to be slotted into one of those buckets. Overall it seems like it doesn't really reduce the net number of issues? |
|
Let's collect a list of advantages and disadvantages:
So by just looking at the advantages/disadvantage (tell me if I missed any!), I'd say that 2) and 3) are both favorable to 1). In fact, the only advantage of 1) over 2) seems to be that there is cross-platform consistency between Windows and unixy operating systems, which I'd argue is very much not expected for Windows users. |
|
Thanks for working on this! Following XDG is a huge win and it would be much nicer if all applications did this. Primarily the clean separation of cache vs user data (config and data). Especially since cargo does not clean up its old caches, having them separated out for easy & confident removal is a win for the user. (The user will be safer to know it's only cache). |
|
I think that if we take this route we'd want to do the "best thing for the platform" in each case, so I wouldn't take the route of XDG everywhere on Unix (ignoring what OSX conventions are). To me any fragmentation is just as bad as lots of fragmentation, so I'm not worried about the degree of fragmentation along those lines. I also think that it may not quite be as black-and-white as listing out pros/cons and seeing which bucket is bigger. The existence of fragmentation can have a multiplicative effect where all of Cargo's decisions affect downstream users and such. For example anyone wanting to write a tool against Cargo's directory layout or something like that would end up having to work with all this logic somehow as well to work across platforms. I'd be curious on some other opinions from @rust-lang/tools as well, I have a feeling that @wycats in particular may have thoughts on this. |
Unless Cargo's directory layout is considered a stable interface, wouldn't any such tool have to invoke Cargo or use it as a library anyway? |
|
@alexcrichton I didn't want to suggest to compare the number of pros and cons, as they can certainly be split up in different ways. I do however, still think that the benefits of 2) and 3) outweigh the solution for 1), especially 2) which is basically a pure improvement IMO (I think that 1) is consistency at the cost of Windows users, because there is virtually no program that stores its configuration in something like |
|
@whitequark perhaps yeah, but it's not unheard of to write a tool that lives for a few weeks or so (e.g. doesn't live until the end of time) and Cargo's layout would be "stable" within that time frame. |
|
@alexcrichton to rephrase, I feel that this would be best addressed by allowing to reuse Cargo's persistency layer, if a consideration at all |
|
I've been skeptical of using XDG in the past since dotfiles work everywhere, and the spec doesn't provide any motivation. I'd be very curious to know what XDG adoption looks like these days, whether it's a winning or losing standard (I still have lots of dotfiles and no A big downside of supporting XDG with dotfile fallback is that users won't know where their stuff is. I've rejected XDG for multirust before. My inclination is to keep waiting. |
|
@brson Note that you would normally not have the I can see that pretty much every standard desktop application I use (on Debian) respects XDG, as well as some 3rd-party applications (Sublime Text), although many other 3rd-party ones don't (most games) and of course non-GUI tool authors don't feel compelled to follow XDG at all... |
|
@brson Look in |
|
@bluss Ah. On a desktop I do have those directories. On my headless machine only |
|
I'm mildly in favour of this - it seems like an improvement and I would expect each platform to differ in this way so I'm not too worried about the fragmentation effect (it is of course not ideal). I would also be interested to know whether XDG is 'winning' though. |
|
Some links that list support of applications: |
|
Fedora has had a goal to make its desktop applications adhere to it: https://fedoraproject.org/wiki/Features/XdgConfigDirs So Fedora & GNOME is the bastion of support I guess, even though many others support it too: XDG_Base_Directory_support / Arch Wiki @brson Main benefit is the user experience. Separating config, user data and caches makes cache and backup management much simpler. Cargo has data of all these three kinds, and a pretty large cache that you don't want to backup I think the “is it winning” is not the right question to ask for two reasons, 1) there is no alternative standard and 2) creating a better user experience doesn't really have any drawbacks. Separating cache from config and data is something that should be done anyway. The ~/.cache directory is normally automatically skipped in the default configuration of many backup tools. Cache and backup management seems to be a thing that's common to all programs and not just desktop applications. Cargo could also adhere to the |
|
@bluss I don't think it's 100% accurate to say there are no downsides, the lack of consistency across platforms and not knowing how to find the directory on an arbitrary platform without probing is a downside to me. |
|
Yes, I understand. I wanted to underline that there are clear benefits of a better user experience too. |
|
We chatted about this in the @rust-lang/tools triage meeting today, and the consensus was that we probably want to move forward with this. @nrc brought up an excellent point that in the long run most tools end up doing the most-platform-specific behavior as there's more and more pressure to do so. Additionally, it generally tends to mesh better with user's expectations. @brson, curious what you think on that? One part we did talk about though was that we'd want to see the OSX/Windows functionality here fleshed out before landing. @vadimcn I believe had a few more details on what we may want to do on Windows. |
|
That's great to hear. My plan was to use On OS X I would use What I couldn't figure out was where to place the executables on either Windows or OS X, so if you have ideas concerning this, please tell me! |
|
Just want to note that on Windows you are supposed to use the SHGetKnownFolderPath API, rather than hard-coding a specific path. The standard location for per-user executables is As for the cache directory, I wonder if |
|
@vadimcn Sure, we're not hardcoding the path on Linux either. Thanks for the place for executables! It seems that |
|
@tbu-: for that Windows provides GetTempPath. Normally, it's per-user, pointing to |
|
Hm. I can't find anything regarding the lifetime of files placed there on the documentation page. Ideally it'd be preserved by reboots, ignored by backup tools and could be cleaned by the Disk Cleanup Wizard. |
|
All of the above is true, in my experience. |
|
@tbu- for binaries on OSX using something like |
|
@alexcrichton Factored out the platform-specific code into a library, added Windows and OS X support and rebased it onto master. |
|
In I also had some concerns above about how the xdg crate is a little eager when panicking, could those be addressed as well? |
|
|
|
I'm still concerned about the confusion it will cause for minimal benefit. The story for Is there going to be any upgrade path? What happens to the existing .cargo folders? |
Can we guard against by having a way of finding out where Cargo installed?
Could questions, we should have answers! |
|
Cargo will inform you to add a directory to your PATH if it's not already in there during I do agree though that this puts a lot more pressure on a feature where through the CLI you can learn about the home directory Cargo thinks it's using. For an upgrade path, this PR currently prioritizes |
|
Here's another problem. multirust/rustup.exe control With the design of rustup.exe though, we're expecting all Cargo's to share their metadata, and for rustup.exe to know where that is. This means that either rustup.exe is going to have to preinitialize Part of the rustup.exe plan was also to share the |
|
@brson I don't know enough about the rustup.exe plan to be sure, but it sounds to me that having "everything Rusty" in one place is not a viable long term plan. People will want strange configurations for all kinds of strange reasons and there will be strange platform-specific requirements which we don't know about yet. IMO, a programming language should try to accommodate the platform it is running on, not try to layer it's own platform on top. Java tried this and despite being wildly successful, this was a pain point which hindered use and something they moved away from more and more as time went by. |
|
Is there an alternative way to solve the cache directories issue? We want it to be simple to purge cargo cache and to exclude it from backups. For N applications it really is easier if they all use the same cache root than having to add N configuration items to your backup tool. |
This may make it difficult to remove |
|
@matklad That's very intrusive. A better method would be to warn in future if you use |
|
Hm yeah that's a good point thinking about rustup.exe plans. I think it may be able to mesh well here, however? For a brand new system, this basically means that Cargo's "home directory" would need to be discovered though the same logic that Cargo has (e.g. this dirs crate). I'd imagine that rustup could either use this or just always set It may not be particularly crucial that rustup installs itself to a globally known location (e.g. While I agree that we should accomadate the platform at hand, I don't think that should ever come at the cost of user experience. Along those lines I wouldn't take that as an ironclad guiding principle. In this case with Cargo, however, and I think with rustup as well, we can get this kind of configuration with little-to-no cost in terms of experience. |
|
I'm not clear on how How does If you don't want to deal with the platform-specific config and just put it in |
|
Should I duplicate the path finding functions for the tests or should I make them less fine-grained? |
|
@brson we've actually already got some custom code to handle that case (e.g. the "home directory" is special). If you put configuration in |
|
@tbu- I'm not sure I understand? There are no tests here? |
|
The tests are still failing because they check for the old location, e.g. tests/test_cargo_install:48-49. I'm unsure how to fix this, should I call the |
|
|
|
@alexcrichton I have rebased the pull request and fixed the tests. Should I squash the commits? |
|
|
|
Ah yes, sorry I meant to get back to this a little earlier. I had a chance to talk with @wycats about this recently and here were some thoughts we had (in addition to what's previously been mentioned here)
Overall it sounded like @wycats was pretty hesitant to move forward on this, and I think some of the new points brought up here are also quite persuasive. |
|
I don't know about OS X.
One very nice part about putting the cache into the folders designated for caches means that existing tools (backup, etc.) work at all together with Cargo. It's true that restarting from scratch might get harder, but if we introduce a
I really see no reason why the XDG directories would work any less "out of the box" than "~/.cargo". Can you elaborate?
Yes, it's pretty much us ("the Cargo developers") who are expected to make Cargo adhere to standards. E.g.: https://wiki.archlinux.org/index.php/XDG_Base_Directory_support#Supported. |
|
Yeah we definitely agree that there are some benefits (like with backup solutions), but the question is whether it's worth the tradeoffs. If no one's really sure of what happens on OSX, then we should probably continue doing what we're doing today there. On Windows it sounds like we're also a little unsure? There doesn't seem to be a clear answer to "yes this is where the directories should be", but conversely there's also nothing saying "no, you should never put directories there".
I think @wycats may be able to add more here, but my understanding is that it's just "one more layer" which may not be guaranteed to work. It's often difficult to imagine these sorts of situations, but there are so many embedded flavors of Linux around that any configuration is bound to exist somewhere, and there are bound to exist configurations where xdg doesn't work but just using the home directory does. Put another way, the use of XDG only seems "clearly correct" for distributions themselves, not necessarily for any Cargo binary running on a linux kernel.
Unfortunately I don't think link does much to answer the question, though. There's nothing indicating that this shouldn't be an off-by-default but turned-on-by-packagers kind of behavior. |
But, as used by cargo, both strategies "just use the home directory", at least for the user data. There's nothing special about |
|
I feel, that this PR is missing a point. Standardized locations aren't used, because they are standard, but because they are convenient:
As such, I do not see any reason to have distinct Anyway, what is there do disagree about? All systems, supported by Rust, have symbolic links. IMO, it makes most sense to leave current layout in place, but replace some of dirs by symlinks to more fitting places ( If done, this should be clearly communicated to users and, probably, followed by creation of uninstaller to remove those directories (because simple |
|
@alexcrichton I believe on Windows the situation is clearly: Don't put the application data (caches) into the home directory. |
Well, since Arch Linux generally ships the exact upstream, it's clear that they want upstream to support XDG. |
I'd like to hear more about that, because currently this is pretty unclear to me. On a normal system, the "XDG" directories are just longer path names, namely "~/.cache/cargo", so it is supported exactly when the home directory is known. |
If you have them in
Except for Windows, where they can only be created by administrators.
This sounds like a good compromise to me (except that it still clutters the home directory with |
|
While we can't create symbolic links on Windows, we can create directory junctions, which as far as I can tell are just as good. |
Sigh. I am unaware of any part of XDG spec, that specifically suggests putting binaries somewhere. I am also unaware of any distribution, adding anything within Putting binaries in the same place under For those reasons I would prefer Cargo to request elevation and put any executables under |
Yes, the exact type of link to use in this case seems irrelevant. |
|
|
|
@Alexander-- Not part of the XDG spec, but the second link in the PR: http://www.freedesktop.org/software/systemd/man/file-hierarchy.html. |
|
This is an example of possible breakage from following these sorts of environment variables. It could be the case that someone invokes |
|
Mh, fair enough, that's definitely a breakage from starting to follow XDG specifications where you previously did not. "The sooner the better?" Your link might even provide some more motivation, even git is doing it (which definitely isn't a desktop application). |
|
To me, being able to backup your cargo folder without copying cache files is the best reason to want this, and that could be achieved by changing the cache location to be platform-specific, possibly optionally. There's less reason to care where cargo stores its internal cache than its configuration.
@Alexander-- I like this point, that encouraging $PATH to include somewhere user-writable weakens security (probably, I'm not sure). I assume that there are precedents in dynamic language package managers that default to non-global installation, but don't know that. We're definitely are encouraging |
|
It'd be strange to use Cocoa conventions on OS X for something that isn't built with Cocoa and isn't pretending to be a native |
Yeah, on OSX, |
|
I've just discovered this PR; on Linux I like the old behaviour better (being able to wipe or backup a single directory) so hopefully it all ends up on an opt-in/opt-out basis. A use case on an SD based ARM system - operate entirely in ramdisk after decompressing a cargo tarball ( |
|
@petevine It's opt-out, you can use the environment variable |
|
@alexcrichton What's the status of this pull request? It seems that there's quite some controversy on changing the Linux behavior. Could we land the Windows version? The situation there is worse than the Linux one: We use the standards from a different platform (dot directories, |
|
@tbu- Of course you can name a file with a leading period, you just have to trick explorer into doing it by naming it |
|
@retep998 Oh, nice trick. I did not know that one when I tried to create .gitignores. :) |
|
Some people in this thread have wondered whether Cargo would be the first package-manager to follow the XDG spec for per-user installation, and whether that would cause user confusion. For what it's worth, Python has looked for installed libraries in As for |
You expect people to be using Cargo, a program that exists to download source code and drive a compiler, on embedded controllers? |
|
@notriddle The standard uses a hardcoded directory |
I'm on OS X. How is this an improvement? I don't really care where my cache files end up, but what's the justification for moving my config files out of |
I don't understand why people are concerned about cargo working on embedded Linux anyway. You need to be able to run the resulting binaries, but this won't affect them. |
|
@frewsxcv These paths would still be inside your home directory (note the |
I meant directly in the home directory, not a subdirectory. |
Things are never installed directly in the home directory. Currently they are installed in subdirectory called |
|
@jan-hudec Please go to rust-lang/rfcs#1615, the discussion is happening there. |
Strategy for backward-compatiblity:
When checking for the relevant Cargo directories, check in the following
order of preference:
CARGO_HOME.The new platform-specific directories are as follows:
On Windows, use
AppData\Local\Temp\Cargofor cache files (obtained viaGetTempPath),AppData\Roaming\Cargofor the config files(
FOLDERID_RoamingAppData) andAppData\Local\Programs\Cargoforinstalled binaries (
FOLDERID_UserProgramFiles).On Unixy systems, use the XDG spec:
~/.cache/cargofor cache files,~/.config/cargofor config,~/.local/binfor installed binaries.http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
http://www.freedesktop.org/software/systemd/man/file-hierarchy.html
On OS X, use
~/Library/Caches/Cargofor cache files,~/Library/Cargofor config files and
~/Library/Cargo/binfor binary files.Fixes #1734. Fixes #1976.