diff options
Diffstat (limited to 'config')
-rw-r--r-- | config/modules.go | 110 | ||||
-rw-r--r-- | config/modules_test.go | 70 |
2 files changed, 160 insertions, 20 deletions
diff --git a/config/modules.go b/config/modules.go index 3f095fa..6733884 100644 --- a/config/modules.go +++ b/config/modules.go @@ -1,20 +1,83 @@ package config -import "errors" +import ( + "bytes" + "errors" + + "gopkg.in/src-d/go-git.v4/plumbing/format/config" +) var ( ErrModuleEmptyURL = errors.New("module config: empty URL") ErrModuleEmptyPath = errors.New("module config: empty path") ) -const DefaultModuleBranch = "master" - // Modules defines the submodules properties -type Modules map[string]*Module +type Modules struct { + Submodules map[string]*Submodule + + raw *config.Config +} + +// NewModules returns a new empty Modules +func NewModules() *Modules { + return &Modules{ + Submodules: make(map[string]*Submodule, 0), + raw: config.New(), + } +} + +const ( + submoduleSection = "submodule" + pathKey = "path" + branchKey = "branch" +) + +// Unmarshal parses a git-config file and stores it +func (m *Modules) Unmarshal(b []byte) error { + r := bytes.NewBuffer(b) + d := config.NewDecoder(r) + + m.raw = config.New() + if err := d.Decode(m.raw); err != nil { + return err + } + + s := m.raw.Section(submoduleSection) + for _, sub := range s.Subsections { + mod := &Submodule{} + mod.unmarshal(sub) + + m.Submodules[mod.Path] = mod + } + + return nil +} + +// Marshal returns Modules encoded as a git-config file +func (m *Modules) Marshal() ([]byte, error) { + s := m.raw.Section(submoduleSection) + s.Subsections = make(config.Subsections, len(m.Submodules)) -// Module defines a submodule + var i int + for _, r := range m.Submodules { + s.Subsections[i] = r.marshal() + i++ + } + + buf := bytes.NewBuffer(nil) + if err := config.NewEncoder(buf).Encode(m.raw); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +// Submodule defines a submodule // https://www.kernel.org/pub/software/scm/git/docs/gitmodules.html -type Module struct { +type Submodule struct { + // Name module name + Name string // Path defines the path, relative to the top-level directory of the Git // working tree, Path string @@ -23,10 +86,12 @@ type Module struct { // Branch is a remote branch name for tracking updates in the upstream // submodule. Branch string + + raw *config.Subsection } // Validate validate the fields and set the default values -func (m *Module) Validate() error { +func (m *Submodule) Validate() error { if m.Path == "" { return ErrModuleEmptyPath } @@ -35,9 +100,34 @@ func (m *Module) Validate() error { return ErrModuleEmptyURL } - if m.Branch == "" { - m.Branch = DefaultModuleBranch + return nil +} + +func (m *Submodule) unmarshal(s *config.Subsection) { + m.raw = s + + m.Name = m.raw.Name + m.Path = m.raw.Option(pathKey) + m.URL = m.raw.Option(urlKey) + m.Branch = m.raw.Option(branchKey) +} + +func (m *Submodule) marshal() *config.Subsection { + if m.raw == nil { + m.raw = &config.Subsection{} } - return nil + m.raw.Name = m.Name + if m.raw.Name == "" { + m.raw.Name = m.Path + } + + m.raw.SetOption(pathKey, m.Path) + m.raw.SetOption(urlKey, m.URL) + + if m.Branch != "" { + m.raw.SetOption(branchKey, m.Branch) + } + + return m.raw } diff --git a/config/modules_test.go b/config/modules_test.go index 50b5691..34ad17c 100644 --- a/config/modules_test.go +++ b/config/modules_test.go @@ -2,22 +2,72 @@ package config import . "gopkg.in/check.v1" -type ModuleSuite struct{} +type ModulesSuite struct{} -var _ = Suite(&ModuleSuite{}) +var _ = Suite(&ModulesSuite{}) -func (s *ModuleSuite) TestModuleValidateMissingURL(c *C) { - m := &Module{Path: "foo"} +func (s *ModulesSuite) TestValidateMissingURL(c *C) { + m := &Submodule{Path: "foo"} c.Assert(m.Validate(), Equals, ErrModuleEmptyURL) } -func (s *ModuleSuite) TestModuleValidateMissingName(c *C) { - m := &Module{URL: "bar"} +func (s *ModulesSuite) TestValidateMissingName(c *C) { + m := &Submodule{URL: "bar"} c.Assert(m.Validate(), Equals, ErrModuleEmptyPath) } -func (s *ModuleSuite) TestModuleValidateDefault(c *C) { - m := &Module{Path: "foo", URL: "http://foo/bar"} - c.Assert(m.Validate(), IsNil) - c.Assert(m.Branch, Equals, DefaultModuleBranch) +func (s *ModulesSuite) TestMarshall(c *C) { + input := []byte(`[submodule "qux"] + path = qux + url = baz + branch = bar +`) + + cfg := NewModules() + cfg.Submodules["qux"] = &Submodule{Path: "qux", URL: "baz", Branch: "bar"} + + output, err := cfg.Marshal() + c.Assert(err, IsNil) + c.Assert(output, DeepEquals, input) +} + +func (s *ModulesSuite) TestUnmarshall(c *C) { + input := []byte(`[submodule "qux"] + path = qux + url = https://github.com/foo/qux.git +[submodule "foo/bar"] + path = foo/bar + url = https://github.com/foo/bar.git + branch = dev +`) + + cfg := NewModules() + err := cfg.Unmarshal(input) + c.Assert(err, IsNil) + + c.Assert(cfg.Submodules, HasLen, 2) + c.Assert(cfg.Submodules["qux"].Name, Equals, "qux") + c.Assert(cfg.Submodules["qux"].URL, Equals, "https://github.com/foo/qux.git") + c.Assert(cfg.Submodules["foo/bar"].Name, Equals, "foo/bar") + c.Assert(cfg.Submodules["foo/bar"].URL, Equals, "https://github.com/foo/bar.git") + c.Assert(cfg.Submodules["foo/bar"].Branch, Equals, "dev") +} + +func (s *ModulesSuite) TestUnmarshallMarshall(c *C) { + input := []byte(`[submodule "qux"] + path = qux + url = https://github.com/foo/qux.git +[submodule "foo/bar"] + path = foo/bar + url = https://github.com/foo/bar.git + ignore = all +`) + + cfg := NewModules() + err := cfg.Unmarshal(input) + c.Assert(err, IsNil) + + output, err := cfg.Marshal() + c.Assert(err, IsNil) + c.Assert(output, DeepEquals, input) } |