2023-06-05 15:41:30 +00:00
|
|
|
package fs
|
|
|
|
|
|
|
|
import (
|
2023-06-16 15:09:08 +00:00
|
|
|
"context"
|
2023-06-05 15:41:30 +00:00
|
|
|
"fmt"
|
2023-06-16 15:09:08 +00:00
|
|
|
"runtime"
|
2023-06-05 15:41:30 +00:00
|
|
|
"strings"
|
2023-06-16 15:09:08 +00:00
|
|
|
|
|
|
|
"github.com/databricks/cli/cmd/root"
|
|
|
|
"github.com/databricks/cli/libs/filer"
|
2024-08-09 09:40:25 +00:00
|
|
|
"github.com/databricks/cli/libs/filer/completer"
|
|
|
|
"github.com/spf13/cobra"
|
2023-06-16 15:09:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func filerForPath(ctx context.Context, fullPath string) (filer.Filer, string, error) {
|
2023-06-23 14:07:09 +00:00
|
|
|
// Split path at : to detect any file schemes
|
|
|
|
parts := strings.SplitN(fullPath, ":", 2)
|
|
|
|
|
|
|
|
// If no scheme is specified, then local path
|
2023-06-16 15:09:08 +00:00
|
|
|
if len(parts) < 2 {
|
2023-06-23 14:07:09 +00:00
|
|
|
f, err := filer.NewLocalClient("")
|
|
|
|
return f, fullPath, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// On windows systems, paths start with a drive letter. If the scheme
|
|
|
|
// is a single letter and the OS is windows, then we conclude the path
|
|
|
|
// is meant to be a local path.
|
|
|
|
if runtime.GOOS == "windows" && len(parts[0]) == 1 {
|
|
|
|
f, err := filer.NewLocalClient("")
|
|
|
|
return f, fullPath, err
|
2023-06-05 15:41:30 +00:00
|
|
|
}
|
2023-06-23 14:07:09 +00:00
|
|
|
|
|
|
|
if parts[0] != "dbfs" {
|
|
|
|
return nil, "", fmt.Errorf("invalid scheme: %s", parts[0])
|
|
|
|
}
|
|
|
|
|
2023-06-16 15:09:08 +00:00
|
|
|
path := parts[1]
|
2023-06-23 14:07:09 +00:00
|
|
|
w := root.WorkspaceClient(ctx)
|
2023-06-16 15:09:08 +00:00
|
|
|
|
2023-06-23 14:07:09 +00:00
|
|
|
// If the specified path has the "Volumes" prefix, use the Files API.
|
|
|
|
if strings.HasPrefix(path, "/Volumes/") {
|
|
|
|
f, err := filer.NewFilesClient(w, "/")
|
2023-06-16 15:09:08 +00:00
|
|
|
return f, path, err
|
|
|
|
}
|
2023-06-23 14:07:09 +00:00
|
|
|
|
|
|
|
// The file is a dbfs file, and uses the DBFS APIs
|
|
|
|
f, err := filer.NewDbfsClient(w, "/")
|
|
|
|
return f, path, err
|
2023-06-05 15:41:30 +00:00
|
|
|
}
|
2023-06-27 12:42:27 +00:00
|
|
|
|
2024-08-09 09:40:25 +00:00
|
|
|
const dbfsPrefix string = "dbfs:"
|
|
|
|
|
2023-06-27 12:42:27 +00:00
|
|
|
func isDbfsPath(path string) bool {
|
2024-08-09 09:40:25 +00:00
|
|
|
return strings.HasPrefix(path, dbfsPrefix)
|
|
|
|
}
|
|
|
|
|
|
|
|
type validArgs struct {
|
|
|
|
mustWorkspaceClientFunc func(cmd *cobra.Command, args []string) error
|
|
|
|
filerForPathFunc func(ctx context.Context, fullPath string) (filer.Filer, string, error)
|
|
|
|
pathArgCount int
|
|
|
|
onlyDirs bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func newValidArgs() *validArgs {
|
|
|
|
return &validArgs{
|
|
|
|
mustWorkspaceClientFunc: root.MustWorkspaceClient,
|
|
|
|
filerForPathFunc: filerForPath,
|
|
|
|
pathArgCount: 1,
|
|
|
|
onlyDirs: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *validArgs) Validate(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
|
|
cmd.SetContext(root.SkipPrompt(cmd.Context()))
|
|
|
|
|
|
|
|
if len(args) >= v.pathArgCount {
|
|
|
|
return nil, cobra.ShellCompDirectiveNoFileComp
|
|
|
|
}
|
|
|
|
|
|
|
|
err := v.mustWorkspaceClientFunc(cmd, args)
|
|
|
|
if err != nil {
|
|
|
|
return nil, cobra.ShellCompDirectiveError
|
|
|
|
}
|
|
|
|
|
|
|
|
filer, toCompletePath, err := v.filerForPathFunc(cmd.Context(), toComplete)
|
|
|
|
if err != nil {
|
|
|
|
return nil, cobra.ShellCompDirectiveError
|
|
|
|
}
|
|
|
|
|
|
|
|
completer := completer.New(cmd.Context(), filer, v.onlyDirs)
|
|
|
|
|
|
|
|
// Dbfs should have a prefix and always use the "/" separator
|
|
|
|
isDbfsPath := isDbfsPath(toComplete)
|
|
|
|
if isDbfsPath {
|
|
|
|
completer.SetPrefix(dbfsPrefix)
|
|
|
|
completer.SetIsLocalPath(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
completions, directive, err := completer.CompletePath(toCompletePath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, cobra.ShellCompDirectiveError
|
|
|
|
}
|
|
|
|
|
|
|
|
return completions, directive
|
2023-06-27 12:42:27 +00:00
|
|
|
}
|