Merge pull request #5 from oug-t/feat/dynamic-target

feat: support dynamic target
This commit is contained in:
Tommy Guo 2026-01-30 15:11:21 -05:00 committed by GitHub
commit 95dcd62910
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 17 deletions

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"os" "os"
@ -10,14 +11,39 @@ import (
) )
func main() { func main() {
// Load config (defaults used if file missing) // Define flags
help := flag.Bool("help", false, "Show help")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: difi [flags] [target-branch]\n")
fmt.Fprintf(os.Stderr, "\nFlags:\n")
flag.PrintDefaults()
fmt.Fprintf(os.Stderr, "\nExamples:\n")
fmt.Fprintf(os.Stderr, " difi # Diff against main\n")
fmt.Fprintf(os.Stderr, " difi develop # Diff against develop\n")
fmt.Fprintf(os.Stderr, " difi HEAD~1 # Diff against last commit\n")
}
flag.Parse()
if *help {
flag.Usage()
os.Exit(0)
}
// Determine Target Branch
// If user provides an argument (e.g., "difi develop"), use it.
// Otherwise default to "main".
target := "main"
if flag.NArg() > 0 {
target = flag.Arg(0)
}
// Load Config
cfg := config.Load() cfg := config.Load()
// Pass config to model // Pass target to the model
p := tea.NewProgram(ui.NewModel(cfg), tea.WithAltScreen()) p := tea.NewProgram(ui.NewModel(cfg, target), tea.WithAltScreen())
if _, err := p.Run(); err != nil { if _, err := p.Run(); err != nil {
fmt.Printf("Error running difi: %v", err) fmt.Printf("Error: %v\n", err)
os.Exit(1) os.Exit(1)
} }
} }

View File

@ -17,7 +17,7 @@ import (
"github.com/oug-t/difi/internal/tree" "github.com/oug-t/difi/internal/tree"
) )
const TargetBranch = "main" // REMOVED: const TargetBranch = "main" (Now dynamic)
type Focus int type Focus int
@ -33,6 +33,7 @@ type Model struct {
selectedPath string selectedPath string
currentBranch string currentBranch string
targetBranch string // Added field for dynamic target
repoName string repoName string
diffContent string diffContent string
@ -47,10 +48,12 @@ type Model struct {
width, height int width, height int
} }
func NewModel(cfg config.Config) Model { // Updated Signature: Accepts targetBranch string
func NewModel(cfg config.Config, targetBranch string) Model {
InitStyles(cfg) InitStyles(cfg)
files, _ := git.ListChangedFiles(TargetBranch) // Use the dynamic targetBranch variable
files, _ := git.ListChangedFiles(targetBranch)
items := tree.Build(files) items := tree.Build(files)
delegate := TreeDelegate{Focused: true} delegate := TreeDelegate{Focused: true}
@ -69,6 +72,7 @@ func NewModel(cfg config.Config) Model {
diffViewport: viewport.New(0, 0), diffViewport: viewport.New(0, 0),
focus: FocusTree, focus: FocusTree,
currentBranch: git.GetCurrentBranch(), currentBranch: git.GetCurrentBranch(),
targetBranch: targetBranch, // Store it
repoName: git.GetRepoName(), repoName: git.GetRepoName(),
showHelp: false, showHelp: false,
inputBuffer: "", inputBuffer: "",
@ -84,7 +88,8 @@ func NewModel(cfg config.Config) Model {
func (m Model) Init() tea.Cmd { func (m Model) Init() tea.Cmd {
if m.selectedPath != "" { if m.selectedPath != "" {
return git.DiffCmd(TargetBranch, m.selectedPath) // Use m.targetBranch instead of constant
return git.DiffCmd(m.targetBranch, m.selectedPath)
} }
return nil return nil
} }
@ -211,7 +216,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.selectedPath = item.FullPath m.selectedPath = item.FullPath
m.diffCursor = 0 m.diffCursor = 0
m.diffViewport.GotoTop() m.diffViewport.GotoTop()
cmds = append(cmds, git.DiffCmd(TargetBranch, m.selectedPath)) // Use m.targetBranch
cmds = append(cmds, git.DiffCmd(m.targetBranch, m.selectedPath))
} }
} }
} }
@ -223,7 +229,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.diffViewport.SetContent(msg.Content) m.diffViewport.SetContent(msg.Content)
case git.EditorFinishedMsg: case git.EditorFinishedMsg:
return m, git.DiffCmd(TargetBranch, m.selectedPath) // Use m.targetBranch
return m, git.DiffCmd(m.targetBranch, m.selectedPath)
} }
return m, tea.Batch(cmds...) return m, tea.Batch(cmds...)
@ -260,7 +267,6 @@ func (m Model) View() string {
return "Loading..." return "Loading..."
} }
// 1. PANES
treeStyle := PaneStyle treeStyle := PaneStyle
if m.focus == FocusTree { if m.focus == FocusTree {
treeStyle = FocusedPaneStyle treeStyle = FocusedPaneStyle
@ -280,11 +286,9 @@ func (m Model) View() string {
end = len(m.diffLines) end = len(m.diffLines)
} }
// RENDER LOOP
for i := start; i < end; i++ { for i := start; i < end; i++ {
line := m.diffLines[i] line := m.diffLines[i]
// --- LINE NUMBERS ---
var numStr string var numStr string
mode := CurrentConfig.UI.LineNumbers mode := CurrentConfig.UI.LineNumbers
@ -310,7 +314,6 @@ func (m Model) View() string {
lineNumRendered = LineNumberStyle.Render(numStr) lineNumRendered = LineNumberStyle.Render(numStr)
} }
// --- DIFF VIEW HIGHLIGHT ---
if m.focus == FocusDiff && i == m.diffCursor { if m.focus == FocusDiff && i == m.diffCursor {
cleanLine := stripAnsi(line) cleanLine := stripAnsi(line)
line = DiffSelectionStyle.Render(" " + cleanLine) line = DiffSelectionStyle.Render(" " + cleanLine)
@ -328,11 +331,11 @@ func (m Model) View() string {
mainPanes := lipgloss.JoinHorizontal(lipgloss.Top, treeView, diffView) mainPanes := lipgloss.JoinHorizontal(lipgloss.Top, treeView, diffView)
// 2. BOTTOM AREA
repoSection := StatusKeyStyle.Render(" " + m.repoName) repoSection := StatusKeyStyle.Render(" " + m.repoName)
divider := StatusDividerStyle.Render("│") divider := StatusDividerStyle.Render("│")
statusText := fmt.Sprintf(" %s ↔ %s", m.currentBranch, TargetBranch) // Use m.targetBranch in status bar
statusText := fmt.Sprintf(" %s ↔ %s", m.currentBranch, m.targetBranch)
if m.inputBuffer != "" { if m.inputBuffer != "" {
statusText += fmt.Sprintf(" [Cmd: %s]", m.inputBuffer) statusText += fmt.Sprintf(" [Cmd: %s]", m.inputBuffer)
} }