github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/gits/gerrit.go (about)

     1  package gits
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/url"
     7  	"os"
     8  	"time"
     9  
    10  	gerrit "github.com/andygrunwald/go-gerrit"
    11  	"github.com/google/go-github/v32/github"
    12  	"github.com/jenkins-x/jx-logging/pkg/log"
    13  	"github.com/olli-ai/jx/v2/pkg/auth"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  type GerritProvider struct {
    18  	Client   *gerrit.Client
    19  	Username string
    20  	Context  context.Context
    21  
    22  	Server auth.AuthServer
    23  	User   auth.UserAuth
    24  	Git    Gitter
    25  }
    26  
    27  func NewGerritProvider(server *auth.AuthServer, user *auth.UserAuth, git Gitter) (GitProvider, error) {
    28  	ctx := context.Background()
    29  
    30  	provider := GerritProvider{
    31  		Server:   *server,
    32  		User:     *user,
    33  		Context:  ctx,
    34  		Username: user.Username,
    35  		Git:      git,
    36  	}
    37  
    38  	client, err := gerrit.NewClient(server.URL, nil)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	client.Authentication.SetBasicAuth(user.Username, user.ApiToken)
    43  	provider.Client = client
    44  
    45  	return &provider, nil
    46  }
    47  
    48  // We have to do this because url.Escape is not idempotent, so we unescape the URL
    49  // to ensure it's not encoded, then we re-encode it.
    50  func buildEncodedProjectName(org, name string) string {
    51  	var fullName string
    52  
    53  	if org != "" {
    54  		fullName = fmt.Sprintf("%s/%s", org, name)
    55  	} else {
    56  		fullName = fmt.Sprintf("%s", name)
    57  	}
    58  
    59  	fullNamePathUnescaped, err := url.PathUnescape(fullName)
    60  	if err != nil {
    61  		return ""
    62  	}
    63  	fullNamePathEscaped := url.PathEscape(fullNamePathUnescaped)
    64  
    65  	return fullNamePathEscaped
    66  }
    67  
    68  func (p *GerritProvider) projectInfoToGitRepository(project *gerrit.ProjectInfo) *GitRepository {
    69  	return &GitRepository{
    70  		Name:     project.Name,
    71  		CloneURL: fmt.Sprintf("%s/%s", p.Server.URL, project.Name),
    72  		SSHURL:   fmt.Sprintf("%s:%s", p.Server.URL, project.Name),
    73  	}
    74  }
    75  
    76  func (p *GerritProvider) ListRepositories(org string) ([]*GitRepository, error) {
    77  	options := &gerrit.ProjectOptions{
    78  		Description: true,
    79  		Prefix:      url.PathEscape(org),
    80  	}
    81  
    82  	gerritProjects, _, err := p.Client.Projects.ListProjects(options)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  
    87  	repos := []*GitRepository{}
    88  
    89  	for name, project := range *gerritProjects {
    90  		proj := project
    91  		proj.Name = name
    92  		repo := p.projectInfoToGitRepository(&proj)
    93  
    94  		repos = append(repos, repo)
    95  	}
    96  
    97  	return repos, nil
    98  }
    99  
   100  func (p *GerritProvider) CreateRepository(org string, name string, private bool) (*GitRepository, error) {
   101  	input := &gerrit.ProjectInput{
   102  		SubmitType:      "INHERIT",
   103  		Description:     "Created automatically by Jenkins X.",
   104  		PermissionsOnly: private,
   105  	}
   106  
   107  	fullNamePathEscaped := buildEncodedProjectName(org, name)
   108  	project, _, err := p.Client.Projects.CreateProject(fullNamePathEscaped, input)
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	repo := p.projectInfoToGitRepository(project)
   114  	return repo, nil
   115  }
   116  
   117  func (p *GerritProvider) GetRepository(org string, name string) (*GitRepository, error) {
   118  	fullName := buildEncodedProjectName(org, name)
   119  
   120  	project, _, err := p.Client.Projects.GetProject(fullName)
   121  	if err != nil {
   122  		return nil, err
   123  	}
   124  	return p.projectInfoToGitRepository(project), nil
   125  }
   126  
   127  func (p *GerritProvider) DeleteRepository(org string, name string) error {
   128  	return nil
   129  }
   130  
   131  func (p *GerritProvider) ForkRepository(originalOrg string, name string, destinationOrg string) (*GitRepository, error) {
   132  	return nil, nil
   133  }
   134  
   135  func (p *GerritProvider) RenameRepository(org string, name string, newName string) (*GitRepository, error) {
   136  	return nil, nil
   137  }
   138  
   139  func (p *GerritProvider) ValidateRepositoryName(org string, name string) error {
   140  	return nil
   141  }
   142  
   143  func (p *GerritProvider) CreatePullRequest(data *GitPullRequestArguments) (*GitPullRequest, error) {
   144  	return nil, nil
   145  }
   146  
   147  // UpdatePullRequest updates pull request with number using data
   148  func (p *GerritProvider) UpdatePullRequest(data *GitPullRequestArguments, number int) (*GitPullRequest, error) {
   149  	return nil, errors.Errorf("Not yet implemented for gerrit")
   150  }
   151  
   152  func (p *GerritProvider) UpdatePullRequestStatus(pr *GitPullRequest) error {
   153  	return nil
   154  }
   155  
   156  func (p *GerritProvider) GetPullRequest(owner string, repo *GitRepository, number int) (*GitPullRequest, error) {
   157  	return nil, nil
   158  }
   159  
   160  // ListOpenPullRequests lists the open pull requests
   161  func (p *GerritProvider) ListOpenPullRequests(owner string, repo string) ([]*GitPullRequest, error) {
   162  	return nil, nil
   163  }
   164  
   165  func (p *GerritProvider) GetPullRequestCommits(owner string, repo *GitRepository, number int) ([]*GitCommit, error) {
   166  	return nil, nil
   167  }
   168  
   169  func (p *GerritProvider) PullRequestLastCommitStatus(pr *GitPullRequest) (string, error) {
   170  	return "", nil
   171  }
   172  
   173  func (p *GerritProvider) ListCommitStatus(org string, repo string, sha string) ([]*GitRepoStatus, error) {
   174  	return nil, nil
   175  }
   176  
   177  // UpdateCommitStatus updates the status of a specified commit in a specified repo.
   178  func (p *GerritProvider) UpdateCommitStatus(org, repo, sha string, status *GitRepoStatus) (*GitRepoStatus, error) {
   179  	return nil, nil
   180  }
   181  
   182  func (p *GerritProvider) MergePullRequest(pr *GitPullRequest, message string) error {
   183  	return nil
   184  }
   185  
   186  func (p *GerritProvider) CreateWebHook(data *GitWebHookArguments) error {
   187  	return nil
   188  }
   189  
   190  // UpdateWebHook update a webhook with the data specified.
   191  func (p *GerritProvider) UpdateWebHook(data *GitWebHookArguments) error {
   192  	return nil
   193  }
   194  
   195  // ListWebHooks lists all webhooks for the specified repo.
   196  func (p *GerritProvider) ListWebHooks(org, repo string) ([]*GitWebHookArguments, error) {
   197  	return nil, nil
   198  }
   199  
   200  // ListOrganisations lists all organizations the configured user has access to.
   201  func (p *GerritProvider) ListOrganisations() ([]GitOrganisation, error) {
   202  	return nil, nil
   203  }
   204  
   205  func (p *GerritProvider) IsGitHub() bool {
   206  	return false
   207  }
   208  
   209  func (p *GerritProvider) IsGitea() bool {
   210  	return false
   211  }
   212  
   213  func (p *GerritProvider) IsBitbucketCloud() bool {
   214  	return false
   215  }
   216  
   217  func (p *GerritProvider) IsBitbucketServer() bool {
   218  	return false
   219  }
   220  
   221  func (p *GerritProvider) IsGerrit() bool {
   222  	return true
   223  }
   224  
   225  func (p *GerritProvider) Kind() string {
   226  	return "gerrit"
   227  }
   228  
   229  func (p *GerritProvider) GetIssue(org string, name string, number int) (*GitIssue, error) {
   230  	log.Logger().Warn("Gerrit does not support issue tracking")
   231  	return nil, nil
   232  }
   233  
   234  func (p *GerritProvider) IssueURL(org string, name string, number int, isPull bool) string {
   235  	log.Logger().Warn("Gerrit does not support issue tracking")
   236  	return ""
   237  }
   238  
   239  func (p *GerritProvider) SearchIssues(org string, name string, query string) ([]*GitIssue, error) {
   240  	log.Logger().Warn("Gerrit does not support issue tracking")
   241  	return nil, nil
   242  }
   243  
   244  func (p *GerritProvider) SearchIssuesClosedSince(org string, name string, t time.Time) ([]*GitIssue, error) {
   245  	log.Logger().Warn("Gerrit does not support issue tracking")
   246  	return nil, nil
   247  }
   248  
   249  func (p *GerritProvider) CreateIssue(owner string, repo string, issue *GitIssue) (*GitIssue, error) {
   250  	log.Logger().Warn("Gerrit does not support issue tracking")
   251  	return nil, nil
   252  }
   253  
   254  func (p *GerritProvider) HasIssues() bool {
   255  	log.Logger().Warn("Gerrit does not support issue tracking")
   256  	return false
   257  }
   258  
   259  func (p *GerritProvider) AddPRComment(pr *GitPullRequest, comment string) error {
   260  	return nil
   261  }
   262  
   263  func (p *GerritProvider) CreateIssueComment(owner string, repo string, number int, comment string) error {
   264  	log.Logger().Warn("Gerrit does not support issue tracking")
   265  	return nil
   266  }
   267  
   268  func (p *GerritProvider) UpdateRelease(owner string, repo string, tag string, releaseInfo *GitRelease) error {
   269  	return nil
   270  }
   271  
   272  // UpdateReleaseStatus is not supported for this git provider
   273  func (p *GerritProvider) UpdateReleaseStatus(owner string, repo string, tag string, releaseInfo *GitRelease) error {
   274  	return nil
   275  }
   276  
   277  func (p *GerritProvider) ListReleases(org string, name string) ([]*GitRelease, error) {
   278  	return nil, nil
   279  }
   280  
   281  // GetRelease returns the release info for org, repo name and tag
   282  func (p *GerritProvider) GetRelease(org string, name string, tag string) (*GitRelease, error) {
   283  	return nil, nil
   284  }
   285  
   286  func (p *GerritProvider) JenkinsWebHookPath(gitURL string, secret string) string {
   287  	return ""
   288  }
   289  
   290  func (p *GerritProvider) Label() string {
   291  	return ""
   292  }
   293  
   294  func (p *GerritProvider) ServerURL() string {
   295  	return ""
   296  }
   297  
   298  func (p *GerritProvider) BranchArchiveURL(org string, name string, branch string) string {
   299  	return ""
   300  }
   301  
   302  func (p *GerritProvider) CurrentUsername() string {
   303  	return ""
   304  }
   305  
   306  func (p *GerritProvider) UserAuth() auth.UserAuth {
   307  	return auth.UserAuth{}
   308  }
   309  
   310  func (p *GerritProvider) UserInfo(username string) *GitUser {
   311  	return nil
   312  }
   313  
   314  func (p *GerritProvider) AddCollaborator(user string, organisation string, repo string) error {
   315  	log.Logger().Infof("Automatically adding the pipeline user as a collaborator is currently not implemented for gerrit. Please add user: %v as a collaborator to this project.", user)
   316  	return nil
   317  }
   318  
   319  func (p *GerritProvider) ListInvitations() ([]*github.RepositoryInvitation, *github.Response, error) {
   320  	log.Logger().Infof("Automatically adding the pipeline user as a collaborator is currently not implemented for gerrit.")
   321  	return []*github.RepositoryInvitation{}, &github.Response{}, nil
   322  }
   323  
   324  func (p *GerritProvider) AcceptInvitation(ID int64) (*github.Response, error) {
   325  	log.Logger().Infof("Automatically adding the pipeline user as a collaborator is currently not implemented for gerrit.")
   326  	return &github.Response{}, nil
   327  }
   328  
   329  func (p *GerritProvider) GetContent(org string, name string, path string, ref string) (*GitFileContent, error) {
   330  	return nil, fmt.Errorf("Getting content not supported on gerrit")
   331  }
   332  
   333  // ShouldForkForPullReques treturns true if we should create a personal fork of this repository
   334  // before creating a pull request
   335  func (p *GerritProvider) ShouldForkForPullRequest(originalOwner string, repoName string, username string) bool {
   336  	return originalOwner != username
   337  }
   338  
   339  func (p *GerritProvider) ListCommits(owner, repo string, opt *ListCommitsArguments) ([]*GitCommit, error) {
   340  	return nil, fmt.Errorf("Listing commits not supported on gerrit")
   341  }
   342  
   343  // AddLabelsToIssue adds labels to issues or pullrequests
   344  func (p *GerritProvider) AddLabelsToIssue(owner, repo string, number int, labels []string) error {
   345  	return fmt.Errorf("Getting content not supported on gerrit")
   346  }
   347  
   348  // GetLatestRelease fetches the latest release from the git provider for org and name
   349  func (p *GerritProvider) GetLatestRelease(org string, name string) (*GitRelease, error) {
   350  	return nil, nil
   351  }
   352  
   353  // UploadReleaseAsset will upload an asset to org/repo to a release with id, giving it a name, it will return the release asset from the git provider
   354  func (p *GerritProvider) UploadReleaseAsset(org string, repo string, id int64, name string, asset *os.File) (*GitReleaseAsset, error) {
   355  	return nil, nil
   356  }
   357  
   358  // GetBranch returns the branch information for an owner/repo, including the commit at the tip
   359  func (p *GerritProvider) GetBranch(owner string, repo string, branch string) (*GitBranch, error) {
   360  	return nil, nil
   361  }
   362  
   363  // GetProjects returns all the git projects in owner/repo
   364  func (p *GerritProvider) GetProjects(owner string, repo string) ([]GitProject, error) {
   365  	return nil, nil
   366  }
   367  
   368  //ConfigureFeatures sets specific features as enabled or disabled for owner/repo
   369  func (p *GerritProvider) ConfigureFeatures(owner string, repo string, issues *bool, projects *bool, wikis *bool) (*GitRepository, error) {
   370  	return nil, nil
   371  }
   372  
   373  // IsWikiEnabled returns true if a wiki is enabled for owner/repo
   374  func (p *GerritProvider) IsWikiEnabled(owner string, repo string) (bool, error) {
   375  	return false, nil
   376  }