mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
refactor(output): share the JSON, created-resource and batch tails
Mutations end with a.jsonResult or a.created instead of hand-rolled --json branches, the two identical jsonResult/writeMutationJSON helpers become one, and writeBatchJSON checks --json itself so batch commands share one tail. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
32 files changed
+85
-215
No files matched your search
@@ -617,11 +617,8 @@ $ tea run cancel 34 --force`,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, run)
|
||||
}
|
||||
a.done(cmd, "Requested cancellation of run %d", id)
|
||||
return nil
|
||||
return a.jsonResult(cmd, run)
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVar(&force, "force", false, "Cancel without waiting for the runner to acknowledge")
|
||||
@@ -678,11 +675,8 @@ $ tea run rerun 34 --job build`,
|
||||
if run, err = service.Run(cmd.Context(), id); err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, run)
|
||||
}
|
||||
a.done(cmd, "Requested rerun of run %d (attempt %d); watch it with: tea run watch %d%s", id, run.Attempt, id, a.suggestedRepo(t))
|
||||
return nil
|
||||
return a.jsonResult(cmd, run)
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVar(&failed, "failed", false, "Rerun only the failed jobs")
|
||||
|
||||
@@ -243,7 +243,7 @@ $ tea workflow run nightly --follow`,
|
||||
if !follow {
|
||||
a.nextStep(cmd, "Watch it: tea run watch %d%s", result.ID, a.suggestedRepo(t))
|
||||
}
|
||||
if err := a.printURL(cmd, result.URL); err != nil || !follow {
|
||||
if err := a.created(cmd, result, result.URL); err != nil || !follow {
|
||||
return err
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(cmd.Context(), timeout)
|
||||
@@ -474,10 +474,7 @@ $ tea workflow %s Nightly`, verb, verb),
|
||||
}
|
||||
a.done(cmd, "%s %s", done, workflow.Label())
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, workflow)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, workflow)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,10 +280,7 @@ $ tea admin user create ci-bot --email ci@example.com --password-file pw.txt --m
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Created user %s", user.Username)
|
||||
if err := a.printURL(cmd, user.URL); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.jsonResult(cmd, user)
|
||||
return a.created(cmd, user, user.URL)
|
||||
}
|
||||
return command
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ $ tea branch create bisect --source 3f2a9c1`,
|
||||
} else {
|
||||
a.done(cmd, "Created branch %s from %s in %s at %s", item.Name, source, target.Repo, shortSHA(item.SHA))
|
||||
}
|
||||
return a.writeMutationJSON(cmd, item)
|
||||
return a.jsonResult(cmd, item)
|
||||
},
|
||||
}
|
||||
command.Flags().StringVarP(&source, "source", "s", "", "Branch, tag or commit to start from (default: the default branch)")
|
||||
|
||||
@@ -143,15 +143,12 @@ argument select it, and the branch tracks the head branch, so that git push upda
|
||||
undoRemote()
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, result)
|
||||
}
|
||||
if result.Detached {
|
||||
a.done(cmd, "Checked out #%d at %s (detached HEAD)", n, shortSHA(result.Commit))
|
||||
} else {
|
||||
a.done(cmd, "Checked out #%d into %s", n, result.Branch)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, result)
|
||||
}}
|
||||
cmd.Flags().BoolVar(&update, "update", false, "Fast-forward an existing branch to the PR head; reject divergence")
|
||||
cmd.Flags().BoolVar(&detached, "detach", false, "Check out the PR commit without creating or changing a branch")
|
||||
|
||||
@@ -142,11 +142,8 @@ func (a *application) commentOn(cmd *cobra.Command, t target, n int64, kind refK
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, comment)
|
||||
}
|
||||
a.done(cmd, "Commented on %s", refLabel(t.Repo, n, item.Title))
|
||||
return a.printURL(cmd, comment.URL)
|
||||
return a.created(cmd, comment, comment.URL)
|
||||
}
|
||||
|
||||
// lastComment returns the newest comment on n by the account tea acts as.
|
||||
@@ -185,11 +182,8 @@ func (a *application) editComment(cmd *cobra.Command, t target, comment services
|
||||
return err
|
||||
}
|
||||
edited.IssueNumber = comment.IssueNumber
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, edited)
|
||||
}
|
||||
a.done(cmd, "Edited %s", commentName(t, edited))
|
||||
return nil
|
||||
return a.jsonResult(cmd, edited)
|
||||
}
|
||||
|
||||
// deleteComment deletes comment after a confirmation that defaults to no.
|
||||
|
||||
@@ -149,12 +149,20 @@ func (a *application) feedback(cmd *cobra.Command, icon, color, format string, a
|
||||
fmt.Fprintln(cmd.ErrOrStderr(), terminal.Colorize(color, icon, a.colorEnabled())+" "+terminal.SafeLine(fmt.Sprintf(format, args...)))
|
||||
}
|
||||
|
||||
// printURL writes the URL of a created resource to stdout unless --json is set, so scripts can
|
||||
// capture it: url=$(tea issue create …).
|
||||
func (a *application) printURL(cmd *cobra.Command, url string) error {
|
||||
if a.options.json != "" {
|
||||
// jsonResult writes the result of a mutation when --json asks for it; people get a done line instead.
|
||||
func (a *application) jsonResult(cmd *cobra.Command, item any) error {
|
||||
if a.options.json == "" {
|
||||
return nil
|
||||
}
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
|
||||
// created writes a created resource as JSON with --json, else its URL to stdout, so scripts can
|
||||
// capture it: url=$(tea issue create …).
|
||||
func (a *application) created(cmd *cobra.Command, item any, url string) error {
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
_, err := fmt.Fprintln(cmd.OutOrStdout(), terminal.SafeLine(url))
|
||||
return err
|
||||
}
|
||||
@@ -170,7 +178,7 @@ type abortBatch struct{ error }
|
||||
func (e abortBatch) Unwrap() error { return e.error }
|
||||
|
||||
// applyBatch applies run to each selection and continues past individual failures, which it
|
||||
// returns prefixed with the selection's label. succeeded sees each result as it arrives.
|
||||
// returns prefixed with the selection's label. succeeded, when set, sees each result as it arrives.
|
||||
func applyBatch[K, T any](cmd *cobra.Command, keys []K, label func(K) string, run func(K) (T, error), succeeded func(T)) ([]T, []error) {
|
||||
results := []T{}
|
||||
var failures []error
|
||||
@@ -189,14 +197,18 @@ func applyBatch[K, T any](cmd *cobra.Command, keys []K, label func(K) string, ru
|
||||
continue
|
||||
}
|
||||
results = append(results, item)
|
||||
if succeeded != nil {
|
||||
succeeded(item)
|
||||
}
|
||||
}
|
||||
return results, failures
|
||||
}
|
||||
|
||||
// writeBatchJSON writes an object for one selection (none if it failed), otherwise an array.
|
||||
// writeBatchJSON writes, with --json, an object for one selection (none if it failed), otherwise an array.
|
||||
func writeBatchJSON[T any](a *application, cmd *cobra.Command, selections int, results []T) error {
|
||||
switch {
|
||||
case a.options.json == "":
|
||||
return nil
|
||||
case selections != 1:
|
||||
return a.writeJSON(cmd, results)
|
||||
case len(results) == 1:
|
||||
@@ -209,11 +221,7 @@ func writeBatchJSON[T any](a *application, cmd *cobra.Command, selections int, r
|
||||
// line from report, such as "Closed issue alice/x#5 (Fix login)", and the results as JSON.
|
||||
func batchDone[K, T any](a *application, cmd *cobra.Command, keys []K, label func(K) string, run func(K) (T, error), report func(T) string) error {
|
||||
results, failures := applyBatch(cmd, keys, label, run, func(item T) { a.done(cmd, "%s", report(item)) })
|
||||
var err error
|
||||
if a.options.json != "" {
|
||||
err = writeBatchJSON(a, cmd, len(keys), results)
|
||||
}
|
||||
return errors.Join(append(failures, err)...)
|
||||
return errors.Join(append(failures, writeBatchJSON(a, cmd, len(keys), results))...)
|
||||
}
|
||||
|
||||
// stateColors colors issue, pull request and milestone states with the terminal's own palette.
|
||||
|
||||
@@ -379,8 +379,12 @@ func TestMutationFeedback(t *testing.T) {
|
||||
ref := refLabel("alice/x", 12, "Fix\x1b[2J login")
|
||||
a.done(cmd, "Created issue %s", ref)
|
||||
a.warn(cmd, "Issue %s is already closed", ref)
|
||||
require.NoError(t, a.printURL(cmd, "https://example.org/12"))
|
||||
require.NoError(t, a.created(cmd, map[string]int{"number": 12}, "https://example.org/12"))
|
||||
if tc.json != "" {
|
||||
require.JSONEq(t, `{"number":12}`, out.String())
|
||||
} else {
|
||||
require.Equal(t, tc.out, out.String())
|
||||
}
|
||||
require.Equal(t, tc.stderr, diagnostics.String())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -111,11 +111,8 @@ $ tea %[1]s attachment upload %[2]s screenshot.png --name before.png`, words.gro
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
a.done(cmd, "Uploaded %s (%s) to %s#%d", item.Name, terminal.Bytes(item.Size), t.Repo, n)
|
||||
return a.printURL(cmd, item.URL)
|
||||
return a.created(cmd, item, item.URL)
|
||||
}}
|
||||
upload.Flags().StringVar(&uploadName, "name", "", "File `name` of the attachment (default: the local file name)")
|
||||
|
||||
@@ -132,11 +129,8 @@ $ tea %[1]s attachment upload %[2]s screenshot.png --name before.png`, words.gro
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
a.done(cmd, "Renamed %s", attachmentName(t, n, item))
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
edit.Flags().StringVar(&newName, "name", "", "New file `name`")
|
||||
|
||||
|
||||
+7
-14
@@ -317,7 +317,7 @@ $ tea issue create --title "Idea" --web`, Args: argsExact(0), RunE: func(cmd *co
|
||||
failures = append(failures, fmt.Errorf("issue %d created; attachment %s upload failed: %w", item.Number, filepath.Base(file.Name()), err))
|
||||
}
|
||||
}
|
||||
return errors.Join(append(failures, a.created(cmd, target, item))...)
|
||||
return errors.Join(append(failures, a.issueCreated(cmd, target, item))...)
|
||||
}}
|
||||
flags := cmd.Flags()
|
||||
flags.StringVarP(&title, "title", "t", "", "Issue title")
|
||||
@@ -340,13 +340,10 @@ $ tea issue create --title "Idea" --web`, Args: argsExact(0), RunE: func(cmd *co
|
||||
return cmd
|
||||
}
|
||||
|
||||
// created reports a new issue: as JSON, or its URL on stdout after a ✓ line for people.
|
||||
func (a *application) created(cmd *cobra.Command, t target, item services.Issue) error {
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
// issueCreated reports a new issue: as JSON, or its URL on stdout after a ✓ line for people.
|
||||
func (a *application) issueCreated(cmd *cobra.Command, t target, item services.Issue) error {
|
||||
a.done(cmd, "Created issue %s", refLabel(t.Repo, item.Number, item.Title))
|
||||
return a.printURL(cmd, item.URL)
|
||||
return a.created(cmd, item, item.URL)
|
||||
}
|
||||
|
||||
func (a *application) createIssueInteractively(cmd *cobra.Command) (runErr error) {
|
||||
@@ -379,7 +376,7 @@ func (a *application) createIssueInteractively(cmd *cobra.Command) (runErr error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.created(cmd, target, item)
|
||||
return a.issueCreated(cmd, target, item)
|
||||
}
|
||||
|
||||
// issueTemplateBody seeds a body from markdown content, or from the description of form templates.
|
||||
@@ -445,12 +442,8 @@ $ tea issue %[1]s 12 13 --comment "Done in #14"`, verb), Annotations: map[string
|
||||
}
|
||||
a.done(cmd, "%s %s %s", past, discussionNoun(item.Kind), refLabel(target.Repo, n, item.Title))
|
||||
return item, nil
|
||||
}, func(services.Issue) {})
|
||||
var err2 error
|
||||
if a.options.json != "" {
|
||||
err2 = writeBatchJSON(a, cmd, len(numbers), results)
|
||||
}
|
||||
return errors.Join(append(failures, err2)...)
|
||||
}, nil)
|
||||
return errors.Join(append(failures, writeBatchJSON(a, cmd, len(numbers), results))...)
|
||||
}}
|
||||
cmd.Flags().StringVarP(&comment, "comment", "c", "", "Leave a comment before the issue is "+state)
|
||||
cmd.ValidArgsFunction = a.completeIssueArgs(completeState, true)
|
||||
|
||||
+3
-12
@@ -226,15 +226,12 @@ func (a *application) askLabelDetails(cmd *cobra.Command, opts *services.LabelOp
|
||||
|
||||
// reportLabel reports a created or updated label as JSON or with a ✓ line.
|
||||
func (a *application) reportLabel(cmd *cobra.Command, s services.Labels, item services.Label, updated bool) error {
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
verb := "Created"
|
||||
if updated {
|
||||
verb = "Updated"
|
||||
}
|
||||
a.done(cmd, "%s %s", verb, labelName(s, item))
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}
|
||||
|
||||
func (a *application) labelEditCommand(scope labelScope, complete cobra.CompletionFunc) *cobra.Command {
|
||||
@@ -262,11 +259,8 @@ $ tea label edit old-stuff --archived`, Annotations: map[string]string{"tea.argu
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
a.done(cmd, "Edited %s", labelName(s, item))
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
fields.register(cmd, "Rename the label")
|
||||
cmd.Flags().BoolVar(&byName, "by-name", false, "Match a numeric argument as a label name rather than an ID")
|
||||
@@ -359,10 +353,7 @@ func (a *application) createLabels(cmd *cobra.Command, s services.Labels, rows [
|
||||
}, func(item services.Label) {
|
||||
a.done(cmd, "%s %s", outcome[item.Name], labelName(s, item))
|
||||
})
|
||||
if a.options.json != "" {
|
||||
failures = append(failures, writeBatchJSON(a, cmd, len(rows), results))
|
||||
}
|
||||
return errors.Join(failures...)
|
||||
return errors.Join(append(failures, writeBatchJSON(a, cmd, len(rows), results))...)
|
||||
}
|
||||
|
||||
// completeScopedLabels completes the label names of the repository or, with --org, of the
|
||||
|
||||
@@ -274,11 +274,8 @@ $ tea milestone create --title v2.0 --editor`, Args: usageArgs(cobra.MaximumNArg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
a.done(cmd, "Created %s", milestoneName(t, item))
|
||||
return a.printURL(cmd, milestoneURL(t, item))
|
||||
return a.created(cmd, item, milestoneURL(t, item))
|
||||
}}
|
||||
fields.register(cmd)
|
||||
enumFlag(cmd, &state, "state", "", "open", "State of the new milestone", "open", "closed")
|
||||
@@ -338,11 +335,8 @@ $ tea milestone edit 3 --editor`, Annotations: map[string]string{"tea.arguments"
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
a.done(cmd, "Edited %s", milestoneName(t, item))
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
fields.register(cmd)
|
||||
cmd.Flags().BoolVar(&byName, "by-name", false, "Match a numeric argument as a milestone title rather than an ID")
|
||||
@@ -369,11 +363,8 @@ $ tea milestone delete 7 --yes`, Annotations: map[string]string{"tea.confirm": "
|
||||
if err := s.Delete(cmd.Context(), item.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
a.done(cmd, "Deleted milestone %q from %s", item.Title, t.Repo)
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
cmd.Flags().BoolVar(&byName, "by-name", false, "Match a numeric argument as a milestone title rather than an ID")
|
||||
cmd.ValidArgsFunction = a.completeMilestoneArgs(false)
|
||||
|
||||
@@ -66,7 +66,7 @@ $ tea milestone issue %[1]s v1.0 12 13 '#14'`, verb), Annotations: map[string]st
|
||||
item, err = service.Edit(cmd.Context(), n, services.IssueEdit{Milestone: &milestone.ID})
|
||||
}
|
||||
return item, itemError(err, target.Repo)
|
||||
}, func(services.Issue) {})
|
||||
}, nil)
|
||||
if len(results) > 0 {
|
||||
changed := make([]string, len(results))
|
||||
for i, item := range results {
|
||||
@@ -74,10 +74,7 @@ $ tea milestone issue %[1]s v1.0 12 13 '#14'`, verb), Annotations: map[string]st
|
||||
}
|
||||
a.done(cmd, "%s %s %s %s", past, strings.Join(changed, ", "), preposition, milestoneName(target, milestone))
|
||||
}
|
||||
if a.options.json != "" {
|
||||
failures = append(failures, writeBatchJSON(a, cmd, len(numbers), results))
|
||||
}
|
||||
return errors.Join(failures...)
|
||||
return errors.Join(append(failures, writeBatchJSON(a, cmd, len(numbers), results))...)
|
||||
}}
|
||||
command.Flags().BoolVar(&byName, "by-name", false, "Match a numeric milestone argument as a title rather than an ID")
|
||||
milestones, issues := a.completeMilestones(), a.completeIssues("open")
|
||||
|
||||
@@ -50,11 +50,8 @@ $ tea milestone %[1]s v1.0 v1.1`, verb), Annotations: map[string]string{"tea.arg
|
||||
a.done(cmd, "%s %s", past, milestoneName(t, item))
|
||||
}
|
||||
return item, err
|
||||
}, func(services.Milestone) {})
|
||||
if a.options.json != "" {
|
||||
failures = append(failures, writeBatchJSON(a, cmd, len(selected), results))
|
||||
}
|
||||
return errors.Join(failures...)
|
||||
}, nil)
|
||||
return errors.Join(append(failures, writeBatchJSON(a, cmd, len(selected), results))...)
|
||||
}}
|
||||
cmd.Flags().BoolVar(&byName, "by-name", false, "Match numeric arguments as milestone titles rather than IDs")
|
||||
cmd.ValidArgsFunction = a.completeMilestoneArgs(true)
|
||||
|
||||
@@ -23,14 +23,6 @@ var visibilities = []string{"public", "limited", "private"}
|
||||
// visibilityColors color the visibility of organizations and accounts.
|
||||
var visibilityColors = map[string]string{"public": "green", "limited": "yellow", "private": "red"}
|
||||
|
||||
// jsonResult writes the result of a mutation when --json asks for it; people get a done line instead.
|
||||
func (a *application) jsonResult(cmd *cobra.Command, item any) error {
|
||||
if a.options.json == "" {
|
||||
return nil
|
||||
}
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
|
||||
// timeField shows an API timestamp relative to now on a TTY, and as RFC3339 for scripts.
|
||||
func timeField(label, raw string, d terminal.Display) terminal.Field {
|
||||
t := terminal.ParseTime(raw)
|
||||
@@ -250,10 +242,7 @@ $ tea org create acme-internal --visibility private`,
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Created organization %s", org.Name)
|
||||
if err := a.printURL(cmd, webURL(target, org.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.jsonResult(cmd, org)
|
||||
return a.created(cmd, org, webURL(target, org.Name))
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -103,9 +103,6 @@ func (a *application) pullCleanCommand() *cobra.Command {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, result)
|
||||
}
|
||||
a.done(cmd, "Deleted local branch %s", result.LocalBranch)
|
||||
switch {
|
||||
case result.RemoteDeleted:
|
||||
@@ -115,7 +112,7 @@ func (a *application) pullCleanCommand() *cobra.Command {
|
||||
case !pull.HeadCanPush:
|
||||
a.warn(cmd, "Kept remote branch %s: you cannot push to %s", pull.Head, pull.HeadRepo)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, result)
|
||||
}}
|
||||
cmd.Flags().BoolVar(&ignoreSHA, "ignore-sha", false, "Find the local branch by name instead of commit hash")
|
||||
cmd.ValidArgsFunction = a.completePulls("closed")
|
||||
|
||||
@@ -371,8 +371,5 @@ func (a *application) createPullInteractively(cmd *cobra.Command, snapshot setti
|
||||
// reportCreatedPull reports a new pull request and prints its URL, or the pull request as JSON.
|
||||
func (a *application) reportCreatedPull(cmd *cobra.Command, t target, item services.Pull) error {
|
||||
a.done(cmd, "Created pull request %s", refLabel(t.Repo, item.Number, item.Title))
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return a.printURL(cmd, item.URL)
|
||||
return a.created(cmd, item, item.URL)
|
||||
}
|
||||
@@ -125,10 +125,7 @@ pull request, or mark it as a draft or ready for review.`, Annotations: pullArgu
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Edited pull request %s", refLabel(t.Repo, n, item.Title))
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
cmd.Flags().StringVarP(&title, "title", "t", "", "Pull request title")
|
||||
cmd.Flags().StringVar(&deadline, "deadline", "", "Due date: YYYY-MM-DD, RFC3339, or Unix timestamp; empty clears")
|
||||
@@ -206,10 +203,7 @@ removes or adds that marker.`, Annotations: pullArgumentsAnnotation(nil), Args:
|
||||
a.done(cmd, "Marked pull request %s as ready for review", refLabel(t.Repo, n, item.Title))
|
||||
}
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
cmd.Flags().BoolVar(&undo, "undo", false, "Turn the pull request back into a draft")
|
||||
cmd.ValidArgsFunction = a.completePulls("open")
|
||||
|
||||
@@ -109,10 +109,7 @@ func (a *application) pullStateCommand(closing bool) *cobra.Command {
|
||||
if deleteBranch {
|
||||
a.deleteHead(cmd, service, item, false)
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
cmd.Flags().StringVarP(&comment, "comment", "c", "", "Leave a comment before changing the state")
|
||||
cmd.ValidArgsFunction = a.completePulls(map[bool]string{true: "open", false: "closed"}[closing])
|
||||
@@ -302,10 +299,7 @@ the base branch.`, Annotations: pullArgumentsAnnotation(map[string]string{"tea.c
|
||||
switch {
|
||||
case item.Merged:
|
||||
a.warn(cmd, "Pull request %s is already merged", ref)
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
case item.State == "closed":
|
||||
return fmt.Errorf("pull request %s is closed; reopen it with: tea pr reopen %d", ref, n)
|
||||
case item.Draft:
|
||||
@@ -362,10 +356,7 @@ the base branch.`, Annotations: pullArgumentsAnnotation(map[string]string{"tea.c
|
||||
a.deleteHead(cmd, service, merged, true)
|
||||
}
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, merged)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, merged)
|
||||
}}
|
||||
enumFlag(cmd, &method, "method", "s", "", "Merge method (default: the repository's default merge style)", mergeMethods...)
|
||||
cmd.Flags().StringVar(&method, "style", "", "Alias of --method")
|
||||
|
||||
@@ -268,14 +268,11 @@ func ownReview(pull services.Pull, t target, state string) error {
|
||||
// reportReview reports a submitted review, then prints its URL, or the review as JSON.
|
||||
func (a *application) reportReview(cmd *cobra.Command, t target, pull services.Pull, item services.Review) error {
|
||||
a.done(cmd, "%s pull request %s", reviewVerbs[item.State], refLabel(t.Repo, pull.Number, pull.Title))
|
||||
switch {
|
||||
case a.options.json != "":
|
||||
return a.writeJSON(cmd, item)
|
||||
case item.URL != "":
|
||||
return a.printURL(cmd, item.URL)
|
||||
}
|
||||
if a.options.json == "" && item.URL == "" {
|
||||
return nil
|
||||
}
|
||||
return a.created(cmd, item, item.URL)
|
||||
}
|
||||
|
||||
// readInlineComments reads the inline comments of --comments-file, a JSON array.
|
||||
func readInlineComments(path string) ([]services.InlineComment, error) {
|
||||
@@ -625,10 +622,7 @@ func (a *application) pullReviewReplyCommand() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Replied to review comment %d on %s#%d", id, t.Repo, n)
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return a.printURL(cmd, item.URL)
|
||||
return a.created(cmd, item, item.URL)
|
||||
}}
|
||||
cmd.Flags().StringVarP(&body, "body", "b", "", "Reply body")
|
||||
cmd.Flags().StringVarP(&file, "body-file", "F", "", "Read the body from `file`, or - for stdin")
|
||||
|
||||
@@ -204,10 +204,7 @@ func (a *application) pullReviewDismissCommand(dismiss bool) *cobra.Command {
|
||||
} else {
|
||||
a.done(cmd, "Restored %s", subject)
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
if dismiss {
|
||||
cmd.Annotations["tea.confirm"] = "true"
|
||||
|
||||
@@ -42,10 +42,7 @@ func (a *application) pullReviewRequestCommand(add bool) *cobra.Command {
|
||||
names = append(names, "team "+team)
|
||||
}
|
||||
a.done(cmd, "%s %s on %s", verb, strings.Join(names, ", "), refLabel(t.Repo, item.Number, item.Title))
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
cmd.Flags().StringSliceVarP(&input.Users, "reviewer", "r", nil, "Reviewer usernames or email addresses; @me for yourself")
|
||||
cmd.Flags().StringSliceVar(&input.Teams, "team", nil, "Teams of the repository's organization")
|
||||
|
||||
@@ -352,7 +352,7 @@ func (a *application) assetEditCommand() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Renamed asset %s to %s in release %s", asset.Name, item.Name, release.Tag)
|
||||
return a.writeMutationJSON(cmd, item)
|
||||
return a.jsonResult(cmd, item)
|
||||
},
|
||||
}
|
||||
command.Flags().StringVar(&name, "name", "", "New asset name")
|
||||
|
||||
@@ -300,12 +300,7 @@ $ tea release create v1.1.0-rc1 --target release/1.1 --draft --prerelease --titl
|
||||
item.Assets = append(item.Assets, asset)
|
||||
a.done(cmd, "Uploaded %s (%s)", asset.Name, terminal.Bytes(asset.Size))
|
||||
}
|
||||
if a.options.json != "" {
|
||||
failures = append(failures, a.writeJSON(cmd, item))
|
||||
} else {
|
||||
failures = append(failures, a.printURL(cmd, item.URL))
|
||||
}
|
||||
return errors.Join(failures...)
|
||||
return errors.Join(append(failures, a.created(cmd, item, item.URL))...)
|
||||
},
|
||||
}
|
||||
fields.register(a, command)
|
||||
@@ -402,11 +397,8 @@ func (a *application) releasePublishCommand() *cobra.Command {
|
||||
a.done(cmd, "Published release %s in %s", item.Tag, target.Repo)
|
||||
}
|
||||
return item, err
|
||||
}, func(services.Release) {})
|
||||
if a.options.json != "" {
|
||||
failures = append(failures, writeBatchJSON(a, cmd, len(args), results))
|
||||
}
|
||||
return errors.Join(failures...)
|
||||
}, nil)
|
||||
return errors.Join(append(failures, writeBatchJSON(a, cmd, len(args), results))...)
|
||||
},
|
||||
}
|
||||
command.ValidArgsFunction = a.completeReleases()
|
||||
|
||||
@@ -278,7 +278,7 @@ $ tea repo clone alice/project -- --branch develop --recurse-submodules`,
|
||||
if _, err := a.cloneRepository(cmd, t, item, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.writeMutationJSON(cmd, item)
|
||||
return a.jsonResult(cmd, item)
|
||||
},
|
||||
}
|
||||
command.Flags().IntVarP(&opts.depth, "depth", "d", 0, "Number of commits to fetch (0: full history)")
|
||||
@@ -352,10 +352,7 @@ $ tea repo fork alice/project --clone -- --depth 1`,
|
||||
return err
|
||||
}
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, fork)
|
||||
}
|
||||
return a.printURL(cmd, fork.URL)
|
||||
return a.created(cmd, fork, fork.URL)
|
||||
},
|
||||
}
|
||||
command.Flags().StringVar(&opts.Organization, "org", "", "Fork into this organization")
|
||||
@@ -552,7 +549,7 @@ $ tea repo archive alice/old-project --yes`,
|
||||
} else {
|
||||
a.warn(cmd, "%s is not archived", item.FullName)
|
||||
}
|
||||
return a.writeMutationJSON(cmd, item)
|
||||
return a.jsonResult(cmd, item)
|
||||
}
|
||||
if archive {
|
||||
if err := a.confirmAction(cmd, terminal.Confirmation{Prompt: "Archive " + t.Repo + inferred + "? It becomes read-only.", NonTTY: "archive " + t.Repo}); err != nil {
|
||||
@@ -568,20 +565,12 @@ $ tea repo archive alice/old-project --yes`,
|
||||
} else {
|
||||
a.done(cmd, "Unarchived repository %s", item.FullName)
|
||||
}
|
||||
return a.writeMutationJSON(cmd, item)
|
||||
return a.jsonResult(cmd, item)
|
||||
}
|
||||
command.ValidArgsFunction = a.completeRepos()
|
||||
return command
|
||||
}
|
||||
|
||||
// writeMutationJSON writes the result of a mutation with --json; people get done lines instead.
|
||||
func (a *application) writeMutationJSON(cmd *cobra.Command, item any) error {
|
||||
if a.options.json == "" {
|
||||
return nil
|
||||
}
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
|
||||
func (a *application) repoRenameCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "rename <new-name>",
|
||||
@@ -624,7 +613,7 @@ $ tea repo rename new-name -R alice/old-name`,
|
||||
if remote, ok := strings.CutPrefix(t.RepoSource, "remote "); ok {
|
||||
a.warn(cmd, "Git remote %s still points to %s; update it with git remote set-url", remote, t.Repo)
|
||||
}
|
||||
return a.writeMutationJSON(cmd, item)
|
||||
return a.jsonResult(cmd, item)
|
||||
},
|
||||
}
|
||||
return command
|
||||
|
||||
@@ -159,10 +159,7 @@ $ tea repo create project --source . --push`,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return a.printURL(cmd, item.URL)
|
||||
return a.created(cmd, item, item.URL)
|
||||
},
|
||||
}
|
||||
flags := command.Flags()
|
||||
|
||||
@@ -143,10 +143,7 @@ $ tea repo migrate https://github.com/acme/tool --service github --issues --pull
|
||||
detail = " (pull mirror)"
|
||||
}
|
||||
a.done(cmd, "Imported %s into %s%s", opts.CloneURL, item.FullName, detail)
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return a.printURL(cmd, item.URL)
|
||||
return a.created(cmd, item, item.URL)
|
||||
},
|
||||
}
|
||||
flags := command.Flags()
|
||||
|
||||
@@ -91,11 +91,8 @@ $ tea repo sync bob/project`,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, result)
|
||||
}
|
||||
a.reportSync(cmd, result, remote+"/"+result.Branch)
|
||||
return nil
|
||||
return a.jsonResult(cmd, result)
|
||||
},
|
||||
}
|
||||
command.Flags().StringVarP(&branch, "branch", "b", "", "Branch to sync (default: the repository's default branch)")
|
||||
@@ -118,7 +115,7 @@ func (a *application) syncOnServer(cmd *cobra.Command, t target, branch string)
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Started updating the mirror %s from its source", item.FullName)
|
||||
return a.writeMutationJSON(cmd, git.SyncResult{Remote: mirrorSourceURL(item)})
|
||||
return a.jsonResult(cmd, git.SyncResult{Remote: mirrorSourceURL(item)})
|
||||
case !item.Fork || item.Parent == nil:
|
||||
return clierr.Wrap(clierr.Usage, fmt.Errorf("%s is neither a fork nor a mirror, and has no Git remote here; run tea repo sync inside a clone of it", item.FullName))
|
||||
}
|
||||
@@ -141,7 +138,7 @@ func (a *application) syncOnServer(cmd *cobra.Command, t target, branch string)
|
||||
} else {
|
||||
a.done(cmd, "Synced %s %s from %s (fast-forward %s..%s)", item.FullName, branch, item.Parent.FullName, shortSHA(result.Previous), shortSHA(result.Commit))
|
||||
}
|
||||
return a.writeMutationJSON(cmd, result)
|
||||
return a.jsonResult(cmd, result)
|
||||
}
|
||||
|
||||
// reportSync tells how a sync from source, such as origin/main, changed the branch.
|
||||
|
||||
@@ -380,10 +380,7 @@ $ tea team create acme ops --permission admin --all-repositories`,
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Created team %s (ID %d) with %s access", team.Slug(), team.ID, team.Access())
|
||||
if err := a.printURL(cmd, teamURL(target, team)); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.jsonResult(cmd, team)
|
||||
return a.created(cmd, team, teamURL(target, team))
|
||||
},
|
||||
}
|
||||
flags.register(cmd, true)
|
||||
|
||||
@@ -174,11 +174,8 @@ $ tea time log https://gitea.com/OWNER/REPO/issues/12 45m`, Annotations: map[str
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
a.done(cmd, "Logged %s on %s", spent(item.Seconds), strings.TrimSuffix(refLabel(target.Repo, n, item.IssueTitle), " ()"))
|
||||
return nil
|
||||
return a.jsonResult(cmd, item)
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
@@ -431,10 +431,7 @@ $ tea webhook create https://hooks.slack.com/services/T0/B0/X --org acme --type
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Created %s in %s for %s", webhookLabel(hook), webhookScopeName(service.Scope), collapsedEvents(hook.Events))
|
||||
if err := a.printURL(cmd, webhookSettingsURL(target, service.Scope, hook.ID)); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.jsonResult(cmd, hook)
|
||||
return a.created(cmd, hook, webhookSettingsURL(target, service.Scope, hook.ID))
|
||||
}
|
||||
return command
|
||||
}
|
||||
|
||||
@@ -213,10 +213,7 @@ $ tea wiki create Home --editor`,
|
||||
return err
|
||||
}
|
||||
a.done(cmd, "Created wiki page %q in %s", item.Title, target.Repo)
|
||||
if a.options.json != "" {
|
||||
return a.writeJSON(cmd, item)
|
||||
}
|
||||
return a.printURL(cmd, item.URL)
|
||||
return a.created(cmd, item, item.URL)
|
||||
},
|
||||
}
|
||||
content.register(command)
|
||||
@@ -298,7 +295,7 @@ $ tea wiki edit Home --editor`,
|
||||
} else {
|
||||
a.done(cmd, "Edited wiki page %q in %s", item.Title, target.Repo)
|
||||
}
|
||||
return a.writeMutationJSON(cmd, item)
|
||||
return a.jsonResult(cmd, item)
|
||||
},
|
||||
}
|
||||
content.register(command)
|
||||
|
||||
Reference in new issue
Block a user