gitea.tea/cmd/pulls/create_app_test.go
ongolk b2bab268d7
Some checks failed
goreleaser / goreleaser (push) Has been cancelled
goreleaser / release-image (push) Has been cancelled
Make tea pulls create honor --output json (#1111)
## Problem

`tea pulls create` accepts `--output` (the flag parses successfully) but never reads it — the action always prints glamour-rendered markdown regardless of the requested format. That is a trap for anyone scripting the CLI: `tea pr create --output json | jq .url` quietly feeds jq a markdown document.

The current output is also hostile to URL-scraping consumers even without `--output`: glamour autolinks the bare PR URL into an OSC 8 terminal hyperlink, so piped stdout contains

```
\x1b]8;;https://host/owner/repo/pulls/33\x1b\\https://host/owner/repo/pulls/33\x1b]8;;\x1b\\
```

instead of a plain URL (repro: `tea pr create ... | cat -v`).

## Why the flag parses but does nothing

`create` itself does not declare `--output`: its flag set (`IssuePRCreateFlags`) carries no `OutputFlag`. The flag parses anyway because urfave/cli v3 resolves flags through `Command.lookupAppliedFlag`, which searches `appliedFlags` — "local flags for current command **or persistent flags from ancestors**". The parent `pulls` command carries `--output` via `AllDefaultFlags`, so the flag reaches the subcommand's parser while being absent from `create --help` — and was never consulted by the action.

## What this changes

- `task.CreatePull` now returns the created `*gitea.PullRequest` instead of printing it.
- `runPullsCreate` switches on `--output`, mirroring the existing detail-command precedent (`RunPullsDetails` in `cmd/pulls.go`): `--output json` emits a lean JSON object; any other value (or no flag at all) falls through to the previous `print.PullDetails` rendering, byte-identical to before.
- Lean JSON shape, since a freshly created PR has no reviews/comments/CI yet: `index`, `title`, `url`, `state`, `base`, `head`.
- `--agit` combined with `--output` now fails fast with an explicit error before any API call or `git push`: the agit flow creates the PR server-side via push and returns no object to print.
- The interactive path is untouched — it only triggers when zero flags are set, so `--output` can never be active there.

Example:

```
$ tea pr create --output json --title "fix: thing" | jq -r .url
https://gitea.example.com/owner/repo/pulls/33
```

---------

Co-authored-by: Danilo Sousa <code@danilosousa.net>
Reviewed-on: https://gitea.com/gitea/tea/pulls/1111
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: ongolk <238961+ongolk@noreply.gitea.com>
2026-09-08 19:20:40 +00:00

49 lines
1.2 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package pulls_test
import (
"context"
"testing"
"gitea.dev/tea/cmd"
"gitea.dev/tea/modules/config"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestPullsCreateAgitOutputRejected verifies that --output (parsed via the
// urfave/cli v3 ancestor-flag cascade, since create itself does not declare
// it) is rejected for the agit flow before any API call or git push happens.
func TestPullsCreateAgitOutputRejected(t *testing.T) {
config.SetConfigForTesting(config.LocalConfig{
Logins: []config.Login{{
Name: "testLogin",
URL: "https://gitea.example.com",
Token: "test-token",
User: "testUser",
Default: true,
}},
})
t.Cleanup(func() {
config.SetConfigForTesting(config.LocalConfig{})
})
app := cmd.App()
args := []string{
"tea", "pulls", "create",
"--agit",
"--output", "json",
"--head", "topic-branch",
"--title", "test",
"--login", "testLogin",
"--repo", "user/repo",
}
err := app.Run(context.Background(), args)
require.Error(t, err)
assert.Contains(t, err.Error(), "--output cannot be combined with --agit")
}