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")
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: tmpDir,
|
||||
BundleRootPath: tmpDir,
|
||||
Config: config.Root{
|
||||
Artifacts: config.Artifacts{
|
||||
"test": {
|
||||
|
@ -63,7 +63,7 @@ func TestExpandGlobs_InvalidPattern(t *testing.T) {
|
|||
tmpDir := t.TempDir()
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: tmpDir,
|
||||
BundleRootPath: tmpDir,
|
||||
Config: config.Root{
|
||||
Artifacts: config.Artifacts{
|
||||
"test": {
|
||||
|
@ -111,7 +111,7 @@ func TestExpandGlobs_NoMatches(t *testing.T) {
|
|||
testutil.Touch(t, tmpDir, "b2.txt")
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: tmpDir,
|
||||
BundleRootPath: tmpDir,
|
||||
Config: config.Root{
|
||||
Artifacts: config.Artifacts{
|
||||
"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 == "" {
|
||||
artifact.Path = b.RootPath
|
||||
artifact.Path = b.BundleRootPath
|
||||
}
|
||||
|
||||
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...")
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
log.Infof(ctx, "No Python wheel project found at bundle root folder")
|
||||
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)
|
||||
|
||||
if b.Config.Artifacts == nil {
|
||||
b.Config.Artifacts = make(map[string]*config.Artifact)
|
||||
}
|
||||
|
||||
pkgPath, err := filepath.Abs(b.RootPath)
|
||||
pkgPath, err := filepath.Abs(b.BundleRootPath)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
|
|
@ -31,22 +31,26 @@ import (
|
|||
const internalFolder = ".internal"
|
||||
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
// 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
|
||||
|
||||
// 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
|
||||
|
||||
// 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) {
|
||||
b := &Bundle{
|
||||
RootPath: filepath.Clean(path),
|
||||
BundleRoot: vfs.MustNew(path),
|
||||
BundleRootPath: filepath.Clean(path),
|
||||
BundleRoot: vfs.MustNew(path),
|
||||
}
|
||||
configFile, err := config.FileNames.FindInPath(path)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -160,7 +164,7 @@ func (b *Bundle) CacheDir(ctx context.Context, paths ...string) (string, error)
|
|||
if !exists || cacheDirName == "" {
|
||||
cacheDirName = filepath.Join(
|
||||
// Anchor at bundle root directory.
|
||||
b.RootPath,
|
||||
b.BundleRootPath,
|
||||
// Static cache directory.
|
||||
".databricks",
|
||||
"bundle",
|
||||
|
@ -212,7 +216,7 @@ func (b *Bundle) GetSyncIncludePatterns(ctx context.Context) ([]string, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
internalDirRel, err := filepath.Rel(b.RootPath, internalDir)
|
||||
internalDirRel, err := filepath.Rel(b.BundleRootPath, internalDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ func (r ReadOnlyBundle) Config() config.Root {
|
|||
}
|
||||
|
||||
func (r ReadOnlyBundle) RootPath() string {
|
||||
return r.b.RootPath
|
||||
return r.b.BundleRootPath
|
||||
}
|
||||
|
||||
func (r ReadOnlyBundle) BundleRoot() vfs.Path {
|
||||
|
|
|
@ -79,7 +79,7 @@ func TestBundleMustLoadSuccess(t *testing.T) {
|
|||
t.Setenv(env.RootVariable, "./tests/basic")
|
||||
b, err := MustLoad(context.Background())
|
||||
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) {
|
||||
|
@ -98,7 +98,7 @@ func TestBundleTryLoadSuccess(t *testing.T) {
|
|||
t.Setenv(env.RootVariable, "./tests/basic")
|
||||
b, err := TryLoad(context.Background())
|
||||
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) {
|
||||
|
|
|
@ -20,7 +20,7 @@ func (m *entryPoint) Name() string {
|
|||
}
|
||||
|
||||
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 {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ func TestEntryPointNoRootPath(t *testing.T) {
|
|||
|
||||
func TestEntryPoint(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "testdata/basic",
|
||||
BundleRootPath: "testdata/basic",
|
||||
}
|
||||
diags := bundle.Apply(context.Background(), b, loader.EntryPoint())
|
||||
require.NoError(t, diags.Error())
|
||||
|
|
|
@ -122,7 +122,7 @@ func validateSingleResourceDefined(configRoot dyn.Value, ext, typ string) diag.D
|
|||
return diag.Diagnostics{
|
||||
{
|
||||
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(),
|
||||
Locations: locations,
|
||||
Paths: paths,
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
func TestProcessInclude(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "testdata/basic",
|
||||
BundleRootPath: "testdata/basic",
|
||||
Config: config.Root{
|
||||
Workspace: config.Workspace{
|
||||
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 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)
|
||||
}
|
||||
|
||||
func TestProcessIncludeFormatPass(t *testing.T) {
|
||||
func TestProcessIncludeFormatMatch(t *testing.T) {
|
||||
for _, fileName := range []string{
|
||||
"one_job.job.yml",
|
||||
"one_pipeline.pipeline.yaml",
|
||||
"two_job.yml",
|
||||
"job_and_pipeline.yml",
|
||||
"multiple_resources.yml",
|
||||
} {
|
||||
t.Run(fileName, func(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "testdata/format_pass",
|
||||
BundleRootPath: "testdata/format_match",
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
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)
|
||||
assert.Empty(t, diags)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessIncludeFormatFail(t *testing.T) {
|
||||
func TestProcessIncludeFormatNotMatch(t *testing.T) {
|
||||
for fileName, expectedDiags := range map[string]diag.Diagnostics{
|
||||
"single_job.pipeline.yaml": {
|
||||
{
|
||||
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",
|
||||
Locations: []dyn.Location{
|
||||
{File: filepath.FromSlash("testdata/format_fail/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: 11, Column: 11},
|
||||
{File: filepath.FromSlash("testdata/format_not_match/single_job.pipeline.yaml"), Line: 4, Column: 7},
|
||||
},
|
||||
Paths: []dyn.Path{
|
||||
dyn.MustPathFromString("resources.jobs.job1"),
|
||||
|
@ -80,11 +81,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
|||
"job_and_pipeline.job.yml": {
|
||||
{
|
||||
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",
|
||||
Locations: []dyn.Location{
|
||||
{File: filepath.FromSlash("testdata/format_fail/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: 11, Column: 11},
|
||||
{File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.job.yml"), Line: 4, Column: 7},
|
||||
},
|
||||
Paths: []dyn.Path{
|
||||
dyn.MustPathFromString("resources.pipelines.pipeline1"),
|
||||
|
@ -95,11 +96,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
|||
"job_and_pipeline.experiment.yml": {
|
||||
{
|
||||
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",
|
||||
Locations: []dyn.Location{
|
||||
{File: filepath.FromSlash("testdata/format_fail/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: 11, Column: 11},
|
||||
{File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.experiment.yml"), Line: 4, Column: 7},
|
||||
},
|
||||
Paths: []dyn.Path{
|
||||
dyn.MustPathFromString("resources.pipelines.pipeline1"),
|
||||
|
@ -110,11 +111,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
|||
"two_jobs.job.yml": {
|
||||
{
|
||||
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",
|
||||
Locations: []dyn.Location{
|
||||
{File: filepath.FromSlash("testdata/format_fail/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: 4, Column: 7},
|
||||
{File: filepath.FromSlash("testdata/format_not_match/two_jobs.job.yml"), Line: 7, Column: 7},
|
||||
},
|
||||
Paths: []dyn.Path{
|
||||
dyn.MustPathFromString("resources.jobs.job1"),
|
||||
|
@ -125,11 +126,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
|||
"second_job_in_target.job.yml": {
|
||||
{
|
||||
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",
|
||||
Locations: []dyn.Location{
|
||||
{File: filepath.FromSlash("testdata/format_fail/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: 11, Column: 11},
|
||||
{File: filepath.FromSlash("testdata/format_not_match/second_job_in_target.job.yml"), Line: 4, Column: 7},
|
||||
},
|
||||
Paths: []dyn.Path{
|
||||
dyn.MustPathFromString("resources.jobs.job1"),
|
||||
|
@ -140,11 +141,11 @@ func TestProcessIncludeFormatFail(t *testing.T) {
|
|||
"two_jobs_in_target.job.yml": {
|
||||
{
|
||||
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",
|
||||
Locations: []dyn.Location{
|
||||
{File: filepath.FromSlash("testdata/format_fail/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: 6, Column: 11},
|
||||
{File: filepath.FromSlash("testdata/format_not_match/two_jobs_in_target.job.yml"), Line: 8, Column: 11},
|
||||
},
|
||||
Paths: []dyn.Path{
|
||||
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) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "testdata/format_fail",
|
||||
BundleRootPath: "testdata/format_not_match",
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
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)
|
||||
require.Len(t, diags, 1)
|
||||
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.
|
||||
matches, err := filepath.Glob(filepath.Join(b.RootPath, entry))
|
||||
matches, err := filepath.Glob(filepath.Join(b.BundleRootPath, entry))
|
||||
if err != nil {
|
||||
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.
|
||||
var includes []string
|
||||
for _, match := range matches {
|
||||
rel, err := filepath.Rel(b.RootPath, match)
|
||||
rel, err := filepath.Rel(b.BundleRootPath, match)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ func (m *processRootIncludes) Apply(ctx context.Context, b *bundle.Bundle) diag.
|
|||
slices.Sort(includes)
|
||||
files = append(files, 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) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: ".",
|
||||
BundleRootPath: ".",
|
||||
}
|
||||
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
||||
require.NoError(t, diags.Error())
|
||||
|
@ -30,7 +30,7 @@ func TestProcessRootIncludesAbs(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: ".",
|
||||
BundleRootPath: ".",
|
||||
Config: config.Root{
|
||||
Include: []string{
|
||||
"/tmp/*.yml",
|
||||
|
@ -44,7 +44,7 @@ func TestProcessRootIncludesAbs(t *testing.T) {
|
|||
|
||||
func TestProcessRootIncludesSingleGlob(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Include: []string{
|
||||
"*.yml",
|
||||
|
@ -52,9 +52,9 @@ func TestProcessRootIncludesSingleGlob(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
testutil.Touch(t, b.RootPath, "databricks.yml")
|
||||
testutil.Touch(t, b.RootPath, "a.yml")
|
||||
testutil.Touch(t, b.RootPath, "b.yml")
|
||||
testutil.Touch(t, b.BundleRootPath, "databricks.yml")
|
||||
testutil.Touch(t, b.BundleRootPath, "a.yml")
|
||||
testutil.Touch(t, b.BundleRootPath, "b.yml")
|
||||
|
||||
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
||||
require.NoError(t, diags.Error())
|
||||
|
@ -63,7 +63,7 @@ func TestProcessRootIncludesSingleGlob(t *testing.T) {
|
|||
|
||||
func TestProcessRootIncludesMultiGlob(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Include: []string{
|
||||
"a*.yml",
|
||||
|
@ -72,8 +72,8 @@ func TestProcessRootIncludesMultiGlob(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
testutil.Touch(t, b.RootPath, "a1.yml")
|
||||
testutil.Touch(t, b.RootPath, "b1.yml")
|
||||
testutil.Touch(t, b.BundleRootPath, "a1.yml")
|
||||
testutil.Touch(t, b.BundleRootPath, "b1.yml")
|
||||
|
||||
diags := bundle.Apply(context.Background(), b, loader.ProcessRootIncludes())
|
||||
require.NoError(t, diags.Error())
|
||||
|
@ -82,7 +82,7 @@ func TestProcessRootIncludesMultiGlob(t *testing.T) {
|
|||
|
||||
func TestProcessRootIncludesRemoveDups(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Include: []string{
|
||||
"*.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())
|
||||
require.NoError(t, diags.Error())
|
||||
|
@ -100,7 +100,7 @@ func TestProcessRootIncludesRemoveDups(t *testing.T) {
|
|||
|
||||
func TestProcessRootIncludesNotExists(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Include: []string{
|
||||
"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:
|
||||
pipelines:
|
||||
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"))
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: dir,
|
||||
BundleRootPath: dir,
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{
|
||||
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.
|
||||
absBundlePath, err := filepath.Abs(b.RootPath)
|
||||
absBundlePath, err := filepath.Abs(b.BundleRootPath)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
rightRoot, diags := m.runPythonMutator(ctx, cacheDir, b.RootPath, pythonPath, leftRoot)
|
||||
rightRoot, diags := m.runPythonMutator(ctx, cacheDir, b.BundleRootPath, pythonPath, leftRoot)
|
||||
mutateDiags = diags
|
||||
if diags.HasError() {
|
||||
return dyn.InvalidValue, mutateDiagsHasError
|
||||
|
@ -228,12 +228,12 @@ func (m *pythonMutator) runPythonMutator(ctx context.Context, cacheDir string, r
|
|||
return output, pythonDiagnostics
|
||||
}
|
||||
|
||||
const installExplanation = `If using Python wheels, ensure that 'databricks-pydabs' is included in the dependencies,
|
||||
const installExplanation = `If using Python wheels, ensure that 'databricks-pydabs' is included in the dependencies,
|
||||
and that the wheel is installed in the Python environment:
|
||||
|
||||
$ .venv/bin/pip install -e .
|
||||
|
||||
If using a virtual environment, ensure it is specified as the venv_path property in databricks.yml,
|
||||
If using a virtual environment, ensure it is specified as the venv_path property in databricks.yml,
|
||||
or activate the environment before running CLI commands:
|
||||
|
||||
experimental:
|
||||
|
|
|
@ -570,12 +570,12 @@ func TestExplainProcessErr(t *testing.T) {
|
|||
|
||||
Explanation: 'databricks-pydabs' library is not installed in the Python environment.
|
||||
|
||||
If using Python wheels, ensure that 'databricks-pydabs' is included in the dependencies,
|
||||
If using Python wheels, ensure that 'databricks-pydabs' is included in the dependencies,
|
||||
and that the wheel is installed in the Python environment:
|
||||
|
||||
$ .venv/bin/pip install -e .
|
||||
|
||||
If using a virtual environment, ensure it is specified as the venv_path property in databricks.yml,
|
||||
If using a virtual environment, ensure it is specified as the venv_path property in databricks.yml,
|
||||
or activate the environment before running CLI commands:
|
||||
|
||||
experimental:
|
||||
|
|
|
@ -45,15 +45,15 @@ func (m *rewriteSyncPaths) makeRelativeTo(root string) dyn.MapFunc {
|
|||
func (m *rewriteSyncPaths) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
|
||||
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) {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return dyn.InvalidValue, err
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
func TestRewriteSyncPathsRelative(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: ".",
|
||||
BundleRootPath: ".",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
Paths: []string{
|
||||
|
@ -54,7 +54,7 @@ func TestRewriteSyncPathsRelative(t *testing.T) {
|
|||
|
||||
func TestRewriteSyncPathsAbsolute(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "/tmp/dir",
|
||||
BundleRootPath: "/tmp/dir",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
Paths: []string{
|
||||
|
@ -94,7 +94,7 @@ func TestRewriteSyncPathsAbsolute(t *testing.T) {
|
|||
func TestRewriteSyncPathsErrorPaths(t *testing.T) {
|
||||
t.Run("no sync block", func(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: ".",
|
||||
BundleRootPath: ".",
|
||||
}
|
||||
|
||||
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) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: ".",
|
||||
BundleRootPath: ".",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
Include: []string{},
|
||||
|
|
|
@ -15,8 +15,8 @@ import (
|
|||
|
||||
func TestSyncDefaultPath_DefaultIfUnset(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "/tmp/some/dir",
|
||||
Config: config.Root{},
|
||||
BundleRootPath: "/tmp/some/dir",
|
||||
Config: config.Root{},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
@ -51,8 +51,8 @@ func TestSyncDefaultPath_SkipIfSet(t *testing.T) {
|
|||
for _, tcase := range tcases {
|
||||
t.Run(tcase.name, func(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "/tmp/some/dir",
|
||||
Config: config.Root{},
|
||||
BundleRootPath: "/tmp/some/dir",
|
||||
Config: config.Root{},
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// 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.
|
||||
// Every sync path must be a descendant of the final sync root path.
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
func TestSyncInferRoot_NominalAbsolute(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "/tmp/some/dir",
|
||||
BundleRootPath: "/tmp/some/dir",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
Paths: []string{
|
||||
|
@ -47,7 +47,7 @@ func TestSyncInferRoot_NominalAbsolute(t *testing.T) {
|
|||
|
||||
func TestSyncInferRoot_NominalRelative(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "./some/dir",
|
||||
BundleRootPath: "./some/dir",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
Paths: []string{
|
||||
|
@ -78,7 +78,7 @@ func TestSyncInferRoot_NominalRelative(t *testing.T) {
|
|||
|
||||
func TestSyncInferRoot_ParentDirectory(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "/tmp/some/dir",
|
||||
BundleRootPath: "/tmp/some/dir",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
Paths: []string{
|
||||
|
@ -109,7 +109,7 @@ func TestSyncInferRoot_ParentDirectory(t *testing.T) {
|
|||
|
||||
func TestSyncInferRoot_ManyParentDirectories(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "/tmp/some/dir/that/is/very/deeply/nested",
|
||||
BundleRootPath: "/tmp/some/dir/that/is/very/deeply/nested",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
Paths: []string{
|
||||
|
@ -146,7 +146,7 @@ func TestSyncInferRoot_ManyParentDirectories(t *testing.T) {
|
|||
|
||||
func TestSyncInferRoot_MultiplePaths(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "/tmp/some/bundle/root",
|
||||
BundleRootPath: "/tmp/some/bundle/root",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
Paths: []string{
|
||||
|
@ -173,7 +173,7 @@ func TestSyncInferRoot_MultiplePaths(t *testing.T) {
|
|||
|
||||
func TestSyncInferRoot_Error(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: "/tmp/some/dir",
|
||||
BundleRootPath: "/tmp/some/dir",
|
||||
Config: config.Root{
|
||||
Sync: config.Sync{
|
||||
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
|
||||
// root
|
||||
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 {
|
||||
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()
|
||||
b := &bundle.Bundle{
|
||||
RootPath: tmpDir,
|
||||
BundleRoot: vfs.MustNew(tmpDir),
|
||||
BundleRootPath: tmpDir,
|
||||
BundleRoot: vfs.MustNew(tmpDir),
|
||||
|
||||
SyncRootPath: tmpDir,
|
||||
SyncRoot: vfs.MustNew(tmpDir),
|
||||
|
@ -259,7 +259,7 @@ func TestStatePullNoState(t *testing.T) {
|
|||
}}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "default",
|
||||
|
@ -447,7 +447,7 @@ func TestStatePullNewerDeploymentStateVersion(t *testing.T) {
|
|||
}}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "default",
|
||||
|
|
|
@ -45,7 +45,7 @@ func TestStatePush(t *testing.T) {
|
|||
}}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "default",
|
||||
|
|
|
@ -27,7 +27,7 @@ func setupBundleForStateUpdate(t *testing.T) *bundle.Bundle {
|
|||
require.NoError(t, err)
|
||||
|
||||
return &bundle.Bundle{
|
||||
RootPath: tmpDir,
|
||||
BundleRootPath: tmpDir,
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "default",
|
||||
|
|
|
@ -33,7 +33,7 @@ func TestInitEnvironmentVariables(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -60,7 +60,7 @@ func TestSetTempDirEnvVarsForUnixWithTmpDirSet(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -88,7 +88,7 @@ func TestSetTempDirEnvVarsForUnixWithTmpDirNotSet(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -114,7 +114,7 @@ func TestSetTempDirEnvVarsForWindowWithAllTmpDirEnvVarsSet(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -144,7 +144,7 @@ func TestSetTempDirEnvVarsForWindowWithUserProfileAndTempSet(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -174,7 +174,7 @@ func TestSetTempDirEnvVarsForWindowsWithoutAnyTempDirEnvVarsSet(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -202,7 +202,7 @@ func TestSetTempDirEnvVarsForWindowsWithoutAnyTempDirEnvVarsSet(t *testing.T) {
|
|||
|
||||
func TestSetProxyEnvVars(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -250,7 +250,7 @@ func TestSetProxyEnvVars(t *testing.T) {
|
|||
|
||||
func TestSetUserAgentExtraEnvVar(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Experimental: &config.Experimental{
|
||||
PyDABs: config.PyDABs{
|
||||
|
@ -333,7 +333,7 @@ func TestFindExecPathFromEnvironmentWithWrongVersion(t *testing.T) {
|
|||
ctx := context.Background()
|
||||
m := &initialize{}
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -357,7 +357,7 @@ func TestFindExecPathFromEnvironmentWithCorrectVersionAndNoBinary(t *testing.T)
|
|||
ctx := context.Background()
|
||||
m := &initialize{}
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -380,7 +380,7 @@ func TestFindExecPathFromEnvironmentWithCorrectVersionAndBinary(t *testing.T) {
|
|||
ctx := context.Background()
|
||||
m := &initialize{}
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
|
|
@ -17,7 +17,7 @@ func TestLoadWithNoState(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
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 {
|
||||
return &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
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 {
|
||||
return &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "default",
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
func TestParseResourcesStateWithNoFile(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -31,7 +31,7 @@ func TestParseResourcesStateWithNoFile(t *testing.T) {
|
|||
func TestParseResourcesStateWithExistingStateFile(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
b := &bundle.Bundle{
|
||||
RootPath: t.TempDir(),
|
||||
BundleRootPath: t.TempDir(),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
|
|
@ -15,8 +15,8 @@ import (
|
|||
"github.com/databricks/cli/bundle/deploy/terraform"
|
||||
"github.com/databricks/cli/bundle/libraries"
|
||||
"github.com/databricks/cli/bundle/permissions"
|
||||
"github.com/databricks/cli/bundle/python"
|
||||
"github.com/databricks/cli/bundle/scripts"
|
||||
"github.com/databricks/cli/bundle/trampoline"
|
||||
"github.com/databricks/cli/libs/cmdio"
|
||||
"github.com/databricks/cli/libs/sync"
|
||||
terraformlib "github.com/databricks/cli/libs/terraform"
|
||||
|
@ -157,7 +157,7 @@ func Deploy(outputHandler sync.OutputHandler) bundle.Mutator {
|
|||
artifacts.CleanUp(),
|
||||
libraries.ExpandGlobReferences(),
|
||||
libraries.Upload(),
|
||||
python.TransformWheelTask(),
|
||||
trampoline.TransformWheelTask(),
|
||||
files.Upload(outputHandler),
|
||||
deploy.StateUpdate(),
|
||||
deploy.StatePush(),
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"github.com/databricks/cli/bundle/deploy/metadata"
|
||||
"github.com/databricks/cli/bundle/deploy/terraform"
|
||||
"github.com/databricks/cli/bundle/permissions"
|
||||
"github.com/databricks/cli/bundle/python"
|
||||
"github.com/databricks/cli/bundle/scripts"
|
||||
"github.com/databricks/cli/bundle/trampoline"
|
||||
)
|
||||
|
||||
// The initialize phase fills in defaults and connects to the workspace.
|
||||
|
@ -66,7 +66,7 @@ func Initialize() bundle.Mutator {
|
|||
mutator.ConfigureWSFS(),
|
||||
|
||||
mutator.TranslatePaths(),
|
||||
python.WrapperWarning(),
|
||||
trampoline.WrapperWarning(),
|
||||
permissions.ApplyBundlePermissions(),
|
||||
permissions.FilterCurrentUser(),
|
||||
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 }}
|
||||
{{ if eq $index 0 }}at {{else}} {{ end}}{{ $element.String | green }}
|
||||
{{- end }}
|
||||
|
@ -112,10 +112,12 @@ func buildTrailer(diags diag.Diagnostics) string {
|
|||
parts = append(parts, color.BlueString(pluralize(recommendations, "recommendation", "recommendations")))
|
||||
}
|
||||
switch {
|
||||
case len(parts) >= 2:
|
||||
case len(parts) >= 3:
|
||||
first := strings.Join(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:
|
||||
return fmt.Sprintf("Found %s", parts[0])
|
||||
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 {
|
||||
errorT := template.Must(template.New("error").Funcs(renderFuncMap).Parse(errorTemplate))
|
||||
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.
|
||||
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
|
||||
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 err == nil {
|
||||
d.Locations[i].File = out
|
||||
|
|
|
@ -149,7 +149,40 @@ func TestRenderTextOutput(t *testing.T) {
|
|||
"Name: test-bundle\n" +
|
||||
"Target: test-target\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",
|
||||
|
@ -215,7 +248,7 @@ func TestRenderTextOutput(t *testing.T) {
|
|||
"Name: test-bundle\n" +
|
||||
"Target: test-target\n" +
|
||||
"\n" +
|
||||
"Found 1 error, 2 warnings and 2 recommendations\n",
|
||||
"Found 1 error, 2 warnings, and 2 recommendations\n",
|
||||
},
|
||||
{
|
||||
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 {
|
||||
executor, err := exec.NewCommandExecutor(b.RootPath)
|
||||
executor, err := exec.NewCommandExecutor(b.BundleRootPath)
|
||||
if err != nil {
|
||||
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)
|
||||
_, out, err := executeHook(context.Background(), executor, b, config.ScriptPreBuild)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package python
|
||||
package trampoline
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -17,8 +17,8 @@ func TestNoTransformByDefault(t *testing.T) {
|
|||
tmpDir := t.TempDir()
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||
BundleRootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "development",
|
||||
|
@ -66,8 +66,8 @@ func TestTransformWithExperimentalSettingSetToTrue(t *testing.T) {
|
|||
tmpDir := t.TempDir()
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||
BundleRootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "development",
|
|
@ -1,4 +1,4 @@
|
|||
package python
|
||||
package trampoline
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -1,4 +1,4 @@
|
|||
package python
|
||||
package trampoline
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -1,4 +1,4 @@
|
|||
package python
|
||||
package trampoline
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -69,7 +69,7 @@ func TransformWheelTask() bundle.Mutator {
|
|||
res := b.Config.Experimental != nil && b.Config.Experimental.PythonWheelWrapper
|
||||
return res, nil
|
||||
},
|
||||
mutator.NewTrampoline(
|
||||
NewTrampoline(
|
||||
"python_wheel",
|
||||
&pythonTrampoline{},
|
||||
NOTEBOOK_TEMPLATE,
|
||||
|
@ -94,9 +94,9 @@ func (t *pythonTrampoline) CleanUp(task *jobs.Task) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *pythonTrampoline) GetTasks(b *bundle.Bundle) []mutator.TaskWithJobKey {
|
||||
func (t *pythonTrampoline) GetTasks(b *bundle.Bundle) []TaskWithJobKey {
|
||||
r := b.Config.Resources
|
||||
result := make([]mutator.TaskWithJobKey, 0)
|
||||
result := make([]TaskWithJobKey, 0)
|
||||
for k := range b.Config.Resources.Jobs {
|
||||
tasks := r.Jobs[k].JobSettings.Tasks
|
||||
for i := range tasks {
|
||||
|
@ -110,7 +110,7 @@ func (t *pythonTrampoline) GetTasks(b *bundle.Bundle) []mutator.TaskWithJobKey {
|
|||
continue
|
||||
}
|
||||
|
||||
result = append(result, mutator.TaskWithJobKey{
|
||||
result = append(result, TaskWithJobKey{
|
||||
JobKey: k,
|
||||
Task: task,
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
package python
|
||||
package trampoline
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -115,7 +115,7 @@ func TestTransformFiltersWheelTasksOnly(t *testing.T) {
|
|||
func TestNoPanicWithNoPythonWheelTasks(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
b := &bundle.Bundle{
|
||||
RootPath: tmpDir,
|
||||
BundleRootPath: tmpDir,
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "development",
|
|
@ -1,4 +1,4 @@
|
|||
package mutator
|
||||
package trampoline
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -23,6 +23,7 @@ type TrampolineFunctions interface {
|
|||
GetTasks(b *bundle.Bundle) []TaskWithJobKey
|
||||
CleanUp(task *jobs.Task) error
|
||||
}
|
||||
|
||||
type trampoline struct {
|
||||
name string
|
||||
functions TrampolineFunctions
|
|
@ -1,4 +1,4 @@
|
|||
package mutator
|
||||
package trampoline
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -56,8 +56,8 @@ func TestGenerateTrampoline(t *testing.T) {
|
|||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||
BundleRootPath: filepath.Join(tmpDir, "parent", "my_bundle"),
|
||||
SyncRootPath: filepath.Join(tmpDir, "parent"),
|
||||
Config: config.Root{
|
||||
Workspace: config.Workspace{
|
||||
FilePath: "/Workspace/files",
|
|
@ -24,7 +24,7 @@ func TestGeneratePipelineCommand(t *testing.T) {
|
|||
|
||||
root := t.TempDir()
|
||||
b := &bundle.Bundle{
|
||||
RootPath: root,
|
||||
BundleRootPath: root,
|
||||
}
|
||||
|
||||
m := mocks.NewMockWorkspaceClient(t)
|
||||
|
@ -122,7 +122,7 @@ func TestGenerateJobCommand(t *testing.T) {
|
|||
|
||||
root := t.TempDir()
|
||||
b := &bundle.Bundle{
|
||||
RootPath: root,
|
||||
BundleRootPath: root,
|
||||
}
|
||||
|
||||
m := mocks.NewMockWorkspaceClient(t)
|
||||
|
|
|
@ -17,10 +17,10 @@ import (
|
|||
func TestSyncOptionsFromBundle(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
b := &bundle.Bundle{
|
||||
RootPath: tempDir,
|
||||
BundleRoot: vfs.MustNew(tempDir),
|
||||
SyncRootPath: tempDir,
|
||||
SyncRoot: vfs.MustNew(tempDir),
|
||||
BundleRootPath: tempDir,
|
||||
BundleRoot: vfs.MustNew(tempDir),
|
||||
SyncRootPath: tempDir,
|
||||
SyncRoot: vfs.MustNew(tempDir),
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "default",
|
||||
|
|
|
@ -36,8 +36,8 @@ func TestAccUploadArtifactFileToCorrectRemotePath(t *testing.T) {
|
|||
wsDir := internal.TemporaryWorkspaceDir(t, w)
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: dir,
|
||||
SyncRootPath: dir,
|
||||
BundleRootPath: dir,
|
||||
SyncRootPath: dir,
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -101,8 +101,8 @@ func TestAccUploadArtifactFileToCorrectRemotePathWithEnvironments(t *testing.T)
|
|||
wsDir := internal.TemporaryWorkspaceDir(t, w)
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: dir,
|
||||
SyncRootPath: dir,
|
||||
BundleRootPath: dir,
|
||||
SyncRootPath: dir,
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
@ -171,8 +171,8 @@ func TestAccUploadArtifactFileToCorrectRemotePathForVolumes(t *testing.T) {
|
|||
touchEmptyFile(t, whlPath)
|
||||
|
||||
b := &bundle.Bundle{
|
||||
RootPath: dir,
|
||||
SyncRootPath: dir,
|
||||
BundleRootPath: dir,
|
||||
SyncRootPath: dir,
|
||||
Config: config.Root{
|
||||
Bundle: config.Bundle{
|
||||
Target: "whatever",
|
||||
|
|
Loading…
Reference in New Issue