fix/prdescribe-patch #8
@ -2,10 +2,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"gmgauthier.com/grokkit/config"
|
"gmgauthier.com/grokkit/config"
|
||||||
|
"gmgauthier.com/grokkit/internal/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
var prDescribeCmd = &cobra.Command{
|
var prDescribeCmd = &cobra.Command{
|
||||||
@ -21,24 +23,26 @@ func init() {
|
|||||||
func runPRDescribe(cmd *cobra.Command, _ []string) {
|
func runPRDescribe(cmd *cobra.Command, _ []string) {
|
||||||
base, _ := cmd.Flags().GetString("base")
|
base, _ := cmd.Flags().GetString("base")
|
||||||
|
|
||||||
diff, err := gitRun([]string{"diff", fmt.Sprintf("%s..HEAD", base), "--no-color"})
|
// Prefer a local base, fallback to origin/<base>. Tolerant of exit code 1.
|
||||||
if err != nil || diff == "" {
|
diff, err := git.Diff([]string{"diff", fmt.Sprintf("%s..HEAD", base), "--no-color"})
|
||||||
diff, err = gitRun([]string{"diff", fmt.Sprintf("origin/%s..HEAD", base), "--no-color"})
|
if err != nil || strings.TrimSpace(diff) == "" {
|
||||||
|
diff, err = git.Diff([]string{"diff", fmt.Sprintf("origin/%s..HEAD", base), "--no-color"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
color.Red("Failed to get branch diff: %v", err)
|
color.Red("Failed to get branch diff: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if diff == "" {
|
if strings.TrimSpace(diff) == "" {
|
||||||
color.Yellow("No changes on this branch compared to %s/origin/%s.", base, base)
|
color.Yellow("No changes on this branch compared to %s/origin/%s.", base, base)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
modelFlag, _ := cmd.Flags().GetString("model")
|
modelFlag, _ := cmd.Flags().GetString("model")
|
||||||
model := config.GetModel("prdescribe", modelFlag)
|
model := config.GetModel("prdescribe", modelFlag)
|
||||||
|
|
||||||
client := newGrokClient()
|
client := newGrokClient()
|
||||||
messages := buildPRDescribeMessages(diff)
|
messages := buildPRDescribeMessages(diff)
|
||||||
color.Yellow("Writing PR description...")
|
color.Yellow("Writing PR description (base=%s)...", base)
|
||||||
client.Stream(messages, model)
|
client.Stream(messages, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
@ -60,3 +61,24 @@ func LogSince(since string) (string, error) {
|
|||||||
args := []string{"log", "--pretty=format:%s%n%b%n---", since + "..HEAD"}
|
args := []string{"log", "--pretty=format:%s%n%b%n---", since + "..HEAD"}
|
||||||
return Run(args)
|
return Run(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Diff runs `git diff` and tolerates exit code 1 (differences found).
|
||||||
|
// This is normal git behavior when there *are* changes — unlike .Output().
|
||||||
|
func Diff(args []string) (string, error) {
|
||||||
|
cmdStr := "git " + strings.Join(args, " ")
|
||||||
|
logger.Debug("executing git diff", "command", cmdStr)
|
||||||
|
|
||||||
|
// nolint:gosec // intentional git subprocess
|
||||||
|
cmd := exec.Command("git", args...)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
var exitErr *exec.ExitError
|
||||||
|
if errors.As(err, &exitErr) && exitErr.ExitCode() == 1 {
|
||||||
|
// legitimate diff (changes exist)
|
||||||
|
return string(out), nil
|
||||||
|
}
|
||||||
|
logger.Error("git diff failed", "command", cmdStr, "error", err)
|
||||||
|
return "", fmt.Errorf("git diff failed: %w", err)
|
||||||
|
}
|
||||||
|
return string(out), nil
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user