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 }