mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
fix(issue): name missing issues and attachments in errors
tea issue close 999 printed "issue 999: not found (HTTP 404 GET …)" and issue attachment view 1 9 blamed issue #1 for a missing attachment. Batch commands (issue close, reopen, edit, milestone issue add and remove) now report "issue 999: not found in alice/x", and attachment commands "attachment 9 not found in alice/x#1". Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
5 files changed
+64
-15
No files matched your search
@@ -114,3 +114,28 @@ func TestIssueMutationsReportDoneLines(t *testing.T) {
|
||||
run(true, "issue", "edit", "5", "--title", "Open one")
|
||||
require.Equal(t, "✓ Edited issue alice/project#5 (Open one)\n", diagnostics.String())
|
||||
}
|
||||
|
||||
func TestMissingItemsAreNamed(t *testing.T) {
|
||||
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/api/v1/repos/alice/project" {
|
||||
_, _ = w.Write([]byte(`{"full_name":"alice/project","has_issues":true,"has_pull_requests":true}`))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
_, _ = w.Write([]byte(`{"message":"not found"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
deps, _, _ := serverDeps(t, server.URL)
|
||||
for _, test := range []struct {
|
||||
args []string
|
||||
want string
|
||||
}{
|
||||
{[]string{"issue", "close", "999"}, "issue 999: not found in alice/project"},
|
||||
{[]string{"issue", "edit", "999", "--title", "x"}, "issue 999: not found in alice/project"},
|
||||
{[]string{"issue", "attachment", "view", "1", "9"}, "attachment 9 not found in alice/project#1"},
|
||||
{[]string{"issue", "attachment", "delete", "1", "9", "--yes"}, "attachment 9 not found in alice/project#1"},
|
||||
} {
|
||||
err := Execute(context.Background(), deps, append(test.args, "-R", "alice/project"))
|
||||
require.EqualError(t, Explain(context.Background(), deps, err), test.want, test.args)
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,8 @@ $ tea issue edit 12 --body-file notes.md`, Annotations: map[string]string{"tea.a
|
||||
opts.Body = &draft.Body
|
||||
}
|
||||
return batchDone(a, cmd, numbers, issueLabel, func(n int64) (services.Issue, error) {
|
||||
return service.Edit(cmd.Context(), n, opts)
|
||||
item, err := service.Edit(cmd.Context(), n, opts)
|
||||
return item, itemError(err, target.Repo)
|
||||
}, editedIssue(target))
|
||||
}}
|
||||
flags := cmd.Flags()
|
||||
@@ -147,7 +148,7 @@ func (a *application) editIssuesInteractively(cmd *cobra.Command, target target,
|
||||
return batchDone(a, cmd, numbers, issueLabel, func(n int64) (item services.Issue, err error) {
|
||||
current, err := service.View(cmd.Context(), n)
|
||||
if err != nil {
|
||||
return item, err
|
||||
return item, itemError(err, target.Repo)
|
||||
}
|
||||
choices := terminal.IssueEditFormChoices{
|
||||
Heading: "Editing " + refLabel(target.Repo, n, current.Title),
|
||||
@@ -182,6 +183,7 @@ func (a *application) editIssuesInteractively(cmd *cobra.Command, target target,
|
||||
opts.RemoveDeadline = &values.ClearDeadline
|
||||
}
|
||||
}
|
||||
return service.Edit(cmd.Context(), n, opts)
|
||||
item, err = service.Edit(cmd.Context(), n, opts)
|
||||
return item, itemError(err, target.Repo)
|
||||
}, editedIssue(target))
|
||||
}
|
||||
+17
-5
@@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"gitea.dev/tea/internal/clierr"
|
||||
"gitea.dev/tea/internal/services"
|
||||
"gitea.dev/tea/internal/terminal"
|
||||
"gitea.dev/tea/internal/transport"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -429,7 +431,7 @@ $ tea issue %[1]s 12 13 --comment "Done in #14"`, verb), Annotations: map[string
|
||||
results, failures := applyBatch(cmd, numbers, issueLabel, func(n int64) (services.Issue, error) {
|
||||
current, err := service.View(cmd.Context(), n)
|
||||
if err != nil {
|
||||
return current, err
|
||||
return current, itemError(err, target.Repo)
|
||||
}
|
||||
if current.State == state || (state == "closed" && current.State == "merged") {
|
||||
a.warn(cmd, "%s %s is already %s", titleCase(discussionNoun(current.Kind)), refLabel(target.Repo, n, current.Title), current.State)
|
||||
@@ -437,14 +439,15 @@ $ tea issue %[1]s 12 13 --comment "Done in #14"`, verb), Annotations: map[string
|
||||
}
|
||||
if comment != "" {
|
||||
if _, err := comments.Create(cmd.Context(), n, comment); err != nil {
|
||||
return current, err
|
||||
return current, itemError(err, target.Repo)
|
||||
}
|
||||
}
|
||||
item, err := service.SetState(cmd.Context(), n, state)
|
||||
if err == nil {
|
||||
a.done(cmd, "%s %s %s", past, discussionNoun(item.Kind), refLabel(target.Repo, n, item.Title))
|
||||
if err != nil {
|
||||
return item, itemError(err, target.Repo)
|
||||
}
|
||||
return item, err
|
||||
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 != "" {
|
||||
@@ -523,6 +526,15 @@ func labelChoices(items []services.Label) []terminal.IssueLabelChoice {
|
||||
|
||||
func issueLabel(n int64) string { return fmt.Sprintf("issue %d", n) }
|
||||
|
||||
// itemError words the failure of one item of a batch, which the batch prefixes with the item, such
|
||||
// as "issue 9: not found in alice/x".
|
||||
func itemError(err error, scope string) error {
|
||||
if apiErr, ok := errors.AsType[*transport.APIError](err); ok && apiErr.Status == http.StatusNotFound {
|
||||
return explain(err, "not found in %s", scope)
|
||||
}
|
||||
return services.ClassifyRequest(err)
|
||||
}
|
||||
|
||||
// nameFilter splits a comma-separated filter of kind, trimming entries and rejecting blanks.
|
||||
func nameFilter(kind, raw string) ([]string, error) {
|
||||
if raw == "" {
|
||||
|
||||
@@ -59,11 +59,13 @@ $ tea milestone issue %[1]s v1.0 12 13 '#14'`, verb), Annotations: map[string]st
|
||||
return err
|
||||
}
|
||||
service := services.Issues{Client: target.client, Repository: target.Repo}
|
||||
results, failures := applyBatch(cmd, numbers, issueLabel, func(n int64) (services.Issue, error) {
|
||||
results, failures := applyBatch(cmd, numbers, issueLabel, func(n int64) (item services.Issue, err error) {
|
||||
if verb == "remove" {
|
||||
return service.RemoveMilestone(cmd.Context(), n, milestone)
|
||||
item, err = service.RemoveMilestone(cmd.Context(), n, milestone)
|
||||
} else {
|
||||
item, err = service.Edit(cmd.Context(), n, services.IssueEdit{Milestone: &milestone.ID})
|
||||
}
|
||||
return service.Edit(cmd.Context(), n, services.IssueEdit{Milestone: &milestone.ID})
|
||||
return item, itemError(err, target.Repo)
|
||||
}, func(services.Issue) {})
|
||||
if len(results) > 0 {
|
||||
changed := make([]string, len(results))
|
||||
|
||||
Reference in new issue
Block a user