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 UserConfigDir #29960

Open
mvdan opened this Issue Jan 28, 2019 · 7 comments

Comments

Projects
None yet
4 participants
@mvdan
Copy link
Member

mvdan commented Jan 28, 2019

Go 1.11 added os.UserCacheDir in #22536, and 1.12 is adding os.UserHomeDir in #26463. This is great, and it covers plenty of common use cases.

UserCacheDir is particularly interesting, as its behavior changes greatly between platforms. For example, on Unix-y systems it tries $XDG_CACHE_HOME and falls back to $HOME/.cache, and on Windows it uses %LocalAppData%.

With those two functions, I believe there's only one piece missing; a configuration directory. Too many applications write "dot files" under the user's home directory, and that's bad practice. Some others hard-code $HOME/.config, which is only marginally better as it doesn't do the right thing on Windows/Mac.

Relying on XDG base directory vars like $XDG_CONFIG_HOME is no good either, as those don't exist on most systems.

We're only left with third-party libraries like https://github.com/shibukawa/configdir, which are moderately popular. In practice, popular software tends to write their own implementations. Below are some examples:

I propose adding func UserConfigDir() (string, error), which would return:

  • $XDG_CONFIG_HOME or $HOME/.config on Unix-y systems
  • %APPDATA% on Windows, which is described as "Contains the full path to the Application Data directory of the logged-in user" (unlike %LOCALAPPDATA%, it's not for temporary files)
  • $HOME/Library/Preferences on Mac

I don't know about plan9, but given that the cache dir is $home/lib/cache, perhaps $home/lib/config would work.

Please note that I'm not suggesting adding support for XDG base directories into the os package. Most notably, adding UserConfigDir might lead to some users requesting UserDataDir. However, I can think of multiple reasons why they're not equally important:

  • Mac and Windows don't obey XDG, so they only have one persistent per-user directory
  • Even on Linux, most apps store all their data in their config dir. For example: Chromium, Libreoffice, GIMP, and gcloud all seem to ignore XDG_DATA_HOME
  • Most programs only need one persistent per-user directory, and it's often for config files; see the links above for examples

The only disadvantage I see with adding this API is that one could say we'd be encouraging users to store data files into XDG_CONFIG_HOME instead of XDG_DATA_HOME on XDG systems. However, those few programs that wish to differentiate their data directory from their config directory could simply do:

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()
}

/cc @kolyshkin @bradfitz @rsc @ianlancetaylor @stapelberg @robpike

@mvdan mvdan added the Proposal label Jan 28, 2019

@mvdan mvdan added this to the Proposal milestone Jan 28, 2019

@mvdan

This comment has been minimized.

Copy link
Member Author

mvdan commented Jan 28, 2019

Forgot to mention: happy to work on this myself early in the 1.13 cycle if the proposal gets accepted.

@robpike

This comment has been minimized.

Copy link
Contributor

robpike commented Jan 28, 2019

The directory on Plan 9 is $home/lib.

@mvdan

This comment has been minimized.

Copy link
Member Author

mvdan commented Jan 28, 2019

I was referring to how UserCacheDir uses $home/lib/cache :)

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Jan 30, 2019

@mvdan, yes but Rob's point is that the config dir is just $home/lib (not $home/lib/config). There's not an obvious cache dir on Plan 9 and I abused $home/lib by making a cache subdirectory.

Anyway...

We chatted about this at proposal review, and UserConfigDir seems fine. None of us can explain what UserDataDir would mean or be appropriate for vs $HOME, so let's be sure not to do that one. :-)

Marking approved for UserConfigDir.

@mvdan

This comment has been minimized.

Copy link
Member Author

mvdan commented Jan 30, 2019

There's not an obvious cache dir on Plan 9 and I abused $home/lib by making a cache subdirectory.

Ah, I understand now. I guess we could always use $home/lib here; I doubt any programs would break if the cache directory is inside the data directory. But we can discuss that in the CL.

so let's be sure not to do that one

I personally tend to not find ~/.local/share useful on Linux, so I tend to agree that we shouldn't open that can of worms :)

I'll send a CL shortly, so that it can be reviewed early during the cycle.

@mvdan mvdan self-assigned this Jan 30, 2019

@gopherbot

This comment has been minimized.

Copy link

gopherbot commented Feb 2, 2019

Change https://golang.org/cl/160877 mentions this issue: os: add UserConfigDir

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Feb 12, 2019

Ah, I understand now. I guess we could always use $home/lib here; I doubt any programs would break if the cache directory is inside the data directory. But we can discuss that in the CL.

FWIW, there's not much to discuss. The idea of a user config dir is well-defined on Plan 9 and is $home/lib. Yes, I stuck a go build cache in the user config dir. My bad. But that doesn't change what UserConfigDir should return on Plan 9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment