-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
proposal: os: add application data directory functions (i.e. os.UserDataDir and os.DataDir) #62382
Comments
@gopherbot add ExpertNeeded |
@gopherbot add WaitingForInfo |
I should note that the user-specific function described in this proposal has briefly been mentioned before in #29960 by @mvdan. His comments are as follows:
They suggest this workaround for systems that respect the XDG base dir spec: func userDataDir() (string, error)
if dir := os.Getenv("XDG_DATA_HOME"); dir != "" {
return dir, nil
}
// fall back to something sane on all platforms
return os.UserConfigDir()
} I do understand the sentiment here—on one hand, because of this the possibility for collisions exists and there is some degree of redundancy on a few platforms. I do have a serious problem with this though:
This seems to be quite a dubious collection of claims to me—I can think of equally many programs that do use multiple folders for application data (regardless of their respect for the XDG base dir spec). Plus, the idea that most programs only store data in the form of configs and cache files is probably untrue (and seems very opinionated to be enforced via a language's standard library). In this proposal, I'm not advocating for the enforcement of the XDG base dir spec through the |
I wrote an external library with a goal similar to this proposal's: Creating a cross-platform over what is, quite frankly, a mess of conflicting conventions was quite challenging and I'm still not really sure I quite nailed it, although I am using this library in production in a few places with reasonable success. Since I wrote that library a long time ago I don't have all of the context loaded in my brain to thoroughly compare what I ran into there with what this proposal proposes, but I do have one immediate observation: Each of these platform conventions has both a different set of base directories and a different convention for how different applications should cohabit within those directories. I don't think just returning the base directory is sufficient for a true cross-platform abstraction. For example, given a hypothetical program called "That Escalated Quickly" by the vendor "AbstractionCorp", the conventional directory to use for that program on these platforms might be:
(I'm not sure what's conventional on plan9. My library doesn't support it.) Assuming that a calling application really does want to follow the platform conventions, they'd need more than just the base directory that they are supposed to create their directory inside. Under the current form of this proposal, it seems like they'd still need to write OS-specific code to achieve that, which makes me think that they then might as well just handle the entire problem themselves (or use a third-party library like mine, if it meets their needs). |
I don't oppose adding these APIs to |
Great points @apparentlymart—I think that if this was the first proposal for one of these |
If anything, it seems The remaining hardcoded location, for Unix/Linux, is the only explicitly "config" directory, Maybe
|
Oh yes, the distinction between "configuration directory" and "data directory" -- or lack thereof -- was another interesting wart in the design of my "userdirs" library, which I ended up resolving just with some documentation:
In other words, callers that intend to treat my library as a cross-platform abstraction must carefully name what they place in each of those directories so that they can be distinguished by something other than just what directory they are in. In the applications where I've used this, I've used some different strategies depending on the situation, including:
I was intentionally vague in the docstring I included above because I was trying to leave room for adding new platform conventions in future, but FWIW here's exactly what my library currently implements in the version that's current at the time of writing this:
In practice then, on both Windows and macOS the "config home" and the "data home" end up being the same directory. Only the XDG implementation actually distinguishes those. Others might disagree with my interpretations of the Windows and macOS conventions. I'm sharing them only in case it's helpful in evaluating this proposal, or in formulating successor proposals. |
In #22536, #26463, and #29960, the
os
package was greatly improved by adding a standard way to get a user's standard cache, home, and config directories—missing still is an easy way to get the correct directories for storing both shared and user-specific application data. Something likeos.DataDir
andos.UserDataDir
respectively, mapped to the following locations:$XDG_DATA_HOME
or~/.local/share
%AppData%
~/Library/Application Support
$home/lib
?$XDG_DATA_DIRS
or/usr/share/
(or maybe/usr/local/share/
)%ProgramData%
/Library/Application Support
/lib
?†I have never actually used macos or plan9, so this information may be of dubious accuracy
I'm sort of shocked go doesn't already have this, considering every platform seems to have a standardized way to handle these sorts of files and for good reason—this would be endlessly useful.
This proposal is just to start the discussion and to crowdsource the knowledge required to implement this on plan9 and macos (and other platforms like ios)—I don't have any experience outside of Linux and Windows.
Possible issues
On Windows, it appears that
%appdata%
is also being returned fromos.UserConfigDir
. This should be made clear in the documentation to prevent possible file collisions.The same issue will appear on macos if the correct data dir to use is
~/Library/Application Support
; also on plan9 if~/lib
is the correct data dir.The text was updated successfully, but these errors were encountered: