summaryrefslogtreecommitdiffhomepage
path: root/internal/git/diff.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/git/diff.go')
-rw-r--r--internal/git/diff.go264
1 files changed, 0 insertions, 264 deletions
diff --git a/internal/git/diff.go b/internal/git/diff.go
deleted file mode 100644
index 2ab139642..000000000
--- a/internal/git/diff.go
+++ /dev/null
@@ -1,264 +0,0 @@
-package git
-
-import (
- "bytes"
- "fmt"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
- "time"
-
- "github.com/go-git/go-git/v5"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-type DiffStats struct {
- Additions int
- Removals int
-}
-
-func GenerateGitDiff(filePath string, contentBefore string, contentAfter string) (string, error) {
- tempDir, err := os.MkdirTemp("", "git-diff-temp")
- if err != nil {
- return "", fmt.Errorf("failed to create temp dir: %w", err)
- }
- defer os.RemoveAll(tempDir)
-
- repo, err := git.PlainInit(tempDir, false)
- if err != nil {
- return "", fmt.Errorf("failed to initialize git repo: %w", err)
- }
-
- wt, err := repo.Worktree()
- if err != nil {
- return "", fmt.Errorf("failed to get worktree: %w", err)
- }
-
- fullPath := filepath.Join(tempDir, filePath)
- if err = os.MkdirAll(filepath.Dir(fullPath), 0o755); err != nil {
- return "", fmt.Errorf("failed to create directories: %w", err)
- }
- if err = os.WriteFile(fullPath, []byte(contentBefore), 0o644); err != nil {
- return "", fmt.Errorf("failed to write 'before' content: %w", err)
- }
-
- _, err = wt.Add(filePath)
- if err != nil {
- return "", fmt.Errorf("failed to add file to git: %w", err)
- }
-
- beforeCommit, err := wt.Commit("Before", &git.CommitOptions{
- Author: &object.Signature{
- Name: "OpenCode",
- Email: "[email protected]",
- When: time.Now(),
- },
- })
- if err != nil {
- return "", fmt.Errorf("failed to commit 'before' version: %w", err)
- }
-
- if err = os.WriteFile(fullPath, []byte(contentAfter), 0o644); err != nil {
- return "", fmt.Errorf("failed to write 'after' content: %w", err)
- }
-
- _, err = wt.Add(filePath)
- if err != nil {
- return "", fmt.Errorf("failed to add updated file to git: %w", err)
- }
-
- afterCommit, err := wt.Commit("After", &git.CommitOptions{
- Author: &object.Signature{
- Name: "OpenCode",
- Email: "[email protected]",
- When: time.Now(),
- },
- })
- if err != nil {
- return "", fmt.Errorf("failed to commit 'after' version: %w", err)
- }
-
- beforeCommitObj, err := repo.CommitObject(beforeCommit)
- if err != nil {
- return "", fmt.Errorf("failed to get 'before' commit: %w", err)
- }
-
- afterCommitObj, err := repo.CommitObject(afterCommit)
- if err != nil {
- return "", fmt.Errorf("failed to get 'after' commit: %w", err)
- }
-
- patch, err := beforeCommitObj.Patch(afterCommitObj)
- if err != nil {
- return "", fmt.Errorf("failed to generate patch: %w", err)
- }
-
- return patch.String(), nil
-}
-
-func GenerateGitDiffWithStats(filePath string, contentBefore string, contentAfter string) (string, DiffStats, error) {
- tempDir, err := os.MkdirTemp("", "git-diff-temp")
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to create temp dir: %w", err)
- }
- defer os.RemoveAll(tempDir)
-
- repo, err := git.PlainInit(tempDir, false)
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to initialize git repo: %w", err)
- }
-
- wt, err := repo.Worktree()
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to get worktree: %w", err)
- }
-
- fullPath := filepath.Join(tempDir, filePath)
- if err = os.MkdirAll(filepath.Dir(fullPath), 0o755); err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to create directories: %w", err)
- }
- if err = os.WriteFile(fullPath, []byte(contentBefore), 0o644); err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to write 'before' content: %w", err)
- }
-
- _, err = wt.Add(filePath)
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to add file to git: %w", err)
- }
-
- beforeCommit, err := wt.Commit("Before", &git.CommitOptions{
- Author: &object.Signature{
- Name: "OpenCode",
- Email: "[email protected]",
- When: time.Now(),
- },
- })
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to commit 'before' version: %w", err)
- }
-
- if err = os.WriteFile(fullPath, []byte(contentAfter), 0o644); err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to write 'after' content: %w", err)
- }
-
- _, err = wt.Add(filePath)
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to add updated file to git: %w", err)
- }
-
- afterCommit, err := wt.Commit("After", &git.CommitOptions{
- Author: &object.Signature{
- Name: "OpenCode",
- Email: "[email protected]",
- When: time.Now(),
- },
- })
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to commit 'after' version: %w", err)
- }
-
- beforeCommitObj, err := repo.CommitObject(beforeCommit)
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to get 'before' commit: %w", err)
- }
-
- afterCommitObj, err := repo.CommitObject(afterCommit)
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to get 'after' commit: %w", err)
- }
-
- patch, err := beforeCommitObj.Patch(afterCommitObj)
- if err != nil {
- return "", DiffStats{}, fmt.Errorf("failed to generate patch: %w", err)
- }
-
- stats := DiffStats{}
- for _, fileStat := range patch.Stats() {
- stats.Additions += fileStat.Addition
- stats.Removals += fileStat.Deletion
- }
-
- return patch.String(), stats, nil
-}
-
-func FormatDiff(diffText string, width int) (string, error) {
- if isSplitDiffsAvailable() {
- return formatWithSplitDiffs(diffText, width)
- }
-
- return formatSimple(diffText), nil
-}
-
-func isSplitDiffsAvailable() bool {
- _, err := exec.LookPath("node")
- return err == nil
-}
-
-func formatWithSplitDiffs(diffText string, width int) (string, error) {
- args := []string{
- "--color",
- }
-
- var diffCmd *exec.Cmd
-
- if _, err := exec.LookPath("git-split-diffs-opencode"); err == nil {
- fullArgs := append([]string{"git-split-diffs-opencode"}, args...)
- diffCmd = exec.Command(fullArgs[0], fullArgs[1:]...)
- } else {
- npxArgs := append([]string{"git-split-diffs-opencode"}, args...)
- diffCmd = exec.Command("npx", npxArgs...)
- }
-
- diffCmd.Env = append(os.Environ(), fmt.Sprintf("DIFF_COLUMNS=%d", width))
-
- diffCmd.Stdin = strings.NewReader(diffText)
-
- var out bytes.Buffer
- diffCmd.Stdout = &out
-
- var stderr bytes.Buffer
- diffCmd.Stderr = &stderr
-
- if err := diffCmd.Run(); err != nil {
- return "", fmt.Errorf("git-split-diffs-opencode error: %w, stderr: %s", err, stderr.String())
- }
-
- return out.String(), nil
-}
-
-func formatSimple(diffText string) string {
- lines := strings.Split(diffText, "\n")
- var result strings.Builder
-
- for _, line := range lines {
- if len(line) == 0 {
- result.WriteString("\n")
- continue
- }
-
- switch line[0] {
- case '+':
- result.WriteString("\033[32m" + line + "\033[0m\n")
- case '-':
- result.WriteString("\033[31m" + line + "\033[0m\n")
- case '@':
- result.WriteString("\033[36m" + line + "\033[0m\n")
- case 'd':
- if strings.HasPrefix(line, "diff --git") {
- result.WriteString("\033[1m" + line + "\033[0m\n")
- } else {
- result.WriteString(line + "\n")
- }
- default:
- result.WriteString(line + "\n")
- }
- }
-
- if !strings.HasSuffix(diffText, "\n") {
- output := result.String()
- return output[:len(output)-1]
- }
-
- return result.String()
-}