Skip to content

Commit

Permalink
feat: added '-u` to update PR from base branch (#458)
Browse files Browse the repository at this point in the history
* Feat: added '-u` to update PR from base branch

* feat: added mergeStateStatus pill

* Update ui/components/prsidebar/prsidebar.go

Change naming

Co-authored-by: Dolev Hadar <[email protected]>

* Update ui/components/pr/pr.go

Change naming

Co-authored-by: Dolev Hadar <[email protected]>

* fix: github added / and changed icon for up-to date

---------

Co-authored-by: Dolev Hadar <[email protected]>
  • Loading branch information
nzspambot and dlvhdr authored Oct 2, 2024
1 parent a7291c9 commit 08e5576
Show file tree
Hide file tree
Showing 14 changed files with 111 additions and 17 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ keybindings:
The list of available builtin commands are:

1. `universal`: up, down, firstLine, lastLine, togglePreview, openGithub, refresh, refreshAll, pageDown, pageUp, nextSection, prevSection, search, copyurl, copyNumber, help, quit
2. `prs`: approve, assign, unassign, comment, diff, checkout, close, ready, reopen, merge, watchChecks, viewIssues
2. `prs`: approve, assign, unassign, comment, diff, checkout, close, ready, reopen, merge, update, watchChecks, viewIssues
3. `Issues`: assign, unassign, comment, close, reopen, viewPrs

#### Defining custom keybindings
Expand Down
1 change: 1 addition & 0 deletions config/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ type ColorThemeText struct {
Faint HexColor `yaml:"faint" validate:"hexcolor"`
Warning HexColor `yaml:"warning" validate:"hexcolor"`
Success HexColor `yaml:"success" validate:"hexcolor"`
Error HexColor `yaml:"error" validate:"hexcolor"`
}

