Skip to content

Commit d6193d5

Browse files
authored
feat: return error exit codes and add windows fixes (#39)
1 parent 9f577f0 commit d6193d5

File tree

19 files changed

+496
-89
lines changed

19 files changed

+496
-89
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ module github.com/mikesmithgh/git-prompt-string
33
go 1.22.0
44

55
require github.com/pelletier/go-toml/v2 v2.1.1
6+
7+
require github.com/buildkite/shellwords v0.0.0-20180315110454-59467a9b8e10

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/buildkite/shellwords v0.0.0-20180315110454-59467a9b8e10 h1:XwHQ5xDtYPdtBbVPyRO6UZoWZe8/mbKUb076f8x7RvI=
2+
github.com/buildkite/shellwords v0.0.0-20180315110454-59467a9b8e10/go.mod h1:gv0DYOzHEsKgo31lTCDGauIg4DTTGn41Bzp+t3wSOlk=
13
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
24
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
35
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

integration/gps_test.go

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,81 @@
11
package integration
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
67
"os/exec"
78
"path/filepath"
8-
"runtime"
99
"testing"
1010
)
1111

1212
func TestGPS(t *testing.T) {
13-
var notFoundMsg string
14-
if runtime.GOOS == "windows" {
15-
notFoundMsg = "The system cannot find the path specified."
16-
} else {
17-
notFoundMsg = "no such file or directory"
18-
}
1913
tests := []struct {
2014
dir string
2115
input []string
2216
expected string
2317
environ []string
18+
err error
2419
}{
25-
{"bare", []string{"--config=NONE"}, "\x1b[90m \ue0a0 BARE:main\x1b[0m", nil},
26-
{"no_upstream", []string{"--config=NONE"}, "\x1b[90m \ue0a0 main\x1b[0m", nil},
27-
{"no_upstream_remote", []string{"--config=NONE"}, "\x1b[90m \ue0a0 main → mikesmithgh/test/main\x1b[0m", nil},
28-
{"git_dir", []string{"--config=NONE"}, "\x1b[90m \ue0a0 GIT_DIR!\x1b[0m", nil},
29-
{"clean", []string{"--config=NONE"}, "\x1b[32m \ue0a0 main\x1b[0m", nil},
30-
{"tag", []string{"--config=NONE"}, "\x1b[90m \ue0a0 (v1.0.0)\x1b[0m", nil},
31-
{"commit", []string{"--config=NONE"}, "\x1b[90m \ue0a0 (24afc95)\x1b[0m", nil},
32-
{"dirty", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main *\x1b[0m", nil},
33-
{"dirty_staged", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main *\x1b[0m", nil},
34-
{"conflict_ahead", []string{"--config=NONE"}, "\x1b[33m \ue0a0 main ↑[1]\x1b[0m", nil},
35-
{"conflict_behind", []string{"--config=NONE"}, "\x1b[33m \ue0a0 main ↓[1]\x1b[0m", nil},
36-
{"conflict_diverged", []string{"--config=NONE"}, "\x1b[33m \ue0a0 main ↕ ↑[1] ↓[1]\x1b[0m", nil},
37-
{"untracked", []string{"--config=NONE"}, "\x1b[35m \ue0a0 main *\x1b[0m", nil},
38-
{"sparse", []string{"--config=NONE"}, "\x1b[32m \ue0a0 main|SPARSE\x1b[0m", nil},
39-
{"sparse_merge_conflict", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|SPARSE|MERGING|CONFLICT *↕ ↑[1] ↓[1]\x1b[0m", nil},
20+
{"bare", []string{"--config=NONE"}, "\x1b[90m \ue0a0 BARE:main\x1b[0m", nil, nil},
21+
{"no_upstream", []string{"--config=NONE"}, "\x1b[90m \ue0a0 main\x1b[0m", nil, nil},
22+
{"no_upstream_remote", []string{"--config=NONE"}, "\x1b[90m \ue0a0 main → mikesmithgh/test/main\x1b[0m", nil, nil},
23+
{"git_dir", []string{"--config=NONE"}, "\x1b[90m \ue0a0 GIT_DIR!\x1b[0m", nil, nil},
24+
{"clean", []string{"--config=NONE"}, "\x1b[32m \ue0a0 main\x1b[0m", nil, nil},
25+
{"tag", []string{"--config=NONE"}, "\x1b[90m \ue0a0 (v1.0.0)\x1b[0m", nil, nil},
26+
{"commit", []string{"--config=NONE"}, "\x1b[90m \ue0a0 (24afc95)\x1b[0m", nil, nil},
27+
{"dirty", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main *\x1b[0m", nil, nil},
28+
{"dirty_staged", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main *\x1b[0m", nil, nil},
29+
{"conflict_ahead", []string{"--config=NONE"}, "\x1b[33m \ue0a0 main ↑[1]\x1b[0m", nil, nil},
30+
{"conflict_behind", []string{"--config=NONE"}, "\x1b[33m \ue0a0 main ↓[1]\x1b[0m", nil, nil},
31+
{"conflict_diverged", []string{"--config=NONE"}, "\x1b[33m \ue0a0 main ↕ ↑[1] ↓[1]\x1b[0m", nil, nil},
32+
{"untracked", []string{"--config=NONE"}, "\x1b[35m \ue0a0 main *\x1b[0m", nil, nil},
33+
{"sparse", []string{"--config=NONE"}, "\x1b[32m \ue0a0 main|SPARSE\x1b[0m", nil, nil},
34+
{"sparse_merge_conflict", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|SPARSE|MERGING|CONFLICT *↕ ↑[1] ↓[1]\x1b[0m", nil, nil},
4035

4136
// rebase merge
42-
{"rebase_i", []string{"--config=NONE"}, "\x1b[34m \ue0a0 main|REBASE-i 1/1\x1b[0m", nil},
43-
{"rebase_m", []string{"--config=NONE"}, "\x1b[34m \ue0a0 main|REBASE-m 1/1\x1b[0m", nil},
37+
{"rebase_i", []string{"--config=NONE"}, "\x1b[34m \ue0a0 main|REBASE-i 1/1\x1b[0m", nil, nil},
38+
{"rebase_m", []string{"--config=NONE"}, "\x1b[34m \ue0a0 main|REBASE-m 1/1\x1b[0m", nil, nil},
4439
// rebase apply
45-
{"am_rebase", []string{"--config=NONE"}, "\x1b[34m \ue0a0 (b69e688)|AM/REBASE 1/1\x1b[0m", nil},
46-
{"am", []string{"--config=NONE"}, "\x1b[34m \ue0a0 (b69e688)|AM 1/1\x1b[0m", nil},
47-
{"rebase", []string{"--config=NONE"}, "\x1b[34m \ue0a0 main|REBASE 1/1\x1b[0m", nil},
40+
{"am_rebase", []string{"--config=NONE"}, "\x1b[34m \ue0a0 (b69e688)|AM/REBASE 1/1\x1b[0m", nil, nil},
41+
{"am", []string{"--config=NONE"}, "\x1b[34m \ue0a0 (b69e688)|AM 1/1\x1b[0m", nil, nil},
42+
{"rebase", []string{"--config=NONE"}, "\x1b[34m \ue0a0 main|REBASE 1/1\x1b[0m", nil, nil},
4843
// merge
49-
{"merge_conflict", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|MERGING|CONFLICT *↕ ↑[1] ↓[1]\x1b[0m", nil},
50-
{"merge", []string{"--config=NONE"}, "\x1b[35m \ue0a0 main|MERGING *↕ ↑[1] ↓[1]\x1b[0m", nil},
44+
{"merge_conflict", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|MERGING|CONFLICT *↕ ↑[1] ↓[1]\x1b[0m", nil, nil},
45+
{"merge", []string{"--config=NONE"}, "\x1b[35m \ue0a0 main|MERGING *↕ ↑[1] ↓[1]\x1b[0m", nil, nil},
5146
// cherry pick
52-
{"cherry_pick_conflict", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|CHERRY-PICKING|CONFLICT *↕ ↑[1] ↓[1]\x1b[0m", nil},
53-
{"cherry_pick", []string{"--config=NONE"}, "\x1b[35m \ue0a0 main|CHERRY-PICKING *↕ ↑[1] ↓[1]\x1b[0m", nil},
47+
{"cherry_pick_conflict", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|CHERRY-PICKING|CONFLICT *↕ ↑[1] ↓[1]\x1b[0m", nil, nil},
48+
{"cherry_pick", []string{"--config=NONE"}, "\x1b[35m \ue0a0 main|CHERRY-PICKING *↕ ↑[1] ↓[1]\x1b[0m", nil, nil},
5449
// revert
55-
{"revert_conflict", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|REVERTING|CONFLICT *↕ ↑[2] ↓[1]\x1b[0m", nil},
56-
{"revert", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|REVERTING *↕ ↑[2] ↓[1]\x1b[0m", nil},
50+
{"revert_conflict", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|REVERTING|CONFLICT *↕ ↑[2] ↓[1]\x1b[0m", nil, nil},
51+
{"revert", []string{"--config=NONE"}, "\x1b[31m \ue0a0 main|REVERTING *↕ ↑[2] ↓[1]\x1b[0m", nil, nil},
5752
// bisect
58-
{"bisect", []string{"--config=NONE"}, "\x1b[34m \ue0a0 main|BISECTING ↓[1]\x1b[0m", nil},
53+
{"bisect", []string{"--config=NONE"}, "\x1b[34m \ue0a0 main|BISECTING ↓[1]\x1b[0m", nil, nil},
5954

6055
// formatting
61-
{"clean", []string{"--config=NONE", "--color-disabled"}, " \ue0a0 main", nil},
62-
{"clean", []string{"--config=NONE", "--color-disabled", "--prompt-prefix= start "}, " start main", nil},
63-
{"clean", []string{"--config=NONE", "--color-disabled", "--prompt-suffix= stop"}, " \ue0a0 main stop", nil},
64-
{"conflict_ahead", []string{"--config=NONE", "--color-disabled", "--ahead-format=ahead by %d"}, " \ue0a0 main ahead by 1", nil},
65-
{"conflict_behind", []string{"--config=NONE", "--color-disabled", "--behind-format=behind by %d"}, " \ue0a0 main behind by 1", nil},
66-
{"conflict_diverged", []string{"--config=NONE", "--color-disabled", "--diverged-format=ahead by %d behind by %d"}, " \ue0a0 main ahead by 1 behind by 1", nil},
67-
{"no_upstream_remote", []string{"--config=NONE", "--color-disabled", "--no-upstream-remote-format= upstream=[repo: %s branch: %s]"}, " \ue0a0 main upstream=[repo: mikesmithgh/test branch: main]", nil},
56+
{"clean", []string{"--config=NONE", "--color-disabled"}, " \ue0a0 main", nil, nil},
57+
{"clean", []string{"--config=NONE", "--color-disabled", "--prompt-prefix= start "}, " start main", nil, nil},
58+
{"clean", []string{"--config=NONE", "--color-disabled", "--prompt-suffix= stop"}, " \ue0a0 main stop", nil, nil},
59+
{"conflict_ahead", []string{"--config=NONE", "--color-disabled", "--ahead-format=ahead by %d"}, " \ue0a0 main ahead by 1", nil, nil},
60+
{"conflict_behind", []string{"--config=NONE", "--color-disabled", "--behind-format=behind by %d"}, " \ue0a0 main behind by 1", nil, nil},
61+
{"conflict_diverged", []string{"--config=NONE", "--color-disabled", "--diverged-format=ahead by %d behind by %d"}, " \ue0a0 main ahead by 1 behind by 1", nil, nil},
62+
{"no_upstream_remote", []string{"--config=NONE", "--color-disabled", "--no-upstream-remote-format= upstream=[repo: %s branch: %s]"}, " \ue0a0 main upstream=[repo: mikesmithgh/test branch: main]", nil, nil},
6863

6964
// color overrides
70-
{"clean", []string{"--config=../configs/color_overrides.toml"}, "\x1b[38;2;230;238;4m \ue0a0 main\x1b[0m", nil},
71-
{"no_upstream", []string{"--config=../configs/color_overrides.toml"}, "\x1b[30m\x1b[47m \ue0a0 main\x1b[0m", nil},
72-
{"dirty", []string{"--config=../configs/color_overrides.toml"}, "\x1b[48;2;179;5;89m \ue0a0 main *\x1b[0m", nil},
73-
{"conflict_ahead", []string{"--config=../configs/color_overrides.toml"}, "\x1b[38;2;252;183;40m \ue0a0 main ↑[1]\x1b[0m", nil},
74-
{"untracked", []string{"--config=../configs/color_overrides.toml"}, "\x1b[38;2;255;0;0m\x1b[48;2;22;242;170m \ue0a0 main *\x1b[0m", nil},
75-
{"bisect", []string{}, "\x1b[48;2;204;204;255m\x1b[35m \ue0a0 main|BISECTING ↓[1]\x1b[0m", []string{"GIT_PROMPT_STRING_CONFIG=../configs/color_overrides.toml"}},
65+
{"clean", []string{"--config=../configs/color_overrides.toml"}, "\x1b[38;2;230;238;4m \ue0a0 main\x1b[0m", nil, nil},
66+
{"no_upstream", []string{"--config=../configs/color_overrides.toml"}, "\x1b[30m\x1b[47m \ue0a0 main\x1b[0m", nil, nil},
67+
{"dirty", []string{"--config=../configs/color_overrides.toml"}, "\x1b[48;2;179;5;89m \ue0a0 main *\x1b[0m", nil, nil},
68+
{"conflict_ahead", []string{"--config=../configs/color_overrides.toml"}, "\x1b[38;2;252;183;40m \ue0a0 main ↑[1]\x1b[0m", nil, nil},
69+
{"untracked", []string{"--config=../configs/color_overrides.toml"}, "\x1b[38;2;255;0;0m\x1b[48;2;22;242;170m \ue0a0 main *\x1b[0m", nil, nil},
70+
{"bisect", []string{}, "\x1b[48;2;204;204;255m\x1b[35m \ue0a0 main|BISECTING ↓[1]\x1b[0m", []string{"GIT_PROMPT_STRING_CONFIG=../configs/color_overrides.toml"}, nil},
7671

7772
// config errors
78-
{"clean", []string{"--config=/fromparam/does/not/exist"}, fmt.Sprintf("\x1b[31m git-prompt-string error(read config): open /fromparam/does/not/exist: %s\x1b[0m", notFoundMsg), nil},
79-
{"configs", []string{}, fmt.Sprintf("\x1b[31m git-prompt-string error(read config): open /fromenvvar/does/not/exist: %s\x1b[0m", notFoundMsg), []string{"GIT_PROMPT_STRING_CONFIG=/fromenvvar/does/not/exist"}},
80-
{"configs", []string{"--config=invalid_syntax.toml"}, "\x1b[31m git-prompt-string error(unmarshal config): toml: expected character =\x1b[0m", nil},
81-
{"configs", []string{}, "\x1b[31m git-prompt-string error(unmarshal config): toml: expected character =\x1b[0m", []string{"GIT_PROMPT_STRING_CONFIG=invalid_syntax.toml"}},
73+
{"clean", []string{"--config=/fromparam/does/not/exist"}, fmt.Sprintf("\x1b[31m git-prompt-string error(read config): \"open /fromparam/does/not/exist: %s\"\x1b[0m", notFoundMsg), nil, errors.New("exit status 1")},
74+
{"configs", []string{}, fmt.Sprintf("\x1b[31m git-prompt-string error(read config): \"open /fromenvvar/does/not/exist: %s\"\x1b[0m", notFoundMsg), []string{"GIT_PROMPT_STRING_CONFIG=/fromenvvar/does/not/exist"}, errors.New("exit status 1")},
75+
{"configs", []string{"--config=invalid_syntax.toml"}, fmt.Sprintf("\x1b[31m git-prompt-string error(unmarshal config): \"toml: expected character %s\"\x1b[0m", escapedEqualSign), nil, errors.New("exit status 1")},
76+
{"configs", []string{}, fmt.Sprintf("\x1b[31m git-prompt-string error(unmarshal config): \"toml: expected character %s\"\x1b[0m", escapedEqualSign), []string{"GIT_PROMPT_STRING_CONFIG=invalid_syntax.toml"}, errors.New("exit status 1")},
8277

83-
{"norepo", []string{"--config=NONE"}, "", nil},
78+
{"norepo", []string{"--config=NONE"}, "", nil, nil},
8479
}
8580

8681
for _, test := range tests {
@@ -91,8 +86,10 @@ func TestGPS(t *testing.T) {
9186
cmd.Env = append(cmd.Env, test.environ...)
9287
}
9388
result, err := cmd.CombinedOutput()
94-
if err != nil {
89+
if test.err == nil && err != nil {
9590
t.Errorf("Unexpected error: %s", err)
91+
} else if test.err != nil && test.err.Error() != err.Error() {
92+
t.Errorf("Expected error: %s, got: %s", test.err, err)
9693
}
9794
actual := string(result)
9895
if actual != test.expected {

integration/init_test.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"os"
66
"os/exec"
77
"path/filepath"
8-
"runtime"
98
"testing"
109
)
1110

@@ -22,19 +21,16 @@ func TestMain(m *testing.M) {
2221
}
2322
defer os.RemoveAll(tmpDir)
2423

25-
gps := "git-prompt-string"
26-
if runtime.GOOS == "windows" {
27-
gps += ".exe"
28-
}
29-
builtBinaryPath = filepath.Join(tmpDir, gps)
24+
builtBinaryPath = filepath.Join(tmpDir, git_prompt_string_bin)
3025

3126
cmd := exec.Command("go", "build", "-o", builtBinaryPath, "..")
3227
output, err := cmd.CombinedOutput()
3328
if err != nil {
3429
panic(fmt.Sprintf("failed to build gps: %s, %s", output, err))
3530
}
3631

37-
cmd = exec.Command("cp", "-r", "../testdata", tmpDir)
32+
copyCommand, copyArgs := copyTestDataCmd("..", tmpDir)
33+
cmd = exec.Command(copyCommand, copyArgs...)
3834
err = cmd.Run()
3935
if err != nil {
4036
panic(fmt.Sprintf("failed to copy test data: %s", err))

integration/init_unix.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//go:build !windows
2+
3+
package integration
4+
5+
import "path/filepath"
6+
7+
var (
8+
notFoundMsg string = "no such file or directory"
9+
git_prompt_string_bin string = "git-prompt-string"
10+
escapedEqualSign string = "\\="
11+
)
12+
13+
func copyTestDataCmd(src string, dest string) (string, []string) {
14+
return "cp", []string{"-r", filepath.Join(src, "testdata"), dest}
15+
}

integration/init_windows.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package integration
2+
3+
import "path/filepath"
4+
5+
var (
6+
notFoundMsg string = "The system cannot find the path specified."
7+
git_prompt_string_bin string = "git-prompt-string.exe"
8+
escapedEqualSign string = "^="
9+
)
10+
11+
func copyTestDataCmd(src string, dest string) (string, []string) {
12+
return "xcopy", []string{"/S", "/E", "/I", filepath.Join(src, "testdata"), filepath.Join(dest, "testdata")}
13+
}

main.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"flag"
55
"fmt"
66
"os"
7+
"os/exec"
78
"path"
8-
"runtime"
99
"strconv"
1010
"strings"
1111

@@ -38,6 +38,7 @@ var (
3838
)
3939

4040
func main() {
41+
// TODO: check if git is installed?
4142
cfg := config.GPSConfig{
4243
PromptPrefix: *promptPrefix,
4344
PromptSuffix: *promptSuffix,
@@ -68,30 +69,26 @@ func main() {
6869
if xdgConfigHome == "" {
6970
home, err := os.UserHomeDir()
7071
if err != nil {
71-
util.ErrMsg("user home", err, 0)
72-
}
73-
if runtime.GOOS == "windows" {
74-
xdgConfigHome = path.Join(home, "AppData", "Local")
75-
} else {
76-
xdgConfigHome = path.Join(home, ".config")
72+
util.ErrMsg("user home", err)
7773
}
74+
xdgConfigHome = path.Join(home, util.XDGConfigPath)
7875
}
7976
gpsConfig = path.Join(xdgConfigHome, "git-prompt-string", "config.toml")
8077
}
8178

8279
if gpsConfig != "NONE" {
8380
gpsConfigRaw, err := os.ReadFile(gpsConfig)
8481
if err != nil && !os.IsNotExist(err) {
85-
util.ErrMsg("read config exists", err, 0)
82+
util.ErrMsg("read config exists", err)
8683
}
8784

8885
if err != nil && (*configPath != "" || gpsConfigEnv != "") {
89-
util.ErrMsg("read config", err, 0)
86+
util.ErrMsg("read config", err)
9087
}
9188

9289
err = toml.Unmarshal(gpsConfigRaw, &cfg)
9390
if err != nil {
94-
util.ErrMsg("unmarshal config", err, 0)
91+
util.ErrMsg("unmarshal config", err)
9592
}
9693
}
9794

@@ -112,7 +109,7 @@ func main() {
112109
case "color-disabled":
113110
colorDisabled, err := strconv.ParseBool(f.Value.String())
114111
if err != nil {
115-
util.ErrMsg("parse color disabled", err, 0)
112+
util.ErrMsg("parse color disabled", err)
116113
}
117114
cfg.ColorDisabled = colorDisabled
118115
case "color-clean":
@@ -147,24 +144,28 @@ func main() {
147144

148145
clearColor, err := color.Color("none")
149146
if err != nil {
150-
util.ErrMsg("color none", err, 0)
147+
util.ErrMsg("color none", err)
151148
}
152149

153150
gitRepo, stderr, err := git.RevParse()
154151
if err != nil {
155-
if strings.Contains(string(stderr), "not a git repository") {
152+
switch {
153+
case strings.Contains(err.Error(), exec.ErrNotFound.Error()):
154+
util.ErrMsg("rev parse", err)
155+
case strings.Contains(string(stderr), "not a git repository"):
156156
os.Exit(0)
157+
default:
158+
// allow other errors to pass through, the git repo may not have upstream
157159
}
158-
// allow other errors to pass through, the git repo may not have upstream
159160
}
160161

161162
branchInfo, err := gitRepo.BranchInfo(cfg)
162163
if err != nil {
163-
util.ErrMsg("branch info", err, 0)
164+
util.ErrMsg("branch info", err)
164165
}
165166
branchStatus, promptColor, err := gitRepo.BranchStatus(cfg)
166167
if err != nil {
167-
util.ErrMsg("branch status", err, 0)
168+
util.ErrMsg("branch status", err)
168169
}
169170

170171
fmt.Printf("%s%s%s%s%s%s", promptColor, cfg.PromptPrefix, branchInfo, branchStatus, cfg.PromptSuffix, clearColor)

0 commit comments

Comments
 (0)