git-bug/repository/gogit_config.go

187 lines
4.1 KiB
Go
Raw Normal View History

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, ".")
if len(split) <= 1 {
return "", fmt.Errorf("invalid key")
}
sectionName := split[0]
if !cfg.Raw.HasSection(sectionName) {
return "", ErrNoConfigEntry
}
section := cfg.Raw.Section(sectionName)
switch {
case len(split) == 2:
optionName := split[1]
if !section.HasOption(optionName) {
return "", ErrNoConfigEntry
}
if len(section.OptionAll(optionName)) > 1 {
return "", ErrMultipleConfigEntry
}
return section.Option(optionName), nil
default:
subsectionName := strings.Join(split[1:len(split)-2], ".")
optionName := split[len(split)-1]
if !section.HasSubsection(subsectionName) {
return "", ErrNoConfigEntry
}
subsection := section.Subsection(subsectionName)
if !subsection.HasOption(optionName) {
return "", ErrNoConfigEntry
}
if len(subsection.OptionAll(optionName)) > 1 {
return "", ErrMultipleConfigEntry
}
return subsection.Option(optionName), 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, ".")
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 cfg.Raw.Section(section).HasOption(rest) {
cfg.Raw.Section(section).RemoveOption(rest)
} else {
return fmt.Errorf("invalid key prefix")
}
}
}
return ggc.repo.SetConfig(cfg)
}