git-lfs/git/config.go

188 lines
4.9 KiB
Go
Raw Normal View History

2017-10-18 18:22:45 +00:00
package git
import (
"os"
"path/filepath"
2017-10-18 18:22:45 +00:00
"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 {
WorkDir string
GitDir string
2017-10-18 18:22:45 +00:00
version string
mu sync.Mutex
}
func NewConfig(workdir, gitdir string) *Configuration {
if len(gitdir) == 0 && len(workdir) > 0 {
gitdir = filepath.Join(workdir, ".git")
}
return &Configuration{WorkDir: workdir, GitDir: gitdir}
}
2017-10-18 18:22:45 +00:00
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, _ := c.git("config", val)
2017-10-18 18:22:45 +00:00
return output
}
// FindGlobal returns the git config value global scope for the key
2017-10-18 18:52:24 +00:00
func (c *Configuration) FindGlobal(key string) string {
output, _ := c.git("config", "--global", key)
2017-10-18 18:22:45 +00:00
return output
}
// FindSystem returns the git config value in system scope for the key
2017-10-18 18:52:24 +00:00
func (c *Configuration) FindSystem(key string) string {
output, _ := c.git("config", "--system", key)
2017-10-18 18:22:45 +00:00
return output
}
// Find returns the git config value for the key
2017-10-18 18:52:24 +00:00
func (c *Configuration) FindLocal(key string) string {
output, _ := c.git("config", "--local", key)
2017-10-18 18:22:45 +00:00
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 c.git("config", "--global", "--replace-all", key, val)
2017-10-18 18:22:45 +00:00
}
// SetSystem sets the git config value for the key in the system config
func (c *Configuration) SetSystem(key, val string) (string, error) {
return c.git("config", "--system", "--replace-all", key, val)
2017-10-18 18:22:45 +00:00
}
// UnsetGlobalSection removes the entire named section from the global config
func (c *Configuration) UnsetGlobalSection(key string) (string, error) {
return c.git("config", "--global", "--remove-section", key)
2017-10-18 18:22:45 +00:00
}
// UnsetSystemSection removes the entire named section from the system config
func (c *Configuration) UnsetSystemSection(key string) (string, error) {
return c.git("config", "--system", "--remove-section", key)
2017-10-18 18:22:45 +00:00
}
// UnsetLocalSection removes the entire named section from the system config
func (c *Configuration) UnsetLocalSection(key string) (string, error) {
return c.git("config", "--local", "--remove-section", key)
2017-10-18 18:22:45 +00:00
}
// 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, 0, 5)
2017-10-18 18:22:45 +00:00
if len(file) > 0 {
args = append(args, "--file", file)
}
return c.git("config", append(args, "--replace-all", key, val)...)
2017-10-18 18:22:45 +00:00
}
// 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, 0, 4)
2017-10-18 18:22:45 +00:00
if len(file) > 0 {
args = append(args, "--file", file)
}
return c.git("config", append(args, "--unset", key)...)
2017-10-18 18:22:45 +00:00
}
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 := c.git("config", "-l", "-f", filename)
2017-10-18 18:22:45 +00:00
if err != nil {
return nil, err
}
return ParseConfigLines(out, true), nil
}
func (c *Configuration) Source() (*ConfigurationSource, error) {
out, err := c.git("config", "-l")
2017-10-18 18:22:45 +00:00
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)
}
func (c *Configuration) git(subcmd string, args ...string) (string, error) {
cmd := make([]string, 1, len(args)+3)
cmd[0] = subcmd
if len(c.GitDir) > 0 {
cmd = append(cmd, "--git-dir", c.GitDir)
}
if len(c.WorkDir) > 0 {
cmd = append(cmd, "--work-tree", c.WorkDir)
}
return gitSimple(append(cmd, args...)...)
}