diff --git a/internal/git/meta.go b/internal/git/meta.go index 0a13833c1a949c40b3beb1170043183276deed6d..52bb2628d2f79658a86719f50baa5458c87b0f90 100644 --- a/internal/git/meta.go +++ b/internal/git/meta.go @@ -7,60 +7,13 @@ "fmt" "io/fs" "os" "path/filepath" - "slices" ) // RepoMeta is the meta information a Repo can have type RepoMeta struct { - Description string `json:"description"` - Private bool `json:"private"` - Tags TagSet `json:"tags"` -} - -// TagSet is a Set of tags -type TagSet map[string]struct{} - -// Add adds a tag to the set -func (t TagSet) Add(tag string) { - t[tag] = struct{}{} -} - -// Remove removes a tag from the set -func (t TagSet) Remove(tag string) { - delete(t, tag) -} - -// Contains checks if a tag is in the set -func (t TagSet) Contains(tag string) bool { - _, ok := t[tag] - return ok -} - -// Slice returns the set as a (sorted) slice -func (t TagSet) Slice() []string { - s := make([]string, 0, len(t)) - for k := range t { - s = append(s, k) - } - slices.Sort(s) - return s -} - -// MarshalJSON implements [json.Marshaler] -func (t TagSet) MarshalJSON() ([]byte, error) { - return json.Marshal(t.Slice()) -} - -// UnmarshalJSON implements [json.Unmarshaler] -func (t *TagSet) UnmarshalJSON(b []byte) error { - var s []string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - for _, ss := range s { - t.Add(ss) - } - return nil + Description string `json:"description"` + Private bool `json:"private"` + Tags []string `json:"tags"` } // Update updates meta given another RepoMeta diff --git a/internal/git/meta_test.go b/internal/git/meta_test.go deleted file mode 100644 index e51c0298c9b1901e6f4a68786806c4eee09ffcb3..0000000000000000000000000000000000000000 --- a/internal/git/meta_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package git - -import ( - "encoding/json" - "testing" - - "github.com/alecthomas/assert/v2" -) - -func TestTagSet(t *testing.T) { - set := make(TagSet) - assert.Equal(t, 0, len(set)) - assert.Equal(t, 0, len(set.Slice())) - - set.Add("foo") - assert.Equal(t, 1, len(set)) - assert.Equal(t, 1, len(set.Slice())) - assert.True(t, set.Contains("foo")) - - set.Add("bar") - assert.Equal(t, 2, len(set)) - assert.Equal(t, 2, len(set.Slice())) - assert.True(t, set.Contains("foo")) - assert.True(t, set.Contains("bar")) - - set.Add("bar") - assert.Equal(t, 2, len(set)) - assert.Equal(t, 2, len(set.Slice())) - assert.True(t, set.Contains("foo")) - assert.True(t, set.Contains("bar")) - - set.Remove("foo") - assert.Equal(t, 1, len(set)) - assert.Equal(t, 1, len(set.Slice())) - assert.False(t, set.Contains("foo")) - assert.True(t, set.Contains("bar")) - - set.Add("foo") - set.Add("baz") - j, err := json.Marshal(set) - assert.NoError(t, err) - assert.Equal(t, `["bar","baz","foo"]`, string(j)) - - set = make(TagSet) - b := []byte(`["foo","bar","baz"]`) - err = json.Unmarshal(b, &set) - assert.NoError(t, err) - assert.Equal(t, 3, len(set)) - assert.Equal(t, 3, len(set.Slice())) - assert.True(t, set.Contains("foo")) - assert.True(t, set.Contains("bar")) - assert.True(t, set.Contains("baz")) -} diff --git a/internal/git/protocol.go b/internal/git/protocol.go index 287347dd7d4dce170b97cb2498dcbd8836efc007..02921bf105d91da66d9dd219726211dc4b19689e 100644 --- a/internal/git/protocol.go +++ b/internal/git/protocol.go @@ -58,11 +58,15 @@ if strings.HasPrefix(tagValue, "-") { remove = true tagValue = strings.TrimPrefix(tagValue, "-") } - tagValue = strings.ToLower(tagValue) - if remove { - repo.Meta.Tags.Remove(tagValue) - } else { - repo.Meta.Tags.Add(tagValue) + for idx, tag := range repo.Meta.Tags { + if strings.EqualFold(tag, tagValue) { + if remove { + repo.Meta.Tags = append(repo.Meta.Tags[:idx], repo.Meta.Tags[idx+1:]...) + } else { + repo.Meta.Tags = append(repo.Meta.Tags, strings.ToLower(tagValue)) + } + break + } } } } diff --git a/internal/html/index.go b/internal/html/index.go index 478cae2a081c35e39dcf2c2f2bb78dafe17897e7..621eaccaa7d50b5ed39eeffdc5704a1667049f19 100644 --- a/internal/html/index.go +++ b/internal/html/index.go @@ -92,7 +92,7 @@ ), ), ), Div(Class("sm:col-span-1 text-subtext0"), - Map(repo.Meta.Tags.Slice(), func(tag string) Node { + Map(repo.Meta.Tags, func(tag string) Node { return A(Class("rounded border-rosewater border-solid border pb-0.5 px-1 mr-1 mb-1 inline-block"), Href("?tag="+tag), Text(tag)) }), ), diff --git a/internal/http/http.go b/internal/http/http.go index b89b8242cf37a25d0bc34562822ffe750a7d53c2..61831c7051c147b8e613715421fbf37896802d6e 100644 --- a/internal/http/http.go +++ b/internal/http/http.go @@ -126,7 +126,7 @@ Description: repo.Meta.Description, Name: chi.URLParam(r, "repo"), Ref: ref, CloneURL: rh.s.CloneURL, - Tags: repo.Meta.Tags.Slice(), + Tags: repo.Meta.Tags, } } diff --git a/internal/http/index.go b/internal/http/index.go index ed752ab1db475fd6e1d086d415884d7f0cc2c3d9..aeac9f82d0d728edb887f6380ff35a93d23b303e 100644 --- a/internal/http/index.go +++ b/internal/http/index.go @@ -3,6 +3,7 @@ import ( "net/http" "os" + "slices" "sort" "strings" "time" @@ -33,10 +34,10 @@ if repo.Meta.Private { if !rh.s.ShowPrivate { continue } - repo.Meta.Tags.Add("private") + repo.Meta.Tags = append(repo.Meta.Tags, "private") } - if tagFilter != "" && !repo.Meta.Tags.Contains(strings.ToLower(tagFilter)) { + if tagFilter != "" && !slices.Contains(repo.Meta.Tags, strings.ToLower(tagFilter)) { continue } repos = append(repos, repo) diff --git a/internal/http/middleware.go b/internal/http/middleware.go index 2b40746e1a565a359c6a91781573f39393113746..b5c4ae002cc2c8d33b1b5b95c514174906e5f647 100644 --- a/internal/http/middleware.go +++ b/internal/http/middleware.go @@ -30,7 +30,7 @@ if repo.Meta.Private { if !rh.s.ShowPrivate { return httperr.Status(errors.New("could not get git repo"), http.StatusNotFound) } - repo.Meta.Tags.Add("private") + repo.Meta.Tags = append(repo.Meta.Tags, "private") } r = r.WithContext(context.WithValue(r.Context(), repoCtxKey, repo)) next.ServeHTTP(w, r)