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

Use XDG Base Directory Spec for default config file. #1061

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions Godeps/_workspace/src/github.com/cep21/xdgbasedir/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Godeps/_workspace/src/github.com/cep21/xdgbasedir/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions Godeps/_workspace/src/github.com/cep21/xdgbasedir/goverify.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

126 changes: 126 additions & 0 deletions Godeps/_workspace/src/github.com/cep21/xdgbasedir/xdgbasedir.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,16 +279,26 @@ superpowers:
Configuration
-------------

### Configuration file

Hub stores its configuration in a file named "hub", located in a directory
determined in accordance with the
[XDG Base Directory Specification](http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html).
Copy link
Owner

Choose a reason for hiding this comment

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

I don't think this section is at all necessary. We can just mention somewhere that hub respects XDG_CONFIG_HOME, and that should be enough for people familiar with XDG to understand what's going on. We can keep referring to ~/.config/hub in the rest of the documentation as before.

Copy link
Author

Choose a reason for hiding this comment

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

Sorry, I just moved house and have had intermittent internet access. I thought I'd get a chance to do this before I moved, but it didn't happen. Lucky this is not very important 😄 I'll sort it out when I get a chance over the next couple of days.

If the environment variable "$XDG_CONFIG_HOME" is set, it's value is taken
to be the full path to the configuration directory. If it is unset or empty,
the default "~/.config/" is used.

### GitHub OAuth authentication

Hub will prompt for GitHub username & password the first time it needs to access
the API and exchange it for an OAuth token, which it saves in "~/.config/hub".
the API and exchange it for an OAuth token, which it saves in the configuration
file as described above.

To avoid being prompted, use **GITHUB_USER** and **GITHUB_PASSWORD** environment
variables.

Alternatively, you may provide **GITHUB_TOKEN**, an access token with
**repo** permissions. This will not be written to `~/.config/hub`.
**repo** permissions. This will not be written to the configuration file.

### HTTPS instead of git protocol

Expand Down
73 changes: 73 additions & 0 deletions features/xdg-config.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
Feature: XDG BaseDir Spec

According to the XDG Base Directory Specification
(http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html),
if the XDG_CONFIG_HOME environment variable is set, this should be used
to store application specific configuration. If unset, then a default of
~/.config should be used.

Background:
Given I am in "dotfiles" git repo

Scenario: XDG_CONFIG_HOME empty, store authorization in default directory
Given the GitHub API server:
"""
require 'socket'
require 'etc'
machine_id = "#{Etc.getlogin}@#{Socket.gethostname}"

post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
assert :scopes => ['repo'],
:note => "hub for #{machine_id}",
:note_url => 'http://hub.github.com/'
json :token => 'OTOKEN'
}
get('/user') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
json :login => 'MiSlAv'
}
post('/user/repos') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
json :full_name => 'mislav/dotfiles'
}
"""
Given $XDG_CONFIG_HOME is ""
When I run `hub create` interactively
When I type "mislav"
And I type "kitty"
And the file "../home/.config/hub" should contain "user: MiSlAv"
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
And the file "../home/.config/hub" should have mode "0600"

Scenario: XDG_CONFIG_HOME is not empty, store authorization in specified directory
Given the GitHub API server:
"""
require 'socket'
require 'etc'
machine_id = "#{Etc.getlogin}@#{Socket.gethostname}"

post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
assert :scopes => ['repo'],
:note => "hub for #{machine_id}",
:note_url => 'http://hub.github.com/'
json :token => 'OTOKEN'
}
get('/user') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
json :login => 'MiSlAv'
}
post('/user/repos') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
json :full_name => 'mislav/dotfiles'
}
"""
Given $XDG_CONFIG_HOME is "../home/.xdgconfig"
Given a directory named "../home/.xdconfig"
When I run `hub create` interactively
When I type "mislav"
And I type "kitty"
And the file "../home/.xdgconfig/hub" should contain "user: MiSlAv"
And the file "../home/.xdgconfig/hub" should contain "oauth_token: OTOKEN"
And the file "../home/.xdgconfig/hub" should have mode "0600"
8 changes: 7 additions & 1 deletion github/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/github/hub/Godeps/_workspace/src/github.com/howeyc/gopass"
"github.com/github/hub/ui"
"github.com/github/hub/utils"
"github.com/github/hub/Godeps/_workspace/src/github.com/cep21/xdgbasedir"
Copy link
Owner

Choose a reason for hiding this comment

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

Instead of pulling in a new dependency, couldn't we simply read the value of XDG_CONFIG_HOME environment variable and default to $HOME/.config if not set?

Copy link
Author

Choose a reason for hiding this comment

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

Sure. I'll do it later today if that's preferred. I just figured that it might be nice to have the xdgbasedir spec available in it's entirety, and why not pull it in from a library?. For instance there is an argument that passwords should go in data not in config, and the dependency has code for data directories as well. Hub config would go in the config directory. If a user wants to cache their password, but not save it permanently that could go in the cache directory etc.

Copy link
Owner

Choose a reason for hiding this comment

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

My general rule for software is not to pull in dependencies when you can simply inline something. This is the entirety of the logic that we're obtaining by pulling in an external library:

// DataHomeDirectory is a single base directory relative to which user-specific data files should be written
func DataHomeDirectory() (string, error) {
    return getInEnvOrJoinWithHome("XDG_DATA_HOME", defaultDataHomeDirectory)
}

we can do the same ourselves. Also, this library uses user.Current(), which we want to avoid due to cross-compilation issues: #1082

)

var defaultConfigsFile string
Expand All @@ -29,7 +30,12 @@ func init() {
utils.Check(fmt.Errorf("Can't get current user's home dir"))
}

defaultConfigsFile = filepath.Join(homeDir, ".config", "hub")
// Config file using XDG Base Directory spec
defaultConfigsDir, xdgerror := xdgbasedir.ConfigHomeDirectory()
if xdgerror != nil {
utils.Check(xdgerror)
}
defaultConfigsFile = filepath.Join(defaultConfigsDir, "hub")
}

type yamlHost struct {
Expand Down
9 changes: 6 additions & 3 deletions man/hub.1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "HUB" "1" "September 2015" "GITHUB" "Hub Manual"
.TH "HUB" "1" "December 2015" "GITHUB" "Hub Manual"
.
.SH "NAME"
\fBhub\fR \- git + hub = github
Expand Down Expand Up @@ -175,14 +175,17 @@ If \fB\-v\fR is given, additionally print detailed report of all checks and thei
.
.SH "CONFIGURATION"
.
.SS "Configuration file"
Hub stores its configuration in a file named "hub", located in a directory determined in accordance with the XDG Base Directory Specification \fIhttp://standards\.freedesktop\.org/basedir\-spec/basedir\-spec\-latest\.html\fR\. If the environment variable "$XDG_CONFIG_HOME" is set, it\'s value is taken to be the full path to the configuration directory\. If it is unset or empty, the default "~/\.config/" is used\.
.
.SS "GitHub OAuth authentication"
Hub will prompt for GitHub username & password the first time it needs to access the API and exchange it for an OAuth token, which it saves in "~/\.config/hub"\.
Hub will prompt for GitHub username & password the first time it needs to access the API and exchange it for an OAuth token, which it saves in the configuration file as described above\.
.
.P
To avoid being prompted, use \fIGITHUB_USER\fR and \fIGITHUB_PASSWORD\fR environment variables\.
.
.P
Alternatively, you may provide \fIGITHUB_TOKEN\fR, an access token with \fIrepo\fR permissions\. This will not be written to \fB~/\.config/hub\fR\.
Alternatively, you may provide \fIGITHUB_TOKEN\fR, an access token with \fIrepo\fR permissions\. This will not be written to the configuration file\.
.
.SS "HTTPS instead of git protocol"
If you prefer the HTTPS protocol for GitHub repositories, you can set "hub\.protocol" to "https"\. This will affect \fBclone\fR, \fBfork\fR, \fBremote add\fR and other operations that expand references to GitHub repositories as full URLs that otherwise use git and ssh protocols\.
Expand Down
16 changes: 13 additions & 3 deletions man/hub.1.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.