fuzzyworld

template / commit

If profile.TargetDirectory does not exist, try to create it.

6543e9475796053f34a126f02aa2425c2bdd7b93 · Pavel Safronov · 2022-12-29 09:48:13 -0800 · parents 97bf176f413c

If profile.TargetDirectory does not exist, try to create it.
 monkey-patch.go |  7 +++++++
 profile.go      |  8 ++++++++
 profile_test.go | 22 +++++++++++++++++-----
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/monkey-patch.go b/monkey-patch.go
index d0b0796..e87d0d6 100644
--- a/monkey-patch.go
+++ b/monkey-patch.go
@@ -38,6 +38,7 @@ type monkeyPatchCalls struct {
 		perm os.FileMode
 	}
 	OSReadDirCalls []struct{ dirname string }
+	OSStatCalls    []struct{ name string }
 }
 
 var monkey = defaultMonkeyPatch()
@@ -64,6 +65,7 @@ func applyTestMonkeyPatch(t *testing.T, monkeyImpl monkeyPatch) *monkeyPatchCall
 			perm os.FileMode
 		}{},
 		OSReadDirCalls: []struct{ dirname string }{},
+		OSStatCalls:    []struct{ name string }{},
 	}
 	monkey = monkeyPatch{
 		ExecCommand: func(name string, arg ...string) *exec.Cmd {
@@ -113,6 +115,11 @@ func applyTestMonkeyPatch(t *testing.T, monkeyImpl monkeyPatch) *monkeyPatchCall
 			results.OSReadDirCalls = append(results.OSReadDirCalls, struct{ dirname string }{dirname})
 			return monkeyImpl.OSReadDir(dirname)
 		},
+		OSStat: func(name string) (os.FileInfo, error) {
+			assert.NotNil(t, monkeyImpl.OSStat, "OSStat is not implemented")
+			results.OSStatCalls = append(results.OSStatCalls, struct{ name string }{name})
+			return monkeyImpl.OSStat(name)
+		},
 	}
 	return &results
 }
diff --git a/profile.go b/profile.go
index 5f727a0..34940a2 100644
--- a/profile.go
+++ b/profile.go
@@ -3,6 +3,7 @@ package main
 import (
 	"bufio"
 	"bytes"
+	"errors"
 	"fmt"
 	"os"
 	"os/user"
@@ -91,6 +92,13 @@ func processProfile(profile Profile, projectName string, extras map[string]strin
 		return []error{fmt.Errorf("unable to get current working directory: %v", err)}
 	}
 	if profile.TargetDirectory != "" {
+		if _, err := monkey.OSStat(profile.TargetDirectory); errors.Is(err, os.ErrNotExist) {
+			err = monkey.OSMkdir(profile.TargetDirectory, 0755)
+			if err != nil {
+				return []error{fmt.Errorf("unable to create target directory: %v", err)}
+			}
+		}
+
 		// change cwd to the profile's path, if one is specified
 		path := getFullPath(profile.TargetDirectory, usr)
 		err = monkey.OSChdir(path)
diff --git a/profile_test.go b/profile_test.go
index c34f84d..86d3f70 100644
--- a/profile_test.go
+++ b/profile_test.go
@@ -8,6 +8,7 @@ import (
 	"path/filepath"
 	"runtime"
 	"testing"
+	"time"
 
 	"github.com/stretchr/testify/assert"
 )
@@ -234,13 +235,21 @@ func (f testFile) Name() string               { return f.name }
 func (f testFile) IsDir() bool                { return f.isDir }
 func (f testFile) Type() fs.FileMode          { return 0 }
 func (f testFile) Info() (fs.FileInfo, error) { return nil, nil }
+func (f testFile) ModTime() time.Time         { return time.Time{} }
+func (f testFile) Mode() fs.FileMode          { return 0 }
+func (f testFile) Size() int64                { return 0 }
+func (f testFile) Sys() any                   { return nil }
+
+var _ os.DirEntry = testFile{}
+var _ os.FileInfo = testFile{}
+
+func createDirEntry(name string, isDir bool) testFile {
+	entry := testFile{name: name, isDir: isDir}
+	return entry
+}
 
 func TestProcessProfile(t *testing.T) {
 	cwd := filepath.Clean("~/test/dir")
-	createDirEntry := func(name string, isDir bool) os.DirEntry {
-		entry := testFile{name: name, isDir: isDir}
-		return entry
-	}
 	var monkeyPatchCalls *monkeyPatchCalls
 	configureMonkeyPatching := func() {
 		monkeyPatchCalls = applyTestMonkeyPatch(t, monkeyPatch{
@@ -262,6 +271,9 @@ func TestProcessProfile(t *testing.T) {
 					createDirEntry("file2", false),
 				}, nil
 			},
+			OSStat: func(name string) (os.FileInfo, error) {
+				return createDirEntry("dir1", true), nil
+			},
 			OSWriteFile: func(filename string, data []byte, perm os.FileMode) error {
 				return nil
 			},
@@ -321,7 +333,7 @@ func TestProcessProfile(t *testing.T) {
 
 	profile.NamePatterns = []ParameterizedText{"file3"}
 	profile.PostScripts = []ParameterizedText{"echo {{.ProjectName}}-{{.Year}}"}
-	profile.TargetDirectory = "~/test/dir"
+	profile.TargetDirectory = "./test/dir"
 	testSuccess(profile)
 	assert.Equal(t, 1, len(monkeyPatchCalls.ExecCommandCalls), "calls to ExecCommand")
 	assert.Equal(t, 1, len(monkeyPatchCalls.OSChdirCalls), "calls to OSChdir")