Allow equivalence checking of filer errors to fs errors (#416)

## Changes

The pattern `errors.Is(err, fs.ErrNotExist)` is common to check for an
error type.

Errors can implement `Is(error) bool` with a custom equivalence checker.

## Tests

New asserts all pass in the integration test.
This commit is contained in:
Pieter Noordhuis 2023-05-31 18:47:00 +00:00 committed by GitHub
parent 42cd8daee0
commit 349e2aff40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 2 deletions

View File

@ -2,14 +2,15 @@ package terraform
import (
"context"
"errors"
"io"
"io/fs"
"os"
"path/filepath"
"github.com/databricks/cli/bundle"
"github.com/databricks/cli/libs/filer"
"github.com/databricks/cli/libs/log"
"github.com/databricks/databricks-sdk-go/apierr"
)
type statePull struct{}
@ -34,7 +35,7 @@ func (l *statePull) Apply(ctx context.Context, b *bundle.Bundle) error {
remote, err := f.Read(ctx, TerraformStateFileName)
if err != nil {
// On first deploy this state file doesn't yet exist.
if apierr.IsMissing(err) {
if errors.Is(err, fs.ErrNotExist) {
log.Infof(ctx, "Remote state file does not exist")
return nil
}

View File

@ -46,10 +46,12 @@ func runFilerReadWriteTest(t *testing.T, ctx context.Context, f filer.Filer) {
// Write should fail because the root path doesn't yet exist.
err = f.Write(ctx, "/foo/bar", strings.NewReader(`hello world`))
assert.True(t, errors.As(err, &filer.NoSuchDirectoryError{}))
assert.True(t, errors.Is(err, fs.ErrNotExist))
// Read should fail because the root path doesn't yet exist.
_, err = f.Read(ctx, "/foo/bar")
assert.True(t, errors.As(err, &filer.FileDoesNotExistError{}))
assert.True(t, errors.Is(err, fs.ErrNotExist))
// Write with CreateParentDirectories flag should succeed.
err = f.Write(ctx, "/foo/bar", strings.NewReader(`hello world`), filer.CreateParentDirectories)
@ -59,6 +61,7 @@ func runFilerReadWriteTest(t *testing.T, ctx context.Context, f filer.Filer) {
// Write should fail because there is an existing file at the specified path.
err = f.Write(ctx, "/foo/bar", strings.NewReader(`hello universe`))
assert.True(t, errors.As(err, &filer.FileAlreadyExistsError{}))
assert.True(t, errors.Is(err, fs.ErrExist))
// Write with OverwriteIfExists should succeed.
err = f.Write(ctx, "/foo/bar", strings.NewReader(`hello universe`), filer.OverwriteIfExists)
@ -68,6 +71,7 @@ func runFilerReadWriteTest(t *testing.T, ctx context.Context, f filer.Filer) {
// Delete should fail if the file doesn't exist.
err = f.Delete(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.
err = f.Delete(ctx, "/foo/bar")
@ -102,6 +106,7 @@ func runFilerReadDirTest(t *testing.T, ctx context.Context, f filer.Filer) {
// Expect an error if the path doesn't exist.
_, err = f.ReadDir(ctx, "/dir/a/b/c/d/e")
assert.True(t, errors.As(err, &filer.NoSuchDirectoryError{}), err)
assert.True(t, errors.Is(err, fs.ErrNotExist))
// Expect two entries in the root.
entries, err = f.ReadDir(ctx, ".")

View File

@ -22,10 +22,18 @@ func (err FileAlreadyExistsError) Error() string {
return fmt.Sprintf("file already exists: %s", err.path)
}
func (err FileAlreadyExistsError) Is(other error) bool {
return other == fs.ErrExist
}
type FileDoesNotExistError struct {
path string
}
func (err FileDoesNotExistError) Is(other error) bool {
return other == fs.ErrNotExist
}
func (err FileDoesNotExistError) Error() string {
return fmt.Sprintf("file does not exist: %s", err.path)
}
@ -38,6 +46,10 @@ func (err NoSuchDirectoryError) Error() string {
return fmt.Sprintf("no such directory: %s", err.path)
}
func (err NoSuchDirectoryError) Is(other error) bool {
return other == fs.ErrNotExist
}
// Filer is used to access files in a workspace.
// It has implementations for accessing files in WSFS and in DBFS.
type Filer interface {