mirror of https://github.com/databricks/cli.git
74 lines
2.0 KiB
Go
74 lines
2.0 KiB
Go
package mutator
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
|
|
"github.com/databricks/cli/bundle"
|
|
"github.com/databricks/cli/libs/diag"
|
|
"github.com/databricks/cli/libs/dyn"
|
|
)
|
|
|
|
type populateLocations struct{}
|
|
|
|
// PopulateLocations collects location information for the entire configuration tree
|
|
// and includes this as the [config.Root.Locations] property.
|
|
func PopulateLocations() bundle.Mutator {
|
|
return &populateLocations{}
|
|
}
|
|
|
|
func (m *populateLocations) Name() string {
|
|
return "PopulateLocations"
|
|
}
|
|
|
|
func computeRelativeLocations(base string, v dyn.Value) []dyn.Location {
|
|
// Skip values that don't have locations.
|
|
// Examples include defaults or values that are set by the program itself.
|
|
locs := v.Locations()
|
|
if len(locs) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// Convert absolute paths to relative paths.
|
|
for i := range locs {
|
|
rel, err := filepath.Rel(base, locs[i].File)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
// Convert the path separator to forward slashes.
|
|
// This makes it possible to compare output across platforms.
|
|
locs[i].File = filepath.ToSlash(rel)
|
|
}
|
|
|
|
return locs
|
|
}
|
|
|
|
func (m *populateLocations) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
|
|
loc := make(map[string][]dyn.Location)
|
|
_, err := dyn.Walk(b.Config.Value(), func(p dyn.Path, v dyn.Value) (dyn.Value, error) {
|
|
// Skip the root value.
|
|
if len(p) == 0 {
|
|
return v, nil
|
|
}
|
|
|
|
// Skip values that don't have locations.
|
|
// Examples include defaults or values that are set by the program itself.
|
|
locs := computeRelativeLocations(b.BundleRootPath, v)
|
|
if len(locs) > 0 {
|
|
// Semantics for a value having multiple locations can be found in [merge.Merge].
|
|
// We don't need to externalize these at the moment, so we limit the number
|
|
// of locations to 1 while still using a slice for the output. This allows us
|
|
// to include multiple entries in the future if we need to.
|
|
loc[p.String()] = locs[0:1]
|
|
}
|
|
|
|
return v, nil
|
|
})
|
|
if err != nil {
|
|
return diag.FromErr(err)
|
|
}
|
|
|
|
b.Config.Locations = loc
|
|
return nil
|
|
}
|