type ColorThemeBorder struct {
Expand Down
19 changes: 11 additions & 8 deletions data/prapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ type PullRequestData struct {
HeadRef struct {
Name string
}
Repository Repository
Assignees Assignees `graphql:"assignees(first: 3)"`
Comments Comments `graphql:"comments(last: 5, orderBy: { field: UPDATED_AT, direction: DESC })"`
LatestReviews Reviews `graphql:"latestReviews(last: 3)"`
ReviewThreads ReviewThreads `graphql:"reviewThreads(last: 20)"`
IsDraft bool
Commits Commits `graphql:"commits(last: 1)"`
Labels PRLabels `graphql:"labels(first: 3)"`
Repository Repository
Assignees Assignees `graphql:"assignees(first: 3)"`
Comments Comments `graphql:"comments(last: 5, orderBy: { field: UPDATED_AT, direction: DESC })"`
LatestReviews Reviews `graphql:"latestReviews(last: 3)"`
ReviewThreads ReviewThreads `graphql:"reviewThreads(last: 20)"`
IsDraft bool
Commits Commits `graphql:"commits(last: 1)"`
Labels PRLabels `graphql:"labels(first: 3)"`
MergeStateStatus MergeStateStatus `graphql:"mergeStateStatus"`
}

type CheckRun struct {
Expand Down Expand Up @@ -152,6 +153,8 @@ type PRLabels struct {
Nodes []Label
}

type MergeStateStatus string

type PageInfo struct {
HasNextPage bool
StartCursor string
Expand Down
13 changes: 13 additions & 0 deletions ui/components/pr/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,19 @@ func (pr *PullRequest) RenderState() string {
}
}

func (pr *PullRequest) RenderMergeStateStatus() string {
switch pr.Data.MergeStateStatus {
case "CLEAN":
return constants.SuccessIcon + " Up-to-date"
case "BLOCKED":
return constants.BlockedIcon + " Blocked"
case "BEHIND":
return constants.BehindIcon + " Behind"
default:
return ""
}
}

func (pr *PullRequest) ToTableRow(isSelected bool) table.Row {
if !pr.Ctx.Config.Theme.Ui.Table.Compact {
return table.Row{
Expand Down
25 changes: 22 additions & 3 deletions ui/components/prsidebar/prsidebar.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,38 @@ func (m *Model) renderMergeablePill() string {
} else if status == "MERGEABLE" {
return m.ctx.Styles.PrSidebar.PillStyle.
Background(m.ctx.Theme.SuccessText).
Render("󰃸 Mergeable")
Render("󰃸 No Merge Conflicts")
}

return ""
}

func (m *Model) renderMergeStateStatusPill() string {
status := m.pr.Data.MergeStateStatus
if status == "CLEAN" {
return m.ctx.Styles.PrSidebar.PillStyle.
Background(m.ctx.Theme.SuccessText).
Render("󰄬 Branch Up-To-Date")
} else if status == "BLOCKED" {
return m.ctx.Styles.PrSidebar.PillStyle.
Background(m.ctx.Theme.ErrorText).
Render("󰅖 Branch Blocked")
} else if status == "BEHIND" {
return m.ctx.Styles.PrSidebar.PillStyle.
Background(m.ctx.Theme.WarningText).
Render(" Branch Behind")
}
return ""
}

func (m *Model) renderChecksPill() string {
s := m.ctx.Styles.PrSidebar.PillStyle
t := m.ctx.Theme

status := m.pr.GetStatusChecksRollup()
if status == "FAILURE" {
return s.
Background(t.WarningText).
Background(t.ErrorText).
Render("󰅖 Checks")
} else if status == "PENDING" {
return s.
Expand All @@ -256,7 +274,8 @@ func (m *Model) renderPills() string {
statusPill := m.renderStatusPill()
mergeablePill := m.renderMergeablePill()
checksPill := m.renderChecksPill()
return lipgloss.JoinHorizontal(lipgloss.Top, statusPill, " ", mergeablePill, " ", checksPill)
uptoDatePill := m.renderMergeStateStatusPill()
return lipgloss.JoinHorizontal(lipgloss.Top, statusPill, " ", mergeablePill, " ", checksPill, " ", uptoDatePill)
}

func (m *Model) renderLabels() string {
Expand Down
2 changes: 2 additions & 0 deletions ui/components/prssection/prssection.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ func (m Model) Update(msg tea.Msg) (section.Section, tea.Cmd) {
cmd = tasks.PRReady(m.Ctx, sid, pr)
case "merge":
cmd = tasks.MergePR(m.Ctx, sid, pr)
case "update":
cmd = tasks.UpdatePR(m.Ctx, sid, pr)
}
}

Expand Down
2 changes: 2 additions & 0 deletions ui/components/reposection/reposection.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ func (m *Model) Update(msg tea.Msg) (section.Section, tea.Cmd) {
cmd = tasks.PRReady(m.Ctx, sid, pr)
case "merge":
cmd = tasks.MergePR(m.Ctx, sid, pr)
case "update":
cmd = tasks.UpdatePR(m.Ctx, sid, pr)
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions ui/components/section/section.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ func (m *BaseModel) GetPromptConfirmation() string {
case m.PromptConfirmationAction == "merge" && m.Ctx.View == config.PRsView:
prompt = "Are you sure you want to merge this PR? (Y/n) "

case m.PromptConfirmationAction == "update" && m.Ctx.View == config.PRsView:
prompt = "Are you sure you want to update this PR? (Y/n) "

case m.PromptConfirmationAction == "close" && m.Ctx.View == config.IssuesView:
prompt = "Are you sure you want to close this issue? (Y/n) "

Expand Down
23 changes: 23 additions & 0 deletions ui/components/tasks/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,26 @@ func CreatePR(ctx *context.ProgramContext, section SectionIdentifer, branchName
}
}))
}

func UpdatePR(ctx *context.ProgramContext, section SectionIdentifer, pr data.RowData) tea.Cmd {
prNumber := pr.GetNumber()
return fireTask(ctx, GitHubTask{
Id: buildTaskId("pr_update", prNumber),
Args: []string{
"pr",
"update-branch",
fmt.Sprint(prNumber),
"-R",
pr.GetRepoNameWithOwner(),
},
Section: section,
StartText: fmt.Sprintf("Updating PR #%d", prNumber),
FinishedText: fmt.Sprintf("PR #%d has been updated", prNumber),
Msg: func(c *exec.Cmd, err error) tea.Msg {
return UpdatePRMsg{
PrNumber: prNumber,
IsClosed: utils.BoolPtr(true),
}
},
})
}
10 changes: 6 additions & 4 deletions ui/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ const (
FailureIcon = "󰅙"
SuccessIcon = ""

DraftIcon = ""
MergedIcon = ""
OpenIcon = ""
ClosedIcon = ""
DraftIcon = ""
BehindIcon = "󰇮"
BlockedIcon = ""
MergedIcon = ""
OpenIcon = ""
ClosedIcon = ""
)
8 changes: 8 additions & 0 deletions ui/keys/branchKeys.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type BranchKeyMap struct {
Push key.Binding
ForcePush key.Binding
Delete key.Binding
UpdatePr key.Binding
ViewPRs key.Binding
}

Expand Down Expand Up @@ -49,6 +50,10 @@ var BranchKeys = BranchKeyMap{
key.WithKeys("d", "backspace"),
key.WithHelp("d/backspace", "delete"),
),
UpdatePr: key.NewBinding(
key.WithKeys("u"),
key.WithHelp("u", "update PR"),
),
ViewPRs: key.NewBinding(
key.WithKeys("s"),
key.WithHelp("s", "Switch to PRs"),
Expand All @@ -64,6 +69,7 @@ func BranchFullHelp() []key.Binding {
BranchKeys.New,
BranchKeys.CreatePr,
BranchKeys.Delete,
BranchKeys.UpdatePr,
BranchKeys.ViewPRs,
}
}
Expand Down Expand Up @@ -95,6 +101,8 @@ func rebindBranchKeys(keys []config.Keybinding) error {
key = &BranchKeys.Checkout
case "viewPRs":
key = &BranchKeys.ViewPRs
case "updatePr":
key = &BranchKeys.UpdatePr
default:
return fmt.Errorf("unknown built-in branch key: '%s'", branchKey.Builtin)
}
Expand Down
8 changes: 8 additions & 0 deletions ui/keys/prKeys.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type PRKeyMap struct {
Ready key.Binding
Reopen key.Binding
Merge key.Binding
Update key.Binding
WatchChecks key.Binding
ViewIssues key.Binding
}
Expand Down Expand Up @@ -65,6 +66,10 @@ var PRKeys = PRKeyMap{
key.WithKeys("m"),
key.WithHelp("m", "merge"),
),
Update: key.NewBinding(
key.WithKeys("u"),
key.WithHelp("u", "update pr from base branch"),
),
WatchChecks: key.NewBinding(
key.WithKeys("w"),
key.WithHelp("w", "Watch checks"),
Expand All @@ -87,6 +92,7 @@ func PRFullHelp() []key.Binding {
PRKeys.Ready,
PRKeys.Reopen,
PRKeys.Merge,
PRKeys.Update,
PRKeys.WatchChecks,
PRKeys.ViewIssues,
}
Expand Down Expand Up @@ -123,6 +129,8 @@ func rebindPRKeys(keys []config.Keybinding) error {
key = &PRKeys.Reopen
case "merge":
key = &PRKeys.Merge
case "update":
key = &PRKeys.Update
case "watchChecks":
key = &PRKeys.WatchChecks
case "viewIssues":
Expand Down
5 changes: 4 additions & 1 deletion ui/theme/theme.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Theme struct {
InvertedText lipgloss.AdaptiveColor // config.Theme.Colors.Text.Inverted
SuccessText lipgloss.AdaptiveColor // config.Theme.Colors.Text.Success
WarningText lipgloss.AdaptiveColor // config.Theme.Colors.Text.Warning
ErrorText lipgloss.AdaptiveColor // config.Theme.Colors.Text.Error
}

var DefaultTheme = &Theme{
Expand All @@ -29,7 +30,8 @@ var DefaultTheme = &Theme{
FaintText: lipgloss.AdaptiveColor{Light: "007", Dark: "245"},
InvertedText: lipgloss.AdaptiveColor{Light: "015", Dark: "236"},
SuccessText: lipgloss.AdaptiveColor{Light: "002", Dark: "002"},
WarningText: lipgloss.AdaptiveColor{Light: "001", Dark: "001"},
WarningText: lipgloss.AdaptiveColor{Light: "003", Dark: "003"},
ErrorText: lipgloss.AdaptiveColor{Light: "001", Dark: "001"},
}

func ParseTheme(cfg *config.Config) Theme {
Expand Down Expand Up @@ -57,6 +59,7 @@ func ParseTheme(cfg *config.Config) Theme {
InvertedText: _shimHex(cfg.Theme.Colors.Inline.Text.Inverted),
SuccessText: _shimHex(cfg.Theme.Colors.Inline.Text.Success),
WarningText: _shimHex(cfg.Theme.Colors.Inline.Text.Warning),
ErrorText: _shimHex(cfg.Theme.Colors.Inline.Text.Error),
}
}

Expand Down
7 changes: 7 additions & 0 deletions ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
return m, cmd

case key.Matches(msg, keys.PRKeys.Update):
if currSection != nil {
currSection.SetPromptConfirmationAction("update")
cmd = currSection.SetIsPromptConfirmationShown(true)
}
return m, cmd

case key.Matches(msg, keys.PRKeys.ViewIssues):
m.ctx.View = m.switchSelectedView()
m.syncMainContentWidth()
Expand Down

0 comments on commit 08e5576

Please sign in to comment.