From dbee0e8bd34107098c47c29aeff50155c3f44ab2440da16922db55023a16a13d Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Tue, 4 Feb 2025 14:24:38 +0100 Subject: [PATCH] submodules --- workflow-pr/submodules.go | 46 ++++++++++- workflow-pr/submodules_test.go | 135 ++++++++++++++++++++++++++------- 2 files changed, 154 insertions(+), 27 deletions(-) diff --git a/workflow-pr/submodules.go b/workflow-pr/submodules.go index 379d79d..841c7f9 100644 --- a/workflow-pr/submodules.go +++ b/workflow-pr/submodules.go @@ -12,6 +12,12 @@ import ( type Submodule struct { Name string Path string + Url string + + Update string + Branch string + Ignore string + Shallow string } var SyntaxError error = errors.New("Syntax error") @@ -51,7 +57,11 @@ func (sub *Submodule) parseSubmoduleName(line string) error { // return SyntaxError } - ch, _, err = r.ReadRune() + for ch, _, err = r.ReadRune(); unicode.IsSpace(ch); ch, _, err = r.ReadRune() { + if err != nil { + return fmt.Errorf("%d %w", 38, err) + } + } if ch != ']' || err != nil { return fmt.Errorf("%c %d, %w", ch, 50, err) @@ -86,6 +96,18 @@ func (s *Submodule) parseKeyValue(line string) error { switch key { case "path": s.Path = val + case "url": + s.Url = val + case "shallow": + s.Shallow = val + case "ignore": + s.Ignore = val + case "branch": + s.Branch = val + case "update": + s.Update = val + default: + return SyntaxError } return nil @@ -127,3 +149,25 @@ func ParseSubmodulesFile(reader io.Reader) ([]Submodule, error) { } return ret, nil } + +func writeValue(out io.Writer, key, value string) { + if len(value) > 0 { + out.Write([]byte(fmt.Sprintf("\t%s = %s\n", key, value))) + } +} + +func WriteSubmodules(subs []Submodule, out io.Writer) error { + for _, sub := range subs { + if len(sub.Name) < 1 { + return fmt.Errorf("Submodule with no name.") + } + out.Write([]byte(fmt.Sprintf("[submodule \"%s\"]\n", sub.Name))) + writeValue(out, "path", sub.Path) + writeValue(out, "url", sub.Url) + writeValue(out, "branch", sub.Branch) + writeValue(out, "ignore", sub.Ignore) + writeValue(out, "shallow", sub.Shallow) + writeValue(out, "update", sub.Update) + } + return nil +} diff --git a/workflow-pr/submodules_test.go b/workflow-pr/submodules_test.go index ef950d7..b9cc44b 100644 --- a/workflow-pr/submodules_test.go +++ b/workflow-pr/submodules_test.go @@ -1,12 +1,13 @@ package main import ( + "bytes" "slices" "strings" "testing" ) -func TestSubmodules(t *testing.T) { +func TestSubmodulesParsing(t *testing.T) { tests := []struct { name string file string @@ -65,31 +66,41 @@ func TestSubmodules(t *testing.T) { }, }, }, - /* - { - name: "Simple submodule", - file: `[submodule "libfoo"] - path = include/foo - url = git://foo.com/git/lib.git - - [submodule "libbar"] - path = include/bar - url = git://bar.com/git/lib.git`, - - subs: []Submodule{ - { - Name: "libfoo", - Path: "include/foo", - Url: "git://foo.com/git/lib.git", - }, - { - Name: "libbar", - Path: "include/bar", - Url: "git://bar.com/git/lib.git", - }, - }, - }, - */ + { + name: "Submodules with funny entries entries", + file: "[submodule \"libfoo\"]\npath = foo [ bar \n\n [ submodule \"test \" ]\npath=ma ma\nurl= safe", + subs: []Submodule{ + { + Name: "libfoo", + Path: "foo [ bar", + }, + { + Name: "test ", + Path: "ma ma", + Url: "safe", + }, + }, + }, + { + name: "Submodule with valid entries", + file: "[submodule \"libfoo\"]\npath=foo\nurl=goo\nupdate=none\nbranch=test\nignore=all\nshallow=true", + subs: []Submodule{ + { + Name: "libfoo", + Path: "foo", + Url: "goo", + Update: "none", + Branch: "test", + Ignore: "all", + Shallow: "true", + }, + }, + }, + { + name: "Submodule with an valid entry", + file: "[submodule \"libfoo\"]\npath=foo\nurl=goo\nupdate=none\nbranch=test\nignore=all\nshallow=true\nunknown = something", + has_error: true, + }, } for _, test := range tests { @@ -108,3 +119,75 @@ func TestSubmodules(t *testing.T) { }) } } + +func TestSubmodulesWriting(t *testing.T) { + tests := []struct { + name string + subs []Submodule + output []byte + has_error bool + }{ + { + name: "empty Submodules", + output: []byte(""), + }, + { + name: "single submodule", + subs: []Submodule{ + { + Name: "foo", + Url: "bar", + }, + }, + output: []byte("[submodule \"foo\"]\n\turl = bar\n"), + }, + { + name: "empty name submodule", + subs: []Submodule{ + { + Name: "foo", + Url: "bar", + }, + {}, + }, + has_error: true, + }, + { + name: "submodule with all the things", + subs: []Submodule{ + { + Name: "foo", + Url: "bar", + }, + { + Name: "1", + Url: "2", + Update: "ok", + Path: "3", + Branch: "4", + Ignore: "5", + Shallow: "6", + }, + }, + output: []byte("[submodule \"foo\"]\n\turl = bar\n[submodule \"1\"]\n\tpath = 3\n\turl = 2\n\tbranch = 4\n\tignore = 5\n\tshallow = 6\n\tupdate = ok\n"), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + out := bytes.Buffer{} + if err := WriteSubmodules(test.subs, &out); err != nil { + if !test.has_error { + t.Error(err) + } + return + } + if test.has_error { + t.Error("expected an error") + } + if !slices.Equal(out.Bytes(), test.output) { + t.Error("expected:", test.output, "but got:", out.Bytes()) + } + }) + } +}