- fgj pr approve / pr reject: thin shortcuts over 'pr review --approve'
and '--request-changes'. Reject requires a body.
- fgj repo migrate: wrap SDK MigrateRepo. Supports git, github, gitlab,
gitea, gogs services; mirror mode with --mirror-interval; selective
import (wiki/labels/milestones/issues/PRs/releases/LFS); auth via
--auth-token or --auth-username/--auth-password. Defaults owner to
the authenticated user.
- fgj repo create-from-template: wrap SDK CreateRepoFromTemplate with
fine-grained --with-{content,topics,labels,webhooks,git-hooks,avatar}
flags. Template is owner/name; new repo defaults to the current user.
- Rework 'fgj actions secret create' input. New cmd/secret_input.go
resolves values from --body, --body-file (path or '-'), hidden TTY
prompt via term.ReadPassword, or piped stdin. Trims trailing
whitespace, rejects empty values. Replaces fmt.Scanln which broke on
spaces/newlines and echoed input.
- CHANGELOG: v0.4.0 Unreleased section documenting all additions,
changes, and development items.
- README: updated feature list with new commands.
102 lines
2.8 KiB
Go
102 lines
2.8 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
"forgejo.zerova.net/public/fgj-sid/internal/api"
|
|
"forgejo.zerova.net/public/fgj-sid/internal/config"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var prApproveCmd = &cobra.Command{
|
|
Use: "approve <number>",
|
|
Aliases: []string{"lgtm"},
|
|
Short: "Approve a pull request",
|
|
Long: "Shortcut for 'fgj pr review <n> --approve'. Body is optional.",
|
|
Example: ` # Approve with no body
|
|
fgj pr approve 42
|
|
|
|
# Approve with a message
|
|
fgj pr approve 42 -b "Thanks, shipping."`,
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: runPRApproveReject(gitea.ReviewStateApproved, "approved", false),
|
|
}
|
|
|
|
var prRejectCmd = &cobra.Command{
|
|
Use: "reject <number>",
|
|
Short: "Request changes on a pull request",
|
|
Long: "Shortcut for 'fgj pr review <n> --request-changes'. Body is required.",
|
|
Example: ` # Reject with explanation
|
|
fgj pr reject 42 -b "See the inline comments on auth.go"
|
|
|
|
# Reject with a longer message from a file
|
|
fgj pr reject 42 --body-file feedback.md`,
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: runPRApproveReject(gitea.ReviewStateRequestChanges, "reviewed with requested changes", true),
|
|
}
|
|
|
|
func init() {
|
|
prCmd.AddCommand(prApproveCmd)
|
|
prCmd.AddCommand(prRejectCmd)
|
|
|
|
for _, c := range []*cobra.Command{prApproveCmd, prRejectCmd} {
|
|
c.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
c.Flags().StringP("body", "b", "", "Review body/message")
|
|
c.Flags().String("body-file", "", "Read body from file (use \"-\" for stdin)")
|
|
addJSONFlags(c, "Output created review as JSON")
|
|
}
|
|
}
|
|
|
|
func runPRApproveReject(state gitea.ReviewStateType, verb string, requireBody bool) func(cmd *cobra.Command, args []string) error {
|
|
return func(cmd *cobra.Command, args []string) error {
|
|
prNumber, err := parseIssueArg(args[0])
|
|
if err != nil {
|
|
return fmt.Errorf("invalid pull request number: %w", err)
|
|
}
|
|
|
|
body, err := readBody(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if requireBody && body == "" {
|
|
return fmt.Errorf("a body is required (use --body or --body-file)")
|
|
}
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
owner, name, err := parseRepo(repo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cfg, err := config.Load()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ios.StartSpinner("Submitting review...")
|
|
review, _, err := client.CreatePullReview(owner, name, prNumber, gitea.CreatePullReviewOptions{
|
|
State: state,
|
|
Body: body,
|
|
})
|
|
ios.StopSpinner()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to submit review: %w", err)
|
|
}
|
|
|
|
if wantJSON(cmd) {
|
|
return outputJSON(cmd, review)
|
|
}
|
|
|
|
cs := ios.ColorScheme()
|
|
fmt.Fprintf(ios.Out, "%s PR #%d %s\n", cs.SuccessIcon(), prNumber, verb)
|
|
if review.HTMLURL != "" {
|
|
fmt.Fprintf(ios.Out, "View at: %s\n", review.HTMLURL)
|
|
}
|
|
return nil
|
|
}
|
|
}
|