From a00bbd0b72d7a879b08f75c7b637afcdea576585 Mon Sep 17 00:00:00 2001 From: David Dansby <39511285+DataDavD@users.noreply.github.com> Date: Thu, 29 Jul 2021 22:52:20 -0700 Subject: [PATCH 1/4] Add/Update Branch and Tag "Name" field This commit renames the "BranchName" field to "Name" for the RepositoryBranchOptions and adds the "Name" RepositoryTagOptions to allow for deleting branch and tags with the same option struct types. --- bitbucket.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bitbucket.go b/bitbucket.go index 257b2b1..afdd261 100644 --- a/bitbucket.go +++ b/bitbucket.go @@ -215,14 +215,14 @@ type RepositoryRefOptions struct { } type RepositoryBranchOptions struct { - Owner string `json:"owner"` - RepoSlug string `json:"repo_slug"` - Query string `json:"query"` - Sort string `json:"sort"` - PageNum int `json:"page"` - Pagelen int `json:"pagelen"` - MaxDepth int `json:"max_depth"` - BranchName string `json:"branch_name"` + Owner string `json:"owner"` + RepoSlug string `json:"repo_slug"` + Query string `json:"query"` + Sort string `json:"sort"` + PageNum int `json:"page"` + Pagelen int `json:"pagelen"` + MaxDepth int `json:"max_depth"` + Name string `json:"name"` } type RepositoryBranchCreationOptions struct { @@ -252,6 +252,7 @@ type RepositoryTagOptions struct { PageNum int `json:"page"` Pagelen int `json:"pagelen"` MaxDepth int `json:"max_depth"` + Name string `json:"name"` } type RepositoryTagCreationOptions struct { From 0ec6e04e48d478929f159b6b090bda720c17df2d Mon Sep 17 00:00:00 2001 From: David Dansby <39511285+DataDavD@users.noreply.github.com> Date: Thu, 29 Jul 2021 23:10:07 -0700 Subject: [PATCH 2/4] Add Delete Tag and Branch methods; rename repo tag options var to rto This commit creates the delete tag and branch methods. It also renames the repo tag options variable name from rbo to rto for code readability and understanding. This repo also renames the BranchName field references to Name. --- repository.go | 61 ++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/repository.go b/repository.go index 805df96..589ba80 100644 --- a/repository.go +++ b/repository.go @@ -366,10 +366,10 @@ func (r *Repository) ListBranches(rbo *RepositoryBranchOptions) (*RepositoryBran } func (r *Repository) GetBranch(rbo *RepositoryBranchOptions) (*RepositoryBranch, error) { - if rbo.BranchName == "" { + if rbo.Name == "" { return nil, errors.New("Error: Branch Name is empty") } - urlStr := r.c.requestUrl("/repositories/%s/%s/refs/branches/%s", rbo.Owner, rbo.RepoSlug, rbo.BranchName) + urlStr := r.c.requestUrl("/repositories/%s/%s/refs/branches/%s", rbo.Owner, rbo.RepoSlug, rbo.Name) response, err := r.c.executeRaw("GET", urlStr, "") if err != nil { return nil, err @@ -382,21 +382,6 @@ func (r *Repository) GetBranch(rbo *RepositoryBranchOptions) (*RepositoryBranch, return decodeRepositoryBranch(bodyString) } -// DeleteBranch https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/refs/branches/%7Bname%7D#delete -func (r *Repository) DeleteBranch(rbo *RepositoryBranchDeleteOptions) error { - repo := rbo.RepoSlug - if rbo.RepoUUID != "" { - repo = rbo.RepoUUID - } - ref := rbo.RefName - if rbo.RefUUID != "" { - ref = rbo.RefUUID - } - urlStr := r.c.requestUrl("/repositories/%s/%s/refs/branches/%s", rbo.Owner, repo, ref) - _, err := r.c.execute("DELETE", urlStr, "") - return err -} - func (r *Repository) CreateBranch(rbo *RepositoryBranchCreationOptions) (*RepositoryBranch, error) { urlStr := r.c.requestUrl("/repositories/%s/%s/refs/branches", rbo.Owner, rbo.RepoSlug) data, err := r.buildBranchBody(rbo) @@ -418,30 +403,36 @@ func (r *Repository) CreateBranch(rbo *RepositoryBranchCreationOptions) (*Reposi return decodeRepositoryBranchCreated(bodyString) } -func (r *Repository) ListTags(rbo *RepositoryTagOptions) (*RepositoryTags, error) { +func (r *Repository) DeleteBranch(rbo *RepositoryBranchOptions) (interface{}, error) { + urlStr := r.c.requestUrl("/repositories/%s/%s/refs/branches/%s", rbo.Owner, rbo.RepoSlug, + rbo.Name) + return r.c.execute("DELETE", urlStr, "") +} + +func (r *Repository) ListTags(rto *RepositoryTagOptions) (*RepositoryTags, error) { params := url.Values{} - if rbo.Query != "" { - params.Add("q", rbo.Query) + if rto.Query != "" { + params.Add("q", rto.Query) } - if rbo.Sort != "" { - params.Add("sort", rbo.Sort) + if rto.Sort != "" { + params.Add("sort", rto.Sort) } - if rbo.PageNum > 0 { - params.Add("page", strconv.Itoa(rbo.PageNum)) + if rto.PageNum > 0 { + params.Add("page", strconv.Itoa(rto.PageNum)) } - if rbo.Pagelen > 0 { - params.Add("pagelen", strconv.Itoa(rbo.Pagelen)) + if rto.Pagelen > 0 { + params.Add("pagelen", strconv.Itoa(rto.Pagelen)) } - if rbo.MaxDepth > 0 { - params.Add("max_depth", strconv.Itoa(rbo.MaxDepth)) + if rto.MaxDepth > 0 { + params.Add("max_depth", strconv.Itoa(rto.MaxDepth)) } - urlStr := r.c.requestUrl("/repositories/%s/%s/refs/tags?%s", rbo.Owner, rbo.RepoSlug, params.Encode()) + urlStr := r.c.requestUrl("/repositories/%s/%s/refs/tags?%s", rto.Owner, rto.RepoSlug, params.Encode()) response, err := r.c.executeRaw("GET", urlStr, "") if err != nil { return nil, err @@ -454,9 +445,9 @@ func (r *Repository) ListTags(rbo *RepositoryTagOptions) (*RepositoryTags, error return decodeRepositoryTags(bodyString) } -func (r *Repository) CreateTag(rbo *RepositoryTagCreationOptions) (*RepositoryTag, error) { - urlStr := r.c.requestUrl("/repositories/%s/%s/refs/tags", rbo.Owner, rbo.RepoSlug) - data, err := r.buildTagBody(rbo) +func (r *Repository) CreateTag(rto *RepositoryTagCreationOptions) (*RepositoryTag, error) { + urlStr := r.c.requestUrl("/repositories/%s/%s/refs/tags", rto.Owner, rto.RepoSlug) + data, err := r.buildTagBody(rto) if err != nil { return nil, err } @@ -475,6 +466,12 @@ func (r *Repository) CreateTag(rbo *RepositoryTagCreationOptions) (*RepositoryTa return decodeRepositoryTagCreated(bodyString) } +func (r *Repository) DeleteTag(rto *RepositoryTagOptions) (interface{}, error) { + urlStr := r.c.requestUrl("/repositories/%s/%s/refs/tags/%s", rto.Owner, rto.RepoSlug, + rto.Name) + return r.c.execute("DELETE", urlStr, "") +} + func (r *Repository) Update(ro *RepositoryOptions) (*Repository, error) { data, err := r.buildRepositoryBody(ro) if err != nil { From 2dd2dbbf645fcdfa6d6c2be59d58318735124629 Mon Sep 17 00:00:00 2001 From: David Dansby <39511285+DataDavD@users.noreply.github.com> Date: Thu, 29 Jul 2021 23:22:34 -0700 Subject: [PATCH 3/4] Refactor Repo Tag and Branch Target types to a single Ref Target This commit refactors the existing RepositoryBranchTarget and RepositoryTagTarget types to a single RepositoryRefTarget since tags and branches are both refs and the two Target variables represented the same type anyways. This will also help us move to removing branch and tag specific options types into a single refs options type. See https://github.com/ktrysmt/go-bitbucket/pull/155 and https://github.com/ktrysmt/go-bitbucket/issues/153#event-5065960820 --- bitbucket.go | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/bitbucket.go b/bitbucket.go index afdd261..a3e8ba4 100644 --- a/bitbucket.go +++ b/bitbucket.go @@ -214,6 +214,10 @@ type RepositoryRefOptions struct { BranchFlg bool } +type RepositoryRefTarget struct { + Hash string `json:"hash"` +} + type RepositoryBranchOptions struct { Owner string `json:"owner"` RepoSlug string `json:"repo_slug"` @@ -226,22 +230,10 @@ type RepositoryBranchOptions struct { } type RepositoryBranchCreationOptions struct { - Owner string `json:"owner"` - RepoSlug string `json:"repo_slug"` - Name string `json:"name"` - Target RepositoryBranchTarget `json:"target"` -} - -type RepositoryBranchDeleteOptions struct { - Owner string `json:"owner"` - RepoSlug string `json:"repo_slug"` - RepoUUID string `json:"uuid"` - RefName string `json:"name"` - RefUUID string `json:uuid` -} - -type RepositoryBranchTarget struct { - Hash string `json:"hash"` + Owner string `json:"owner"` + RepoSlug string `json:"repo_slug"` + Name string `json:"name"` + Target RepositoryRefTarget `json:"target"` } type RepositoryTagOptions struct { @@ -259,11 +251,7 @@ type RepositoryTagCreationOptions struct { Owner string `json:"owner"` RepoSlug string `json:"repo_slug"` Name string `json:"name"` - Target RepositoryTagTarget `json:"target"` -} - -type RepositoryTagTarget struct { - Hash string `json:"hash"` + Target RepositoryRefTarget `json:"target"` } type PullRequestsOptions struct { From 57c51b0420fcbbbf53d2a2b7b4838c8a495aef13 Mon Sep 17 00:00:00 2001 From: David Dansby <39511285+DataDavD@users.noreply.github.com> Date: Thu, 29 Jul 2021 23:33:28 -0700 Subject: [PATCH 4/4] Create test for DeleteBranch and DeleteTag and update Refs test This commit tests the DeleteBranch and DeleteTag repo methods. It also updates the ListRefs part of the tests to ensure that it also properly lists tags as well as branches. --- tests/repository_test.go | 110 +++++++++++++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 10 deletions(-) diff --git a/tests/repository_test.go b/tests/repository_test.go index 263c6d3..c4890d2 100644 --- a/tests/repository_test.go +++ b/tests/repository_test.go @@ -274,8 +274,10 @@ func TestDeleteRepositoryPipelineVariables(t *testing.T) { } } +// This test tests the CreateBranch, CreateTag, ListRefs, DeleteBranch, and DeleteTag repo methods func TestGetRepositoryRefs(t *testing.T) { - + // Create Branch, List Refs and search for Branch that was created, + // then test successful Branch deletion user := os.Getenv("BITBUCKET_TEST_USERNAME") pass := os.Getenv("BITBUCKET_TEST_PASSWORD") owner := os.Getenv("BITBUCKET_TEST_OWNER") @@ -300,7 +302,7 @@ func TestGetRepositoryRefs(t *testing.T) { Owner: owner, RepoSlug: repo, Name: "TestGetRepoRefsBranch", - Target: bitbucket.RepositoryBranchTarget{Hash: "master"}, + Target: bitbucket.RepositoryRefTarget{Hash: "master"}, } _, err := c.Repositories.Repository.CreateBranch(opt) @@ -308,39 +310,127 @@ func TestGetRepositoryRefs(t *testing.T) { t.Error("Could not create new branch", err) } - refOpts := &bitbucket.RepositoryRefOptions{ + refBranchOpts := &bitbucket.RepositoryRefOptions{ Owner: owner, RepoSlug: repo, } - resRefs, err := c.Repositories.Repository.ListRefs(refOpts) + resBranchRefs, err := c.Repositories.Repository.ListRefs(refBranchOpts) if err != nil { - t.Error("The refs is not found.") + t.Error("The refs/branch is not found.") } - expected := struct { + branchExpected := struct { n string t string }{} - for _, ref := range resRefs.Refs { + for _, ref := range resBranchRefs.Refs { for k, v := range ref { // kCopy := k vCopy := v if val, ok := vCopy.(string); ok { if k == "name" && val == "TestGetRepoRefsBranch" { - expected.n = val + branchExpected.n = val } } if val, ok := vCopy.(string); ok { if k == "type" && val == "branch" { - expected.t = val + branchExpected.t = val } } } } - if !(expected.n == "TestGetRepoRefsBranch" && expected.t == "branch") { + if !(branchExpected.n == "TestGetRepoRefsBranch" && branchExpected.t == "branch") { t.Error("Could not list refs/branch that was created in test setup") } + + delBranchOpt := &bitbucket.RepositoryBranchOptions{ + Owner: owner, + RepoSlug: repo, + Name: "TestGetRepoRefsBranch", + } + resBranchDel, err := c.Repositories.Repository.DeleteBranch(delBranchOpt) + if err != nil { + t.Error("Could not delete branch") + } + + if mp, ok := resBranchDel.(map[string]interface{}); ok { + for k, v := range mp { + if k == "type" && v == "error" { + t.Error("Delete branch returned an error, when it should have successfully" + + "delete the test branch created during test setup") + } + } + } + + // Create Tag, List Refs and search for Tag that was created, + // then test successful Tag deletion + tagOpt := &bitbucket.RepositoryTagCreationOptions{ + Owner: owner, + RepoSlug: repo, + Name: "TestGetRepoRefsTag", + Target: bitbucket.RepositoryRefTarget{Hash: "master"}, + } + + _, err = c.Repositories.Repository.CreateTag(tagOpt) + if err != nil { + t.Error("Could not create new tag", err) + } + + refTagOpts := &bitbucket.RepositoryRefOptions{ + Owner: owner, + RepoSlug: repo, + } + + resTagRefs, err := c.Repositories.Repository.ListRefs(refTagOpts) + if err != nil { + t.Error("The ref/tag is not found.") + } + + tagExpected := struct { + n string + t string + }{} + + for _, ref := range resTagRefs.Refs { + for k, v := range ref { + // kCopy := k + vCopy := v + if val, ok := vCopy.(string); ok { + if k == "name" && val == "TestGetRepoRefsTag" { + tagExpected.n = val + } + } + if val, ok := vCopy.(string); ok { + if k == "type" && val == "tag" { + tagExpected.t = val + } + } + } + } + + if !(tagExpected.n == "TestGetRepoRefsTag" && tagExpected.t == "tag") { + t.Error("Could not list refs/tag that was created in test setup") + } + + delTagOpt := &bitbucket.RepositoryTagOptions{ + Owner: owner, + RepoSlug: repo, + Name: "TestGetRepoRefsTag", + } + resTagDel, err := c.Repositories.Repository.DeleteTag(delTagOpt) + if err != nil { + t.Error("Could not delete tag") + } + + if mp, ok := resTagDel.(map[string]interface{}); ok { + for k, v := range mp { + if k == "type" && v == "error" { + t.Error("Delete tag returned an error, when it should have successfully" + + "delete the test tag created during test setup") + } + } + } }