···44 "encoding/json"55 "fmt"66 "net/http"77+ "net/url"7889 "tangled.org/core/api/tangled"910 "tangled.org/core/appview/db"1011 "tangled.org/core/appview/models"1112 "tangled.org/core/appview/pages"1313+ "tangled.org/core/appview/reporesolver"1214 xrpcclient "tangled.org/core/appview/xrpcclient"1315 "tangled.org/core/orm"1416 "tangled.org/core/types"···103101104102 xrpcBytes, err := tangled.RepoTag(r.Context(), xrpcc, repo, tag)105103 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {106106- l.Error("failed to call XRPC repo.tags", "err", xrpcerr)104104+ // if we don't match an existing tag, and the tag we're trying105105+ // to match is "latest", resolve to the most recent tag106106+ if tag == "latest" {107107+ tagsBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 1, repo)108108+ if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {109109+ l.Error("failed to call XRPC repo.tags for latest", "err", xrpcerr)110110+ rp.pages.Error503(w)111111+ return112112+ }113113+ var tagsResult types.RepoTagsResponse114114+ if err := json.Unmarshal(tagsBytes, &tagsResult); err != nil {115115+ l.Error("failed to decode XRPC response", "err", err)116116+ rp.pages.Error503(w)117117+ return118118+ }119119+ if len(tagsResult.Tags) == 0 {120120+ rp.pages.Error503(w)121121+ return122122+ }123123+ latestTag := tagsResult.Tags[0].Name124124+ ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)125125+ http.Redirect(w, r, fmt.Sprintf("/%s/tags/%s", ownerSlashRepo, url.PathEscape(latestTag)), http.StatusTemporaryRedirect)126126+ return127127+ }128128+ l.Error("failed to call XRPC repo.tag", "err", xrpcerr)107129 rp.pages.Error503(w)108130 return109131 }
+21
knotserver/git/tag_test.go
···353353 assert.Len(s.T(), tags, 5, "zero limit should return all tags")354354}355355356356+func (s *TagSuite) TestTags_OrderedNewestFirst() {357357+ s.setupRepoWithTags()358358+359359+ tags, err := s.repo.Tags(nil)360360+ require.NoError(s.T(), err)361361+ require.Len(s.T(), tags, 5)362362+363363+ // v3.0.0 has the latest tagger date (baseTime+3h), should be first364364+ assert.Equal(s.T(), "v3.0.0", tags[0].Name, "newest tag should be first")365365+}366366+367367+func (s *TagSuite) TestTags_LatestWithLimit1() {368368+ s.setupRepoWithTags()369369+370370+ tags, err := s.repo.Tags(&TagsOptions{Limit: 1})371371+ require.NoError(s.T(), err)372372+ require.Len(s.T(), tags, 1)373373+374374+ assert.Equal(s.T(), "v3.0.0", tags[0].Name, "limit=1 should return the newest tag")375375+}376376+356377func (s *TagSuite) TestTags_Pattern() {357378 s.setupRepoWithTags()358379