mirror of https://github.com/databricks/cli.git
Compare commits
9 Commits
506a4bd3f8
...
7855d91597
Author | SHA1 | Date |
---|---|---|
|
7855d91597 | |
|
c07f1370d2 | |
|
79a52dc592 | |
|
c0cf3f8535 | |
|
8cc50c2a19 | |
|
bebbf4b767 | |
|
34a37cf4a8 | |
|
de5155ed0a | |
|
33613b5d2a |
|
@ -99,7 +99,7 @@ func TestAccept(t *testing.T) {
|
||||||
testName := strings.ReplaceAll(dir, "\\", "/")
|
testName := strings.ReplaceAll(dir, "\\", "/")
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
runTest(t, dir, coverDir, repls)
|
runTest(t, dir, coverDir, repls.Clone())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,13 @@ func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsCont
|
||||||
tmpDir = t.TempDir()
|
tmpDir = t.TempDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repls.Set("/private"+tmpDir, "$TMPDIR")
|
||||||
|
repls.Set("/private"+filepath.Dir(tmpDir), "$TMPPARENT")
|
||||||
|
repls.Set("/private"+filepath.Dir(filepath.Dir(tmpDir)), "$TMPGPARENT")
|
||||||
|
repls.Set(tmpDir, "$TMPDIR")
|
||||||
|
repls.Set(filepath.Dir(tmpDir), "$TMPPARENT")
|
||||||
|
repls.Set(filepath.Dir(filepath.Dir(tmpDir)), "$TMPGPARENT")
|
||||||
|
|
||||||
scriptContents := readMergedScriptContents(t, dir)
|
scriptContents := readMergedScriptContents(t, dir)
|
||||||
testutil.WriteFile(t, filepath.Join(tmpDir, EntryPointScript), scriptContents)
|
testutil.WriteFile(t, filepath.Join(tmpDir, EntryPointScript), scriptContents)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
bundle:
|
||||||
|
name: test-bundle
|
||||||
|
sync:
|
||||||
|
paths:
|
||||||
|
- ..
|
|
@ -0,0 +1,11 @@
|
||||||
|
Error: path "$TMPPARENT" is not within repository root "$TMPDIR"
|
||||||
|
|
||||||
|
Name: test-bundle
|
||||||
|
Target: default
|
||||||
|
Workspace:
|
||||||
|
User: $USERNAME
|
||||||
|
Path: /Workspace/Users/$USERNAME/.bundle/test-bundle/default
|
||||||
|
|
||||||
|
Found 1 error
|
||||||
|
|
||||||
|
Exit code: 1
|
|
@ -0,0 +1 @@
|
||||||
|
$CLI bundle validate
|
|
@ -0,0 +1,24 @@
|
||||||
|
workspace:
|
||||||
|
profile: profile_name
|
||||||
|
root_path: ${var.workspace_root}/path/to/root
|
||||||
|
|
||||||
|
variables:
|
||||||
|
workspace_root:
|
||||||
|
description: "root directory in the Databricks workspace to store the asset bundle and associated artifacts"
|
||||||
|
default: /Users/${workspace.current_user.userName}
|
||||||
|
|
||||||
|
targets:
|
||||||
|
dev:
|
||||||
|
default: true
|
||||||
|
prod:
|
||||||
|
variables:
|
||||||
|
workspace_root: /Shared
|
||||||
|
|
||||||
|
resources:
|
||||||
|
jobs:
|
||||||
|
my_job:
|
||||||
|
tasks:
|
||||||
|
- existing_cluster_id: 500
|
||||||
|
python_wheel_task:
|
||||||
|
named_parameters:
|
||||||
|
conf-file: "${workspace.file_path}/path/to/config.yaml"
|
|
@ -0,0 +1,67 @@
|
||||||
|
/Workspace should be prepended on all paths, but it is not the case:
|
||||||
|
{
|
||||||
|
"bundle": {
|
||||||
|
"environment": "dev",
|
||||||
|
"git": {
|
||||||
|
"bundle_root_path": ".",
|
||||||
|
"inferred": true
|
||||||
|
},
|
||||||
|
"target": "dev",
|
||||||
|
"terraform": {
|
||||||
|
"exec_path": "$TMPHOME"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"jobs": {
|
||||||
|
"my_job": {
|
||||||
|
"deployment": {
|
||||||
|
"kind": "BUNDLE",
|
||||||
|
"metadata_file_path": "/Users/$USERNAME/path/to/root/state/metadata.json"
|
||||||
|
},
|
||||||
|
"edit_mode": "UI_LOCKED",
|
||||||
|
"format": "MULTI_TASK",
|
||||||
|
"permissions": [],
|
||||||
|
"queue": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"tags": {},
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"existing_cluster_id": "500",
|
||||||
|
"python_wheel_task": {
|
||||||
|
"named_parameters": {
|
||||||
|
"conf-file": "/Users/$USERNAME/path/to/root/files/path/to/config.yaml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"task_key": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sync": {
|
||||||
|
"paths": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"targets": null,
|
||||||
|
"variables": {
|
||||||
|
"workspace_root": {
|
||||||
|
"default": "/Users/$USERNAME",
|
||||||
|
"description": "root directory in the Databricks workspace to store the asset bundle and associated artifacts",
|
||||||
|
"value": "/Users/$USERNAME"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"artifact_path": "/Users/$USERNAME/path/to/root/artifacts",
|
||||||
|
"current_user": {
|
||||||
|
"short_name": "$USERNAME",
|
||||||
|
"userName": "$USERNAME"
|
||||||
|
},
|
||||||
|
"file_path": "/Users/$USERNAME/path/to/root/files",
|
||||||
|
"profile": "profile_name",
|
||||||
|
"resource_path": "/Users/$USERNAME/path/to/root/resources",
|
||||||
|
"root_path": "/Users/$USERNAME/path/to/root",
|
||||||
|
"state_path": "/Users/$USERNAME/path/to/root/state"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
echo /Workspace should be prepended on all paths, but it is not the case: #2181
|
||||||
|
$CLI bundle validate -o json
|
|
@ -72,6 +72,7 @@ type Bundle struct {
|
||||||
// It can be initialized on demand after loading the configuration.
|
// It can be initialized on demand after loading the configuration.
|
||||||
clientOnce sync.Once
|
clientOnce sync.Once
|
||||||
client *databricks.WorkspaceClient
|
client *databricks.WorkspaceClient
|
||||||
|
clientErr error
|
||||||
|
|
||||||
// Files that are synced to the workspace.file_path
|
// Files that are synced to the workspace.file_path
|
||||||
Files []fileset.File
|
Files []fileset.File
|
||||||
|
@ -134,23 +135,25 @@ func TryLoad(ctx context.Context) (*Bundle, error) {
|
||||||
return Load(ctx, root)
|
return Load(ctx, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bundle) InitializeWorkspaceClient() (*databricks.WorkspaceClient, error) {
|
func (b *Bundle) WorkspaceClientE() (*databricks.WorkspaceClient, error) {
|
||||||
client, err := b.Config.Workspace.Client()
|
b.clientOnce.Do(func() {
|
||||||
if err != nil {
|
var err error
|
||||||
return nil, fmt.Errorf("cannot resolve bundle auth configuration: %w", err)
|
b.client, err = b.WorkspaceClientE()
|
||||||
}
|
if err != nil {
|
||||||
return client, nil
|
b.clientErr = fmt.Errorf("cannot resolve bundle auth configuration: %w", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return b.client, b.clientErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bundle) WorkspaceClient() *databricks.WorkspaceClient {
|
func (b *Bundle) WorkspaceClient() *databricks.WorkspaceClient {
|
||||||
b.clientOnce.Do(func() {
|
client, err := b.WorkspaceClientE()
|
||||||
var err error
|
if err != nil {
|
||||||
b.client, err = b.InitializeWorkspaceClient()
|
panic(err)
|
||||||
if err != nil {
|
}
|
||||||
panic(err)
|
|
||||||
}
|
return client
|
||||||
})
|
|
||||||
return b.client
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWorkpaceClient sets the workspace client for this bundle.
|
// SetWorkpaceClient sets the workspace client for this bundle.
|
||||||
|
|
|
@ -209,7 +209,7 @@ func MustWorkspaceClient(cmd *cobra.Command, args []string) error {
|
||||||
if b != nil {
|
if b != nil {
|
||||||
ctx = context.WithValue(ctx, &configUsed, b.Config.Workspace.Config())
|
ctx = context.WithValue(ctx, &configUsed, b.Config.Workspace.Config())
|
||||||
cmd.SetContext(ctx)
|
cmd.SetContext(ctx)
|
||||||
client, err := b.InitializeWorkspaceClient()
|
client, err := b.WorkspaceClientE()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ func configureBundle(cmd *cobra.Command, b *bundle.Bundle) (*bundle.Bundle, diag
|
||||||
|
|
||||||
// Set the auth configuration in the command context. This can be used
|
// Set the auth configuration in the command context. This can be used
|
||||||
// downstream to initialize a API client.
|
// downstream to initialize a API client.
|
||||||
client, err := b.InitializeWorkspaceClient()
|
client, err := b.WorkspaceClientE()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return b, diags.Extend(diag.FromErr(err))
|
return b, diags.Extend(diag.FromErr(err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/databricks/cli/internal/testutil"
|
"github.com/databricks/cli/internal/testutil"
|
||||||
|
@ -31,6 +32,10 @@ type ReplacementsContext struct {
|
||||||
Repls []Replacement
|
Repls []Replacement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ReplacementsContext) Clone() ReplacementsContext {
|
||||||
|
return ReplacementsContext{Repls: slices.Clone(r.Repls)}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ReplacementsContext) Replace(s string) string {
|
func (r *ReplacementsContext) Replace(s string) string {
|
||||||
// QQQ Should probably only replace whole words
|
// QQQ Should probably only replace whole words
|
||||||
for _, repl := range r.Repls {
|
for _, repl := range r.Repls {
|
||||||
|
|
Loading…
Reference in New Issue