feat: generic git https (#73)

Previously, only `github.com` was supported for HTTP cloning of packages.

With this change, every git host using the http protocol (GitHub, Gitlab, Gitea) is supported :D
This commit is contained in:
Cody Boggs 2020-02-03 10:07:44 -07:00 committed by GitHub
parent 8f14d63f95
commit 0ba0ff5522
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 127 additions and 19 deletions

View file

@ -43,17 +43,17 @@ func TestParseDependency(t *testing.T) {
}, },
{ {
name: "Invalid", name: "Invalid",
path: "github.com/foo", path: "example.com/foo",
want: nil, want: nil,
}, },
{ {
name: "GitHub", name: "GitHTTPS",
path: "github.com/jsonnet-bundler/jsonnet-bundler", path: "example.com/jsonnet-bundler/jsonnet-bundler",
want: &deps.Dependency{ want: &deps.Dependency{
Source: deps.Source{ Source: deps.Source{
GitSource: &deps.Git{ GitSource: &deps.Git{
Scheme: deps.GitSchemeHTTPS, Scheme: deps.GitSchemeHTTPS,
Host: "github.com", Host: "example.com",
User: "jsonnet-bundler", User: "jsonnet-bundler",
Repo: "jsonnet-bundler", Repo: "jsonnet-bundler",
Subdir: "", Subdir: "",

View file

@ -40,7 +40,17 @@ func TestParseDependency(t *testing.T) {
}, },
{ {
name: "Invalid", name: "Invalid",
path: "github.com/foo", path: "example.com/foo",
want: nil,
},
{
name: "InvalidDomain",
path: "example.c/foo/bar",
want: nil,
},
{
name: "InvalidDomain2",
path: "examplec/foo/bar",
want: nil, want: nil,
}, },
{ {

View file

@ -33,11 +33,11 @@ type Git struct {
// Hostname the repo is located at // Hostname the repo is located at
Host string Host string
// User (github.com/<user>) // User (example.com/<user>)
User string User string
// Repo (github.com/<user>/<repo>) // Repo (example.com/<user>/<repo>)
Repo string Repo string
// Subdir (github.com/<user>/<repo>/<subdir>) // Subdir (example.com/<user>/<repo>/<subdir>)
Subdir string Subdir string
} }
@ -75,7 +75,7 @@ func (gs *Git) UnmarshalJSON(data []byte) error {
return nil return nil
} }
// Name returns the repository in a go-like format (github.com/user/repo/subdir) // Name returns the repository in a go-like format (example.com/user/repo/subdir)
func (gs *Git) Name() string { func (gs *Git) Name() string {
return fmt.Sprintf("%s/%s/%s%s", gs.Host, gs.User, gs.Repo, gs.Subdir) return fmt.Sprintf("%s/%s/%s%s", gs.Host, gs.User, gs.Repo, gs.Subdir)
} }
@ -102,13 +102,11 @@ func (gs *Git) Remote() string {
const ( const (
gitSSHExp = `ssh://git@(?P<host>.+)/(?P<user>.+)/(?P<repo>.+).git` gitSSHExp = `ssh://git@(?P<host>.+)/(?P<user>.+)/(?P<repo>.+).git`
gitSCPExp = `^git@(?P<host>.+):(?P<user>.+)/(?P<repo>.+).git` gitSCPExp = `^git@(?P<host>.+):(?P<user>.+)/(?P<repo>.+).git`
githubSlugExp = `github.com/(?P<user>[-_a-zA-Z0-9]+)/(?P<repo>[-_a-zA-Z0-9]+)` // The long ugly pattern for ${host} here is a generic pattern for "valid URL with zero or more subdomains and a valid TLD"
gitHTTPSExp = `(?P<host>[a-zA-Z0-9][a-zA-Z0-9-\.]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,})/(?P<user>[-_a-zA-Z0-9]+)/(?P<repo>[-_a-zA-Z0-9]+)`
) )
var ( var (
gitSSHRegex = regexp.MustCompile(gitSSHExp)
githubSlugRegex = regexp.MustCompile(githubSlugExp)
VersionRegex = `@(?P<version>.*)` VersionRegex = `@(?P<version>.*)`
PathRegex = `/(?P<subdir>.*)` PathRegex = `/(?P<subdir>.*)`
PathAndVersionRegex = `/(?P<subdir>.*)@(?P<version>.*)` PathAndVersionRegex = `/(?P<subdir>.*)@(?P<version>.*)`
@ -129,10 +127,9 @@ func parseGit(uri string) *Dependency {
case reMatch(gitSCPExp, uri): case reMatch(gitSCPExp, uri):
gs, version = match(uri, gitSCPExp) gs, version = match(uri, gitSCPExp)
gs.Scheme = GitSchemeSSH gs.Scheme = GitSchemeSSH
case reMatch(githubSlugExp, uri): case reMatch(gitHTTPSExp, uri):
gs, version = match(uri, githubSlugExp) gs, version = match(uri, gitHTTPSExp)
gs.Scheme = GitSchemeHTTPS gs.Scheme = GitSchemeHTTPS
gs.Host = "github.com"
default: default:
return nil return nil
} }
@ -150,7 +147,6 @@ func parseGit(uri string) *Dependency {
func match(p string, exp string) (gs *Git, version string) { func match(p string, exp string) (gs *Git, version string) {
gs = &Git{} gs = &Git{}
exps := []*regexp.Regexp{ exps := []*regexp.Regexp{
regexp.MustCompile(exp + PathAndVersionRegex), regexp.MustCompile(exp + PathAndVersionRegex),
regexp.MustCompile(exp + PathRegex), regexp.MustCompile(exp + PathRegex),

View file

@ -67,6 +67,108 @@ func TestParseGit(t *testing.T) {
want: sshWant("my.host"), want: sshWant("my.host"),
wantRemote: "ssh://git@my.host/user/repo.git", // want ssh format here wantRemote: "ssh://git@my.host/user/repo.git", // want ssh format here
}, },
{
name: "ValidGitHTTPS",
uri: "https://example.com/foo/bar",
want: &Dependency{
Version: "master",
Source: Source{
GitSource: &Git{
Scheme: GitSchemeHTTPS,
Host: "example.com",
User: "foo",
Repo: "bar",
Subdir: "",
},
},
},
wantRemote: "https://example.com/foo/bar",
},
{
name: "ValidGitNoScheme",
uri: "example.com/foo/bar",
want: &Dependency{
Version: "master",
Source: Source{
GitSource: &Git{
Scheme: GitSchemeHTTPS,
Host: "example.com",
User: "foo",
Repo: "bar",
Subdir: "",
},
},
},
wantRemote: "https://example.com/foo/bar",
},
{
name: "ValidGitPath",
uri: "example.com/foo/bar/baz/bat",
want: &Dependency{
Version: "master",
Source: Source{
GitSource: &Git{
Scheme: GitSchemeHTTPS,
Host: "example.com",
User: "foo",
Repo: "bar",
Subdir: "/baz/bat",
},
},
},
wantRemote: "https://example.com/foo/bar",
},
{
name: "ValidGitVersion",
uri: "example.com/foo/bar@baz",
want: &Dependency{
Version: "baz",
Source: Source{
GitSource: &Git{
Scheme: GitSchemeHTTPS,
Host: "example.com",
User: "foo",
Repo: "bar",
Subdir: "",
},
},
},
wantRemote: "https://example.com/foo/bar",
},
{
name: "ValidGitPathVersion",
uri: "example.com/foo/bar/baz@bat",
want: &Dependency{
Version: "bat",
Source: Source{
GitSource: &Git{
Scheme: GitSchemeHTTPS,
Host: "example.com",
User: "foo",
Repo: "bar",
Subdir: "/baz",
},
},
},
wantRemote: "https://example.com/foo/bar",
},
{
name: "ValidGitSubdomain",
uri: "git.example.com/foo/bar",
want: &Dependency{
Version: "master",
Source: Source{
GitSource: &Git{
Scheme: GitSchemeHTTPS,
Host: "git.example.com",
User: "foo",
Repo: "bar",
Subdir: "",
},
},
},
wantRemote: "https://git.example.com/foo/bar",
},
} }
for _, c := range tests { for _, c := range tests {