diff options
| author | Dave Henderson <dhenderson@gmail.com> | 2022-01-09 14:45:24 -0500 |
|---|---|---|
| committer | Dave Henderson <dhenderson@gmail.com> | 2022-02-13 11:53:47 -0500 |
| commit | 4510ec9c9e9b1cdce83ec893dfe2aebfdd5db8d7 (patch) | |
| tree | 831048f23820fe9c3c8749bedbbf839a4a546621 /internal | |
| parent | 839e8973475f1f0bdc05657ea13cd23a16d85cd8 (diff) | |
Ensure output file paths exist
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/iohelpers/filemode.go | 6 | ||||
| -rw-r--r-- | internal/iohelpers/filemode_test.go | 4 | ||||
| -rw-r--r-- | internal/tests/integration/basic_test.go | 45 |
3 files changed, 47 insertions, 8 deletions
diff --git a/internal/iohelpers/filemode.go b/internal/iohelpers/filemode.go index 35a3c142..7ac0e3df 100644 --- a/internal/iohelpers/filemode.go +++ b/internal/iohelpers/filemode.go @@ -17,8 +17,10 @@ func NormalizeFileMode(mode os.FileMode) os.FileMode { } func windowsFileMode(mode os.FileMode) os.FileMode { - // non-owner and execute bits are stripped - mode &^= 0o177 + // non-owner and execute bits are stripped on files + if !mode.IsDir() { + mode &^= 0o177 + } if mode&0o200 != 0 { // writeable implies read/write on Windows diff --git a/internal/iohelpers/filemode_test.go b/internal/iohelpers/filemode_test.go index 2ebb0ed7..8a7c9a2e 100644 --- a/internal/iohelpers/filemode_test.go +++ b/internal/iohelpers/filemode_test.go @@ -2,6 +2,7 @@ package iohelpers import ( "fmt" + "io/fs" "os" "testing" @@ -34,4 +35,7 @@ func TestWindowsFileMode(t *testing.T) { assert.Equal(t, fmt.Sprintf("%o", d.expected), fmt.Sprintf("%o", actual)) assert.Equal(t, d.expected, actual) } + + // directories are always 0777 + assert.Equal(t, 0o777|fs.ModeDir, windowsFileMode(0o755|fs.ModeDir)) } diff --git a/internal/tests/integration/basic_test.go b/internal/tests/integration/basic_test.go index 243bef4b..a1e2dc70 100644 --- a/internal/tests/integration/basic_test.go +++ b/internal/tests/integration/basic_test.go @@ -1,6 +1,7 @@ package integration import ( + "io/fs" "io/ioutil" "os" "testing" @@ -8,14 +9,19 @@ import ( "github.com/hairyhenderson/gomplate/v3/internal/iohelpers" "gotest.tools/v3/assert" "gotest.tools/v3/assert/cmp" - "gotest.tools/v3/fs" + testfs "gotest.tools/v3/fs" ) -func setupBasicTest(t *testing.T) *fs.Dir { - tmpDir := fs.NewDir(t, "gomplate-inttests", - fs.WithFile("one", "hi\n", fs.WithMode(0640)), - fs.WithFile("two", "hello\n"), - fs.WithFile("broken", "", fs.WithMode(0000))) +func setupBasicTest(t *testing.T) *testfs.Dir { + tmpDir := testfs.NewDir(t, "gomplate-inttests", + testfs.WithFile("one", "hi\n", testfs.WithMode(0640)), + testfs.WithFile("two", "hello\n"), + testfs.WithFile("broken", "", testfs.WithMode(0000)), + testfs.WithDir("subdir", + testfs.WithFile("f1", "first\n", testfs.WithMode(0640)), + testfs.WithFile("f2", "second\n"), + ), + ) t.Cleanup(tmpDir.Remove) return tmpDir } @@ -256,3 +262,30 @@ func TestBasic_AppliesChmodBeforeWrite(t *testing.T) { assert.NilError(t, err) assert.Equal(t, "hi\n", string(content)) } + +func TestBasic_CreatesMissingDirectory(t *testing.T) { + tmpDir := setupBasicTest(t) + out := tmpDir.Join("foo/bar/baz") + o, e, err := cmd(t, "-f", tmpDir.Join("one"), "-o", out).run() + assertSuccess(t, o, e, err, "") + + info, err := os.Stat(out) + assert.NilError(t, err) + assert.Equal(t, iohelpers.NormalizeFileMode(0640), info.Mode()) + content, err := ioutil.ReadFile(out) + assert.NilError(t, err) + assert.Equal(t, "hi\n", string(content)) + + out = tmpDir.Join("outdir") + o, e, err = cmd(t, + "--input-dir", tmpDir.Join("subdir"), + "--output-dir", out, + ).run() + assertSuccess(t, o, e, err, "") + + info, err = os.Stat(out) + assert.NilError(t, err) + + assert.Equal(t, iohelpers.NormalizeFileMode(0o755|fs.ModeDir), info.Mode()) + assert.Equal(t, true, info.IsDir()) +} |
