Fix symlink behaviour (#1020)
* Fix symlink behaviour Make sure to evaluate symlinks when the path is not absolute and not local. Otherwise just fall back to regular absolute paths. Signed-off-by: Zoltán Reegn <zoltan.reegn@gmail.com>
This commit is contained in:
parent
ad258463b6
commit
4fb150238b
|
|
@ -34,17 +34,18 @@ type FileSystem struct {
|
||||||
Getwd func() (string, error)
|
Getwd func() (string, error)
|
||||||
Chdir func(string) error
|
Chdir func(string) error
|
||||||
Abs func(string) (string, error)
|
Abs func(string) (string, error)
|
||||||
|
EvalSymlinks func(string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultFileSystem() *FileSystem {
|
func DefaultFileSystem() *FileSystem {
|
||||||
dfs := FileSystem{
|
dfs := FileSystem{
|
||||||
ReadDir: os.ReadDir,
|
ReadDir: os.ReadDir,
|
||||||
DeleteFile: os.Remove,
|
DeleteFile: os.Remove,
|
||||||
Stat: os.Stat,
|
Stat: os.Stat,
|
||||||
Glob: filepath.Glob,
|
Glob: filepath.Glob,
|
||||||
Getwd: os.Getwd,
|
Getwd: os.Getwd,
|
||||||
Chdir: os.Chdir,
|
Chdir: os.Chdir,
|
||||||
Abs: filepath.Abs,
|
EvalSymlinks: filepath.EvalSymlinks,
|
||||||
}
|
}
|
||||||
|
|
||||||
dfs.Stat = dfs.stat
|
dfs.Stat = dfs.stat
|
||||||
|
|
@ -52,6 +53,7 @@ func DefaultFileSystem() *FileSystem {
|
||||||
dfs.FileExistsAt = dfs.fileExistsAtDefault
|
dfs.FileExistsAt = dfs.fileExistsAtDefault
|
||||||
dfs.DirectoryExistsAt = dfs.directoryExistsDefault
|
dfs.DirectoryExistsAt = dfs.directoryExistsDefault
|
||||||
dfs.FileExists = dfs.fileExistsDefault
|
dfs.FileExists = dfs.fileExistsDefault
|
||||||
|
dfs.Abs = dfs.absDefault
|
||||||
return &dfs
|
return &dfs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +93,9 @@ func FromFileSystem(params FileSystem) *FileSystem {
|
||||||
if params.Abs != nil {
|
if params.Abs != nil {
|
||||||
dfs.Abs = params.Abs
|
dfs.Abs = params.Abs
|
||||||
}
|
}
|
||||||
|
if params.EvalSymlinks != nil {
|
||||||
|
dfs.EvalSymlinks = params.EvalSymlinks
|
||||||
|
}
|
||||||
return dfs
|
return dfs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,13 +114,20 @@ func (filesystem *FileSystem) readFile(name string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (filesystem *FileSystem) fileExistsAtDefault(path string) bool {
|
func (filesystem *FileSystem) fileExistsAtDefault(path string) bool {
|
||||||
|
path, err := filesystem.resolveSymlinks(path)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
fileInfo, err := filesystem.Stat(path)
|
fileInfo, err := filesystem.Stat(path)
|
||||||
return err == nil && fileInfo.Mode().IsRegular()
|
return err == nil && fileInfo.Mode().IsRegular()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (filesystem *FileSystem) fileExistsDefault(path string) (bool, error) {
|
func (filesystem *FileSystem) fileExistsDefault(path string) (bool, error) {
|
||||||
_, err := filesystem.Stat(path)
|
path, err := filesystem.resolveSymlinks(path)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
_, err = filesystem.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
@ -127,6 +138,38 @@ func (filesystem *FileSystem) fileExistsDefault(path string) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (filesystem *FileSystem) directoryExistsDefault(path string) bool {
|
func (filesystem *FileSystem) directoryExistsDefault(path string) bool {
|
||||||
|
path, err := filesystem.resolveSymlinks(path)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
fileInfo, err := filesystem.Stat(path)
|
fileInfo, err := filesystem.Stat(path)
|
||||||
return err == nil && fileInfo.Mode().IsDir()
|
return err == nil && fileInfo.Mode().IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (filesystem *FileSystem) resolveSymlinks(path string) (string, error) {
|
||||||
|
if !filepath.IsAbs(path) && !filepath.IsLocal(path) {
|
||||||
|
basePath, err := filesystem.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
basePath, err = filesystem.EvalSymlinks(basePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
path, err := filesystem.EvalSymlinks(filepath.Join(basePath, path))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (filesystem *FileSystem) absDefault(path string) (string, error) {
|
||||||
|
path, err := filesystem.resolveSymlinks(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Abs(path)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,28 +12,58 @@ import (
|
||||||
func NewTestFileSystem() FileSystem {
|
func NewTestFileSystem() FileSystem {
|
||||||
replaceffs := FileSystem{
|
replaceffs := FileSystem{
|
||||||
Stat: func(s string) (os.FileInfo, error) {
|
Stat: func(s string) (os.FileInfo, error) {
|
||||||
if strings.HasPrefix(s, "existing_file") {
|
if strings.HasSuffix(s, "existing_file.txt") {
|
||||||
return fileStat{mode: 0}, nil
|
return fileStat{mode: 0}, nil
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(s, "existing_dir") {
|
if strings.HasSuffix(s, "existing_dir") {
|
||||||
return fileStat{mode: fs.ModeDir}, nil
|
return fileStat{mode: fs.ModeDir}, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("Error")
|
return nil, errors.New("Error")
|
||||||
},
|
},
|
||||||
|
Getwd: func() (string, error) {
|
||||||
|
return "/test/dir", nil
|
||||||
|
},
|
||||||
|
EvalSymlinks: func(s string) (string, error) {
|
||||||
|
if s == "/test/dir" {
|
||||||
|
return "/real/dir", nil
|
||||||
|
} else {
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return *FromFileSystem(replaceffs)
|
return *FromFileSystem(replaceffs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFs_resolveSymlinks(t *testing.T) {
|
||||||
|
ffs := NewTestFileSystem()
|
||||||
|
path, _ := ffs.resolveSymlinks("../existing_file.txt")
|
||||||
|
if path != "/real/existing_file.txt" {
|
||||||
|
t.Errorf("Expected absolute path %s but got %s", "/real/existing_file.txt", path)
|
||||||
|
}
|
||||||
|
path, _ = ffs.resolveSymlinks("./existing_file.txt")
|
||||||
|
if path != "./existing_file.txt" {
|
||||||
|
t.Errorf("Expected local path %s but got %s", "./existing_file.txt", path)
|
||||||
|
}
|
||||||
|
path, _ = ffs.resolveSymlinks("existing_file.txt")
|
||||||
|
if path != "existing_file.txt" {
|
||||||
|
t.Errorf("Expected local path %s but got %s", "existing_file.txt", path)
|
||||||
|
}
|
||||||
|
path, _ = ffs.resolveSymlinks("/a/b/c/existing_file.txt")
|
||||||
|
if path != "/a/b/c/existing_file.txt" {
|
||||||
|
t.Errorf("Expected absolute path %s but got %s", "/a/b/c/existing_file.txt", path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFs_fileExistsDefault(t *testing.T) {
|
func TestFs_fileExistsDefault(t *testing.T) {
|
||||||
ffs := NewTestFileSystem()
|
ffs := NewTestFileSystem()
|
||||||
var exists, _ = ffs.FileExists("existing_file.txt")
|
exists, _ := ffs.FileExists("existing_file.txt")
|
||||||
if !exists {
|
if !exists {
|
||||||
t.Errorf("Expected file %s, not found", "existing_file.txt")
|
t.Errorf("Expected file %s, not found", "existing_file.txt")
|
||||||
}
|
}
|
||||||
|
|
||||||
exists, _ = ffs.FileExists("non_existing_file.txt")
|
exists, _ = ffs.FileExists("missing_file.txt")
|
||||||
if exists {
|
if exists {
|
||||||
t.Errorf("Not expected file %s, found", "non_existing_file.txt")
|
t.Errorf("Not expected file %s, found", "missing_file.txt")
|
||||||
}
|
}
|
||||||
|
|
||||||
dfs := DefaultFileSystem()
|
dfs := DefaultFileSystem()
|
||||||
|
|
@ -46,14 +76,14 @@ func TestFs_fileExistsDefault(t *testing.T) {
|
||||||
func TestFs_fileExistsAtDefault(t *testing.T) {
|
func TestFs_fileExistsAtDefault(t *testing.T) {
|
||||||
ffs := NewTestFileSystem()
|
ffs := NewTestFileSystem()
|
||||||
|
|
||||||
var exists = ffs.FileExistsAt("existing_file.txt")
|
exists := ffs.FileExistsAt("existing_file.txt")
|
||||||
if !exists {
|
if !exists {
|
||||||
t.Errorf("Expected file %s, not found", "existing_file.txt")
|
t.Errorf("Expected file %s, not found", "existing_file.txt")
|
||||||
}
|
}
|
||||||
|
|
||||||
exists = ffs.FileExistsAt("non_existing_file.txt")
|
exists = ffs.FileExistsAt("missing_file.txt")
|
||||||
if exists {
|
if exists {
|
||||||
t.Errorf("Not expected file %s, found", "non_existing_file.txt")
|
t.Errorf("Not expected file %s, found", "missing_file.txt")
|
||||||
}
|
}
|
||||||
|
|
||||||
exists = ffs.FileExistsAt("existing_dir")
|
exists = ffs.FileExistsAt("existing_dir")
|
||||||
|
|
@ -70,12 +100,12 @@ func TestFs_fileExistsAtDefault(t *testing.T) {
|
||||||
|
|
||||||
func TestFs_directoryExistsDefault(t *testing.T) {
|
func TestFs_directoryExistsDefault(t *testing.T) {
|
||||||
ffs := NewTestFileSystem()
|
ffs := NewTestFileSystem()
|
||||||
var exists = ffs.DirectoryExistsAt("existing_dir")
|
exists := ffs.DirectoryExistsAt("existing_dir")
|
||||||
if !exists {
|
if !exists {
|
||||||
t.Errorf("Expected file %s, not found", "existing_dir")
|
t.Errorf("Expected file %s, not found", "existing_dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
exists = ffs.DirectoryExistsAt("not_existing_dir")
|
exists = ffs.DirectoryExistsAt("missing_dir")
|
||||||
if exists {
|
if exists {
|
||||||
t.Errorf("Not expected file %s, found", "existing_dir")
|
t.Errorf("Not expected file %s, found", "existing_dir")
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +178,8 @@ func TestFs_DefaultBuilder(t *testing.T) {
|
||||||
ffs.Stat == nil ||
|
ffs.Stat == nil ||
|
||||||
ffs.Getwd == nil ||
|
ffs.Getwd == nil ||
|
||||||
ffs.Chdir == nil ||
|
ffs.Chdir == nil ||
|
||||||
ffs.Abs == nil {
|
ffs.Abs == nil ||
|
||||||
|
ffs.EvalSymlinks == nil {
|
||||||
t.Errorf("Missing functions in DefaultFileSystem")
|
t.Errorf("Missing functions in DefaultFileSystem")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue