gitsource: add new methods to handle refs and commits

Add new methods to handle refs and commits and related urls
This commit is contained in:
Simone Gotti 2019-06-11 11:07:39 +02:00
parent 47b7c5040f
commit fafcf3a623
5 changed files with 367 additions and 0 deletions

View File

@ -168,3 +168,43 @@ func (c *Client) CreateCommitStatus(repopath, commitSHA string, status gitsource
func (c *Client) ListUserRepos() ([]*gitsource.RepoInfo, error) { func (c *Client) ListUserRepos() ([]*gitsource.RepoInfo, error) {
return nil, nil return nil, nil
} }
func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
return nil, nil
}
func (c *Client) RefType(ref string) (gitsource.RefType, string, error) {
return -1, "", nil
}
func (c *Client) GetCommit(repopath, commitSHA string) (*gitsource.Commit, error) {
return nil, nil
}
func (c *Client) BranchRef(branch string) string {
return ""
}
func (c *Client) TagRef(tag string) string {
return ""
}
func (c *Client) PullRequestRef(prID string) string {
return ""
}
func (c *Client) CommitLink(repoInfo *gitsource.RepoInfo, commitSHA string) string {
return ""
}
func (c *Client) BranchLink(repoInfo *gitsource.RepoInfo, branch string) string {
return ""
}
func (c *Client) TagLink(repoInfo *gitsource.RepoInfo, tag string) string {
return ""
}
func (c *Client) PullRequestLink(repoInfo *gitsource.RepoInfo, prID string) string {
return ""
}

View File

@ -23,6 +23,7 @@ import (
"net" "net"
"net/http" "net/http"
"path" "path"
"regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -45,6 +46,11 @@ const (
var ( var (
// gitea corrently doesn't have any auth scope // gitea corrently doesn't have any auth scope
GiteaOauth2Scopes = []string{""} GiteaOauth2Scopes = []string{""}
branchRefPrefix = "refs/heads/"
tagRefPrefix = "refs/tags/"
pullRequestRefRegex = regexp.MustCompile("refs/pull/(.*)/head")
pullRequestRefFmt = "refs/pull/%s/head"
) )
type Opts struct { type Opts struct {
@ -397,3 +403,93 @@ func fromGiteaRepo(rr *gitea.Repository) *gitsource.RepoInfo {
HTTPCloneURL: rr.CloneURL, HTTPCloneURL: rr.CloneURL,
} }
} }
func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
owner, reponame, err := parseRepoPath(repopath)
if err != nil {
return nil, err
}
remoteRef, err := c.client.GetRepoRef(owner, reponame, ref)
if err != nil {
return nil, err
}
return fromGiteaRef(remoteRef)
}
func fromGiteaRef(remoteRef *gitea.Reference) (*gitsource.Ref, error) {
t := remoteRef.Object.Type
switch t {
case "commit":
default:
return nil, fmt.Errorf("unsupported object type: %s", t)
}
return &gitsource.Ref{
Ref: remoteRef.Ref,
CommitSHA: remoteRef.Object.SHA,
}, nil
}
func (c *Client) RefType(ref string) (gitsource.RefType, string, error) {
switch {
case strings.HasPrefix(ref, branchRefPrefix):
return gitsource.RefTypeBranch, strings.TrimPrefix(ref, branchRefPrefix), nil
case strings.HasPrefix(ref, tagRefPrefix):
return gitsource.RefTypeTag, strings.TrimPrefix(ref, tagRefPrefix), nil
case pullRequestRefRegex.MatchString(ref):
m := pullRequestRefRegex.FindStringSubmatch(ref)
return gitsource.RefTypePullRequest, m[0], nil
default:
return -1, "", fmt.Errorf("unsupported ref: %s", ref)
}
}
func (c *Client) GetCommit(repopath, commitSHA string) (*gitsource.Commit, error) {
owner, reponame, err := parseRepoPath(repopath)
if err != nil {
return nil, err
}
commit, err := c.client.GetSingleCommit(owner, reponame, commitSHA)
if err != nil {
return nil, err
}
return &gitsource.Commit{
SHA: commit.SHA,
Message: commit.RepoCommit.Message,
}, nil
}
func (c *Client) BranchRef(branch string) string {
return branchRefPrefix + branch
}
func (c *Client) TagRef(tag string) string {
return tagRefPrefix + tag
}
func (c *Client) PullRequestRef(prID string) string {
return fmt.Sprintf(pullRequestRefFmt, prID)
}
func (c *Client) CommitLink(repoInfo *gitsource.RepoInfo, commitSHA string) string {
return fmt.Sprintf("%s/commit/%s", repoInfo.HTMLURL, commitSHA)
}
func (c *Client) BranchLink(repoInfo *gitsource.RepoInfo, branch string) string {
return fmt.Sprintf("%s/src/branch/%s", repoInfo.HTMLURL, branch)
}
func (c *Client) TagLink(repoInfo *gitsource.RepoInfo, tag string) string {
return fmt.Sprintf("%s/src/tag/%s", repoInfo.HTMLURL, tag)
}
func (c *Client) PullRequestLink(repoInfo *gitsource.RepoInfo, prID string) string {
return fmt.Sprintf("%s/pulls/%s", repoInfo.HTMLURL, prID)
}

