Imported Upstream version 2.4.0
[scm/test.git] / git / config.go
1 package git
2
3 import (
4         "os"
5         "path/filepath"
6         "strings"
7         "sync"
8
9         "github.com/git-lfs/git-lfs/subprocess"
10 )
11
12 // Configuration can fetch or modify the current Git config and track the Git
13 // version.
14 type Configuration struct {
15         WorkDir string
16         GitDir  string
17         version *string
18         mu      sync.Mutex
19 }
20
21 func NewConfig(workdir, gitdir string) *Configuration {
22         if len(gitdir) == 0 && len(workdir) > 0 {
23                 gitdir = filepath.Join(workdir, ".git")
24         }
25         return &Configuration{WorkDir: workdir, GitDir: gitdir}
26 }
27
28 func ParseConfigLines(lines string, onlySafeKeys bool) *ConfigurationSource {
29         return &ConfigurationSource{
30                 Lines:        strings.Split(lines, "\n"),
31                 OnlySafeKeys: onlySafeKeys,
32         }
33 }
34
35 type ConfigurationSource struct {
36         Lines        []string
37         OnlySafeKeys bool
38 }
39
40 // Find returns the git config value for the key
41 func (c *Configuration) Find(val string) string {
42         output, _ := c.gitConfig(val)
43         return output
44 }
45
46 // FindGlobal returns the git config value global scope for the key
47 func (c *Configuration) FindGlobal(key string) string {
48         output, _ := c.gitConfig("--global", key)
49         return output
50 }
51
52 // FindSystem returns the git config value in system scope for the key
53 func (c *Configuration) FindSystem(key string) string {
54         output, _ := c.gitConfig("--system", key)
55         return output
56 }
57
58 // Find returns the git config value for the key
59 func (c *Configuration) FindLocal(key string) string {
60         output, _ := c.gitConfig("--local", key)
61         return output
62 }
63
64 // SetGlobal sets the git config value for the key in the global config
65 func (c *Configuration) SetGlobal(key, val string) (string, error) {
66         return c.gitConfig("--global", "--replace-all", key, val)
67 }
68
69 // SetSystem sets the git config value for the key in the system config
70 func (c *Configuration) SetSystem(key, val string) (string, error) {
71         return c.gitConfig("--system", "--replace-all", key, val)
72 }
73
74 // UnsetGlobalSection removes the entire named section from the global config
75 func (c *Configuration) UnsetGlobalSection(key string) (string, error) {
76         return c.gitConfig("--global", "--remove-section", key)
77 }
78
79 // UnsetSystemSection removes the entire named section from the system config
80 func (c *Configuration) UnsetSystemSection(key string) (string, error) {
81         return c.gitConfig("--system", "--remove-section", key)
82 }
83
84 // UnsetLocalSection removes the entire named section from the system config
85 func (c *Configuration) UnsetLocalSection(key string) (string, error) {
86         return c.gitConfig("--local", "--remove-section", key)
87 }
88
89 // SetLocal sets the git config value for the key in the specified config file
90 func (c *Configuration) SetLocal(key, val string) (string, error) {
91         return c.gitConfig("--replace-all", key, val)
92 }
93
94 // UnsetLocalKey removes the git config value for the key from the specified config file
95 func (c *Configuration) UnsetLocalKey(key string) (string, error) {
96         return c.gitConfig("--unset", key)
97 }
98
99 func (c *Configuration) Sources(optionalFilename string) ([]*ConfigurationSource, error) {
100         gitconfig, err := c.Source()
101         if err != nil {
102                 return nil, err
103         }
104
105         fileconfig, err := c.FileSource(optionalFilename)
106         if err != nil && !os.IsNotExist(err) {
107                 return nil, err
108         }
109
110         configs := make([]*ConfigurationSource, 0, 2)
111         if fileconfig != nil {
112                 configs = append(configs, fileconfig)
113         }
114
115         return append(configs, gitconfig), nil
116 }
117
118 func (c *Configuration) FileSource(filename string) (*ConfigurationSource, error) {
119         if _, err := os.Stat(filename); err != nil {
120                 return nil, err
121         }
122
123         out, err := c.gitConfig("-l", "-f", filename)
124         if err != nil {
125                 return nil, err
126         }
127         return ParseConfigLines(out, true), nil
128 }
129
130 func (c *Configuration) Source() (*ConfigurationSource, error) {
131         out, err := c.gitConfig("-l")
132         if err != nil {
133                 return nil, err
134         }
135         return ParseConfigLines(out, false), nil
136 }
137
138 func (c *Configuration) gitConfig(args ...string) (string, error) {
139         args = append([]string{"config"}, args...)
140         subprocess.Trace("git", args...)
141         cmd := subprocess.ExecCommand("git", args...)
142         if len(c.GitDir) > 0 {
143                 cmd.Dir = c.GitDir
144         }
145         return subprocess.Output(cmd)
146 }