Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nextchanges/cli/6118.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support `dbfs:/Skills/...` paths in `databricks fs` commands, routed to the Files API.
1 change: 1 addition & 0 deletions acceptance/cmd/fs/cp/file-to-skill/local.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello world!
3 changes: 3 additions & 0 deletions acceptance/cmd/fs/cp/file-to-skill/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions acceptance/cmd/fs/cp/file-to-skill/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

>>> [CLI] fs cp local.txt dbfs:/Skills/main/default/fs-cp-test-[UNIQUE_NAME]/README.md
local.txt -> dbfs:/Skills/main/default/fs-cp-test-[UNIQUE_NAME]/README.md

>>> [CLI] fs cat dbfs:/Skills/main/default/fs-cp-test-[UNIQUE_NAME]/README.md
hello world!
13 changes: 13 additions & 0 deletions acceptance/cmd/fs/cp/file-to-skill/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CATALOG_NAME="main"
SCHEMA_NAME="default"
SKILL_NAME="fs-cp-test-${UNIQUE_NAME}"

# Create target directory. UC Skills are served by the Files API, so unlike the
# Volumes tests there is no catalog object to create first.
$CLI fs mkdir dbfs:/Skills/${CATALOG_NAME}/${SCHEMA_NAME}/${SKILL_NAME}

# Upload a local file into the skill bundle.
trace $CLI fs cp local.txt dbfs:/Skills/${CATALOG_NAME}/${SCHEMA_NAME}/${SKILL_NAME}/README.md

# Verify file was uploaded correctly.
trace $CLI fs cat dbfs:/Skills/${CATALOG_NAME}/${SCHEMA_NAME}/${SKILL_NAME}/README.md
4 changes: 4 additions & 0 deletions acceptance/cmd/fs/cp/file-to-skill/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Local only: the UC Skills Files API path is gated by a server-side feature flag
# that has not rolled out, so a real workspace rejects these writes.
Local = true
Cloud = false
2 changes: 1 addition & 1 deletion cmd/fs/cat.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func newCatCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "cat FILE_PATH",
Short: "Show file content.",
Long: `Show the contents of a file in DBFS or a UC Volume.`,
Long: `Show the contents of a file in DBFS, a UC Volume or a UC Skill.`,
Args: root.ExactArgs(1),
PreRunE: root.MustWorkspaceClient,
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/fs/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ func newCpCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "cp SOURCE_PATH TARGET_PATH",
Short: "Copy files and directories.",
Long: `Copy files and directories to and from any paths on DBFS, UC Volumes or your local filesystem.
Long: `Copy files and directories to and from any paths on DBFS, UC Volumes, UC Skills or your local filesystem.

For paths in DBFS and UC Volumes, it is required that you specify the "dbfs" scheme.
For paths in DBFS, UC Volumes and UC Skills, it is required that you specify the "dbfs" scheme.
For example: dbfs:/foo/bar.

Recursively copying a directory will copy all files inside directory
Expand Down
2 changes: 1 addition & 1 deletion cmd/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ func New() *cobra.Command {
cmd := &cobra.Command{
Use: "fs",
Short: "Filesystem related commands",
Long: `Commands to do file system operations on DBFS and UC Volumes.`,
Long: `Commands to do file system operations on DBFS, UC Volumes and UC Skills.`,
GroupID: "workspace",
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/fs/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ func filerForPath(ctx context.Context, fullPath string) (filer.Filer, string, er
path := parts[1]
w := cmdctx.WorkspaceClient(ctx)

// If the specified path has the "Volumes" prefix, use the Files API.
if strings.HasPrefix(path, "/Volumes/") {
// If the specified path has the "Volumes" or "Skills" prefix, use the Files API.
if strings.HasPrefix(path, "/Volumes/") || strings.HasPrefix(path, "/Skills/") {
f, err := filer.NewFilesClient(ctx, w, "/")
return f, path, err
}
Expand Down
26 changes: 26 additions & 0 deletions cmd/fs/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/databricks/cli/libs/cmdctx"
"github.com/databricks/cli/libs/fakefs"
"github.com/databricks/cli/libs/filer"
databrickscfg "github.com/databricks/databricks-sdk-go/config"
"github.com/databricks/databricks-sdk-go/experimental/mocks"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -41,6 +42,31 @@ func TestFilerForPathForInvalidScheme(t *testing.T) {
assert.ErrorContains(t, err, "invalid scheme")
}

func TestFilerForPathForDbfsScheme(t *testing.T) {
tcases := []struct {
fullPath string
path string
filer filer.Filer
}{
{"dbfs:/Volumes/foo/bar/baz", "/Volumes/foo/bar/baz", &filer.FilesClient{}},
{"dbfs:/Skills/foo/bar/baz", "/Skills/foo/bar/baz", &filer.FilesClient{}},
{"dbfs:/foo/bar/baz", "/foo/bar/baz", &filer.DbfsClient{}},
}

for _, tc := range tcases {
t.Run(tc.fullPath, func(t *testing.T) {
m := mocks.NewMockWorkspaceClient(t)
m.WorkspaceClient.Config = &databrickscfg.Config{}
ctx := cmdctx.SetWorkspaceClient(t.Context(), m.WorkspaceClient)

f, path, err := filerForPath(ctx, tc.fullPath)
require.NoError(t, err)
assert.Equal(t, tc.path, path)
assert.IsType(t, tc.filer, f)
})
}
}

func testWindowsFilerForPath(t *testing.T, ctx context.Context, fullPath string) {
f, path, err := filerForPath(ctx, fullPath)
assert.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion cmd/fs/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func newLsCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "ls DIR_PATH",
Short: "Lists files.",
Long: `Lists files in DBFS and UC Volumes.`,
Long: `Lists files in DBFS, UC Volumes and UC Skills.`,
Args: root.ExactArgs(1),
PreRunE: root.MustWorkspaceClient,
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/fs/mkdir.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func newMkdirCommand() *cobra.Command {
// is called databricks fs mkdirs in our legacy CLI: https://github.com/databricks/databricks-cli
Aliases: []string{"mkdirs"},
Short: "Make directories.",
Long: `Make directories in DBFS and UC Volumes. Mkdir will create directories along the path to the argument directory.`,
Long: `Make directories in DBFS, UC Volumes and UC Skills. Mkdir will create directories along the path to the argument directory.`,
Args: root.ExactArgs(1),
PreRunE: root.MustWorkspaceClient,
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/fs/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func newRmCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "rm PATH",
Short: "Remove files and directories.",
Long: `Remove files and directories from DBFS and UC Volumes.`,
Long: `Remove files and directories from DBFS, UC Volumes and UC Skills.`,
Args: root.ExactArgs(1),
PreRunE: root.MustWorkspaceClient,
}
Expand Down