View File

@ -23,6 +23,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -36,6 +37,11 @@ import (
var ( var (
GitHubOauth2Scopes = []string{"repo"} GitHubOauth2Scopes = []string{"repo"}
branchRefPrefix = "refs/heads/"
tagRefPrefix = "refs/tags/"
pullRequestRefRegex = regexp.MustCompile("refs/pull/(.*)/head")
pullRequestRefFmt = "refs/pull/%s/head"
) )
const ( const (
@ -392,3 +398,93 @@ func fromGithubRepo(rr *github.Repository) *gitsource.RepoInfo {
HTTPCloneURL: *rr.CloneURL, HTTPCloneURL: *rr.CloneURL,
} }
} }
func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
owner, reponame, err := parseRepoPath(repopath)
if err != nil {
return nil, err
}
remoteRef, _, err := c.client.Git.GetRef(context.TODO(), owner, reponame, ref)
if err != nil {
return nil, err
}
return fromGithubRef(remoteRef)
}
func fromGithubRef(remoteRef *github.Reference) (*gitsource.Ref, error) {
t := *(remoteRef.Object.Type)
switch t {
case "commit":
default:
return nil, fmt.Errorf("unsupported object type: %s", t)
}
return &gitsource.Ref{
Ref: *remoteRef.Ref,
CommitSHA: *remoteRef.Object.SHA,
}, nil
}
func (c *Client) RefType(ref string) (gitsource.RefType, string, error) {
switch {
case strings.HasPrefix(ref, branchRefPrefix):
return gitsource.RefTypeBranch, strings.TrimPrefix(ref, branchRefPrefix), nil
case strings.HasPrefix(ref, tagRefPrefix):
return gitsource.RefTypeTag, strings.TrimPrefix(ref, tagRefPrefix), nil
case pullRequestRefRegex.MatchString(ref):
m := pullRequestRefRegex.FindStringSubmatch(ref)
return gitsource.RefTypePullRequest, m[0], nil
default:
return -1, "", fmt.Errorf("unsupported ref: %s", ref)
}
}
func (c *Client) GetCommit(repopath, commitSHA string) (*gitsource.Commit, error) {
owner, reponame, err := parseRepoPath(repopath)
if err != nil {
return nil, err
}
commit, _, err := c.client.Git.GetCommit(context.TODO(), owner, reponame, commitSHA)
if err != nil {
return nil, err
}
return &gitsource.Commit{
SHA: *commit.SHA,
Message: *commit.Message,
}, nil
}
func (c *Client) BranchRef(branch string) string {
return branchRefPrefix + branch
}
func (c *Client) TagRef(tag string) string {
return tagRefPrefix + tag
}
func (c *Client) PullRequestRef(prID string) string {
return fmt.Sprintf(pullRequestRefFmt, prID)
}
func (c *Client) CommitLink(repoInfo *gitsource.RepoInfo, commitSHA string) string {
return fmt.Sprintf("%s/commit/%s", repoInfo.HTMLURL, commitSHA)
}
func (c *Client) BranchLink(repoInfo *gitsource.RepoInfo, branch string) string {
return fmt.Sprintf("%s/src/branch/%s", repoInfo.HTMLURL, branch)
}
func (c *Client) TagLink(repoInfo *gitsource.RepoInfo, tag string) string {
return fmt.Sprintf("%s/src/tag/%s", repoInfo.HTMLURL, tag)
}
func (c *Client) PullRequestLink(repoInfo *gitsource.RepoInfo, prID string) string {
return fmt.Sprintf("%s/pull/%s", repoInfo.HTMLURL, prID)
}

View File

