diff options
author | tiwood <andre.bindewald@live.com> | 2021-12-30 16:04:49 +0100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2022-03-16 20:52:49 +1100 |
commit | f0d0d45ba7325f54123756f676f33e0260fa1e15 (patch) | |
tree | 00d2d75b00490587d78c92b7e961a37e56a9f867 /pkg | |
parent | 08ee3309cb1125cc06bb10529495695099da0375 (diff) |
refactor: 💡 Use new approach introduced via #1637
fix: 🐛 The root URI for Azure DevOps repositories contains _git
refactor so that we don't have conditional logic based on service definition
no need for this commend anymore
add comment
Fixed RegEx for HTTP remote git URL
Added Tests
pretty sure we can do this safely
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/commands/hosting_service/definitions.go | 28 | ||||
-rw-r--r-- | pkg/commands/hosting_service/hosting_service.go | 42 | ||||
-rw-r--r-- | pkg/commands/hosting_service/hosting_service_test.go | 97 |
3 files changed, 79 insertions, 88 deletions
diff --git a/pkg/commands/hosting_service/definitions.go b/pkg/commands/hosting_service/definitions.go index c70062a67..3e7f144da 100644 --- a/pkg/commands/hosting_service/definitions.go +++ b/pkg/commands/hosting_service/definitions.go @@ -6,6 +6,7 @@ var defaultUrlRegexStrings = []string{ `^(?:https?|ssh)://.*/(?P<owner>.*)/(?P<repo>.*?)(?:\.git)?$`, `^git@.*:(?P<owner>.*)/(?P<repo>.*?)(?:\.git)?$`, } +var defaultRepoURLTemplate = "https://{{.webDomain}}/{{.owner}}/{{.repo}}" // we've got less type safety using go templates but this lends itself better to // users adding custom service definitions in their config @@ -15,6 +16,7 @@ var githubServiceDef = ServiceDefinition{ pullRequestURLIntoTargetBranch: "/compare/{{.To}}...{{.From}}?expand=1", commitURL: "/commit/{{.CommitSha}}", regexStrings: defaultUrlRegexStrings, + repoURLTemplate: defaultRepoURLTemplate, } var bitbucketServiceDef = ServiceDefinition{ @@ -23,6 +25,7 @@ var bitbucketServiceDef = ServiceDefinition{ pullRequestURLIntoTargetBranch: "/pull-requests/new?source={{.From}}&dest={{.To}}&t=1", commitURL: "/commits/{{.CommitSha}}", regexStrings: defaultUrlRegexStrings, + repoURLTemplate: defaultRepoURLTemplate, } var gitLabServiceDef = ServiceDefinition{ @@ -31,9 +34,27 @@ var gitLabServiceDef = ServiceDefinition{ pullRequestURLIntoTargetBranch: "/merge_requests/new?merge_request[source_branch]={{.From}}&merge_request[target_branch]={{.To}}", commitURL: "/commit/{{.CommitSha}}", regexStrings: defaultUrlRegexStrings, + repoURLTemplate: defaultRepoURLTemplate, } -var serviceDefinitions = []ServiceDefinition{githubServiceDef, bitbucketServiceDef, gitLabServiceDef} +var azdoServiceDef = ServiceDefinition{ + provider: "azuredevops", + pullRequestURLIntoDefaultBranch: "/pullrequestcreate?sourceRef={{.From}}", + pullRequestURLIntoTargetBranch: "/pullrequestcreate?sourceRef={{.From}}&targetRef={{.To}}", + commitURL: "/commit/{{.CommitSha}}", + regexStrings: []string{ + `^git@ssh.dev.azure.com.*/(?P<org>.*)/(?P<project>.*)/(?P<repo>.*?)(?:\.git)?$`, + `^https://.*@dev.azure.com/(?P<org>.*?)/(?P<project>.*?)/_git/(?P<repo>.*?)(?:\.git)?$`, + }, + repoURLTemplate: "https://{{.webDomain}}/{{.org}}/{{.project}}/_git/{{.repo}}", +} + +var serviceDefinitions = []ServiceDefinition{ + githubServiceDef, + bitbucketServiceDef, + gitLabServiceDef, + azdoServiceDef, +} var defaultServiceDomains = []ServiceDomain{ { @@ -51,4 +72,9 @@ var defaultServiceDomains = []ServiceDomain{ gitDomain: "gitlab.com", webDomain: "gitlab.com", }, + { + serviceDefinition: azdoServiceDef, + gitDomain: "dev.azure.com", + webDomain: "dev.azure.com", + }, } diff --git a/pkg/commands/hosting_service/hosting_service.go b/pkg/commands/hosting_service/hosting_service.go index 01e07e9eb..4a0a49681 100644 --- a/pkg/commands/hosting_service/hosting_service.go +++ b/pkg/commands/hosting_service/hosting_service.go @@ -1,7 +1,6 @@ package hosting_service import ( - "fmt" "net/url" "regexp" "strings" @@ -66,13 +65,13 @@ func (self *HostingServiceMgr) getService() (*Service, error) { return nil, err } - root, err := serviceDomain.getRootFromRemoteURL(self.remoteURL) + repoURL, err := serviceDomain.serviceDefinition.getRepoURLFromRemoteURL(self.remoteURL, serviceDomain.webDomain) if err != nil { return nil, err } return &Service{ - root: root, + repoURL: repoURL, ServiceDefinition: serviceDomain.serviceDefinition, }, nil } @@ -139,47 +138,32 @@ type ServiceDomain struct { serviceDefinition ServiceDefinition } -func (self ServiceDomain) getRootFromRemoteURL(repoURL string) (string, error) { - // we may want to make this more specific to the service in future e.g. if - // some new service comes along which has a different root url structure. - repoInfo, err := self.serviceDefinition.getRepoInfoFromURL(repoURL) - if err != nil { - return "", err - } - return fmt.Sprintf("https://%s/%s/%s", self.webDomain, repoInfo.Owner, repoInfo.Repository), nil -} - -// RepoInformation holds some basic information about the repo -type RepoInformation struct { - Owner string - Repository string -} - type ServiceDefinition struct { provider string pullRequestURLIntoDefaultBranch string pullRequestURLIntoTargetBranch string commitURL string regexStrings []string + + // can expect 'webdomain' to be passed in. Otherwise, you get to pick what we match in the regex + repoURLTemplate string } -func (self ServiceDefinition) getRepoInfoFromURL(url string) (*RepoInformation, error) { +func (self ServiceDefinition) getRepoURLFromRemoteURL(url string, webDomain string) (string, error) { for _, regexStr := range self.regexStrings { re := regexp.MustCompile(regexStr) - matches := utils.FindNamedMatches(re, url) - if matches != nil { - return &RepoInformation{ - Owner: matches["owner"], - Repository: matches["repo"], - }, nil + input := utils.FindNamedMatches(re, url) + if input != nil { + input["webDomain"] = webDomain + return utils.ResolvePlaceholderString(self.repoURLTemplate, input), nil } } - return nil, errors.New("Failed to parse repo information from url") + return "", errors.New("Failed to parse repo information from url") } type Service struct { - root string + repoURL string ServiceDefinition } @@ -196,5 +180,5 @@ func (self *Service) getCommitURL(commitSha string) string { } func (self *Service) resolveUrl(templateString string, args map[string]string) string { - return self.root + utils.ResolvePlaceholderString(templateString, args) + return self.repoURL + utils.ResolvePlaceholderString(templateString, args) } diff --git a/pkg/commands/hosting_service/hosting_service_test.go b/pkg/commands/hosting_service/hosting_service_test.go index 98c097a33..5bffa0165 100644 --- a/pkg/commands/hosting_service/hosting_service_test.go +++ b/pkg/commands/hosting_service/hosting_service_test.go @@ -8,63 +8,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGetRepoInfoFromURL(t *testing.T) { - type scenario struct { - serviceDefinition ServiceDefinition - testName string - repoURL string - test func(*RepoInformation) - } - - scenarios := []scenario{ - { - githubServiceDef, - "Returns repository information for git remote url", - "git@github.com:petersmith/super_calculator", - func(repoInfo *RepoInformation) { - assert.EqualValues(t, repoInfo.Owner, "petersmith") - assert.EqualValues(t, repoInfo.Repository, "super_calculator") - }, - }, - { - githubServiceDef, - "Returns repository information for git remote url, trimming trailing '.git'", - "git@github.com:petersmith/super_calculator.git", - func(repoInfo *RepoInformation) { - assert.EqualValues(t, repoInfo.Owner, "petersmith") - assert.EqualValues(t, repoInfo.Repository, "super_calculator") - }, - }, - { - githubServiceDef, - "Returns repository information for ssh remote url", - "ssh://git@github.com/petersmith/super_calculator", - func(repoInfo *RepoInformation) { - assert.EqualValues(t, repoInfo.Owner, "petersmith") - assert.EqualValues(t, repoInfo.Repository, "super_calculator") - }, - }, - { - githubServiceDef, - "Returns repository information for http remote url", - "https://my_username@bitbucket.org/johndoe/social_network.git", - func(repoInfo *RepoInformation) { - assert.EqualValues(t, repoInfo.Owner, "johndoe") - assert.EqualValues(t, repoInfo.Repository, "social_network") - }, - }, - } - - for _, s := range scenarios { - s := s - t.Run(s.testName, func(t *testing.T) { - result, err := s.serviceDefinition.getRepoInfoFromURL(s.repoURL) - assert.NoError(t, err) - s.test(result) - }) - } -} - func TestGetPullRequestURL(t *testing.T) { type scenario struct { testName string @@ -173,6 +116,44 @@ func TestGetPullRequestURL(t *testing.T) { }, }, { + testName: "Opens a link to new pull request on Azure DevOps (SSH)", + from: "feature/new", + remoteUrl: "git@ssh.dev.azure.com:v3/myorg/myproject/myrepo", + test: func(url string, err error) { + assert.NoError(t, err) + assert.Equal(t, "https://dev.azure.com/myorg/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature/new", url) + }, + }, + { + testName: "Opens a link to new pull request on Azure DevOps (SSH) with specifc target", + from: "feature/new", + to: "dev", + remoteUrl: "git@ssh.dev.azure.com:v3/myorg/myproject/myrepo", + test: func(url string, err error) { + assert.NoError(t, err) + assert.Equal(t, "https://dev.azure.com/myorg/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature/new&targetRef=dev", url) + }, + }, + { + testName: "Opens a link to new pull request on Azure DevOps (HTTP)", + from: "feature/new", + remoteUrl: "https://myorg@dev.azure.com/myorg/myproject/_git/myrepo", + test: func(url string, err error) { + assert.NoError(t, err) + assert.Equal(t, "https://dev.azure.com/myorg/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature/new", url) + }, + }, + { + testName: "Opens a link to new pull request on Azure DevOps (HTTP) with specifc target", + from: "feature/new", + to: "dev", + remoteUrl: "https://myorg@dev.azure.com/myorg/myproject/_git/myrepo", + test: func(url string, err error) { + assert.NoError(t, err) + assert.Equal(t, "https://dev.azure.com/myorg/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature/new&targetRef=dev", url) + }, + }, + { testName: "Throws an error if git service is unsupported", from: "feature/divide-operation", remoteUrl: "git@something.com:peter/calculator.git", @@ -218,7 +199,7 @@ func TestGetPullRequestURL(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "https://bitbucket.org/johndoe/social_network/pull-requests/new?source=feature%2Fprofile-page&t=1", url) }, - expectedLoggedErrors: []string{"Unknown git service type: 'noservice'. Expected one of github, bitbucket, gitlab"}, + expectedLoggedErrors: []string{"Unknown git service type: 'noservice'. Expected one of github, bitbucket, gitlab, azuredevops"}, }, { testName: "Escapes reserved URL characters in from branch name", |