summaryrefslogtreecommitdiffstats
path: root/pkg/commands
diff options
context:
space:
mode:
authortiwood <andre.bindewald@live.com>2021-12-30 16:04:49 +0100
committerJesse Duffield <jessedduffield@gmail.com>2022-03-16 20:52:49 +1100
commitf0d0d45ba7325f54123756f676f33e0260fa1e15 (patch)
tree00d2d75b00490587d78c92b7e961a37e56a9f867 /pkg/commands
parent08ee3309cb1125cc06bb10529495695099da0375 (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/commands')
-rw-r--r--pkg/commands/hosting_service/definitions.go28
-rw-r--r--pkg/commands/hosting_service/hosting_service.go42
-rw-r--r--pkg/commands/hosting_service/hosting_service_test.go97
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",