template / commit
Rewired main a bit, this improves organization.
.vscode/launch.json | 32 ++++++-- default_config.go | 29 ++++++- main.go | 223 ++++++++++++++++++++++++++++++---------------------- monkey-patch.go | 14 +++- 4 files changed, 191 insertions(+), 107 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 031cf0a..b51d111 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,7 +25,17 @@ "request": "launch", "mode": "auto", "program": ".", - "args": ["--default-config"] + "args": [] + }, + { + "name": "Run: template reset", + "type": "go", + "request": "launch", + "mode": "auto", + "program": ".", + "args": [ + "reset", + ] }, { "name": "Run: template blog", @@ -33,7 +43,9 @@ "request": "launch", "mode": "auto", "program": ".", - "args": ["blog", "--default-config"] + "args": [ + "blog", + ] }, { "name": "Run: template daily", @@ -41,7 +53,9 @@ "request": "launch", "mode": "auto", "program": ".", - "args": ["daily"] + "args": [ + "daily" + ] }, { "name": "Run: template work", @@ -49,7 +63,9 @@ "request": "launch", "mode": "auto", "program": ".", - "args": ["work"] + "args": [ + "work" + ] }, { "name": "Run: template --profile work --project testProj --default-config", @@ -62,7 +78,6 @@ "work", "--project", "testProj", - "--default-config" ] }, { @@ -71,7 +86,10 @@ "request": "launch", "mode": "auto", "program": ".", - "args": ["note", "whoa"] + "args": [ + "note", + "whoa" + ] }, { "name": "Run: template test blah", @@ -90,4 +108,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/default_config.go b/default_config.go index 9cc0c14..35981c4 100644 --- a/default_config.go +++ b/default_config.go @@ -34,7 +34,6 @@ Today's notes for {{.Year}}-{{.Month}}-{{.Day}}. Description: "Creates a MD file in ~/Notes in the format YYYY-MM-DD[-ProjectName][-vVersion].md", OS: "All", Path: "~/Notes", - IsDefault: true, Type: FileType, NamePatterns: []ParameterizedText{ "{{$version := getVersion}}" + @@ -48,6 +47,34 @@ Today's notes for {{.Year}}-{{.Month}}-{{.Day}}. "code \"{{.FullPath}}\"", }, }, + { + Name: "note-here", + Description: "Creates a MD file in the current folder in the format YYYY-MM-DD[-HH[-MM[-SS]]][-ProjectName][-vVersion].md", + OS: "All", + Type: FileType, + IsDefault: true, + NamePatterns: []ParameterizedText{ + "{{$version := getVersion}}" + + "{{.Year}}-{{.Month}}-{{.Day}}" + + "{{if .ProjectName}}-{{.ProjectName}}{{end}}" + + "{{if (gt $version 1)}}n{{$version}}{{end}}" + + ".md", + "{{$version := getVersion}}" + + "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}" + + "{{if .ProjectName}}-{{.ProjectName}}{{end}}" + + "{{if (gt $version 1)}}n{{$version}}{{end}}" + + ".md", + "{{$version := getVersion}}" + + "{{.Year}}-{{.Month}}-{{.Day}}-{{.Hour}}-{{.Second}}" + + "{{if .ProjectName}}-{{.ProjectName}}{{end}}" + + "{{if (gt $version 1)}}n{{$version}}{{end}}" + + ".md", + }, + ScriptShell: "pwsh", + PostScripts: []ParameterizedText{ + "code \"{{.FullPath}}\"", + }, + }, { Name: "blog", Description: "Creates a MD file in the ~/Blog folder in the format YYYY-MM-DD[-ProjectName][-vVersion].md", diff --git a/main.go b/main.go index c5eb514..b6aedbd 100644 --- a/main.go +++ b/main.go @@ -11,14 +11,22 @@ import ( "gopkg.in/yaml.v3" ) +type ArgumentValues struct { + profile string + projectName string + configFilePath string + extrasFilePath string + useDefaultConfig bool +} +type Settings struct { + ArgumentValues + extras map[string]string +} + func main() { - var profileName string - var projectName string - var configFilePath string - var extrasFilePath string - var useDefaultConfig bool - var err error - var usr *user.User + // var err error + // var usr *user.User + argumentValues := ArgumentValues{} app := &cli.App{ Name: "template", @@ -31,7 +39,7 @@ func main() { Aliases: []string{"p"}, Value: "", Usage: "`PROFILE` to use for the template", - Destination: &profileName, + Destination: &argumentValues.profile, // Value: defaultProfileName, // Required: true, // EnvVars: []string{"TEMPLATE_PROFILE"}, @@ -41,129 +49,152 @@ func main() { Aliases: []string{"n"}, Usage: "name of the project to create", Value: "", - Destination: &projectName, + Destination: &argumentValues.projectName, }, &cli.PathFlag{ Name: "config-yaml", Aliases: []string{"c"}, Usage: "path to the config yaml file", Value: "~/.template.yaml", - Destination: &configFilePath, + Destination: &argumentValues.configFilePath, }, &cli.PathFlag{ Name: "extras-yaml", Aliases: []string{"e"}, Usage: "path to the extras yaml file", Value: "~/.template-extras.yaml", - Destination: &extrasFilePath, + Destination: &argumentValues.extrasFilePath, }, &cli.BoolFlag{ Name: "default-config", Aliases: []string{"d"}, Usage: "use the default hard-coded config (testing only)", Value: false, - Destination: &useDefaultConfig, + Destination: &argumentValues.useDefaultConfig, }, }, Action: func(context *cli.Context) error { - - usr, err = user.Current() + settings, err := parseArguments(argumentValues, context) if err != nil { - log.Fatal(err) + return fmt.Errorf("error parsing arguments: %w", err) } - - // get config - fullConfigPath := getFullPath(configFilePath, *usr) - var config Config - if useDefaultConfig { - config = defaultConfig() - } else { - config, err = getOrCreateConfig(fullConfigPath) - if err != nil { - return err - } + err = mainLogic(settings) + if err != nil { + return fmt.Errorf("error in main logic: %w", err) } + return nil + }, + } - // read args - args := context.Args() - fmt.Println("Args:", args) + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } +} - // get profile name from args - // if not set explicitly, use first arg, if present - if profileName == "" && args.Len() > 0 { - profileName = args.Get(0) - } - fmt.Println("Profile:", profileName) +func parseArguments( + argumentValues ArgumentValues, + context *cli.Context, +) (Settings, error) { + settings := Settings{ + ArgumentValues: argumentValues, + } - // get project name from args - // if not set explicitly, use second arg, if present - if projectName == "" && args.Len() > 1 { - projectName = args.Get(1) - } - if projectName != "" { - fmt.Println("Project name:", projectName) - } + // read args + args := context.Args() + fmt.Println("Args:", args) - // extra features - extras, err := loadExtras(extrasFilePath) - if err != nil { - return fmt.Errorf("error loading extras from %v: %w", extrasFilePath, err) - } + // get profile name from args + // if not set explicitly, use first arg, if present + if settings.profile == "" && args.Len() > 0 { + settings.profile = args.Get(0) + } + fmt.Println("Profile:", settings.profile) - // list profiles - if profileName == "list" { - fmt.Println("Available profiles:") - for _, p := range config.Profiles { - fmt.Printf(" %v: %v\n", p.Name, p.Description) - } - return nil - } + // get project name from args + // if not set explicitly, use second arg, if present + if settings.projectName == "" && args.Len() > 1 { + settings.projectName = args.Get(1) + } + fmt.Println("Project name:", settings.projectName) - // 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 - } + // extra features + extras, err := loadExtras(settings.extrasFilePath) + if err != nil { + return settings, fmt.Errorf("error loading extras from %v: %w", settings.extrasFilePath, err) + } + settings.extras = extras - // reset config to the default - if profileName == "reset" { - fmt.Printf("Resetting config at '%v' to default\n", fullConfigPath) - err = saveConfig(fullConfigPath, defaultConfig()) - if err != nil { - return fmt.Errorf("error saving default config: %v", err) - } - return nil - } + return settings, nil +} - // find profile - profile, err := findProfile(config, profileName) - if err != nil { - return fmt.Errorf("error finding profile: %v", err) - } +func mainLogic(settings Settings) error { + usr, err := user.Current() + if err != nil { + log.Fatal(err) + } - // process profile - errors := processProfile(profile, projectName, extras, *usr) - if len(errors) > 0 { - return fmt.Errorf("error processing profile: %v", errors) - } + // get config + fullConfigPath := getFullPath(settings.configFilePath, *usr) + var config Config + if settings.useDefaultConfig { + config = defaultConfig() + } else { + config, err = getOrCreateConfig(fullConfigPath) + if err != nil { + return err + } + } - return nil - }, + // list profiles + if settings.profile == "list" { + fmt.Println("Available profiles:") + for _, p := range config.Profiles { + fmt.Printf(" %v: %v\n", p.Name, p.Description) + } + return nil } - if err := app.Run(os.Args); err != nil { - log.Fatal(err) + // get profile information + if settings.profile == "get" { + fmt.Printf("Profile '%v':\n", settings.projectName) + profile, err := findProfile(config, settings.projectName) + if err != nil { + return fmt.Errorf("profile '%v' not found", settings.projectName) + } + + writer := strings.Builder{} + encoder := yaml.NewEncoder(&writer) + err = encoder.Encode(profile) + if err != nil { + return fmt.Errorf("error encoding profile: %v", err) + } + + yamlText := writer.String() + fmt.Println(yamlText) + return nil + } + + // reset config to the default + if settings.profile == "reset" { + fmt.Printf("Resetting config at '%v' to default\n", fullConfigPath) + err = saveConfig(fullConfigPath, defaultConfig()) + if err != nil { + return fmt.Errorf("error saving default config: %v", err) + } + return nil } + + // find profile + profile, err := findProfile(config, settings.profile) + if err != nil { + return fmt.Errorf("error finding profile: %v", err) + } + + // process profile + errors := processProfile(profile, settings.projectName, settings.extras, *usr) + if len(errors) > 0 { + return fmt.Errorf("error processing profile: %v", errors) + } + + return nil } diff --git a/monkey-patch.go b/monkey-patch.go index bc67233..44e3e63 100644 --- a/monkey-patch.go +++ b/monkey-patch.go @@ -8,6 +8,10 @@ import ( "github.com/stretchr/testify/assert" ) +type monkeyOsDirEntry interface { + Name() string + IsDir() bool +} type monkeyPatch struct { ExecCommand func(name string, arg ...string) *exec.Cmd OSWriteFile func(filename string, data []byte, perm os.FileMode) error @@ -35,7 +39,7 @@ type monkeyPatchCalls struct { OSReadDirCalls []struct{ dirname string } } -var monkey = monkeyPatch{} +var monkey = defaultMonkeyPatch() func applyTestMonkeyPatch(t *testing.T, monkeyImpl monkeyPatch) *monkeyPatchCalls { t.Cleanup(undoMonkeyPatch) @@ -102,8 +106,8 @@ func applyTestMonkeyPatch(t *testing.T, monkeyImpl monkeyPatch) *monkeyPatchCall return &results } -func undoMonkeyPatch() { - monkey = monkeyPatch{ +func defaultMonkeyPatch() monkeyPatch { + return monkeyPatch{ ExecCommand: exec.Command, OSWriteFile: os.WriteFile, OSGetwd: os.Getwd, @@ -112,3 +116,7 @@ func undoMonkeyPatch() { OSReadDir: os.ReadDir, } } + +func undoMonkeyPatch() { + monkey = defaultMonkeyPatch() +}