mirror of https://github.com/databricks/cli.git
Define translation mode and options
This commit is contained in:
parent
aa9226446b
commit
9c8c85ddc1
|
@ -17,6 +17,34 @@ import (
|
|||
"github.com/databricks/cli/libs/notebook"
|
||||
)
|
||||
|
||||
// TranslateMode specifies how a path should be translated.
|
||||
type TranslateMode int
|
||||
|
||||
const (
|
||||
// TranslateModeNotebook translates a path to a remote notebook.
|
||||
TranslateModeNotebook TranslateMode = iota
|
||||
|
||||
// TranslateModeFile translates a path to a remote regular file.
|
||||
TranslateModeFile
|
||||
|
||||
// TranslateModeDirectory translates a path to a remote directory.
|
||||
TranslateModeDirectory
|
||||
|
||||
// TranslateModeRetainLocalAbsoluteFilePath translates a path to the local absolute file path.
|
||||
TranslateModeRetainLocalAbsoluteFilePath
|
||||
|
||||
// TranslateModeNoOp does not translate the path.
|
||||
TranslateModeNoOp
|
||||
|
||||
// TranslateModeNoOpWithPrefix does not translate the path, but adds a prefix to it.
|
||||
TranslateModeNoOpWithPrefix
|
||||
)
|
||||
|
||||
// translateOptions specifies how a path should be translated.
|
||||
type translateOptions struct {
|
||||
Mode TranslateMode
|
||||
}
|
||||
|
||||
type ErrIsNotebook struct {
|
||||
path string
|
||||
}
|
||||
|
@ -44,8 +72,6 @@ func (m *translatePaths) Name() string {
|
|||
return "TranslatePaths"
|
||||
}
|
||||
|
||||
type rewriteFunc func(ctx context.Context, literal, localFullPath, localRelPath, remotePath string) (string, error)
|
||||
|
||||
// translateContext is a context for rewriting paths in a config.
|
||||
// It is freshly instantiated on every mutator apply call.
|
||||
// It provides access to the underlying bundle object such that
|
||||
|
@ -64,8 +90,8 @@ type translateContext struct {
|
|||
// - The context in which the function is called.
|
||||
// - The argument `dir` is the directory relative to which the relative path should be interpreted.
|
||||
// - The argument `input` is the relative path to rewrite.
|
||||
// - The argument `fn` is a function that performs the actual rewriting logic.
|
||||
// This logic is different between regular files or notebooks.
|
||||
// - The argument `opts` is a struct that specifies how the path should be rewritten.
|
||||
// It contains a `Mode` field that specifies how the path should be rewritten.
|
||||
//
|
||||
// The function returns the rewritten path if successful, or an error if the path could not be rewritten.
|
||||
// The returned path is an empty string if the path was not rewritten.
|
||||
|
@ -73,7 +99,7 @@ func (t *translateContext) rewritePath(
|
|||
ctx context.Context,
|
||||
dir string,
|
||||
input string,
|
||||
fn rewriteFunc,
|
||||
opts translateOptions,
|
||||
) (string, error) {
|
||||
// We assume absolute paths point to a location in the workspace
|
||||
if path.IsAbs(input) {
|
||||
|
@ -115,7 +141,23 @@ func (t *translateContext) rewritePath(
|
|||
remotePath := path.Join(workspacePath, filepath.ToSlash(localRelPath))
|
||||
|
||||
// Convert local path into workspace path via specified function.
|
||||
interp, err := fn(ctx, input, localPath, localRelPath, remotePath)
|
||||
var interp string
|
||||
switch opts.Mode {
|
||||
case TranslateModeNotebook:
|
||||
interp, err = t.translateNotebookPath(ctx, input, localPath, localRelPath, remotePath)
|
||||
case TranslateModeFile:
|
||||
interp, err = t.translateFilePath(ctx, input, localPath, localRelPath, remotePath)
|
||||
case TranslateModeDirectory:
|
||||
interp, err = t.translateDirectoryPath(ctx, input, localPath, localRelPath, remotePath)
|
||||
case TranslateModeRetainLocalAbsoluteFilePath:
|
||||
interp, err = t.retainLocalAbsoluteFilePath(ctx, input, localPath, localRelPath, remotePath)
|
||||
case TranslateModeNoOp:
|
||||
interp, err = t.translateNoOp(ctx, input, localPath, localRelPath, remotePath)
|
||||
case TranslateModeNoOpWithPrefix:
|
||||
interp, err = t.translateNoOpWithPrefix(ctx, input, localPath, localRelPath, remotePath)
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported translate mode: %d", opts.Mode)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -191,10 +233,6 @@ func (t *translateContext) translateDirectoryPath(ctx context.Context, literal,
|
|||
return remotePath, nil
|
||||
}
|
||||
|
||||
func (t *translateContext) translateNoOp(ctx context.Context, literal, localFullPath, localRelPath, remotePath string) (string, error) {
|
||||
return localRelPath, nil
|
||||
}
|
||||
|
||||
func (t *translateContext) retainLocalAbsoluteFilePath(ctx context.Context, literal, localFullPath, localRelPath, remotePath string) (string, error) {
|
||||
info, err := t.b.SyncRoot.Stat(filepath.ToSlash(localRelPath))
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
|
@ -209,6 +247,10 @@ func (t *translateContext) retainLocalAbsoluteFilePath(ctx context.Context, lite
|
|||
return localFullPath, nil
|
||||
}
|
||||
|
||||
func (t *translateContext) translateNoOp(ctx context.Context, literal, localFullPath, localRelPath, remotePath string) (string, error) {
|
||||
return localRelPath, nil
|
||||
}
|
||||
|
||||
func (t *translateContext) translateNoOpWithPrefix(ctx context.Context, literal, localFullPath, localRelPath, remotePath string) (string, error) {
|
||||
if !strings.HasPrefix(localRelPath, ".") {
|
||||
localRelPath = "." + string(filepath.Separator) + localRelPath
|
||||
|
@ -216,8 +258,8 @@ func (t *translateContext) translateNoOpWithPrefix(ctx context.Context, literal,
|
|||
return localRelPath, nil
|
||||
}
|
||||
|
||||
func (t *translateContext) rewriteValue(ctx context.Context, p dyn.Path, v dyn.Value, fn rewriteFunc, dir string) (dyn.Value, error) {
|
||||
out, err := t.rewritePath(ctx, dir, v.MustString(), fn)
|
||||
func (t *translateContext) rewriteValue(ctx context.Context, p dyn.Path, v dyn.Value, dir string, opts translateOptions) (dyn.Value, error) {
|
||||
out, err := t.rewritePath(ctx, dir, v.MustString(), opts)
|
||||
if err != nil {
|
||||
if target := (&ErrIsNotebook{}); errors.As(err, target) {
|
||||
return dyn.InvalidValue, fmt.Errorf(`expected a file for "%s" but got a notebook: %w`, p, target)
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
type artifactRewritePattern struct {
|
||||
pattern dyn.Pattern
|
||||
fn rewriteFunc
|
||||
opts translateOptions
|
||||
}
|
||||
|
||||
func (t *translateContext) artifactRewritePatterns() []artifactRewritePattern {
|
||||
|
@ -23,7 +23,7 @@ func (t *translateContext) artifactRewritePatterns() []artifactRewritePattern {
|
|||
return []artifactRewritePattern{
|
||||
{
|
||||
base.Append(dyn.Key("path")),
|
||||
t.translateNoOp,
|
||||
translateOptions{Mode: TranslateModeNoOp},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ func (t *translateContext) applyArtifactTranslations(ctx context.Context, v dyn.
|
|||
return dyn.InvalidValue, fmt.Errorf("unable to determine directory for artifact %s: %w", key, err)
|
||||
}
|
||||
|
||||
return t.rewriteValue(ctx, p, v, rewritePattern.fn, dir)
|
||||
return t.rewriteValue(ctx, p, v, dir, rewritePattern.opts)
|
||||
})
|
||||
if err != nil {
|
||||
return dyn.InvalidValue, err
|
||||
|
|
|
@ -17,6 +17,10 @@ func (t *translateContext) applyDashboardTranslations(ctx context.Context, v dyn
|
|||
dyn.Key("file_path"),
|
||||
)
|
||||
|
||||
opts := translateOptions{
|
||||
Mode: TranslateModeRetainLocalAbsoluteFilePath,
|
||||
}
|
||||
|
||||
return dyn.MapByPattern(v, pattern, func(p dyn.Path, v dyn.Value) (dyn.Value, error) {
|
||||
key := p[2].Key()
|
||||
dir, err := v.Location().Directory()
|
||||
|
@ -24,6 +28,6 @@ func (t *translateContext) applyDashboardTranslations(ctx context.Context, v dyn
|
|||
return dyn.InvalidValue, fmt.Errorf("unable to determine directory for dashboard %s: %w", key, err)
|
||||
}
|
||||
|
||||
return t.rewriteValue(ctx, p, v, t.retainLocalAbsoluteFilePath, dir)
|
||||
return t.rewriteValue(ctx, p, v, dir, opts)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -39,13 +39,17 @@ func (t *translateContext) applyJobTranslations(ctx context.Context, v dyn.Value
|
|||
return dyn.InvalidValue, fmt.Errorf("unable to determine directory for job %s: %w", key, err)
|
||||
}
|
||||
|
||||
rewritePatternFn, err := t.getRewritePatternFn(kind)
|
||||
mode, err := getJobTranslateMode(kind)
|
||||
if err != nil {
|
||||
return dyn.InvalidValue, err
|
||||
}
|
||||
|
||||
opts := translateOptions{
|
||||
Mode: mode,
|
||||
}
|
||||
|
||||
// Try to rewrite the path relative to the directory of the configuration file where the value was defined.
|
||||
nv, err := t.rewriteValue(ctx, p, v, rewritePatternFn, dir)
|
||||
nv, err := t.rewriteValue(ctx, p, v, dir, opts)
|
||||
if err == nil {
|
||||
return nv, nil
|
||||
}
|
||||
|
@ -53,7 +57,7 @@ func (t *translateContext) applyJobTranslations(ctx context.Context, v dyn.Value
|
|||
// If we failed to rewrite the path, try to rewrite it relative to the fallback directory.
|
||||
// We only do this for jobs and pipelines because of the comment in [gatherFallbackPaths].
|
||||
if fallback[key] != "" {
|
||||
nv, nerr := t.rewriteValue(ctx, p, v, rewritePatternFn, fallback[key])
|
||||
nv, nerr := t.rewriteValue(ctx, p, v, fallback[key], opts)
|
||||
if nerr == nil {
|
||||
// TODO: Emit a warning that this path should be rewritten.
|
||||
return nv, nil
|
||||
|
@ -64,19 +68,19 @@ func (t *translateContext) applyJobTranslations(ctx context.Context, v dyn.Value
|
|||
})
|
||||
}
|
||||
|
||||
func (t *translateContext) getRewritePatternFn(kind paths.PathKind) (rewriteFunc, error) {
|
||||
func getJobTranslateMode(kind paths.PathKind) (TranslateMode, error) {
|
||||
switch kind {
|
||||
case paths.PathKindLibrary:
|
||||
return t.translateNoOp, nil
|
||||
return TranslateModeNoOp, nil
|
||||
case paths.PathKindNotebook:
|
||||
return t.translateNotebookPath, nil
|
||||
return TranslateModeNotebook, nil
|
||||
case paths.PathKindWorkspaceFile:
|
||||
return t.translateFilePath, nil
|
||||
return TranslateModeFile, nil
|
||||
case paths.PathKindDirectory:
|
||||
return t.translateDirectoryPath, nil
|
||||
return TranslateModeDirectory, nil
|
||||
case paths.PathKindWithPrefix:
|
||||
return t.translateNoOpWithPrefix, nil
|
||||
return TranslateModeNoOpWithPrefix, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported path kind: %d", kind)
|
||||
return TranslateMode(0), fmt.Errorf("unsupported path kind: %d", kind)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
type pipelineRewritePattern struct {
|
||||
pattern dyn.Pattern
|
||||
fn rewriteFunc
|
||||
opts translateOptions
|
||||
}
|
||||
|
||||
func (t *translateContext) pipelineRewritePatterns() []pipelineRewritePattern {
|
||||
|
@ -26,11 +26,11 @@ func (t *translateContext) pipelineRewritePatterns() []pipelineRewritePattern {
|
|||
return []pipelineRewritePattern{
|
||||
{
|
||||
base.Append(dyn.Key("notebook"), dyn.Key("path")),
|
||||
t.translateNotebookPath,
|
||||
translateOptions{Mode: TranslateModeNotebook},
|
||||
},
|
||||
{
|
||||
base.Append(dyn.Key("file"), dyn.Key("path")),
|
||||
t.translateFilePath,
|
||||
translateOptions{Mode: TranslateModeFile},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ func (t *translateContext) applyPipelineTranslations(ctx context.Context, v dyn.
|
|||
}
|
||||
|
||||
// Try to rewrite the path relative to the directory of the configuration file where the value was defined.
|
||||
nv, err := t.rewriteValue(ctx, p, v, rewritePattern.fn, dir)
|
||||
nv, err := t.rewriteValue(ctx, p, v, dir, rewritePattern.opts)
|
||||
if err == nil {
|
||||
return nv, nil
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ func (t *translateContext) applyPipelineTranslations(ctx context.Context, v dyn.
|
|||
// If we failed to rewrite the path, try to rewrite it relative to the fallback directory.
|
||||
// We only do this for jobs and pipelines because of the comment in [gatherFallbackPaths].
|
||||
if fallback[key] != "" {
|
||||
nv, nerr := t.rewriteValue(ctx, p, v, rewritePattern.fn, fallback[key])
|
||||
nv, nerr := t.rewriteValue(ctx, p, v, fallback[key], rewritePattern.opts)
|
||||
if nerr == nil {
|
||||
// TODO: Emit a warning that this path should be rewritten.
|
||||
return nv, nil
|
||||
|
|
Loading…
Reference in New Issue