@ -21,7 +21,9 @@ import (
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"regexp"
"strconv" "strconv"
"strings"
"time" "time"
gitsource "github.com/sorintlab/agola/internal/gitsources" gitsource "github.com/sorintlab/agola/internal/gitsources"
@ -33,6 +35,11 @@ import (
var ( var (
GitlabOauth2Scopes = []string{"api"} GitlabOauth2Scopes = []string{"api"}
branchRefPrefix = "refs/heads/"
tagRefPrefix = "refs/tags/"
pullRequestRefRegex = regexp.MustCompile("refs/merge-requests/(.*)/head")
pullRequestRefFmt = "refs/merge-requests/%s/head"
) )
type Opts struct { type Opts struct {
@ -284,3 +291,100 @@ func fromGitlabRepo(rr *gitlab.Project) *gitsource.RepoInfo {
HTTPCloneURL: rr.HTTPURLToRepo, HTTPCloneURL: rr.HTTPURLToRepo,
} }
} }
// NOTE(sgotti) gitlab doesn't provide a get ref api
func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
switch {
case strings.HasPrefix(ref, "refs/heads/"):
branch := strings.TrimPrefix(ref, "refs/heads/")
remoteBranch, _, err := c.client.Branches.GetBranch(repopath, branch)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
return &gitsource.Ref{
Ref: ref,
CommitSHA: remoteBranch.Commit.ID,
}, nil
case strings.HasPrefix(ref, "refs/tags/"):
tag := strings.TrimPrefix(ref, "refs/heads/")
remoteTag, _, err := c.client.Tags.GetTag(repopath, tag)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
return &gitsource.Ref{
Ref: ref,
CommitSHA: remoteTag.Commit.ID,
}, nil
default:
return nil, fmt.Errorf("unsupported ref: %s", ref)
}
}
func (c *Client) RefType(ref string) (gitsource.RefType, string, error) {
switch {
case strings.HasPrefix(ref, branchRefPrefix):
return gitsource.RefTypeBranch, strings.TrimPrefix(ref, branchRefPrefix), nil
case strings.HasPrefix(ref, tagRefPrefix):
return gitsource.RefTypeTag, strings.TrimPrefix(ref, tagRefPrefix), nil
case pullRequestRefRegex.MatchString(ref):
m := pullRequestRefRegex.FindStringSubmatch(ref)
return gitsource.RefTypePullRequest, m[0], nil
default:
return -1, "", fmt.Errorf("unsupported ref: %s", ref)
}
}
func (c *Client) GetCommit(repopath, commitSHA string) (*gitsource.Commit, error) {
commit, _, err := c.client.Commits.GetCommit(repopath, commitSHA, nil)
if err != nil {
return nil, err
}
return &gitsource.Commit{
SHA: commit.ID,
Message: commit.Message,
}, nil
}
func (c *Client) BranchRef(branch string) string {
return branchRefPrefix + branch
}
func (c *Client) TagRef(tag string) string {
return tagRefPrefix + tag
}
func (c *Client) PullRequestRef(prID string) string {
return fmt.Sprintf(pullRequestRefFmt, prID)
}
func (c *Client) CommitLink(repoInfo *gitsource.RepoInfo, commitSHA string) string {
return fmt.Sprintf("%s/commit/%s", repoInfo.HTMLURL, commitSHA)
}
func (c *Client) BranchLink(repoInfo *gitsource.RepoInfo, branch string) string {
return fmt.Sprintf("%s/tree/%s", repoInfo.HTMLURL, branch)
}
func (c *Client) TagLink(repoInfo *gitsource.RepoInfo, tag string) string {
return fmt.Sprintf("%s/tree/%s", repoInfo.HTMLURL, tag)
}
func (c *Client) PullRequestLink(repoInfo *gitsource.RepoInfo, prID string) string {
return fmt.Sprintf("%s/merge_requests/%s", repoInfo.HTMLURL, prID)
}

View File

@ -45,6 +45,19 @@ type GitSource interface {
CreateCommitStatus(repopath, commitSHA string, status CommitStatus, targetURL, description, context string) error CreateCommitStatus(repopath, commitSHA string, status CommitStatus, targetURL, description, context string) error
// ListUserRepos report repos where the user has the permission to create deploy keys and webhooks // ListUserRepos report repos where the user has the permission to create deploy keys and webhooks
ListUserRepos() ([]*RepoInfo, error) ListUserRepos() ([]*RepoInfo, error)
GetRef(repopath, ref string) (*Ref, error)
// RefType returns the ref type and the related name (branch, tag, pr id)
RefType(ref string) (RefType, string, error)
GetCommit(repopath, commitSHA string) (*Commit, error)
BranchRef(branch string) string
TagRef(tag string) string
PullRequestRef(prID string) string
CommitLink(repoInfo *RepoInfo, commitSHA string) string
BranchLink(repoInfo *RepoInfo, branch string) string
TagLink(repoInfo *RepoInfo, tag string) string
PullRequestLink(repoInfo *RepoInfo, prID string) string
} }
type UserSource interface { type UserSource interface {
@ -80,3 +93,21 @@ type UserInfo struct {
LoginName string LoginName string
Email string Email string
} }
type RefType int
const (
RefTypeBranch RefType = iota
RefTypeTag
RefTypePullRequest
)
type Ref struct {
Ref string
CommitSHA string
}
type Commit struct {
SHA string
Message string
}