From 7d9461b819921280c34d621b85dae4286c3e0938 Mon Sep 17 00:00:00 2001 From: Matthew Gleich Date: Wed, 6 Jan 2021 15:13:58 -0500 Subject: [PATCH 1/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20to=20use=20?= =?UTF-8?q?os.UserHomeDir()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- git/ssh_config.go | 4 ++-- internal/config/config_file.go | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/git/ssh_config.go b/git/ssh_config.go index 317ff605941..1030b811a2f 100644 --- a/git/ssh_config.go +++ b/git/ssh_config.go @@ -9,7 +9,7 @@ import ( "regexp" "strings" - "github.com/mitchellh/go-homedir" + "github.com/cli/cli/internal/config" ) var ( @@ -147,7 +147,7 @@ func ParseSSHConfig() SSHAliasMap { p := sshParser{} - if homedir, err := homedir.Dir(); err == nil { + if homedir, err := config.DeprecatedHomeDirPath(); err == nil { userConfig := filepath.Join(homedir, ".ssh", "config") configFiles = append([]string{userConfig}, configFiles...) p.homeDir = homedir diff --git a/internal/config/config_file.go b/internal/config/config_file.go index d4c132360ee..9ee42b28764 100644 --- a/internal/config/config_file.go +++ b/internal/config/config_file.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "path" + "path/filepath" "syscall" "github.com/mitchellh/go-homedir" @@ -14,8 +15,8 @@ import ( ) func ConfigDir() string { - dir, _ := homedir.Expand("~/.config/gh") - return dir + homeDir, _ := DeprecatedHomeDirPath(".config", "gh") + return homeDir } func ConfigFile() string { @@ -30,6 +31,35 @@ func ParseDefaultConfig() (Config, error) { return ParseConfig(ConfigFile()) } +// Get the absolute path for a folder or file. Support for the old homedir method +// Use os.UserHomeDir() for all new uses of the user's home dir. +// Tied to https://github.com/cli/cli/pull/2740 +func DeprecatedHomeDirPath(elem ...string) (string, error) { + oldHomeDir, err := homedir.Dir() + if err != nil { + return "", err + } + + homeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } + + fullOldPath := filepath.Join(append([]string{oldHomeDir}, elem...)...) + fullPath := filepath.Join(append([]string{homeDir}, elem...)...) + + if fullOldPath != fullPath && len(elem) > 0 { + oldStat, err := os.Stat(fullOldPath) + if os.IsNotExist(err) && !oldStat.IsDir() { + return fullPath, nil + } + + err = os.Rename(fullOldPath, fullPath) + return fullPath, err + } + return fullPath, err +} + var ReadConfigFile = func(filename string) ([]byte, error) { f, err := os.Open(filename) if err != nil { From 64fda21116b23af846836eb97732545d62c39528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 22 Jan 2021 20:19:59 +0100 Subject: [PATCH 2/2] Avoid ever invoking go-homedir when config was found in a new location --- git/ssh_config.go | 6 ++-- internal/config/config_file.go | 59 +++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/git/ssh_config.go b/git/ssh_config.go index 1030b811a2f..7f2778fd916 100644 --- a/git/ssh_config.go +++ b/git/ssh_config.go @@ -147,10 +147,10 @@ func ParseSSHConfig() SSHAliasMap { p := sshParser{} - if homedir, err := config.DeprecatedHomeDirPath(); err == nil { - userConfig := filepath.Join(homedir, ".ssh", "config") + if sshDir, err := config.HomeDirPath(".ssh"); err == nil { + userConfig := filepath.Join(sshDir, "config") configFiles = append([]string{userConfig}, configFiles...) - p.homeDir = homedir + p.homeDir = filepath.Dir(sshDir) } for _, file := range configFiles { diff --git a/internal/config/config_file.go b/internal/config/config_file.go index 9ee42b28764..9804aec36ef 100644 --- a/internal/config/config_file.go +++ b/internal/config/config_file.go @@ -15,7 +15,7 @@ import ( ) func ConfigDir() string { - homeDir, _ := DeprecatedHomeDirPath(".config", "gh") + homeDir, _ := homeDirAutoMigrate() return homeDir } @@ -31,33 +31,60 @@ func ParseDefaultConfig() (Config, error) { return ParseConfig(ConfigFile()) } -// Get the absolute path for a folder or file. Support for the old homedir method -// Use os.UserHomeDir() for all new uses of the user's home dir. -// Tied to https://github.com/cli/cli/pull/2740 -func DeprecatedHomeDirPath(elem ...string) (string, error) { - oldHomeDir, err := homedir.Dir() +func HomeDirPath(subdir string) (string, error) { + homeDir, err := os.UserHomeDir() if err != nil { + // TODO: remove go-homedir fallback in GitHub CLI v2 + if legacyDir, err := homedir.Dir(); err == nil { + return filepath.Join(legacyDir, subdir), nil + } return "", err } + newPath := filepath.Join(homeDir, subdir) + if s, err := os.Stat(newPath); err == nil && s.IsDir() { + return newPath, nil + } + + // TODO: remove go-homedir fallback in GitHub CLI v2 + if legacyDir, err := homedir.Dir(); err == nil { + legacyPath := filepath.Join(legacyDir, subdir) + if s, err := os.Stat(legacyPath); err == nil && s.IsDir() { + return legacyPath, nil + } + } + + return newPath, nil +} + +// Looks up the `~/.config/gh` directory with backwards-compatibility with go-homedir and auto-migration +// when an old homedir location was found. +func homeDirAutoMigrate() (string, error) { homeDir, err := os.UserHomeDir() if err != nil { + // TODO: remove go-homedir fallback in GitHub CLI v2 + if legacyDir, err := homedir.Dir(); err == nil { + return filepath.Join(legacyDir, ".config", "gh"), nil + } return "", err } - fullOldPath := filepath.Join(append([]string{oldHomeDir}, elem...)...) - fullPath := filepath.Join(append([]string{homeDir}, elem...)...) + newPath := filepath.Join(homeDir, ".config", "gh") + _, newPathErr := os.Stat(newPath) + if newPathErr == nil || !os.IsNotExist(err) { + return newPath, newPathErr + } - if fullOldPath != fullPath && len(elem) > 0 { - oldStat, err := os.Stat(fullOldPath) - if os.IsNotExist(err) && !oldStat.IsDir() { - return fullPath, nil + // TODO: remove go-homedir fallback in GitHub CLI v2 + if legacyDir, err := homedir.Dir(); err == nil { + legacyPath := filepath.Join(legacyDir, ".config", "gh") + if s, err := os.Stat(legacyPath); err == nil && s.IsDir() { + _ = os.MkdirAll(filepath.Dir(newPath), 0755) + return newPath, os.Rename(legacyPath, newPath) } - - err = os.Rename(fullOldPath, fullPath) - return fullPath, err } - return fullPath, err + + return newPath, nil } var ReadConfigFile = func(filename string) ([]byte, error) {