Show conflicts to parent branch

This commit is contained in:
2026-07-28 11:46:43 +02:00
parent 0e880fa9b0
commit f93c2c517a
8 changed files with 509 additions and 41 deletions

60
tui.go
View File

@@ -1504,6 +1504,9 @@ func (m App) dashboardLines() []string {
dashboardMetadata("review", reviewAndMergeState(pr)),
dashboardMetadata("checks", coloredState(pr.CheckState)),
dashboardMetadata("merge state", firstNonEmpty(strings.ToLower(pr.MergeState), "unknown")),
)
lines = append(lines, dashboardMetadataLines("conflicts", conflictStateText(pr), width)...)
lines = append(lines,
dashboardMetadata("assignees", handlesText(pr.Assignees)),
dashboardMetadata("reviewers", reviewersText(pr.Reviewers)),
dashboardMetadata("labels", labels),
@@ -1527,6 +1530,21 @@ func (m App) dashboardLines() []string {
dashboardMetadata("updated", updated),
dashboardMetadata("url", pr.URL),
)
if len(pr.ConflictFiles) > 0 {
lines = append(lines, "", titleStyle.Render(fmt.Sprintf(
"Conflicting files (%d)", len(pr.ConflictFiles),
)), "")
for _, file := range pr.ConflictFiles {
parts := strings.Split(ansi.Hardwrap(file, max(1, width-4), false), "\n")
for index, part := range parts {
prefix := " "
if index == 0 {
prefix = "• "
}
lines = append(lines, badStyle.Render(prefix)+part)
}
}
}
lines = append(lines, "", titleStyle.Render("Write capability gate"), "")
lines = append(lines, writeCapabilityLines(pr, m.selectedThread())...)
if pr.ThreadsTruncated {
@@ -1688,6 +1706,22 @@ func dashboardMetadata(label, value string) string {
return titleStyle.Render(pad(label+":", 13)) + " " + value
}
func dashboardMetadataLines(label, value string, width int) []string {
const labelWidth = 13
valueWidth := max(1, width-labelWidth-1)
wrapped := ansi.Hardwrap(ansi.Wordwrap(value, valueWidth, ""), valueWidth, false)
parts := strings.Split(wrapped, "\n")
lines := make([]string, 0, len(parts))
for index, part := range parts {
currentLabel := ""
if index == 0 {
currentLabel = label + ":"
}
lines = append(lines, titleStyle.Render(pad(currentLabel, labelWidth))+" "+part)
}
return lines
}
func threadStatusCounts(threads []ReviewThread) (open, outdated, resolved int) {
for _, thread := range threads {
switch threadStatus(thread) {
@@ -2391,6 +2425,32 @@ func reviewAndMergeState(pr PRDetails) string {
}
}
func conflictStateText(pr PRDetails) string {
switch pr.Mergeable {
case "MERGEABLE":
return okStyle.Render("none")
case "CONFLICTING":
if len(pr.ConflictFiles) > 0 {
return badStyle.Render(fmt.Sprintf("%d conflicting files", len(pr.ConflictFiles)))
}
if pr.ConflictFileError != "" {
return badStyle.Render("detected") + " " +
warnStyle.Render("file scan unavailable: "+firstLine(pr.ConflictFileError))
}
return badStyle.Render("detected") + " " +
dimStyle.Render("no individual file paths reported")
default:
return warnStyle.Render("checking")
}
}
func firstLine(value string) string {
if line, _, found := strings.Cut(value, "\n"); found {
return line
}
return value
}
func coloredState(state string) string {
switch state {
case "SUCCESS", "EXPECTED", "COMPLETED", "NEUTRAL", "SKIPPED":