Skip to content

Commit 241bf17

Browse files
authored
Merge pull request #52 from thatonecodes/config-file
feat: add configuration file support
2 parents e9aa1d2 + e7c25ee commit 241bf17

17 files changed

Lines changed: 1692 additions & 5 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,11 @@ ggc
188188
- `reset` - Reset and clean
189189
- `reset-clean` - Reset to HEAD and clean untracked files and directories
190190

191+
- `config` - Manage ggc configuration file
192+
- `config list` - List all variables in ggc configuration file
193+
- `config get <key>` - Get configuration variable from key
194+
- `config set <key> <value>` - Set configuration variable from key and value
195+
191196
- `tag` - List all tags
192197
- `tag list` - List all tags (sorted)
193198
- `tag list v1.*` - List tags matching pattern

cmd/cmd.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Executer interface {
2222
Push(args []string)
2323
Reset(args []string)
2424
Diff(args []string)
25+
Config(args []string)
2526
Version(args []string)
2627
Status(args []string)
2728
Tag(args []string)
@@ -47,6 +48,7 @@ type Cmd struct {
4748
remoteer *Remoteer
4849
rebaser *Rebaser
4950
stasher *Stasher
51+
configureer *Configureer
5052
tagger *Tagger
5153
statuseer *Statuseer
5254
versioneer *Versioneer
@@ -78,6 +80,7 @@ func NewCmd() *Cmd {
7880
remoteer: NewRemoteer(),
7981
rebaser: NewRebaser(),
8082
stasher: NewStasher(),
83+
configureer: NewConfigureer(),
8184
tagger: NewTagger(),
8285
statuseer: NewStatuseer(),
8386
versioneer: NewVersioneer(),
@@ -116,6 +119,11 @@ func (c *Cmd) Status(args []string) {
116119
c.statuseer.Status(args)
117120
}
118121

122+
// Config executes the status command with the given arguments.
123+
func (c *Cmd) Config(args []string) {
124+
c.configureer.Config(args)
125+
}
126+
119127
// Tag executes the tag command with the given arguments.
120128
func (c *Cmd) Tag(args []string) {
121129
c.tagger.Tag(args)
@@ -226,6 +234,8 @@ func (c *Cmd) Route(args []string) {
226234
c.rebaser.Rebase(args[1:])
227235
case "stash":
228236
c.stasher.Stash(args[1:])
237+
case "config":
238+
c.configureer.Config(args[1:])
229239
case "tag":
230240
c.tagger.Tag(args[1:])
231241
case "status":

cmd/config.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
"os/exec"
8+
"sort"
9+
"strconv"
10+
11+
"github.com/bmf-san/ggc/config"
12+
)
13+
14+
// Configureer handles config operations.
15+
type Configureer struct {
16+
outputWriter io.Writer
17+
helper *Helper
18+
execCommand func(string, ...string) *exec.Cmd
19+
}
20+
21+
// NewConfigureer creates a new Configureer instance.
22+
func NewConfigureer() *Configureer {
23+
return &Configureer{
24+
outputWriter: os.Stdout,
25+
helper: NewHelper(),
26+
execCommand: exec.Command,
27+
}
28+
}
29+
30+
// LoadConfig executes loads the configuration.
31+
func (c *Configureer) LoadConfig() *config.Manager {
32+
cm := config.NewConfigManager()
33+
if err := cm.Load(); err != nil {
34+
_, _ = fmt.Fprintf(c.outputWriter, "failed to load config: %s", err)
35+
return nil
36+
}
37+
return cm
38+
}
39+
40+
// Config executes config command operations with the given arguments.
41+
func (c *Configureer) Config(args []string) {
42+
if len(args) == 0 {
43+
c.helper.ShowConfigHelp()
44+
return
45+
}
46+
switch args[0] {
47+
case "list":
48+
cm := c.LoadConfig()
49+
configs := cm.List()
50+
51+
keys := make([]string, 0, len(configs))
52+
for key := range configs {
53+
keys = append(keys, key)
54+
}
55+
sort.Strings(keys)
56+
57+
for _, key := range keys {
58+
_, _ = fmt.Fprintf(c.outputWriter, "%-30s = %s\n", key, formatValue(configs[key]))
59+
}
60+
return
61+
case "get":
62+
if len(args) < 2 {
63+
_, _ = fmt.Fprintf(c.outputWriter, "must provide key to get (arg missing)\n")
64+
return
65+
}
66+
67+
cm := c.LoadConfig()
68+
69+
value, err := cm.Get(args[1])
70+
if err != nil {
71+
_, _ = fmt.Fprintf(c.outputWriter, "failed to get config value: %s", err)
72+
}
73+
74+
_, _ = fmt.Fprintf(c.outputWriter, "%s\n", formatValue(value))
75+
return
76+
case "set":
77+
if len(args) < 3 {
78+
_, _ = fmt.Fprintf(c.outputWriter, "must provide key && value to set (arg(s) missing)\n")
79+
return
80+
}
81+
82+
cm := c.LoadConfig()
83+
84+
value := parseValue(args[2])
85+
if err := cm.Set(args[1], value); err != nil {
86+
_, _ = fmt.Fprintf(c.outputWriter, "failed to set config value: %s", err)
87+
}
88+
89+
_, _ = fmt.Fprintf(c.outputWriter, "Set %s = %s\n", args[1], formatValue(value))
90+
return
91+
default:
92+
c.helper.ShowConfigHelp()
93+
return
94+
}
95+
}
96+
97+
func formatValue(value any) string {
98+
switch v := value.(type) {
99+
case string:
100+
return v
101+
case bool:
102+
return strconv.FormatBool(v)
103+
case int, int8, int16, int32, int64:
104+
return fmt.Sprintf("%d", v)
105+
case uint, uint8, uint16, uint32, uint64:
106+
return fmt.Sprintf("%d", v)
107+
case float32, float64:
108+
return fmt.Sprintf("%g", v)
109+
case map[string]any:
110+
return fmt.Sprintf("%v", v)
111+
default:
112+
return fmt.Sprintf("%v", v)
113+
}
114+
}
115+
116+
func parseValue(value string) any {
117+
if b, err := strconv.ParseBool(value); err == nil {
118+
return b
119+
}
120+
if i, err := strconv.ParseInt(value, 10, 64); err == nil {
121+
return i
122+
}
123+
if f, err := strconv.ParseFloat(value, 64); err == nil {
124+
return f
125+
}
126+
return value
127+
}

0 commit comments

Comments
 (0)