diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 0f71834ff5..bd2aee56c4 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -5,6 +5,7 @@ ### Notable Changes ### CLI +* Recognize `ssh://` template URLs in `databricks bundle init` ([#5891](https://github.com/databricks/cli/pull/5891)). ### Bundles diff --git a/libs/template/resolver.go b/libs/template/resolver.go index b5a2fa8d88..f7ca1f9c82 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 2174fe1afe..12de32ab96 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) {