aboutsummaryrefslogtreecommitdiffstats
path: root/repository/gogit_config.go
diff options
context:
space:
mode:
Diffstat (limited to 'repository/gogit_config.go')
-rw-r--r--repository/gogit_config.go175
1 files changed, 175 insertions, 0 deletions
diff --git a/repository/gogit_config.go b/repository/gogit_config.go
new file mode 100644
index 00000000..0f91b092
--- /dev/null
+++ b/repository/gogit_config.go
@@ -0,0 +1,175 @@
+package repository
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+ "time"
+
+ gogit "github.com/go-git/go-git/v5"
+ "github.com/go-git/go-git/v5/plumbing/format/config"
+)
+
+var _ Config = &goGitConfig{}
+
+type goGitConfig struct {
+ repo *gogit.Repository
+}
+
+func newGoGitConfig(repo *gogit.Repository) *goGitConfig {
+ return &goGitConfig{repo: repo}
+}
+
+func (ggc *goGitConfig) StoreString(key, value string) error {
+ cfg, err := ggc.repo.Config()
+ if err != nil {
+ return err
+ }
+
+ split := strings.Split(key, ".")
+
+ switch {
+ case len(split) <= 1:
+ return fmt.Errorf("invalid key")
+ case len(split) == 2:
+ cfg.Raw.Section(split[0]).SetOption(split[1], value)
+ default:
+ section := split[0]
+ subsection := strings.Join(split[1:len(split)-2], ".")
+ option := split[len(split)-1]
+ cfg.Raw.Section(section).Subsection(subsection).SetOption(option, value)
+ }
+
+ return ggc.repo.SetConfig(cfg)
+}
+
+func (ggc *goGitConfig) StoreTimestamp(key string, value time.Time) error {
+ return ggc.StoreString(key, strconv.Itoa(int(value.Unix())))
+}
+
+func (ggc *goGitConfig) StoreBool(key string, value bool) error {
+ return ggc.StoreString(key, strconv.FormatBool(value))
+}
+
+func (ggc *goGitConfig) ReadAll(keyPrefix string) (map[string]string, error) {
+ cfg, err := ggc.repo.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ split := strings.Split(keyPrefix, ".")
+
+ var opts config.Options
+
+ switch {
+ case len(split) < 1:
+ return nil, fmt.Errorf("invalid key prefix")
+ case len(split) == 1:
+ opts = cfg.Raw.Section(split[0]).Options
+ default:
+ section := split[0]
+ subsection := strings.Join(split[1:len(split)-1], ".")
+ opts = cfg.Raw.Section(section).Subsection(subsection).Options
+ }
+
+ if len(opts) == 0 {
+ return nil, fmt.Errorf("invalid section")
+ }
+
+ if keyPrefix[len(keyPrefix)-1:] != "." {
+ keyPrefix += "."
+ }
+
+ result := make(map[string]string, len(opts))
+ for _, opt := range opts {
+ result[keyPrefix+opt.Key] = opt.Value
+ }
+
+ return result, nil
+}
+
+func (ggc *goGitConfig) ReadBool(key string) (bool, error) {
+ val, err := ggc.ReadString(key)
+ if err != nil {
+ return false, err
+ }
+
+ return strconv.ParseBool(val)
+}
+
+func (ggc *goGitConfig) ReadString(key string) (string, error) {
+ cfg, err := ggc.repo.Config()
+ if err != nil {
+ return "", err
+ }
+
+ split := strings.Split(key, ".")
+
+ // TODO: return ErrNoConfigEntry and ErrMultipleConfigEntry
+ // Can use forked go-git: https://github.com/go-git/go-git/pull/112
+
+ switch {
+ case len(split) <= 1:
+ return "", fmt.Errorf("invalid key")
+ case len(split) == 2:
+ return cfg.Raw.Section(split[0]).Option(split[1]), nil
+ default:
+ section := split[0]
+ subsection := strings.Join(split[1:len(split)-2], ".")
+ option := split[len(split)-1]
+ return cfg.Raw.Section(section).Subsection(subsection).Option(option), nil
+ }
+}
+
+func (ggc *goGitConfig) ReadTimestamp(key string) (time.Time, error) {
+ value, err := ggc.ReadString(key)
+ if err != nil {
+ return time.Time{}, err
+ }
+ return ParseTimestamp(value)
+}
+
+func (ggc *goGitConfig) RemoveAll(keyPrefix string) error {
+ cfg, err := ggc.repo.Config()
+ if err != nil {
+ return err
+ }
+
+ split := strings.Split(keyPrefix, ".")
+
+ // missing in go-git
+ hasOption := func(options config.Options, key string) bool {
+ for _, option := range options {
+ if option.IsKey(key) {
+ return true
+ }
+ }
+ return false
+ }
+
+ switch {
+ case len(split) < 1:
+ return fmt.Errorf("invalid key prefix")
+ case len(split) == 1:
+ if len(cfg.Raw.Section(split[0]).Options) > 0 {
+ cfg.Raw.RemoveSection(split[0])
+ } else {
+ return fmt.Errorf("invalid key prefix")
+ }
+ default:
+ section := split[0]
+ rest := strings.Join(split[1:], ".")
+
+ if cfg.Raw.Section(section).HasSubsection(rest) {
+ cfg.Raw.RemoveSubsection(section, rest)
+ } else {
+ if hasOption(cfg.Raw.Section(section).Options, rest) {
+ cfg.Raw.Section(section).RemoveOption(rest)
+ } else {
+ return fmt.Errorf("invalid key prefix")
+ }
+ }
+ }
+
+ return ggc.repo.SetConfig(cfg)
+}