fuzzyworld

template / commit

Added support for creating files within a folder.

5e7795dc9a8e180018f1d133375e59cc3dcddbdd · Pavel Safronov · 2022-10-21 15:36:36 -0700 · parents 1a02ef4e7763

Added support for creating files within a folder.
 default_config.go    | 12 ++++++++-
 name_pattern.go      |  6 ++---
 name_pattern_test.go |  6 ++---
 profile.go           | 71 ++++++++++++++++++++++++++++++++++++----------------
 4 files changed, 67 insertions(+), 28 deletions(-)

diff --git a/default_config.go b/default_config.go
index bce8d8e..698d955 100644
--- a/default_config.go
+++ b/default_config.go
@@ -131,7 +131,17 @@ Sincerely, me
 				PostScripts: []ParameterizedText{
 					"code \"{{.Path}}\"",
 				},
-				Files: []File{},
+				Files: []FileInFolder{
+					FileInFolder{
+						File: File{
+							Template: `# {{.ProjectName}}
+
+Work notes on {{.ProjectName}}
+`,
+						},
+						Name: "README.md",
+					},
+				},
 			},
 			{
 				Name:        "folder",
diff --git a/name_pattern.go b/name_pattern.go
index 11e0996..0ef34b3 100644
--- a/name_pattern.go
+++ b/name_pattern.go
@@ -16,8 +16,8 @@ type NamePatternData struct {
 	Extras                                 map[string]string
 }
 
-func createNewNameForProfile(now time.Time, projectName string, profile Profile, extras map[string]string, existingEntities []string) (string, error) {
-	for index, namePattern := range profile.NamePatterns {
+func createNewNameForPatterns(now time.Time, projectName string, namePatterns []ParameterizedText, extras map[string]string, existingEntities []string) (string, error) {
+	for index, namePattern := range namePatterns {
 
 		startingVersion := 1
 		invokeCount := 0
@@ -55,7 +55,7 @@ func createNewNameForProfile(now time.Time, projectName string, profile Profile,
 			newName := sb.String()
 			alreadyExists := slices.Contains(existingEntities, newName)
 			useIndex := invokeCount > 0
-			isLastPattern := index == len(profile.NamePatterns)-1
+			isLastPattern := index == len(namePatterns)-1
 
 			// if no conflict, use this name
 			if !alreadyExists {
diff --git a/name_pattern_test.go b/name_pattern_test.go
index 485ccf8..6e53ae6 100644
--- a/name_pattern_test.go
+++ b/name_pattern_test.go
@@ -29,7 +29,7 @@ func TestCreateNewName(t *testing.T) {
 
 	testHappyPath := func(projectName string, expectedName string, existingEntities []string) func(t *testing.T) {
 		return func(t *testing.T) {
-			newName, err := createNewNameForProfile(now, projectName, profile, extras, existingEntities)
+			newName, err := createNewNameForPatterns(now, projectName, profile.NamePatterns, extras, existingEntities)
 			if err != nil {
 				t.Error("Error creating new name: ", err)
 			}
@@ -40,7 +40,7 @@ func TestCreateNewName(t *testing.T) {
 	}
 	testErrorPath := func(projectName string, existingEntities []string) func(t *testing.T) {
 		return func(t *testing.T) {
-			_, err := createNewNameForProfile(now, projectName, profile, extras, existingEntities)
+			_, err := createNewNameForPatterns(now, projectName, profile.NamePatterns, extras, existingEntities)
 			if err == nil {
 				t.Error("Expected error but got none")
 			}
@@ -78,7 +78,7 @@ func TestCreateNewName_Index(t *testing.T) {
 
 	testHappyPath := func(expectedName string, existingEntities []string) func(t *testing.T) {
 		return func(t *testing.T) {
-			newName, err := createNewNameForProfile(now, "test-project", profile, extras, existingEntities)
+			newName, err := createNewNameForPatterns(now, "test-project", profile.NamePatterns, extras, existingEntities)
 			if err != nil {
 				t.Error("Error creating new name: ", err)
 			}
diff --git a/profile.go b/profile.go
index 5d76df4..7d9d95a 100644
--- a/profile.go
+++ b/profile.go
@@ -38,6 +38,11 @@ type File struct {
 	Template     ParameterizedText
 }
 
+type FileInFolder struct {
+	File
+	Name ParameterizedText
+}
+
 type Profile struct {
 	File
 	IsDefault    bool
@@ -49,7 +54,7 @@ type Profile struct {
 	PostScripts  []ParameterizedText
 	ScriptShell  string
 	OS           OSType
-	Files        []File
+	Files        []FileInFolder
 }
 
 var forbiddenProfileNames = []string{
@@ -123,7 +128,7 @@ func processProfile(profile Profile, projectName string, extras map[string]strin
 
 	// generate a new name based on time, profile, and existing entities
 	now := time.Now()
-	newName, err := createNewNameForProfile(now, projectName, profile, extras, entities)
+	newName, err := createNewNameForPatterns(now, projectName, profile.NamePatterns, extras, entities)
 	if err != nil {
 		return err
 	}
@@ -145,25 +150,26 @@ func processProfile(profile Profile, projectName string, extras map[string]strin
 		if err != nil {
 			return fmt.Errorf("unable to change directory to %v: %v", fullPath, err)
 		}
-	} else if profileType == FileType {
-		useTemplateFile := profile.TemplatePath != ""
-		useTemplate := profile.Template != ""
-		if useTemplateFile {
-			fmt.Printf("Creating file '%v' from template: %v\n", fullPath, profile.TemplatePath)
-			err := createFileFromTemplateFile(profile.TemplatePath, fullPath, projectName, newName, extras, usr)
-			if err != nil {
-				return fmt.Errorf("error creating template file: %v", err)
-			}
-		} else if useTemplate {
-			fmt.Printf("Creating file '%v' from template string\n", fullPath)
-			templateString, err := createTemplateString(profile.Template, projectName, newName, extras)
-			if err != nil {
-				return fmt.Errorf("error creating template: %v", err)
+
+		// create files in the new folder
+		if len(profile.Files) > 0 {
+			fmt.Printf("Creating files in directory: %v\n", fullPath)
+			for index, file := range profile.Files {
+				fileName, err := createNewNameForPatterns(now, projectName, []ParameterizedText{file.Name}, extras, []string{})
+				if err != nil {
+					return fmt.Errorf("error creating file name for file index %v : %v", index, err)
+				}
+				subFilePath := filepath.Join(fullPath, fileName)
+				err = createFile(file.File, subFilePath, projectName, fileName, extras, usr)
+				if err != nil {
+					return err
+				}
 			}
-			ioutil.WriteFile(fullPath, []byte(templateString), os.ModePerm)
-		} else {
-			fmt.Printf("Creating empty file: %v\n", fullPath)
-			os.WriteFile(fullPath, []byte{}, os.ModePerm)
+		}
+	} else if profileType == FileType {
+		err := createFile(profile.File, fullPath, projectName, newName, extras, usr)
+		if err != nil {
+			return err
 		}
 	} else {
 		fmt.Printf("Profile type is script, doing nothing during main phase\n")
@@ -190,6 +196,29 @@ func processProfile(profile Profile, projectName string, extras map[string]strin
 	return nil
 }
 
+func createFile(file File, fullPath string, projectName string, newName string, extras map[string]string, usr user.User) error {
+	useTemplateFile := file.TemplatePath != ""
+	useTemplate := file.Template != ""
+	if useTemplateFile {
+		fmt.Printf("Creating file '%v' from template: %v\n", fullPath, file.TemplatePath)
+		err := createFileFromTemplateFile(file.TemplatePath, fullPath, projectName, newName, extras, usr)
+		if err != nil {
+			return fmt.Errorf("error creating template file: %v", err)
+		}
+	} else if useTemplate {
+		fmt.Printf("Creating file '%v' from template string\n", fullPath)
+		templateString, err := createTemplateString(file.Template, projectName, newName, extras)
+		if err != nil {
+			return fmt.Errorf("error creating template: %v", err)
+		}
+		ioutil.WriteFile(fullPath, []byte(templateString), os.ModePerm)
+	} else {
+		fmt.Printf("Creating empty file: %v\n", fullPath)
+		os.WriteFile(fullPath, []byte{}, os.ModePerm)
+	}
+	return nil
+}
+
 func validateProfile(profile *Profile) error {
 	if profile.Name == "" {
 		return fmt.Errorf("Profile name is required")
@@ -219,7 +248,7 @@ func validateProfile(profile *Profile) error {
 		return fmt.Errorf("script shell is required for profile %s", profile.Name)
 	}
 	if profile.Files == nil {
-		profile.Files = []File{}
+		profile.Files = []FileInFolder{}
 	}
 	return nil
 }