aboutsummaryrefslogtreecommitdiffstats
path: root/storage/filesystem
diff options
context:
space:
mode:
authorSantiago M. Mola <santi@mola.io>2016-10-26 18:41:39 +0200
committerMáximo Cuadros <mcuadros@gmail.com>2016-10-26 16:41:39 +0000
commit61f0188edcea55dbcfa1c3a35da0c34fed10fd54 (patch)
tree08b59ecd20719f448d64073845bf40cf2d86fd7c /storage/filesystem
parent194da90f885d4cb7cf2bf4c84a74e5d559000764 (diff)
downloadgo-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')
-rw-r--r--storage/filesystem/config.go103
-rw-r--r--storage/filesystem/config_test.go47
2 files changed, 96 insertions, 54 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,
+ }
}
diff --git a/storage/filesystem/config_test.go b/storage/filesystem/config_test.go
index cbff1e0..20af595 100644
--- a/storage/filesystem/config_test.go
+++ b/storage/filesystem/config_test.go
@@ -1,7 +1,7 @@
package filesystem
import (
- "bytes"
+ "gopkg.in/src-d/go-git.v4/formats/config"
. "gopkg.in/check.v1"
)
@@ -10,31 +10,22 @@ type ConfigSuite struct{}
var _ = Suite(&ConfigSuite{})
-func (s *ConfigSuite) TestConfigFileDecode(c *C) {
- config := &ConfigFile{}
-
- err := config.Decode(bytes.NewBuffer(configFixture))
- c.Assert(err, IsNil)
-
- c.Assert(config.Remotes, HasLen, 2)
- c.Assert(config.Remotes["origin"].URL, Equals, "git@github.com:src-d/go-git.git")
- c.Assert(config.Remotes["origin"].Fetch, HasLen, 1)
- c.Assert(config.Remotes["origin"].Fetch[0].String(), Equals, "+refs/heads/*:refs/remotes/origin/*")
+func (s *ConfigSuite) TestParseRemote(c *C) {
+ remote := parseRemote(&config.Subsection{
+ Name: "origin",
+ Options: []*config.Option{
+ {
+ Key: "url",
+ Value: "git@github.com:src-d/go-git.git",
+ },
+ {
+ Key: "fetch",
+ Value: "+refs/heads/*:refs/remotes/origin/*",
+ },
+ },
+ })
+
+ c.Assert(remote.URL, Equals, "git@github.com:src-d/go-git.git")
+ c.Assert(remote.Fetch, HasLen, 1)
+ c.Assert(remote.Fetch[0].String(), Equals, "+refs/heads/*:refs/remotes/origin/*")
}
-
-var configFixture = []byte(`
-[core]
- repositoryformatversion = 0
- filemode = true
- bare = false
- logallrefupdates = true
-[remote "origin"]
- url = git@github.com:src-d/go-git.git
- fetch = +refs/heads/*:refs/remotes/origin/*
-[branch "v4"]
- remote = origin
- merge = refs/heads/v4
-[remote "mcuadros"]
- url = git@github.com:mcuadros/go-git.git
- fetch = +refs/heads/*:refs/remotes/mcuadros/*
-`)