mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
feat(issue): gh-style issue list, view, create, edit, close and reopen
issue list renders through the shared table: a context line, ID TITLE LABELS [STATE] [KIND] AUTHOR UPDATED with relative times on a terminal, the ID colored by state and linked, and a stable tab-separated column set when piped; empty results say so on stderr. It gains -s -L -l -a -A -m -S -w, @me, comma-separated label and milestone filters, and --web. issue view, edit, close and reopen accept #N, OWNER/REPO#N and issue URLs. Mutations report "✓ Created/Edited/Closed issue alice/x#5 (title)" on a terminal; issue create prints the new issue's URL on stdout (also as issue new), and close and reopen skip issues already in that state with a ! line and take -c/--comment. issue create and edit gain the gh short flags and singular --add-label, --remove-label, --add-assignee and --remove-assignee (the plural names still work), and create gains --web. The interactive create form asks for the title and body, then "What's next?" (submit, add metadata or cancel), without a confirmation after it; the edit form names the issue it edits. Every issue command has help text with examples and completes its flags and issue numbers. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
18 files changed
+789
-376
No files matched your search
@@ -36,7 +36,7 @@ type Issue struct {
|
||||
// Kinds of Issue: Gitea lists pull requests among issues.
|
||||
const (
|
||||
KindIssue = "issue"
|
||||
KindPull = "pull"
|
||||
KindPull = "pr"
|
||||
)
|
||||
|
||||
// discussionFrom converts an issue or a pull request listed among issues; the state of a merged
|
||||
@@ -96,9 +96,15 @@ func (s Issues) endpoint() string { return "repos/" + s.Repository + "/issues" }
|
||||
// List returns a page of issues, even when the server caps its page size below the limit,
|
||||
// and reports whether more issues follow.
|
||||
func (s Issues) List(ctx context.Context, opts ListOptions) ([]Issue, bool, error) {
|
||||
page, err := s.ListPage(ctx, opts)
|
||||
return page.Items, page.More, err
|
||||
}
|
||||
|
||||
// ListPage is List with the number of issues that match, as the server counts them.
|
||||
func (s Issues) ListPage(ctx context.Context, opts ListOptions) (Page[Issue], error) {
|
||||
owner, repo, err := splitRepository(s.Repository)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return Page[Issue]{}, err
|
||||
}
|
||||
kind := "issues"
|
||||
if opts.Kind != "" {
|
||||
@@ -115,7 +121,7 @@ func (s Issues) List(ctx context.Context, opts ListOptions) ([]Issue, bool, erro
|
||||
if opts.Before != nil {
|
||||
query.Before = *opts.Before
|
||||
}
|
||||
issues, more, err := listWindow(opts.Limit, opts.Page, func(limit, page int) ([]*gitea.Issue, http.Header, error) {
|
||||
issues, err := listPage(opts.Limit, opts.Page, func(limit, page int) ([]*gitea.Issue, http.Header, error) {
|
||||
query.ListOptions = listOptions(limit, page)
|
||||
issues, resp, err := call(ctx, s.Client, func(ctx context.Context, c *gitea.Client) ([]*gitea.Issue, *gitea.Response, error) {
|
||||
return c.Issues.ListRepoIssues(ctx, owner, repo, query)
|
||||
@@ -123,9 +129,9 @@ func (s Issues) List(ctx context.Context, opts ListOptions) ([]Issue, bool, erro
|
||||
return issues, headerOf(resp), err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return Page[Issue]{}, err
|
||||
}
|
||||
return convertAll(issues, discussionFrom), more, nil
|
||||
return Page[Issue]{Items: convertAll(issues.Items, discussionFrom), More: issues.More, Total: issues.Total, Counted: issues.Counted}, nil
|
||||
}
|
||||
|
||||
// filterValues splits a comma-separated filter, which the SDK joins again.
|
||||
|
||||
Reference in new issue
Block a user