fuzzyworld

template / commit

Changed a few things:

4a7759dbbf562255e9a8c28d5438a300f388b054 · Pavel Safronov · 2022-09-24 01:08:54 -0700 · parents b65fb5e95ac5

Changed a few things:
- added folder profile, which creates a versioned folder in current location
- added "create-react-app" profile, that creates a versioned folder in current locaiton and installs "create-react-app" there
- added ability to have multiple script executions
- added "template list" method: it lists the known profiles
- added "template get XYZ" method: it shows XYZ profile as YAML
 config.go     | 50 ++++++++++++++++++++++++++++++++++++++++++--------
 main.go       | 40 +++++++++++++++++++++++++++++++++++-----
 postscript.go | 34 +++++++++++++++++++---------------
 profile.go    | 26 +++++++++++++++-----------
 utils.go      | 13 -------------
 5 files changed, 111 insertions(+), 52 deletions(-)

diff --git a/config.go b/config.go
index e092919..98219db 100644
--- a/config.go
+++ b/config.go
@@ -28,7 +28,7 @@ type Profile struct {
 	Path             string
 	Type             ProfileType
 	NamePatterns     []string
-	PostScript       []string
+	PostScripts      [][]string
 	ScriptShell      string
 	OS               OSType
 	FileTemplatePath string
@@ -55,11 +55,12 @@ func defaultConfig() Config {
 						".md",
 				},
 				ScriptShell: "pwsh",
-				PostScript: []string{
+				PostScripts: [][]string{{
 					"code",
 					".",
 					"\"{{.Path}}\"",
 				},
+				},
 			},
 			{
 				Name:      "note",
@@ -74,10 +75,10 @@ func defaultConfig() Config {
 						".md",
 				},
 				ScriptShell: "pwsh",
-				PostScript: []string{
+				PostScripts: [][]string{{
 					"code",
 					"\"{{.Path}}\"",
-				},
+				}},
 			},
 			{
 				Name:             "blog",
@@ -93,11 +94,11 @@ func defaultConfig() Config {
 						".md",
 				},
 				ScriptShell: "pwsh",
-				PostScript: []string{
+				PostScripts: [][]string{{
 					"code",
 					".",
 					"\"{{.Name}}\"",
-				},
+				}},
 			},
 			{
 				Name: "work",
@@ -111,9 +112,42 @@ func defaultConfig() Config {
 					"{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}-{{.Minute}}-{{.Second}}{{if .ProjectName}}-{{.ProjectName}}{{end}}",
 				},
 				ScriptShell: "pwsh",
-				PostScript: []string{
+				PostScripts: [][]string{{
 					"explorer",
 					"\"{{.Path}}\"",
+				}},
+			},
+			{
+				Name:        "folder",
+				Type:        FolderType,
+				ScriptShell: "pwsh",
+				NamePatterns: []string{
+					"{{$version := getVersion}}" +
+						"{{.Year}}-{{.Month}}-{{.Day}}" +
+						"{{if .ProjectName}}-{{.ProjectName}}{{end}}" +
+						"{{if (gt $version 1)}}-n{{$version}}{{end}}",
+				},
+			},
+			{
+				Name:        "create-react-app",
+				Type:        FolderType,
+				ScriptShell: "pwsh",
+				NamePatterns: []string{
+					"{{$version := getVersion}}" +
+						"create-react-app" +
+						"{{if .ProjectName}}-{{.ProjectName}}{{end}}" +
+						"{{if (gt $version 1)}}-n{{$version}}{{end}}",
+				},
+				PostScripts: [][]string{
+					{
+						"npx",
+						"create-react-app",
+						".",
+					},
+					{
+						"code",
+						".",
+					},
 				},
 			},
 		},
@@ -145,7 +179,7 @@ func validateConfig(config Config) error {
 		if profile.Type != FileType && profile.FileTemplatePath != "" {
 			return fmt.Errorf("File template path is not supported for profile %s, which has Type=%s", profile.Name, profile.Type)
 		}
-		if profile.ScriptShell == "" && profile.PostScript != nil && len(profile.PostScript) > 0 {
+		if profile.ScriptShell == "" && profile.PostScripts != nil && len(profile.PostScripts) > 0 {
 			return fmt.Errorf("Script shell is required for profile %s", profile.Name)
 		}
 	}
diff --git a/main.go b/main.go
index 19cd09e..f7f6d5b 100644
--- a/main.go
+++ b/main.go
@@ -4,8 +4,10 @@ import (
 	"fmt"
 	"log"
 	"os"
+	"strings"
 
 	"github.com/urfave/cli/v2" // imports as package "cli"
+	"gopkg.in/yaml.v3"
 )
 
 func main() {
@@ -45,13 +47,13 @@ func main() {
 				// create config and save
 				err := saveConfig(configFilePath, defaultConfig())
 				if err != nil {
-					processError(err, "Error while saving")
+					return fmt.Errorf("Error creating config: %v", err)
 				}
 
 				// load config
 				config, err = loadConfig(configFilePath)
 				if err != nil {
-					processError(err, "Error while loading")
+					return fmt.Errorf("Error loading config: %v", err)
 				}
 			} else {
 				// log successful load
@@ -61,7 +63,7 @@ func main() {
 			// validate config
 			err = validateConfig(config)
 			if err != nil {
-				processError(err, "Invalid config")
+				return fmt.Errorf("Error validating config: %v", err)
 			}
 
 			// read args
@@ -83,16 +85,44 @@ func main() {
 				fmt.Println("Project name:", projectName)
 			}
 
+			// extra features
+
+			// list profiles
+			if profileName == "list" {
+				fmt.Println("Available profiles:")
+				for _, p := range config.Profiles {
+					fmt.Printf("  %v\n", p.Name)
+				}
+				return nil
+			}
+			// get profile information
+			if profileName == "get" {
+				fmt.Printf("Profile '%v':\n", projectName)
+				for _, p := range config.Profiles {
+					if p.Name == projectName {
+						writer := strings.Builder{}
+						encoder := yaml.NewEncoder(&writer)
+						err = encoder.Encode(p)
+						if err != nil {
+							return fmt.Errorf("Error encoding profile: %v", err)
+						}
+						yamlText := writer.String()
+						fmt.Println(yamlText)
+					}
+				}
+				return nil
+			}
+
 			// find profile
 			profile, err := findProfile(config, profileName)
 			if err != nil {
-				processError(err, "Error while finding profile")
+				return fmt.Errorf("Error finding profile: %v", err)
 			}
 
 			// process profile
 			err = processProfile(profile, projectName)
 			if err != nil {
-				processError(err, "Error processing profile")
+				return fmt.Errorf("Error processing profile: %v", err)
 			}
 
 			return nil
diff --git a/postscript.go b/postscript.go
index 2f6a869..e909164 100644
--- a/postscript.go
+++ b/postscript.go
@@ -10,10 +10,10 @@ type PostScriptPatternData struct {
 	Path string
 }
 
-func createPostScriptArray(profile Profile, newName string, fullPath string) ([]string, error) {
-	array := make([]string, 0)
+func createPostScriptArrays(profile Profile, newName string, fullPath string) ([][]string, error) {
+	array := make([][]string, 0)
 
-	if profile.PostScript == nil || len(profile.PostScript) == 0 {
+	if profile.PostScripts == nil || len(profile.PostScripts) == 0 {
 		return nil, nil
 	}
 
@@ -22,21 +22,25 @@ func createPostScriptArray(profile Profile, newName string, fullPath string) ([]
 		Path: fullPath,
 	}
 
-	for _, postScriptPattern := range profile.PostScript {
+	for _, postScriptPatterns := range profile.PostScripts {
+		subarray := make([]string, 0)
+		for _, postScriptPattern := range postScriptPatterns {
 
-		template, err := template.New("postscript").Parse(postScriptPattern)
-		if err != nil {
-			return nil, err
-		}
+			template, err := template.New("postscript").Parse(postScriptPattern)
+			if err != nil {
+				return nil, err
+			}
 
-		sb := new(strings.Builder)
-		err = template.Execute(sb, patternData)
-		if err != nil {
-			return nil, err
-		}
+			sb := new(strings.Builder)
+			err = template.Execute(sb, patternData)
+			if err != nil {
+				return nil, err
+			}
 
-		postScript := sb.String()
-		array = append(array, postScript)
+			postScript := sb.String()
+			subarray = append(subarray, postScript)
+		}
+		array = append(array, subarray)
 	}
 
 	return array, nil
diff --git a/profile.go b/profile.go
index 5049734..b80d0ac 100644
--- a/profile.go
+++ b/profile.go
@@ -26,9 +26,9 @@ func findProfile(config Config, profileName string) (Profile, error) {
 				return p, nil
 			}
 		}
-		return Profile{}, fmt.Errorf("Unable to find profile '%v'", profileName)
+		return Profile{}, fmt.Errorf("unable to find profile '%v'", profileName)
 	}
-	return Profile{}, errors.New("Couldn't find profile")
+	return Profile{}, errors.New("couldn't find profile")
 }
 
 func processProfile(profile Profile, projectName string) error {
@@ -51,14 +51,14 @@ func processProfile(profile Profile, projectName string) error {
 
 	cwd, err := os.Getwd()
 	if err != nil {
-		processError(err, "Unable to get current working directory")
+		return fmt.Errorf("unable to get current working directory: %v", err)
 	}
 	if profile.Path != "" {
 		// change cwd to the profile's path, if one is specified
 		path := getFullPath(profile.Path)
 		err := os.Chdir(path)
 		if err != nil {
-			processError(err, fmt.Sprintf("Error while changing directory to '%v'", path))
+			return fmt.Errorf("unable to change directory to %v: %v", path, err)
 		}
 		cwd = path
 	}
@@ -77,7 +77,7 @@ func processProfile(profile Profile, projectName string) error {
 	case FolderType:
 		useDirs = true
 	default:
-		return fmt.Errorf("Unknown profile type: %v", profile.Type)
+		return fmt.Errorf("unknown profile type: %v", profile.Type)
 	}
 
 	// filter entities to just files or directories
@@ -98,7 +98,7 @@ func processProfile(profile Profile, projectName string) error {
 
 	// check newName is created
 	if newName == "" {
-		return errors.New("Couldn't find a good new name")
+		return errors.New("couldn't find a good new name")
 	}
 
 	// create new entity
@@ -107,7 +107,11 @@ func processProfile(profile Profile, projectName string) error {
 		fmt.Printf("Creating directory: %v\n", fullPath)
 		err = os.Mkdir(fullPath, os.ModePerm)
 		if err != nil {
-			return fmt.Errorf("Error creating directory: %v", err)
+			return fmt.Errorf("error creating directory: %v", err)
+		}
+		err := os.Chdir(fullPath)
+		if err != nil {
+			return fmt.Errorf("unable to change directory to %v: %v", fullPath, err)
 		}
 	} else {
 		useTemplateFile := profile.FileTemplatePath != ""
@@ -115,7 +119,7 @@ func processProfile(profile Profile, projectName string) error {
 			fmt.Printf("Creating file '%v' from template: %v\n", fullPath, profile.FileTemplatePath)
 			err := createTemplateFile(profile.FileTemplatePath, fullPath, projectName, newName)
 			if err != nil {
-				return fmt.Errorf("Error creating template file: %v", err)
+				return fmt.Errorf("error creating template file: %v", err)
 			}
 		} else {
 			fmt.Printf("Creating empty file: %v\n", fullPath)
@@ -124,12 +128,12 @@ func processProfile(profile Profile, projectName string) error {
 	}
 
 	// execute PostScript, if present
-	postScripts, err := createPostScriptArray(profile, newName, fullPath)
+	postScripts, err := createPostScriptArrays(profile, newName, fullPath)
 	if err != nil {
 		return err
 	}
-	if postScripts != nil && len(postScripts) > 0 {
-		allArgs := append([]string{"-c"}, postScripts...)
+	for _, postScript := range postScripts {
+		allArgs := append([]string{"-c"}, postScript...)
 		shell := profile.ScriptShell
 		fmt.Printf("Executing post script: %v %v\n", shell, strings.Join(allArgs, " "))
 		cmd := exec.Command(shell, allArgs...)
diff --git a/utils.go b/utils.go
index ceb6403..91e1cac 100644
--- a/utils.go
+++ b/utils.go
@@ -1,24 +1,11 @@
 package main
 
 import (
-	"fmt"
-	"os"
 	"os/user"
 	"path/filepath"
 	"strings"
 )
 
-func processError(err error, message string) {
-	fmt.Println()
-	fmt.Println("---")
-
-	fmt.Println("Fatal error encountered.")
-	fmt.Println("Message: " + message)
-	fmt.Println(err)
-
-	os.Exit(2)
-}
-
 func getFullPath(path string) string {
 	usr, _ := user.Current()
 	dir := usr.HomeDir