Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -838,16 +838,7 @@ func main() {
log.V(0).Info("unexpected stderr reading git config", "stdout", stdout, "stderr", stderr)
os.Exit(1)
} else {
cfgs := strings.Split(stdout, string(rune(0)))
kvs := funcr.PseudoStruct{} // like a map but ordered
for _, cfg := range cfgs {
if cfg == "" {
continue
}
parts := strings.SplitN(cfg, "\n", 2) // any additional newlines are part of the value
kvs = append(kvs, parts[0], parts[1])
}
log.V(0).Info("git config", "configs", kvs)
log.V(0).Info("git config", "configs", parseGitConfigList(stdout))
}

// The scope of the initialization context ends here, so we call cancel to release resources associated with it.
Expand Down Expand Up @@ -2324,6 +2315,26 @@ type keyVal struct {
val string
}

// parseGitConfigList parses the output of `git config list -z`. A key with no
// value (e.g. a bare `key` line, which git treats as boolean true) is printed
// without a newline, and is reported with a nil value.
func parseGitConfigList(stdout string) funcr.PseudoStruct {
cfgs := strings.Split(stdout, string(rune(0)))
kvs := funcr.PseudoStruct{} // like a map but ordered
for _, cfg := range cfgs {
if cfg == "" {
continue
}
parts := strings.SplitN(cfg, "\n", 2) // any additional newlines are part of the value
if len(parts) == 1 {
kvs = append(kvs, parts[0], nil)
continue
}
kvs = append(kvs, parts[0], parts[1])
}
return kvs
}

func parseGitConfigs(configsFlag string) ([]keyVal, error) {
// Use a channel as a FIFO. We don't expect the input strings to be very
// large, so this simple model should suffice.
Expand Down
48 changes: 48 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"testing"
"time"

"github.com/go-logr/logr/funcr"
"go.uber.org/goleak"
)

Expand Down Expand Up @@ -248,6 +249,53 @@ func TestParseGitConfigs(t *testing.T) {
}
}

func TestParseGitConfigList(t *testing.T) {
cases := []struct {
name string
input string
expect funcr.PseudoStruct
}{{
name: "empty",
input: "",
expect: funcr.PseudoStruct{},
}, {
name: "one-pair",
input: "k\nv\x00",
expect: funcr.PseudoStruct{"k", "v"},
}, {
name: "no-trailing-nul",
input: "k\nv",
expect: funcr.PseudoStruct{"k", "v"},
}, {
name: "empty-value",
input: "k\n\x00",
expect: funcr.PseudoStruct{"k", ""},
}, {
name: "multi-line-value",
input: "k\nline1\nline2\x00",
expect: funcr.PseudoStruct{"k", "line1\nline2"},
}, {
// `git config list -z` prints a key with no value (e.g. a bare `key`
// line, which git treats as boolean true) without a newline.
name: "no-value",
input: "k\x00",
expect: funcr.PseudoStruct{"k", nil},
}, {
name: "multiple",
input: "core.bare\nfalse\x00demo.bare\x00demo.empty\n\x00demo.multi\nline1\nline2\x00",
expect: funcr.PseudoStruct{"core.bare", "false", "demo.bare", nil, "demo.empty", "", "demo.multi", "line1\nline2"},
}}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
kvs := parseGitConfigList(tc.input)
if !reflect.DeepEqual(kvs, tc.expect) {
t.Errorf("bad result:\n\texpected: %#v\n\t got: %#v", tc.expect, kvs)
}
})
}
}

func TestDirIsEmpty(t *testing.T) {
root := absPath(t.TempDir())

Expand Down