diff options
author | Santiago M. Mola <santi@mola.io> | 2016-10-26 18:41:39 +0200 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2016-10-26 16:41:39 +0000 |
commit | 61f0188edcea55dbcfa1c3a35da0c34fed10fd54 (patch) | |
tree | 08b59ecd20719f448d64073845bf40cf2d86fd7c /storage/filesystem/config.go | |
parent | 194da90f885d4cb7cf2bf4c84a74e5d559000764 (diff) | |
download | go-git-61f0188edcea55dbcfa1c3a35da0c34fed10fd54.tar.gz |
formats/config: Added encoder/decoder for git config files. (#97)
* WIP: Add config format parser.
* add decoder based on gcfg.
Portions of code taken from:
https://github.com/go-gcfg/gcfg/blob/5b9f94ee80b2331c3982477bd84be8edd857df33/read.go
* add git config encoder and config methods.
* use format/config in storage/filesystem for read
* use format/config in storage/filesystem to write
* formats/config: improve docs.
* formats/config: improve tests.
* formats/config: use our fork of gcfg; improve api.
* formats/config: improve api.
* storage/filesystem: fix gofmt
* formats/config: use NoSubsection constant.
* formats/config: add doc.go
* formats/config: requested sytle changes.
* formats/config: do not use *_test packages.
Diffstat (limited to 'storage/filesystem/config.go')
-rw-r--r-- | storage/filesystem/config.go | 103 |
1 files changed, 77 insertions, 26 deletions
diff --git a/storage/filesystem/config.go b/storage/filesystem/config.go index 1cff05a..84252eb 100644 --- a/storage/filesystem/config.go +++ b/storage/filesystem/config.go @@ -1,58 +1,79 @@ package filesystem import ( - "fmt" - "io" - - "gopkg.in/gcfg.v1" "gopkg.in/src-d/go-git.v4/config" + gitconfig "gopkg.in/src-d/go-git.v4/formats/config" "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" ) +const ( + remoteSection = "remote" + fetchKey = "fetch" + urlKey = "url" +) + type ConfigStorage struct { dir *dotgit.DotGit } func (c *ConfigStorage) Remote(name string) (*config.RemoteConfig, error) { - file, err := c.read() + cfg, err := c.read() if err != nil { return nil, err } - r, ok := file.Remotes[name] - if ok { - return r, nil + s := cfg.Section(remoteSection).Subsection(name) + if s == nil { + return nil, config.ErrRemoteConfigNotFound } - return nil, config.ErrRemoteConfigNotFound + return parseRemote(s), nil } func (c *ConfigStorage) Remotes() ([]*config.RemoteConfig, error) { - file, err := c.read() + cfg, err := c.read() if err != nil { return nil, err } - remotes := make([]*config.RemoteConfig, len(file.Remotes)) - - var i int - for _, r := range file.Remotes { - remotes[i] = r + remotes := []*config.RemoteConfig{} + sect := cfg.Section(remoteSection) + for _, s := range sect.Subsections { + remotes = append(remotes, parseRemote(s)) } return remotes, nil } func (c *ConfigStorage) SetRemote(r *config.RemoteConfig) error { - return nil - return fmt.Errorf("set remote - not implemented yet") + cfg, err := c.read() + if err != nil { + return err + } + + s := cfg.Section(remoteSection).Subsection(r.Name) + s.Name = r.Name + s.SetOption(urlKey, r.URL) + s.RemoveOption(fetchKey) + for _, rs := range r.Fetch { + s.AddOption(fetchKey, rs.String()) + } + + return c.write(cfg) } func (c *ConfigStorage) DeleteRemote(name string) error { - return fmt.Errorf("delete - remote not implemented yet") + cfg, err := c.read() + if err != nil { + return err + } + + cfg = cfg.RemoveSubsection(remoteSection, name) + + return c.write(cfg) } -func (c *ConfigStorage) read() (*ConfigFile, error) { +func (c *ConfigStorage) read() (*gitconfig.Config, error) { f, err := c.dir.Config() if err != nil { return nil, err @@ -60,15 +81,45 @@ func (c *ConfigStorage) read() (*ConfigFile, error) { defer f.Close() - config := &ConfigFile{} - return config, config.Decode(f) + cfg := gitconfig.New() + d := gitconfig.NewDecoder(f) + err = d.Decode(cfg) + if err != nil { + return nil, err + } + + return cfg, nil } -type ConfigFile struct { - Remotes map[string]*config.RemoteConfig `gcfg:"remote"` +func (c *ConfigStorage) write(cfg *gitconfig.Config) error { + f, err := c.dir.Config() + if err != nil { + return err + } + + defer f.Close() + + e := gitconfig.NewEncoder(f) + err = e.Encode(cfg) + if err != nil { + return err + } + + return nil } -// Decode decode a git config file intro the ConfigStore -func (c *ConfigFile) Decode(r io.Reader) error { - return gcfg.FatalOnly(gcfg.ReadInto(c, r)) +func parseRemote(s *gitconfig.Subsection) *config.RemoteConfig { + fetch := []config.RefSpec{} + for _, f := range s.Options.GetAll(fetchKey) { + rs := config.RefSpec(f) + if rs.IsValid() { + fetch = append(fetch, rs) + } + } + + return &config.RemoteConfig{ + Name: s.Name, + URL: s.Option(urlKey), + Fetch: fetch, + } } |