Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions bitbucket/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ var bitbucketAPI = "https://api.bitbucket.org/2.0"
// setBitbucketAPI overrides the Bitbucket API base URL (for testing).
func setBitbucketAPI(url string) { bitbucketAPI = url }

type bbCloneLink struct {
Href string `json:"href"`
Name string `json:"name"` // "https" or "ssh"
}

func parseCloneURLs(links []bbCloneLink) (cloneURL, sshURL string) {
for _, link := range links {
switch link.Name {
case "https":
cloneURL = link.Href
case "ssh":
sshURL = link.Href
}
}
return
}

type bitbucketForge struct {
token string
httpClient *http.Client
Expand Down Expand Up @@ -69,10 +86,7 @@ type bbRepository struct {
Avatar struct {
Href string `json:"href"`
} `json:"avatar"`
Clone []struct {
Href string `json:"href"`
Name string `json:"name"`
} `json:"clone"`
Clone []bbCloneLink `json:"clone"`
} `json:"links"`
CreatedOn string `json:"created_on"`
UpdatedOn string `json:"updated_on"`
Expand Down Expand Up @@ -157,14 +171,7 @@ func convertBitbucketRepo(bb bbRepository) forge.Repository {
LogoURL: bb.Links.Avatar.Href,
}

for _, c := range bb.Links.Clone {
switch c.Name {
case "https":
result.CloneURL = c.Href
case "ssh":
result.SSHURL = c.Href
}
}
result.CloneURL, result.SSHURL = parseCloneURLs(bb.Links.Clone)

if bb.Owner != nil {
result.Owner = bb.Owner.Username
Expand Down
5 changes: 1 addition & 4 deletions bitbucket/bitbucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,7 @@ func TestBitbucketGetRepo(t *testing.T) {
Avatar struct {
Href string `json:"href"`
} `json:"avatar"`
Clone []struct {
Href string `json:"href"`
Name string `json:"name"`
} `json:"clone"`
Clone []bbCloneLink `json:"clone"`
}{
HTML: struct {
Href string `json:"href"`
Expand Down
69 changes: 52 additions & 17 deletions bitbucket/prs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"net/http"
"strings"
"time"

forge "github.com/git-pkgs/forge"
Expand All @@ -21,22 +22,29 @@ func (f *bitbucketForge) PullRequests() forge.PullRequestService {
return &bitbucketPRService{token: f.token, httpClient: f.httpClient}
}

type bbPRBranch struct {
Branch struct {
Name string `json:"name"`
} `json:"branch"`
Commit *struct {
Hash string `json:"hash"`
} `json:"commit"`
Repository *struct {
FullName string `json:"full_name"`
Links struct {
Clone []bbCloneLink `json:"clone"`
} `json:"links"`
} `json:"repository"`
}

type bbPullRequest struct {
ID int `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
State string `json:"state"` // OPEN, MERGED, DECLINED, SUPERSEDED
Source struct {
Branch struct {
Name string `json:"name"`
} `json:"branch"`
} `json:"source"`
Destination struct {
Branch struct {
Name string `json:"name"`
} `json:"branch"`
} `json:"destination"`
Author *struct {
ID int `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
State string `json:"state"` // OPEN, MERGED, DECLINED, SUPERSEDED
Source bbPRBranch `json:"source"`
Destination bbPRBranch `json:"destination"`
Author *struct {
Username string `json:"username"`
DisplayName string `json:"display_name"`
Links struct {
Expand Down Expand Up @@ -81,13 +89,40 @@ func convertBitbucketPR(bb bbPullRequest) forge.PullRequest {
Number: bb.ID,
Title: bb.Title,
Body: bb.Description,
Head: bb.Source.Branch.Name,
Base: bb.Destination.Branch.Name,
Head: forge.PRBranch{Ref: bb.Source.Branch.Name},
Base: forge.PRBranch{Ref: bb.Destination.Branch.Name},
Comments: bb.CommentCount,
HTMLURL: bb.Links.HTML.Href,
DiffURL: bb.Links.Diff.Href,
}

var destFullName string
if bb.Destination.Commit != nil {
result.Base.SHA = bb.Destination.Commit.Hash
}
if bb.Destination.Repository != nil {
destFullName = bb.Destination.Repository.FullName
}

if bb.Source.Commit != nil {
result.Head.SHA = bb.Source.Commit.Hash
}
if bb.Source.Repository != nil && bb.Source.Repository.FullName != destFullName {
cloneURL, sshURL := parseCloneURLs(bb.Source.Repository.Links.Clone)
parts := strings.Split(bb.Source.Repository.FullName, "/")
var owner, name string
if len(parts) >= 2 {
owner = parts[0]
name = parts[1]
}
result.Head.Fork = &forge.ForkInfo{
Owner: owner,
Name: name,
CloneURL: cloneURL,
SSHURL: sshURL,
}
}

switch bb.State {
case "OPEN":
result.State = "open"
Expand Down
16 changes: 4 additions & 12 deletions bitbucket/prs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,10 @@ func TestBitbucketGetPR(t *testing.T) {
Title: "Add feature",
Description: "New feature PR",
State: "OPEN",
Source: struct {
Branch struct {
Name string `json:"name"`
} `json:"branch"`
}{Branch: struct {
Source: bbPRBranch{Branch: struct {
Name string `json:"name"`
}{Name: "feature-branch"}},
Destination: struct {
Branch struct {
Name string `json:"name"`
} `json:"branch"`
}{Branch: struct {
Destination: bbPRBranch{Branch: struct {
Name string `json:"name"`
}{Name: "main"}},
Author: &struct {
Expand Down Expand Up @@ -82,8 +74,8 @@ func TestBitbucketGetPR(t *testing.T) {
assertEqual(t, "Title", "Add feature", pr.Title)
assertEqual(t, "Body", "New feature PR", pr.Body)
assertEqual(t, "State", "open", pr.State)
assertEqual(t, "Head", "feature-branch", pr.Head)
assertEqual(t, "Base", "main", pr.Base)
assertEqual(t, "Head", "feature-branch", pr.Head.Ref)
assertEqual(t, "Base", "main", pr.Base.Ref)
assertEqual(t, "Author.Login", "author1", pr.Author.Login)
assertEqualInt(t, "Comments", 3, pr.Comments)
assertEqualBool(t, "Merged", false, pr.Merged)
Expand Down
24 changes: 20 additions & 4 deletions gitea/prs.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,27 @@ func convertGiteaPR(pr *gitea.PullRequest) forge.PullRequest {
result.State = stateOpen
}

if pr.Head != nil {
result.Head = pr.Head.Name
}
var baseRepoID int64
if pr.Base != nil {
result.Base = pr.Base.Name
result.Base = forge.PRBranch{
Ref: pr.Base.Ref,
SHA: pr.Base.Sha,
}
baseRepoID = pr.Base.RepoID
}
if pr.Head != nil {
result.Head = forge.PRBranch{
Ref: pr.Head.Ref,
SHA: pr.Head.Sha,
}
if pr.Head.RepoID != baseRepoID && pr.Head.Repository != nil && pr.Head.Repository.Owner != nil {
result.Head.Fork = &forge.ForkInfo{
Owner: pr.Head.Repository.Owner.UserName,
Name: pr.Head.Repository.Name,
CloneURL: pr.Head.Repository.CloneURL,
SSHURL: pr.Head.Repository.SSHURL,
}
}
}

if pr.Poster != nil {
Expand Down
28 changes: 24 additions & 4 deletions github/prs.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,31 @@ func convertGitHubPR(pr *github.PullRequest) forge.PullRequest {
}
}

if h := pr.GetHead(); h != nil {
result.Head = h.GetRef()
}
var baseFullName string
if b := pr.GetBase(); b != nil {
result.Base = b.GetRef()
result.Base = forge.PRBranch{
Ref: b.GetRef(),
SHA: b.GetSHA(),
}
if repo := b.GetRepo(); repo != nil {
baseFullName = repo.GetFullName()
}
}
if h := pr.GetHead(); h != nil {
result.Head = forge.PRBranch{
Ref: h.GetRef(),
SHA: h.GetSHA(),
}
if repo := h.GetRepo(); repo != nil {
if repo.GetFullName() != baseFullName {
result.Head.Fork = &forge.ForkInfo{
Owner: repo.GetOwner().GetLogin(),
Name: repo.GetName(),
CloneURL: repo.GetCloneURL(),
SSHURL: repo.GetSSHURL(),
}
}
}
}

if u := pr.GetMergedBy(); u != nil {
Expand Down
6 changes: 3 additions & 3 deletions github/prs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ func TestGitHubGetPR(t *testing.T) {
assertEqualBool(t, "Draft", false, pr.Draft)
assertEqualBool(t, "Merged", false, pr.Merged)
assertEqualBool(t, "Mergeable", true, pr.Mergeable)
assertEqual(t, "Head", "feature-branch", pr.Head)
assertEqual(t, "Base", "main", pr.Base)
assertEqual(t, "Head", "feature-branch", pr.Head.Ref)
assertEqual(t, "Base", "main", pr.Base.Ref)
assertEqual(t, "Author.Login", "octocat", pr.Author.Login)
assertEqualInt(t, "Comments", 2, pr.Comments)
assertEqualInt(t, "Additions", 10, pr.Additions)
Expand Down Expand Up @@ -174,7 +174,7 @@ func TestGitHubListPRs(t *testing.T) {
t.Fatalf("expected 2 PRs, got %d", len(prs))
}
assertEqual(t, "prs[0].Title", "First PR", prs[0].Title)
assertEqual(t, "prs[0].Head", "feature-1", prs[0].Head)
assertEqual(t, "prs[0].Head", "feature-1", prs[0].Head.Ref)
assertEqual(t, "prs[1].Title", "Second PR", prs[1].Title)
}

Expand Down
27 changes: 22 additions & 5 deletions gitlab/prs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package gitlab

import (
"context"
forge "github.com/git-pkgs/forge"
"fmt"
"net/http"
"time"

forge "github.com/git-pkgs/forge"
gitlab "gitlab.com/gitlab-org/api/client-go"
)

Expand All @@ -28,8 +29,8 @@ func convertGitLabMR(mr *gitlab.MergeRequest) forge.PullRequest {
Body: mr.Description,
State: mr.State, // "opened", "closed", "merged"
Draft: mr.Draft,
Head: mr.SourceBranch,
Base: mr.TargetBranch,
Head: forge.PRBranch{Ref: mr.SourceBranch, SHA: mr.SHA},
Base: forge.PRBranch{Ref: mr.TargetBranch},
Merged: mr.State == "merged",
Comments: int(mr.UserNotesCount),
// ChangesCount is a string in the GitLab API
Expand Down Expand Up @@ -117,8 +118,8 @@ func convertBasicGitLabMR(mr *gitlab.BasicMergeRequest) forge.PullRequest {
Body: mr.Description,
State: mr.State,
Draft: mr.Draft,
Head: mr.SourceBranch,
Base: mr.TargetBranch,
Head: forge.PRBranch{Ref: mr.SourceBranch},
Base: forge.PRBranch{Ref: mr.TargetBranch},
Merged: mr.State == "merged",
HTMLURL: mr.WebURL,
}
Expand Down Expand Up @@ -184,6 +185,22 @@ func (s *gitLabPRService) Get(ctx context.Context, owner, repo string, number in
return nil, err
}
result := convertGitLabMR(mr)

if mr.SourceProjectID != mr.TargetProjectID {
sourceProject, _, err := s.client.Projects.GetProject(mr.SourceProjectID, nil)
if err != nil {
return nil, fmt.Errorf("getting source project: %w", err)
}
if sourceProject != nil {
result.Head.Fork = &forge.ForkInfo{
Owner: sourceProject.Namespace.Path,
Name: sourceProject.Path,
CloneURL: sourceProject.HTTPURLToRepo,
SSHURL: sourceProject.SSHURLToRepo,
}
}
}

return &result, nil
}

Expand Down
Loading
Loading