Skip to content

Commit

Permalink
Ensure directories are created before template/touch (#194)
Browse files Browse the repository at this point in the history
Fixes a rare case that happens when initializing a new fogg repo, where an error occurs if a directory does not yet exist when a file is templated.
  • Loading branch information
mbarrien authored Jan 2, 2019
1 parent 5581f4b commit 9f88d1b
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
16 changes: 15 additions & 1 deletion apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,14 @@ func fmtHcl(fs afero.Fs, path string) error {
}

func touchFile(dest afero.Fs, path string) error {
_, err := dest.Stat(path)
dir, _ := filepath.Split(path)
ospath := filepath.FromSlash(dir)
err := dest.MkdirAll(ospath, 0755)
if err != nil {
return errs.WrapUserf(err, "couldn't create %s directory", dir)
}

_, err = dest.Stat(path)
if err != nil { // TODO we might not want to do this for all errors
log.Infof("%s touched", path)
_, err = dest.Create(path)
Expand Down Expand Up @@ -305,6 +312,13 @@ func removeExtension(path string) string {
}

func applyTemplate(sourceFile io.Reader, dest afero.Fs, path string, overrides interface{}) error {
dir, _ := filepath.Split(path)
ospath := filepath.FromSlash(dir)
err := dest.MkdirAll(ospath, 0755)
if err != nil {
return errs.WrapUserf(err, "couldn't create %s directory", dir)
}

log.Infof("%s templated", path)
writer, err := dest.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
Expand Down
66 changes: 66 additions & 0 deletions apply/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"os"
"strings"
"testing"
"math/rand"
"path/filepath"

"github.com/chanzuckerberg/fogg/config"
"github.com/chanzuckerberg/fogg/templates"
Expand All @@ -20,6 +22,26 @@ func init() {
}
log.SetFormatter(formatter)
}

func randomString(n int) string {
var letter = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

b := make([]rune, n)
for i := range b {
b[i] = letter[rand.Intn(len(letter))]
}
return string(b)
}

func getNonExistentDirectoryName() string {
nonexistentDir := "noexist-" + randomString(20)
for {
_, err := os.Stat(nonexistentDir)
if os.IsNotExist(err) { return nonexistentDir; }
nonexistentDir = "noexist-" + randomString(20)
}
}

func TestRemoveExtension(t *testing.T) {
x := removeExtension("foo")
assert.Equal(t, "foo", x)
Expand Down Expand Up @@ -49,6 +71,24 @@ func TestApplyTemplateBasic(t *testing.T) {
assert.Equal(t, "foo", string(r))
}

func TestApplyTemplateBasicNewDirectory(t *testing.T) {
sourceFile := strings.NewReader("foo")
// Potential errors do not show up if using NewMemMapFs; needs real OS fs.
dest := afero.NewOsFs()
nonexistentDir := getNonExistentDirectoryName()
defer dest.RemoveAll(nonexistentDir)
path := filepath.Join(nonexistentDir, "bar")
overrides := struct{ Foo string }{"foo"}

e := applyTemplate(sourceFile, dest, path, overrides)
assert.Nil(t, e)
f, e := dest.Open(path)
assert.Nil(t, e)
r, e := ioutil.ReadAll(f)
assert.Nil(t, e)
assert.Equal(t, "foo", string(r))
}

func TestApplyTemplate(t *testing.T) {
sourceFile := strings.NewReader("Hello {{.Name}}")
dest := afero.NewMemMapFs()
Expand Down Expand Up @@ -89,6 +129,19 @@ func TestTouchFile(t *testing.T) {

}

func TestTouchFileNonExistentDirectory(t *testing.T) {
// Potential errors do not show up if using NewMemMapFs; needs real OS fs.
dest := afero.NewOsFs()
nonexistentDir := getNonExistentDirectoryName()
defer dest.RemoveAll(nonexistentDir)
e := touchFile(dest, filepath.Join(nonexistentDir, "foo"))
assert.Nil(t, e)
r, e := readFile(dest, filepath.Join(nonexistentDir, "foo"))
assert.Nil(t, e)
assert.Equal(t, "", r)
assert.Nil(t, e)
}

func TestCreateFile(t *testing.T) {
fs := afero.NewMemMapFs()

Expand Down Expand Up @@ -118,6 +171,19 @@ func TestCreateFile(t *testing.T) {
r, e = readFile(fs, "foo")
assert.Nil(t, e)
assert.Equal(t, "bar", r)
}

func TestCreateFileNonExistentDirectory(t *testing.T) {

// create new file in nonexistent directory
dest := afero.NewOsFs()

e := createFile(dest, "newdir/foo", strings.NewReader("bar"))
assert.Nil(t, e)

r, e := readFile(dest, "newdir/foo")
assert.Nil(t, e)
assert.Equal(t, "bar", r)

}

Expand Down

0 comments on commit 9f88d1b

Please sign in to comment.