Remove dependency on `ConfigFilePath` from path translation mutator (#1437)

## Changes

This is one step toward removing the `path.Paths` struct embedding from
resource types.

Going forward, we'll exclusively use the `dyn.Value` tree for location
information.

## Tests

Existing unit tests that cover path resolution with fallback behavior
pass.
This commit is contained in:
Pieter Noordhuis 2024-05-17 11:26:09 +02:00 committed by GitHub
parent 4556d33e6b
commit dd94107853
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 35 deletions

View File

@ -213,3 +213,31 @@ func (m *translatePaths) Apply(_ context.Context, b *bundle.Bundle) diag.Diagnos
return diag.FromErr(err) return diag.FromErr(err)
} }
func gatherFallbackPaths(v dyn.Value, typ string) (map[string]string, error) {
var fallback = make(map[string]string)
var pattern = dyn.NewPattern(dyn.Key("resources"), dyn.Key(typ), dyn.AnyKey())
// Previous behavior was to use a resource's location as the base path to resolve
// relative paths in its definition. With the introduction of [dyn.Value] throughout,
// we can use the location of the [dyn.Value] of the relative path itself.
//
// This is more flexible, as resources may have overrides that are not
// located in the same directory as the resource configuration file.
//
// To maintain backwards compatibility, we allow relative paths to be resolved using
// the original approach as fallback if the [dyn.Value] location cannot be resolved.
_, err := dyn.MapByPattern(v, pattern, func(p dyn.Path, v dyn.Value) (dyn.Value, error) {
key := p[2].Key()
dir, err := v.Location().Directory()
if err != nil {
return dyn.InvalidValue, fmt.Errorf("unable to determine directory for %s: %w", p, err)
}
fallback[key] = dir
return v, nil
})
if err != nil {
return nil, err
}
return fallback, nil
}

View File

@ -55,21 +55,14 @@ func rewritePatterns(base dyn.Pattern) []jobRewritePattern {
} }
func (m *translatePaths) applyJobTranslations(b *bundle.Bundle, v dyn.Value) (dyn.Value, error) { func (m *translatePaths) applyJobTranslations(b *bundle.Bundle, v dyn.Value) (dyn.Value, error) {
var fallback = make(map[string]string) fallback, err := gatherFallbackPaths(v, "jobs")
var ignore []string
var err error
for key, job := range b.Config.Resources.Jobs {
dir, err := job.ConfigFileDirectory()
if err != nil { if err != nil {
return dyn.InvalidValue, fmt.Errorf("unable to determine directory for job %s: %w", key, err) return dyn.InvalidValue, err
} }
// If we cannot resolve the relative path using the [dyn.Value] location itself, // Do not translate job task paths if using Git source
// use the job's location as fallback. This is necessary for backwards compatibility. var ignore []string
fallback[key] = dir for key, job := range b.Config.Resources.Jobs {
// Do not translate job task paths if using git source
if job.GitSource != nil { if job.GitSource != nil {
ignore = append(ignore, key) ignore = append(ignore, key)
} }

View File

@ -8,18 +8,9 @@ import (
) )
func (m *translatePaths) applyPipelineTranslations(b *bundle.Bundle, v dyn.Value) (dyn.Value, error) { func (m *translatePaths) applyPipelineTranslations(b *bundle.Bundle, v dyn.Value) (dyn.Value, error) {
var fallback = make(map[string]string) fallback, err := gatherFallbackPaths(v, "pipelines")
var err error
for key, pipeline := range b.Config.Resources.Pipelines {
dir, err := pipeline.ConfigFileDirectory()
if err != nil { if err != nil {
return dyn.InvalidValue, fmt.Errorf("unable to determine directory for pipeline %s: %w", key, err) return dyn.InvalidValue, err
}
// If we cannot resolve the relative path using the [dyn.Value] location itself,
// use the pipeline's location as fallback. This is necessary for backwards compatibility.
fallback[key] = dir
} }
// Base pattern to match all libraries in all pipelines. // Base pattern to match all libraries in all pipelines.

View File

@ -1,9 +1,6 @@
package paths package paths
import ( import (
"fmt"
"path/filepath"
"github.com/databricks/cli/libs/dyn" "github.com/databricks/cli/libs/dyn"
) )
@ -23,10 +20,3 @@ func (p *Paths) ConfigureConfigFilePath() {
} }
p.ConfigFilePath = p.DynamicValue.Location().File p.ConfigFilePath = p.DynamicValue.Location().File
} }
func (p *Paths) ConfigFileDirectory() (string, error) {
if p.ConfigFilePath == "" {
return "", fmt.Errorf("config file path not configured")
}
return filepath.Dir(p.ConfigFilePath), nil
}