mirror of https://github.com/databricks/cli.git
115 lines
2.6 KiB
Go
115 lines
2.6 KiB
Go
package mutator
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
"github.com/databricks/cli/bundle"
|
|
"github.com/databricks/cli/bundle/libraries"
|
|
"github.com/databricks/cli/libs/diag"
|
|
"github.com/databricks/cli/libs/dyn"
|
|
)
|
|
|
|
type expandPipelineGlobPaths struct{}
|
|
|
|
func ExpandPipelineGlobPaths() bundle.Mutator {
|
|
return &expandPipelineGlobPaths{}
|
|
}
|
|
|
|
func (m *expandPipelineGlobPaths) expandLibrary(v dyn.Value) ([]dyn.Value, error) {
|
|
// Probe for the path field in the library.
|
|
for _, p := range []dyn.Path{
|
|
dyn.NewPath(dyn.Key("notebook"), dyn.Key("path")),
|
|
dyn.NewPath(dyn.Key("file"), dyn.Key("path")),
|
|
} {
|
|
pv, err := dyn.GetByPath(v, p)
|
|
if dyn.IsNoSuchKeyError(err) {
|
|
continue
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// If the path is empty or not a local path, return the original value.
|
|
path := pv.MustString()
|
|
if path == "" || !libraries.IsLocalPath(path) {
|
|
return []dyn.Value{v}, nil
|
|
}
|
|
|
|
dir, err := v.Location().Directory()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
matches, err := filepath.Glob(filepath.Join(dir, path))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// If there are no matches, return the original value.
|
|
if len(matches) == 0 {
|
|
return []dyn.Value{v}, nil
|
|
}
|
|
|
|
// Emit a new value for each match.
|
|
var ev []dyn.Value
|
|
for _, match := range matches {
|
|
m, err := filepath.Rel(dir, match)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
nv, err := dyn.SetByPath(v, p, dyn.NewValue(m, pv.Locations()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ev = append(ev, nv)
|
|
}
|
|
|
|
return ev, nil
|
|
}
|
|
|
|
// Neither of the library paths were found. This is likely an invalid node,
|
|
// but it isn't this mutator's job to enforce that. Return the original value.
|
|
return []dyn.Value{v}, nil
|
|
}
|
|
|
|
func (m *expandPipelineGlobPaths) expandSequence(p dyn.Path, v dyn.Value) (dyn.Value, error) {
|
|
s, ok := v.AsSequence()
|
|
if !ok {
|
|
return dyn.InvalidValue, fmt.Errorf("expected sequence, got %s", v.Kind())
|
|
}
|
|
|
|
var vs []dyn.Value
|
|
for _, sv := range s {
|
|
v, err := m.expandLibrary(sv)
|
|
if err != nil {
|
|
return dyn.InvalidValue, err
|
|
}
|
|
|
|
vs = append(vs, v...)
|
|
}
|
|
|
|
return dyn.NewValue(vs, v.Locations()), nil
|
|
}
|
|
|
|
func (m *expandPipelineGlobPaths) Apply(_ context.Context, b *bundle.Bundle) diag.Diagnostics {
|
|
err := b.Config.Mutate(func(v dyn.Value) (dyn.Value, error) {
|
|
p := dyn.NewPattern(
|
|
dyn.Key("resources"),
|
|
dyn.Key("pipelines"),
|
|
dyn.AnyKey(),
|
|
dyn.Key("libraries"),
|
|
)
|
|
|
|
// Visit each pipeline's "libraries" field and expand any glob patterns.
|
|
return dyn.MapByPattern(v, p, m.expandSequence)
|
|
})
|
|
|
|
return diag.FromErr(err)
|
|
}
|
|
|
|
func (*expandPipelineGlobPaths) Name() string {
|
|
return "ExpandPipelineGlobPaths"
|
|
}
|