mirror of https://github.com/databricks/cli.git
This commit is contained in:
parent
cf04ef8550
commit
7529c8a4ca
|
@ -18,11 +18,8 @@ type LocalClient struct {
|
|||
}
|
||||
|
||||
func NewLocalClient(root string) (Filer, error) {
|
||||
if runtime.GOOS == "windows" && root == "/" {
|
||||
// Windows file systems do not have a "root" directory. Instead paths require
|
||||
// a Volume/Drive letter specified. This allows us to refer to files across
|
||||
// different drives from a single client
|
||||
return &LocalClient{root: NopRootPath{}}, nil
|
||||
if runtime.GOOS == "windows" {
|
||||
return &LocalClient{root: WindowsRootPath{root}}, nil
|
||||
}
|
||||
return &LocalClient{
|
||||
root: NewUnixRootPath(root),
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package filer
|
||||
|
||||
// RootPath can be joined with a relative path and ensures that
|
||||
// the returned path is always a strict child of the root path.
|
||||
type RootPath interface {
|
||||
// Join returns the specified path name joined to the root.
|
||||
// It returns an error if the resulting path is not a strict child of the root path.
|
||||
Join(string) (string, error)
|
||||
|
||||
Root() string
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// UnixRootPath can be joined with a relative path and ensures that
|
||||
// the returned path is always a strict child of the root path.
|
||||
type UnixRootPath struct {
|
||||
rootPath string
|
||||
}
|
||||
|
@ -20,8 +18,6 @@ func NewUnixRootPath(name string) UnixRootPath {
|
|||
}
|
||||
}
|
||||
|
||||
// Join returns the specified path name joined to the root.
|
||||
// It returns an error if the resulting path is not a strict child of the root path.
|
||||
func (p UnixRootPath) Join(name string) (string, error) {
|
||||
absPath := path.Join(p.rootPath, name)
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package filer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type WindowsRootPath struct {
|
||||
rootPath string
|
||||
}
|
||||
|
||||
func NewWindowsRootPath(name string) WindowsRootPath {
|
||||
// Windows file systems do not have a "root" directory. Instead paths require
|
||||
// a Volume/Drive letter specified. If a user of this struct specifies "/" then
|
||||
// we treat it as the "root" and skip any validation
|
||||
if name == "/" {
|
||||
return WindowsRootPath{""}
|
||||
}
|
||||
|
||||
return WindowsRootPath{filepath.Clean(name)}
|
||||
}
|
||||
|
||||
// Join returns the specified path name joined to the root.
|
||||
// It returns an error if the resulting path is not a strict child of the root path.
|
||||
func (p WindowsRootPath) Join(name string) (string, error) {
|
||||
absPath := filepath.Join(p.rootPath, name)
|
||||
|
||||
// Don't allow escaping the specified root using relative paths.
|
||||
if !strings.HasPrefix(absPath, p.rootPath) {
|
||||
return "", fmt.Errorf("relative path escapes root: %s", name)
|
||||
}
|
||||
|
||||
return absPath, nil
|
||||
}
|
||||
|
||||
func (p WindowsRootPath) Root() string {
|
||||
return p.rootPath
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package filer
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestWindowsRootPathForRoot(t *testing.T) {
|
||||
if runtime.GOOS != "windows" {
|
||||
t.Skip("this test is meant for windows")
|
||||
}
|
||||
|
||||
rp := NewWindowsRootPath("/")
|
||||
|
||||
// Assert root value returned
|
||||
assert.Equal(t, "", rp.Root())
|
||||
|
||||
// case: absolute windows path
|
||||
path, err := rp.Join(`c:\a\b`)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `c:\a\b`, path)
|
||||
|
||||
// case: absolute windows path following file URI scheme
|
||||
path, err = rp.Join(`D:/a/b`)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `D:/a/b`, path)
|
||||
|
||||
// case: relative windows paths
|
||||
path, err = rp.Join(`c:a\b`)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `c:a\b`, path)
|
||||
|
||||
path, err = rp.Join(`c:a`)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `c:a`, path)
|
||||
|
||||
// case: relative windows paths following file URI scheme
|
||||
path, err = rp.Join(`c:a/b`)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `C:a/b`, path)
|
||||
}
|
||||
|
||||
func TestWindowsRootPath(t *testing.T) {
|
||||
if runtime.GOOS != "windows" {
|
||||
t.Skip("this test is meant for windows")
|
||||
}
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
rp := NewWindowsRootPath(t.TempDir())
|
||||
|
||||
// Assert root value returned
|
||||
assert.Equal(t, tmpDir, rp.Root())
|
||||
|
||||
path, err := rp.Join(`a\b\c`)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tmpDir+`\a\b`, path)
|
||||
|
||||
path, err = rp.Join("a/b")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tmpDir + `\a/b`, path)
|
||||
}
|
Loading…
Reference in New Issue