databricks-cli/libs/template/resolver.go

123 lines
3.0 KiB
Go

package template
import (
"context"
"errors"
"strings"
"github.com/databricks/cli/libs/git"
)
var gitUrlPrefixes = []string{
"https://",
"git@",
}
func isRepoUrl(url string) bool {
result := false
for _, prefix := range gitUrlPrefixes {
if strings.HasPrefix(url, prefix) {
result = true
break
}
}
return result
}
type Resolver struct {
// One of the following three:
// 1. Path to a local template directory.
// 2. URL to a Git repository containing a template.
// 3. Name of a built-in template.
TemplatePathOrUrl string
// Path to a JSON file containing the configuration values to be used for
// template initialization.
ConfigFile string
// Directory to write the initialized template to.
OutputDir string
// Directory path within a Git repository containing the template.
TemplateDir string
// Git tag or branch to download the template from. Only one of these can be
// specified.
Tag string
Branch string
}
// ErrCustomSelected is returned when the user selects the "custom..." option
// in the prompt UI when they run `databricks bundle init`. This error signals
// the upstream callsite to show documentation to the user on how to use a custom
// template.
var ErrCustomSelected = errors.New("custom template selected")
// Configures the reader and the writer for template and returns
// a handle to the template.
// Prompts the user if needed.
func (r Resolver) Resolve(ctx context.Context) (*Template, error) {
if r.Tag != "" && r.Branch != "" {
return nil, errors.New("only one of tag or branch can be specified")
}
// Git ref to use for template initialization
ref := r.Branch
if r.Tag != "" {
ref = r.Tag
}
var err error
var templateName TemplateName
if r.TemplatePathOrUrl == "" {
// Prompt the user to select a template
// if a template path or URL is not provided.
templateName, err = SelectTemplate(ctx)
if err != nil {
return nil, err
}
} else {
templateName = TemplateName(r.TemplatePathOrUrl)
}
tmpl := GetDatabricksTemplate(templateName)
// If we could not find a databricks template with the name provided by the user,
// then we assume that the user provided us with a reference to a custom template.
//
// This reference could be one of:
// 1. Path to a local template directory.
// 2. URL to a Git repository containing a template.
//
// We resolve the appropriate reader according to the reference provided by the user.
if tmpl == nil {
tmpl = &Template{
name: Custom,
// We use a writer that does not log verbose telemetry for custom templates.
// This is important because template definitions can contain PII that we
// do not want to centralize.
Writer: &defaultWriter{},
}
if isRepoUrl(r.TemplatePathOrUrl) {
tmpl.Reader = &gitReader{
gitUrl: r.TemplatePathOrUrl,
ref: ref,
templateDir: r.TemplateDir,
cloneFunc: git.Clone,
}
} else {
tmpl.Reader = &localReader{
path: r.TemplatePathOrUrl,
}
}
}
err = tmpl.Writer.Configure(ctx, r.ConfigFile, r.OutputDir)
if err != nil {
return nil, err
}
return tmpl, nil
}