mirror of https://github.com/databricks/cli.git
made events work and moved validation outside sync object
This commit is contained in:
parent
f0f75ff98f
commit
43aadba1f8
|
@ -99,6 +99,12 @@ var syncCmd = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that the remote path we're about to synchronize to is valid and allowed.
|
||||||
|
err = sync.EnsureRemotePathIsUserScoped(ctx, opts.WorkspaceClient, opts.RemotePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var outputFunc func(context.Context, <-chan sync.Event, io.Writer)
|
var outputFunc func(context.Context, <-chan sync.Event, io.Writer)
|
||||||
switch output {
|
switch output {
|
||||||
case flags.OutputText:
|
case flags.OutputText:
|
||||||
|
|
|
@ -55,7 +55,10 @@ var importDirCmd = &cobra.Command{
|
||||||
})
|
})
|
||||||
|
|
||||||
// Start Uploading local files
|
// Start Uploading local files
|
||||||
cmdio.RenderWithTemplate(ctx, newImportStartedEvent(sourcePath, targetPath), `Starting import {{.SourcePath}} -> {{TargetPath}}`)
|
err = cmdio.RenderWithTemplate(ctx, newImportStartedEvent(sourcePath, targetPath), "Starting import {{.SourcePath}} -> {{.TargetPath}}\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = s.RunOnce(ctx)
|
err = s.RunOnce(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -69,8 +72,7 @@ var importDirCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render import completetion event
|
// Render import completetion event
|
||||||
cmdio.RenderWithTemplate(ctx, newImportCompleteEvent(sourcePath, targetPath), `Completed import. Files available at {{.TargetPath}}`)
|
return cmdio.RenderWithTemplate(ctx, newImportCompleteEvent(sourcePath, targetPath), "Completed import. Files available at {{.TargetPath}}\n")
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ func newImportStartedEvent(sourcePath, targetPath string) fileIOEvent {
|
||||||
|
|
||||||
func newImportCompleteEvent(sourcePath, targetPath string) fileIOEvent {
|
func newImportCompleteEvent(sourcePath, targetPath string) fileIOEvent {
|
||||||
return fileIOEvent{
|
return fileIOEvent{
|
||||||
Type: EventTypeImportComplete,
|
Type: EventTypeImportComplete,
|
||||||
|
TargetPath: targetPath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,14 +53,17 @@ func renderSyncEvents(ctx context.Context, eventChannel <-chan sync.Event, synce
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if e.String() == "" {
|
if e.String() == "" {
|
||||||
return nil
|
continue
|
||||||
}
|
}
|
||||||
switch v := e.(type) {
|
switch v := e.(type) {
|
||||||
case *sync.EventSyncProgress:
|
case *sync.EventSyncProgress:
|
||||||
// TODO: only emit this event if the the sync event has progress 1.o0
|
// TODO: only emit this event if the the sync event has progress 1.o0
|
||||||
// File upload has been completed. This renders the event for that
|
// File upload has been completed. This renders the event for that
|
||||||
// on the console
|
// on the console
|
||||||
return cmdio.RenderWithTemplate(ctx, newUploadCompleteEvent(v.Path), `Uploaded {{.SourcePath}}`)
|
err := cmdio.RenderWithTemplate(ctx, newUploadCompleteEvent(v.Path), "Uploaded {{.SourcePath}}\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -459,12 +459,12 @@ func TestAccSyncEnsureRemotePathIsUsableIfRepoDoesntExist(t *testing.T) {
|
||||||
|
|
||||||
// Hypothetical repo path doesn't exist.
|
// Hypothetical repo path doesn't exist.
|
||||||
nonExistingRepoPath := fmt.Sprintf("/Repos/%s/%s", me.UserName, RandomName("doesnt-exist-"))
|
nonExistingRepoPath := fmt.Sprintf("/Repos/%s/%s", me.UserName, RandomName("doesnt-exist-"))
|
||||||
err = sync.EnsureRemotePathIsUsable(ctx, wsc, nonExistingRepoPath)
|
err = sync.EnsureRemotePathIsUserScoped(ctx, wsc, nonExistingRepoPath)
|
||||||
assert.ErrorContains(t, err, " does not exist; please create it first")
|
assert.ErrorContains(t, err, " does not exist; please create it first")
|
||||||
|
|
||||||
// Paths nested under a hypothetical repo path should yield the same error.
|
// Paths nested under a hypothetical repo path should yield the same error.
|
||||||
nestedPath := path.Join(nonExistingRepoPath, "nested/directory")
|
nestedPath := path.Join(nonExistingRepoPath, "nested/directory")
|
||||||
err = sync.EnsureRemotePathIsUsable(ctx, wsc, nestedPath)
|
err = sync.EnsureRemotePathIsUserScoped(ctx, wsc, nestedPath)
|
||||||
assert.ErrorContains(t, err, " does not exist; please create it first")
|
assert.ErrorContains(t, err, " does not exist; please create it first")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,12 +476,12 @@ func TestAccSyncEnsureRemotePathIsUsableIfRepoExists(t *testing.T) {
|
||||||
_, remoteRepoPath := setupRepo(t, wsc, ctx)
|
_, remoteRepoPath := setupRepo(t, wsc, ctx)
|
||||||
|
|
||||||
// Repo itself is usable.
|
// Repo itself is usable.
|
||||||
err := sync.EnsureRemotePathIsUsable(ctx, wsc, remoteRepoPath)
|
err := sync.EnsureRemotePathIsUserScoped(ctx, wsc, remoteRepoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Path nested under repo path is usable.
|
// Path nested under repo path is usable.
|
||||||
nestedPath := path.Join(remoteRepoPath, "nested/directory")
|
nestedPath := path.Join(remoteRepoPath, "nested/directory")
|
||||||
err = sync.EnsureRemotePathIsUsable(ctx, wsc, nestedPath)
|
err = sync.EnsureRemotePathIsUserScoped(ctx, wsc, nestedPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Verify that the directory has been created.
|
// Verify that the directory has been created.
|
||||||
|
@ -499,7 +499,7 @@ func TestAccSyncEnsureRemotePathIsUsableInWorkspace(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
remotePath := fmt.Sprintf("/Users/%s/%s", me.UserName, RandomName("ensure-path-exists-test-"))
|
remotePath := fmt.Sprintf("/Users/%s/%s", me.UserName, RandomName("ensure-path-exists-test-"))
|
||||||
err = sync.EnsureRemotePathIsUsable(ctx, wsc, remotePath)
|
err = sync.EnsureRemotePathIsUserScoped(ctx, wsc, remotePath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Clean up directory after test.
|
// Clean up directory after test.
|
||||||
|
|
|
@ -58,9 +58,9 @@ func repoPathForPath(me *iam.User, remotePath string) string {
|
||||||
return remotePath
|
return remotePath
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureRemotePathIsUsable checks if the specified path is nested under
|
// EnsureRemotePathIsUserScoped checks if the specified path is nested under
|
||||||
// expected base paths and if it is a directory or repository.
|
// the caller's username and if it is a directory or repository.
|
||||||
func EnsureRemotePathIsUsable(ctx context.Context, wsc *databricks.WorkspaceClient, remotePath string) error {
|
func EnsureRemotePathIsUserScoped(ctx context.Context, wsc *databricks.WorkspaceClient, remotePath string) error {
|
||||||
me, err := wsc.CurrentUser.Me(ctx)
|
me, err := wsc.CurrentUser.Me(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -31,11 +31,12 @@ type RepoFiles struct {
|
||||||
workspaceClient *databricks.WorkspaceClient
|
workspaceClient *databricks.WorkspaceClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func Create(repoRoot, localRoot string, workspaceClient *databricks.WorkspaceClient) *RepoFiles {
|
func Create(repoRoot, localRoot string, workspaceClient *databricks.WorkspaceClient, opts *RepoFileOptions) *RepoFiles {
|
||||||
return &RepoFiles{
|
return &RepoFiles{
|
||||||
repoRoot: repoRoot,
|
repoRoot: repoRoot,
|
||||||
localRoot: localRoot,
|
localRoot: localRoot,
|
||||||
workspaceClient: workspaceClient,
|
workspaceClient: workspaceClient,
|
||||||
|
RepoFileOptions: opts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
func TestRepoFilesRemotePath(t *testing.T) {
|
func TestRepoFilesRemotePath(t *testing.T) {
|
||||||
repoRoot := "/Repos/doraemon/bar"
|
repoRoot := "/Repos/doraemon/bar"
|
||||||
repoFiles := Create(repoRoot, "/doraemon/foo/bar", nil)
|
repoFiles := Create(repoRoot, "/doraemon/foo/bar", nil, nil)
|
||||||
|
|
||||||
remotePath, err := repoFiles.remotePath("a/b/c")
|
remotePath, err := repoFiles.remotePath("a/b/c")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -81,8 +81,8 @@ func TestRepoReadLocal(t *testing.T) {
|
||||||
err := os.WriteFile(helloPath, []byte("my name is doraemon :P"), os.ModePerm)
|
err := os.WriteFile(helloPath, []byte("my name is doraemon :P"), os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
repoFiles := Create("/Repos/doraemon/bar", tempDir, nil)
|
repoFiles := Create("/Repos/doraemon/bar", tempDir, nil, nil)
|
||||||
bytes, err := repoFiles.readLocal("./a/../hello.txt")
|
bytes, err := repoFiles.readLocal("./a/../hello.txt")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "my name is doraemon :P", string(bytes))
|
assert.Equal(t, "my name is doraemon :P", string(bytes), nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,12 +55,6 @@ func New(ctx context.Context, opts SyncOptions) (*Sync, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the remote path we're about to synchronize to is valid and allowed.
|
|
||||||
err = EnsureRemotePathIsUsable(ctx, opts.WorkspaceClient, opts.RemotePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: The host may be late-initialized in certain Azure setups where we
|
// TODO: The host may be late-initialized in certain Azure setups where we
|
||||||
// specify the workspace by its resource ID. tracked in: https://databricks.atlassian.net/browse/DECO-194
|
// specify the workspace by its resource ID. tracked in: https://databricks.atlassian.net/browse/DECO-194
|
||||||
opts.Host = opts.WorkspaceClient.Config.Host
|
opts.Host = opts.WorkspaceClient.Config.Host
|
||||||
|
@ -82,12 +76,9 @@ func New(ctx context.Context, opts SyncOptions) (*Sync, error) {
|
||||||
return nil, fmt.Errorf("unable to load sync snapshot: %w", err)
|
return nil, fmt.Errorf("unable to load sync snapshot: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
repoFiles, err := repofiles.Create(opts.RemotePath, opts.LocalPath, opts.WorkspaceClient, &repofiles.RepoFileOptions{
|
repoFiles := repofiles.Create(opts.RemotePath, opts.LocalPath, opts.WorkspaceClient, &repofiles.RepoFileOptions{
|
||||||
OverwriteIfExists: opts.AllowOverwrites,
|
OverwriteIfExists: opts.AllowOverwrites,
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Sync{
|
return &Sync{
|
||||||
SyncOptions: &opts,
|
SyncOptions: &opts,
|
||||||
|
|
Loading…
Reference in New Issue