mirror of https://github.com/databricks/cli.git
Make init command aware of built-in templates
This commit is contained in:
parent
4621079f71
commit
e2174f5870
|
@ -3,6 +3,7 @@ package bundle
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
"slices"
|
||||||
|
@ -109,6 +110,24 @@ func getUrlForNativeTemplate(name string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getFsForNativeTemplate(name string) (fs.FS, error) {
|
||||||
|
builtin, err := template.Builtin()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a built-in template, the return value will be non-nil.
|
||||||
|
var templateFS fs.FS
|
||||||
|
for _, entry := range builtin {
|
||||||
|
if entry.Name == name {
|
||||||
|
templateFS = entry.FS
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return templateFS, nil
|
||||||
|
}
|
||||||
|
|
||||||
func isRepoUrl(url string) bool {
|
func isRepoUrl(url string) bool {
|
||||||
result := false
|
result := false
|
||||||
for _, prefix := range gitUrlPrefixes {
|
for _, prefix := range gitUrlPrefixes {
|
||||||
|
@ -198,9 +217,20 @@ See https://docs.databricks.com/en/dev-tools/bundles/templates.html for more inf
|
||||||
if templateDir != "" {
|
if templateDir != "" {
|
||||||
return errors.New("--template-dir can only be used with a Git repository URL")
|
return errors.New("--template-dir can only be used with a Git repository URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
templateFS, err := getFsForNativeTemplate(templatePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is not a built-in template, then it must be a local file system path.
|
||||||
|
if templateFS == nil {
|
||||||
|
templateFS = os.DirFS(templatePath)
|
||||||
|
}
|
||||||
|
|
||||||
// skip downloading the repo because input arg is not a URL. We assume
|
// skip downloading the repo because input arg is not a URL. We assume
|
||||||
// it's a path on the local file system in that case
|
// it's a path on the local file system in that case
|
||||||
return template.Materialize(ctx, configFile, templatePath, outputDir)
|
return template.Materialize(ctx, configFile, templateFS, outputDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a temporary directory with the name of the repository. The '*'
|
// Create a temporary directory with the name of the repository. The '*'
|
||||||
|
@ -224,7 +254,8 @@ See https://docs.databricks.com/en/dev-tools/bundles/templates.html for more inf
|
||||||
|
|
||||||
// Clean up downloaded repository once the template is materialized.
|
// Clean up downloaded repository once the template is materialized.
|
||||||
defer os.RemoveAll(repoDir)
|
defer os.RemoveAll(repoDir)
|
||||||
return template.Materialize(ctx, configFile, filepath.Join(repoDir, templateDir), outputDir)
|
templateFS := os.DirFS(filepath.Join(repoDir, templateDir))
|
||||||
|
return template.Materialize(ctx, configFile, templateFS, outputDir)
|
||||||
}
|
}
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package template
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"io/fs"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed all:templates
|
||||||
|
var builtinTemplates embed.FS
|
||||||
|
|
||||||
|
// BuiltinTemplate represents a template that is built into the CLI.
|
||||||
|
type BuiltinTemplate struct {
|
||||||
|
Name string
|
||||||
|
FS fs.FS
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builtin returns the list of all built-in templates.
|
||||||
|
func Builtin() ([]BuiltinTemplate, error) {
|
||||||
|
templates, err := fs.Sub(builtinTemplates, "templates")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
entries, err := fs.ReadDir(templates, ".")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var out []BuiltinTemplate
|
||||||
|
for _, entry := range entries {
|
||||||
|
if !entry.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
templateFS, err := fs.Sub(templates, entry.Name())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
out = append(out, BuiltinTemplate{
|
||||||
|
Name: entry.Name(),
|
||||||
|
FS: templateFS,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package template
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/fs"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuiltin(t *testing.T) {
|
||||||
|
out, err := Builtin()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, out, 3)
|
||||||
|
|
||||||
|
// Confirm names.
|
||||||
|
assert.Equal(t, "dbt-sql", out[0].Name)
|
||||||
|
assert.Equal(t, "default-python", out[1].Name)
|
||||||
|
assert.Equal(t, "default-sql", out[2].Name)
|
||||||
|
|
||||||
|
// Confirm that the filesystems work.
|
||||||
|
_, err = fs.Stat(out[0].FS, `template/{{.project_name}}/dbt_project.yml.tmpl`)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
_, err = fs.Stat(out[1].FS, `template/{{.project_name}}/tests/main_test.py.tmpl`)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
_, err = fs.Stat(out[2].FS, `template/{{.project_name}}/src/orders_daily.sql.tmpl`)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package template
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"embed"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
@ -14,9 +13,6 @@ const libraryDirName = "library"
|
||||||
const templateDirName = "template"
|
const templateDirName = "template"
|
||||||
const schemaFileName = "databricks_template_schema.json"
|
const schemaFileName = "databricks_template_schema.json"
|
||||||
|
|
||||||
//go:embed all:templates
|
|
||||||
var builtinTemplates embed.FS
|
|
||||||
|
|
||||||
// This function materializes the input templates as a project, using user defined
|
// This function materializes the input templates as a project, using user defined
|
||||||
// configurations.
|
// configurations.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
|
|
Loading…
Reference in New Issue