Move path field to bundle type (#1316)

## Changes

The bundle path was previously stored on the `config.Root` type under
the assumption that the first configuration file being loaded would set
it. This is slightly counterintuitive and we know what the path is upon
construction of the bundle. The new location for this property reflects
this.

## Tests

Unit tests pass.
This commit is contained in:
Pieter Noordhuis 2024-03-27 10:03:24 +01:00 committed by GitHub
parent b50380471e
commit 00d76d5afa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
39 changed files with 104 additions and 124 deletions

View File

@ -46,7 +46,7 @@ func (m *build) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
// If artifact path is not provided, use bundle root dir // If artifact path is not provided, use bundle root dir
if artifact.Path == "" { if artifact.Path == "" {
artifact.Path = b.Config.Path artifact.Path = b.RootPath
} }
if !filepath.IsAbs(artifact.Path) { if !filepath.IsAbs(artifact.Path) {

View File

@ -36,8 +36,8 @@ func TestExpandGlobFilesSource(t *testing.T) {
t2.Close(t) t2.Close(t)
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: rootPath,
Config: config.Root{ Config: config.Root{
Path: rootPath,
Artifacts: map[string]*config.Artifact{ Artifacts: map[string]*config.Artifact{
"test": { "test": {
Type: "custom", Type: "custom",
@ -72,8 +72,8 @@ func TestExpandGlobFilesSourceWithNoMatches(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: rootPath,
Config: config.Root{ Config: config.Root{
Path: rootPath,
Artifacts: map[string]*config.Artifact{ Artifacts: map[string]*config.Artifact{
"test": { "test": {
Type: "custom", Type: "custom",

View File

@ -35,21 +35,21 @@ func (m *detectPkg) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostic
log.Infof(ctx, "Detecting Python wheel project...") log.Infof(ctx, "Detecting Python wheel project...")
// checking if there is setup.py in the bundle root // checking if there is setup.py in the bundle root
setupPy := filepath.Join(b.Config.Path, "setup.py") setupPy := filepath.Join(b.RootPath, "setup.py")
_, err := os.Stat(setupPy) _, err := os.Stat(setupPy)
if err != nil { if err != nil {
log.Infof(ctx, "No Python wheel project found at bundle root folder") log.Infof(ctx, "No Python wheel project found at bundle root folder")
return nil return nil
} }
log.Infof(ctx, fmt.Sprintf("Found Python wheel project at %s", b.Config.Path)) log.Infof(ctx, fmt.Sprintf("Found Python wheel project at %s", b.RootPath))
module := extractModuleName(setupPy) module := extractModuleName(setupPy)
if b.Config.Artifacts == nil { if b.Config.Artifacts == nil {
b.Config.Artifacts = make(map[string]*config.Artifact) b.Config.Artifacts = make(map[string]*config.Artifact)
} }
pkgPath, err := filepath.Abs(b.Config.Path) pkgPath, err := filepath.Abs(b.RootPath)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@ -30,7 +30,7 @@ func (*fromLibraries) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnost
tasks := libraries.FindAllWheelTasksWithLocalLibraries(b) tasks := libraries.FindAllWheelTasksWithLocalLibraries(b)
for _, task := range tasks { for _, task := range tasks {
for _, lib := range task.Libraries { for _, lib := range task.Libraries {
matches, err := filepath.Glob(filepath.Join(b.Config.Path, lib.Whl)) matches, err := filepath.Glob(filepath.Join(b.RootPath, lib.Whl))
// File referenced from libraries section does not exists, skipping // File referenced from libraries section does not exists, skipping
if err != nil { if err != nil {
continue continue

View File

@ -30,6 +30,10 @@ import (
const internalFolder = ".internal" const internalFolder = ".internal"
type Bundle struct { type Bundle struct {
// RootPath contains the directory path to the root of the bundle.
// It is set when we instantiate a new bundle instance.
RootPath string
Config config.Root Config config.Root
// Metadata about the bundle deployment. This is the interface Databricks services // Metadata about the bundle deployment. This is the interface Databricks services
@ -63,7 +67,9 @@ type Bundle struct {
} }
func Load(ctx context.Context, path string) (*Bundle, error) { func Load(ctx context.Context, path string) (*Bundle, error) {
b := &Bundle{} b := &Bundle{
RootPath: filepath.Clean(path),
}
stat, err := os.Stat(path) stat, err := os.Stat(path)
if err != nil { if err != nil {
return nil, err return nil, err
@ -75,7 +81,6 @@ func Load(ctx context.Context, path string) (*Bundle, error) {
if hasRootEnv && hasIncludesEnv && stat.IsDir() { if hasRootEnv && hasIncludesEnv && stat.IsDir() {
log.Debugf(ctx, "No bundle configuration; using bundle root: %s", path) log.Debugf(ctx, "No bundle configuration; using bundle root: %s", path)
b.Config = config.Root{ b.Config = config.Root{
Path: path,
Bundle: config.Bundle{ Bundle: config.Bundle{
Name: filepath.Base(path), Name: filepath.Base(path),
}, },
@ -158,7 +163,7 @@ func (b *Bundle) CacheDir(ctx context.Context, paths ...string) (string, error)
if !exists || cacheDirName == "" { if !exists || cacheDirName == "" {
cacheDirName = filepath.Join( cacheDirName = filepath.Join(
// Anchor at bundle root directory. // Anchor at bundle root directory.
b.Config.Path, b.RootPath,
// Static cache directory. // Static cache directory.
".databricks", ".databricks",
"bundle", "bundle",
@ -210,7 +215,7 @@ func (b *Bundle) GetSyncIncludePatterns(ctx context.Context) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
internalDirRel, err := filepath.Rel(b.Config.Path, internalDir) internalDirRel, err := filepath.Rel(b.RootPath, internalDir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -218,7 +223,7 @@ func (b *Bundle) GetSyncIncludePatterns(ctx context.Context) ([]string, error) {
} }
func (b *Bundle) GitRepository() (*git.Repository, error) { func (b *Bundle) GitRepository() (*git.Repository, error) {
rootPath, err := folders.FindDirWithLeaf(b.Config.Path, ".git") rootPath, err := folders.FindDirWithLeaf(b.RootPath, ".git")
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to locate repository root: %w", err) return nil, fmt.Errorf("unable to locate repository root: %w", err)
} }

View File

@ -77,7 +77,7 @@ func TestBundleMustLoadSuccess(t *testing.T) {
t.Setenv(env.RootVariable, "./tests/basic") t.Setenv(env.RootVariable, "./tests/basic")
b, err := MustLoad(context.Background()) b, err := MustLoad(context.Background())
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "tests/basic", filepath.ToSlash(b.Config.Path)) assert.Equal(t, "tests/basic", filepath.ToSlash(b.RootPath))
} }
func TestBundleMustLoadFailureWithEnv(t *testing.T) { func TestBundleMustLoadFailureWithEnv(t *testing.T) {
@ -96,7 +96,7 @@ func TestBundleTryLoadSuccess(t *testing.T) {
t.Setenv(env.RootVariable, "./tests/basic") t.Setenv(env.RootVariable, "./tests/basic")
b, err := TryLoad(context.Background()) b, err := TryLoad(context.Background())
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "tests/basic", filepath.ToSlash(b.Config.Path)) assert.Equal(t, "tests/basic", filepath.ToSlash(b.RootPath))
} }
func TestBundleTryLoadFailureWithEnv(t *testing.T) { func TestBundleTryLoadFailureWithEnv(t *testing.T) {

View File

@ -41,8 +41,8 @@ func TestExpandGlobPathsInPipelines(t *testing.T) {
touchEmptyFile(t, filepath.Join(dir, "skip/test7.py")) touchEmptyFile(t, filepath.Join(dir, "skip/test7.py"))
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Resources: config.Resources{ Resources: config.Resources{
Pipelines: map[string]*resources.Pipeline{ Pipelines: map[string]*resources.Pipeline{
"pipeline": { "pipeline": {

View File

@ -22,7 +22,7 @@ func (m *loadGitDetails) Name() string {
func (m *loadGitDetails) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics { func (m *loadGitDetails) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
// Load relevant git repository // Load relevant git repository
repo, err := git.NewRepository(b.Config.Path) repo, err := git.NewRepository(b.RootPath)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
@ -56,7 +56,7 @@ func (m *loadGitDetails) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagn
} }
// Compute relative path of the bundle root from the Git repo root. // Compute relative path of the bundle root from the Git repo root.
absBundlePath, err := filepath.Abs(b.Config.Path) absBundlePath, err := filepath.Abs(b.RootPath)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@ -16,8 +16,8 @@ import (
func TestProcessInclude(t *testing.T) { func TestProcessInclude(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Workspace: config.Workspace{ Workspace: config.Workspace{
Host: "foo", Host: "foo",
}, },
@ -25,7 +25,7 @@ func TestProcessInclude(t *testing.T) {
} }
relPath := "./file.yml" relPath := "./file.yml"
fullPath := filepath.Join(b.Config.Path, relPath) fullPath := filepath.Join(b.RootPath, relPath)
f, err := os.Create(fullPath) f, err := os.Create(fullPath)
require.NoError(t, err) require.NoError(t, err)
fmt.Fprint(f, "workspace:\n host: bar\n") fmt.Fprint(f, "workspace:\n host: bar\n")

View File

@ -51,7 +51,7 @@ func (m *processRootIncludes) Apply(ctx context.Context, b *bundle.Bundle) diag.
// Converts extra include paths from environment variable to relative paths // Converts extra include paths from environment variable to relative paths
for _, extraIncludePath := range getExtraIncludePaths(ctx) { for _, extraIncludePath := range getExtraIncludePaths(ctx) {
if filepath.IsAbs(extraIncludePath) { if filepath.IsAbs(extraIncludePath) {
rel, err := filepath.Rel(b.Config.Path, extraIncludePath) rel, err := filepath.Rel(b.RootPath, extraIncludePath)
if err != nil { if err != nil {
return diag.Errorf("unable to include file '%s': %v", extraIncludePath, err) return diag.Errorf("unable to include file '%s': %v", extraIncludePath, err)
} }
@ -70,7 +70,7 @@ func (m *processRootIncludes) Apply(ctx context.Context, b *bundle.Bundle) diag.
} }
// Anchor includes to the bundle root path. // Anchor includes to the bundle root path.
matches, err := filepath.Glob(filepath.Join(b.Config.Path, entry)) matches, err := filepath.Glob(filepath.Join(b.RootPath, entry))
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
@ -84,7 +84,7 @@ func (m *processRootIncludes) Apply(ctx context.Context, b *bundle.Bundle) diag.
// Filter matches to ones we haven't seen yet. // Filter matches to ones we haven't seen yet.
var includes []string var includes []string
for _, match := range matches { for _, match := range matches {
rel, err := filepath.Rel(b.Config.Path, match) rel, err := filepath.Rel(b.RootPath, match)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }
@ -99,7 +99,7 @@ func (m *processRootIncludes) Apply(ctx context.Context, b *bundle.Bundle) diag.
slices.Sort(includes) slices.Sort(includes)
files = append(files, includes...) files = append(files, includes...)
for _, include := range includes { for _, include := range includes {
out = append(out, ProcessInclude(filepath.Join(b.Config.Path, include), include)) out = append(out, ProcessInclude(filepath.Join(b.RootPath, include), include))
} }
} }

View File

@ -19,9 +19,7 @@ import (
func TestProcessRootIncludesEmpty(t *testing.T) { func TestProcessRootIncludesEmpty(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
Config: config.Root{ RootPath: ".",
Path: ".",
},
} }
diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes()) diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes())
require.NoError(t, diags.Error()) require.NoError(t, diags.Error())
@ -36,8 +34,8 @@ func TestProcessRootIncludesAbs(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: ".",
Config: config.Root{ Config: config.Root{
Path: ".",
Include: []string{ Include: []string{
"/tmp/*.yml", "/tmp/*.yml",
}, },
@ -50,17 +48,17 @@ func TestProcessRootIncludesAbs(t *testing.T) {
func TestProcessRootIncludesSingleGlob(t *testing.T) { func TestProcessRootIncludesSingleGlob(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Include: []string{ Include: []string{
"*.yml", "*.yml",
}, },
}, },
} }
testutil.Touch(t, b.Config.Path, "databricks.yml") testutil.Touch(t, b.RootPath, "databricks.yml")
testutil.Touch(t, b.Config.Path, "a.yml") testutil.Touch(t, b.RootPath, "a.yml")
testutil.Touch(t, b.Config.Path, "b.yml") testutil.Touch(t, b.RootPath, "b.yml")
diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes()) diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes())
require.NoError(t, diags.Error()) require.NoError(t, diags.Error())
@ -69,8 +67,8 @@ func TestProcessRootIncludesSingleGlob(t *testing.T) {
func TestProcessRootIncludesMultiGlob(t *testing.T) { func TestProcessRootIncludesMultiGlob(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Include: []string{ Include: []string{
"a*.yml", "a*.yml",
"b*.yml", "b*.yml",
@ -78,8 +76,8 @@ func TestProcessRootIncludesMultiGlob(t *testing.T) {
}, },
} }
testutil.Touch(t, b.Config.Path, "a1.yml") testutil.Touch(t, b.RootPath, "a1.yml")
testutil.Touch(t, b.Config.Path, "b1.yml") testutil.Touch(t, b.RootPath, "b1.yml")
diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes()) diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes())
require.NoError(t, diags.Error()) require.NoError(t, diags.Error())
@ -88,8 +86,8 @@ func TestProcessRootIncludesMultiGlob(t *testing.T) {
func TestProcessRootIncludesRemoveDups(t *testing.T) { func TestProcessRootIncludesRemoveDups(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Include: []string{ Include: []string{
"*.yml", "*.yml",
"*.yml", "*.yml",
@ -97,7 +95,7 @@ func TestProcessRootIncludesRemoveDups(t *testing.T) {
}, },
} }
testutil.Touch(t, b.Config.Path, "a.yml") testutil.Touch(t, b.RootPath, "a.yml")
diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes()) diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes())
require.NoError(t, diags.Error()) require.NoError(t, diags.Error())
@ -106,8 +104,8 @@ func TestProcessRootIncludesRemoveDups(t *testing.T) {
func TestProcessRootIncludesNotExists(t *testing.T) { func TestProcessRootIncludesNotExists(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Include: []string{ Include: []string{
"notexist.yml", "notexist.yml",
}, },
@ -125,9 +123,7 @@ func TestProcessRootIncludesExtrasFromEnvVar(t *testing.T) {
t.Setenv(env.IncludesVariable, path.Join(rootPath, testYamlName)) t.Setenv(env.IncludesVariable, path.Join(rootPath, testYamlName))
b := &bundle.Bundle{ b := &bundle.Bundle{
Config: config.Root{ RootPath: rootPath,
Path: rootPath,
},
} }
diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes()) diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes())
@ -148,9 +144,7 @@ func TestProcessRootIncludesDedupExtrasFromEnvVar(t *testing.T) {
)) ))
b := &bundle.Bundle{ b := &bundle.Bundle{
Config: config.Root{ RootPath: rootPath,
Path: rootPath,
},
} }
diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes()) diags := bundle.Apply(context.Background(), b, mutator.ProcessRootIncludes())

View File

@ -45,11 +45,11 @@ func (m *rewriteSyncPaths) makeRelativeTo(root string) dyn.MapFunc {
func (m *rewriteSyncPaths) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics { func (m *rewriteSyncPaths) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
err := b.Config.Mutate(func(v dyn.Value) (dyn.Value, error) { err := b.Config.Mutate(func(v dyn.Value) (dyn.Value, error) {
return dyn.Map(v, "sync", func(_ dyn.Path, v dyn.Value) (nv dyn.Value, err error) { return dyn.Map(v, "sync", func(_ dyn.Path, v dyn.Value) (nv dyn.Value, err error) {
v, err = dyn.Map(v, "include", dyn.Foreach(m.makeRelativeTo(b.Config.Path))) v, err = dyn.Map(v, "include", dyn.Foreach(m.makeRelativeTo(b.RootPath)))
if err != nil { if err != nil {
return dyn.NilValue, err return dyn.NilValue, err
} }
v, err = dyn.Map(v, "exclude", dyn.Foreach(m.makeRelativeTo(b.Config.Path))) v, err = dyn.Map(v, "exclude", dyn.Foreach(m.makeRelativeTo(b.RootPath)))
if err != nil { if err != nil {
return dyn.NilValue, err return dyn.NilValue, err
} }

View File

@ -14,8 +14,8 @@ import (
func TestRewriteSyncPathsRelative(t *testing.T) { func TestRewriteSyncPathsRelative(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: ".",
Config: config.Root{ Config: config.Root{
Path: ".",
Sync: config.Sync{ Sync: config.Sync{
Include: []string{ Include: []string{
"foo", "foo",
@ -45,8 +45,8 @@ func TestRewriteSyncPathsRelative(t *testing.T) {
func TestRewriteSyncPathsAbsolute(t *testing.T) { func TestRewriteSyncPathsAbsolute(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: "/tmp/dir",
Config: config.Root{ Config: config.Root{
Path: "/tmp/dir",
Sync: config.Sync{ Sync: config.Sync{
Include: []string{ Include: []string{
"foo", "foo",
@ -77,9 +77,7 @@ func TestRewriteSyncPathsAbsolute(t *testing.T) {
func TestRewriteSyncPathsErrorPaths(t *testing.T) { func TestRewriteSyncPathsErrorPaths(t *testing.T) {
t.Run("no sync block", func(t *testing.T) { t.Run("no sync block", func(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
Config: config.Root{ RootPath: ".",
Path: ".",
},
} }
diags := bundle.Apply(context.Background(), b, mutator.RewriteSyncPaths()) diags := bundle.Apply(context.Background(), b, mutator.RewriteSyncPaths())
@ -88,8 +86,8 @@ func TestRewriteSyncPathsErrorPaths(t *testing.T) {
t.Run("empty include/exclude blocks", func(t *testing.T) { t.Run("empty include/exclude blocks", func(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: ".",
Config: config.Root{ Config: config.Root{
Path: ".",
Sync: config.Sync{ Sync: config.Sync{
Include: []string{}, Include: []string{},
Exclude: []string{}, Exclude: []string{},

View File

@ -82,7 +82,7 @@ func (m *trampoline) generateNotebookWrapper(ctx context.Context, b *bundle.Bund
return err return err
} }
internalDirRel, err := filepath.Rel(b.Config.Path, internalDir) internalDirRel, err := filepath.Rel(b.RootPath, internalDir)
if err != nil { if err != nil {
return err return err
} }

View File

@ -57,8 +57,8 @@ func TestGenerateTrampoline(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: tmpDir,
Config: config.Root{ Config: config.Root{
Path: tmpDir,
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "development", Target: "development",
}, },

View File

@ -85,7 +85,7 @@ func (m *translatePaths) rewritePath(
} }
// Remote path must be relative to the bundle root. // Remote path must be relative to the bundle root.
localRelPath, err := filepath.Rel(b.Config.Path, localPath) localRelPath, err := filepath.Rel(b.RootPath, localPath)
if err != nil { if err != nil {
return err return err
} }

View File

@ -36,8 +36,8 @@ func touchEmptyFile(t *testing.T, path string) {
func TestTranslatePathsSkippedWithGitSource(t *testing.T) { func TestTranslatePathsSkippedWithGitSource(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Workspace: config.Workspace{ Workspace: config.Workspace{
FilePath: "/bundle", FilePath: "/bundle",
}, },
@ -106,8 +106,8 @@ func TestTranslatePaths(t *testing.T) {
touchEmptyFile(t, filepath.Join(dir, "dist", "task.jar")) touchEmptyFile(t, filepath.Join(dir, "dist", "task.jar"))
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Workspace: config.Workspace{ Workspace: config.Workspace{
FilePath: "/bundle", FilePath: "/bundle",
}, },
@ -273,8 +273,8 @@ func TestTranslatePathsInSubdirectories(t *testing.T) {
touchEmptyFile(t, filepath.Join(dir, "job", "my_dbt_project", "dbt_project.yml")) touchEmptyFile(t, filepath.Join(dir, "job", "my_dbt_project", "dbt_project.yml"))
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Workspace: config.Workspace{ Workspace: config.Workspace{
FilePath: "/bundle", FilePath: "/bundle",
}, },
@ -367,8 +367,8 @@ func TestTranslatePathsOutsideBundleRoot(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Workspace: config.Workspace{ Workspace: config.Workspace{
FilePath: "/bundle", FilePath: "/bundle",
}, },
@ -400,8 +400,8 @@ func TestJobNotebookDoesNotExistError(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Resources: config.Resources{ Resources: config.Resources{
Jobs: map[string]*resources.Job{ Jobs: map[string]*resources.Job{
"job": { "job": {
@ -430,8 +430,8 @@ func TestJobFileDoesNotExistError(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Resources: config.Resources{ Resources: config.Resources{
Jobs: map[string]*resources.Job{ Jobs: map[string]*resources.Job{
"job": { "job": {
@ -460,8 +460,8 @@ func TestPipelineNotebookDoesNotExistError(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Resources: config.Resources{ Resources: config.Resources{
Pipelines: map[string]*resources.Pipeline{ Pipelines: map[string]*resources.Pipeline{
"pipeline": { "pipeline": {
@ -490,8 +490,8 @@ func TestPipelineFileDoesNotExistError(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Resources: config.Resources{ Resources: config.Resources{
Pipelines: map[string]*resources.Pipeline{ Pipelines: map[string]*resources.Pipeline{
"pipeline": { "pipeline": {
@ -521,8 +521,8 @@ func TestJobSparkPythonTaskWithNotebookSourceError(t *testing.T) {
touchNotebookFile(t, filepath.Join(dir, "my_notebook.py")) touchNotebookFile(t, filepath.Join(dir, "my_notebook.py"))
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Workspace: config.Workspace{ Workspace: config.Workspace{
FilePath: "/bundle", FilePath: "/bundle",
}, },
@ -555,8 +555,8 @@ func TestJobNotebookTaskWithFileSourceError(t *testing.T) {
touchEmptyFile(t, filepath.Join(dir, "my_file.py")) touchEmptyFile(t, filepath.Join(dir, "my_file.py"))
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Workspace: config.Workspace{ Workspace: config.Workspace{
FilePath: "/bundle", FilePath: "/bundle",
}, },
@ -589,8 +589,8 @@ func TestPipelineNotebookLibraryWithFileSourceError(t *testing.T) {
touchEmptyFile(t, filepath.Join(dir, "my_file.py")) touchEmptyFile(t, filepath.Join(dir, "my_file.py"))
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Workspace: config.Workspace{ Workspace: config.Workspace{
FilePath: "/bundle", FilePath: "/bundle",
}, },
@ -623,8 +623,8 @@ func TestPipelineFileLibraryWithNotebookSourceError(t *testing.T) {
touchNotebookFile(t, filepath.Join(dir, "my_notebook.py")) touchNotebookFile(t, filepath.Join(dir, "my_notebook.py"))
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Workspace: config.Workspace{ Workspace: config.Workspace{
FilePath: "/bundle", FilePath: "/bundle",
}, },

View File

@ -5,7 +5,6 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings" "strings"
"github.com/databricks/cli/bundle/config/resources" "github.com/databricks/cli/bundle/config/resources"
@ -24,10 +23,6 @@ type Root struct {
diags diag.Diagnostics diags diag.Diagnostics
depth int depth int
// Path contains the directory path to the root of the bundle.
// It is set when loading `databricks.yml`.
Path string `json:"-" bundle:"readonly"`
// Contains user defined variables // Contains user defined variables
Variables map[string]*variable.Variable `json:"variables,omitempty"` Variables map[string]*variable.Variable `json:"variables,omitempty"`
@ -80,9 +75,7 @@ func Load(path string) (*Root, error) {
return nil, err return nil, err
} }
r := Root{ r := Root{}
Path: filepath.Dir(path),
}
// Load configuration tree from YAML. // Load configuration tree from YAML.
v, err := yamlloader.LoadYAML(path, bytes.NewBuffer(raw)) v, err := yamlloader.LoadYAML(path, bytes.NewBuffer(raw))
@ -135,12 +128,10 @@ func (r *Root) updateWithDynamicValue(nv dyn.Value) error {
// the configuration equals nil (happens in tests). // the configuration equals nil (happens in tests).
diags := r.diags diags := r.diags
depth := r.depth depth := r.depth
path := r.Path
defer func() { defer func() {
r.diags = diags r.diags = diags
r.depth = depth r.depth = depth
r.Path = path
}() }()
// Convert normalized configuration tree to typed configuration. // Convert normalized configuration tree to typed configuration.

View File

@ -28,7 +28,7 @@ func GetSyncOptions(ctx context.Context, b *bundle.Bundle) (*sync.SyncOptions, e
} }
opts := &sync.SyncOptions{ opts := &sync.SyncOptions{
LocalPath: b.Config.Path, LocalPath: b.RootPath,
RemotePath: b.Config.Workspace.FilePath, RemotePath: b.Config.Workspace.FilePath,
Include: includes, Include: includes,
Exclude: b.Config.Sync.Exclude, Exclude: b.Config.Sync.Exclude,

View File

@ -39,7 +39,7 @@ func (m *compute) Apply(_ context.Context, b *bundle.Bundle) diag.Diagnostics {
for name, job := range b.Config.Resources.Jobs { for name, job := range b.Config.Resources.Jobs {
// Compute config file path the job is defined in, relative to the bundle // Compute config file path the job is defined in, relative to the bundle
// root // root
relativePath, err := filepath.Rel(b.Config.Path, job.ConfigFilePath) relativePath, err := filepath.Rel(b.RootPath, job.ConfigFilePath)
if err != nil { if err != nil {
return diag.Errorf("failed to compute relative path for job %s: %v", name, err) return diag.Errorf("failed to compute relative path for job %s: %v", name, err)
} }

View File

@ -85,7 +85,7 @@ func (s *statePull) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostic
} }
log.Infof(ctx, "Creating new snapshot") log.Infof(ctx, "Creating new snapshot")
snapshot, err := sync.NewSnapshot(state.Files.ToSlice(b.Config.Path), opts) snapshot, err := sync.NewSnapshot(state.Files.ToSlice(b.RootPath), opts)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@ -59,8 +59,8 @@ func testStatePull(t *testing.T, opts statePullOpts) {
}} }}
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },
@ -77,11 +77,11 @@ func testStatePull(t *testing.T, opts statePullOpts) {
ctx := context.Background() ctx := context.Background()
for _, file := range opts.localFiles { for _, file := range opts.localFiles {
testutil.Touch(t, filepath.Join(b.Config.Path, "bar"), file) testutil.Touch(t, filepath.Join(b.RootPath, "bar"), file)
} }
for _, file := range opts.localNotebooks { for _, file := range opts.localNotebooks {
testutil.TouchNotebook(t, filepath.Join(b.Config.Path, "bar"), file) testutil.TouchNotebook(t, filepath.Join(b.RootPath, "bar"), file)
} }
if opts.withExistingSnapshot { if opts.withExistingSnapshot {
@ -251,8 +251,8 @@ func TestStatePullNoState(t *testing.T) {
}} }}
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },
@ -439,8 +439,8 @@ func TestStatePullNewerDeploymentStateVersion(t *testing.T) {
}} }}
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },

View File

@ -45,8 +45,8 @@ func TestStatePush(t *testing.T) {
}} }}
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },

View File

@ -22,8 +22,8 @@ func TestStateUpdate(t *testing.T) {
s := &stateUpdate{} s := &stateUpdate{}
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },
@ -39,8 +39,8 @@ func TestStateUpdate(t *testing.T) {
}, },
} }
testutil.Touch(t, b.Config.Path, "test1.py") testutil.Touch(t, b.RootPath, "test1.py")
testutil.Touch(t, b.Config.Path, "test2.py") testutil.Touch(t, b.RootPath, "test2.py")
m := mocks.NewMockWorkspaceClient(t) m := mocks.NewMockWorkspaceClient(t)
m.WorkspaceClient.Config = &databrickscfg.Config{ m.WorkspaceClient.Config = &databrickscfg.Config{
@ -82,8 +82,8 @@ func TestStateUpdateWithExistingState(t *testing.T) {
s := &stateUpdate{} s := &stateUpdate{}
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },
@ -99,8 +99,8 @@ func TestStateUpdateWithExistingState(t *testing.T) {
}, },
} }
testutil.Touch(t, b.Config.Path, "test1.py") testutil.Touch(t, b.RootPath, "test1.py")
testutil.Touch(t, b.Config.Path, "test2.py") testutil.Touch(t, b.RootPath, "test2.py")
m := mocks.NewMockWorkspaceClient(t) m := mocks.NewMockWorkspaceClient(t)
m.WorkspaceClient.Config = &databrickscfg.Config{ m.WorkspaceClient.Config = &databrickscfg.Config{

View File

@ -28,8 +28,8 @@ func TestInitEnvironmentVariables(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
Terraform: &config.Terraform{ Terraform: &config.Terraform{
@ -55,8 +55,8 @@ func TestSetTempDirEnvVarsForUnixWithTmpDirSet(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
}, },
@ -83,8 +83,8 @@ func TestSetTempDirEnvVarsForUnixWithTmpDirNotSet(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
}, },
@ -109,8 +109,8 @@ func TestSetTempDirEnvVarsForWindowWithAllTmpDirEnvVarsSet(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
}, },
@ -139,8 +139,8 @@ func TestSetTempDirEnvVarsForWindowWithUserProfileAndTempSet(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
}, },
@ -169,8 +169,8 @@ func TestSetTempDirEnvVarsForWindowsWithoutAnyTempDirEnvVarsSet(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
}, },
@ -197,8 +197,8 @@ func TestSetTempDirEnvVarsForWindowsWithoutAnyTempDirEnvVarsSet(t *testing.T) {
func TestSetProxyEnvVars(t *testing.T) { func TestSetProxyEnvVars(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
}, },

View File

@ -17,8 +17,8 @@ func TestLoadWithNoState(t *testing.T) {
} }
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Path: t.TempDir(),
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
Terraform: &config.Terraform{ Terraform: &config.Terraform{

View File

@ -32,11 +32,11 @@ func mockStateFilerForPull(t *testing.T, contents map[string]int, merr error) fi
func statePullTestBundle(t *testing.T) *bundle.Bundle { func statePullTestBundle(t *testing.T) *bundle.Bundle {
return &bundle.Bundle{ return &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },
Path: t.TempDir(),
}, },
} }
} }

View File

@ -29,11 +29,11 @@ func mockStateFilerForPush(t *testing.T, fn func(body io.Reader)) filer.Filer {
func statePushTestBundle(t *testing.T) *bundle.Bundle { func statePushTestBundle(t *testing.T) *bundle.Bundle {
return &bundle.Bundle{ return &bundle.Bundle{
RootPath: t.TempDir(),
Config: config.Root{ Config: config.Root{
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },
Path: t.TempDir(),
}, },
} }
} }

View File

@ -65,7 +65,7 @@ func findLibraryMatches(lib *compute.Library, b *bundle.Bundle) ([]string, error
return nil, nil return nil, nil
} }
fullPath := filepath.Join(b.Config.Path, path) fullPath := filepath.Join(b.RootPath, path)
return filepath.Glob(fullPath) return filepath.Glob(fullPath)
} }

View File

@ -15,8 +15,8 @@ import (
func TestMapFilesToTaskLibrariesNoGlob(t *testing.T) { func TestMapFilesToTaskLibrariesNoGlob(t *testing.T) {
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: "testdata",
Config: config.Root{ Config: config.Root{
Path: "testdata",
Resources: config.Resources{ Resources: config.Resources{
Jobs: map[string]*resources.Job{ Jobs: map[string]*resources.Job{
"job1": { "job1": {

View File

@ -18,8 +18,8 @@ func TestNoTransformByDefault(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: tmpDir,
Config: config.Root{ Config: config.Root{
Path: tmpDir,
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "development", Target: "development",
}, },
@ -63,8 +63,8 @@ func TestTransformWithExperimentalSettingSetToTrue(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: tmpDir,
Config: config.Root{ Config: config.Root{
Path: tmpDir,
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "development", Target: "development",
}, },
@ -106,7 +106,7 @@ func TestTransformWithExperimentalSettingSetToTrue(t *testing.T) {
dir, err := b.InternalDir(context.Background()) dir, err := b.InternalDir(context.Background())
require.NoError(t, err) require.NoError(t, err)
internalDirRel, err := filepath.Rel(b.Config.Path, dir) internalDirRel, err := filepath.Rel(b.RootPath, dir)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, path.Join(filepath.ToSlash(internalDirRel), "notebook_job1_key1"), task.NotebookTask.NotebookPath) require.Equal(t, path.Join(filepath.ToSlash(internalDirRel), "notebook_job1_key1"), task.NotebookTask.NotebookPath)

View File

@ -116,8 +116,8 @@ func TestTransformFiltersWheelTasksOnly(t *testing.T) {
func TestNoPanicWithNoPythonWheelTasks(t *testing.T) { func TestNoPanicWithNoPythonWheelTasks(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: tmpDir,
Config: config.Root{ Config: config.Root{
Path: tmpDir,
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "development", Target: "development",
}, },

View File

@ -106,7 +106,7 @@ func TestLoadYamlWhenIncludesEnvPresent(t *testing.T) {
cwd, err := os.Getwd() cwd, err := os.Getwd()
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, cwd, bundle.Config.Path) assert.Equal(t, cwd, bundle.RootPath)
} }
func TestLoadDefautlBundleWhenNoYamlAndRootAndIncludesEnvPresent(t *testing.T) { func TestLoadDefautlBundleWhenNoYamlAndRootAndIncludesEnvPresent(t *testing.T) {
@ -118,7 +118,7 @@ func TestLoadDefautlBundleWhenNoYamlAndRootAndIncludesEnvPresent(t *testing.T) {
bundle, err := MustLoad(ctx) bundle, err := MustLoad(ctx)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, dir, bundle.Config.Path) assert.Equal(t, dir, bundle.RootPath)
} }
func TestErrorIfNoYamlNoRootEnvAndIncludesEnvPresent(t *testing.T) { func TestErrorIfNoYamlNoRootEnvAndIncludesEnvPresent(t *testing.T) {

View File

@ -30,7 +30,7 @@ func (m *script) Name() string {
} }
func (m *script) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics { func (m *script) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
executor, err := exec.NewCommandExecutor(b.Config.Path) executor, err := exec.NewCommandExecutor(b.RootPath)
if err != nil { if err != nil {
return diag.FromErr(err) return diag.FromErr(err)
} }

View File

@ -23,7 +23,7 @@ func TestExecutesHook(t *testing.T) {
}, },
} }
executor, err := exec.NewCommandExecutor(b.Config.Path) executor, err := exec.NewCommandExecutor(b.RootPath)
require.NoError(t, err) require.NoError(t, err)
_, out, err := executeHook(context.Background(), executor, b, config.ScriptPreBuild) _, out, err := executeHook(context.Background(), executor, b, config.ScriptPreBuild)
require.NoError(t, err) require.NoError(t, err)

View File

@ -79,9 +79,7 @@ func TestPythonWheelBuildNoBuildJustUpload(t *testing.T) {
artifact := b.Config.Artifacts["my_test_code-0.0.1-py3-none-any.whl"] artifact := b.Config.Artifacts["my_test_code-0.0.1-py3-none-any.whl"]
require.NotNil(t, artifact) require.NotNil(t, artifact)
require.Empty(t, artifact.BuildCommand) require.Empty(t, artifact.BuildCommand)
require.Contains(t, artifact.Files[0].Source, filepath.Join( require.Contains(t, artifact.Files[0].Source, filepath.Join(b.RootPath, "package",
b.Config.Path,
"package",
"my_test_code-0.0.1-py3-none-any.whl", "my_test_code-0.0.1-py3-none-any.whl",
)) ))
} }

View File

@ -10,7 +10,6 @@ import (
"testing" "testing"
"github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config"
"github.com/databricks/databricks-sdk-go/experimental/mocks" "github.com/databricks/databricks-sdk-go/experimental/mocks"
"github.com/databricks/databricks-sdk-go/service/compute" "github.com/databricks/databricks-sdk-go/service/compute"
"github.com/databricks/databricks-sdk-go/service/jobs" "github.com/databricks/databricks-sdk-go/service/jobs"
@ -25,9 +24,7 @@ func TestGeneratePipelineCommand(t *testing.T) {
root := t.TempDir() root := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
Config: config.Root{ RootPath: root,
Path: root,
},
} }
m := mocks.NewMockWorkspaceClient(t) m := mocks.NewMockWorkspaceClient(t)
@ -125,9 +122,7 @@ func TestGenerateJobCommand(t *testing.T) {
root := t.TempDir() root := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
Config: config.Root{ RootPath: root,
Path: root,
},
} }
m := mocks.NewMockWorkspaceClient(t) m := mocks.NewMockWorkspaceClient(t)

View File

@ -16,9 +16,8 @@ import (
func TestSyncOptionsFromBundle(t *testing.T) { func TestSyncOptionsFromBundle(t *testing.T) {
tempDir := t.TempDir() tempDir := t.TempDir()
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: tempDir,
Config: config.Root{ Config: config.Root{
Path: tempDir,
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "default", Target: "default",
}, },

View File

@ -36,8 +36,8 @@ func TestAccUploadArtifactFileToCorrectRemotePath(t *testing.T) {
wsDir := internal.TemporaryWorkspaceDir(t, w) wsDir := internal.TemporaryWorkspaceDir(t, w)
b := &bundle.Bundle{ b := &bundle.Bundle{
RootPath: dir,
Config: config.Root{ Config: config.Root{
Path: dir,
Bundle: config.Bundle{ Bundle: config.Bundle{
Target: "whatever", Target: "whatever",
}, },