made events work and moved validation outside sync object

This commit is contained in:
Shreyas Goenka 2023-06-06 15:12:56 +02:00
parent f0f75ff98f
commit 43aadba1f8
No known key found for this signature in database
GPG Key ID: 92A07DF49CCB0622
8 changed files with 32 additions and 28 deletions

View File

@ -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:

View File

@ -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
}, },
} }

View File

@ -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
}
} }
} }

View File

@ -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.

View File

@ -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

View File

@ -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,
} }
} }

View File

@ -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)
} }

View File

@ -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,