From 21988b514d67a69e80faabb0e71c168fe64c833a Mon Sep 17 00:00:00 2001 From: rick olson Date: Wed, 18 Oct 2017 12:22:45 -0600 Subject: [PATCH] move git config parsing to git pkg --- config/git_fetcher.go | 46 ++--------- git/config.go | 177 ++++++++++++++++++++++++++++++++++++++++++ git/git.go | 129 ------------------------------ 3 files changed, 182 insertions(+), 170 deletions(-) create mode 100644 git/config.go diff --git a/config/git_fetcher.go b/config/git_fetcher.go index aa2071c1..6ceda26e 100644 --- a/config/git_fetcher.go +++ b/config/git_fetcher.go @@ -16,19 +16,7 @@ type GitFetcher struct { vals map[string][]string } -type GitConfig struct { - Lines []string - OnlySafeKeys bool -} - -func NewGitConfig(gitconfiglines string, onlysafe bool) *GitConfig { - return &GitConfig{ - Lines: strings.Split(gitconfiglines, "\n"), - OnlySafeKeys: onlysafe, - } -} - -func ReadGitConfig(configs ...*GitConfig) (gf *GitFetcher, extensions map[string]Extension, uniqRemotes map[string]bool) { +func ReadGitConfig(configs ...*git.ConfigurationSource) (gf *GitFetcher, extensions map[string]Extension, uniqRemotes map[string]bool) { vals := make(map[string][]string) ignored := make([]string, 0) @@ -161,37 +149,13 @@ func (g *GitFetcher) All() map[string][]string { return newmap } -func getGitConfigs() (sources []*GitConfig) { - if lfsconfig := getFileGitConfig(".lfsconfig"); lfsconfig != nil { - sources = append(sources, lfsconfig) - } - - globalList, err := git.Config.List() - if err == nil { - sources = append(sources, NewGitConfig(globalList, false)) - } else { +func getGitConfigs() (sources []*git.ConfigurationSource) { + sources, err := git.Config.Sources(filepath.Join(LocalWorkingDir, ".lfsconfig")) + if err != nil { fmt.Fprintf(os.Stderr, "Error reading git config: %s\n", err) - } - - return -} - -func getFileGitConfig(basename string) *GitConfig { - fullname := filepath.Join(LocalWorkingDir, basename) - if _, err := os.Stat(fullname); err != nil { - if !os.IsNotExist(err) { - fmt.Fprintf(os.Stderr, "Error reading %s: %s\n", basename, err) - } return nil } - - lines, err := git.Config.ListFromFile(fullname) - if err == nil { - return NewGitConfig(lines, true) - } - - fmt.Fprintf(os.Stderr, "Error reading %s: %s\n", basename, err) - return nil + return sources } func keyIsUnsafe(key string) bool { diff --git a/git/config.go b/git/config.go new file mode 100644 index 00000000..b199c79e --- /dev/null +++ b/git/config.go @@ -0,0 +1,177 @@ +package git + +import ( + "os" + "strings" + "sync" + + "github.com/rubyist/tracerx" +) + +var Config = &Configuration{} + +// Configuration can fetch or modify the current Git config and track the Git +// version. +type Configuration struct { + version string + mu sync.Mutex +} + +func ParseConfigLines(lines string, onlySafeKeys bool) *ConfigurationSource { + return &ConfigurationSource{ + Lines: strings.Split(lines, "\n"), + OnlySafeKeys: onlySafeKeys, + } +} + +type ConfigurationSource struct { + Lines []string + OnlySafeKeys bool +} + +// Find returns the git config value for the key +func (c *Configuration) Find(val string) string { + output, _ := gitSimple("config", val) + return output +} + +// FindGlobal returns the git config value global scope for the key +func (c *Configuration) FindGlobal(val string) string { + output, _ := gitSimple("config", "--global", val) + return output +} + +// FindSystem returns the git config value in system scope for the key +func (c *Configuration) FindSystem(val string) string { + output, _ := gitSimple("config", "--system", val) + return output +} + +// Find returns the git config value for the key +func (c *Configuration) FindLocal(val string) string { + output, _ := gitSimple("config", "--local", val) + return output +} + +// SetGlobal sets the git config value for the key in the global config +func (c *Configuration) SetGlobal(key, val string) (string, error) { + return gitSimple("config", "--global", "--replace-all", key, val) +} + +// SetSystem sets the git config value for the key in the system config +func (c *Configuration) SetSystem(key, val string) (string, error) { + return gitSimple("config", "--system", "--replace-all", key, val) +} + +// UnsetGlobal removes the git config value for the key from the global config +func (c *Configuration) UnsetGlobal(key string) (string, error) { + return gitSimple("config", "--global", "--unset", key) +} + +// UnsetSystem removes the git config value for the key from the system config +func (c *Configuration) UnsetSystem(key string) (string, error) { + return gitSimple("config", "--system", "--unset", key) +} + +// UnsetGlobalSection removes the entire named section from the global config +func (c *Configuration) UnsetGlobalSection(key string) (string, error) { + return gitSimple("config", "--global", "--remove-section", key) +} + +// UnsetSystemSection removes the entire named section from the system config +func (c *Configuration) UnsetSystemSection(key string) (string, error) { + return gitSimple("config", "--system", "--remove-section", key) +} + +// UnsetLocalSection removes the entire named section from the system config +func (c *Configuration) UnsetLocalSection(key string) (string, error) { + return gitSimple("config", "--local", "--remove-section", key) +} + +// SetLocal sets the git config value for the key in the specified config file +func (c *Configuration) SetLocal(file, key, val string) (string, error) { + args := make([]string, 1, 6) + args[0] = "config" + if len(file) > 0 { + args = append(args, "--file", file) + } + args = append(args, "--replace-all", key, val) + return gitSimple(args...) +} + +// UnsetLocalKey removes the git config value for the key from the specified config file +func (c *Configuration) UnsetLocalKey(file, key string) (string, error) { + args := make([]string, 1, 5) + args[0] = "config" + if len(file) > 0 { + args = append(args, "--file", file) + } + args = append(args, "--unset", key) + return gitSimple(args...) +} + +func (c *Configuration) Sources(optionalFilename string) ([]*ConfigurationSource, error) { + gitconfig, err := c.Source() + if err != nil { + return nil, err + } + + fileconfig, err := c.FileSource(optionalFilename) + if err != nil && !os.IsNotExist(err) { + return nil, err + } + + configs := make([]*ConfigurationSource, 0, 2) + if fileconfig != nil { + configs = append(configs, fileconfig) + } + + return append(configs, gitconfig), nil +} + +func (c *Configuration) FileSource(filename string) (*ConfigurationSource, error) { + if _, err := os.Stat(filename); err != nil { + return nil, err + } + + out, err := gitSimple("config", "-l", "-f", filename) + if err != nil { + return nil, err + } + return ParseConfigLines(out, true), nil +} + +func (c *Configuration) Source() (*ConfigurationSource, error) { + out, err := gitSimple("config", "-l") + if err != nil { + return nil, err + } + return ParseConfigLines(out, false), nil +} + +// Version returns the git version +func (c *Configuration) Version() (string, error) { + c.mu.Lock() + defer c.mu.Unlock() + + if len(c.version) == 0 { + v, err := gitSimple("version") + if err != nil { + return v, err + } + c.version = v + } + + return c.version, nil +} + +// IsVersionAtLeast returns whether the git version is the one specified or higher +// argument is plain version string separated by '.' e.g. "2.3.1" but can omit minor/patch +func (c *Configuration) IsGitVersionAtLeast(ver string) bool { + gitver, err := c.Version() + if err != nil { + tracerx.Printf("Error getting git version: %v", err) + return false + } + return IsVersionAtLeast(gitver, ver) +} diff --git a/git/git.go b/git/git.go index 6bdd8239..a92dad09 100644 --- a/git/git.go +++ b/git/git.go @@ -16,7 +16,6 @@ import ( "regexp" "strconv" "strings" - "sync" "time" lfserrors "github.com/git-lfs/git-lfs/errors" @@ -293,7 +292,6 @@ func RemoteBranchForLocalBranch(localBranch string) string { } else { return localBranch } - } func RemoteList() ([]string, error) { @@ -462,133 +460,6 @@ func UpdateIndexFromStdin() *subprocess.Cmd { return git("update-index", "-q", "--refresh", "--stdin") } -// Configuration can fetch or modify the current Git config and track the Git -// version. -type Configuration struct { - version string - mu sync.Mutex -} - -var Config = &Configuration{} - -// Find returns the git config value for the key -func (c *Configuration) Find(val string) string { - output, _ := gitSimple("config", val) - return output -} - -// FindGlobal returns the git config value global scope for the key -func (c *Configuration) FindGlobal(val string) string { - output, _ := gitSimple("config", "--global", val) - return output -} - -// FindSystem returns the git config value in system scope for the key -func (c *Configuration) FindSystem(val string) string { - output, _ := gitSimple("config", "--system", val) - return output -} - -// Find returns the git config value for the key -func (c *Configuration) FindLocal(val string) string { - output, _ := gitSimple("config", "--local", val) - return output -} - -// SetGlobal sets the git config value for the key in the global config -func (c *Configuration) SetGlobal(key, val string) (string, error) { - return gitSimple("config", "--global", "--replace-all", key, val) -} - -// SetSystem sets the git config value for the key in the system config -func (c *Configuration) SetSystem(key, val string) (string, error) { - return gitSimple("config", "--system", "--replace-all", key, val) -} - -// UnsetGlobal removes the git config value for the key from the global config -func (c *Configuration) UnsetGlobal(key string) (string, error) { - return gitSimple("config", "--global", "--unset", key) -} - -// UnsetSystem removes the git config value for the key from the system config -func (c *Configuration) UnsetSystem(key string) (string, error) { - return gitSimple("config", "--system", "--unset", key) -} - -// UnsetGlobalSection removes the entire named section from the global config -func (c *Configuration) UnsetGlobalSection(key string) (string, error) { - return gitSimple("config", "--global", "--remove-section", key) -} - -// UnsetSystemSection removes the entire named section from the system config -func (c *Configuration) UnsetSystemSection(key string) (string, error) { - return gitSimple("config", "--system", "--remove-section", key) -} - -// UnsetLocalSection removes the entire named section from the system config -func (c *Configuration) UnsetLocalSection(key string) (string, error) { - return gitSimple("config", "--local", "--remove-section", key) -} - -// SetLocal sets the git config value for the key in the specified config file -func (c *Configuration) SetLocal(file, key, val string) (string, error) { - args := make([]string, 1, 6) - args[0] = "config" - if len(file) > 0 { - args = append(args, "--file", file) - } - args = append(args, "--replace-all", key, val) - return gitSimple(args...) -} - -// UnsetLocalKey removes the git config value for the key from the specified config file -func (c *Configuration) UnsetLocalKey(file, key string) (string, error) { - args := make([]string, 1, 5) - args[0] = "config" - if len(file) > 0 { - args = append(args, "--file", file) - } - args = append(args, "--unset", key) - return gitSimple(args...) -} - -// List lists all of the git config values -func (c *Configuration) List() (string, error) { - return gitSimple("config", "-l") -} - -// ListFromFile lists all of the git config values in the given config file -func (c *Configuration) ListFromFile(f string) (string, error) { - return gitSimple("config", "-l", "-f", f) -} - -// Version returns the git version -func (c *Configuration) Version() (string, error) { - c.mu.Lock() - defer c.mu.Unlock() - - if len(c.version) == 0 { - v, err := gitSimple("version") - if err != nil { - return v, err - } - c.version = v - } - - return c.version, nil -} - -// IsVersionAtLeast returns whether the git version is the one specified or higher -// argument is plain version string separated by '.' e.g. "2.3.1" but can omit minor/patch -func (c *Configuration) IsGitVersionAtLeast(ver string) bool { - gitver, err := c.Version() - if err != nil { - tracerx.Printf("Error getting git version: %v", err) - return false - } - return IsVersionAtLeast(gitver, ver) -} - // RecentBranches returns branches with commit dates on or after the given date/time // Return full Ref type for easier detection of duplicate SHAs etc // since: refs with commits on or after this date will be included