diff --git a/api/handler.go b/api/handler.go index 5f533b8..690decb 100644 --- a/api/handler.go +++ b/api/handler.go @@ -355,3 +355,26 @@ func GetBranch(w http.ResponseWriter, r *http.Request) { } w.Write(b) } + +func GetTag(w http.ResponseWriter, r *http.Request) { + repo := r.URL.Query().Get(":name") + ref := r.URL.Query().Get("ref") + if repo == "" { + err := fmt.Errorf("Error when trying to obtain tags on ref %s of repository %s (repository is required).", ref, repo) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + tags, err := repository.GetTag(repo) + if err != nil { + err := fmt.Errorf("Error when trying to obtain tags on ref %s of repository %s (%s).", ref, repo, err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + b, err := json.Marshal(tags) + if err != nil { + err := fmt.Errorf("Error when trying to obtain tags on ref %s of repository %s (%s).", ref, repo, err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + w.Write(b) +} diff --git a/api/handler_test.go b/api/handler_test.go index b0a8e85..91ce3c1 100644 --- a/api/handler_test.go +++ b/api/handler_test.go @@ -1046,3 +1046,38 @@ func (s *S) TestGetBranchWhenCommandFails(c *gocheck.C) { c.Assert(recorder.Code, gocheck.Equals, http.StatusBadRequest) c.Assert(recorder.Body.String(), gocheck.Equals, "Error when trying to obtain the branches of repository repo (output error).\n") } + +func (s *S) TestGetTag(c *gocheck.C) { + url := "/repository/repo/tag?:name=repo" + tags := make([]map[string]string, 1) + tags[0] = make(map[string]string) + tags[0]["ref"] = "a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9" + tags[0]["name"] = "0.1" + tags[0]["commiterName"] = "doge" + tags[0]["commiterEmail"] = "" + tags[0]["authorName"] = "doge" + tags[0]["authorEmail"] = "" + tags[0]["subject"] = "will bark" + mockRetriever := repository.MockContentRetriever{ + Refs: tags, + } + repository.Retriever = &mockRetriever + defer func() { + repository.Retriever = nil + }() + request, err := http.NewRequest("GET", url, nil) + c.Assert(err, gocheck.IsNil) + recorder := httptest.NewRecorder() + GetTag(recorder, request) + c.Assert(recorder.Code, gocheck.Equals, http.StatusOK) + var obj []map[string]string + json.Unmarshal(recorder.Body.Bytes(), &obj) + c.Assert(len(obj), gocheck.Equals, 1) + c.Assert(obj[0]["ref"], gocheck.Equals, tags[0]["ref"]) + c.Assert(obj[0]["name"], gocheck.Equals, tags[0]["name"]) + c.Assert(obj[0]["commiterName"], gocheck.Equals, tags[0]["commiterName"]) + c.Assert(obj[0]["commiterEmail"], gocheck.Equals, tags[0]["commiterEmail"]) + c.Assert(obj[0]["authorName"], gocheck.Equals, tags[0]["authorName"]) + c.Assert(obj[0]["authorEmail"], gocheck.Equals, tags[0]["authorEmail"]) + c.Assert(obj[0]["subject"], gocheck.Equals, tags[0]["subject"]) +} diff --git a/repository/mocks.go b/repository/mocks.go index 0c814a7..59cbfbc 100644 --- a/repository/mocks.go +++ b/repository/mocks.go @@ -229,6 +229,16 @@ func CreateBranchesOnTestRepository(tmpPath string, repo string, branches ...str return err } +func CreateTag(testPath, tagname string) error { + gitPath, err := exec.LookPath("git") + if err != nil { + return err + } + cmd := exec.Command(gitPath, "tag", tagname) + cmd.Dir = testPath + return cmd.Run() +} + func (r *MockContentRetriever) GetTree(repo, ref, path string) ([]map[string]string, error) { if r.LookPathError != nil { return nil, r.LookPathError @@ -270,3 +280,13 @@ func (r *MockContentRetriever) GetDiff(repo, previousCommit, lastCommit string) } return r.ResultContents, nil } + +func (r *MockContentRetriever) GetTag(repo string) ([]map[string]string, error) { + if r.LookPathError != nil { + return nil, r.LookPathError + } + if r.OutputError != nil { + return nil, r.OutputError + } + return r.Refs, nil +} diff --git a/repository/repository.go b/repository/repository.go index 3b43464..b0eb965 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -252,6 +252,7 @@ type ContentRetriever interface { GetForEachRef(repo, pattern string) ([]map[string]string, error) GetBranch(repo string) ([]map[string]string, error) GetDiff(repo, lastCommit, previousCommit string) ([]byte, error) + GetTag(repo string) ([]map[string]string, error) } var Retriever ContentRetriever @@ -435,6 +436,11 @@ func (*GitContentRetriever) GetDiff(repo, previousCommit, lastCommit string) ([] return out, nil } +func (*GitContentRetriever) GetTag(repo string) ([]map[string]string, error) { + tags, err := retriever().GetForEachRef(repo, "refs/tags/") + return tags, err +} + func retriever() ContentRetriever { if Retriever == nil { Retriever = &GitContentRetriever{} @@ -469,3 +475,7 @@ func GetBranch(repo string) ([]map[string]string, error) { func GetDiff(repo, previousCommit, lastCommit string) ([]byte, error) { return retriever().GetDiff(repo, previousCommit, lastCommit) } + +func GetTag(repo string) ([]map[string]string, error) { + return retriever().GetTag(repo) +} diff --git a/repository/repository_test.go b/repository/repository_test.go index 55175ff..bae5a60 100644 --- a/repository/repository_test.go +++ b/repository/repository_test.go @@ -1065,3 +1065,40 @@ func (s *S) TestGetDiffIntegrationWhenInvalidCommit(c *gocheck.C) { _, err = GetDiff(repo, "12beu23eu23923ey32eiyeg2ye", string(firstHashCommit)) c.Assert(err.Error(), gocheck.Equals, fmt.Sprintf("Error when trying to obtain diff with commits %s and 12beu23eu23923ey32eiyeg2ye of repository %s (exit status 128).", firstHashCommit, repo)) } + +func (s *S) TestGetTagIntegration(c *gocheck.C) { + oldBare := bare + bare = "/tmp" + repo := "gandalf-test-repo-tags" + file := "README" + content := "much WOW" + cleanUp, errCreate := CreateTestRepository(bare, repo, file, content) + defer func() { + cleanUp() + bare = oldBare + }() + c.Assert(errCreate, gocheck.IsNil) + testPath := path.Join(bare, repo+".git") + errCreateTag := CreateTag(testPath, "0.1") + c.Assert(errCreateTag, gocheck.IsNil) + errCreateCommit := CreateCommit(bare, repo, "", "") + c.Assert(errCreateCommit, gocheck.IsNil) + errCreateTag = CreateTag(testPath, "0.2") + c.Assert(errCreateTag, gocheck.IsNil) + tags, err := GetTag(repo) + c.Assert(err, gocheck.IsNil) + c.Assert(tags[0]["ref"], gocheck.Matches, "[a-f0-9]{40}") + c.Assert(tags[0]["name"], gocheck.Equals, "0.1") + c.Assert(tags[0]["commiterName"], gocheck.Equals, "doge") + c.Assert(tags[0]["commiterEmail"], gocheck.Equals, "") + c.Assert(tags[0]["authorName"], gocheck.Equals, "doge") + c.Assert(tags[0]["authorEmail"], gocheck.Equals, "") + c.Assert(tags[0]["subject"], gocheck.Equals, "much WOW") + c.Assert(tags[1]["ref"], gocheck.Matches, "[a-f0-9]{40}") + c.Assert(tags[1]["name"], gocheck.Equals, "0.2") + c.Assert(tags[1]["commiterName"], gocheck.Equals, "doge") + c.Assert(tags[1]["commiterEmail"], gocheck.Equals, "") + c.Assert(tags[1]["authorName"], gocheck.Equals, "doge") + c.Assert(tags[1]["authorEmail"], gocheck.Equals, "") + c.Assert(tags[1]["subject"], gocheck.Equals, "") +} diff --git a/webserver/main.go b/webserver/main.go index f135fc7..88b0987 100644 --- a/webserver/main.go +++ b/webserver/main.go @@ -50,6 +50,7 @@ For an example conf check gandalf/etc/gandalf.conf file.\n %s` router.Get("/repository/:name/tree/:path", http.HandlerFunc(api.GetTree)) router.Get("/repository/:name/tree", http.HandlerFunc(api.GetTree)) router.Get("/repository/:name/branch", http.HandlerFunc(api.GetBranch)) + router.Get("/repository/:name/tag", http.HandlerFunc(api.GetTag)) router.Get("/healthcheck/", http.HandlerFunc(api.HealthCheck)) router.Post("/hook/:name", http.HandlerFunc(api.AddHook))