template / commit
Adding tests and a few small changes:
.vscode/launch.json | 15 ++++++++++++-- config.go | 24 ++++++++++++++++++---- new.go | 47 +++++++++++++++++++++++-------------------- new_test.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 27 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 7820d09..c3f50c6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -46,7 +46,7 @@ ] }, { - "name": "Run: template --profile work --name testProj", + "name": "Run: template --profile work --project testProj", "type": "go", "request": "launch", "mode": "auto", @@ -54,9 +54,20 @@ "args": [ "--profile", "work", - "--name", + "--project", "testProj" ] + }, + { + "name": "Run: template note whoa", + "type": "go", + "request": "launch", + "mode": "auto", + "program": ".", + "args": [ + "note", + "whoa" + ] } ] } \ No newline at end of file diff --git a/config.go b/config.go index 3f01dfa..bccb10e 100644 --- a/config.go +++ b/config.go @@ -41,10 +41,9 @@ func defaultConfig() Config { return Config{ Profiles: map[string]Profile{ "daily": { - IsDefault: true, - OS: "Windows", - Path: "C:\\work\\daily-notes", - Type: FileType, + OS: "Windows", + Path: "C:\\work\\daily-notes", + Type: FileType, NamePatterns: []string{ "{{$version := getVersion}}" + "{{.Year}}-{{.Month}}-{{.Day}}" + @@ -58,6 +57,23 @@ func defaultConfig() Config { "{{.Path}}", }, }, + "note": { + OS: "All", + IsDefault: true, + Type: FileType, + NamePatterns: []string{ + "{{$version := getVersion}}" + + "{{.Year}}-{{.Month}}-{{.Day}}" + + "{{if .ProjectName}}-{{.ProjectName}}{{end}}" + + "{{if (gt $version 1)}}n{{$version}}{{end}}" + + ".md", + }, + ScriptShell: "pwsh", + PostScript: []string{ + "code", + "{{.Path}}", + }, + }, "blog": { OS: "All", Path: "~/Dropbox/Blog", diff --git a/new.go b/new.go index 734391d..a6b4411 100644 --- a/new.go +++ b/new.go @@ -14,8 +14,8 @@ import ( "golang.org/x/exp/slices" ) -func findProfile(config Config, name string) (Profile, error) { - if name == "" { +func findProfile(config Config, profileName string) (Profile, error) { + if profileName == "" { // use default profile for _, p := range config.Profiles { if p.IsDefault { @@ -24,22 +24,23 @@ func findProfile(config Config, name string) (Profile, error) { } } else { // find profile by name - profile, ok := config.Profiles[name] + profile, ok := config.Profiles[profileName] if ok { return profile, nil } else { - return Profile{}, fmt.Errorf("Unable to find profile '%v'", name) + return Profile{}, fmt.Errorf("Unable to find profile '%v'", profileName) } } return Profile{}, errors.New("Couldn't find profile") } -func processProfile(profile Profile, name string) error { +func processProfile(profile Profile, projectName string) error { // validate profile if profile.NamePatterns == nil || len(profile.NamePatterns) == 0 { return errors.New("No name patterns specified") } + // decide if the profile should run on this OS profileOs := profile.OS isWindows := runtime.GOOS == "windows" shouldRun := profileOs == "All" || @@ -50,13 +51,19 @@ func processProfile(profile Profile, name string) error { return nil } - // change cwd - path := getFullPath(profile.Path) - err := os.Chdir(path) + cwd, err := os.Getwd() if err != nil { - processError(err, fmt.Sprintf("Error while changing directory to '%v'", path)) + processError(err, "Unable to get current working directory") + } + 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)) + } + cwd = path } - cwd := path // get all entities in current directory files, err := os.ReadDir(cwd) @@ -84,8 +91,9 @@ func processProfile(profile Profile, name string) error { } } - // generate a new name based on profile and existing entities - newName, err := createNewName(name, profile, entities) + // generate a new name based on time, profile, and existing entities + now := time.Now() + newName, err := createNewName(now, projectName, profile, entities) if err != nil { return err } @@ -131,16 +139,14 @@ func processProfile(profile Profile, name string) error { type NamePatternData struct { Year, Month, Day, Hour, Minute, Second string ProjectName string - Index int } type PostScriptPatternData struct { Name string Path string } -func createNewName(name string, profile Profile, existingEntities []string) (string, error) { - now := time.Now() - patternInfo := createNamePatternData(now, name) +func createNewName(now time.Time, projectName string, profile Profile, existingEntities []string) (string, error) { + patternInfo := createNamePatternData(now, projectName) newName, err := createNewNameForProfile(profile, patternInfo, existingEntities) if err != nil { return "", err @@ -158,7 +164,6 @@ func createNamePatternData(now time.Time, projectName string) NamePatternData { Minute: now.Format("04"), Second: now.Format("05"), ProjectName: projectName, - Index: 0, } return patternInfo @@ -216,7 +221,7 @@ func createNewNameForProfile(profile Profile, patternData NamePatternData, exist return "", errors.New("Couldn't find a new name") } -func createPostScriptArray(profile Profile, name string, path string) ([]string, error) { +func createPostScriptArray(profile Profile, newName string, fullPath string) ([]string, error) { array := make([]string, 0) if profile.PostScript == nil || len(profile.PostScript) == 0 { @@ -224,13 +229,13 @@ func createPostScriptArray(profile Profile, name string, path string) ([]string, } patternData := PostScriptPatternData{ - Name: name, - Path: path, + Name: newName, + Path: fullPath, } for _, postScriptPattern := range profile.PostScript { - template, err := template.New("template-name").Parse(postScriptPattern) + template, err := template.New("postscript").Parse(postScriptPattern) if err != nil { return nil, err } diff --git a/new_test.go b/new_test.go new file mode 100644 index 0000000..7540c4a --- /dev/null +++ b/new_test.go @@ -0,0 +1,57 @@ +package main + +import ( + "testing" + "time" +) + +func TestCreateNewName(t *testing.T) { + // setup code + + // Mon Jan 2 15:04:05 MST 2006 + now := time.Date(2006, 1, 2, 15, 4, 5, 0, time.UTC) + profile := Profile{ + IsDefault: true, + Type: FileType, + NamePatterns: []string{ + "{{.Year}}-{{.Month}}-{{.Day}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.txt", + "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.txt", + "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}-{{.Minute}}-{{.Second}}-{{.ProjectName}}.txt", + }, + } + newName1 := "2006-01-02-test-project.txt" + newName2 := "2006-01-02-15-test-project.txt" + newName3 := "2006-01-02-15-04-05-test-project.txt" + + testHappyPath := func(projectName string, expectedName string, existingEntities []string) func(t *testing.T) { + return func(t *testing.T) { + newName, err := createNewName(now, projectName, profile, existingEntities) + if err != nil { + t.Error("Error creating new name: ", err) + } + if newName != expectedName { + t.Error("Expected name to be ", expectedName, " but got ", newName) + } + } + } + testErrorPath := func(projectName string, existingEntities []string) func(t *testing.T) { + return func(t *testing.T) { + _, err := createNewName(now, projectName, profile, existingEntities) + if err == nil { + t.Error("Expected error but got none") + } + } + } + + // test code + + // happy path + t.Run("createNewName - happy path", testHappyPath("test-project", newName1, []string{})) + t.Run("createNewName - use second pattern", testHappyPath("test-project", newName2, []string{newName1})) + t.Run("createNewName - use third pattern", testHappyPath("test-project", newName3, []string{newName1, newName2})) + + // error path + t.Run("createNewName - error path - collision", testErrorPath("test-project", []string{newName1, newName2, newName3})) + + // teardown code +}