mirror of https://github.com/databricks/cli.git
Add Stat function to filer.Filer interface (#421)
## Changes TSIA ## Tests New integration test passes.
This commit is contained in:
parent
7a4ca786d8
commit
2b56af6016
|
@ -68,11 +68,32 @@ func runFilerReadWriteTest(t *testing.T, ctx context.Context, f filer.Filer) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
filerTest{t, f}.assertContents(ctx, "/foo/bar", `hello universe`)
|
filerTest{t, f}.assertContents(ctx, "/foo/bar", `hello universe`)
|
||||||
|
|
||||||
|
// Stat on a directory should succeed.
|
||||||
|
// Note: size and modification time behave differently between WSFS and DBFS.
|
||||||
|
info, err := f.Stat(ctx, "/foo")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "foo", info.Name())
|
||||||
|
assert.True(t, info.Mode().IsDir())
|
||||||
|
assert.Equal(t, true, info.IsDir())
|
||||||
|
|
||||||
|
// Stat on a file should succeed.
|
||||||
|
// Note: size and modification time behave differently between WSFS and DBFS.
|
||||||
|
info, err = f.Stat(ctx, "/foo/bar")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "bar", info.Name())
|
||||||
|
assert.True(t, info.Mode().IsRegular())
|
||||||
|
assert.Equal(t, false, info.IsDir())
|
||||||
|
|
||||||
// Delete should fail if the file doesn't exist.
|
// Delete should fail if the file doesn't exist.
|
||||||
err = f.Delete(ctx, "/doesnt_exist")
|
err = f.Delete(ctx, "/doesnt_exist")
|
||||||
assert.True(t, errors.As(err, &filer.FileDoesNotExistError{}))
|
assert.True(t, errors.As(err, &filer.FileDoesNotExistError{}))
|
||||||
assert.True(t, errors.Is(err, fs.ErrNotExist))
|
assert.True(t, errors.Is(err, fs.ErrNotExist))
|
||||||
|
|
||||||
|
// Stat should fail if the file doesn't exist.
|
||||||
|
_, err = f.Stat(ctx, "/doesnt_exist")
|
||||||
|
assert.True(t, errors.As(err, &filer.FileDoesNotExistError{}))
|
||||||
|
assert.True(t, errors.Is(err, fs.ErrNotExist))
|
||||||
|
|
||||||
// Delete should succeed for file that does exist.
|
// Delete should succeed for file that does exist.
|
||||||
err = f.Delete(ctx, "/foo/bar")
|
err = f.Delete(ctx, "/foo/bar")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
@ -22,11 +22,7 @@ type dbfsDirEntry struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry dbfsDirEntry) Type() fs.FileMode {
|
func (entry dbfsDirEntry) Type() fs.FileMode {
|
||||||
typ := fs.ModePerm
|
return entry.Mode()
|
||||||
if entry.fi.IsDir {
|
|
||||||
typ |= fs.ModeDir
|
|
||||||
}
|
|
||||||
return typ
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry dbfsDirEntry) Info() (fs.FileInfo, error) {
|
func (entry dbfsDirEntry) Info() (fs.FileInfo, error) {
|
||||||
|
@ -47,7 +43,11 @@ func (info dbfsFileInfo) Size() int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (info dbfsFileInfo) Mode() fs.FileMode {
|
func (info dbfsFileInfo) Mode() fs.FileMode {
|
||||||
return fs.ModePerm
|
mode := fs.ModePerm
|
||||||
|
if info.fi.IsDir {
|
||||||
|
mode |= fs.ModeDir
|
||||||
|
}
|
||||||
|
return mode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (info dbfsFileInfo) ModTime() time.Time {
|
func (info dbfsFileInfo) ModTime() time.Time {
|
||||||
|
@ -240,3 +240,29 @@ func (w *DbfsClient) Mkdir(ctx context.Context, name string) error {
|
||||||
|
|
||||||
return w.workspaceClient.Dbfs.MkdirsByPath(ctx, dirPath)
|
return w.workspaceClient.Dbfs.MkdirsByPath(ctx, dirPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *DbfsClient) Stat(ctx context.Context, name string) (fs.FileInfo, error) {
|
||||||
|
absPath, err := w.root.Join(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := w.workspaceClient.Dbfs.GetStatusByPath(ctx, absPath)
|
||||||
|
if err != nil {
|
||||||
|
var aerr *apierr.APIError
|
||||||
|
if !errors.As(err, &aerr) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// This API returns a 404 if the file doesn't exist.
|
||||||
|
if aerr.StatusCode == http.StatusNotFound {
|
||||||
|
if aerr.ErrorCode == "RESOURCE_DOES_NOT_EXIST" {
|
||||||
|
return nil, FileDoesNotExistError{absPath}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbfsFileInfo{*info}, nil
|
||||||
|
}
|
||||||
|
|
|
@ -68,4 +68,7 @@ type Filer interface {
|
||||||
|
|
||||||
// Creates directory at `path`, creating any intermediate directories as required.
|
// Creates directory at `path`, creating any intermediate directories as required.
|
||||||
Mkdir(ctx context.Context, path string) error
|
Mkdir(ctx context.Context, path string) error
|
||||||
|
|
||||||
|
// Stat returns information about the file at `path`.
|
||||||
|
Stat(ctx context.Context, name string) (fs.FileInfo, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,3 +256,26 @@ func (w *WorkspaceFilesClient) Mkdir(ctx context.Context, name string) error {
|
||||||
Path: dirPath,
|
Path: dirPath,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WorkspaceFilesClient) Stat(ctx context.Context, name string) (fs.FileInfo, error) {
|
||||||
|
absPath, err := w.root.Join(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := w.workspaceClient.Workspace.GetStatusByPath(ctx, absPath)
|
||||||
|
if err != nil {
|
||||||
|
// If we got an API error we deal with it below.
|
||||||
|
var aerr *apierr.APIError
|
||||||
|
if !errors.As(err, &aerr) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// This API returns a 404 if the specified path does not exist.
|
||||||
|
if aerr.StatusCode == http.StatusNotFound {
|
||||||
|
return nil, FileDoesNotExistError{absPath}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wsfsFileInfo{*info}, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue