mirror of https://github.com/databricks/cli.git
Compare commits
12 Commits
4373e7b513
...
90f360b08b
Author | SHA1 | Date |
---|---|---|
|
90f360b08b | |
|
dd10eedb14 | |
|
dd20a52743 | |
|
367048bde5 | |
|
e22ba75062 | |
|
14e73acb11 | |
|
dd28a56b7d | |
|
b4bd47f4ba | |
|
65ad2f0557 | |
|
1d1aa0a416 | |
|
56cd96cb93 | |
|
a1dca56abf |
|
@ -24,7 +24,7 @@ func TestExpandGlobs_Nominal(t *testing.T) {
|
||||||
testutil.Touch(t, tmpDir, "bc.txt")
|
testutil.Touch(t, tmpDir, "bc.txt")
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: tmpDir,
|
BundleRootPath: tmpDir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Artifacts: config.Artifacts{
|
Artifacts: config.Artifacts{
|
||||||
"test": {
|
"test": {
|
||||||
|
@ -63,7 +63,7 @@ func TestExpandGlobs_InvalidPattern(t *testing.T) {
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: tmpDir,
|
BundleRootPath: tmpDir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Artifacts: config.Artifacts{
|
Artifacts: config.Artifacts{
|
||||||
"test": {
|
"test": {
|
||||||
|
@ -111,7 +111,7 @@ func TestExpandGlobs_NoMatches(t *testing.T) {
|
||||||
testutil.Touch(t, tmpDir, "b2.txt")
|
testutil.Touch(t, tmpDir, "b2.txt")
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: tmpDir,
|
BundleRootPath: tmpDir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Artifacts: config.Artifacts{
|
Artifacts: config.Artifacts{
|
||||||
"test": {
|
"test": {
|
||||||
|
|
|
@ -47,7 +47,7 @@ func (m *prepare) 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.RootPath
|
artifact.Path = b.BundleRootPath
|
||||||
}
|
}
|
||||||
|
|
||||||
if !filepath.IsAbs(artifact.Path) {
|
if !filepath.IsAbs(artifact.Path) {
|
||||||
|
|
|
@ -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.RootPath, "setup.py")
|
setupPy := filepath.Join(b.BundleRootPath, "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.RootPath))
|
log.Infof(ctx, fmt.Sprintf("Found Python wheel project at %s", b.BundleRootPath))
|
||||||
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.RootPath)
|
pkgPath, err := filepath.Abs(b.BundleRootPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,22 +31,26 @@ import (
|
||||||
const internalFolder = ".internal"
|
const internalFolder = ".internal"
|
||||||
|
|
||||||
type Bundle struct {
|
type Bundle struct {
|
||||||
// RootPath contains the directory path to the root of the bundle.
|
// BundleRootPath is the local path to the root directory of the bundle.
|
||||||
// It is set when we instantiate a new bundle instance.
|
// It is set when we instantiate a new bundle instance.
|
||||||
RootPath string
|
BundleRootPath string
|
||||||
|
|
||||||
// BundleRoot is a virtual filesystem path to the root of the bundle.
|
// BundleRoot is a virtual filesystem path to [BundleRootPath].
|
||||||
// Exclusively use this field for filesystem operations.
|
// Exclusively use this field for filesystem operations.
|
||||||
BundleRoot vfs.Path
|
BundleRoot vfs.Path
|
||||||
|
|
||||||
// SyncRoot is a virtual filesystem path to the root directory of the files that are synchronized to the workspace.
|
|
||||||
// It can be an ancestor to [BundleRoot], but not a descendant; that is, [SyncRoot] must contain [BundleRoot].
|
|
||||||
SyncRoot vfs.Path
|
|
||||||
|
|
||||||
// SyncRootPath is the local path to the root directory of files that are synchronized to the workspace.
|
// SyncRootPath is the local path to the root directory of files that are synchronized to the workspace.
|
||||||
// It is equal to `SyncRoot.Native()` and included as dedicated field for convenient access.
|
// By default, it is the same as [BundleRootPath].
|
||||||
|
// If it is different, it must be an ancestor to [BundleRootPath].
|
||||||
|
// That is, [SyncRootPath] must contain [BundleRootPath].
|
||||||
SyncRootPath string
|
SyncRootPath string
|
||||||
|
|
||||||
|
// SyncRoot is a virtual filesystem path to [SyncRootPath].
|
||||||
|
// Exclusively use this field for filesystem operations.
|
||||||
|
SyncRoot vfs.Path
|
||||||
|
|
||||||
|
// Config contains the bundle configuration.
|
||||||
|
// It is loaded from the bundle configuration files and mutators may update it.
|
||||||
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
|
||||||
|
@ -84,14 +88,14 @@ 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),
|
BundleRootPath: filepath.Clean(path),
|
||||||
BundleRoot: vfs.MustNew(path),
|
BundleRoot: vfs.MustNew(path),
|
||||||
}
|
}
|
||||||
configFile, err := config.FileNames.FindInPath(path)
|
configFile, err := config.FileNames.FindInPath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Debugf(ctx, "Found bundle root at %s (file %s)", b.RootPath, configFile)
|
log.Debugf(ctx, "Found bundle root at %s (file %s)", b.BundleRootPath, configFile)
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +164,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.RootPath,
|
b.BundleRootPath,
|
||||||
// Static cache directory.
|
// Static cache directory.
|
||||||
".databricks",
|
".databricks",
|
||||||
"bundle",
|
"bundle",
|
||||||
|
@ -212,7 +216,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.RootPath, internalDir)
|
internalDirRel, err := filepath.Rel(b.BundleRootPath, internalDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func (r ReadOnlyBundle) Config() config.Root {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r ReadOnlyBundle) RootPath() string {
|
func (r ReadOnlyBundle) RootPath() string {
|
||||||
return r.b.RootPath
|
return r.b.BundleRootPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r ReadOnlyBundle) BundleRoot() vfs.Path {
|
func (r ReadOnlyBundle) BundleRoot() vfs.Path {
|
||||||
|
|
|
@ -79,7 +79,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.RootPath))
|
assert.Equal(t, "tests/basic", filepath.ToSlash(b.BundleRootPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBundleMustLoadFailureWithEnv(t *testing.T) {
|
func TestBundleMustLoadFailureWithEnv(t *testing.T) {
|
||||||
|
@ -98,7 +98,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.RootPath))
|
assert.Equal(t, "tests/basic", filepath.ToSlash(b.BundleRootPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBundleTryLoadFailureWithEnv(t *testing.T) {
|
func TestBundleTryLoadFailureWithEnv(t *testing.T) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ func (m *entryPoint) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *entryPoint) Apply(_ context.Context, b *bundle.Bundle) diag.Diagnostics {
|
func (m *entryPoint) Apply(_ context.Context, b *bundle.Bundle) diag.Diagnostics {
|
||||||
path, err := config.FileNames.FindInPath(b.RootPath)
|
path, err := config.FileNames.FindInPath(b.BundleRootPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ func TestEntryPointNoRootPath(t *testing.T) {
|
||||||
|
|
||||||
func TestEntryPoint(t *testing.T) {
|
func TestEntryPoint(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "testdata/basic",
|
BundleRootPath: "testdata/basic",
|
||||||
}
|
}
|
||||||
diags := bundle.Apply(context.Background(), b, loader.EntryPoint())
|
diags := bundle.Apply(context.Background(), b, loader.EntryPoint())
|
||||||
require.NoError(t, diags.Error())
|
require.NoError(t, diags.Error())
|
||||||
|
|
|
@ -122,7 +122,7 @@ func validateSingleResourceDefined(configRoot dyn.Value, ext, typ string) diag.D
|
||||||
return diag.Diagnostics{
|
return diag.Diagnostics{
|
||||||
{
|
{
|
||||||
Severity: diag.Recommendation,
|
Severity: diag.Recommendation,
|
||||||
Summary: fmt.Sprintf("We recommend only defining a single %s in a file with the %s extension.", typ, ext),
|
Summary: fmt.Sprintf("define a single %s in a file with the %s extension.", strings.ReplaceAll(typ, "_", " "), ext),
|
||||||
Detail: detail.String(),
|
Detail: detail.String(),
|
||||||
Locations: locations,
|
Locations: locations,
|
||||||
Paths: paths,
|
Paths: paths,
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
|
|
||||||
func TestProcessInclude(t *testing.T) {
|
func TestProcessInclude(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "testdata/basic",
|
BundleRootPath: "testdata/basic",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Workspace: config.Workspace{
|
Workspace: config.Workspace{
|
||||||
Host: "foo",
|
Host: "foo",
|
||||||
|
@ -24,7 +24,7 @@ func TestProcessInclude(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
m := loader.ProcessInclude(filepath.Join(b.RootPath, "host.yml"), "host.yml")
|
m := loader.ProcessInclude(filepath.Join(b.BundleRootPath, "host.yml"), "host.yml")
|
||||||
assert.Equal(t, "ProcessInclude(host.yml)", m.Name())
|
assert.Equal(t, "ProcessInclude(host.yml)", m.Name())
|
||||||
|
|
||||||
// Assert the host value prior to applying the mutator
|
// Assert the host value prior to applying the mutator
|
||||||
|
@ -36,16 +36,17 @@ func TestProcessInclude(t *testing.T) {
|
||||||
assert.Equal(t, "bar", b.Config.Workspace.Host)
|
assert.Equal(t, "bar", b.Config.Workspace.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestProcessIncludeFormatPass(t *testing.T) {
|
func TestProcessIncludeFormatMatch(t *testing.T) {
|
||||||
for _, fileName := range []string{
|
for _, fileName := range []string{
|
||||||
"one_job.job.yml",
|
"one_job.job.yml",
|
||||||
"one_pipeline.pipeline.yaml",
|
"one_pipeline.pipeline.yaml",
|
||||||
"two_job.yml",
|
"two_job.yml",
|
||||||
"job_and_pipeline.yml",
|
"job_and_pipeline.yml",
|
||||||
|
"multiple_resources.yml",
|
||||||
} {
|
} {
|
||||||
t.Run(fileName, func(t *testing.T) {
|
t.Run(fileName, func(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "testdata/format_pass",
|
BundleRootPath: "testdata/format_match",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Name: "format_test",
|
Name: "format_test",
|
||||||
|
@ -53,23 +54,23 @@ func TestProcessIncludeFormatPass(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
m := loader.ProcessInclude(filepath.Join(b.RootPath, fileName), fileName)
|
m := loader.ProcessInclude(filepath.Join(b.BundleRootPath, fileName), fileName)
|
||||||
diags := bundle.Apply(context.Background(), b, m)
|
diags := bundle.Apply(context.Background(), b, m)
|
||||||
assert.Empty(t, diags)
|
assert.Empty(t, diags)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestProcessIncludeFormatFail(t *testing.T) {
|
func TestProcessIncludeFormatNotMatch(t *testing.T) {
|
||||||
for fileName, expectedDiags := range map[string]diag.Diagnostics{
|
for fileName, expectedDiags := range map[string]diag.Diagnostics{
|
||||||
"single_job.pipeline.yaml": {
|
"single_job.pipeline.yaml": {
|
||||||
{
|
{
|
||||||
Severity: diag.Recommendation,
|
Severity: diag.Recommendation,
|
||||||
Summary: "We recommend only defining a single pipeline in a file with the .pipeline.yaml extension.",
|
Summary: "define a single pipeline in a file with the .pipeline.yaml extension.",
|
||||||
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n",
|
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n",
|
||||||
Locations: []dyn.Location{
|
Locations: []dyn.Location{
|
||||||
{File: filepath.FromSlash("testdata/format_fail/single_job.pipeline.yaml"), Line: 11, Column: 11},
|
{File: filepath.FromSlash("testdata/format_not_match/single_job.pipeline.yaml"), Line: 11, Column: 11},
|
||||||
{File: filepath.FromSlash("testdata/format_fail/single_job.pipeline.yaml"), Line: 4, Column: 7},
|
{File: filepath.FromSlash("testdata/format_not_match/single_job.pipeline.yaml"), Line: 4, Column: 7},
|
||||||
},
|
},
|
||||||
Paths: []dyn.Path{
|
Paths: []dyn.Path{
|
||||||
dyn.MustPathFromString("resources.jobs.job1"),
|
dyn.MustPathFromString("resources.jobs.job1"),
|
||||||
|
@ -80,11 +81,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
||||||
"job_and_pipeline.job.yml": {
|
"job_and_pipeline.job.yml": {
|
||||||
{
|
{
|
||||||
Severity: diag.Recommendation,
|
Severity: diag.Recommendation,
|
||||||
Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
|
Summary: "define a single job in a file with the .job.yml extension.",
|
||||||
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n",
|
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n",
|
||||||
Locations: []dyn.Location{
|
Locations: []dyn.Location{
|
||||||
{File: filepath.FromSlash("testdata/format_fail/job_and_pipeline.job.yml"), Line: 11, Column: 11},
|
{File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.job.yml"), Line: 11, Column: 11},
|
||||||
{File: filepath.FromSlash("testdata/format_fail/job_and_pipeline.job.yml"), Line: 4, Column: 7},
|
{File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.job.yml"), Line: 4, Column: 7},
|
||||||
},
|
},
|
||||||
Paths: []dyn.Path{
|
Paths: []dyn.Path{
|
||||||
dyn.MustPathFromString("resources.pipelines.pipeline1"),
|
dyn.MustPathFromString("resources.pipelines.pipeline1"),
|
||||||
|
@ -95,11 +96,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
||||||
"job_and_pipeline.experiment.yml": {
|
"job_and_pipeline.experiment.yml": {
|
||||||
{
|
{
|
||||||
Severity: diag.Recommendation,
|
Severity: diag.Recommendation,
|
||||||
Summary: "We recommend only defining a single experiment in a file with the .experiment.yml extension.",
|
Summary: "define a single experiment in a file with the .experiment.yml extension.",
|
||||||
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n",
|
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n",
|
||||||
Locations: []dyn.Location{
|
Locations: []dyn.Location{
|
||||||
{File: filepath.FromSlash("testdata/format_fail/job_and_pipeline.experiment.yml"), Line: 11, Column: 11},
|
{File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.experiment.yml"), Line: 11, Column: 11},
|
||||||
{File: filepath.FromSlash("testdata/format_fail/job_and_pipeline.experiment.yml"), Line: 4, Column: 7},
|
{File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.experiment.yml"), Line: 4, Column: 7},
|
||||||
},
|
},
|
||||||
Paths: []dyn.Path{
|
Paths: []dyn.Path{
|
||||||
dyn.MustPathFromString("resources.pipelines.pipeline1"),
|
dyn.MustPathFromString("resources.pipelines.pipeline1"),
|
||||||
|
@ -110,11 +111,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
||||||
"two_jobs.job.yml": {
|
"two_jobs.job.yml": {
|
||||||
{
|
{
|
||||||
Severity: diag.Recommendation,
|
Severity: diag.Recommendation,
|
||||||
Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
|
Summary: "define a single job in a file with the .job.yml extension.",
|
||||||
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
|
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
|
||||||
Locations: []dyn.Location{
|
Locations: []dyn.Location{
|
||||||
{File: filepath.FromSlash("testdata/format_fail/two_jobs.job.yml"), Line: 4, Column: 7},
|
{File: filepath.FromSlash("testdata/format_not_match/two_jobs.job.yml"), Line: 4, Column: 7},
|
||||||
{File: filepath.FromSlash("testdata/format_fail/two_jobs.job.yml"), Line: 7, Column: 7},
|
{File: filepath.FromSlash("testdata/format_not_match/two_jobs.job.yml"), Line: 7, Column: 7},
|
||||||
},
|
},
|
||||||
Paths: []dyn.Path{
|
Paths: []dyn.Path{
|
||||||
dyn.MustPathFromString("resources.jobs.job1"),
|
dyn.MustPathFromString("resources.jobs.job1"),
|
||||||
|
@ -125,11 +126,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
||||||
"second_job_in_target.job.yml": {
|
"second_job_in_target.job.yml": {
|
||||||
{
|
{
|
||||||
Severity: diag.Recommendation,
|
Severity: diag.Recommendation,
|
||||||
Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
|
Summary: "define a single job in a file with the .job.yml extension.",
|
||||||
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
|
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
|
||||||
Locations: []dyn.Location{
|
Locations: []dyn.Location{
|
||||||
{File: filepath.FromSlash("testdata/format_fail/second_job_in_target.job.yml"), Line: 11, Column: 11},
|
{File: filepath.FromSlash("testdata/format_not_match/second_job_in_target.job.yml"), Line: 11, Column: 11},
|
||||||
{File: filepath.FromSlash("testdata/format_fail/second_job_in_target.job.yml"), Line: 4, Column: 7},
|
{File: filepath.FromSlash("testdata/format_not_match/second_job_in_target.job.yml"), Line: 4, Column: 7},
|
||||||
},
|
},
|
||||||
Paths: []dyn.Path{
|
Paths: []dyn.Path{
|
||||||
dyn.MustPathFromString("resources.jobs.job1"),
|
dyn.MustPathFromString("resources.jobs.job1"),
|
||||||
|
@ -140,11 +141,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
||||||
"two_jobs_in_target.job.yml": {
|
"two_jobs_in_target.job.yml": {
|
||||||
{
|
{
|
||||||
Severity: diag.Recommendation,
|
Severity: diag.Recommendation,
|
||||||
Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
|
Summary: "define a single job in a file with the .job.yml extension.",
|
||||||
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
|
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
|
||||||
Locations: []dyn.Location{
|
Locations: []dyn.Location{
|
||||||
{File: filepath.FromSlash("testdata/format_fail/two_jobs_in_target.job.yml"), Line: 6, Column: 11},
|
{File: filepath.FromSlash("testdata/format_not_match/two_jobs_in_target.job.yml"), Line: 6, Column: 11},
|
||||||
{File: filepath.FromSlash("testdata/format_fail/two_jobs_in_target.job.yml"), Line: 8, Column: 11},
|
{File: filepath.FromSlash("testdata/format_not_match/two_jobs_in_target.job.yml"), Line: 8, Column: 11},
|
||||||
},
|
},
|
||||||
Paths: []dyn.Path{
|
Paths: []dyn.Path{
|
||||||
dyn.MustPathFromString("targets.target1.resources.jobs.job1"),
|
dyn.MustPathFromString("targets.target1.resources.jobs.job1"),
|
||||||
|
@ -152,10 +153,55 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"multiple_resources.model_serving_endpoint.yml": {
|
||||||
|
{
|
||||||
|
Severity: diag.Recommendation,
|
||||||
|
Summary: "define a single model serving endpoint in a file with the .model_serving_endpoint.yml extension.",
|
||||||
|
Detail: `The following resources are defined or configured in this file:
|
||||||
|
- experiment1 (experiment)
|
||||||
|
- job1 (job)
|
||||||
|
- job2 (job)
|
||||||
|
- job3 (job)
|
||||||
|
- model1 (model)
|
||||||
|
- model_serving_endpoint1 (model_serving_endpoint)
|
||||||
|
- pipeline1 (pipeline)
|
||||||
|
- pipeline2 (pipeline)
|
||||||
|
- quality_monitor1 (quality_monitor)
|
||||||
|
- registered_model1 (registered_model)
|
||||||
|
- schema1 (schema)
|
||||||
|
`,
|
||||||
|
Locations: []dyn.Location{
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 12, Column: 7},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 14, Column: 7},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 18, Column: 7},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 22, Column: 7},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 24, Column: 7},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 28, Column: 7},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 35, Column: 11},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 39, Column: 11},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 43, Column: 11},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 4, Column: 7},
|
||||||
|
{File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 8, Column: 7},
|
||||||
|
},
|
||||||
|
Paths: []dyn.Path{
|
||||||
|
dyn.MustPathFromString("resources.experiments.experiment1"),
|
||||||
|
dyn.MustPathFromString("resources.jobs.job1"),
|
||||||
|
dyn.MustPathFromString("resources.jobs.job2"),
|
||||||
|
dyn.MustPathFromString("resources.model_serving_endpoints.model_serving_endpoint1"),
|
||||||
|
dyn.MustPathFromString("resources.models.model1"),
|
||||||
|
dyn.MustPathFromString("resources.pipelines.pipeline1"),
|
||||||
|
dyn.MustPathFromString("resources.pipelines.pipeline2"),
|
||||||
|
dyn.MustPathFromString("resources.schemas.schema1"),
|
||||||
|
dyn.MustPathFromString("targets.target1.resources.jobs.job3"),
|
||||||
|
dyn.MustPathFromString("targets.target1.resources.quality_monitors.quality_monitor1"),
|
||||||
|
dyn.MustPathFromString("targets.target1.resources.registered_models.registered_model1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(fileName, func(t *testing.T) {
|
t.Run(fileName, func(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "testdata/format_fail",
|
BundleRootPath: "testdata/format_not_match",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Name: "format_test",
|
Name: "format_test",
|
||||||
|
@ -163,7 +209,7 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
m := loader.ProcessInclude(filepath.Join(b.RootPath, fileName), fileName)
|
m := loader.ProcessInclude(filepath.Join(b.BundleRootPath, fileName), fileName)
|
||||||
diags := bundle.Apply(context.Background(), b, m)
|
diags := bundle.Apply(context.Background(), b, m)
|
||||||
require.Len(t, diags, 1)
|
require.Len(t, diags, 1)
|
||||||
assert.Equal(t, expectedDiags, diags)
|
assert.Equal(t, expectedDiags, diags)
|
||||||
|
|
|
@ -47,7 +47,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.RootPath, entry))
|
matches, err := filepath.Glob(filepath.Join(b.BundleRootPath, entry))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,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.RootPath, match)
|
rel, err := filepath.Rel(b.BundleRootPath, match)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,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.RootPath, include), include))
|
out = append(out, ProcessInclude(filepath.Join(b.BundleRootPath, include), include))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
func TestProcessRootIncludesEmpty(t *testing.T) {
|
func TestProcessRootIncludesEmpty(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: ".",
|
BundleRootPath: ".",
|
||||||
}
|
}
|
||||||
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
||||||
require.NoError(t, diags.Error())
|
require.NoError(t, diags.Error())
|
||||||
|
@ -30,7 +30,7 @@ func TestProcessRootIncludesAbs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: ".",
|
BundleRootPath: ".",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Include: []string{
|
Include: []string{
|
||||||
"/tmp/*.yml",
|
"/tmp/*.yml",
|
||||||
|
@ -44,7 +44,7 @@ func TestProcessRootIncludesAbs(t *testing.T) {
|
||||||
|
|
||||||
func TestProcessRootIncludesSingleGlob(t *testing.T) {
|
func TestProcessRootIncludesSingleGlob(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Include: []string{
|
Include: []string{
|
||||||
"*.yml",
|
"*.yml",
|
||||||
|
@ -52,9 +52,9 @@ func TestProcessRootIncludesSingleGlob(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
testutil.Touch(t, b.RootPath, "databricks.yml")
|
testutil.Touch(t, b.BundleRootPath, "databricks.yml")
|
||||||
testutil.Touch(t, b.RootPath, "a.yml")
|
testutil.Touch(t, b.BundleRootPath, "a.yml")
|
||||||
testutil.Touch(t, b.RootPath, "b.yml")
|
testutil.Touch(t, b.BundleRootPath, "b.yml")
|
||||||
|
|
||||||
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
||||||
require.NoError(t, diags.Error())
|
require.NoError(t, diags.Error())
|
||||||
|
@ -63,7 +63,7 @@ func TestProcessRootIncludesSingleGlob(t *testing.T) {
|
||||||
|
|
||||||
func TestProcessRootIncludesMultiGlob(t *testing.T) {
|
func TestProcessRootIncludesMultiGlob(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Include: []string{
|
Include: []string{
|
||||||
"a*.yml",
|
"a*.yml",
|
||||||
|
@ -72,8 +72,8 @@ func TestProcessRootIncludesMultiGlob(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
testutil.Touch(t, b.RootPath, "a1.yml")
|
testutil.Touch(t, b.BundleRootPath, "a1.yml")
|
||||||
testutil.Touch(t, b.RootPath, "b1.yml")
|
testutil.Touch(t, b.BundleRootPath, "b1.yml")
|
||||||
|
|
||||||
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
||||||
require.NoError(t, diags.Error())
|
require.NoError(t, diags.Error())
|
||||||
|
@ -82,7 +82,7 @@ func TestProcessRootIncludesMultiGlob(t *testing.T) {
|
||||||
|
|
||||||
func TestProcessRootIncludesRemoveDups(t *testing.T) {
|
func TestProcessRootIncludesRemoveDups(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Include: []string{
|
Include: []string{
|
||||||
"*.yml",
|
"*.yml",
|
||||||
|
@ -91,7 +91,7 @@ func TestProcessRootIncludesRemoveDups(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
testutil.Touch(t, b.RootPath, "a.yml")
|
testutil.Touch(t, b.BundleRootPath, "a.yml")
|
||||||
|
|
||||||
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
||||||
require.NoError(t, diags.Error())
|
require.NoError(t, diags.Error())
|
||||||
|
@ -100,7 +100,7 @@ func TestProcessRootIncludesRemoveDups(t *testing.T) {
|
||||||
|
|
||||||
func TestProcessRootIncludesNotExists(t *testing.T) {
|
func TestProcessRootIncludesNotExists(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Include: []string{
|
Include: []string{
|
||||||
"notexist.yml",
|
"notexist.yml",
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
bundle:
|
|
||||||
name: format_test
|
|
|
@ -1,7 +0,0 @@
|
||||||
resources:
|
|
||||||
jobs:
|
|
||||||
foo:
|
|
||||||
name: foo
|
|
||||||
|
|
||||||
bar:
|
|
||||||
name: bar
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
resources:
|
||||||
|
experiments:
|
||||||
|
experiment1:
|
||||||
|
name: experiment1
|
||||||
|
|
||||||
|
model_serving_endpoints:
|
||||||
|
model_serving_endpoint1:
|
||||||
|
name: model_serving_endpoint1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
job1:
|
||||||
|
name: job1
|
||||||
|
job2:
|
||||||
|
name: job2
|
||||||
|
|
||||||
|
models:
|
||||||
|
model1:
|
||||||
|
name: model1
|
||||||
|
|
||||||
|
pipelines:
|
||||||
|
pipeline1:
|
||||||
|
name: pipeline1
|
||||||
|
pipeline2:
|
||||||
|
name: pipeline2
|
||||||
|
|
||||||
|
schemas:
|
||||||
|
schema1:
|
||||||
|
name: schema1
|
||||||
|
|
||||||
|
targets:
|
||||||
|
target1:
|
||||||
|
resources:
|
||||||
|
quality_monitors:
|
||||||
|
quality_monitor1:
|
||||||
|
baseline_table_name: quality_monitor1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
job3:
|
||||||
|
name: job3
|
||||||
|
|
||||||
|
registered_models:
|
||||||
|
registered_model1:
|
||||||
|
name: registered_model1
|
|
@ -1,4 +1,3 @@
|
||||||
# TODO: Remove all the schema inlined references
|
|
||||||
resources:
|
resources:
|
||||||
pipelines:
|
pipelines:
|
||||||
pipeline1:
|
pipeline1:
|
43
bundle/config/loader/testdata/format_not_match/multiple_resources.model_serving_endpoint.yml
vendored
Normal file
43
bundle/config/loader/testdata/format_not_match/multiple_resources.model_serving_endpoint.yml
vendored
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
resources:
|
||||||
|
experiments:
|
||||||
|
experiment1:
|
||||||
|
name: experiment1
|
||||||
|
|
||||||
|
model_serving_endpoints:
|
||||||
|
model_serving_endpoint1:
|
||||||
|
name: model_serving_endpoint1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
job1:
|
||||||
|
name: job1
|
||||||
|
job2:
|
||||||
|
name: job2
|
||||||
|
|
||||||
|
models:
|
||||||
|
model1:
|
||||||
|
name: model1
|
||||||
|
|
||||||
|
pipelines:
|
||||||
|
pipeline1:
|
||||||
|
name: pipeline1
|
||||||
|
pipeline2:
|
||||||
|
name: pipeline2
|
||||||
|
|
||||||
|
schemas:
|
||||||
|
schema1:
|
||||||
|
name: schema1
|
||||||
|
|
||||||
|
targets:
|
||||||
|
target1:
|
||||||
|
resources:
|
||||||
|
quality_monitors:
|
||||||
|
quality_monitor1:
|
||||||
|
baseline_table_name: quality_monitor1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
job3:
|
||||||
|
name: job3
|
||||||
|
|
||||||
|
registered_models:
|
||||||
|
registered_model1:
|
||||||
|
name: registered_model1
|
|
@ -42,7 +42,7 @@ 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,
|
BundleRootPath: dir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Resources: config.Resources{
|
Resources: config.Resources{
|
||||||
Pipelines: map[string]*resources.Pipeline{
|
Pipelines: map[string]*resources.Pipeline{
|
||||||
|
|
|
@ -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.RootPath)
|
absBundlePath, err := filepath.Abs(b.BundleRootPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ func (m *pythonMutator) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagno
|
||||||
return dyn.InvalidValue, fmt.Errorf("failed to create cache dir: %w", err)
|
return dyn.InvalidValue, fmt.Errorf("failed to create cache dir: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rightRoot, diags := m.runPythonMutator(ctx, cacheDir, b.RootPath, pythonPath, leftRoot)
|
rightRoot, diags := m.runPythonMutator(ctx, cacheDir, b.BundleRootPath, pythonPath, leftRoot)
|
||||||
mutateDiags = diags
|
mutateDiags = diags
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return dyn.InvalidValue, mutateDiagsHasError
|
return dyn.InvalidValue, mutateDiagsHasError
|
||||||
|
|
|
@ -45,15 +45,15 @@ 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, "paths", dyn.Foreach(m.makeRelativeTo(b.RootPath)))
|
v, err = dyn.Map(v, "paths", dyn.Foreach(m.makeRelativeTo(b.BundleRootPath)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dyn.InvalidValue, err
|
return dyn.InvalidValue, err
|
||||||
}
|
}
|
||||||
v, err = dyn.Map(v, "include", dyn.Foreach(m.makeRelativeTo(b.RootPath)))
|
v, err = dyn.Map(v, "include", dyn.Foreach(m.makeRelativeTo(b.BundleRootPath)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dyn.InvalidValue, err
|
return dyn.InvalidValue, err
|
||||||
}
|
}
|
||||||
v, err = dyn.Map(v, "exclude", dyn.Foreach(m.makeRelativeTo(b.RootPath)))
|
v, err = dyn.Map(v, "exclude", dyn.Foreach(m.makeRelativeTo(b.BundleRootPath)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dyn.InvalidValue, err
|
return dyn.InvalidValue, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
func TestRewriteSyncPathsRelative(t *testing.T) {
|
func TestRewriteSyncPathsRelative(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: ".",
|
BundleRootPath: ".",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Paths: []string{
|
Paths: []string{
|
||||||
|
@ -54,7 +54,7 @@ func TestRewriteSyncPathsRelative(t *testing.T) {
|
||||||
|
|
||||||
func TestRewriteSyncPathsAbsolute(t *testing.T) {
|
func TestRewriteSyncPathsAbsolute(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "/tmp/dir",
|
BundleRootPath: "/tmp/dir",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Paths: []string{
|
Paths: []string{
|
||||||
|
@ -94,7 +94,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{
|
||||||
RootPath: ".",
|
BundleRootPath: ".",
|
||||||
}
|
}
|
||||||
|
|
||||||
diags := bundle.Apply(context.Background(), b, mutator.RewriteSyncPaths())
|
diags := bundle.Apply(context.Background(), b, mutator.RewriteSyncPaths())
|
||||||
|
@ -103,7 +103,7 @@ 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: ".",
|
BundleRootPath: ".",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Include: []string{},
|
Include: []string{},
|
||||||
|
|
|
@ -15,8 +15,8 @@ import (
|
||||||
|
|
||||||
func TestSyncDefaultPath_DefaultIfUnset(t *testing.T) {
|
func TestSyncDefaultPath_DefaultIfUnset(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "/tmp/some/dir",
|
BundleRootPath: "/tmp/some/dir",
|
||||||
Config: config.Root{},
|
Config: config.Root{},
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
@ -51,8 +51,8 @@ func TestSyncDefaultPath_SkipIfSet(t *testing.T) {
|
||||||
for _, tcase := range tcases {
|
for _, tcase := range tcases {
|
||||||
t.Run(tcase.name, func(t *testing.T) {
|
t.Run(tcase.name, func(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "/tmp/some/dir",
|
BundleRootPath: "/tmp/some/dir",
|
||||||
Config: config.Root{},
|
Config: config.Root{},
|
||||||
}
|
}
|
||||||
|
|
||||||
diags := bundle.ApplyFunc(context.Background(), b, func(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
|
diags := bundle.ApplyFunc(context.Background(), b, func(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
|
||||||
|
|
|
@ -57,7 +57,7 @@ func (m *syncInferRoot) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagno
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
// Use the bundle root path as the starting point for inferring the sync root path.
|
// Use the bundle root path as the starting point for inferring the sync root path.
|
||||||
bundleRootPath := filepath.Clean(b.RootPath)
|
bundleRootPath := filepath.Clean(b.BundleRootPath)
|
||||||
|
|
||||||
// Infer the sync root path by looking at each one of the sync paths.
|
// Infer the sync root path by looking at each one of the sync paths.
|
||||||
// Every sync path must be a descendant of the final sync root path.
|
// Every sync path must be a descendant of the final sync root path.
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
|
|
||||||
func TestSyncInferRoot_NominalAbsolute(t *testing.T) {
|
func TestSyncInferRoot_NominalAbsolute(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "/tmp/some/dir",
|
BundleRootPath: "/tmp/some/dir",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Paths: []string{
|
Paths: []string{
|
||||||
|
@ -47,7 +47,7 @@ func TestSyncInferRoot_NominalAbsolute(t *testing.T) {
|
||||||
|
|
||||||
func TestSyncInferRoot_NominalRelative(t *testing.T) {
|
func TestSyncInferRoot_NominalRelative(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "./some/dir",
|
BundleRootPath: "./some/dir",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Paths: []string{
|
Paths: []string{
|
||||||
|
@ -78,7 +78,7 @@ func TestSyncInferRoot_NominalRelative(t *testing.T) {
|
||||||
|
|
||||||
func TestSyncInferRoot_ParentDirectory(t *testing.T) {
|
func TestSyncInferRoot_ParentDirectory(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "/tmp/some/dir",
|
BundleRootPath: "/tmp/some/dir",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Paths: []string{
|
Paths: []string{
|
||||||
|
@ -109,7 +109,7 @@ func TestSyncInferRoot_ParentDirectory(t *testing.T) {
|
||||||
|
|
||||||
func TestSyncInferRoot_ManyParentDirectories(t *testing.T) {
|
func TestSyncInferRoot_ManyParentDirectories(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "/tmp/some/dir/that/is/very/deeply/nested",
|
BundleRootPath: "/tmp/some/dir/that/is/very/deeply/nested",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Paths: []string{
|
Paths: []string{
|
||||||
|
@ -146,7 +146,7 @@ func TestSyncInferRoot_ManyParentDirectories(t *testing.T) {
|
||||||
|
|
||||||
func TestSyncInferRoot_MultiplePaths(t *testing.T) {
|
func TestSyncInferRoot_MultiplePaths(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "/tmp/some/bundle/root",
|
BundleRootPath: "/tmp/some/bundle/root",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Paths: []string{
|
Paths: []string{
|
||||||
|
@ -173,7 +173,7 @@ func TestSyncInferRoot_MultiplePaths(t *testing.T) {
|
||||||
|
|
||||||
func TestSyncInferRoot_Error(t *testing.T) {
|
func TestSyncInferRoot_Error(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: "/tmp/some/dir",
|
BundleRootPath: "/tmp/some/dir",
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Sync: config.Sync{
|
Sync: config.Sync{
|
||||||
Paths: []string{
|
Paths: []string{
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (m *compute) Apply(_ context.Context, b *bundle.Bundle) diag.Diagnostics {
|
||||||
// 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
|
||||||
l := b.Config.GetLocation("resources.jobs." + name)
|
l := b.Config.GetLocation("resources.jobs." + name)
|
||||||
relativePath, err := filepath.Rel(b.RootPath, l.File)
|
relativePath, err := filepath.Rel(b.BundleRootPath, l.File)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,8 @@ func testStatePull(t *testing.T, opts statePullOpts) {
|
||||||
|
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: tmpDir,
|
BundleRootPath: tmpDir,
|
||||||
BundleRoot: vfs.MustNew(tmpDir),
|
BundleRoot: vfs.MustNew(tmpDir),
|
||||||
|
|
||||||
SyncRootPath: tmpDir,
|
SyncRootPath: tmpDir,
|
||||||
SyncRoot: vfs.MustNew(tmpDir),
|
SyncRoot: vfs.MustNew(tmpDir),
|
||||||
|
@ -259,7 +259,7 @@ func TestStatePullNoState(t *testing.T) {
|
||||||
}}
|
}}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "default",
|
Target: "default",
|
||||||
|
@ -447,7 +447,7 @@ func TestStatePullNewerDeploymentStateVersion(t *testing.T) {
|
||||||
}}
|
}}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "default",
|
Target: "default",
|
||||||
|
|
|
@ -45,7 +45,7 @@ func TestStatePush(t *testing.T) {
|
||||||
}}
|
}}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "default",
|
Target: "default",
|
||||||
|
|
|
@ -27,7 +27,7 @@ func setupBundleForStateUpdate(t *testing.T) *bundle.Bundle {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return &bundle.Bundle{
|
return &bundle.Bundle{
|
||||||
RootPath: tmpDir,
|
BundleRootPath: tmpDir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "default",
|
Target: "default",
|
||||||
|
|
|
@ -33,7 +33,7 @@ func TestInitEnvironmentVariables(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -60,7 +60,7 @@ func TestSetTempDirEnvVarsForUnixWithTmpDirSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -88,7 +88,7 @@ func TestSetTempDirEnvVarsForUnixWithTmpDirNotSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -114,7 +114,7 @@ func TestSetTempDirEnvVarsForWindowWithAllTmpDirEnvVarsSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -144,7 +144,7 @@ func TestSetTempDirEnvVarsForWindowWithUserProfileAndTempSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -174,7 +174,7 @@ func TestSetTempDirEnvVarsForWindowsWithoutAnyTempDirEnvVarsSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -202,7 +202,7 @@ func TestSetTempDirEnvVarsForWindowsWithoutAnyTempDirEnvVarsSet(t *testing.T) {
|
||||||
|
|
||||||
func TestSetProxyEnvVars(t *testing.T) {
|
func TestSetProxyEnvVars(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -250,7 +250,7 @@ func TestSetProxyEnvVars(t *testing.T) {
|
||||||
|
|
||||||
func TestSetUserAgentExtraEnvVar(t *testing.T) {
|
func TestSetUserAgentExtraEnvVar(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Experimental: &config.Experimental{
|
Experimental: &config.Experimental{
|
||||||
PyDABs: config.PyDABs{
|
PyDABs: config.PyDABs{
|
||||||
|
@ -333,7 +333,7 @@ func TestFindExecPathFromEnvironmentWithWrongVersion(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
m := &initialize{}
|
m := &initialize{}
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -357,7 +357,7 @@ func TestFindExecPathFromEnvironmentWithCorrectVersionAndNoBinary(t *testing.T)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
m := &initialize{}
|
m := &initialize{}
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -380,7 +380,7 @@ func TestFindExecPathFromEnvironmentWithCorrectVersionAndBinary(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
m := &initialize{}
|
m := &initialize{}
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestLoadWithNoState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
|
|
@ -32,7 +32,7 @@ func mockStateFilerForPull(t *testing.T, contents map[string]any, 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(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "default",
|
Target: "default",
|
||||||
|
|
|
@ -29,7 +29,7 @@ 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(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "default",
|
Target: "default",
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
func TestParseResourcesStateWithNoFile(t *testing.T) {
|
func TestParseResourcesStateWithNoFile(t *testing.T) {
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -31,7 +31,7 @@ func TestParseResourcesStateWithNoFile(t *testing.T) {
|
||||||
func TestParseResourcesStateWithExistingStateFile(t *testing.T) {
|
func TestParseResourcesStateWithExistingStateFile(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: t.TempDir(),
|
BundleRootPath: t.TempDir(),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
|
|
@ -15,8 +15,8 @@ import (
|
||||||
"github.com/databricks/cli/bundle/deploy/terraform"
|
"github.com/databricks/cli/bundle/deploy/terraform"
|
||||||
"github.com/databricks/cli/bundle/libraries"
|
"github.com/databricks/cli/bundle/libraries"
|
||||||
"github.com/databricks/cli/bundle/permissions"
|
"github.com/databricks/cli/bundle/permissions"
|
||||||
"github.com/databricks/cli/bundle/python"
|
|
||||||
"github.com/databricks/cli/bundle/scripts"
|
"github.com/databricks/cli/bundle/scripts"
|
||||||
|
"github.com/databricks/cli/bundle/trampoline"
|
||||||
"github.com/databricks/cli/libs/cmdio"
|
"github.com/databricks/cli/libs/cmdio"
|
||||||
"github.com/databricks/cli/libs/sync"
|
"github.com/databricks/cli/libs/sync"
|
||||||
terraformlib "github.com/databricks/cli/libs/terraform"
|
terraformlib "github.com/databricks/cli/libs/terraform"
|
||||||
|
@ -157,7 +157,7 @@ func Deploy(outputHandler sync.OutputHandler) bundle.Mutator {
|
||||||
artifacts.CleanUp(),
|
artifacts.CleanUp(),
|
||||||
libraries.ExpandGlobReferences(),
|
libraries.ExpandGlobReferences(),
|
||||||
libraries.Upload(),
|
libraries.Upload(),
|
||||||
python.TransformWheelTask(),
|
trampoline.TransformWheelTask(),
|
||||||
files.Upload(outputHandler),
|
files.Upload(outputHandler),
|
||||||
deploy.StateUpdate(),
|
deploy.StateUpdate(),
|
||||||
deploy.StatePush(),
|
deploy.StatePush(),
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"github.com/databricks/cli/bundle/deploy/metadata"
|
"github.com/databricks/cli/bundle/deploy/metadata"
|
||||||
"github.com/databricks/cli/bundle/deploy/terraform"
|
"github.com/databricks/cli/bundle/deploy/terraform"
|
||||||
"github.com/databricks/cli/bundle/permissions"
|
"github.com/databricks/cli/bundle/permissions"
|
||||||
"github.com/databricks/cli/bundle/python"
|
|
||||||
"github.com/databricks/cli/bundle/scripts"
|
"github.com/databricks/cli/bundle/scripts"
|
||||||
|
"github.com/databricks/cli/bundle/trampoline"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The initialize phase fills in defaults and connects to the workspace.
|
// The initialize phase fills in defaults and connects to the workspace.
|
||||||
|
@ -66,7 +66,7 @@ func Initialize() bundle.Mutator {
|
||||||
mutator.ConfigureWSFS(),
|
mutator.ConfigureWSFS(),
|
||||||
|
|
||||||
mutator.TranslatePaths(),
|
mutator.TranslatePaths(),
|
||||||
python.WrapperWarning(),
|
trampoline.WrapperWarning(),
|
||||||
permissions.ApplyBundlePermissions(),
|
permissions.ApplyBundlePermissions(),
|
||||||
permissions.FilterCurrentUser(),
|
permissions.FilterCurrentUser(),
|
||||||
metadata.AnnotateJobs(),
|
metadata.AnnotateJobs(),
|
||||||
|
|
|
@ -56,7 +56,7 @@ const warningTemplate = `{{ "Warning" | yellow }}: {{ .Summary }}
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const infoTemplate = `{{ "Recommendation" | blue }}: {{ .Summary }}
|
const recommendationTemplate = `{{ "Recommendation" | blue }}: {{ .Summary }}
|
||||||
{{- range $index, $element := .Paths }}
|
{{- range $index, $element := .Paths }}
|
||||||
{{ if eq $index 0 }}at {{else}} {{ end}}{{ $element.String | green }}
|
{{ if eq $index 0 }}at {{else}} {{ end}}{{ $element.String | green }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -112,10 +112,12 @@ func buildTrailer(diags diag.Diagnostics) string {
|
||||||
parts = append(parts, color.BlueString(pluralize(recommendations, "recommendation", "recommendations")))
|
parts = append(parts, color.BlueString(pluralize(recommendations, "recommendation", "recommendations")))
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case len(parts) >= 2:
|
case len(parts) >= 3:
|
||||||
first := strings.Join(parts[:len(parts)-1], ", ")
|
first := strings.Join(parts[:len(parts)-1], ", ")
|
||||||
last := parts[len(parts)-1]
|
last := parts[len(parts)-1]
|
||||||
return fmt.Sprintf("Found %s and %s", first, last)
|
return fmt.Sprintf("Found %s, and %s", first, last)
|
||||||
|
case len(parts) == 2:
|
||||||
|
return fmt.Sprintf("Found %s and %s", parts[0], parts[1])
|
||||||
case len(parts) == 1:
|
case len(parts) == 1:
|
||||||
return fmt.Sprintf("Found %s", parts[0])
|
return fmt.Sprintf("Found %s", parts[0])
|
||||||
default:
|
default:
|
||||||
|
@ -153,7 +155,7 @@ func renderSummaryTemplate(out io.Writer, b *bundle.Bundle, diags diag.Diagnosti
|
||||||
func renderDiagnostics(out io.Writer, b *bundle.Bundle, diags diag.Diagnostics) error {
|
func renderDiagnostics(out io.Writer, b *bundle.Bundle, diags diag.Diagnostics) error {
|
||||||
errorT := template.Must(template.New("error").Funcs(renderFuncMap).Parse(errorTemplate))
|
errorT := template.Must(template.New("error").Funcs(renderFuncMap).Parse(errorTemplate))
|
||||||
warningT := template.Must(template.New("warning").Funcs(renderFuncMap).Parse(warningTemplate))
|
warningT := template.Must(template.New("warning").Funcs(renderFuncMap).Parse(warningTemplate))
|
||||||
recommendationT := template.Must(template.New("info").Funcs(renderFuncMap).Parse(infoTemplate))
|
recommendationT := template.Must(template.New("recommendation").Funcs(renderFuncMap).Parse(recommendationTemplate))
|
||||||
|
|
||||||
// Print errors and warnings.
|
// Print errors and warnings.
|
||||||
for _, d := range diags {
|
for _, d := range diags {
|
||||||
|
@ -174,7 +176,7 @@ func renderDiagnostics(out io.Writer, b *bundle.Bundle, diags diag.Diagnostics)
|
||||||
|
|
||||||
// Make location relative to bundle root
|
// Make location relative to bundle root
|
||||||
if d.Locations[i].File != "" {
|
if d.Locations[i].File != "" {
|
||||||
out, err := filepath.Rel(b.RootPath, d.Locations[i].File)
|
out, err := filepath.Rel(b.BundleRootPath, d.Locations[i].File)
|
||||||
// if we can't relativize the path, just use path as-is
|
// if we can't relativize the path, just use path as-is
|
||||||
if err == nil {
|
if err == nil {
|
||||||
d.Locations[i].File = out
|
d.Locations[i].File = out
|
||||||
|
|
|
@ -149,7 +149,40 @@ func TestRenderTextOutput(t *testing.T) {
|
||||||
"Name: test-bundle\n" +
|
"Name: test-bundle\n" +
|
||||||
"Target: test-target\n" +
|
"Target: test-target\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"Found 2 errors, 1 warning and 1 recommendation\n",
|
"Found 2 errors, 1 warning, and 1 recommendation\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bundle during 'load' and 1 error and 1 warning",
|
||||||
|
bundle: loadingBundle,
|
||||||
|
diags: diag.Diagnostics{
|
||||||
|
diag.Diagnostic{
|
||||||
|
Severity: diag.Error,
|
||||||
|
Summary: "error (1)",
|
||||||
|
Detail: "detail (1)",
|
||||||
|
Locations: []dyn.Location{{File: "foo.py", Line: 1, Column: 1}},
|
||||||
|
},
|
||||||
|
diag.Diagnostic{
|
||||||
|
Severity: diag.Warning,
|
||||||
|
Summary: "warning (2)",
|
||||||
|
Detail: "detail (2)",
|
||||||
|
Locations: []dyn.Location{{File: "foo.py", Line: 2, Column: 1}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
opts: RenderOptions{RenderSummaryTable: true},
|
||||||
|
expected: "Error: error (1)\n" +
|
||||||
|
" in foo.py:1:1\n" +
|
||||||
|
"\n" +
|
||||||
|
"detail (1)\n" +
|
||||||
|
"\n" +
|
||||||
|
"Warning: warning (2)\n" +
|
||||||
|
" in foo.py:2:1\n" +
|
||||||
|
"\n" +
|
||||||
|
"detail (2)\n" +
|
||||||
|
"\n" +
|
||||||
|
"Name: test-bundle\n" +
|
||||||
|
"Target: test-target\n" +
|
||||||
|
"\n" +
|
||||||
|
"Found 1 error and 1 warning\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "bundle during 'load' and 1 errors, 2 warning and 2 recommendations with details",
|
name: "bundle during 'load' and 1 errors, 2 warning and 2 recommendations with details",
|
||||||
|
@ -215,7 +248,7 @@ func TestRenderTextOutput(t *testing.T) {
|
||||||
"Name: test-bundle\n" +
|
"Name: test-bundle\n" +
|
||||||
"Target: test-target\n" +
|
"Target: test-target\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"Found 1 error, 2 warnings and 2 recommendations\n",
|
"Found 1 error, 2 warnings, and 2 recommendations\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "bundle during 'init'",
|
name: "bundle during 'init'",
|
||||||
|
|
|
@ -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.RootPath)
|
executor, err := exec.NewCommandExecutor(b.BundleRootPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ func TestExecutesHook(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
executor, err := exec.NewCommandExecutor(b.RootPath)
|
executor, err := exec.NewCommandExecutor(b.BundleRootPath)
|
||||||
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)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package python
|
package trampoline
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -17,8 +17,8 @@ func TestNoTransformByDefault(t *testing.T) {
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
BundleRootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "development",
|
Target: "development",
|
||||||
|
@ -66,8 +66,8 @@ func TestTransformWithExperimentalSettingSetToTrue(t *testing.T) {
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
BundleRootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "development",
|
Target: "development",
|
|
@ -1,4 +1,4 @@
|
||||||
package python
|
package trampoline
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
|
@ -1,4 +1,4 @@
|
||||||
package python
|
package trampoline
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
|
@ -1,4 +1,4 @@
|
||||||
package python
|
package trampoline
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -69,7 +69,7 @@ func TransformWheelTask() bundle.Mutator {
|
||||||
res := b.Config.Experimental != nil && b.Config.Experimental.PythonWheelWrapper
|
res := b.Config.Experimental != nil && b.Config.Experimental.PythonWheelWrapper
|
||||||
return res, nil
|
return res, nil
|
||||||
},
|
},
|
||||||
mutator.NewTrampoline(
|
NewTrampoline(
|
||||||
"python_wheel",
|
"python_wheel",
|
||||||
&pythonTrampoline{},
|
&pythonTrampoline{},
|
||||||
NOTEBOOK_TEMPLATE,
|
NOTEBOOK_TEMPLATE,
|
||||||
|
@ -94,9 +94,9 @@ func (t *pythonTrampoline) CleanUp(task *jobs.Task) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *pythonTrampoline) GetTasks(b *bundle.Bundle) []mutator.TaskWithJobKey {
|
func (t *pythonTrampoline) GetTasks(b *bundle.Bundle) []TaskWithJobKey {
|
||||||
r := b.Config.Resources
|
r := b.Config.Resources
|
||||||
result := make([]mutator.TaskWithJobKey, 0)
|
result := make([]TaskWithJobKey, 0)
|
||||||
for k := range b.Config.Resources.Jobs {
|
for k := range b.Config.Resources.Jobs {
|
||||||
tasks := r.Jobs[k].JobSettings.Tasks
|
tasks := r.Jobs[k].JobSettings.Tasks
|
||||||
for i := range tasks {
|
for i := range tasks {
|
||||||
|
@ -110,7 +110,7 @@ func (t *pythonTrampoline) GetTasks(b *bundle.Bundle) []mutator.TaskWithJobKey {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, mutator.TaskWithJobKey{
|
result = append(result, TaskWithJobKey{
|
||||||
JobKey: k,
|
JobKey: k,
|
||||||
Task: task,
|
Task: task,
|
||||||
})
|
})
|
|
@ -1,4 +1,4 @@
|
||||||
package python
|
package trampoline
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -115,7 +115,7 @@ 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,
|
BundleRootPath: tmpDir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "development",
|
Target: "development",
|
|
@ -1,4 +1,4 @@
|
||||||
package mutator
|
package trampoline
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -23,6 +23,7 @@ type TrampolineFunctions interface {
|
||||||
GetTasks(b *bundle.Bundle) []TaskWithJobKey
|
GetTasks(b *bundle.Bundle) []TaskWithJobKey
|
||||||
CleanUp(task *jobs.Task) error
|
CleanUp(task *jobs.Task) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type trampoline struct {
|
type trampoline struct {
|
||||||
name string
|
name string
|
||||||
functions TrampolineFunctions
|
functions TrampolineFunctions
|
|
@ -1,4 +1,4 @@
|
||||||
package mutator
|
package trampoline
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -56,8 +56,8 @@ func TestGenerateTrampoline(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
BundleRootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Workspace: config.Workspace{
|
Workspace: config.Workspace{
|
||||||
FilePath: "/Workspace/files",
|
FilePath: "/Workspace/files",
|
|
@ -24,7 +24,7 @@ func TestGeneratePipelineCommand(t *testing.T) {
|
||||||
|
|
||||||
root := t.TempDir()
|
root := t.TempDir()
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: root,
|
BundleRootPath: root,
|
||||||
}
|
}
|
||||||
|
|
||||||
m := mocks.NewMockWorkspaceClient(t)
|
m := mocks.NewMockWorkspaceClient(t)
|
||||||
|
@ -122,7 +122,7 @@ func TestGenerateJobCommand(t *testing.T) {
|
||||||
|
|
||||||
root := t.TempDir()
|
root := t.TempDir()
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: root,
|
BundleRootPath: root,
|
||||||
}
|
}
|
||||||
|
|
||||||
m := mocks.NewMockWorkspaceClient(t)
|
m := mocks.NewMockWorkspaceClient(t)
|
||||||
|
|
|
@ -17,10 +17,10 @@ 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,
|
BundleRootPath: tempDir,
|
||||||
BundleRoot: vfs.MustNew(tempDir),
|
BundleRoot: vfs.MustNew(tempDir),
|
||||||
SyncRootPath: tempDir,
|
SyncRootPath: tempDir,
|
||||||
SyncRoot: vfs.MustNew(tempDir),
|
SyncRoot: vfs.MustNew(tempDir),
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "default",
|
Target: "default",
|
||||||
|
|
|
@ -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,
|
BundleRootPath: dir,
|
||||||
SyncRootPath: dir,
|
SyncRootPath: dir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -101,8 +101,8 @@ func TestAccUploadArtifactFileToCorrectRemotePathWithEnvironments(t *testing.T)
|
||||||
wsDir := internal.TemporaryWorkspaceDir(t, w)
|
wsDir := internal.TemporaryWorkspaceDir(t, w)
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: dir,
|
BundleRootPath: dir,
|
||||||
SyncRootPath: dir,
|
SyncRootPath: dir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
@ -171,8 +171,8 @@ func TestAccUploadArtifactFileToCorrectRemotePathForVolumes(t *testing.T) {
|
||||||
touchEmptyFile(t, whlPath)
|
touchEmptyFile(t, whlPath)
|
||||||
|
|
||||||
b := &bundle.Bundle{
|
b := &bundle.Bundle{
|
||||||
RootPath: dir,
|
BundleRootPath: dir,
|
||||||
SyncRootPath: dir,
|
SyncRootPath: dir,
|
||||||
Config: config.Root{
|
Config: config.Root{
|
||||||
Bundle: config.Bundle{
|
Bundle: config.Bundle{
|
||||||
Target: "whatever",
|
Target: "whatever",
|
||||||
|
|
Loading…
Reference in New Issue