diff --git a/.nextchanges/bundles/bundle-init-git-clone-url.md b/.nextchanges/bundles/bundle-init-git-clone-url.md new file mode 100644 index 00000000000..a234b42c1f7 --- /dev/null +++ b/.nextchanges/bundles/bundle-init-git-clone-url.md @@ -0,0 +1 @@ +Recognize `ssh://` template URLs in `databricks bundle init` ([#5891](https://github.com/databricks/cli/pull/5891)). diff --git a/libs/template/resolver.go b/libs/template/resolver.go index b5a2fa8d881..f7ca1f9c829 100644 --- a/libs/template/resolver.go +++ b/libs/template/resolver.go @@ -8,20 +8,22 @@ import ( "github.com/databricks/cli/libs/git" ) +// See https://git-scm.com/docs/git-clone#_git_urls for the set of supported +// Git URL forms. We deliberately exclude deprecated/insecure protocols (git, http, ftp[s]). var gitUrlPrefixes = []string{ "https://", + "ssh://", + // recognize git@ without ssh:// protocol because this is very common "git@", } -func IsRepoUrl(url string) bool { - result := false +func IsGitRepoUrl(url string) bool { for _, prefix := range gitUrlPrefixes { if strings.HasPrefix(url, prefix) { - result = true - break + return true } } - return result + return false } // ResolveReader resolves a template path/URL to a Reader (built-in, git or local) @@ -30,7 +32,7 @@ func ResolveReader(templatePathOrUrl, templateDir, ref string) (Reader, bool) { return tmpl.Reader, false } - if IsRepoUrl(templatePathOrUrl) { + if IsGitRepoUrl(templatePathOrUrl) { return NewGitReader(templatePathOrUrl, ref, templateDir, git.Clone), true } diff --git a/libs/template/resolver_test.go b/libs/template/resolver_test.go index 2174fe1afe9..12de32ab963 100644 --- a/libs/template/resolver_test.go +++ b/libs/template/resolver_test.go @@ -100,12 +100,22 @@ func TestTemplateResolverForCustomPath(t *testing.T) { assert.Equal(t, "/config/file", tmpl.Writer.(*defaultWriter).configPath) } -func TestBundleInitIsRepoUrl(t *testing.T) { - assert.True(t, IsRepoUrl("git@github.com:databricks/cli.git")) - assert.True(t, IsRepoUrl("https://github.com/databricks/cli.git")) - - assert.False(t, IsRepoUrl("./local")) - assert.False(t, IsRepoUrl("foo")) +func TestBundleInitIsGitRepoUrl(t *testing.T) { + // Supported + assert.True(t, IsGitRepoUrl("git@github.com:databricks/cli.git")) + assert.True(t, IsGitRepoUrl("https://github.com/databricks/cli.git")) + assert.True(t, IsGitRepoUrl("ssh://user@company.ghe.com/databricks/cli.git")) + + // Unsupported + assert.False(t, IsGitRepoUrl("git://github.com/databricks/cli.git")) + assert.False(t, IsGitRepoUrl("http://github.com/databricks/cli.git")) + assert.False(t, IsGitRepoUrl("ftp://github.com/databricks/cli.git")) + assert.False(t, IsGitRepoUrl("ftps://github.com/databricks/cli.git")) + + // Not git repos + assert.False(t, IsGitRepoUrl("./local")) + assert.False(t, IsGitRepoUrl("foo")) + assert.False(t, IsGitRepoUrl("github.com/databricks/cli.git")) } func TestResolveReader(t *testing.T) {