databricks-cli/bundle/config/validate/validate_sync_patterns.go

88 lines
2.1 KiB
Go

package validate
import (
"context"
"fmt"
"strings"
"sync"
"github.com/databricks/cli/bundle"
"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/fileset"
"golang.org/x/sync/errgroup"
)
func ValidateSyncPatterns() bundle.ReadOnlyMutator {
return &validateSyncPatterns{}
}
type validateSyncPatterns struct {
}
func (v *validateSyncPatterns) Name() string {
return "validate:validate_sync_patterns"
}
func (v *validateSyncPatterns) Apply(ctx context.Context, rb bundle.ReadOnlyBundle) diag.Diagnostics {
s := rb.Config().Sync
if len(s.Exclude) == 0 && len(s.Include) == 0 {
return nil
}
diags, err := checkPatterns(s.Exclude, "sync.exclude", rb)
if err != nil {
return diag.FromErr(err)
}
includeDiags, err := checkPatterns(s.Include, "sync.include", rb)
if err != nil {
return diag.FromErr(err)
}
return diags.Extend(includeDiags)
}
func checkPatterns(patterns []string, path string, rb bundle.ReadOnlyBundle) (diag.Diagnostics, error) {
var mu sync.Mutex
var errs errgroup.Group
var diags diag.Diagnostics
for i, pattern := range patterns {
index := i
fullPattern := pattern
// If the pattern is negated, strip the negation prefix
// and check if the pattern matches any files.
// Negation in gitignore syntax means "don't look at this path'
// So if p matches nothing it's useless negation, but if there are matches,
// it means: do not include these files into result set
p := strings.TrimPrefix(fullPattern, "!")
errs.Go(func() error {
fs, err := fileset.NewGlobSet(rb.BundleRoot(), []string{p})
if err != nil {
return err
}
all, err := fs.Files()
if err != nil {
return err
}
if len(all) == 0 {
loc := location{path: fmt.Sprintf("%s[%d]", path, index), rb: rb}
mu.Lock()
diags = diags.Append(diag.Diagnostic{
Severity: diag.Warning,
Summary: fmt.Sprintf("Pattern %s does not match any files", fullPattern),
Locations: []dyn.Location{loc.Location()},
Paths: []dyn.Path{loc.Path()},
})
mu.Unlock()
}
return nil
})
}
return diags, errs.Wait()
}