fork of go-git with some jj specific features
1package config
2
3import (
4 "os"
5 "path/filepath"
6 "strings"
7
8 "github.com/go-git/go-billy/v5/osfs"
9 "github.com/go-git/go-billy/v5/util"
10 "github.com/go-git/go-git/v5/plumbing"
11 . "gopkg.in/check.v1"
12)
13
14type ConfigSuite struct{}
15
16var _ = Suite(&ConfigSuite{})
17
18func (s *ConfigSuite) TestUnmarshal(c *C) {
19 input := []byte(`[core]
20 bare = true
21 worktree = foo
22 commentchar = bar
23[user]
24 name = John Doe
25 email = john@example.com
26[author]
27 name = Jane Roe
28 email = jane@example.com
29[committer]
30 name = Richard Roe
31 email = richard@example.com
32[pack]
33 window = 20
34[remote "origin"]
35 url = git@github.com:mcuadros/go-git.git
36 fetch = +refs/heads/*:refs/remotes/origin/*
37[remote "alt"]
38 url = git@github.com:mcuadros/go-git.git
39 url = git@github.com:src-d/go-git.git
40 fetch = +refs/heads/*:refs/remotes/origin/*
41 fetch = +refs/pull/*:refs/remotes/origin/pull/*
42[remote "insteadOf"]
43 url = https://github.com/kostyay/go-git.git
44[remote "win-local"]
45 url = X:\\Git\\
46[submodule "qux"]
47 path = qux
48 url = https://github.com/foo/qux.git
49 branch = bar
50[branch "master"]
51 remote = origin
52 merge = refs/heads/master
53 description = "Add support for branch description.\\n\\nEdit branch description: git branch --edit-description\\n"
54[init]
55 defaultBranch = main
56[url "ssh://git@github.com/"]
57 insteadOf = https://github.com/
58`)
59
60 cfg := NewConfig()
61 err := cfg.Unmarshal(input)
62 c.Assert(err, IsNil)
63
64 c.Assert(cfg.Core.IsBare, Equals, true)
65 c.Assert(cfg.Core.Worktree, Equals, "foo")
66 c.Assert(cfg.Core.CommentChar, Equals, "bar")
67 c.Assert(cfg.User.Name, Equals, "John Doe")
68 c.Assert(cfg.User.Email, Equals, "john@example.com")
69 c.Assert(cfg.Author.Name, Equals, "Jane Roe")
70 c.Assert(cfg.Author.Email, Equals, "jane@example.com")
71 c.Assert(cfg.Committer.Name, Equals, "Richard Roe")
72 c.Assert(cfg.Committer.Email, Equals, "richard@example.com")
73 c.Assert(cfg.Pack.Window, Equals, uint(20))
74 c.Assert(cfg.Remotes, HasLen, 4)
75 c.Assert(cfg.Remotes["origin"].Name, Equals, "origin")
76 c.Assert(cfg.Remotes["origin"].URLs, DeepEquals, []string{"git@github.com:mcuadros/go-git.git"})
77 c.Assert(cfg.Remotes["origin"].Fetch, DeepEquals, []RefSpec{"+refs/heads/*:refs/remotes/origin/*"})
78 c.Assert(cfg.Remotes["alt"].Name, Equals, "alt")
79 c.Assert(cfg.Remotes["alt"].URLs, DeepEquals, []string{"git@github.com:mcuadros/go-git.git", "git@github.com:src-d/go-git.git"})
80 c.Assert(cfg.Remotes["alt"].Fetch, DeepEquals, []RefSpec{"+refs/heads/*:refs/remotes/origin/*", "+refs/pull/*:refs/remotes/origin/pull/*"})
81 c.Assert(cfg.Remotes["win-local"].Name, Equals, "win-local")
82 c.Assert(cfg.Remotes["win-local"].URLs, DeepEquals, []string{"X:\\Git\\"})
83 c.Assert(cfg.Remotes["insteadOf"].URLs, DeepEquals, []string{"ssh://git@github.com/kostyay/go-git.git"})
84 c.Assert(cfg.Submodules, HasLen, 1)
85 c.Assert(cfg.Submodules["qux"].Name, Equals, "qux")
86 c.Assert(cfg.Submodules["qux"].URL, Equals, "https://github.com/foo/qux.git")
87 c.Assert(cfg.Submodules["qux"].Branch, Equals, "bar")
88 c.Assert(cfg.Branches["master"].Remote, Equals, "origin")
89 c.Assert(cfg.Branches["master"].Merge, Equals, plumbing.ReferenceName("refs/heads/master"))
90 c.Assert(cfg.Branches["master"].Description, Equals, "Add support for branch description.\n\nEdit branch description: git branch --edit-description\n")
91 c.Assert(cfg.Init.DefaultBranch, Equals, "main")
92}
93
94func (s *ConfigSuite) TestMarshal(c *C) {
95 output := []byte(`[core]
96 bare = true
97 worktree = bar
98[pack]
99 window = 20
100[remote "alt"]
101 url = git@github.com:mcuadros/go-git.git
102 url = git@github.com:src-d/go-git.git
103 fetch = +refs/heads/*:refs/remotes/origin/*
104 fetch = +refs/pull/*:refs/remotes/origin/pull/*
105[remote "insteadOf"]
106 url = https://github.com/kostyay/go-git.git
107[remote "origin"]
108 url = git@github.com:mcuadros/go-git.git
109[remote "win-local"]
110 url = "X:\\Git\\"
111[submodule "qux"]
112 url = https://github.com/foo/qux.git
113[branch "master"]
114 remote = origin
115 merge = refs/heads/master
116 description = "Add support for branch description.\\n\\nEdit branch description: git branch --edit-description\\n"
117[url "ssh://git@github.com/"]
118 insteadOf = https://github.com/
119[init]
120 defaultBranch = main
121`)
122
123 cfg := NewConfig()
124 cfg.Core.IsBare = true
125 cfg.Core.Worktree = "bar"
126 cfg.Pack.Window = 20
127 cfg.Init.DefaultBranch = "main"
128 cfg.Remotes["origin"] = &RemoteConfig{
129 Name: "origin",
130 URLs: []string{"git@github.com:mcuadros/go-git.git"},
131 }
132
133 cfg.Remotes["alt"] = &RemoteConfig{
134 Name: "alt",
135 URLs: []string{"git@github.com:mcuadros/go-git.git", "git@github.com:src-d/go-git.git"},
136 Fetch: []RefSpec{"+refs/heads/*:refs/remotes/origin/*", "+refs/pull/*:refs/remotes/origin/pull/*"},
137 }
138
139 cfg.Remotes["win-local"] = &RemoteConfig{
140 Name: "win-local",
141 URLs: []string{"X:\\Git\\"},
142 }
143
144 cfg.Remotes["insteadOf"] = &RemoteConfig{
145 Name: "insteadOf",
146 URLs: []string{"https://github.com/kostyay/go-git.git"},
147 }
148
149 cfg.Submodules["qux"] = &Submodule{
150 Name: "qux",
151 URL: "https://github.com/foo/qux.git",
152 }
153
154 cfg.Branches["master"] = &Branch{
155 Name: "master",
156 Remote: "origin",
157 Merge: "refs/heads/master",
158 Description: "Add support for branch description.\n\nEdit branch description: git branch --edit-description\n",
159 }
160
161 cfg.URLs["ssh://git@github.com/"] = &URL{
162 Name: "ssh://git@github.com/",
163 InsteadOf: "https://github.com/",
164 }
165
166 b, err := cfg.Marshal()
167 c.Assert(err, IsNil)
168
169 c.Assert(string(b), Equals, string(output))
170}
171
172func (s *ConfigSuite) TestUnmarshalMarshal(c *C) {
173 input := []byte(`[core]
174 bare = true
175 worktree = foo
176 custom = ignored
177[user]
178 name = John Doe
179 email = john@example.com
180[author]
181 name = Jane Roe
182 email = jane@example.com
183[committer]
184 name = Richard Roe
185 email = richard@example.co
186[pack]
187 window = 20
188[remote "insteadOf"]
189 url = https://github.com/kostyay/go-git.git
190[remote "origin"]
191 url = git@github.com:mcuadros/go-git.git
192 fetch = +refs/heads/*:refs/remotes/origin/*
193 mirror = true
194[remote "win-local"]
195 url = "X:\\Git\\"
196[branch "master"]
197 remote = origin
198 merge = refs/heads/master
199[url "ssh://git@github.com/"]
200 insteadOf = https://github.com/
201`)
202
203 cfg := NewConfig()
204 err := cfg.Unmarshal(input)
205 c.Assert(err, IsNil)
206
207 output, err := cfg.Marshal()
208 c.Assert(err, IsNil)
209 c.Assert(string(output), DeepEquals, string(input))
210}
211
212func (s *ConfigSuite) TestLoadConfigXDG(c *C) {
213 cfg := NewConfig()
214 cfg.User.Name = "foo"
215 cfg.User.Email = "foo@foo.com"
216
217 tmp, err := util.TempDir(osfs.Default, "", "test-commit-options")
218 c.Assert(err, IsNil)
219 defer util.RemoveAll(osfs.Default, tmp)
220
221 err = osfs.Default.MkdirAll(filepath.Join(tmp, "git"), 0777)
222 c.Assert(err, IsNil)
223
224 os.Setenv("XDG_CONFIG_HOME", tmp)
225 defer func() {
226 os.Setenv("XDG_CONFIG_HOME", "")
227 }()
228
229 content, err := cfg.Marshal()
230 c.Assert(err, IsNil)
231
232 cfgFile := filepath.Join(tmp, "git/config")
233 err = util.WriteFile(osfs.Default, cfgFile, content, 0777)
234 c.Assert(err, IsNil)
235
236 cfg, err = LoadConfig(GlobalScope)
237 c.Assert(err, IsNil)
238
239 c.Assert(cfg.User.Email, Equals, "foo@foo.com")
240}
241
242func (s *ConfigSuite) TestValidateConfig(c *C) {
243 config := &Config{
244 Remotes: map[string]*RemoteConfig{
245 "bar": {
246 Name: "bar",
247 URLs: []string{"http://foo/bar"},
248 },
249 },
250 Branches: map[string]*Branch{
251 "bar": {
252 Name: "bar",
253 },
254 "foo": {
255 Name: "foo",
256 Remote: "origin",
257 Merge: plumbing.ReferenceName("refs/heads/foo"),
258 },
259 },
260 }
261
262 c.Assert(config.Validate(), IsNil)
263}
264
265func (s *ConfigSuite) TestValidateInvalidRemote(c *C) {
266 config := &Config{
267 Remotes: map[string]*RemoteConfig{
268 "foo": {Name: "foo"},
269 },
270 }
271
272 c.Assert(config.Validate(), Equals, ErrRemoteConfigEmptyURL)
273}
274
275func (s *ConfigSuite) TestValidateInvalidRemoteKey(c *C) {
276 config := &Config{
277 Remotes: map[string]*RemoteConfig{
278 "bar": {Name: "foo"},
279 },
280 }
281
282 c.Assert(config.Validate(), Equals, ErrInvalid)
283}
284
285func (s *ConfigSuite) TestRemoteConfigValidateMissingURL(c *C) {
286 config := &RemoteConfig{Name: "foo"}
287 c.Assert(config.Validate(), Equals, ErrRemoteConfigEmptyURL)
288}
289
290func (s *ConfigSuite) TestRemoteConfigValidateMissingName(c *C) {
291 config := &RemoteConfig{}
292 c.Assert(config.Validate(), Equals, ErrRemoteConfigEmptyName)
293}
294
295func (s *ConfigSuite) TestRemoteConfigValidateDefault(c *C) {
296 config := &RemoteConfig{Name: "foo", URLs: []string{"http://foo/bar"}}
297 c.Assert(config.Validate(), IsNil)
298
299 fetch := config.Fetch
300 c.Assert(fetch, HasLen, 1)
301 c.Assert(fetch[0].String(), Equals, "+refs/heads/*:refs/remotes/foo/*")
302}
303
304func (s *ConfigSuite) TestValidateInvalidBranchKey(c *C) {
305 config := &Config{
306 Branches: map[string]*Branch{
307 "foo": {
308 Name: "bar",
309 Remote: "origin",
310 Merge: plumbing.ReferenceName("refs/heads/bar"),
311 },
312 },
313 }
314
315 c.Assert(config.Validate(), Equals, ErrInvalid)
316}
317
318func (s *ConfigSuite) TestValidateInvalidBranch(c *C) {
319 config := &Config{
320 Branches: map[string]*Branch{
321 "bar": {
322 Name: "bar",
323 Remote: "origin",
324 Merge: plumbing.ReferenceName("refs/heads/bar"),
325 },
326 "foo": {
327 Name: "foo",
328 Remote: "origin",
329 Merge: plumbing.ReferenceName("baz"),
330 },
331 },
332 }
333
334 c.Assert(config.Validate(), Equals, errBranchInvalidMerge)
335}
336
337func (s *ConfigSuite) TestRemoteConfigDefaultValues(c *C) {
338 config := NewConfig()
339
340 c.Assert(config.Remotes, HasLen, 0)
341 c.Assert(config.Branches, HasLen, 0)
342 c.Assert(config.Submodules, HasLen, 0)
343 c.Assert(config.Raw, NotNil)
344 c.Assert(config.Pack.Window, Equals, DefaultPackWindow)
345}
346
347func (s *ConfigSuite) TestLoadConfigLocalScope(c *C) {
348 cfg, err := LoadConfig(LocalScope)
349 c.Assert(err, NotNil)
350 c.Assert(cfg, IsNil)
351}
352
353func (s *ConfigSuite) TestRemoveUrlOptions(c *C) {
354 buf := []byte(`
355[remote "alt"]
356 url = git@github.com:mcuadros/go-git.git
357 url = git@github.com:src-d/go-git.git
358 fetch = +refs/heads/*:refs/remotes/origin/*
359 fetch = +refs/pull/*:refs/remotes/origin/pull/*`)
360
361 cfg := NewConfig()
362 err := cfg.Unmarshal(buf)
363 c.Assert(err, IsNil)
364 c.Assert(len(cfg.Remotes), Equals, 1)
365 cfg.Remotes["alt"].URLs = []string{}
366
367 buf, err = cfg.Marshal()
368 c.Assert(err, IsNil)
369 if strings.Contains(string(buf), "url") {
370 c.Fatal("config should not contain any url sections")
371 }
372 c.Assert(err, IsNil)
373}
374
375func (s *ConfigSuite) TestUnmarshalRemotes(c *C) {
376 input := []byte(`[core]
377 bare = true
378 worktree = foo
379 custom = ignored
380[user]
381 name = John Doe
382 email = john@example.com
383[remote "origin"]
384 url = https://git.sr.ht/~mcepl/go-git
385 pushurl = git@git.sr.ht:~mcepl/go-git.git
386 fetch = +refs/heads/*:refs/remotes/origin/*
387 mirror = true
388`)
389
390 cfg := NewConfig()
391 err := cfg.Unmarshal(input)
392 c.Assert(err, IsNil)
393
394 c.Assert(cfg.Remotes["origin"].URLs[0], Equals, "https://git.sr.ht/~mcepl/go-git")
395 c.Assert(cfg.Remotes["origin"].URLs[1], Equals, "git@git.sr.ht:~mcepl/go-git.git")
396}
397