mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
feat(app): report mutations on stderr and say what --web opens
Mutations printed a list row, or nothing, so a person could not tell what changed and scripts parsed rows meant for people. Commands now get the helpers for the gh convention: - done and warn print "✓ Closed issue alice/x#5 (Fix login)" and "! … is already closed" to stderr, only when stdout is a terminal and --json is not set. - printURL prints a created resource's URL to stdout unless --json is set, so url=$(tea issue create …) works. - batchDone applies a mutation to several selections like batch and reports each success with a done line instead of a table. - issueRef formats "alice/x#5 (title)" references. --web now prints "Opening localhost:3001/alice/project/issues/1 in your browser." to stderr on a terminal before the browser starts. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
4 files changed
+167
-12
No files matched your search
@@ -6,6 +6,7 @@ package app
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -348,6 +349,66 @@ func TestWriteView(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMutationFeedback(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name, json, out, stderr string
|
||||
tty bool
|
||||
}{
|
||||
{name: "terminal", tty: true, out: "https://example.org/12\n", stderr: "✓ Created issue alice/x#12 (Fix[2J login)\n! Issue alice/x#12 (Fix[2J login) is already closed\n"},
|
||||
{name: "piped", out: "https://example.org/12\n"},
|
||||
{name: "JSON", tty: true, json: "number"},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
deps, out, diagnostics := testDeps(t)
|
||||
deps.Streams.OutTTY = tc.tty
|
||||
deps.Getenv = envFunc(map[string]string{"NO_COLOR": "1"})
|
||||
a, cmd := outputApplication(deps, tc.json)
|
||||
ref := issueRef("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.Equal(t, tc.out, out.String())
|
||||
require.Equal(t, tc.stderr, diagnostics.String())
|
||||
})
|
||||
}
|
||||
deps, _, diagnostics := testDeps(t)
|
||||
deps.Streams.OutTTY = true
|
||||
a, cmd := outputApplication(deps, "")
|
||||
a.done(cmd, "Closed issue %s", "alice/x#5 (Bug)")
|
||||
a.warn(cmd, "nothing to do")
|
||||
require.Equal(t, "\x1b[32m✓\x1b[0m Closed issue alice/x#5 (Bug)\n\x1b[33m!\x1b[0m nothing to do\n", diagnostics.String())
|
||||
}
|
||||
|
||||
func TestBatchDoneReportsEachSuccess(t *testing.T) {
|
||||
run := func(n int64) (listed, error) {
|
||||
if n == 2 {
|
||||
return listed{}, errors.New("not found")
|
||||
}
|
||||
return listed{Number: n, Title: fmt.Sprintf("Issue %d", n)}, nil
|
||||
}
|
||||
label := func(n int64) string { return fmt.Sprintf("#%d", n) }
|
||||
report := func(item listed) string { return "Closed issue " + issueRef("alice/x", item.Number, item.Title) }
|
||||
for _, tc := range []struct {
|
||||
name, json, out, stderr string
|
||||
tty bool
|
||||
}{
|
||||
{name: "terminal", tty: true, stderr: "✓ Closed issue alice/x#1 (Issue 1)\n✓ Closed issue alice/x#3 (Issue 3)\n"},
|
||||
{name: "piped"},
|
||||
{name: "JSON", json: "number", out: `[{"number":1},{"number":3}]` + "\n"},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
deps, out, diagnostics := testDeps(t)
|
||||
deps.Streams.OutTTY = tc.tty
|
||||
deps.Getenv = envFunc(map[string]string{"NO_COLOR": "1"})
|
||||
a, cmd := outputApplication(deps, tc.json)
|
||||
err := batchDone(a, cmd, []int64{1, 2, 3}, label, run, report)
|
||||
require.EqualError(t, err, "#2: not found")
|
||||
require.Equal(t, tc.out, out.String())
|
||||
require.Equal(t, tc.stderr, diagnostics.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestShowing(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
shown int
|
||||
|
||||
Reference in new issue
Block a user