-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into default-test
- Loading branch information
Showing
5 changed files
with
201 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Package loadfile provides functions to load files from a directory. | ||
package loadfile | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
) | ||
|
||
// LoadContext reads the content of each file into a map where the key | ||
// is the absolute filepath and the file content is the value. | ||
func LoadContext(neededFilepaths []string) (map[string][]byte, error) { | ||
result := map[string][]byte{} | ||
var err error | ||
for _, filePath := range neededFilepaths { | ||
absPath, err := filepath.Abs(filePath) | ||
if err != nil { | ||
return nil, fmt.Errorf("error obtaining absolute path of file %s (%w)", | ||
filePath, err) | ||
} | ||
fileData, err := os.ReadFile(filepath.Clean(absPath)) | ||
if err != nil { | ||
return nil, fmt.Errorf("error reading file %s (%w)", absPath, err) | ||
} | ||
result[absPath] = fileData | ||
} | ||
return result, err | ||
} | ||
|
||
// AbsPathsWithContext creates a map of absolute filepaths. If a required | ||
// file is not provided with an absolute path, then it is joined with the | ||
// root directory. | ||
func AbsPathsWithContext(rootDir string, requiredFiles map[string]string) (map[string]string, error) { | ||
absDir, err := filepath.Abs(rootDir) | ||
if err != nil { | ||
return nil, fmt.Errorf("error determining context directory absolute path %s (%w)", rootDir, err) | ||
} | ||
requiredFilesAbs := map[string]string{} | ||
for key, f := range requiredFiles { | ||
abspath := f | ||
if !filepath.IsAbs(f) { | ||
abspath = filepath.Join(absDir, f) | ||
} | ||
requiredFilesAbs[key] = abspath | ||
} | ||
return requiredFilesAbs, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package loadfile_test | ||
|
||
import ( | ||
"go.arcalot.io/assert" | ||
"go.flow.arcalot.io/engine/loadfile" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
) | ||
|
||
// This tests the functional behavior of LoadContext when it is given | ||
// a directory of files that cover more than the directory file node | ||
// type 'd' (as seen in *nix systems). Specifically, this test adds | ||
// symbolic link files for a regular file and a directory file. The | ||
// engine should only attempt to read files of a type that the os can | ||
// read (i.e. not throw an error on a call to os.ReadFile()), and | ||
// disregard (not throw an error) files with a type it cannot read. | ||
func TestLoadContext(t *testing.T) { | ||
testdir := "/tmp/loadfile-test" | ||
// cleanup directory even if it's there | ||
_ = os.RemoveAll(testdir) | ||
|
||
assert.NoError(t, os.MkdirAll(testdir, os.ModePerm)) | ||
|
||
// create a directory | ||
dirname := "mydir" | ||
dirpath := filepath.Join(testdir, dirname) | ||
assert.NoError(t, os.MkdirAll(dirpath, os.ModePerm)) | ||
|
||
// create a file | ||
filename := "myfile" | ||
filePath := filepath.Join(testdir, filename) | ||
f, err := os.Create(filepath.Clean(filePath)) | ||
assert.NoError(t, err) | ||
assert.NoError(t, f.Close()) | ||
|
||
// create symlink to the directory | ||
symlinkDirname := dirname + "_sym" | ||
symlinkDirpath := filepath.Join(testdir, symlinkDirname) | ||
assert.NoError(t, os.Symlink(dirpath, symlinkDirpath)) | ||
|
||
// create symlink to the file | ||
symlinkFilepath := filePath + "_sym" | ||
assert.NoError(t, os.Symlink(filePath, symlinkFilepath)) | ||
|
||
neededFiles := []string{ | ||
filePath, | ||
symlinkFilepath, | ||
} | ||
filemap, err := loadfile.LoadContext(neededFiles) | ||
// assert no error on attempting to read files | ||
// that cannot be read | ||
assert.NoError(t, err) | ||
|
||
// assert only the regular and symlinked file are loaded | ||
filemapExp := map[string][]byte{ | ||
filePath: {}, | ||
symlinkFilepath: {}, | ||
} | ||
assert.Equals(t, filemap, filemapExp) | ||
|
||
// error on loading a directory | ||
neededFiles = []string{ | ||
dirpath, | ||
} | ||
|
||
errFileRead := "reading file" | ||
ctxFiles, err := loadfile.LoadContext(neededFiles) | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), errFileRead) | ||
assert.Nil(t, ctxFiles) | ||
|
||
// error on loading a symlink directory | ||
neededFiles = []string{ | ||
symlinkDirpath, | ||
} | ||
ctxFiles, err = loadfile.LoadContext(neededFiles) | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), errFileRead) | ||
assert.Nil(t, ctxFiles) | ||
|
||
t.Cleanup(func() { | ||
assert.NoError(t, os.RemoveAll(testdir)) | ||
}) | ||
} | ||
|
||
// This tests AbsPathsWithContext which joins relative paths | ||
// with the context (root) directory, and passes through | ||
// absolute paths unmodified. | ||
func TestContextAbsFilepaths(t *testing.T) { | ||
testdir, err := os.MkdirTemp(os.TempDir(), "") | ||
assert.NoError(t, err) | ||
|
||
testFilepaths := map[string]string{ | ||
"a": "a.yaml", | ||
"b": "/b.toml", | ||
"c": "rel/../subdir/c.txt", | ||
} | ||
|
||
absPathsExp := map[string]string{ | ||
"a": filepath.Join(testdir, testFilepaths["a"]), | ||
"b": testFilepaths["b"], | ||
"c": filepath.Join(testdir, testFilepaths["c"]), | ||
} | ||
|
||
absPathsGot, err := loadfile.AbsPathsWithContext(testdir, testFilepaths) | ||
assert.NoError(t, err) | ||
assert.Equals(t, absPathsExp, absPathsGot) | ||
|
||
t.Cleanup(func() { | ||
assert.NoError(t, os.RemoveAll(testdir)) | ||
}) | ||
} |