зеркало из https://github.com/mislav/hub.git
Support XDG Base Directory Specification
Respect XDG_CONFIG_HOME and XDG_CONFIG_DIRS. https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables Fixes #1048, closes #1061
This commit is contained in:
Родитель
02db852769
Коммит
f8bd902145
|
@ -171,6 +171,57 @@ Feature: OAuth authentication
|
|||
Then the output should not contain "github.com password for mislav"
|
||||
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
|
||||
|
||||
Scenario: XDG: legacy config found, credentials from GITHUB_USER & GITHUB_PASSWORD
|
||||
Given I am "mislav" on github.com with OAuth token "LTOKEN"
|
||||
And the GitHub API server:
|
||||
"""
|
||||
post('/authorizations') {
|
||||
assert_basic_auth 'mislav', 'kitty'
|
||||
status 201
|
||||
json :token => 'OTOKEN'
|
||||
}
|
||||
get('/user') {
|
||||
json :login => 'mislav'
|
||||
}
|
||||
post('/user/repos') {
|
||||
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
|
||||
status 201
|
||||
json :full_name => 'mislav/dotfiles'
|
||||
}
|
||||
"""
|
||||
And $GITHUB_USER is "mislav"
|
||||
And $GITHUB_PASSWORD is "kitty"
|
||||
And $XDG_CONFIG_HOME is "$HOME/.xdg"
|
||||
When I successfully run `hub create`
|
||||
Then the file "../home/.xdg/hub" should contain "oauth_token: OTOKEN"
|
||||
And the stderr should contain exactly:
|
||||
"""
|
||||
Notice: config file found but not respected at: $HOME/.config/hub
|
||||
You might want to move it to `$HOME/.xdg/hub' to avoid re-authenticating.\n
|
||||
"""
|
||||
|
||||
Scenario: XDG: config from secondary directories
|
||||
Given I am "mislav" on github.com with OAuth token "OTOKEN"
|
||||
And the GitHub API server:
|
||||
"""
|
||||
get('/user') {
|
||||
json :login => 'mislav'
|
||||
}
|
||||
post('/user/repos') {
|
||||
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
|
||||
status 201
|
||||
json :full_name => 'mislav/dotfiles'
|
||||
}
|
||||
"""
|
||||
And $GITHUB_USER is "mislav"
|
||||
And $GITHUB_PASSWORD is "kitty"
|
||||
And $XDG_CONFIG_HOME is "$HOME/.xdg"
|
||||
And $XDG_CONFIG_DIRS is "/etc/xdg-nonsense:$HOME/.xdg-dir"
|
||||
When I move the file named "../home/.config/hub" to "../home/.xdg-dir/hub"
|
||||
And I successfully run `hub create`
|
||||
Then the file "../home/.xdg/hub" should not exist
|
||||
And the stderr should contain exactly ""
|
||||
|
||||
Scenario: Credentials from GITHUB_TOKEN
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
|
@ -390,7 +441,7 @@ Feature: OAuth authentication
|
|||
When I run `hub create` interactively
|
||||
Then the output should contain:
|
||||
"""
|
||||
/home/.config/hub: permission denied\n
|
||||
$HOME/.config/hub: permission denied\n
|
||||
"""
|
||||
And the exit status should be 1
|
||||
And the file "../home/.config/hub" should not exist
|
||||
|
|
|
@ -40,7 +40,7 @@ Given(/^I am "([^"]*)" on ([\S]+)(?: with OAuth token "([^"]*)")?$/) do |name, h
|
|||
end
|
||||
|
||||
Given(/^\$(\w+) is "([^"]*)"$/) do |name, value|
|
||||
set_env name, value
|
||||
set_env name, value.gsub(/\$([A-Z_]+)/) { ENV.fetch($1) }
|
||||
end
|
||||
|
||||
Given(/^I am in "([^"]*)" git repo$/) do |dir_name|
|
||||
|
@ -153,6 +153,13 @@ Given(/^the current dir is not a repo$/) do
|
|||
end
|
||||
end
|
||||
|
||||
When(/^I move the file named "([^"]+)" to "([^"]+)"?$/) do |source, dest|
|
||||
in_current_dir do
|
||||
FileUtils.mkdir_p(File.dirname(dest))
|
||||
FileUtils.mv(source, dest)
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^the GitHub API server:$/) do |endpoints_str|
|
||||
@server = Hub::LocalServer.start_sinatra do
|
||||
eval endpoints_str, binding
|
||||
|
|
|
@ -191,4 +191,16 @@ World Module.new {
|
|||
def shell_escape(message)
|
||||
message.to_s.gsub(/['"\\ $]/) { |m| "\\#{m}" }
|
||||
end
|
||||
|
||||
%w[output_from stdout_from stderr_from all_stdout all_stderr].each do |m|
|
||||
define_method(m) do |*args|
|
||||
home = ENV['HOME'].to_s
|
||||
output = super(*args)
|
||||
if home.empty?
|
||||
output
|
||||
else
|
||||
output.gsub(home, '$HOME')
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
|
|
@ -17,15 +17,6 @@ import (
|
|||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
var defaultConfigsFile string
|
||||
|
||||
func init() {
|
||||
homeDir, err := homedir.Dir()
|
||||
utils.Check(err)
|
||||
|
||||
defaultConfigsFile = filepath.Join(homeDir, ".config", "hub")
|
||||
}
|
||||
|
||||
type yamlHost struct {
|
||||
User string `yaml:"user"`
|
||||
OAuthToken string `yaml:"oauth_token"`
|
||||
|
@ -243,13 +234,65 @@ func (c *Config) selectHost() *Host {
|
|||
return c.Hosts[i-1]
|
||||
}
|
||||
|
||||
var defaultConfigsFile string
|
||||
|
||||
func configsFile() string {
|
||||
configsFile := os.Getenv("HUB_CONFIG")
|
||||
if configsFile == "" {
|
||||
configsFile = defaultConfigsFile
|
||||
if configFromEnv := os.Getenv("HUB_CONFIG"); configFromEnv != "" {
|
||||
return configFromEnv
|
||||
}
|
||||
if defaultConfigsFile == "" {
|
||||
var err error
|
||||
defaultConfigsFile, err = determineConfigLocation()
|
||||
utils.Check(err)
|
||||
}
|
||||
return defaultConfigsFile
|
||||
}
|
||||
|
||||
func homeConfig() (string, error) {
|
||||
if home, err := homedir.Dir(); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
return filepath.Join(home, ".config"), nil
|
||||
}
|
||||
}
|
||||
|
||||
func determineConfigLocation() (string, error) {
|
||||
var err error
|
||||
|
||||
xdgHome := os.Getenv("XDG_CONFIG_HOME")
|
||||
configDir := xdgHome
|
||||
if configDir == "" {
|
||||
if configDir, err = homeConfig(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return configsFile
|
||||
xdgDirs := os.Getenv("XDG_CONFIG_DIRS")
|
||||
if xdgDirs == "" {
|
||||
xdgDirs = "/etc/xdg"
|
||||
}
|
||||
searchDirs := append([]string{configDir}, strings.Split(xdgDirs, ":")...)
|
||||
|
||||
for _, dir := range searchDirs {
|
||||
filename := filepath.Join(dir, "hub")
|
||||
if _, err := os.Stat(filename); err == nil {
|
||||
return filename, nil
|
||||
}
|
||||
}
|
||||
|
||||
configFile := filepath.Join(configDir, "hub")
|
||||
|
||||
if configDir == xdgHome {
|
||||
if homeDir, _ := homeConfig(); homeDir != "" {
|
||||
legacyConfig := filepath.Join(homeDir, "hub")
|
||||
if _, err = os.Stat(legacyConfig); err == nil {
|
||||
ui.Errorf("Notice: config file found but not respected at: %s\n", legacyConfig)
|
||||
ui.Errorf("You might want to move it to `%s' to avoid re-authenticating.\n", configFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return configFile, nil
|
||||
}
|
||||
|
||||
var currentConfig *Config
|
||||
|
@ -315,7 +358,7 @@ func CheckWriteable(filename string) error {
|
|||
// Public for testing purpose
|
||||
func CreateTestConfigs(user, token string) *Config {
|
||||
f, _ := ioutil.TempFile("", "test-config")
|
||||
defaultConfigsFile = f.Name()
|
||||
os.Setenv("HUB_CONFIG", f.Name())
|
||||
|
||||
host := &Host{
|
||||
User: "jingweno",
|
||||
|
|
Загрузка…
Ссылка в новой задаче