2022-11-18 09:57:31 +00:00
|
|
|
package mutator
|
|
|
|
|
|
|
|
import (
|
2022-11-28 09:59:43 +00:00
|
|
|
"context"
|
2022-11-18 09:57:31 +00:00
|
|
|
"fmt"
|
|
|
|
"path/filepath"
|
2023-07-07 10:22:58 +00:00
|
|
|
"strings"
|
2022-11-18 09:57:31 +00:00
|
|
|
|
2023-05-16 16:35:39 +00:00
|
|
|
"github.com/databricks/cli/bundle"
|
|
|
|
"github.com/databricks/cli/bundle/config"
|
2022-11-18 09:57:31 +00:00
|
|
|
"golang.org/x/exp/slices"
|
|
|
|
)
|
|
|
|
|
|
|
|
type processRootIncludes struct{}
|
|
|
|
|
|
|
|
// ProcessRootIncludes expands the patterns in the configuration's include list
|
|
|
|
// into a list of mutators for each matching file.
|
2022-11-28 09:59:43 +00:00
|
|
|
func ProcessRootIncludes() bundle.Mutator {
|
2022-11-18 09:57:31 +00:00
|
|
|
return &processRootIncludes{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *processRootIncludes) Name() string {
|
|
|
|
return "ProcessRootIncludes"
|
|
|
|
}
|
|
|
|
|
2023-05-24 12:45:19 +00:00
|
|
|
func (m *processRootIncludes) Apply(ctx context.Context, b *bundle.Bundle) error {
|
2022-11-28 09:59:43 +00:00
|
|
|
var out []bundle.Mutator
|
2022-11-18 09:57:31 +00:00
|
|
|
|
|
|
|
// Map with files we've already seen to avoid loading them twice.
|
|
|
|
var seen = map[string]bool{
|
|
|
|
config.FileName: true,
|
|
|
|
}
|
|
|
|
|
2023-02-20 20:01:28 +00:00
|
|
|
// Maintain list of files in order of files being loaded.
|
|
|
|
// This is stored in the bundle configuration for observability.
|
|
|
|
var files []string
|
|
|
|
|
2022-11-18 09:57:31 +00:00
|
|
|
// For each glob, find all files to load.
|
|
|
|
// Ordering of the list of globs is maintained in the output.
|
|
|
|
// For matches that appear in multiple globs, only the first is kept.
|
2022-11-28 09:59:43 +00:00
|
|
|
for _, entry := range b.Config.Include {
|
2022-11-18 09:57:31 +00:00
|
|
|
// Include paths must be relative.
|
|
|
|
if filepath.IsAbs(entry) {
|
2023-05-24 12:45:19 +00:00
|
|
|
return fmt.Errorf("%s: includes must be relative paths", entry)
|
2022-11-18 09:57:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Anchor includes to the bundle root path.
|
2022-11-28 09:59:43 +00:00
|
|
|
matches, err := filepath.Glob(filepath.Join(b.Config.Path, entry))
|
2022-11-18 09:57:31 +00:00
|
|
|
if err != nil {
|
2023-05-24 12:45:19 +00:00
|
|
|
return err
|
2022-11-18 09:57:31 +00:00
|
|
|
}
|
|
|
|
|
2023-07-07 10:22:58 +00:00
|
|
|
// If the entry is not a glob pattern and no matches found,
|
|
|
|
// return an error because the file defined is not found
|
|
|
|
if len(matches) == 0 && !strings.ContainsAny(entry, "*?[") {
|
|
|
|
return fmt.Errorf("%s defined in 'include' section does not match any files", entry)
|
|
|
|
}
|
|
|
|
|
2022-11-18 09:57:31 +00:00
|
|
|
// Filter matches to ones we haven't seen yet.
|
|
|
|
var includes []string
|
|
|
|
for _, match := range matches {
|
2022-11-28 09:59:43 +00:00
|
|
|
rel, err := filepath.Rel(b.Config.Path, match)
|
2022-11-18 09:57:31 +00:00
|
|
|
if err != nil {
|
2023-05-24 12:45:19 +00:00
|
|
|
return err
|
2022-11-18 09:57:31 +00:00
|
|
|
}
|
|
|
|
if _, ok := seen[rel]; ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
seen[rel] = true
|
|
|
|
includes = append(includes, rel)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add matches to list of mutators to return.
|
|
|
|
slices.Sort(includes)
|
2023-02-20 20:01:28 +00:00
|
|
|
files = append(files, includes...)
|
2022-11-18 09:57:31 +00:00
|
|
|
for _, include := range includes {
|
2022-11-28 09:59:43 +00:00
|
|
|
out = append(out, ProcessInclude(filepath.Join(b.Config.Path, include), include))
|
2022-11-18 09:57:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-20 20:01:28 +00:00
|
|
|
// Swap out the original includes list with the expanded globs.
|
|
|
|
b.Config.Include = files
|
|
|
|
|
2023-05-24 12:45:19 +00:00
|
|
|
return bundle.Apply(ctx, b, bundle.Seq(out...))
|
2022-11-18 09:57:31 +00:00
|
|
|
}
|