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
@@ -78,7 +78,7 @@ func TestIssueListRespectsColorNeverAndStillPages(t *testing.T) {
|
||||
}))
|
||||
defer server.Close()
|
||||
deps, out, _, pager := pagedDeps(t, server.URL, nil, "color", "never", "pager", "configured-pager")
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"issue", "list", "-R", "alice/project", "--no-input"}))
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"issue", "list", "-R", "alice/project", "--state", "all", "--no-input"}))
|
||||
require.Equal(t, 1, pager.calls)
|
||||
require.Equal(t, "configured-pager", pager.command)
|
||||
require.NotContains(t, pager.input, "\x1b[")
|
||||
@@ -172,9 +172,8 @@ func TestMultiItemHumanOutputPagesOnce(t *testing.T) {
|
||||
args []string
|
||||
want string
|
||||
}{
|
||||
{[]string{"milestone", "issue", "list", "3"}, "1 Issue 1 closed\n2 Issue 2 closed\n"},
|
||||
{[]string{"issue", "close", "1", "2"}, "1 Issue 1 closed\n2 Issue 2 closed\n"},
|
||||
{[]string{"branch", "list"}, "Showing 2 of 2 branches in alice/project\n\nNAME COMMIT PROTECTED UPDATED MESSAGE\nmain (default) abc\ndev def\n"},
|
||||
{[]string{"milestone", "issue", "list", "3"}, "1 Issue 1 closed issue\n2 Issue 2 closed issue\n"},
|
||||
{[]string{"issue", "comment", "list", "5"}, "1 alice\none\n\n2 bob\ntwo\n\n"},
|
||||
} {
|
||||
t.Run(tc.args[0]+" "+tc.args[1], func(t *testing.T) {
|
||||
@@ -224,21 +223,27 @@ func TestListsFitTheTerminalAndSplitWhenPiped(t *testing.T) {
|
||||
`{"number":5,"title":"支持中文路径 (support CJK paths)","state":"open","user":{"login":""}}]`))
|
||||
}))
|
||||
defer server.Close()
|
||||
for _, group := range []string{"issue"} {
|
||||
for group, want := range map[string][2]string{
|
||||
"issue": {
|
||||
"6\tA very long issue title that keeps going and going to see how list output handles wrapping\t\topen\tissue\talice\t\n" +
|
||||
"5\t支持中文路径 (support CJK paths)\t\topen\tissue\t\t\n",
|
||||
"Showing 2 of 2 open issues in alice/project\n\n" +
|
||||
"ID TITLE LABELS AUTHOR UPDATED\n" +
|
||||
"#6 A very long issue ti… alice\n" +
|
||||
"#5 支持中文路径 (suppor…\n",
|
||||
},
|
||||
} {
|
||||
t.Run(group, func(t *testing.T) {
|
||||
deps, out, _ := serverDeps(t, server.URL)
|
||||
args := []string{group, "list", "-R", "alice/project"}
|
||||
require.NoError(t, Execute(context.Background(), deps, args))
|
||||
require.Equal(t, "6\tA very long issue title that keeps going and going to see how list output handles wrapping\topen\talice\n"+
|
||||
"5\t支持中文路径 (support CJK paths)\topen\t\n", out.String())
|
||||
require.Equal(t, want[0], out.String())
|
||||
|
||||
out.Reset()
|
||||
deps.Streams.OutTTY, deps.Streams.Width = true, 50
|
||||
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1"})
|
||||
require.NoError(t, Execute(context.Background(), deps, args))
|
||||
require.Equal(t, "ID TITLE STATE AUTHOR\n"+
|
||||
"#6 A very long issue title that k… open alice\n"+
|
||||
"#5 支持中文路径 (support CJK path… open\n", stripLinks(out.String()))
|
||||
require.Equal(t, want[1], stripLinks(out.String()))
|
||||
for _, line := range strings.Split(strings.TrimSpace(out.String()), "\n") {
|
||||
require.LessOrEqual(t, runewidth.StringWidth(stripLinks(line)), 50, line)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user