Skip to content
Permalink
Browse files

String() of GitConfig is ready for saving file

Show content of config while ignore inherit and include settings:

    cfg.String()

Show all content of config:

    cfg.StringOfScope(ScopeAll)

Show system level config, with include settings:

    cfg.StringOfScope(ScopeSystem|ScopeInclude)

Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
  • Loading branch information...
jiangxin committed Mar 11, 2019
1 parent 784eaa8 commit feb3e92f752625e07e3627d5a951fc500cbba0bf
Showing with 227 additions and 10 deletions.
  1. +101 −1 git-config.go
  2. +117 −0 git-config_test.go
  3. +1 −1 goconfig.go
  4. +8 −8 load_test.go
@@ -1,6 +1,8 @@
package goconfig

import (
"fmt"
"reflect"
"sort"
"strconv"
"strings"
@@ -50,6 +52,17 @@ type GitConfigValue struct {
value string
}

// Keys returns sorted kesy in one section
func (v GitConfigKeys) Keys() []string {
keys := reflect.ValueOf(v).MapKeys()
strkeys := make([]string, len(keys))
for i := 0; i < len(keys); i++ {
strkeys[i] = keys[i].String()
}
sort.Strings(strkeys)
return strkeys
}

// Set is used to set value
func (v *GitConfigValue) Set(value string) {
v.value = value
@@ -71,6 +84,17 @@ func NewGitConfig() GitConfig {
return c
}

// Sections returns sorted sections
func (v GitConfig) Sections() []string {
keys := reflect.ValueOf(v).MapKeys()
strkeys := make([]string, len(keys))
for i := 0; i < len(keys); i++ {
strkeys[i] = keys[i].String()
}
sort.Strings(strkeys)
return strkeys
}

// Keys returns all config variable keys (in lower case)
func (v GitConfig) Keys() []string {
allKeys := []string{}
@@ -99,7 +123,11 @@ func (v GitConfig) _add(section, key, value string) {
if _, ok := v[section][key]; !ok {
v[section][key] = []*GitConfigValue{}
}
v[section][key] = append(v[section][key], &GitConfigValue{value: value})
v[section][key] = append(v[section][key],
&GitConfigValue{
scope: ScopeSelf,
value: value,
})
}

// Get value from key
@@ -236,3 +264,75 @@ func (v GitConfig) Merge(c GitConfig, scope Scope) GitConfig {
}
return v
}

// String returns content of GitConfig ready to save config file
func (v GitConfig) String() string {
return v.StringOfScope(ScopeSelf)
}

// StringOfScope returns contents with matching scope ready to save config file
func (v GitConfig) StringOfScope(scope Scope) string {
lines := []string{}
showInc := false
if scope&ScopeInclude != 0 {
showInc = true
scope &= (^ScopeInclude)
}

for _, s := range v.Sections() {
secs := strings.SplitN(s, ".", 2)
sec := s
if len(secs) == 2 {
sec = fmt.Sprintf("%s \"%s\"", secs[0], secs[1])
}
once := true
for _, k := range v[s].Keys() {
for _, value := range v[s][k] {
if !showInc && (value.scope&ScopeInclude != 0) {
continue
}
if (value.scope & (^ScopeInclude) & scope) == 0 {
continue
}

if once {
once = false
lines = append(lines, "["+sec+"]")
}
line := "\t" + k + " = "
quote := false
if isspace(value.value[0]) || isspace(value.value[len(value.value)-1]) {
quote = true
}
if quote {
line += "\""
}
for _, c := range value.value {
switch c {
case '\n':
line += "\\n"
continue
case '\t':
line += "\\t"
continue
case '\b':
line += "\\b"
continue
case '\\':
line += "\\"
case '"':
line += "\\"
}
line += string(c)
}
if quote {
line += "\""
}

lines = append(lines, line)
}
}

}
return strings.Join(lines, "\n") + "\n"
}
@@ -245,3 +245,120 @@ func ExampleMerge() {
// sect2.name1 = value-0.2.1 (system-inc)
// sect3.name1 = value-2.3.1 (global)
}

func TestGitConfigContent(t *testing.T) {
assert := assert.New(t)

data := `[ab "cd"]
value1 = x
value2 = x y
value3 = a \"quote
value4 = "has tailing spaces "
value5 = "has tailing tabs\t"
value6 = "has tailing eol\n"
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/tags/*:refs/tags/*
`
cfg, _, err := Parse([]byte(data), "filename")
assert.Nil(err)
assert.Equal(data, cfg.String())
}

func TestStringOfScope(t *testing.T) {
assert := assert.New(t)

sys := NewGitConfig()
sys.Add("sect1.Name1", "value-1.1.1")
sys.Add("sect1.Name2", "value-1.1.2")

inc1 := NewGitConfig()
inc1.Add("sect1.Name3", "value-0.1.3")
inc1.Add("sect2.name1", "value-0.2.1")

sys.Merge(inc1, ScopeInclude)

global := NewGitConfig()
global.Add("sect1.name2", "value-2.1.2")
global.Add("sect1.name3", "value-2.1.3")
global.Add("sect1.name4", "value-2.1.4")
global.Add("sect3.name1", "value-2.3.1")

repo := NewGitConfig()
repo.Add("sect1.name2", "value-3.1.2")
repo.Add("sect1.name3", "value-3.1.3")
repo.Add("sect1.name4", "value-3.1.4.1")
repo.Add("sect1.name4", "value-3.1.4.2")

all := NewGitConfig()
all.Merge(sys, ScopeSystem)
all.Merge(global, ScopeGlobal)
all.Merge(repo, ScopeSelf)

expect := `[sect1]
name2 = value-3.1.2
name3 = value-3.1.3
name4 = value-3.1.4.1
name4 = value-3.1.4.2
`
assert.Equal(expect, all.String())

expect = `[sect1]
name1 = value-1.1.1
name2 = value-1.1.2
name3 = value-0.1.3
[sect2]
name1 = value-0.2.1
`
assert.Equal(expect, all.StringOfScope(ScopeSystem|ScopeInclude))

expect = `[sect1]
name1 = value-1.1.1
name2 = value-1.1.2
`
assert.Equal(expect, all.StringOfScope(ScopeSystem))

expect = `[sect1]
name1 = value-1.1.1
name2 = value-1.1.2
name2 = value-2.1.2
name3 = value-2.1.3
name4 = value-2.1.4
[sect3]
name1 = value-2.3.1
`
assert.Equal(expect, all.StringOfScope(ScopeSystem|ScopeGlobal))

expect = `[sect1]
name1 = value-1.1.1
name2 = value-1.1.2
name2 = value-2.1.2
name2 = value-3.1.2
name3 = value-2.1.3
name3 = value-3.1.3
name4 = value-2.1.4
name4 = value-3.1.4.1
name4 = value-3.1.4.2
[sect3]
name1 = value-2.3.1
`
assert.Equal(expect, all.StringOfScope(ScopeSystem|ScopeGlobal|ScopeSelf))

expect = `[sect1]
name1 = value-1.1.1
name2 = value-1.1.2
name2 = value-2.1.2
name2 = value-3.1.2
name3 = value-0.1.3
name3 = value-2.1.3
name3 = value-3.1.3
name4 = value-2.1.4
name4 = value-3.1.4.1
name4 = value-3.1.4.2
[sect2]
name1 = value-0.2.1
[sect3]
name1 = value-2.3.1
`
assert.Equal(expect, all.StringOfScope(ScopeAll))
}
@@ -103,7 +103,7 @@ func (cf *parser) parse() (GitConfig, error) {
if err != nil {
return cfg, err
}
cfg.Merge(config, ScopeInclude)
cfg.Merge(config, ScopeSelf|ScopeInclude)
}
}
}
@@ -25,6 +25,7 @@ func TestSystemConfig(t *testing.T) {

cfgFile := filepath.Join(tmpdir, "test.config")
os.Setenv(gitSystemConfigEnv, cfgFile)
defer os.Unsetenv(gitSystemConfigEnv)

err = ioutil.WriteFile(cfgFile,
[]byte(`[test]
@@ -84,8 +85,6 @@ func TestSystemConfig(t *testing.T) {
func TestLoadGlobalConfig(t *testing.T) {
assert := assert.New(t)

home := os.Getenv("HOME")

tmpdir, err := ioutil.TempDir("", "goconfig")
if err != nil {
panic(err)
@@ -94,7 +93,9 @@ func TestLoadGlobalConfig(t *testing.T) {
os.RemoveAll(dir)
}(tmpdir)

home := os.Getenv("HOME")
os.Setenv("HOME", tmpdir)
defer os.Setenv("HOME", home)

cfg, err := GlobalConfig()
assert.Nil(err)
@@ -154,13 +155,10 @@ func TestLoadGlobalConfig(t *testing.T) {
assert.NotNil(cfg)
assert.Equal("user3", cfg.Get("user.name"))
assert.Equal("user3@email.addr", cfg.Get("user.email"))

os.Setenv("HOME", home)
}

func TestRepoConfig(t *testing.T) {
assert := assert.New(t)
home := os.Getenv("HOME")

tmpdir, err := ioutil.TempDir("", "goconfig")
if err != nil {
@@ -170,6 +168,7 @@ func TestRepoConfig(t *testing.T) {
os.RemoveAll(dir)
}(tmpdir)

home := os.Getenv("HOME")
os.Setenv("HOME", tmpdir)
defer os.Setenv("HOME", home)

@@ -244,6 +243,8 @@ func TestAllConfig(t *testing.T) {
// Create system config
sysCfgFile := filepath.Join(tmpdir, "system-config")
os.Setenv(gitSystemConfigEnv, sysCfgFile)
defer os.Unsetenv(gitSystemConfigEnv)

assert.Nil(exec.Command("git", "config", "-f", sysCfgFile, "test.key1", "sys 1").Run())
assert.Nil(exec.Command("git", "config", "-f", sysCfgFile, "test.key2", "sys 2").Run())
assert.Nil(exec.Command("git", "config", "-f", sysCfgFile, "test.key3", "sys 3").Run())
@@ -254,6 +255,8 @@ func TestAllConfig(t *testing.T) {
// Create user config
home := os.Getenv("HOME")
os.Setenv("HOME", tmpdir)
defer os.Setenv("HOME", home)

userCfgFile, err := globalConfigFile()
assert.Nil(err)
assert.Nil(exec.Command("git", "config", "-f", userCfgFile, "test.key2", "user 2").Run())
@@ -312,7 +315,4 @@ func TestAllConfig(t *testing.T) {
assert.Equal("repo 3", allConfig.Get("test.key3"))
assert.Equal("repo 4", allConfig.Get("test.key4"))
assert.Equal("repo 5", allConfig.Get("test.key5"))

os.Unsetenv(gitSystemConfigEnv)
os.Setenv("HOME", home)
}

0 comments on commit feb3e92

Please sign in to comment.
You can’t perform that action at this time.