From 62a71543106f0719f29d23e0a64b88c32ff10f28 Mon Sep 17 00:00:00 2001 From: John Murphy Date: Sun, 30 Mar 2025 13:03:43 -0400 Subject: [PATCH 1/3] Add tooling to allow for user-defined post question pick command --- cmd/pick.go | 6 +++++- config/config.go | 1 + lang/base.go | 15 ++++++++------- lang/cpp.go | 16 ++++++++++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/cmd/pick.go b/cmd/pick.go index 47d7955c..ebaba098 100644 --- a/cmd/pick.go +++ b/cmd/pick.go @@ -6,6 +6,7 @@ import ( "github.com/AlecAivazis/survey/v2" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/log" "github.com/spf13/cobra" "github.com/j178/leetgo/editor" @@ -105,7 +106,6 @@ leetgo pick two-sum`, RunE: func(cmd *cobra.Command, args []string) error { c := leetcode.NewClient(leetcode.ReadCredentials()) var q *leetcode.QuestionData - if len(args) > 0 { qid := args[0] qs, err := leetcode.ParseQID(qid, c) @@ -136,6 +136,10 @@ leetgo pick two-sum`, if err != nil { return err } + + if result.PostPickError != "" { + log.Error("Post-pick action error: %s\n", result.PostPickError) + } if !skipEditor { err = editor.Open(result) return err diff --git a/config/config.go b/config/config.go index 5fe63f04..3505454e 100644 --- a/config/config.go +++ b/config/config.go @@ -89,6 +89,7 @@ type BaseLangConfig struct { SeparateDescriptionFile bool `yaml:"separate_description_file,omitempty" mapstructure:"separate_description_file" comment:"Generate question description into a separate question.md file, otherwise it will be embed in the code file."` Blocks []Block `yaml:"blocks,omitempty" mapstructure:"blocks" comment:"Replace some blocks of the generated code."` Modifiers []Modifier `yaml:"modifiers,omitempty" mapstructure:"modifiers" comment:"Functions that modify the generated code."` + PostPickAction string `yaml:"post_pick_action,omitempty" mapstructure:"post_pick_action" comment: "Run command after picking problem."` } type GoConfig struct { diff --git a/lang/base.go b/lang/base.go index e1fb2833..319d5cff 100644 --- a/lang/base.go +++ b/lang/base.go @@ -26,13 +26,14 @@ const ( const manualWarning = "Warning: this is a manual question, the generated test code may be incorrect." type GenerateResult struct { - mask int - Question *leetcode.QuestionData - Lang Lang - OutDir string - SubDir string - Files []FileOutput - ResultHooks []func(*GenerateResult) error + mask int + Question *leetcode.QuestionData + Lang Lang + OutDir string + SubDir string + Files []FileOutput + ResultHooks []func(*GenerateResult) error + PostPickError string } type FileOutput struct { diff --git a/lang/cpp.go b/lang/cpp.go index 31a312d0..c6b852aa 100644 --- a/lang/cpp.go +++ b/lang/cpp.go @@ -2,6 +2,8 @@ package lang import ( "fmt" + "os" + "os/exec" "path/filepath" "strings" @@ -383,6 +385,20 @@ func (c cpp) Generate(q *leetcode.QuestionData) (*GenerateResult, error) { } genResult.AddFile(docFile) } + // Run post-pick action directly. + postAction := getCodeStringConfig(c, "post_pick_action") + print(postAction) + if postAction != "" { + parts := strings.Fields(postAction) + if len(parts) > 0 { + cmd := exec.Command(parts[0], parts[1:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("post-pick action failed: %w", err) + } + } + } return genResult, nil } From 22263812a534fb109bee4842f339ab08eff4b390 Mon Sep 17 00:00:00 2001 From: John Murphy Date: Sun, 30 Mar 2025 13:21:21 -0400 Subject: [PATCH 2/3] Remove Changes to cpp.go (not needed) and add gen.go (Missed in first review) --- lang/cpp.go | 16 ---------------- lang/gen.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/lang/cpp.go b/lang/cpp.go index c6b852aa..31a312d0 100644 --- a/lang/cpp.go +++ b/lang/cpp.go @@ -2,8 +2,6 @@ package lang import ( "fmt" - "os" - "os/exec" "path/filepath" "strings" @@ -385,20 +383,6 @@ func (c cpp) Generate(q *leetcode.QuestionData) (*GenerateResult, error) { } genResult.AddFile(docFile) } - // Run post-pick action directly. - postAction := getCodeStringConfig(c, "post_pick_action") - print(postAction) - if postAction != "" { - parts := strings.Fields(postAction) - if len(parts) > 0 { - cmd := exec.Command(parts[0], parts[1:]...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("post-pick action failed: %w", err) - } - } - } return genResult, nil } diff --git a/lang/gen.go b/lang/gen.go index 9fffd3bb..2c7ac532 100644 --- a/lang/gen.go +++ b/lang/gen.go @@ -1,10 +1,13 @@ package lang import ( + "bytes" "errors" "fmt" "os" + "os/exec" "strings" + "text/template" "github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2/terminal" @@ -105,6 +108,41 @@ func generate(q *leetcode.QuestionData) (Lang, *GenerateResult, error) { } result.Files[i].Written = written } + + // Execute post-pick action after file writes + postAction := getCodeStringConfig(gen, "post_pick_action") + if postAction != "" { + // Build the substitution context. + data := struct { + Folder string + }{ + Folder: result.TargetDir(), + } + // Parse and execute the template. + tmpl, err := template.New("postPick").Parse(postAction) + if err != nil { + result.PostPickError = fmt.Sprintf("post-pick action template parsing failed: %v", err) + } else { + var buf bytes.Buffer + if err := tmpl.Execute(&buf, data); err != nil { + result.PostPickError = fmt.Sprintf("post-pick action template execution failed: %v", err) + } else { + substitutedCommand := buf.String() + // Split the substituted command into parts. + parts := strings.Fields(substitutedCommand) + if len(parts) > 0 { + log.Info("executing", "post_pick_action", substitutedCommand) + cmd := exec.Command(parts[0], parts[1:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + result.PostPickError = fmt.Sprintf("post-pick action failed: %v", err) + } + } + } + } + } + return gen, result, nil } From 4f050bf98a76b4752bd92bbe32a7ae8e844ff28f Mon Sep 17 00:00:00 2001 From: John Murphy Date: Sun, 30 Mar 2025 13:25:05 -0400 Subject: [PATCH 3/3] Normalize error messages --- cmd/pick.go | 2 +- lang/gen.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/pick.go b/cmd/pick.go index ebaba098..38aeaa24 100644 --- a/cmd/pick.go +++ b/cmd/pick.go @@ -138,7 +138,7 @@ leetgo pick two-sum`, } if result.PostPickError != "" { - log.Error("Post-pick action error: %s\n", result.PostPickError) + log.Error("error", "post_pick_action", result.PostPickError) } if !skipEditor { err = editor.Open(result) diff --git a/lang/gen.go b/lang/gen.go index 2c7ac532..4ba6976f 100644 --- a/lang/gen.go +++ b/lang/gen.go @@ -136,7 +136,7 @@ func generate(q *leetcode.QuestionData) (Lang, *GenerateResult, error) { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { - result.PostPickError = fmt.Sprintf("post-pick action failed: %v", err) + result.PostPickError = fmt.Sprintf("%v", err) } } }