2025-12-08 09:49:07 +01:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
"net/http"
|
|
|
|
|
"os/exec"
|
2025-12-08 09:49:07 +01:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"code.gitea.io/sdk/gitea"
|
2026-04-26 08:16:52 -06:00
|
|
|
"forgejo.zerova.net/public/fj/internal/api"
|
|
|
|
|
"forgejo.zerova.net/public/fj/internal/config"
|
|
|
|
|
gitpkg "forgejo.zerova.net/public/fj/internal/git"
|
|
|
|
|
"forgejo.zerova.net/public/fj/internal/text"
|
2026-01-18 11:48:08 +01:00
|
|
|
"github.com/spf13/cobra"
|
2025-12-08 09:49:07 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var prCmd = &cobra.Command{
|
|
|
|
|
Use: "pr",
|
|
|
|
|
Aliases: []string{"pull-request"},
|
|
|
|
|
Short: "Manage pull requests",
|
|
|
|
|
Long: "Create, view, list, and manage pull requests.",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prListCmd = &cobra.Command{
|
|
|
|
|
Use: "list [flags]",
|
|
|
|
|
Short: "List pull requests",
|
|
|
|
|
Long: "List pull requests in a repository.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # List open pull requests
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr list
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# List all pull requests for a specific repo
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr list -s all -R owner/repo
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Output as JSON
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr list --json`,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
RunE: runPRList,
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prViewCmd = &cobra.Command{
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Use: "view [<number>]",
|
2025-12-08 09:49:07 +01:00
|
|
|
Short: "View a pull request",
|
|
|
|
|
Long: "Display detailed information about a pull request.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # View pull request #5
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr view 5
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# View using URL
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr view https://codeberg.org/owner/repo/pulls/5
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# View PR for current branch
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr view
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Open in browser
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr view 5 --web
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# View as JSON
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr view 5 --json`,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Args: cobra.MaximumNArgs(1),
|
|
|
|
|
RunE: runPRView,
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prCreateCmd = &cobra.Command{
|
|
|
|
|
Use: "create",
|
|
|
|
|
Short: "Create a pull request",
|
|
|
|
|
Long: "Create a new pull request.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # Create a pull request from feature branch to main
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr create -t "Add login page" -H feature/login
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Create with body and custom base branch
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr create -t "Fix bug" -b "Closes #42" -H fix/bug -B develop
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Create and self-assign
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr create -t "Update docs" -H docs/update -a @me`,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
RunE: runPRCreate,
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prMergeCmd = &cobra.Command{
|
|
|
|
|
Use: "merge <number>",
|
|
|
|
|
Short: "Merge a pull request",
|
|
|
|
|
Long: "Merge a pull request.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # Merge pull request #5
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr merge 5
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Squash merge
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr merge 5 --merge-method squash
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Rebase merge
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr merge 5 --merge-method rebase
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Merge without confirmation
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr merge 5 -y`,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Args: cobra.ExactArgs(1),
|
|
|
|
|
RunE: runPRMerge,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prCloseCmd = &cobra.Command{
|
|
|
|
|
Use: "close <number>",
|
|
|
|
|
Short: "Close a pull request",
|
|
|
|
|
Long: "Close a pull request without merging.",
|
|
|
|
|
Example: ` # Close PR #5
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr close 5
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Close with a comment
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr close 5 -c "Won't merge, superseded by #10"`,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Args: cobra.ExactArgs(1),
|
|
|
|
|
RunE: runPRClose,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prReopenCmd = &cobra.Command{
|
|
|
|
|
Use: "reopen <number>",
|
|
|
|
|
Short: "Reopen a pull request",
|
|
|
|
|
Long: "Reopen a closed pull request.",
|
|
|
|
|
Example: ` # Reopen PR #5
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr reopen 5`,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Args: cobra.ExactArgs(1),
|
|
|
|
|
RunE: runPRReopen,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prEditCmd = &cobra.Command{
|
|
|
|
|
Use: "edit <number>",
|
|
|
|
|
Short: "Edit a pull request",
|
|
|
|
|
Long: "Edit a pull request's title, body, or metadata.",
|
|
|
|
|
Example: ` # Update the title of PR #5
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr edit 5 -t "Updated title"
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Add assignees and labels
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr edit 5 --add-assignee user1 --add-label bug
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
|
|
|
|
|
# Remove a reviewer and set milestone
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr edit 5 --remove-reviewer user2 --milestone "v1.0"`,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Args: cobra.ExactArgs(1),
|
|
|
|
|
RunE: runPREdit,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prCheckoutCmd = &cobra.Command{
|
|
|
|
|
Use: "checkout <number>",
|
|
|
|
|
Short: "Check out a pull request locally",
|
|
|
|
|
Long: "Check out the head branch of a pull request.",
|
|
|
|
|
Example: ` # Check out PR #5
|
2026-04-26 08:16:52 -06:00
|
|
|
fj pr checkout 5`,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Args: cobra.ExactArgs(1),
|
|
|
|
|
RunE: runPRCheckout,
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
rootCmd.AddCommand(prCmd)
|
|
|
|
|
prCmd.AddCommand(prListCmd)
|
|
|
|
|
prCmd.AddCommand(prViewCmd)
|
|
|
|
|
prCmd.AddCommand(prCreateCmd)
|
|
|
|
|
prCmd.AddCommand(prMergeCmd)
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
prCmd.AddCommand(prCloseCmd)
|
|
|
|
|
prCmd.AddCommand(prReopenCmd)
|
|
|
|
|
prCmd.AddCommand(prEditCmd)
|
|
|
|
|
prCmd.AddCommand(prCheckoutCmd)
|
|
|
|
|
|
|
|
|
|
prCloseCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
prCloseCmd.Flags().StringP("comment", "c", "", "Comment body to add before closing")
|
|
|
|
|
|
|
|
|
|
prReopenCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
2025-12-08 09:49:07 +01:00
|
|
|
|
|
|
|
|
prListCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
prListCmd.Flags().StringP("state", "s", "open", "Filter by state: open, closed, all")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
prListCmd.Flags().IntP("limit", "L", 30, "Maximum number of results")
|
|
|
|
|
prListCmd.Flags().StringP("assignee", "a", "", "Filter by assignee username")
|
|
|
|
|
prListCmd.Flags().String("author", "", "Filter by author username")
|
|
|
|
|
prListCmd.Flags().StringSliceP("label", "l", nil, "Filter by label names")
|
|
|
|
|
prListCmd.Flags().StringP("search", "S", "", "Search keyword filter")
|
|
|
|
|
prListCmd.Flags().Bool("draft", false, "Filter by draft status")
|
|
|
|
|
prListCmd.Flags().String("head", "", "Filter by head branch")
|
|
|
|
|
prListCmd.Flags().String("base", "", "Filter by base branch")
|
|
|
|
|
prListCmd.Flags().BoolP("web", "w", false, "Open list in web browser")
|
|
|
|
|
addJSONFlags(prListCmd, "Output pull requests as JSON")
|
2025-12-08 09:49:07 +01:00
|
|
|
|
|
|
|
|
prViewCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
addJSONFlags(prViewCmd, "Output pull request as JSON")
|
|
|
|
|
prViewCmd.Flags().BoolP("web", "w", false, "Open in web browser")
|
2025-12-08 09:49:07 +01:00
|
|
|
|
|
|
|
|
prCreateCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
prCreateCmd.Flags().StringP("title", "t", "", "Title for the pull request")
|
|
|
|
|
prCreateCmd.Flags().StringP("body", "b", "", "Body for the pull request")
|
|
|
|
|
prCreateCmd.Flags().StringP("head", "H", "", "Head branch")
|
|
|
|
|
prCreateCmd.Flags().StringP("base", "B", "", "Base branch (default: main)")
|
2025-12-24 10:15:50 +01:00
|
|
|
prCreateCmd.Flags().StringSliceP("assignee", "a", []string{}, "Assign people by their login. Use \"@me\" to self-assign.")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
prCreateCmd.Flags().BoolP("draft", "d", false, "Create as draft pull request")
|
|
|
|
|
prCreateCmd.Flags().StringSliceP("reviewer", "r", nil, "Request reviewers by username")
|
|
|
|
|
prCreateCmd.Flags().StringSliceP("label", "l", nil, "Add labels by name")
|
|
|
|
|
prCreateCmd.Flags().StringP("milestone", "m", "", "Set milestone by name")
|
2025-12-08 09:49:07 +01:00
|
|
|
|
|
|
|
|
prMergeCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
prMergeCmd.Flags().String("merge-method", "merge", "Merge method: merge, rebase, squash")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
prMergeCmd.Flags().BoolP("yes", "y", false, "Skip confirmation prompt")
|
|
|
|
|
prMergeCmd.Flags().BoolP("delete-branch", "d", false, "Delete the branch after merge")
|
|
|
|
|
prMergeCmd.Flags().Bool("auto", false, "Merge automatically when checks succeed")
|
|
|
|
|
|
|
|
|
|
prCheckoutCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
|
|
|
|
|
prEditCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
prEditCmd.Flags().StringP("title", "t", "", "New title for the pull request")
|
|
|
|
|
prEditCmd.Flags().StringP("body", "b", "", "New body for the pull request")
|
|
|
|
|
prEditCmd.Flags().StringP("base", "B", "", "New base branch for the pull request")
|
|
|
|
|
prEditCmd.Flags().StringSlice("add-assignee", nil, "Assignees to add (login names)")
|
|
|
|
|
prEditCmd.Flags().StringSlice("remove-assignee", nil, "Assignees to remove (login names)")
|
|
|
|
|
prEditCmd.Flags().StringSlice("add-label", nil, "Labels to add (by name)")
|
|
|
|
|
prEditCmd.Flags().StringSlice("remove-label", nil, "Labels to remove (by name)")
|
|
|
|
|
prEditCmd.Flags().StringSlice("add-reviewer", nil, "Reviewers to add (login names)")
|
|
|
|
|
prEditCmd.Flags().StringSlice("remove-reviewer", nil, "Reviewers to remove (login names)")
|
|
|
|
|
prEditCmd.Flags().String("milestone", "", "Milestone name to set (empty string to clear)")
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runPRList(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
state, _ := cmd.Flags().GetString("state")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
limit, _ := cmd.Flags().GetInt("limit")
|
|
|
|
|
assignee, _ := cmd.Flags().GetString("assignee")
|
|
|
|
|
author, _ := cmd.Flags().GetString("author")
|
|
|
|
|
labels, _ := cmd.Flags().GetStringSlice("label")
|
|
|
|
|
search, _ := cmd.Flags().GetString("search")
|
|
|
|
|
draft, _ := cmd.Flags().GetBool("draft")
|
|
|
|
|
head, _ := cmd.Flags().GetString("head")
|
|
|
|
|
base, _ := cmd.Flags().GetString("base")
|
2025-12-08 09:49:07 +01:00
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 12:39:51 -06:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
2025-12-08 09:49:07 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if web, _ := cmd.Flags().GetBool("web"); web {
|
|
|
|
|
return ios.OpenInBrowser(fmt.Sprintf("https://%s/%s/%s/pulls", client.Hostname(), owner, name))
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-08 09:49:07 +01:00
|
|
|
var stateType gitea.StateType
|
|
|
|
|
switch strings.ToLower(state) {
|
|
|
|
|
case "open":
|
|
|
|
|
stateType = gitea.StateOpen
|
|
|
|
|
case "closed":
|
|
|
|
|
stateType = gitea.StateClosed
|
|
|
|
|
case "all":
|
|
|
|
|
stateType = gitea.StateAll
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("invalid state: %s", state)
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
needsClientFilter := assignee != "" || author != "" || len(labels) > 0 || search != "" || draft || head != "" || base != ""
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Fetching pull requests...")
|
|
|
|
|
var prs []*gitea.PullRequest
|
|
|
|
|
if needsClientFilter {
|
|
|
|
|
page := 1
|
|
|
|
|
for {
|
|
|
|
|
batch, _, err := client.ListRepoPullRequests(owner, name, gitea.ListPullRequestsOptions{
|
|
|
|
|
State: stateType,
|
|
|
|
|
ListOptions: gitea.ListOptions{Page: page, PageSize: 50},
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to list pull requests: %w", err)
|
|
|
|
|
}
|
|
|
|
|
prs = append(prs, batch...)
|
|
|
|
|
if len(batch) < 50 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
page++
|
|
|
|
|
}
|
|
|
|
|
prs = filterPRs(prs, author, assignee, labels, search, draft, head, base)
|
|
|
|
|
if len(prs) > limit {
|
|
|
|
|
prs = prs[:limit]
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
prs, _, err = client.ListRepoPullRequests(owner, name, gitea.ListPullRequestsOptions{
|
|
|
|
|
State: stateType,
|
|
|
|
|
ListOptions: gitea.ListOptions{PageSize: limit},
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to list pull requests: %w", err)
|
|
|
|
|
}
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2025-12-08 09:49:07 +01:00
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if wantJSON(cmd) {
|
|
|
|
|
return outputJSON(cmd, prs)
|
2026-01-18 11:48:08 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-08 09:49:07 +01:00
|
|
|
if len(prs) == 0 {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "No %s pull requests in %s/%s\n", state, owner, name)
|
2025-12-08 09:49:07 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
tp := ios.NewTablePrinter()
|
|
|
|
|
tp.AddHeader("NUMBER", "TITLE", "BRANCH", "STATE")
|
2025-12-08 09:49:07 +01:00
|
|
|
for _, pr := range prs {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
tp.AddRow(fmt.Sprintf("#%d", pr.Index), pr.Title, pr.Head.Ref, string(pr.State))
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
return tp.Render()
|
|
|
|
|
}
|
2025-12-08 09:49:07 +01:00
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
func filterPRs(prs []*gitea.PullRequest, author, assignee string, labels []string, search string, draft bool, head, base string) []*gitea.PullRequest {
|
|
|
|
|
var result []*gitea.PullRequest
|
|
|
|
|
for _, pr := range prs {
|
|
|
|
|
if author != "" && !strings.EqualFold(pr.Poster.UserName, author) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if assignee != "" {
|
|
|
|
|
found := false
|
|
|
|
|
for _, a := range pr.Assignees {
|
|
|
|
|
if strings.EqualFold(a.UserName, assignee) {
|
|
|
|
|
found = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if len(labels) > 0 {
|
|
|
|
|
prLabelNames := make(map[string]bool)
|
|
|
|
|
for _, l := range pr.Labels {
|
|
|
|
|
prLabelNames[strings.ToLower(l.Name)] = true
|
|
|
|
|
}
|
|
|
|
|
allFound := true
|
|
|
|
|
for _, label := range labels {
|
|
|
|
|
if !prLabelNames[strings.ToLower(label)] {
|
|
|
|
|
allFound = false
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !allFound {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if search != "" && !strings.Contains(strings.ToLower(pr.Title), strings.ToLower(search)) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if draft && !pr.Draft {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if head != "" && !strings.EqualFold(pr.Head.Ref, head) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if base != "" && !strings.EqualFold(pr.Base.Ref, base) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
result = append(result, pr)
|
|
|
|
|
}
|
|
|
|
|
return result
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runPRView(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 12:39:51 -06:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
2025-12-08 09:49:07 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
var prNumber int64
|
|
|
|
|
if len(args) == 0 {
|
|
|
|
|
// Try to find PR for current branch
|
|
|
|
|
branch, branchErr := gitpkg.GetCurrentBranch()
|
|
|
|
|
if branchErr != nil {
|
|
|
|
|
return fmt.Errorf("no pull request number specified and could not detect current branch: %w", branchErr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Finding pull request for branch...")
|
|
|
|
|
prs, _, listErr := client.ListRepoPullRequests(owner, name, gitea.ListPullRequestsOptions{
|
|
|
|
|
State: gitea.StateOpen,
|
|
|
|
|
})
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
if listErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to list pull requests: %w", listErr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var found bool
|
|
|
|
|
for _, pr := range prs {
|
|
|
|
|
if pr.Head.Ref == branch {
|
|
|
|
|
prNumber = pr.Index
|
|
|
|
|
found = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
return fmt.Errorf("no open pull request found for branch %q", branch)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
prNumber, err = parseIssueArg(args[0])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("invalid pull request number: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Fetching pull request...")
|
2025-12-08 09:49:07 +01:00
|
|
|
pr, _, err := client.GetPullRequest(owner, name, prNumber)
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2025-12-08 09:49:07 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to get pull request: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if web, _ := cmd.Flags().GetBool("web"); web {
|
|
|
|
|
return ios.OpenInBrowser(pr.HTMLURL)
|
2026-01-18 11:48:08 +01:00
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if wantJSON(cmd) {
|
|
|
|
|
return outputJSON(cmd, pr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := ios.StartPager(); err != nil {
|
|
|
|
|
fmt.Fprintf(ios.ErrOut, "warning: failed to start pager: %v\n", err)
|
|
|
|
|
}
|
|
|
|
|
defer ios.StopPager()
|
|
|
|
|
|
|
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
isTTY := ios.IsStdoutTTY()
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Pull Request #%d\n", cs.Bold(""), pr.Index)
|
|
|
|
|
fmt.Fprintf(ios.Out, "Title: %s\n", cs.Bold(pr.Title))
|
|
|
|
|
fmt.Fprintf(ios.Out, "State: %s\n", pr.State)
|
|
|
|
|
fmt.Fprintf(ios.Out, "Author: %s\n", pr.Poster.UserName)
|
|
|
|
|
fmt.Fprintf(ios.Out, "Branch: %s -> %s\n", pr.Head.Ref, pr.Base.Ref)
|
|
|
|
|
if pr.Created != nil {
|
|
|
|
|
fmt.Fprintf(ios.Out, "Created: %s\n", text.FormatDate(*pr.Created, isTTY))
|
|
|
|
|
}
|
|
|
|
|
if pr.Updated != nil {
|
|
|
|
|
fmt.Fprintf(ios.Out, "Updated: %s\n", text.FormatDate(*pr.Updated, isTTY))
|
|
|
|
|
}
|
2025-12-08 09:49:07 +01:00
|
|
|
if pr.Body != "" {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "\n%s\n", pr.Body)
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runPRCreate(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
title, _ := cmd.Flags().GetString("title")
|
|
|
|
|
body, _ := cmd.Flags().GetString("body")
|
|
|
|
|
head, _ := cmd.Flags().GetString("head")
|
|
|
|
|
base, _ := cmd.Flags().GetString("base")
|
2025-12-24 10:15:50 +01:00
|
|
|
assignees, _ := cmd.Flags().GetStringSlice("assignee")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
draft, _ := cmd.Flags().GetBool("draft")
|
|
|
|
|
reviewers, _ := cmd.Flags().GetStringSlice("reviewer")
|
|
|
|
|
labelNames, _ := cmd.Flags().GetStringSlice("label")
|
|
|
|
|
milestoneName, _ := cmd.Flags().GetString("milestone")
|
2025-12-08 09:49:07 +01:00
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
// Interactive mode: prompt for missing fields when TTY
|
|
|
|
|
if title == "" && ios.IsStdinTTY() {
|
|
|
|
|
title, err = promptLine("Title: ")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if title == "" {
|
|
|
|
|
return fmt.Errorf("title is required")
|
|
|
|
|
}
|
|
|
|
|
} else if title == "" {
|
|
|
|
|
return fmt.Errorf("title is required (use -t flag)")
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if head == "" && ios.IsStdinTTY() {
|
|
|
|
|
// Default to current branch
|
|
|
|
|
branch, branchErr := gitpkg.GetCurrentBranch()
|
|
|
|
|
if branchErr == nil {
|
|
|
|
|
head = branch
|
|
|
|
|
fmt.Fprintf(ios.ErrOut, "Using current branch %q as head\n", head)
|
|
|
|
|
} else {
|
|
|
|
|
head, err = promptLine("Head branch: ")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-08 09:49:07 +01:00
|
|
|
if head == "" {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
return fmt.Errorf("head branch is required (use -H flag)")
|
2025-12-08 09:49:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 12:39:51 -06:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
2025-12-08 09:49:07 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if base == "" {
|
|
|
|
|
ios.StartSpinner("Fetching repository info...")
|
|
|
|
|
repoInfo, _, err := client.GetRepo(owner, name)
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to get repository info: %w", err)
|
|
|
|
|
}
|
|
|
|
|
base = repoInfo.DefaultBranch
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-24 10:15:50 +01:00
|
|
|
// Resolve @me in assignees
|
|
|
|
|
resolvedAssignees := make([]string, 0, len(assignees))
|
|
|
|
|
for _, assignee := range assignees {
|
|
|
|
|
if assignee == "@me" {
|
|
|
|
|
user, _, err := client.GetMyUserInfo()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to get current user info: %w", err)
|
|
|
|
|
}
|
|
|
|
|
resolvedAssignees = append(resolvedAssignees, user.UserName)
|
|
|
|
|
} else {
|
|
|
|
|
resolvedAssignees = append(resolvedAssignees, assignee)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
// Resolve label names to IDs
|
|
|
|
|
var labelIDs []int64
|
|
|
|
|
if len(labelNames) > 0 {
|
|
|
|
|
labelIDs, err = resolveLabelIDs(client, owner, name, labelNames)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolve milestone name to ID
|
|
|
|
|
var milestoneID int64
|
|
|
|
|
if milestoneName != "" {
|
|
|
|
|
milestones, _, msErr := client.ListRepoMilestones(owner, name, gitea.ListMilestoneOption{})
|
|
|
|
|
if msErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to list milestones: %w", msErr)
|
|
|
|
|
}
|
|
|
|
|
found := false
|
|
|
|
|
for _, ms := range milestones {
|
|
|
|
|
if ms.Title == milestoneName {
|
|
|
|
|
milestoneID = ms.ID
|
|
|
|
|
found = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
return fmt.Errorf("milestone not found: %s", milestoneName)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Creating pull request...")
|
2025-12-08 09:49:07 +01:00
|
|
|
pr, _, err := client.CreatePullRequest(owner, name, gitea.CreatePullRequestOption{
|
2025-12-24 10:15:50 +01:00
|
|
|
Title: title,
|
|
|
|
|
Body: body,
|
|
|
|
|
Head: head,
|
|
|
|
|
Base: base,
|
|
|
|
|
Assignees: resolvedAssignees,
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Reviewers: reviewers,
|
|
|
|
|
Labels: labelIDs,
|
|
|
|
|
Milestone: milestoneID,
|
2025-12-08 09:49:07 +01:00
|
|
|
})
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2025-12-08 09:49:07 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to create pull request: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
// Set draft status via raw API if needed
|
|
|
|
|
if draft {
|
|
|
|
|
_, draftErr := client.DoJSON("PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d", owner, name, pr.Index), map[string]any{"draft": true}, nil)
|
|
|
|
|
if draftErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to set pull request as draft: %w", draftErr)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Pull request created: #%d\n", cs.SuccessIcon(), pr.Index)
|
|
|
|
|
fmt.Fprintf(ios.Out, "View at: %s\n", pr.HTMLURL)
|
2025-12-08 09:49:07 +01:00
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runPRMerge(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
mergeMethod, _ := cmd.Flags().GetString("merge-method")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
yes, _ := cmd.Flags().GetBool("yes")
|
|
|
|
|
deleteBranch, _ := cmd.Flags().GetBool("delete-branch")
|
|
|
|
|
autoMerge, _ := cmd.Flags().GetBool("auto")
|
|
|
|
|
|
|
|
|
|
prNumber, err := parseIssueArg(args[0])
|
2025-12-08 09:49:07 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("invalid pull request number: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 12:39:51 -06:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
2025-12-08 09:49:07 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var method gitea.MergeStyle
|
|
|
|
|
switch strings.ToLower(mergeMethod) {
|
|
|
|
|
case "merge":
|
|
|
|
|
method = gitea.MergeStyleMerge
|
|
|
|
|
case "rebase":
|
|
|
|
|
method = gitea.MergeStyleRebase
|
|
|
|
|
case "squash":
|
|
|
|
|
method = gitea.MergeStyleSquash
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("invalid merge method: %s", mergeMethod)
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if !yes {
|
|
|
|
|
confirmed, err := ios.ConfirmAction(fmt.Sprintf("Merge pull request #%d via %s?", prNumber, mergeMethod))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if !confirmed {
|
|
|
|
|
fmt.Fprintln(ios.ErrOut, "Aborted")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Merging pull request...")
|
2025-12-08 09:49:07 +01:00
|
|
|
_, _, err = client.MergePullRequest(owner, name, prNumber, gitea.MergePullRequestOption{
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Style: method,
|
|
|
|
|
DeleteBranchAfterMerge: deleteBranch,
|
|
|
|
|
MergeWhenChecksSucceed: autoMerge,
|
2025-12-08 09:49:07 +01:00
|
|
|
})
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2025-12-08 09:49:07 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to merge pull request: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
if autoMerge {
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Auto-merge enabled for PR #%d\n", cs.SuccessIcon(), prNumber)
|
|
|
|
|
} else {
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Pull request #%d merged successfully\n", cs.SuccessIcon(), prNumber)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runPRClose(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
commentBody, _ := cmd.Flags().GetString("comment")
|
|
|
|
|
prNumber, err := parseIssueArg(args[0])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("invalid pull request number: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 12:39:51 -06:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if commentBody != "" {
|
|
|
|
|
ios.StartSpinner("Adding comment...")
|
|
|
|
|
_, _, err = client.CreateIssueComment(owner, name, prNumber, gitea.CreateIssueCommentOption{
|
|
|
|
|
Body: commentBody,
|
|
|
|
|
})
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to create comment: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Closing pull request...")
|
|
|
|
|
stateClosed := gitea.StateClosed
|
|
|
|
|
_, _, err = client.EditPullRequest(owner, name, prNumber, gitea.EditPullRequestOption{
|
|
|
|
|
State: &stateClosed,
|
|
|
|
|
})
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to close pull request: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Pull request #%d closed\n", cs.SuccessIcon(), prNumber)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runPRReopen(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
prNumber, err := parseIssueArg(args[0])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("invalid pull request number: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 12:39:51 -06:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Reopening pull request...")
|
|
|
|
|
stateOpen := gitea.StateOpen
|
|
|
|
|
_, _, err = client.EditPullRequest(owner, name, prNumber, gitea.EditPullRequestOption{
|
|
|
|
|
State: &stateOpen,
|
|
|
|
|
})
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to reopen pull request: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Pull request #%d reopened\n", cs.SuccessIcon(), prNumber)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runPRCheckout(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
|
|
|
|
|
prNumber, err := parseIssueArg(args[0])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("invalid pull request number: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 12:39:51 -06:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Fetching pull request...")
|
|
|
|
|
pr, _, err := client.GetPullRequest(owner, name, prNumber)
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to get pull request: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
headBranch := pr.Head.Ref
|
|
|
|
|
headRepo := pr.Head.Repository
|
|
|
|
|
|
|
|
|
|
// Determine if same-repo or cross-repo PR
|
|
|
|
|
isSameRepo := headRepo == nil || headRepo.FullName == fmt.Sprintf("%s/%s", owner, name)
|
|
|
|
|
|
|
|
|
|
if isSameRepo {
|
|
|
|
|
// Same repo: fetch and checkout
|
|
|
|
|
ios.StartSpinner("Checking out branch...")
|
|
|
|
|
|
|
|
|
|
gitFetch := exec.Command("git", "fetch", "origin", headBranch)
|
|
|
|
|
gitFetch.Stdout = ios.Out
|
|
|
|
|
gitFetch.Stderr = ios.ErrOut
|
|
|
|
|
if err := gitFetch.Run(); err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to fetch branch: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Try to checkout existing branch first
|
|
|
|
|
gitCheckout := exec.Command("git", "checkout", headBranch)
|
|
|
|
|
gitCheckout.Stdout = ios.Out
|
|
|
|
|
gitCheckout.Stderr = ios.ErrOut
|
|
|
|
|
if err := gitCheckout.Run(); err != nil {
|
|
|
|
|
// Branch doesn't exist locally, create it tracking remote
|
|
|
|
|
gitCheckout = exec.Command("git", "checkout", "-b", headBranch, "origin/"+headBranch)
|
|
|
|
|
gitCheckout.Stdout = ios.Out
|
|
|
|
|
gitCheckout.Stderr = ios.ErrOut
|
|
|
|
|
if err := gitCheckout.Run(); err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to checkout branch: %w", err)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Branch existed, pull latest
|
|
|
|
|
gitPull := exec.Command("git", "pull")
|
|
|
|
|
gitPull.Stdout = ios.Out
|
|
|
|
|
gitPull.Stderr = ios.ErrOut
|
|
|
|
|
_ = gitPull.Run()
|
|
|
|
|
}
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
} else {
|
|
|
|
|
// Cross-repo (fork): add remote and checkout
|
|
|
|
|
forkOwner := headRepo.Owner.UserName
|
|
|
|
|
forkCloneURL := headRepo.CloneURL
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Checking out branch from fork...")
|
|
|
|
|
|
|
|
|
|
// Add fork as remote (ignore error if already exists)
|
|
|
|
|
gitRemoteAdd := exec.Command("git", "remote", "add", forkOwner, forkCloneURL)
|
|
|
|
|
gitRemoteAdd.Stdout = ios.Out
|
|
|
|
|
gitRemoteAdd.Stderr = ios.ErrOut
|
|
|
|
|
_ = gitRemoteAdd.Run() // ignore error if remote already exists
|
|
|
|
|
|
|
|
|
|
// Fetch from fork
|
|
|
|
|
gitFetch := exec.Command("git", "fetch", forkOwner)
|
|
|
|
|
gitFetch.Stdout = ios.Out
|
|
|
|
|
gitFetch.Stderr = ios.ErrOut
|
|
|
|
|
if err := gitFetch.Run(); err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to fetch from fork: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Checkout the branch
|
|
|
|
|
gitCheckout := exec.Command("git", "checkout", "-b", headBranch, forkOwner+"/"+headBranch)
|
|
|
|
|
gitCheckout.Stdout = ios.Out
|
|
|
|
|
gitCheckout.Stderr = ios.ErrOut
|
|
|
|
|
if err := gitCheckout.Run(); err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to checkout branch: %w", err)
|
|
|
|
|
}
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Checked out PR #%d on branch %q\n", cs.SuccessIcon(), prNumber, headBranch)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runPREdit(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
prNumber, err := parseIssueArg(args[0])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("invalid pull request number: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check that at least one flag was provided
|
|
|
|
|
anyChanged := false
|
|
|
|
|
for _, flag := range []string{"title", "body", "base", "add-assignee", "remove-assignee",
|
|
|
|
|
"add-label", "remove-label", "add-reviewer", "remove-reviewer", "milestone"} {
|
|
|
|
|
if cmd.Flags().Changed(flag) {
|
|
|
|
|
anyChanged = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !anyChanged {
|
|
|
|
|
return fmt.Errorf("at least one of --title, --body, --base, --add-assignee, --remove-assignee, " +
|
|
|
|
|
"--add-label, --remove-label, --add-reviewer, --remove-reviewer, or --milestone must be provided")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 12:39:51 -06:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build EditPullRequestOption from changed flags
|
|
|
|
|
editOpt := gitea.EditPullRequestOption{}
|
|
|
|
|
needsEditCall := false
|
|
|
|
|
|
|
|
|
|
if cmd.Flags().Changed("title") {
|
|
|
|
|
title, _ := cmd.Flags().GetString("title")
|
|
|
|
|
editOpt.Title = title
|
|
|
|
|
needsEditCall = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if cmd.Flags().Changed("body") {
|
|
|
|
|
body, _ := cmd.Flags().GetString("body")
|
|
|
|
|
editOpt.Body = &body
|
|
|
|
|
needsEditCall = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if cmd.Flags().Changed("base") {
|
|
|
|
|
base, _ := cmd.Flags().GetString("base")
|
|
|
|
|
editOpt.Base = base
|
|
|
|
|
needsEditCall = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle milestone
|
|
|
|
|
if cmd.Flags().Changed("milestone") {
|
|
|
|
|
milestoneName, _ := cmd.Flags().GetString("milestone")
|
|
|
|
|
if milestoneName == "" {
|
|
|
|
|
// Clear milestone by setting to 0
|
|
|
|
|
editOpt.Milestone = 0
|
|
|
|
|
} else {
|
|
|
|
|
milestones, _, msErr := client.ListRepoMilestones(owner, name, gitea.ListMilestoneOption{})
|
|
|
|
|
if msErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to list milestones: %w", msErr)
|
|
|
|
|
}
|
|
|
|
|
var milestoneID int64
|
|
|
|
|
for _, ms := range milestones {
|
|
|
|
|
if ms.Title == milestoneName {
|
|
|
|
|
milestoneID = ms.ID
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if milestoneID == 0 {
|
|
|
|
|
return fmt.Errorf("milestone not found: %s", milestoneName)
|
|
|
|
|
}
|
|
|
|
|
editOpt.Milestone = milestoneID
|
|
|
|
|
}
|
|
|
|
|
needsEditCall = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle assignees (add/remove requires fetching current PR)
|
|
|
|
|
addAssignees, _ := cmd.Flags().GetStringSlice("add-assignee")
|
|
|
|
|
removeAssignees, _ := cmd.Flags().GetStringSlice("remove-assignee")
|
|
|
|
|
|
|
|
|
|
if len(addAssignees) > 0 || len(removeAssignees) > 0 {
|
|
|
|
|
ios.StartSpinner("Fetching pull request...")
|
|
|
|
|
pr, _, prErr := client.GetPullRequest(owner, name, prNumber)
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
if prErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to get pull request: %w", prErr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build current assignee set
|
|
|
|
|
assigneeSet := make(map[string]bool)
|
|
|
|
|
for _, a := range pr.Assignees {
|
|
|
|
|
assigneeSet[a.UserName] = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add new assignees
|
|
|
|
|
for _, a := range addAssignees {
|
|
|
|
|
assigneeSet[a] = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove assignees
|
|
|
|
|
for _, a := range removeAssignees {
|
|
|
|
|
delete(assigneeSet, a)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert back to slice
|
|
|
|
|
newAssignees := make([]string, 0, len(assigneeSet))
|
|
|
|
|
for a := range assigneeSet {
|
|
|
|
|
newAssignees = append(newAssignees, a)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
editOpt.Assignees = newAssignees
|
|
|
|
|
needsEditCall = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Updating pull request...")
|
|
|
|
|
|
|
|
|
|
// Perform the edit API call if needed
|
|
|
|
|
if needsEditCall {
|
|
|
|
|
_, _, err = client.EditPullRequest(owner, name, prNumber, editOpt)
|
|
|
|
|
if err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to edit pull request: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle labels
|
|
|
|
|
addLabelNames, _ := cmd.Flags().GetStringSlice("add-label")
|
|
|
|
|
removeLabelNames, _ := cmd.Flags().GetStringSlice("remove-label")
|
|
|
|
|
|
|
|
|
|
if len(addLabelNames) > 0 {
|
|
|
|
|
labelIDs, labelErr := resolveLabelIDs(client, owner, name, addLabelNames)
|
|
|
|
|
if labelErr != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return labelErr
|
|
|
|
|
}
|
|
|
|
|
_, _, err = client.AddIssueLabels(owner, name, prNumber, gitea.IssueLabelsOption{
|
|
|
|
|
Labels: labelIDs,
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to add labels: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(removeLabelNames) > 0 {
|
|
|
|
|
labelIDs, labelErr := resolveLabelIDs(client, owner, name, removeLabelNames)
|
|
|
|
|
if labelErr != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return labelErr
|
|
|
|
|
}
|
|
|
|
|
for _, labelID := range labelIDs {
|
|
|
|
|
_, err = client.DeleteIssueLabel(owner, name, prNumber, labelID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to remove label %d: %w", labelID, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle reviewers
|
|
|
|
|
addReviewers, _ := cmd.Flags().GetStringSlice("add-reviewer")
|
|
|
|
|
removeReviewers, _ := cmd.Flags().GetStringSlice("remove-reviewer")
|
|
|
|
|
|
|
|
|
|
if len(addReviewers) > 0 {
|
|
|
|
|
reviewerReq := map[string][]string{
|
|
|
|
|
"reviewers": addReviewers,
|
|
|
|
|
}
|
|
|
|
|
endpoint := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", owner, name, prNumber)
|
|
|
|
|
_, err := client.DoJSON(http.MethodPost, endpoint, reviewerReq, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to add reviewers: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(removeReviewers) > 0 {
|
|
|
|
|
reviewerReq := map[string][]string{
|
|
|
|
|
"reviewers": removeReviewers,
|
|
|
|
|
}
|
|
|
|
|
endpoint := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", owner, name, prNumber)
|
|
|
|
|
_, err := client.DoJSON(http.MethodDelete, endpoint, reviewerReq, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return fmt.Errorf("failed to remove reviewers: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
|
|
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Pull request #%d updated\n", cs.SuccessIcon(), prNumber)
|
2025-12-08 09:49:07 +01:00
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|