template / commit
Added support for unique indexes.
.vscode/launch.json | 7 +++++ .vscode/tasks.json | 17 +++++++++++ config.go | 18 +++++------ main.go | 9 +++--- new.go | 88 ++++++++++++++++++++++++++++++++++------------------- utils.go | 3 -- 6 files changed, 94 insertions(+), 48 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index f9195f2..8ed2713 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,6 +11,13 @@ "script": "rm ~/.template.yaml -ErrorAction SilentlyContinue", "cwd": "${workspaceFolder}" }, + { + "name": "Install template", + "type": "PowerShell", + "request": "launch", + "script": "go install", + "cwd": "${workspaceFolder}" + }, { "name": "Run: template", "type": "go", diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..2e7bb7f --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "remove-template-yaml", + "type": "shell", + "command": "rm ~/.template.yaml -ErrorAction SilentlyContinue", + "options": { + "shell": { + "executable": "powershell.exe" + } + } + } + ] +} \ No newline at end of file diff --git a/config.go b/config.go index 962eccc..b1991e9 100644 --- a/config.go +++ b/config.go @@ -20,7 +20,6 @@ type Profile struct { NamePatterns []string PostScript []string - // ReplacementStrings map[string][]string // FileTemplatePath string } @@ -36,10 +35,10 @@ func defaultConfig() Config { Path: "C:\\work\\daily-notes", Type: FileType, NamePatterns: []string{ - "{{.Year}}-{{.Month}}-{{.Day}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.md", - "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.md", - "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}-{{.Minute}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.md", - "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}-{{.Minute}}-{{.Second}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.md", + "{{$index := getUniqueIndex}}" + + "{{.Year}}-{{.Month}}-{{.Day}}" + + "{{if (gt $index 0)}}-{{$index}}{{end}}" + + ".md", }, PostScript: []string{ "code", @@ -51,10 +50,11 @@ func defaultConfig() Config { Path: "~/Dropbox/Blog", Type: FileType, NamePatterns: []string{ - "{{.Year}}-{{.Month}}-{{.Day}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.md", - "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.md", - "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}-{{.Minute}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.md", - "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}-{{.Minute}}-{{.Second}}{{if .ProjectName}}-{{.ProjectName}}{{end}}.md", + "{{$index := getUniqueIndex}}" + + "{{.Year}}-{{.Month}}-{{.Day}}" + + "{{if (gt $index 0)}}-{{$index}}{{end}}" + + "{{if .ProjectName}}-{{.ProjectName}}{{end}}" + + ".md", }, PostScript: []string{ "code", diff --git a/main.go b/main.go index d1e87f6..a8ad254 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,6 @@ import ( func main() { configFilePath := getFullPath("~/.template.yaml") - // defaultProfileName := "default" var profileName string var projectName string @@ -20,12 +19,12 @@ func main() { EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ - Name: "profile", - Aliases: []string{"p"}, - Value: "", - // Value: defaultProfileName, + Name: "profile", + Aliases: []string{"p"}, + Value: "", Usage: "`PROFILE` to use for the template", Destination: &profileName, + // Value: defaultProfileName, // Required: true, // EnvVars: []string{"TEMPLATE_PROFILE"}, }, diff --git a/new.go b/new.go index 2812a37..4033292 100644 --- a/new.go +++ b/new.go @@ -83,7 +83,6 @@ func processProfile(profile Profile, name string) error { if newName == "" { return errors.New("Couldn't find a good new name") } else { - fmt.Printf("newName: %v\n", newName) if useDirs { fmt.Printf("Creating directory: %v\n", fullPath) err = os.Mkdir(fullPath, os.ModePerm) @@ -104,10 +103,12 @@ func processProfile(profile Profile, name string) error { if postScripts != nil && len(postScripts) > 0 { allArgs := []string{"/C"} allArgs = append(allArgs, postScripts...) - fmt.Printf("Executing post script: cmd %v \n", strings.Trim(fmt.Sprint(allArgs), "[]")) + debugProfileScript := fmt.Sprintf("cmd %v", strings.Trim(fmt.Sprint(allArgs), "[]")) + fmt.Printf("Executing post script: %v \n", debugProfileScript) cmd := exec.Command("cmd", allArgs...) if err := cmd.Run(); err != nil { - // return err + // post scripts tend to fail (TODO: investigate why), so for now we'll just log the error + fmt.Printf("Error executing post script '%v': %v\n", debugProfileScript, err) } } @@ -117,6 +118,7 @@ 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 @@ -125,19 +127,16 @@ type PostScriptPatternData struct { func createNewName(name string, profile Profile, existingEntities []string) (string, error) { now := time.Now() - patternInfos := createNamePatternData(now, name) - for _, patternInfo := range patternInfos { - newName, err := createNewNameForProfile(profile, patternInfo, existingEntities) - if err != nil { - return "", err - } else { - return newName, nil - } + patternInfo := createNamePatternData(now, name) + newName, err := createNewNameForProfile(profile, patternInfo, existingEntities) + if err != nil { + return "", err + } else { + return newName, nil } - return "", errors.New("Couldn't find a new name") } -func createNamePatternData(now time.Time, projectName string) []NamePatternData { +func createNamePatternData(now time.Time, projectName string) NamePatternData { patternInfo := NamePatternData{ Year: now.Format("2006"), Month: now.Format("01"), @@ -146,28 +145,59 @@ func createNamePatternData(now time.Time, projectName string) []NamePatternData Minute: now.Format("04"), Second: now.Format("05"), ProjectName: projectName, + Index: 0, } - return []NamePatternData{patternInfo} + return patternInfo } func createNewNameForProfile(profile Profile, patternData NamePatternData, existingEntities []string) (string, error) { - for _, namePattern := range profile.NamePatterns { - template, err := template.New("template-name").Parse(namePattern) - if err != nil { - return "", err + for index, namePattern := range profile.NamePatterns { + + startingIndex := 0 + invokeCount := 0 + funcMap := template.FuncMap{ + "getUniqueIndex": func() int { + invokeCount++ + return startingIndex + }, } + template := template.New("template-name").Funcs(funcMap) - sb := new(strings.Builder) - err = template.Execute(sb, patternData) - if err != nil { - return "", err - } + for { + + template, err := template.Parse(namePattern) + if err != nil { + return "", err + } + + sb := new(strings.Builder) + err = template.Execute(sb, patternData) + if err != nil { + return "", err + } + + newName := sb.String() + alreadyExists := slices.Contains(existingEntities, newName) + useIndex := invokeCount > 0 + isLastPattern := index == len(profile.NamePatterns)-1 - newName := sb.String() - alreadyExists := slices.Contains(existingEntities, newName) - if !alreadyExists { - return newName, nil + // if no conflict, use this name + if !alreadyExists { + return newName, nil + } + // if index is not being used (template did not invoke getUniqueIndex) + // then we're done + if !useIndex { + break + } + + // if getUniqueIndex was used, but this isn't the last pattern, report an error + if useIndex && !isLastPattern { + return "", errors.New("Cannot use function getUniqueIndex in a pattern that is not the last pattern") + } + + startingIndex++ } } return "", errors.New("Couldn't find a new name") @@ -204,7 +234,3 @@ func createPostScriptArray(profile Profile, name string, path string) ([]string, return array, nil } - -// func getNextEntry(name string, existingNames []string, profile Profile) string { -// profile. -// } diff --git a/utils.go b/utils.go index bbc6035..ceb6403 100644 --- a/utils.go +++ b/utils.go @@ -24,11 +24,8 @@ func getFullPath(path string) string { dir := usr.HomeDir var newPath string if path == "~" { - // In case of "~", which won't be caught by the "else if" newPath = dir } else if strings.HasPrefix(path, "~/") { - // Use strings.HasPrefix so we don't match paths like - // "/something/~/something/" newPath = filepath.Join(dir, path[2:]) } else { newPath = path