mirror of
https://gitea.com/gitea/tea.git
synced 2026-09-10 07:26:33 -04:00
Compare commits
No commits in common. "main" and "v0.14.1" have entirely different histories.
|
|
@ -8,47 +8,36 @@ jobs:
|
|||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: git fetch --force --tags
|
||||
# Custom publishers (the R2 upload below) run as the very last
|
||||
# step of goreleaser's publish pipeline, after the Gitea release
|
||||
# has already been created. Fail here instead, before anything
|
||||
# is built or published, if the R2 secrets are missing.
|
||||
- name: check R2 configuration
|
||||
run: sh scripts/upload-r2.sh --check-config
|
||||
env:
|
||||
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
||||
R2_BUCKET: ${{ secrets.R2_BUCKET }}
|
||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
check-latest: true
|
||||
- name: import gpg
|
||||
id: import_gpg
|
||||
uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7
|
||||
uses: crazy-max/ghaction-import-gpg@v7
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
|
||||
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
||||
- name: get SDK version
|
||||
id: sdk_version
|
||||
run: echo "version=$(go list -f '{{.Version}}' -m gitea.dev/sdk)" >> "$GITHUB_OUTPUT"
|
||||
run: echo "version=$(go list -f '{{.Version}}' -m code.gitea.io/sdk/gitea)" >> "$GITHUB_OUTPUT"
|
||||
- name: goreleaser
|
||||
uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
with:
|
||||
distribution: goreleaser-pro
|
||||
version: "~> v2"
|
||||
version: "~> v1"
|
||||
args: release --nightly
|
||||
env:
|
||||
SDK_VERSION: ${{ steps.sdk_version.outputs.version }}
|
||||
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
||||
R2_BUCKET: ${{ secrets.R2_BUCKET }}
|
||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
AWS_REGION: ${{ secrets.AWS_REGION }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
S3_REGION: ${{ secrets.AWS_REGION }}
|
||||
S3_BUCKET: ${{ secrets.AWS_BUCKET }}
|
||||
GORELEASER_FORCE_TOKEN: 'gitea'
|
||||
GPGSIGN_PASSPHRASE: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
||||
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
||||
|
|
@ -60,24 +49,24 @@ jobs:
|
|||
DOCKER_LATEST: nightly
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0 # all history for all branches and tags
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker BuildX
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
|
||||
uses: docker/build-push-action@v7
|
||||
env:
|
||||
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -9,47 +9,36 @@ jobs:
|
|||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: git fetch --force --tags
|
||||
# Custom publishers (the R2 upload below) run as the very last
|
||||
# step of goreleaser's publish pipeline, after the Gitea release
|
||||
# has already been created. Fail here instead, before anything
|
||||
# is built or published, if the R2 secrets are missing.
|
||||
- name: check R2 configuration
|
||||
run: sh scripts/upload-r2.sh --check-config
|
||||
env:
|
||||
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
||||
R2_BUCKET: ${{ secrets.R2_BUCKET }}
|
||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
check-latest: true
|
||||
- name: import gpg
|
||||
id: import_gpg
|
||||
uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7
|
||||
uses: crazy-max/ghaction-import-gpg@v7
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
|
||||
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
||||
- name: get SDK version
|
||||
id: sdk_version
|
||||
run: echo "version=$(go list -f '{{.Version}}' -m gitea.dev/sdk)" >> "$GITHUB_OUTPUT"
|
||||
run: echo "version=$(go list -f '{{.Version}}' -m code.gitea.io/sdk/gitea)" >> "$GITHUB_OUTPUT"
|
||||
- name: goreleaser
|
||||
uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
with:
|
||||
distribution: goreleaser-pro
|
||||
version: "~> v2"
|
||||
version: "~> v1"
|
||||
args: release
|
||||
env:
|
||||
SDK_VERSION: ${{ steps.sdk_version.outputs.version }}
|
||||
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
||||
R2_BUCKET: ${{ secrets.R2_BUCKET }}
|
||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
AWS_REGION: ${{ secrets.AWS_REGION }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
S3_REGION: ${{ secrets.AWS_REGION }}
|
||||
S3_BUCKET: ${{ secrets.AWS_BUCKET }}
|
||||
GORELEASER_FORCE_TOKEN: 'gitea'
|
||||
GPGSIGN_PASSPHRASE: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
||||
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
||||
|
|
@ -61,18 +50,18 @@ jobs:
|
|||
DOCKER_LATEST: nightly
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0 # all history for all branches and tags
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker BuildX
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
|
@ -82,7 +71,7 @@ jobs:
|
|||
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
|
||||
uses: docker/build-push-action@v7
|
||||
env:
|
||||
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -16,11 +16,10 @@ jobs:
|
|||
name: Lint Build And Unit Coverage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
check-latest: true
|
||||
- name: lint and build
|
||||
run: |
|
||||
make clean
|
||||
|
|
@ -42,29 +41,17 @@ jobs:
|
|||
GITEA_TEA_TEST_USERNAME: "test01"
|
||||
GITEA_TEA_TEST_PASSWORD: "test01"
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
check-latest: true
|
||||
- name: wait for the gitea instance to be ready
|
||||
run: |
|
||||
for i in $(seq 1 30); do
|
||||
if curl --noproxy "*" -sf http://gitea:3000/api/v1/version; then
|
||||
echo "gitea is ready after ${i} attempt(s)"
|
||||
exit 0
|
||||
fi
|
||||
echo "waiting for gitea, attempt ${i}/30"
|
||||
sleep 2
|
||||
done
|
||||
echo "::error::gitea did not become ready within 60s"
|
||||
exit 1
|
||||
- run: curl --noproxy "*" http://gitea:3000/api/v1/version # verify connection to instance
|
||||
- name: integration test
|
||||
run: |
|
||||
make integration-test
|
||||
services:
|
||||
gitea:
|
||||
image: docker.gitea.com/gitea:1.27.0
|
||||
image: docker.gitea.com/gitea:1.26.1
|
||||
cmd:
|
||||
- bash
|
||||
- -c
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
version: 2
|
||||
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
|
|
@ -58,7 +56,7 @@ builds:
|
|||
flags:
|
||||
- -trimpath
|
||||
ldflags:
|
||||
- -s -w -X "gitea.dev/tea/modules/version.Version={{ trimprefix .Summary "v" }}" -X "gitea.dev/tea/modules/version.Tags=" -X "gitea.dev/tea/modules/version.SDK={{ .Env.SDK_VERSION }}"
|
||||
- -s -w -X "code.gitea.io/tea/modules/version.Version={{ trimprefix .Summary "v" }}" -X "code.gitea.io/tea/modules/version.Tags=" -X "code.gitea.io/tea/modules/version.SDK={{ .Env.SDK_VERSION }}"
|
||||
binary: >-
|
||||
{{ .ProjectName }}-
|
||||
{{- .Version }}-
|
||||
|
|
@ -76,43 +74,15 @@ builds:
|
|||
- cmd: sh .goreleaser.checksum.sh {{ .Path }}
|
||||
- cmd: sh .goreleaser.checksum.sh {{ .Path }}.xz
|
||||
|
||||
# Uploads the release artifacts to Cloudflare R2. A `blobs:` entry is
|
||||
# not used here since the blob pipe authenticates from the global
|
||||
# AWS_* env with no per-entry credentials; `publishers:` supports
|
||||
# per-entry `env:` instead, so it's used to invoke
|
||||
# scripts/upload-r2.sh once per artifact. Custom publishers inherit
|
||||
# almost nothing from the environment, hence the explicit R2_*
|
||||
# forwarding below.
|
||||
#
|
||||
# This publisher fires more than once per distinct key because
|
||||
# goreleaser's release pipe already registers `release.extra_files`
|
||||
# (./**.xz and ./**.xz.sha256, see the `release:` block below) as
|
||||
# UploadableFile artifacts, and `internal/exec`'s filterArtifacts
|
||||
# appends this block's own extra_files with no de-duplication. It
|
||||
# can't be globbed away, since gobwas/glob (via goreleaser/fileglob)
|
||||
# has no substring-exclusion matcher. It's harmless: PUT is
|
||||
# idempotent, and the `./**.xz` glob below is kept deliberately so
|
||||
# this publisher declares its own complete file set rather than
|
||||
# implicitly depending on the `release:` block's globs.
|
||||
#
|
||||
# checksum: true mirrors goreleaser's generated checksums.txt;
|
||||
# signature: true additionally mirrors checksums.txt.sig, which the
|
||||
# `signs:` block below produces by GPG-signing that checksum file.
|
||||
# Without signature: true, artifacts downloaded from the R2 mirror
|
||||
# would have no signature file to verify against.
|
||||
publishers:
|
||||
- name: cloudflare-r2
|
||||
checksum: true
|
||||
signature: true
|
||||
blobs:
|
||||
-
|
||||
provider: s3
|
||||
bucket: "{{ .Env.S3_BUCKET }}"
|
||||
region: "{{ .Env.S3_REGION }}"
|
||||
folder: "tea/{{.Version}}"
|
||||
extra_files:
|
||||
- glob: ./**.xz
|
||||
- glob: ./**.sha256
|
||||
cmd: sh scripts/upload-r2.sh {{ abs .ArtifactPath }} tea/{{ .Version }}/{{ .ArtifactName }}
|
||||
env:
|
||||
- R2_ENDPOINT={{ index .Env "R2_ENDPOINT" }}
|
||||
- R2_BUCKET={{ index .Env "R2_BUCKET" }}
|
||||
- R2_ACCESS_KEY_ID={{ index .Env "R2_ACCESS_KEY_ID" }}
|
||||
- R2_SECRET_ACCESS_KEY={{ index .Env "R2_SECRET_ACCESS_KEY" }}
|
||||
|
||||
archives:
|
||||
- format: binary
|
||||
|
|
@ -134,10 +104,10 @@ signs:
|
|||
args: ["--batch", "-u", "{{ .Env.GPG_FINGERPRINT }}", "--output", "${signature}", "--detach-sign", "${artifact}"]
|
||||
|
||||
snapshot:
|
||||
version_template: "{{ .Branch }}-devel"
|
||||
name_template: "{{ .Branch }}-devel"
|
||||
|
||||
nightly:
|
||||
version_template: "{{ .Branch }}"
|
||||
name_template: "{{ .Branch }}"
|
||||
|
||||
gitea_urls:
|
||||
api: https://gitea.com/api/v1
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ import (
|
|||
|
||||
// local packages
|
||||
"code.gitea.io/gitea/models"
|
||||
"gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
|
||||
// external packages
|
||||
"github.com/foo/bar"
|
||||
|
|
|
|||
14
Makefile
14
Makefile
|
|
@ -24,17 +24,16 @@ endif
|
|||
TEA_VERSION_TAG ?= $(shell sed 's/+/_/' <<< $(TEA_VERSION))
|
||||
|
||||
TAGS ?=
|
||||
SDK ?= $(shell $(GO) list -f '{{.Version}}' -m gitea.dev/sdk)
|
||||
LDFLAGS := -X "gitea.dev/tea/modules/version.Version=$(TEA_VERSION)" -X "gitea.dev/tea/modules/version.Tags=$(TAGS)" -X "gitea.dev/tea/modules/version.SDK=$(SDK)" -s -w
|
||||
SDK ?= $(shell $(GO) list -f '{{.Version}}' -m code.gitea.io/sdk/gitea)
|
||||
LDFLAGS := -X "code.gitea.io/tea/modules/version.Version=$(TEA_VERSION)" -X "code.gitea.io/tea/modules/version.Tags=$(TAGS)" -X "code.gitea.io/tea/modules/version.SDK=$(SDK)" -s -w
|
||||
|
||||
# override to allow passing additional goflags via make CLI
|
||||
override GOFLAGS := $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)'
|
||||
|
||||
PACKAGES ?= $(shell $(GO) list ./... | grep -v '^gitea.dev/tea/tests')
|
||||
PACKAGES ?= $(shell $(GO) list ./... | grep -v '^code.gitea.io/tea/tests')
|
||||
UNIT_PACKAGES ?= $(PACKAGES)
|
||||
INTEGRATION_PACKAGES ?= $(shell $(GO) list ./tests/... 2>/dev/null)
|
||||
INTEGRATION_TEST_TAGS ?= testtools
|
||||
INTEGRATION_TEST_GOFLAGS ?= -v
|
||||
SOURCES ?= $(shell find . -name "*.go" -type f)
|
||||
|
||||
# OS specific vars.
|
||||
|
|
@ -104,7 +103,7 @@ unit-test:
|
|||
.PHONY: integration-test
|
||||
integration-test:
|
||||
@if [ -n "$(INTEGRATION_PACKAGES)" ]; then \
|
||||
$(GO) test $(INTEGRATION_TEST_GOFLAGS) -tags='$(INTEGRATION_TEST_TAGS)' $(INTEGRATION_PACKAGES); \
|
||||
$(GO) test -tags='$(INTEGRATION_TEST_TAGS)' $(INTEGRATION_PACKAGES); \
|
||||
else \
|
||||
echo "No integration test packages found"; \
|
||||
fi
|
||||
|
|
@ -118,12 +117,7 @@ unit-test-coverage:
|
|||
|
||||
.PHONY: tidy
|
||||
tidy:
|
||||
$(eval GO_TOOLCHAIN := $(shell grep -Eo '^toolchain\s+go[0-9.]+' go.mod | cut -d' ' -f2))
|
||||
$(GO) mod tidy
|
||||
@# workaround https://github.com/golang/go/issues/75331: restore toolchain if tidy dropped it
|
||||
@if [ -n "$(GO_TOOLCHAIN)" ] && ! grep -qE '^toolchain\s' go.mod; then \
|
||||
$(GO) mod edit -toolchain=$(GO_TOOLCHAIN); \
|
||||
fi
|
||||
|
||||
.PHONY: check
|
||||
check: test
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://gitea.com/gitea/tea/releases)
|
||||
[](https://discord.gg/Gitea)
|
||||
[](https://goreportcard.com/report/gitea.dev/tea) [](https://godoc.org/gitea.dev/tea)
|
||||
[](https://goreportcard.com/report/code.gitea.io/tea) [](https://godoc.org/code.gitea.io/tea)
|
||||

|
||||
|
||||
## The official CLI for Gitea
|
||||
|
|
@ -97,7 +97,7 @@ ABOUT
|
|||
More info about Gitea itself on https://about.gitea.com.
|
||||
```
|
||||
|
||||
- tea uses [gitea.dev/sdk](https://gitea.dev/sdk) and interacts with the Gitea API.
|
||||
- tea uses [code.gitea.io/sdk](https://code.gitea.io/sdk) and interacts with the Gitea API.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ Make sure you have a current Go version installed (1.26 or newer).
|
|||
|
||||
- For a quick installation without `git` & `make`, set $version and exec:
|
||||
```sh
|
||||
go install gitea.dev/tea@${version}
|
||||
go install code.gitea.io/tea@${version}
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package cmd
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"gitea.dev/tea/cmd/actions"
|
||||
"code.gitea.io/tea/cmd/actions"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package actions
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"gitea.dev/tea/cmd/actions/runs"
|
||||
"code.gitea.io/tea/cmd/actions/runs"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -61,7 +61,7 @@ func runRunsDelete(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
}
|
||||
|
||||
_, err = client.Actions.DeleteRepoRun(ctx, c.Owner, c.Repo, runID)
|
||||
_, err = client.DeleteRepoActionRun(c.Owner, c.Repo, runID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete run: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ func RunRunsList(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
// Build list options
|
||||
listOpts := flags.GetListOptions(cmd)
|
||||
|
||||
runs, _, err := client.Actions.ListRepoRuns(ctx, c.Owner, c.Repo, gitea.ListRepoActionRunsOptions{
|
||||
runs, _, err := client.ListRepoActionRuns(c.Owner, c.Repo, gitea.ListRepoActionRunsOptions{
|
||||
ListOptions: listOpts,
|
||||
Status: cmd.String("status"),
|
||||
Branch: cmd.String("branch"),
|
||||
|
|
|
|||
|
|
@ -4,15 +4,15 @@
|
|||
package runs
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/modules/config"
|
||||
)
|
||||
|
||||
func TestFilterRunsByTime(t *testing.T) {
|
||||
|
|
@ -106,6 +106,6 @@ func TestRunRunsListRequiresRepoContext(t *testing.T) {
|
|||
}
|
||||
require.NoError(t, cmd.Set("login", "test"))
|
||||
|
||||
err = RunRunsList(t.Context(), cmd)
|
||||
err = RunRunsList(stdctx.Background(), cmd)
|
||||
require.ErrorContains(t, err, "remote repository required")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -69,10 +69,10 @@ func runRunsLogs(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
if follow {
|
||||
return followJobLogs(ctx, client, c, jobID, "")
|
||||
return followJobLogs(client, c, jobID, "")
|
||||
}
|
||||
|
||||
logs, _, err := client.Actions.GetRepoRunJobLogs(ctx, c.Owner, c.Repo, jobID)
|
||||
logs, _, err := client.GetRepoActionJobLogs(c.Owner, c.Repo, jobID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get logs for job %d: %w", jobID, err)
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ func runRunsLogs(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
// Otherwise, fetch all jobs and their logs
|
||||
jobs, _, err := client.Actions.ListRepoJobsByRun(ctx, c.Owner, c.Repo, runID, gitea.ListRepoActionJobsOptions{
|
||||
jobs, _, err := client.ListRepoActionRunJobs(c.Owner, c.Repo, runID, gitea.ListRepoActionJobsOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -102,7 +102,7 @@ func runRunsLogs(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
|
||||
// If following with single job, follow it
|
||||
if follow && len(jobs.Jobs) == 1 {
|
||||
return followJobLogs(ctx, client, c, jobs.Jobs[0].ID, jobs.Jobs[0].Name)
|
||||
return followJobLogs(client, c, jobs.Jobs[0].ID, jobs.Jobs[0].Name)
|
||||
}
|
||||
|
||||
// Fetch logs for each job
|
||||
|
|
@ -115,7 +115,7 @@ func runRunsLogs(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
fmt.Printf("Status: %s\n", job.Status)
|
||||
fmt.Println("---")
|
||||
|
||||
logs, _, err := client.Actions.GetRepoRunJobLogs(ctx, c.Owner, c.Repo, job.ID)
|
||||
logs, _, err := client.GetRepoActionJobLogs(c.Owner, c.Repo, job.ID)
|
||||
if err != nil {
|
||||
fmt.Printf("Error fetching logs: %v\n", err)
|
||||
continue
|
||||
|
|
@ -128,7 +128,7 @@ func runRunsLogs(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
// followJobLogs continuously fetches and displays logs for a running job
|
||||
func followJobLogs(requestCtx stdctx.Context, client *gitea.Client, c *context.TeaContext, jobID int64, jobName string) error {
|
||||
func followJobLogs(client *gitea.Client, c *context.TeaContext, jobID int64, jobName string) error {
|
||||
var lastLogLength int
|
||||
|
||||
if jobName != "" {
|
||||
|
|
@ -140,7 +140,7 @@ func followJobLogs(requestCtx stdctx.Context, client *gitea.Client, c *context.T
|
|||
|
||||
for {
|
||||
// Fetch job status
|
||||
job, _, err := client.Actions.GetRepoRunJob(requestCtx, c.Owner, c.Repo, jobID)
|
||||
job, _, err := client.GetRepoActionJob(c.Owner, c.Repo, jobID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get job: %w", err)
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ func followJobLogs(requestCtx stdctx.Context, client *gitea.Client, c *context.T
|
|||
isRunning := job.Status == "in_progress" || job.Status == "queued" || job.Status == "pending"
|
||||
|
||||
// Fetch logs
|
||||
logs, _, err := client.Actions.GetRepoRunJobLogs(requestCtx, c.Owner, c.Repo, jobID)
|
||||
logs, _, err := client.GetRepoActionJobLogs(c.Owner, c.Repo, jobID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get logs: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ func runRunsView(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
// Fetch run details
|
||||
run, _, err := client.Actions.GetRepoRun(ctx, c.Owner, c.Repo, runID)
|
||||
run, _, err := client.GetRepoActionRun(c.Owner, c.Repo, runID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get run: %w", err)
|
||||
}
|
||||
|
|
@ -63,7 +64,7 @@ func runRunsView(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
|
||||
// Fetch and print jobs if requested
|
||||
if cmd.Bool("jobs") {
|
||||
jobs, _, err := client.Actions.ListRepoJobsByRun(ctx, c.Owner, c.Repo, runID, gitea.ListRepoActionJobsOptions{
|
||||
jobs, _, err := client.ListRepoActionRunJobs(c.Owner, c.Repo, runID, gitea.ListRepoActionJobsOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package actions
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"gitea.dev/tea/cmd/actions/secrets"
|
||||
"code.gitea.io/tea/cmd/actions/secrets"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ func runSecretsCreate(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = client.Actions.CreateRepoSecret(ctx, c.Owner, c.Repo, secretName, gitea.CreateOrUpdateSecretOption{
|
||||
_, err = client.CreateRepoActionSecret(c.Owner, c.Repo, secretName, gitea.CreateOrUpdateSecretOption{
|
||||
Data: secretValue,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -56,7 +56,7 @@ func runSecretsDelete(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
}
|
||||
|
||||
_, err = client.Actions.DeleteRepoSecret(ctx, c.Owner, c.Repo, secretName)
|
||||
_, err = client.DeleteRepoActionSecret(c.Owner, c.Repo, secretName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ package secrets
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ func RunSecretsList(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
client := c.Login.Client()
|
||||
|
||||
secrets, _, err := client.Actions.ListRepoSecrets(ctx, c.Owner, c.Repo, gitea.ListRepoActionSecretOption{
|
||||
secrets, _, err := client.ListRepoActionSecret(c.Owner, c.Repo, gitea.ListRepoActionSecretOption{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@
|
|||
package secrets
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/modules/config"
|
||||
)
|
||||
|
||||
func TestSecretsListFlags(t *testing.T) {
|
||||
|
|
@ -93,6 +93,6 @@ func TestRunSecretsListRequiresRepoContext(t *testing.T) {
|
|||
}
|
||||
require.NoError(t, cmd.Set("login", "test"))
|
||||
|
||||
err = RunSecretsList(t.Context(), cmd)
|
||||
err = RunSecretsList(stdctx.Background(), cmd)
|
||||
require.ErrorContains(t, err, "remote repository required")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package actions
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"gitea.dev/tea/cmd/actions/variables"
|
||||
"code.gitea.io/tea/cmd/actions/variables"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -56,7 +56,7 @@ func runVariablesDelete(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
}
|
||||
|
||||
_, err = client.Actions.DeleteRepoVariable(ctx, c.Owner, c.Repo, variableName)
|
||||
_, err = client.DeleteRepoActionVariable(c.Owner, c.Repo, variableName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -42,7 +42,7 @@ func RunVariablesList(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
|
||||
if name := cmd.String("name"); name != "" {
|
||||
// Get specific variable
|
||||
variable, _, err := client.Actions.GetRepoVariable(ctx, c.Owner, c.Repo, name)
|
||||
variable, _, err := client.GetRepoActionVariable(c.Owner, c.Repo, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@
|
|||
package variables
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/modules/config"
|
||||
)
|
||||
|
||||
func TestVariablesListFlags(t *testing.T) {
|
||||
|
|
@ -93,6 +93,6 @@ func TestRunVariablesListRequiresRepoContext(t *testing.T) {
|
|||
}
|
||||
require.NoError(t, cmd.Set("login", "test"))
|
||||
|
||||
err = RunVariablesList(t.Context(), cmd)
|
||||
err = RunVariablesList(stdctx.Background(), cmd)
|
||||
require.ErrorContains(t, err, "remote repository required")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import (
|
|||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -69,7 +69,7 @@ func runVariablesSet(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = client.Actions.CreateRepoVariable(ctx, c.Owner, c.Repo, variableName, variableValue)
|
||||
_, err = client.CreateRepoActionVariable(c.Owner, c.Repo, variableName, variableValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package actions
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"gitea.dev/tea/cmd/actions/workflows"
|
||||
"code.gitea.io/tea/cmd/actions/workflows"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -55,7 +55,7 @@ func runWorkflowsDisable(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
}
|
||||
|
||||
_, err = client.Actions.DisableRepoWorkflow(ctx, c.Owner, c.Repo, workflowID)
|
||||
_, err = client.DisableRepoActionWorkflow(c.Owner, c.Repo, workflowID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to disable workflow: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ func runWorkflowsDispatch(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
Inputs: inputs,
|
||||
}
|
||||
|
||||
details, _, err := client.Actions.DispatchRepoWorkflow(ctx, c.Owner, c.Repo, workflowID, opt, true)
|
||||
details, _, err := client.DispatchRepoActionWorkflow(c.Owner, c.Repo, workflowID, opt, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to dispatch workflow: %w", err)
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ func runWorkflowsDispatch(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
print.ActionWorkflowDispatchResult(details)
|
||||
|
||||
if cmd.Bool("follow") && details != nil && details.WorkflowRunID > 0 {
|
||||
return followDispatchedRun(ctx, client, c, details.WorkflowRunID)
|
||||
return followDispatchedRun(client, c, details.WorkflowRunID)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -107,7 +107,7 @@ const (
|
|||
)
|
||||
|
||||
// followDispatchedRun waits for the dispatched run to start, then follows its logs
|
||||
func followDispatchedRun(ctx stdctx.Context, client *gitea.Client, c *context.TeaContext, runID int64) error {
|
||||
func followDispatchedRun(client *gitea.Client, c *context.TeaContext, runID int64) error {
|
||||
fmt.Printf("\nWaiting for run %d to start...\n", runID)
|
||||
|
||||
var jobs *gitea.ActionWorkflowJobsResponse
|
||||
|
|
@ -115,7 +115,7 @@ func followDispatchedRun(ctx stdctx.Context, client *gitea.Client, c *context.Te
|
|||
time.Sleep(followPollInterval)
|
||||
|
||||
var err error
|
||||
jobs, _, err = client.Actions.ListRepoJobsByRun(ctx, c.Owner, c.Repo, runID, gitea.ListRepoActionJobsOptions{})
|
||||
jobs, _, err = client.ListRepoActionRunJobs(c.Owner, c.Repo, runID, gitea.ListRepoActionJobsOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get jobs: %w", err)
|
||||
}
|
||||
|
|
@ -136,14 +136,14 @@ func followDispatchedRun(ctx stdctx.Context, client *gitea.Client, c *context.Te
|
|||
deadline := time.Now().Add(followMaxDuration)
|
||||
var lastLogLength int
|
||||
for time.Now().Before(deadline) {
|
||||
job, _, err := client.Actions.GetRepoRunJob(ctx, c.Owner, c.Repo, jobID)
|
||||
job, _, err := client.GetRepoActionJob(c.Owner, c.Repo, jobID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get job: %w", err)
|
||||
}
|
||||
|
||||
isRunning := job.Status == "in_progress" || job.Status == "queued" || job.Status == "pending"
|
||||
|
||||
logs, _, logErr := client.Actions.GetRepoRunJobLogs(ctx, c.Owner, c.Repo, jobID)
|
||||
logs, _, logErr := client.GetRepoActionJobLogs(c.Owner, c.Repo, jobID)
|
||||
if logErr != nil && isRunning {
|
||||
time.Sleep(followPollInterval)
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -38,7 +38,7 @@ func runWorkflowsEnable(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
client := c.Login.Client()
|
||||
|
||||
workflowID := cmd.Args().First()
|
||||
_, err = client.Actions.EnableRepoWorkflow(ctx, c.Owner, c.Repo, workflowID)
|
||||
_, err = client.EnableRepoActionWorkflow(c.Owner, c.Repo, workflowID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to enable workflow: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ func RunWorkflowsList(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
client := c.Login.Client()
|
||||
|
||||
resp, _, err := client.Actions.ListRepoWorkflows(ctx, c.Owner, c.Repo)
|
||||
resp, _, err := client.ListRepoActionWorkflows(c.Owner, c.Repo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list workflows: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -40,7 +40,7 @@ func runWorkflowsView(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
client := c.Login.Client()
|
||||
|
||||
workflowID := cmd.Args().First()
|
||||
wf, _, err := client.Actions.GetRepoWorkflow(ctx, c.Owner, c.Repo, workflowID)
|
||||
wf, _, err := client.GetRepoActionWorkflow(c.Owner, c.Repo, workflowID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get workflow: %w", err)
|
||||
}
|
||||
|
|
|
|||
13
cmd/admin.go
13
cmd/admin.go
|
|
@ -6,11 +6,10 @@ package cmd
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"code.gitea.io/tea/cmd/admin/users"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/admin/users"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
)
|
||||
|
||||
// CmdAdmin represents the namespace of admin commands.
|
||||
|
|
@ -20,7 +19,7 @@ var CmdAdmin = cli.Command{
|
|||
Usage: "Operations requiring admin access on the Gitea instance",
|
||||
Aliases: []string{"a"},
|
||||
Category: catMisc,
|
||||
Action: func(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
Action: func(_ stdctx.Context, cmd *cli.Command) error {
|
||||
return cli.ShowSubcommandHelp(cmd)
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
|
|
@ -47,13 +46,13 @@ var cmdAdminUsers = cli.Command{
|
|||
Flags: users.CmdUserList.Flags,
|
||||
}
|
||||
|
||||
func runAdminUserDetail(requestCtx stdctx.Context, cmd *cli.Command, u string) error {
|
||||
func runAdminUserDetail(_ stdctx.Context, cmd *cli.Command, u string) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := ctx.Login.Client()
|
||||
user, _, err := client.Users.GetUserInfo(requestCtx, u)
|
||||
user, _, err := client.GetUserInfo(u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
|
@ -83,7 +83,7 @@ var CmdUserCreate = cli.Command{
|
|||
}
|
||||
|
||||
// RunUserCreate creates a new user
|
||||
func RunUserCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunUserCreate(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -177,7 +177,7 @@ func RunUserCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
createOpts.Visibility = vis
|
||||
|
||||
// Create the user
|
||||
user, _, err := client.Admin.CreateUser(requestCtx, createOpts)
|
||||
user, _, err := client.AdminCreateUser(createOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -202,13 +202,13 @@ func RunUserCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
// Update user with admin/restricted/prohibit-login settings
|
||||
_, err = client.Admin.EditUser(requestCtx, username, editOpts)
|
||||
_, err = client.AdminEditUser(username, editOpts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user created but failed to update admin/restricted/prohibit-login status: %w", err)
|
||||
}
|
||||
|
||||
// Refresh user info to reflect the changes
|
||||
user, _, err = client.Users.GetUserInfo(requestCtx, username)
|
||||
user, _, err = client.GetUserInfo(username)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user updated but failed to retrieve updated user info: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -31,7 +31,7 @@ var CmdUserDelete = cli.Command{
|
|||
}
|
||||
|
||||
// RunUserDelete deletes a user
|
||||
func RunUserDelete(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunUserDelete(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -45,7 +45,7 @@ func RunUserDelete(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
username := ctx.Args().First()
|
||||
|
||||
// Get user details first to show what we're deleting
|
||||
user, _, err := client.Users.GetUserInfo(requestCtx, username)
|
||||
user, _, err := client.GetUserInfo(username)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get user info: %w", err)
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ func RunUserDelete(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
}
|
||||
|
||||
_, err = client.Admin.DeleteUser(requestCtx, username)
|
||||
_, err = client.AdminDeleteUser(username)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete user: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
|
@ -134,7 +135,7 @@ var CmdUserEdit = cli.Command{
|
|||
}
|
||||
|
||||
// RunUserEdit edits an existing user
|
||||
func RunUserEdit(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunUserEdit(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -148,7 +149,7 @@ func RunUserEdit(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
username := ctx.Args().First()
|
||||
|
||||
// Verify the user exists before attempting an update.
|
||||
_, _, err = client.Users.GetUserInfo(requestCtx, username)
|
||||
_, _, err = client.GetUserInfo(username)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get user info: %w", err)
|
||||
}
|
||||
|
|
@ -357,13 +358,13 @@ func RunUserEdit(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
// Update the user
|
||||
_, err = client.Admin.EditUser(requestCtx, username, editOpts)
|
||||
_, err = client.AdminEditUser(username, editOpts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update user: %w", err)
|
||||
}
|
||||
|
||||
// Refresh user info to reflect the changes
|
||||
updatedUser, _, err := client.Users.GetUserInfo(requestCtx, username)
|
||||
updatedUser, _, err := client.GetUserInfo(username)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user updated but failed to retrieve updated user info: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ package users
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ var CmdUserList = cli.Command{
|
|||
}
|
||||
|
||||
// RunUserList list users
|
||||
func RunUserList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunUserList(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -45,7 +45,7 @@ func RunUserList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
client := ctx.Login.Client()
|
||||
users, _, err := client.Admin.ListUsers(requestCtx, gitea.AdminListUsersOptions{
|
||||
users, _, err := client.AdminListUsers(gitea.AdminListUsersOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
)
|
||||
|
||||
func parseUserVisibility(visibility string) (*gitea.VisibleType, error) {
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/api"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/api"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
"golang.org/x/term"
|
||||
|
|
@ -104,7 +104,7 @@ type preparedAPIRequest struct {
|
|||
Body []byte
|
||||
}
|
||||
|
||||
func runApi(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runApi(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -8,14 +8,16 @@ import (
|
|||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/context"
|
||||
tea_git "gitea.dev/tea/modules/git"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
tea_git "code.gitea.io/tea/modules/git"
|
||||
|
||||
gogit "github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
|
@ -296,7 +298,7 @@ func runApiWithArgs(t *testing.T, args []string) (method string, body []byte, er
|
|||
}
|
||||
|
||||
fullArgs := append([]string{"api", "--login", "testLogin"}, args...)
|
||||
runErr := cmd.Run(t.Context(), fullArgs)
|
||||
runErr := cmd.Run(stdctx.Background(), fullArgs)
|
||||
|
||||
return capturedMethod, capturedBody, runErr
|
||||
}
|
||||
|
|
@ -570,32 +572,33 @@ func TestExpandPlaceholders(t *testing.T) {
|
|||
|
||||
t.Run("replaces branch from local repo HEAD", func(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
runGit := func(args ...string) {
|
||||
cmd := exec.Command("git", args...)
|
||||
cmd.Dir = tmpDir
|
||||
require.NoError(t, cmd.Run())
|
||||
}
|
||||
|
||||
runGit("init")
|
||||
runGit("config", "user.email", "test@test.com")
|
||||
runGit("config", "user.name", "test")
|
||||
repo, err := gogit.PlainInit(tmpDir, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create an initial commit so HEAD points to a branch.
|
||||
wt, err := repo.Worktree()
|
||||
require.NoError(t, err)
|
||||
tmpFile := filepath.Join(tmpDir, "init.txt")
|
||||
require.NoError(t, os.WriteFile(tmpFile, []byte("init"), 0o644))
|
||||
runGit("add", "init.txt")
|
||||
runGit("commit", "-m", "initial commit")
|
||||
_, err = wt.Add("init.txt")
|
||||
require.NoError(t, err)
|
||||
_, err = wt.Commit("initial commit", &gogit.CommitOptions{
|
||||
Author: &object.Signature{Name: "test", Email: "test@test.com"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create and checkout a feature branch.
|
||||
runGit("checkout", "-b", "feature/my-branch")
|
||||
|
||||
repo, err := tea_git.RepoFromPath(tmpDir)
|
||||
headRef, err := repo.Head()
|
||||
require.NoError(t, err)
|
||||
branchRef := plumbing.NewBranchReferenceName("feature/my-branch")
|
||||
ref := plumbing.NewHashReference(branchRef, headRef.Hash())
|
||||
require.NoError(t, repo.Storer.SetReference(ref))
|
||||
require.NoError(t, wt.Checkout(&gogit.CheckoutOptions{Branch: branchRef}))
|
||||
|
||||
ctx := &context.TeaContext{
|
||||
Owner: "alice",
|
||||
Repo: "proj",
|
||||
LocalRepo: repo,
|
||||
LocalRepo: &tea_git.TeaRepo{Repository: repo},
|
||||
}
|
||||
result := expandPlaceholders("/repos/{owner}/{repo}/branches/{branch}", ctx)
|
||||
assert.Equal(t, "/repos/alice/proj/branches/feature/my-branch", result)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"gitea.dev/tea/cmd/attachments"
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"code.gitea.io/tea/cmd/attachments"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/cmd/releases"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/cmd/releases"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -27,7 +27,7 @@ var CmdReleaseAttachmentCreate = cli.Command{
|
|||
Flags: flags.AllDefaultFlags,
|
||||
}
|
||||
|
||||
func runReleaseAttachmentCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runReleaseAttachmentCreate(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -46,7 +46,7 @@ func runReleaseAttachmentCreate(requestCtx stdctx.Context, cmd *cli.Command) err
|
|||
return fmt.Errorf("release tag needed to create attachment")
|
||||
}
|
||||
|
||||
release, err := releases.GetReleaseByTag(requestCtx, ctx.Owner, ctx.Repo, tag, client)
|
||||
release, err := releases.GetReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ func runReleaseAttachmentCreate(requestCtx stdctx.Context, cmd *cli.Command) err
|
|||
|
||||
filePath := filepath.Base(asset)
|
||||
|
||||
if _, _, err = ctx.Login.Client().Releases.CreateReleaseAttachment(requestCtx, ctx.Owner, ctx.Repo, release.ID, file, filePath); err != nil {
|
||||
if _, _, err = ctx.Login.Client().CreateReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, file, filePath); err != nil {
|
||||
file.Close()
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/cmd/releases"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/cmd/releases"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ var CmdReleaseAttachmentDelete = cli.Command{
|
|||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
func runReleaseAttachmentDelete(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runReleaseAttachmentDelete(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -56,14 +56,14 @@ func runReleaseAttachmentDelete(requestCtx stdctx.Context, cmd *cli.Command) err
|
|||
return nil
|
||||
}
|
||||
|
||||
release, err := releases.GetReleaseByTag(requestCtx, ctx.Owner, ctx.Repo, tag, client)
|
||||
release, err := releases.GetReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var existing []*gitea.Attachment
|
||||
for page := 1; ; {
|
||||
page_attachments, resp, err := client.Releases.ListReleaseAttachments(requestCtx, ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
|
||||
page_attachments, resp, err := client.ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
|
||||
ListOptions: gitea.ListOptions{Page: page, PageSize: 50},
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -87,7 +87,7 @@ func runReleaseAttachmentDelete(requestCtx stdctx.Context, cmd *cli.Command) err
|
|||
return fmt.Errorf("release does not have attachment named '%s'", name)
|
||||
}
|
||||
|
||||
_, err = client.Releases.DeleteReleaseAttachment(requestCtx, ctx.Owner, ctx.Repo, release.ID, attachment.ID)
|
||||
_, err = client.DeleteReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, attachment.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/cmd/releases"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/cmd/releases"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ var CmdReleaseAttachmentList = cli.Command{
|
|||
}
|
||||
|
||||
// RunReleaseAttachmentList list release attachments
|
||||
func RunReleaseAttachmentList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunReleaseAttachmentList(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -45,12 +46,12 @@ func RunReleaseAttachmentList(requestCtx stdctx.Context, cmd *cli.Command) error
|
|||
return fmt.Errorf("release tag needed to list attachments")
|
||||
}
|
||||
|
||||
release, err := releases.GetReleaseByTag(requestCtx, ctx.Owner, ctx.Repo, tag, client)
|
||||
release, err := releases.GetReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
attachments, _, err := ctx.Login.Client().Releases.ListReleaseAttachments(requestCtx, ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
|
||||
attachments, _, err := ctx.Login.Client().ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/tea/cmd/branches"
|
||||
"code.gitea.io/tea/cmd/branches"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ package branches
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ var CmdBranchesList = cli.Command{
|
|||
}
|
||||
|
||||
// RunBranchesList list branches
|
||||
func RunBranchesList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunBranchesList(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -53,14 +53,14 @@ func RunBranchesList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
|
||||
var branches []*gitea.Branch
|
||||
var protections []*gitea.BranchProtection
|
||||
branches, _, err = ctx.Login.Client().Repositories.ListRepoBranches(requestCtx, owner, ctx.Repo, gitea.ListRepoBranchesOptions{
|
||||
branches, _, err = ctx.Login.Client().ListRepoBranches(owner, ctx.Repo, gitea.ListRepoBranchesOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
protections, _, err = ctx.Login.Client().Repositories.ListBranchProtections(requestCtx, owner, ctx.Repo, gitea.ListBranchProtectionsOptions{
|
||||
protections, _, err = ctx.Login.Client().ListBranchProtections(owner, ctx.Repo, gitea.ListBranchProtectionsOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ var CmdBranchesUnprotect = cli.Command{
|
|||
}
|
||||
|
||||
// RunBranchesProtect function to protect/unprotect a list of branches
|
||||
func RunBranchesProtect(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunBranchesProtect(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -67,7 +67,7 @@ func RunBranchesProtect(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
var err error
|
||||
command := ctx.Command.Name
|
||||
if command == "protect" {
|
||||
_, _, err = ctx.Login.Client().Repositories.CreateBranchProtection(requestCtx, owner, ctx.Repo, gitea.CreateBranchProtectionOption{
|
||||
_, _, err = ctx.Login.Client().CreateBranchProtection(owner, ctx.Repo, gitea.CreateBranchProtectionOption{
|
||||
BranchName: branch,
|
||||
RuleName: "",
|
||||
EnablePush: false,
|
||||
|
|
@ -93,7 +93,7 @@ func RunBranchesProtect(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
UnprotectedFilePatterns: "",
|
||||
})
|
||||
} else if command == "unprotect" {
|
||||
_, err = ctx.Login.Client().Repositories.DeleteBranchProtection(requestCtx, owner, ctx.Repo, branch)
|
||||
_, err = ctx.Login.Client().DeleteBranchProtection(owner, ctx.Repo, branch)
|
||||
} else {
|
||||
return fmt.Errorf("command %s is not supported", command)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ var CmdBranchesRename = cli.Command{
|
|||
}
|
||||
|
||||
// RunBranchesRename function to rename a branch
|
||||
func RunBranchesRename(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunBranchesRename(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -54,7 +54,7 @@ func RunBranchesRename(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
owner = ctx.String("owner")
|
||||
}
|
||||
|
||||
successful, _, err := ctx.Login.Client().Repositories.RenameRepoBranch(requestCtx, owner, ctx.Repo, oldBranchName, gitea.RenameRepoBranchOption{
|
||||
successful, _, err := ctx.Login.Client().RenameRepoBranch(owner, ctx.Repo, oldBranchName, gitea.RenameRepoBranchOption{
|
||||
Name: newBranchName,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
17
cmd/clone.go
17
cmd/clone.go
|
|
@ -7,14 +7,14 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/debug"
|
||||
"gitea.dev/tea/modules/git"
|
||||
"gitea.dev/tea/modules/interact"
|
||||
"gitea.dev/tea/modules/task"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/debug"
|
||||
"code.gitea.io/tea/modules/git"
|
||||
"code.gitea.io/tea/modules/interact"
|
||||
"code.gitea.io/tea/modules/task"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -88,7 +88,6 @@ func runRepoClone(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
_, err = task.RepoClone(
|
||||
ctx,
|
||||
dir,
|
||||
login,
|
||||
owner,
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Tea is command line tool for Gitea.
|
||||
package cmd // import "gitea.dev/tea"
|
||||
package cmd // import "code.gitea.io/tea"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/tea/modules/version"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/modules/version"
|
||||
)
|
||||
|
||||
// App creates and returns a tea Command with all subcommands set
|
||||
|
|
@ -39,9 +38,8 @@ func App() *cli.Command {
|
|||
&CmdRepos,
|
||||
&CmdBranches,
|
||||
&CmdActions,
|
||||
&CmdWiki,
|
||||
&CmdWebhooks,
|
||||
&CmdComments,
|
||||
&CmdAddComment,
|
||||
|
||||
&CmdOpen,
|
||||
&CmdNotifications,
|
||||
|
|
|
|||
104
cmd/comment.go
104
cmd/comment.go
|
|
@ -4,28 +4,92 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"gitea.dev/tea/cmd/comments"
|
||||
stdctx "context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/interact"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
"code.gitea.io/tea/modules/theme"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"charm.land/huh/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// CmdComments is the top-level command for managing comments on issues and pull requests.
|
||||
var CmdComments = cli.Command{
|
||||
Name: "comments",
|
||||
Aliases: []string{"comment", "c"},
|
||||
Category: catEntities,
|
||||
Usage: "Manage comments on issues and pull requests",
|
||||
Description: `Manage comments on issues and pull requests.
|
||||
|
||||
When invoked with an issue/PR index and an optional body, behaves like 'tea comments add'
|
||||
(this preserves the historical 'tea comment <idx> "<body>"' shorthand).`,
|
||||
ArgsUsage: "<issue / pr index> [<comment body>]",
|
||||
Action: comments.RunCommentsAdd,
|
||||
Flags: comments.CmdCommentsAdd.Flags,
|
||||
Commands: []*cli.Command{
|
||||
&comments.CmdCommentsAdd,
|
||||
&comments.CmdCommentsList,
|
||||
&comments.CmdCommentsEdit,
|
||||
&comments.CmdCommentsDelete,
|
||||
},
|
||||
// CmdAddComment is the main command to operate with notifications
|
||||
var CmdAddComment = cli.Command{
|
||||
Name: "comment",
|
||||
Aliases: []string{"c"},
|
||||
Category: catEntities,
|
||||
Usage: "Add a comment to an issue / pr",
|
||||
Description: "Add a comment to an issue / pr",
|
||||
ArgsUsage: "<issue / pr index> [<comment body>]",
|
||||
Action: runAddComment,
|
||||
Flags: flags.AllDefaultFlags,
|
||||
}
|
||||
|
||||
func runAddComment(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
args := ctx.Args()
|
||||
if args.Len() == 0 {
|
||||
return fmt.Errorf("please specify issue / pr index")
|
||||
}
|
||||
|
||||
idx, err := utils.ArgToIndex(ctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body := strings.Join(ctx.Args().Tail(), " ")
|
||||
if interact.IsStdinPiped() {
|
||||
// custom solution until https://github.com/AlecAivazis/survey/issues/328 is fixed
|
||||
if bodyStdin, err := io.ReadAll(ctx.Reader); err != nil {
|
||||
return err
|
||||
} else if len(bodyStdin) != 0 {
|
||||
body = strings.Join([]string{body, string(bodyStdin)}, "\n\n")
|
||||
}
|
||||
} else if len(body) == 0 {
|
||||
if err := huh.NewForm(
|
||||
huh.NewGroup(
|
||||
huh.NewText().
|
||||
Title("Comment(markdown):").
|
||||
ExternalEditor(config.GetPreferences().Editor).
|
||||
EditorExtension("md").
|
||||
Value(&body),
|
||||
),
|
||||
).WithTheme(theme.GetTheme()).
|
||||
Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(body) == 0 {
|
||||
return errors.New("no comment content provided")
|
||||
}
|
||||
|
||||
client := ctx.Login.Client()
|
||||
comment, _, err := client.CreateIssueComment(ctx.Owner, ctx.Repo, idx, gitea.CreateIssueCommentOption{
|
||||
Body: body,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
print.Comment(comment)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,96 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package comments
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/interact"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/theme"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
|
||||
"charm.land/huh/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// CmdCommentsAdd adds a comment to an issue or pull request.
|
||||
var CmdCommentsAdd = cli.Command{
|
||||
Name: "add",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Add a comment to an issue or pull request",
|
||||
Description: "Add a comment to an issue or pull request.",
|
||||
ArgsUsage: "<issue / pr index> [<comment body>]",
|
||||
Action: RunCommentsAdd,
|
||||
Flags: append([]cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "description",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "comment body (alternative to the positional argument)",
|
||||
},
|
||||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
// RunCommentsAdd creates a new comment.
|
||||
func RunCommentsAdd(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Args().Len() == 0 {
|
||||
return fmt.Errorf("please specify issue / pr index")
|
||||
}
|
||||
|
||||
idx, err := utils.ArgToIndex(ctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stdinPiped := interact.IsStdinPiped()
|
||||
body, err := resolveBody(strings.Join(ctx.Args().Tail(), " "), ctx.String("description"), stdinPiped, ctx.Reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(body) == 0 && !stdinPiped {
|
||||
if err := huh.NewForm(
|
||||
huh.NewGroup(
|
||||
huh.NewText().
|
||||
Title("Comment(markdown):").
|
||||
ExternalEditor(config.GetPreferences().Editor).
|
||||
EditorExtension("md").
|
||||
Value(&body),
|
||||
),
|
||||
).WithTheme(theme.GetTheme()).
|
||||
Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(body) == 0 {
|
||||
return errors.New("no comment content provided")
|
||||
}
|
||||
|
||||
client := ctx.Login.Client()
|
||||
comment, _, err := client.Issues.CreateIssueComment(requestCtx, ctx.Owner, ctx.Repo, idx, gitea.CreateIssueCommentOption{
|
||||
Body: body,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
print.Comment(comment)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package comments
|
||||
|
||||
import "io"
|
||||
|
||||
// resolveBody picks the comment body from the non-interactive sources, in
|
||||
// precedence order:
|
||||
//
|
||||
// 1. the positional argument (kept first for back-compat with the historical
|
||||
// 'tea comment <idx> "<body>"' shorthand),
|
||||
// 2. the -d/--description flag (mirrors the body flag on 'issue create',
|
||||
// 'issue edit' and 'pr create'),
|
||||
// 3. piped stdin.
|
||||
//
|
||||
// stdin is only read when stdinPiped is true (a non-TTY stdin, e.g. CI,
|
||||
// subshells or agent harnesses) and no body was supplied otherwise, so the
|
||||
// command never blocks reading an interactive terminal when a body is already
|
||||
// given. An empty result means the caller should fall back to the editor (when
|
||||
// interactive) or error out.
|
||||
func resolveBody(positional, description string, stdinPiped bool, stdin io.Reader) (string, error) {
|
||||
if len(positional) != 0 {
|
||||
return positional, nil
|
||||
}
|
||||
if len(description) != 0 {
|
||||
return description, nil
|
||||
}
|
||||
if stdinPiped {
|
||||
stdinBytes, err := io.ReadAll(stdin)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(stdinBytes), nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package comments
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestResolveBody(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
positional string
|
||||
description string
|
||||
stdinPiped bool
|
||||
stdin string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "positional only",
|
||||
positional: "from positional",
|
||||
expected: "from positional",
|
||||
},
|
||||
{
|
||||
name: "description flag only",
|
||||
description: "from -d",
|
||||
expected: "from -d",
|
||||
},
|
||||
{
|
||||
name: "positional wins over description for back-compat",
|
||||
positional: "from positional",
|
||||
description: "from -d",
|
||||
expected: "from positional",
|
||||
},
|
||||
{
|
||||
name: "description wins over piped stdin",
|
||||
description: "from -d",
|
||||
stdinPiped: true,
|
||||
stdin: "from stdin",
|
||||
expected: "from -d",
|
||||
},
|
||||
{
|
||||
name: "piped stdin used when nothing else given",
|
||||
stdinPiped: true,
|
||||
stdin: "from stdin",
|
||||
expected: "from stdin",
|
||||
},
|
||||
{
|
||||
name: "stdin ignored when not piped (interactive terminal)",
|
||||
stdinPiped: false,
|
||||
stdin: "should never be read",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "empty when no source provided",
|
||||
stdinPiped: false,
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "piped but empty stdin yields empty body",
|
||||
stdinPiped: true,
|
||||
stdin: "",
|
||||
expected: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
body, err := resolveBody(tc.positional, tc.description, tc.stdinPiped, strings.NewReader(tc.stdin))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.expected, body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestResolveBodyDoesNotReadStdinWhenBodyGiven guards the original bug: when a
|
||||
// body is supplied positionally (or via -d), stdin must not be consumed, so the
|
||||
// command can never block on a non-TTY stdin under CI / agent harnesses.
|
||||
func TestResolveBodyDoesNotReadStdinWhenBodyGiven(t *testing.T) {
|
||||
reader := &trackingReader{}
|
||||
|
||||
body, err := resolveBody("positional body", "", true, reader)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "positional body", body)
|
||||
assert.False(t, reader.read, "stdin must not be read when a body is supplied")
|
||||
}
|
||||
|
||||
// trackingReader records whether Read was ever called.
|
||||
type trackingReader struct {
|
||||
read bool
|
||||
}
|
||||
|
||||
func (r *trackingReader) Read(p []byte) (int, error) {
|
||||
r.read = true
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package comments
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// CmdCommentsDelete deletes one or more comments by ID.
|
||||
var CmdCommentsDelete = cli.Command{
|
||||
Name: "delete",
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Delete one or more comments by ID",
|
||||
Description: "Delete one or more comments by their comment ID. Use 'tea comments list <issue>' to find IDs.",
|
||||
ArgsUsage: "<comment id> [<comment id>...]",
|
||||
Action: RunCommentsDelete,
|
||||
Flags: flags.AllDefaultFlags,
|
||||
}
|
||||
|
||||
// RunCommentsDelete removes one or more comments.
|
||||
func RunCommentsDelete(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Args().Len() == 0 {
|
||||
return fmt.Errorf("please specify at least one comment id")
|
||||
}
|
||||
|
||||
ids, err := utils.ArgsToIndices(ctx.Args().Slice())
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid comment id: %s", err)
|
||||
}
|
||||
|
||||
client := ctx.Login.Client()
|
||||
for _, id := range ids {
|
||||
if _, err := client.Issues.DeleteIssueComment(requestCtx, ctx.Owner, ctx.Repo, id); err != nil {
|
||||
return fmt.Errorf("could not delete comment %d: %s", id, err)
|
||||
}
|
||||
fmt.Printf("Deleted comment %d\n", id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package comments
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/interact"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/theme"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
|
||||
"charm.land/huh/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// CmdCommentsEdit edits an existing comment.
|
||||
var CmdCommentsEdit = cli.Command{
|
||||
Name: "edit",
|
||||
Aliases: []string{"e"},
|
||||
Usage: "Edit the body of an existing comment",
|
||||
Description: `Edit the body of an existing comment by its comment ID. Use 'tea comments list <issue>' to find IDs.
|
||||
|
||||
The new body can be supplied as a positional argument, via -d/--description, piped on stdin, or (if none is given and stdin is a terminal) entered in your $EDITOR.`,
|
||||
ArgsUsage: "<comment id> [<new body>]",
|
||||
Action: RunCommentsEdit,
|
||||
Flags: append([]cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "description",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "new comment body (alternative to the positional argument)",
|
||||
},
|
||||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
// RunCommentsEdit updates the body of an existing comment.
|
||||
func RunCommentsEdit(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Args().Len() == 0 {
|
||||
return fmt.Errorf("please specify comment id")
|
||||
}
|
||||
|
||||
id, err := utils.ArgToIndex(ctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid comment id %q: %s", ctx.Args().First(), err)
|
||||
}
|
||||
|
||||
stdinPiped := interact.IsStdinPiped()
|
||||
body, err := resolveBody(strings.Join(ctx.Args().Tail(), " "), ctx.String("description"), stdinPiped, ctx.Reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(body) == 0 && !stdinPiped {
|
||||
// Fetch current body to pre-populate the editor.
|
||||
client := ctx.Login.Client()
|
||||
current, _, fetchErr := client.Issues.GetIssueComment(requestCtx, ctx.Owner, ctx.Repo, id)
|
||||
if fetchErr != nil {
|
||||
return fmt.Errorf("could not fetch comment %d: %s", id, fetchErr)
|
||||
}
|
||||
body = current.Body
|
||||
if err := huh.NewForm(
|
||||
huh.NewGroup(
|
||||
huh.NewText().
|
||||
Title("Comment(markdown):").
|
||||
ExternalEditor(config.GetPreferences().Editor).
|
||||
EditorExtension("md").
|
||||
Value(&body),
|
||||
),
|
||||
).WithTheme(theme.GetTheme()).
|
||||
Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(body) == 0 {
|
||||
return errors.New("no comment content provided")
|
||||
}
|
||||
|
||||
client := ctx.Login.Client()
|
||||
comment, _, err := client.Issues.EditIssueComment(requestCtx, ctx.Owner, ctx.Repo, id, gitea.EditIssueCommentOption{
|
||||
Body: body,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
print.Comment(comment)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package comments
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// CmdCommentsList lists comments on an issue or pull request.
|
||||
var CmdCommentsList = cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List comments on an issue or pull request",
|
||||
Description: "List comments on an issue or pull request. Comment IDs returned here are the IDs accepted by 'tea comments edit' and 'tea comments delete'.",
|
||||
ArgsUsage: "<issue / pr index>",
|
||||
Action: RunCommentsList,
|
||||
Flags: append([]cli.Flag{
|
||||
&flags.PaginationPageFlag,
|
||||
&flags.PaginationLimitFlag,
|
||||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
// RunCommentsList lists comments on the given issue/PR.
|
||||
func RunCommentsList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Args().Len() == 0 {
|
||||
return fmt.Errorf("please specify issue / pr index")
|
||||
}
|
||||
|
||||
idx, err := utils.ArgToIndex(ctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := ctx.Login.Client()
|
||||
comments, _, err := client.Issues.ListIssueComments(requestCtx, ctx.Owner, ctx.Repo, idx, gitea.ListIssueCommentOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return print.CommentsList(comments, ctx.Output)
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"io"
|
||||
"time"
|
||||
|
||||
"gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
)
|
||||
|
||||
type detailLabelData struct {
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package flags
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
// stdinPiped reports whether stdin is not a terminal, e.g. when a description
|
||||
// is piped from a file, command substitution, or a CI harness.
|
||||
func stdinPiped() bool {
|
||||
return !term.IsTerminal(int(os.Stdin.Fd()))
|
||||
}
|
||||
|
||||
// resolveCreateBody returns the issue/PR description for create commands.
|
||||
//
|
||||
// Precedence:
|
||||
// 1. --description-file (read from the file, or stdin when the path is "-")
|
||||
// 2. --description
|
||||
// 3. piped stdin
|
||||
func resolveCreateBody(description, descriptionFile string, descriptionFileSet, stdinPiped bool, stdin io.Reader) (string, error) {
|
||||
if descriptionFileSet {
|
||||
return readDescriptionSource(descriptionFile, stdin)
|
||||
}
|
||||
if description != "" {
|
||||
return description, nil
|
||||
}
|
||||
if stdinPiped {
|
||||
return readDescriptionStdin(stdin)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// resolveEditBody returns the new issue/PR body when a description flag was
|
||||
// provided, or nil when the caller should leave the body unchanged.
|
||||
func resolveEditBody(description string, descriptionSet bool, descriptionFile string, descriptionFileSet bool, stdin io.Reader) (*string, error) {
|
||||
if descriptionFileSet {
|
||||
body, err := readDescriptionSource(descriptionFile, stdin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &body, nil
|
||||
}
|
||||
if descriptionSet {
|
||||
body := description
|
||||
return &body, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func readDescriptionSource(source string, stdin io.Reader) (string, error) {
|
||||
if source == "-" {
|
||||
return readDescriptionStdin(stdin)
|
||||
}
|
||||
data, err := os.ReadFile(source)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not read description file %q: %w", source, err)
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
func readDescriptionStdin(stdin io.Reader) (string, error) {
|
||||
data, err := io.ReadAll(stdin)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not read description from stdin: %w", err)
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package flags
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestResolveCreateBody(t *testing.T) {
|
||||
file := filepath.Join(t.TempDir(), "body.md")
|
||||
require.NoError(t, os.WriteFile(file, []byte("from file"), 0o600))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
description string
|
||||
descriptionFile string
|
||||
descriptionFileSet bool
|
||||
stdinPiped bool
|
||||
stdin string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "description flag",
|
||||
description: "from -d",
|
||||
want: "from -d",
|
||||
},
|
||||
{
|
||||
name: "description file",
|
||||
descriptionFile: file,
|
||||
descriptionFileSet: true,
|
||||
want: "from file",
|
||||
},
|
||||
{
|
||||
name: "description file wins over description",
|
||||
description: "from -d",
|
||||
descriptionFile: file,
|
||||
descriptionFileSet: true,
|
||||
want: "from file",
|
||||
},
|
||||
{
|
||||
name: "dash reads stdin",
|
||||
descriptionFile: "-",
|
||||
descriptionFileSet: true,
|
||||
stdin: "from stdin",
|
||||
want: "from stdin",
|
||||
},
|
||||
{
|
||||
name: "description wins over piped stdin",
|
||||
description: "from -d",
|
||||
stdinPiped: true,
|
||||
stdin: "from stdin",
|
||||
want: "from -d",
|
||||
},
|
||||
{
|
||||
name: "piped stdin",
|
||||
stdinPiped: true,
|
||||
stdin: "from stdin",
|
||||
want: "from stdin",
|
||||
},
|
||||
{
|
||||
name: "empty description falls back to piped stdin",
|
||||
description: "",
|
||||
stdinPiped: true,
|
||||
stdin: "from stdin",
|
||||
want: "from stdin",
|
||||
},
|
||||
{
|
||||
name: "empty when no source provided",
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := resolveCreateBody(tt.description, tt.descriptionFile, tt.descriptionFileSet, tt.stdinPiped, strings.NewReader(tt.stdin))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveEditBody(t *testing.T) {
|
||||
file := filepath.Join(t.TempDir(), "body.md")
|
||||
require.NoError(t, os.WriteFile(file, []byte("from file"), 0o600))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
description string
|
||||
descriptionSet bool
|
||||
descriptionFile string
|
||||
descriptionFileSet bool
|
||||
stdin string
|
||||
wantBody string
|
||||
wantSet bool
|
||||
}{
|
||||
{
|
||||
name: "no description flag",
|
||||
},
|
||||
{
|
||||
name: "description flag",
|
||||
description: "from -d",
|
||||
descriptionSet: true,
|
||||
wantBody: "from -d",
|
||||
wantSet: true,
|
||||
},
|
||||
{
|
||||
name: "empty description clears body",
|
||||
descriptionSet: true,
|
||||
wantSet: true,
|
||||
},
|
||||
{
|
||||
name: "description file",
|
||||
descriptionFile: file,
|
||||
descriptionFileSet: true,
|
||||
wantBody: "from file",
|
||||
wantSet: true,
|
||||
},
|
||||
{
|
||||
name: "description file wins over description",
|
||||
description: "from -d",
|
||||
descriptionSet: true,
|
||||
descriptionFile: file,
|
||||
descriptionFileSet: true,
|
||||
wantBody: "from file",
|
||||
wantSet: true,
|
||||
},
|
||||
{
|
||||
name: "dash reads stdin",
|
||||
descriptionFile: "-",
|
||||
descriptionFileSet: true,
|
||||
stdin: "from stdin",
|
||||
wantBody: "from stdin",
|
||||
wantSet: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := resolveEditBody(tt.description, tt.descriptionSet, tt.descriptionFile, tt.descriptionFileSet, strings.NewReader(tt.stdin))
|
||||
require.NoError(t, err)
|
||||
if !tt.wantSet {
|
||||
assert.Nil(t, got)
|
||||
return
|
||||
}
|
||||
require.NotNil(t, got)
|
||||
assert.Equal(t, tt.wantBody, *got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveDescriptionSourceError(t *testing.T) {
|
||||
_, err := resolveCreateBody("", filepath.Join(t.TempDir(), "missing.md"), true, false, strings.NewReader(""))
|
||||
require.ErrorContains(t, err, "could not read description file")
|
||||
}
|
||||
|
|
@ -7,9 +7,8 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/modules/utils"
|
||||
)
|
||||
|
||||
// CsvFlag is a wrapper around cli.StringFlag, with an added GetValues() method
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"io"
|
||||
"testing"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
|
@ -75,7 +75,7 @@ func TestPaginationFlags(t *testing.T) {
|
|||
},
|
||||
Flags: PaginationFlags,
|
||||
}
|
||||
err := cmd.Run(t.Context(), tc.args)
|
||||
err := cmd.Run(context.Background(), tc.args)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ func TestPaginationFailures(t *testing.T) {
|
|||
ErrWriter: io.Discard,
|
||||
}
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := cmd.Run(t.Context(), tc.args)
|
||||
err := cmd.Run(context.Background(), tc.args)
|
||||
require.ErrorContains(t, err, tc.expectedError.Error())
|
||||
// require.ErrorIs(t, err, tc.expectedError)
|
||||
})
|
||||
|
|
@ -140,7 +140,7 @@ func TestGetListOptionsDoesNotLeakBetweenCommands(t *testing.T) {
|
|||
Flags: PaginationFlags,
|
||||
}
|
||||
|
||||
require.NoError(t, cmd.Run(t.Context(), args))
|
||||
require.NoError(t, cmd.Run(context.Background(), args))
|
||||
}
|
||||
|
||||
run([]string{"test", "--page", "5", "--limit", "10"})
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@
|
|||
package flags
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/task"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/task"
|
||||
|
||||
"github.com/araddon/dateparse"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
|
@ -100,10 +98,6 @@ var issuePRFlags = append([]cli.Flag{
|
|||
Name: "description",
|
||||
Aliases: []string{"d"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "description-file",
|
||||
Usage: "Read description from file ('-' for stdin)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "referenced-version",
|
||||
Aliases: []string{"v"},
|
||||
|
|
@ -136,23 +130,13 @@ var IssuePRCreateFlags = append([]cli.Flag{
|
|||
}, issuePRFlags...)
|
||||
|
||||
// GetIssuePRCreateFlags parses all IssuePREditFlags
|
||||
func GetIssuePRCreateFlags(requestCtx stdctx.Context, ctx *context.TeaContext) (*gitea.CreateIssueOption, error) {
|
||||
body, err := resolveCreateBody(
|
||||
ctx.String("description"),
|
||||
ctx.String("description-file"),
|
||||
ctx.IsSet("description-file"),
|
||||
stdinPiped(),
|
||||
ctx.Reader,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func GetIssuePRCreateFlags(ctx *context.TeaContext) (*gitea.CreateIssueOption, error) {
|
||||
opts := gitea.CreateIssueOption{
|
||||
Title: ctx.String("title"),
|
||||
Body: body,
|
||||
Body: ctx.String("description"),
|
||||
Assignees: strings.Split(ctx.String("assignees"), ","),
|
||||
}
|
||||
var err error
|
||||
|
||||
date := ctx.String("deadline")
|
||||
if date != "" {
|
||||
|
|
@ -170,7 +154,7 @@ func GetIssuePRCreateFlags(requestCtx stdctx.Context, ctx *context.TeaContext) (
|
|||
if client == nil {
|
||||
client = ctx.Login.Client()
|
||||
}
|
||||
if opts.Labels, err = task.ResolveLabelNames(requestCtx, client, ctx.Owner, ctx.Repo, labelNames); err != nil {
|
||||
if opts.Labels, err = task.ResolveLabelNames(client, ctx.Owner, ctx.Repo, labelNames); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -179,7 +163,7 @@ func GetIssuePRCreateFlags(requestCtx stdctx.Context, ctx *context.TeaContext) (
|
|||
if client == nil {
|
||||
client = ctx.Login.Client()
|
||||
}
|
||||
ms, _, err := client.Repositories.GetMilestoneByName(requestCtx, ctx.Owner, ctx.Repo, milestoneName)
|
||||
ms, _, err := client.GetMilestoneByName(ctx.Owner, ctx.Repo, milestoneName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("milestone '%s' not found", milestoneName)
|
||||
}
|
||||
|
|
@ -191,18 +175,10 @@ func GetIssuePRCreateFlags(requestCtx stdctx.Context, ctx *context.TeaContext) (
|
|||
|
||||
// IssuePREditFlags defines flags for editing properties of issues and PRs
|
||||
var IssuePREditFlags = append([]cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "set-assignees",
|
||||
Usage: "Clear all existing assignees and assign comma-separated list of usernames. Takes precedence over --add-assignees and --remove-assignees",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "add-assignees",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Comma-separated list of usernames to assign. Takes precedence over --remove-assignees",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "remove-assignees",
|
||||
Usage: "Comma-separated list of usernames to remove",
|
||||
Usage: "Comma-separated list of usernames to assign",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "add-labels",
|
||||
|
|
@ -222,18 +198,9 @@ func GetIssuePREditFlags(ctx *context.TeaContext) (*task.EditIssueOption, error)
|
|||
val := ctx.String("title")
|
||||
opts.Title = &val
|
||||
}
|
||||
body, err := resolveEditBody(
|
||||
ctx.String("description"),
|
||||
ctx.IsSet("description"),
|
||||
ctx.String("description-file"),
|
||||
ctx.IsSet("description-file"),
|
||||
ctx.Reader,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if body != nil {
|
||||
opts.Body = body
|
||||
if ctx.IsSet("description") {
|
||||
val := ctx.String("description")
|
||||
opts.Body = &val
|
||||
}
|
||||
if ctx.IsSet("referenced-version") {
|
||||
val := ctx.String("referenced-version")
|
||||
|
|
@ -255,25 +222,17 @@ func GetIssuePREditFlags(ctx *context.TeaContext) (*task.EditIssueOption, error)
|
|||
opts.Deadline = &t
|
||||
}
|
||||
}
|
||||
if ctx.IsSet("set-assignees") {
|
||||
val := ctx.String("set-assignees")
|
||||
opts.SetAssignees = strings.Split(strings.ReplaceAll(val, " ", ""), ",")
|
||||
}
|
||||
if ctx.IsSet("add-assignees") {
|
||||
val := ctx.String("add-assignees")
|
||||
opts.AddAssignees = strings.Split(strings.ReplaceAll(val, " ", ""), ",")
|
||||
}
|
||||
if ctx.IsSet("remove-assignees") {
|
||||
val := ctx.String("remove-assignees")
|
||||
opts.RemoveAssignees = strings.Split(strings.ReplaceAll(val, " ", ""), ",")
|
||||
opts.AddAssignees = strings.Split(val, ",")
|
||||
}
|
||||
if ctx.IsSet("add-labels") {
|
||||
val := ctx.String("add-labels")
|
||||
opts.AddLabels = strings.Split(strings.ReplaceAll(val, " ", ""), ",")
|
||||
opts.AddLabels = strings.Split(val, ",")
|
||||
}
|
||||
if ctx.IsSet("remove-labels") {
|
||||
val := ctx.String("remove-labels")
|
||||
opts.RemoveLabels = strings.Split(strings.ReplaceAll(val, " ", ""), ",")
|
||||
opts.RemoveLabels = strings.Split(val, ",")
|
||||
}
|
||||
return &opts, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/cmd/issues"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/interact"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/cmd/issues"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/interact"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -38,12 +37,12 @@ type issueData struct {
|
|||
}
|
||||
|
||||
type issueDetailClient interface {
|
||||
GetIssue(ctx stdctx.Context, owner, repo string, index int64) (*gitea.Issue, *gitea.Response, error)
|
||||
ListIssueReactions(ctx stdctx.Context, owner, repo string, index int64, opt gitea.ListIssueReactionsOptions) ([]*gitea.Reaction, *gitea.Response, error)
|
||||
GetIssue(owner, repo string, index int64) (*gitea.Issue, *gitea.Response, error)
|
||||
GetIssueReactions(owner, repo string, index int64) ([]*gitea.Reaction, *gitea.Response, error)
|
||||
}
|
||||
|
||||
type issueCommentClient interface {
|
||||
ListIssueComments(ctx stdctx.Context, owner, repo string, index int64, opt gitea.ListIssueCommentOptions) ([]*gitea.Comment, *gitea.Response, error)
|
||||
ListIssueComments(owner, repo string, index int64, opt gitea.ListIssueCommentOptions) ([]*gitea.Comment, *gitea.Response, error)
|
||||
}
|
||||
|
||||
type commentData = detailCommentData
|
||||
|
|
@ -79,13 +78,13 @@ func runIssues(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
return issues.RunIssuesList(ctx, cmd)
|
||||
}
|
||||
|
||||
func runIssueDetail(requestCtx stdctx.Context, cmd *cli.Command, index string) error {
|
||||
func runIssueDetail(_ stdctx.Context, cmd *cli.Command, index string) error {
|
||||
ctx, idx, err := resolveIssueDetailContext(cmd, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return runIssueDetailWithClient(requestCtx, ctx, idx, ctx.Login.Client().Issues)
|
||||
return runIssueDetailWithClient(ctx, idx, ctx.Login.Client())
|
||||
}
|
||||
|
||||
func resolveIssueDetailContext(cmd *cli.Command, index string) (*context.TeaContext, int64, error) {
|
||||
|
|
@ -108,12 +107,12 @@ func resolveIssueDetailContext(cmd *cli.Command, index string) (*context.TeaCont
|
|||
return ctx, idx, nil
|
||||
}
|
||||
|
||||
func runIssueDetailWithClient(requestCtx stdctx.Context, ctx *context.TeaContext, idx int64, client issueDetailClient) error {
|
||||
issue, _, err := client.GetIssue(requestCtx, ctx.Owner, ctx.Repo, idx)
|
||||
func runIssueDetailWithClient(ctx *context.TeaContext, idx int64, client issueDetailClient) error {
|
||||
issue, _, err := client.GetIssue(ctx.Owner, ctx.Repo, idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reactions, _, err := client.ListIssueReactions(requestCtx, ctx.Owner, ctx.Repo, idx, gitea.ListIssueReactionsOptions{})
|
||||
reactions, _, err := client.GetIssueReactions(ctx.Owner, ctx.Repo, idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -121,14 +120,14 @@ func runIssueDetailWithClient(requestCtx stdctx.Context, ctx *context.TeaContext
|
|||
if ctx.IsSet("output") {
|
||||
switch ctx.String("output") {
|
||||
case "json":
|
||||
return runIssueDetailAsJSON(requestCtx, ctx, issue)
|
||||
return runIssueDetailAsJSON(ctx, issue)
|
||||
}
|
||||
}
|
||||
|
||||
print.IssueDetails(issue, reactions)
|
||||
|
||||
if issue.Comments > 0 {
|
||||
err = interact.ShowCommentsMaybeInteractive(requestCtx, ctx, idx, issue.Comments)
|
||||
err = interact.ShowCommentsMaybeInteractive(ctx, idx, issue.Comments)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error loading comments: %v", err)
|
||||
}
|
||||
|
|
@ -137,17 +136,17 @@ func runIssueDetailWithClient(requestCtx stdctx.Context, ctx *context.TeaContext
|
|||
return nil
|
||||
}
|
||||
|
||||
func runIssueDetailAsJSON(requestCtx stdctx.Context, ctx *context.TeaContext, issue *gitea.Issue) error {
|
||||
return runIssueDetailAsJSONWithClient(requestCtx, ctx, issue, ctx.Login.Client().Issues)
|
||||
func runIssueDetailAsJSON(ctx *context.TeaContext, issue *gitea.Issue) error {
|
||||
return runIssueDetailAsJSONWithClient(ctx, issue, ctx.Login.Client())
|
||||
}
|
||||
|
||||
func runIssueDetailAsJSONWithClient(requestCtx stdctx.Context, ctx *context.TeaContext, issue *gitea.Issue, c issueCommentClient) error {
|
||||
func runIssueDetailAsJSONWithClient(ctx *context.TeaContext, issue *gitea.Issue, c issueCommentClient) error {
|
||||
opts := gitea.ListIssueCommentOptions{ListOptions: flags.GetListOptions(ctx.Command)}
|
||||
comments := []*gitea.Comment{}
|
||||
|
||||
if ctx.Bool("comments") {
|
||||
var err error
|
||||
comments, _, err = c.ListIssueComments(requestCtx, ctx.Owner, ctx.Repo, issue.Index, opts)
|
||||
comments, _, err = c.ListIssueComments(ctx.Owner, ctx.Repo, issue.Index, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ var CmdIssuesClose = cli.Command{
|
|||
}
|
||||
|
||||
// editIssueState abstracts the arg parsing to edit the given issue
|
||||
func editIssueState(requestCtx stdctx.Context, cmd *cli.Command, opts gitea.EditIssueOption) error {
|
||||
func editIssueState(_ stdctx.Context, cmd *cli.Command, opts gitea.EditIssueOption) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -49,7 +49,7 @@ func editIssueState(requestCtx stdctx.Context, cmd *cli.Command, opts gitea.Edit
|
|||
|
||||
client := ctx.Login.Client()
|
||||
for _, index := range indices {
|
||||
issue, _, err := client.Issues.EditIssue(requestCtx, ctx.Owner, ctx.Repo, index, opts)
|
||||
issue, _, err := client.EditIssue(ctx.Owner, ctx.Repo, index, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,18 +5,13 @@ package issues
|
|||
|
||||
import (
|
||||
stdctx "context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/interact"
|
||||
"code.gitea.io/tea/modules/task"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/interact"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/task"
|
||||
)
|
||||
|
||||
// CmdIssuesCreate represents a sub command of issues to create issue
|
||||
|
|
@ -30,7 +25,7 @@ var CmdIssuesCreate = cli.Command{
|
|||
Flags: flags.IssuePRCreateFlags,
|
||||
}
|
||||
|
||||
func runIssuesCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runIssuesCreate(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -40,56 +35,22 @@ func runIssuesCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
if ctx.IsInteractiveMode() {
|
||||
err := interact.CreateIssue(requestCtx, ctx.Login, ctx.Owner, ctx.Repo)
|
||||
err := interact.CreateIssue(ctx.Login, ctx.Owner, ctx.Repo)
|
||||
if err != nil && !interact.IsQuitting(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
opts, err := flags.GetIssuePRCreateFlags(requestCtx, ctx)
|
||||
opts, err := flags.GetIssuePRCreateFlags(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
issue, err := task.CreateIssue(requestCtx, ctx.Login,
|
||||
return task.CreateIssue(
|
||||
ctx.Login,
|
||||
ctx.Owner,
|
||||
ctx.Repo,
|
||||
*opts,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.IsSet("output") {
|
||||
switch ctx.String("output") {
|
||||
case "json":
|
||||
return writeCreatedIssueAsJSON(ctx.Writer, issue)
|
||||
}
|
||||
}
|
||||
|
||||
print.IssueDetails(issue, nil)
|
||||
|
||||
fmt.Println(issue.HTMLURL)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createdIssueJSON is the machine-readable representation of a freshly
|
||||
// created issue, mirroring the create-PR equivalent in cmd/pulls/create.go
|
||||
// (createdPullJSON).
|
||||
type createdIssueJSON struct {
|
||||
Index int64 `json:"index"`
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
State gitea.StateType `json:"state"`
|
||||
}
|
||||
|
||||
func writeCreatedIssueAsJSON(w io.Writer, issue *gitea.Issue) error {
|
||||
return json.NewEncoder(w).Encode(createdIssueJSON{
|
||||
Index: issue.Index,
|
||||
Title: issue.Title,
|
||||
URL: issue.HTMLURL,
|
||||
State: issue.State,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package issues
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestWriteCreatedIssueAsJSON(t *testing.T) {
|
||||
issue := &gitea.Issue{
|
||||
Index: 42,
|
||||
Title: "test title",
|
||||
HTMLURL: "https://gitea.example.com/owner/repo/issues/42",
|
||||
State: gitea.StateOpen,
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
require.NoError(t, writeCreatedIssueAsJSON(&buf, issue))
|
||||
|
||||
var got map[string]any
|
||||
require.NoError(t, json.Unmarshal(buf.Bytes(), &got))
|
||||
|
||||
assert.Equal(t, float64(42), got["index"])
|
||||
assert.Equal(t, "test title", got["title"])
|
||||
assert.Equal(t, "https://gitea.example.com/owner/repo/issues/42", got["url"])
|
||||
assert.Equal(t, "open", got["state"])
|
||||
|
||||
// exactly the lean field set, nothing extra
|
||||
assert.Len(t, got, 4)
|
||||
|
||||
// machine-readable output must not contain terminal escape sequences
|
||||
assert.NotContains(t, buf.String(), "\x1b")
|
||||
}
|
||||
|
|
@ -8,14 +8,13 @@ import (
|
|||
|
||||
stdctx "context"
|
||||
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/interact"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
"code.gitea.io/tea/modules/task"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/interact"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/task"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
)
|
||||
|
||||
// CmdIssuesEdit is the subcommand of issues to edit issues
|
||||
|
|
@ -30,7 +29,7 @@ use an empty string (eg. --milestone "").`,
|
|||
Flags: flags.IssuePREditFlags,
|
||||
}
|
||||
|
||||
func runIssuesEdit(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runIssuesEdit(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -57,7 +56,7 @@ func runIssuesEdit(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
for _, opts.Index = range indices {
|
||||
if ctx.IsInteractiveMode() {
|
||||
var err error
|
||||
opts, err = interact.EditIssue(requestCtx, *ctx, opts.Index)
|
||||
opts, err = interact.EditIssue(*ctx, opts.Index)
|
||||
if err != nil {
|
||||
if interact.IsQuitting(err) {
|
||||
return nil // user quit
|
||||
|
|
@ -66,7 +65,7 @@ func runIssuesEdit(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
}
|
||||
|
||||
issue, err := task.EditIssue(requestCtx, ctx, client, *opts)
|
||||
issue, err := task.EditIssue(ctx, client, *opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/araddon/dateparse"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -33,7 +33,7 @@ var CmdIssuesList = cli.Command{
|
|||
}
|
||||
|
||||
// RunIssuesList list issues
|
||||
func RunIssuesList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunIssuesList(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -72,7 +72,7 @@ func RunIssuesList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
milestones, _ := flags.MilestoneFilterFlag.GetValues(cmd)
|
||||
var issues []*gitea.Issue
|
||||
if ctx.Repo != "" {
|
||||
issues, _, err = ctx.Login.Client().Issues.ListRepoIssues(requestCtx, owner, ctx.Repo, gitea.ListIssueOption{
|
||||
issues, _, err = ctx.Login.Client().ListRepoIssues(owner, ctx.Repo, gitea.ListIssueOption{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
State: state,
|
||||
Type: kind,
|
||||
|
|
@ -92,7 +92,7 @@ func RunIssuesList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
if ctx.IsSet("assignee") {
|
||||
return errors.New("--assignee requires --repo (global issue search does not support assignee filter)")
|
||||
}
|
||||
issues, _, err = ctx.Login.Client().Issues.ListIssues(requestCtx, gitea.ListIssueOption{
|
||||
issues, _, err = ctx.Login.Client().ListIssues(gitea.ListIssueOption{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
State: state,
|
||||
Type: kind,
|
||||
|
|
|
|||
|
|
@ -1,115 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package issues
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.dev/tea/modules/config"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
func TestRunIssuesListWithSSHPubkeyLoginDoesNotDeadlock(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sshKeyPath, fingerprint := writeTestSSHKey(t)
|
||||
|
||||
var versionRequests atomic.Int32
|
||||
var issueRequests atomic.Int32
|
||||
var signedVersionRequests atomic.Int32
|
||||
var signedIssueRequests atomic.Int32
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/api/v1/version":
|
||||
versionRequests.Add(1)
|
||||
if r.Header.Get("Signature") != "" {
|
||||
signedVersionRequests.Add(1)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"version":"1.26.4"}`))
|
||||
case "/api/v1/repos/gitea/tea/issues":
|
||||
issueRequests.Add(1)
|
||||
if r.Header.Get("Signature") != "" {
|
||||
signedIssueRequests.Add(1)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`[]`))
|
||||
default:
|
||||
t.Errorf("unexpected path %s", r.URL.Path)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
config.SetConfigForTesting(config.LocalConfig{
|
||||
Logins: []config.Login{{
|
||||
Name: "ssh-login",
|
||||
URL: server.URL,
|
||||
SSHKey: sshKeyPath,
|
||||
SSHKeyFingerprint: fingerprint,
|
||||
VersionCheck: true,
|
||||
Default: true,
|
||||
}},
|
||||
})
|
||||
|
||||
cmd := cli.Command{
|
||||
Name: CmdIssuesList.Name,
|
||||
Flags: CmdIssuesList.Flags,
|
||||
}
|
||||
require.NoError(t, cmd.Set("login", "ssh-login"))
|
||||
require.NoError(t, cmd.Set("repo", "gitea/tea"))
|
||||
require.NoError(t, cmd.Set("output", "json"))
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- RunIssuesList(stdctx.Background(), &cmd)
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-done:
|
||||
require.NoError(t, err)
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("RunIssuesList deadlocked while bootstrapping the server version for HTTPSign authentication")
|
||||
}
|
||||
|
||||
assert.EqualValues(t, 1, versionRequests.Load())
|
||||
assert.EqualValues(t, 0, signedVersionRequests.Load())
|
||||
assert.EqualValues(t, 1, issueRequests.Load())
|
||||
assert.EqualValues(t, 1, signedIssueRequests.Load())
|
||||
}
|
||||
|
||||
func writeTestSSHKey(t *testing.T) (string, string) {
|
||||
t.Helper()
|
||||
|
||||
_, privateKey, err := ed25519.GenerateKey(rand.Reader)
|
||||
require.NoError(t, err)
|
||||
|
||||
pkcs8, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
pemBytes := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: pkcs8})
|
||||
sshKeyPath := filepath.Join(t.TempDir(), "id_ed25519")
|
||||
require.NoError(t, os.WriteFile(sshKeyPath, pemBytes, 0o600))
|
||||
|
||||
signer, err := ssh.NewSignerFromKey(privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
return sshKeyPath, ssh.FingerprintSHA256(signer.PublicKey())
|
||||
}
|
||||
|
|
@ -6,9 +6,9 @@ package issues
|
|||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,20 +5,18 @@ package cmd
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
stdctx "context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/context"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -33,7 +31,7 @@ type fakeIssueCommentClient struct {
|
|||
comments []*gitea.Comment
|
||||
}
|
||||
|
||||
func (f *fakeIssueCommentClient) ListIssueComments(_ stdctx.Context, owner, repo string, index int64, _ gitea.ListIssueCommentOptions) ([]*gitea.Comment, *gitea.Response, error) {
|
||||
func (f *fakeIssueCommentClient) ListIssueComments(owner, repo string, index int64, _ gitea.ListIssueCommentOptions) ([]*gitea.Comment, *gitea.Response, error) {
|
||||
f.owner = owner
|
||||
f.repo = repo
|
||||
f.index = index
|
||||
|
|
@ -48,14 +46,14 @@ type fakeIssueDetailClient struct {
|
|||
reactions []*gitea.Reaction
|
||||
}
|
||||
|
||||
func (f *fakeIssueDetailClient) GetIssue(_ stdctx.Context, owner, repo string, index int64) (*gitea.Issue, *gitea.Response, error) {
|
||||
func (f *fakeIssueDetailClient) GetIssue(owner, repo string, index int64) (*gitea.Issue, *gitea.Response, error) {
|
||||
f.owner = owner
|
||||
f.repo = repo
|
||||
f.index = index
|
||||
return f.issue, nil, nil
|
||||
}
|
||||
|
||||
func (f *fakeIssueDetailClient) ListIssueReactions(_ stdctx.Context, owner, repo string, index int64, _ gitea.ListIssueReactionsOptions) ([]*gitea.Reaction, *gitea.Response, error) {
|
||||
func (f *fakeIssueDetailClient) GetIssueReactions(owner, repo string, index int64) ([]*gitea.Reaction, *gitea.Response, error) {
|
||||
f.owner = owner
|
||||
f.repo = repo
|
||||
f.index = index
|
||||
|
|
@ -222,7 +220,7 @@ func TestRunIssueDetailAsJSON(t *testing.T) {
|
|||
require.NoError(t, testContext.Set("comments", "false"))
|
||||
}
|
||||
|
||||
err := runIssueDetailAsJSONWithClient(t.Context(), &testContext, &testCase.issue, client)
|
||||
err := runIssueDetailAsJSONWithClient(&testContext, &testCase.issue, client)
|
||||
|
||||
require.NoError(t, err, "Failed to run issue detail as JSON")
|
||||
if testCase.flagComments {
|
||||
|
|
@ -352,7 +350,7 @@ func TestRunIssueDetailUsesOwnerFlag(t *testing.T) {
|
|||
reactions: []*gitea.Reaction{},
|
||||
}
|
||||
|
||||
err = runIssueDetailWithClient(t.Context(), teaCtx, idx, client)
|
||||
err = runIssueDetailWithClient(teaCtx, idx, client)
|
||||
require.NoError(t, err, "Expected runIssueDetail to succeed")
|
||||
assert.Equal(t, expectedOwner, client.owner)
|
||||
assert.Equal(t, expectedRepo, client.repo)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/tea/cmd/labels"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/labels"
|
||||
)
|
||||
|
||||
// CmdLabels represents to operate repositories' labels.
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ var CmdLabelCreate = cli.Command{
|
|||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
func runLabelCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runLabelCreate(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -56,7 +56,7 @@ func runLabelCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
|
||||
labelFile := ctx.String("file")
|
||||
if len(labelFile) == 0 {
|
||||
_, _, err := ctx.Login.Client().Repositories.CreateLabel(requestCtx, ctx.Owner, ctx.Repo, gitea.CreateLabelOption{
|
||||
_, _, err := ctx.Login.Client().CreateLabel(ctx.Owner, ctx.Repo, gitea.CreateLabelOption{
|
||||
Name: ctx.String("name"),
|
||||
Color: ctx.String("color"),
|
||||
Description: ctx.String("description"),
|
||||
|
|
@ -78,7 +78,7 @@ func runLabelCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
if color == "" || name == "" {
|
||||
log.Printf("Line %d ignored because lack of enough fields: %s\n", i, line)
|
||||
} else {
|
||||
_, _, err = ctx.Login.Client().Repositories.CreateLabel(requestCtx, ctx.Owner, ctx.Repo, gitea.CreateLabelOption{
|
||||
_, _, err = ctx.Login.Client().CreateLabel(ctx.Owner, ctx.Repo, gitea.CreateLabelOption{
|
||||
Name: name,
|
||||
Color: color,
|
||||
Description: description,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -30,7 +30,7 @@ var CmdLabelDelete = cli.Command{
|
|||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
func runLabelDelete(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runLabelDelete(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -43,12 +43,12 @@ func runLabelDelete(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
client := ctx.Login.Client()
|
||||
|
||||
// Verify the label exists first
|
||||
label, _, err := client.Repositories.GetRepoLabel(requestCtx, ctx.Owner, ctx.Repo, labelID)
|
||||
label, _, err := client.GetRepoLabel(ctx.Owner, ctx.Repo, labelID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get label %d: %w", labelID, err)
|
||||
}
|
||||
|
||||
_, err = client.Repositories.DeleteLabel(requestCtx, ctx.Owner, ctx.Repo, labelID)
|
||||
_, err = client.DeleteLabel(ctx.Owner, ctx.Repo, labelID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete label '%s' (id: %d): %w", label.Name, labelID, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,13 @@ package labels
|
|||
|
||||
import (
|
||||
stdctx "context"
|
||||
"log"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
"code.gitea.io/tea/modules/task"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/task"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -30,37 +29,25 @@ var CmdLabelsList = cli.Command{
|
|||
Aliases: []string{"s"},
|
||||
Usage: "Save all the labels as a file",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "org",
|
||||
Usage: "List organization labels",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "exclude-org",
|
||||
Usage: "Exclude organization labels from the list",
|
||||
},
|
||||
&flags.PaginationPageFlag,
|
||||
&flags.PaginationLimitFlag,
|
||||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
// RunLabelsList list labels.
|
||||
func RunLabelsList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunLabelsList(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmd.String("org") == "" && cmd.String("repo") == "" {
|
||||
if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.String("org") != "" && cmd.String("repo") != "" {
|
||||
log.Printf("Warning: Both --org and --repo flags are set. Ignoring --org and using --repo value as owner.\n")
|
||||
if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := ctx.Login.Client()
|
||||
labels, err := collectLabels(requestCtx, client, ctx, cmd)
|
||||
labels, _, err := client.ListRepoLabels(ctx.Owner, ctx.Repo, gitea.ListLabelsOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -71,37 +58,3 @@ func RunLabelsList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
|
||||
return print.LabelsList(labels, ctx.Output)
|
||||
}
|
||||
|
||||
// CollectLabels collects labels based on the provided command flags and context.
|
||||
func collectLabels(requestCtx stdctx.Context, client *gitea.Client, ctx *context.TeaContext, cmd *cli.Command) ([]*gitea.Label, error) {
|
||||
var labels []*gitea.Label
|
||||
var err error
|
||||
owner := ctx.Owner
|
||||
|
||||
// If --org is set but --repo is not, list organization labels only and skip repository labels.
|
||||
if cmd.String("org") != "" && cmd.String("repo") == "" {
|
||||
owner = ctx.Org
|
||||
} else {
|
||||
labels, _, err = client.Repositories.ListRepoLabels(requestCtx, owner, ctx.Repo, gitea.ListLabelsOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Failed to list repository labels: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// If --exclude is not set and the owner is an organization, also list organization labels and append them to the list.
|
||||
if !ctx.IsSet("exclude-org") {
|
||||
if _, _, err = client.Organizations.GetOrg(requestCtx, owner); err == nil {
|
||||
orgLabels, _, err := client.Organizations.ListOrgLabels(requestCtx, owner, gitea.ListOrgLabelsOptions{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
labels = append(labels, orgLabels...)
|
||||
}
|
||||
}
|
||||
|
||||
return labels, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ package labels
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ var CmdLabelUpdate = cli.Command{
|
|||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
func runLabelUpdate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runLabelUpdate(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -66,7 +66,7 @@ func runLabelUpdate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
pDescription = &description
|
||||
}
|
||||
|
||||
_, _, err = ctx.Login.Client().Repositories.EditLabel(requestCtx, ctx.Owner, ctx.Repo, id, gitea.EditLabelOption{
|
||||
_, _, err = ctx.Login.Client().EditLabel(ctx.Owner, ctx.Repo, id, gitea.EditLabelOption{
|
||||
Name: pName,
|
||||
Color: pColor,
|
||||
Description: pDescription,
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/login"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/tea/cmd/login"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -31,7 +31,6 @@ var CmdLogin = cli.Command{
|
|||
&login.CmdLoginSetDefault,
|
||||
&login.CmdLoginHelper,
|
||||
&login.CmdLoginOAuthRefresh,
|
||||
&login.CmdLoginStatus,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,24 +7,19 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/modules/auth"
|
||||
"gitea.dev/tea/modules/interact"
|
||||
"gitea.dev/tea/modules/task"
|
||||
"code.gitea.io/tea/modules/auth"
|
||||
"code.gitea.io/tea/modules/interact"
|
||||
"code.gitea.io/tea/modules/task"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// CmdLoginAdd represents to login a gitea server.
|
||||
var CmdLoginAdd = cli.Command{
|
||||
Name: "add",
|
||||
Usage: "Add a Gitea login",
|
||||
Description: `Add a Gitea login, without args it will create one interactively.
|
||||
|
||||
By default tea only stores the token for its own API use. Pass --git-credentials
|
||||
to also register tea as a git credential helper for the login's URL, so that
|
||||
'git push' and 'git clone' over HTTPS authenticate silently using the stored
|
||||
token. Equivalent to running 'tea login helper setup' afterwards.`,
|
||||
ArgsUsage: " ", // command does not accept arguments
|
||||
Name: "add",
|
||||
Usage: "Add a Gitea login",
|
||||
Description: `Add a Gitea login, without args it will create one interactively`,
|
||||
ArgsUsage: " ", // command does not accept arguments
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
|
|
@ -94,9 +89,9 @@ token. Equivalent to running 'tea login helper setup' afterwards.`,
|
|||
Usage: "Use SSH public key or SSH fingerprint to login (needs a running ssh-agent with ssh key loaded)",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "git-credentials",
|
||||
Aliases: []string{"helper", "j"},
|
||||
Usage: "Register tea as a git credential helper for this login's URL, so 'git push' and 'git clone' over HTTPS authenticate silently using the stored token",
|
||||
Name: "helper",
|
||||
Aliases: []string{"j"},
|
||||
Usage: "Add helper",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "oauth",
|
||||
|
|
@ -115,10 +110,10 @@ token. Equivalent to running 'tea login helper setup' afterwards.`,
|
|||
Action: runLoginAdd,
|
||||
}
|
||||
|
||||
func runLoginAdd(requestCtx context.Context, cmd *cli.Command) error {
|
||||
func runLoginAdd(_ context.Context, cmd *cli.Command) error {
|
||||
// if no args create login interactive
|
||||
if cmd.NumFlags() == 0 {
|
||||
if err := interact.CreateLogin(requestCtx); err != nil && !interact.IsQuitting(err) {
|
||||
if err := interact.CreateLogin(); err != nil && !interact.IsQuitting(err) {
|
||||
return fmt.Errorf("error adding login: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
|
@ -142,7 +137,7 @@ func runLoginAdd(requestCtx context.Context, cmd *cli.Command) error {
|
|||
opts.RedirectURL = cmd.String("redirect-url")
|
||||
}
|
||||
|
||||
return auth.OAuthLoginWithFullOptions(requestCtx, opts)
|
||||
return auth.OAuthLoginWithFullOptions(opts)
|
||||
}
|
||||
|
||||
sshAgent := false
|
||||
|
|
@ -152,7 +147,6 @@ func runLoginAdd(requestCtx context.Context, cmd *cli.Command) error {
|
|||
|
||||
// else use args to add login
|
||||
return task.CreateLogin(
|
||||
requestCtx,
|
||||
cmd.String("name"),
|
||||
cmd.String("token"),
|
||||
cmd.String("user"),
|
||||
|
|
@ -166,6 +160,6 @@ func runLoginAdd(requestCtx context.Context, cmd *cli.Command) error {
|
|||
cmd.Bool("insecure"),
|
||||
sshAgent,
|
||||
!cmd.Bool("no-version-check"),
|
||||
cmd.Bool("git-credentials"),
|
||||
cmd.Bool("helper"),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -23,7 +23,7 @@ var CmdLoginSetDefault = cli.Command{
|
|||
Flags: []cli.Flag{&flags.OutputFlag},
|
||||
}
|
||||
|
||||
func runLoginSetDefault(requestCtx context.Context, cmd *cli.Command) error {
|
||||
func runLoginSetDefault(_ context.Context, cmd *cli.Command) error {
|
||||
if cmd.Args().Len() == 0 {
|
||||
l, err := config.GetDefaultLogin()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -23,7 +23,7 @@ var CmdLoginDelete = cli.Command{
|
|||
}
|
||||
|
||||
// RunLoginDelete runs the action of a login delete command
|
||||
func RunLoginDelete(requestCtx context.Context, cmd *cli.Command) error {
|
||||
func RunLoginDelete(_ context.Context, cmd *cli.Command) error {
|
||||
logins, err := config.GetLogins()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
|
@ -28,7 +28,7 @@ var CmdLoginEdit = cli.Command{
|
|||
Flags: []cli.Flag{&flags.OutputFlag},
|
||||
}
|
||||
|
||||
func runLoginEdit(requestCtx context.Context, _ *cli.Command) error {
|
||||
func runLoginEdit(_ context.Context, _ *cli.Command) error {
|
||||
ymlPath := config.GetConfigPath()
|
||||
if e, ok := os.LookupEnv("EDITOR"); ok && e != "" {
|
||||
cmd := exec.Command(e, ymlPath)
|
||||
|
|
|
|||
|
|
@ -11,40 +11,31 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/task"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/task"
|
||||
)
|
||||
|
||||
// CmdLoginHelper represents to login a gitea helper.
|
||||
var CmdLoginHelper = cli.Command{
|
||||
Name: "helper",
|
||||
Aliases: []string{"git-credential"},
|
||||
Usage: "Act as a git credential helper for stored Gitea logins",
|
||||
Description: `Speaks git's credential helper protocol so that HTTPS push and clone
|
||||
operations against your configured Gitea instances authenticate silently
|
||||
using the tokens tea already stores.
|
||||
|
||||
Typical use is automatic: 'tea login add --git-credentials' (or 'tea login
|
||||
helper setup' for existing logins) registers '!tea login helper' as a
|
||||
credential helper in ~/.gitconfig. Git then invokes the 'get' subcommand
|
||||
when it needs credentials for a configured host.`,
|
||||
Name: "helper",
|
||||
Aliases: []string{"git-credential"},
|
||||
Usage: "Git helper",
|
||||
Description: `Git helper`,
|
||||
Hidden: true,
|
||||
Commands: []*cli.Command{
|
||||
{
|
||||
Name: "store",
|
||||
Description: "Command drops",
|
||||
Aliases: []string{"erase"},
|
||||
Usage: "No-op (git credential protocol store/erase)",
|
||||
Description: "No-op invoked by git on credential store/erase; tea persists credentials only in its own config",
|
||||
Action: func(requestCtx context.Context, _ *cli.Command) error {
|
||||
Action: func(_ context.Context, _ *cli.Command) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "setup",
|
||||
Usage: "Register tea as a git credential helper for every configured login",
|
||||
Description: "Register tea as a git credential helper in ~/.gitconfig for every configured login",
|
||||
Action: func(requestCtx context.Context, _ *cli.Command) error {
|
||||
Description: "Setup helper to tea authenticate",
|
||||
Action: func(_ context.Context, _ *cli.Command) error {
|
||||
logins, err := config.GetLogins()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -64,8 +55,7 @@ when it needs credentials for a configured host.`,
|
|||
},
|
||||
{
|
||||
Name: "get",
|
||||
Usage: "Return the stored token for a URL (git credential protocol)",
|
||||
Description: "Return the stored token for a given URL in git's credential helper protocol (called by git, reads request from stdin)",
|
||||
Description: "Get token to auth",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "login",
|
||||
|
|
@ -73,7 +63,7 @@ when it needs credentials for a configured host.`,
|
|||
Usage: "Use a specific login",
|
||||
},
|
||||
},
|
||||
Action: func(requestCtx context.Context, cmd *cli.Command) error {
|
||||
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||
wants := map[string]string{}
|
||||
s := bufio.NewScanner(os.Stdin)
|
||||
for s.Scan() {
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ package login
|
|||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -25,7 +25,7 @@ var CmdLoginList = cli.Command{
|
|||
}
|
||||
|
||||
// RunLoginList list all logins
|
||||
func RunLoginList(requestCtx context.Context, cmd *cli.Command) error {
|
||||
func RunLoginList(_ context.Context, cmd *cli.Command) error {
|
||||
logins, err := config.GetLogins()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/modules/auth"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/auth"
|
||||
"code.gitea.io/tea/modules/config"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -22,7 +22,7 @@ var CmdLoginOAuthRefresh = cli.Command{
|
|||
Action: runLoginOAuthRefresh,
|
||||
}
|
||||
|
||||
func runLoginOAuthRefresh(requestCtx context.Context, cmd *cli.Command) error {
|
||||
func runLoginOAuthRefresh(_ context.Context, cmd *cli.Command) error {
|
||||
var loginName string
|
||||
|
||||
// Get login name from args or use default
|
||||
|
|
@ -62,7 +62,7 @@ func runLoginOAuthRefresh(requestCtx context.Context, cmd *cli.Command) error {
|
|||
fmt.Printf("Token refresh failed: %s\n", err)
|
||||
fmt.Println("Opening browser for re-authentication...")
|
||||
|
||||
if err := auth.ReauthenticateLogin(requestCtx, login); err != nil {
|
||||
if err := auth.ReauthenticateLogin(login); err != nil {
|
||||
return fmt.Errorf("re-authentication failed: %s", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package login
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/config"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/task"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
// CmdLoginStatus represents a command to show authentication status for logins.
|
||||
var CmdLoginStatus = cli.Command{
|
||||
Name: "status",
|
||||
Usage: "Show authentication status for Gitea logins",
|
||||
Description: `Verify the stored token for one or all Gitea logins and report its validity.`,
|
||||
ArgsUsage: "[<login name>]",
|
||||
Action: RunLoginStatus,
|
||||
Flags: []cli.Flag{&flags.OutputFlag},
|
||||
}
|
||||
|
||||
// RunLoginStatus verifies one login, or every configured login when no name is
|
||||
// provided, and prints a short authentication report.
|
||||
func RunLoginStatus(requestCtx context.Context, cmd *cli.Command) error {
|
||||
var logins []config.Login
|
||||
|
||||
switch cmd.Args().Len() {
|
||||
case 0:
|
||||
var err error
|
||||
logins, err = config.GetLogins()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case 1:
|
||||
login, err := config.GetLoginByName(cmd.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if login == nil {
|
||||
return fmt.Errorf("login '%s' not found", cmd.Args().First())
|
||||
}
|
||||
logins = []config.Login{*login}
|
||||
default:
|
||||
return fmt.Errorf("too many arguments")
|
||||
}
|
||||
|
||||
statuses := make([]print.LoginStatus, 0, len(logins))
|
||||
for i := range logins {
|
||||
statuses = append(statuses, task.CheckLoginStatus(requestCtx, &logins[i]))
|
||||
}
|
||||
|
||||
return print.LoginStatuses(statuses, cmd.String("output"))
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"gitea.dev/tea/cmd/login"
|
||||
"code.gitea.io/tea/cmd/login"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,11 +6,10 @@ package cmd
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"code.gitea.io/tea/cmd/milestones"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/milestones"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
)
|
||||
|
||||
// CmdMilestones represents to operate repositories milestones.
|
||||
|
|
@ -40,7 +39,7 @@ func runMilestones(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
return milestones.RunMilestonesList(ctx, cmd)
|
||||
}
|
||||
|
||||
func runMilestoneDetail(requestCtx stdctx.Context, cmd *cli.Command, name string) error {
|
||||
func runMilestoneDetail(_ stdctx.Context, cmd *cli.Command, name string) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -50,7 +49,7 @@ func runMilestoneDetail(requestCtx stdctx.Context, cmd *cli.Command, name string
|
|||
}
|
||||
client := ctx.Login.Client()
|
||||
|
||||
milestone, _, err := client.Repositories.GetMilestoneByName(requestCtx, ctx.Owner, ctx.Repo, name)
|
||||
milestone, _, err := client.GetMilestoneByName(ctx.Owner, ctx.Repo, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,8 @@ package milestones
|
|||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
)
|
||||
|
||||
// CmdMilestonesClose represents a sub command of milestones to close an milestone
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ import (
|
|||
|
||||
stdctx "context"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/interact"
|
||||
"code.gitea.io/tea/modules/task"
|
||||
"github.com/araddon/dateparse"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/interact"
|
||||
"gitea.dev/tea/modules/task"
|
||||
)
|
||||
|
||||
// CmdMilestonesCreate represents a sub command of milestones to create milestone
|
||||
|
|
@ -50,7 +49,7 @@ var CmdMilestonesCreate = cli.Command{
|
|||
}, flags.AllDefaultFlags...),
|
||||
}
|
||||
|
||||
func runMilestonesCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runMilestonesCreate(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -72,13 +71,14 @@ func runMilestonesCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
if ctx.IsInteractiveMode() {
|
||||
if err := interact.CreateMilestone(requestCtx, ctx.Login, ctx.Owner, ctx.Repo); err != nil && !interact.IsQuitting(err) {
|
||||
if err := interact.CreateMilestone(ctx.Login, ctx.Owner, ctx.Repo); err != nil && !interact.IsQuitting(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return task.CreateMilestone(requestCtx, ctx.Login,
|
||||
return task.CreateMilestone(
|
||||
ctx.Login,
|
||||
ctx.Owner,
|
||||
ctx.Repo,
|
||||
ctx.String("title"),
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ package milestones
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -23,7 +23,7 @@ var CmdMilestonesDelete = cli.Command{
|
|||
Flags: flags.AllDefaultFlags,
|
||||
}
|
||||
|
||||
func deleteMilestone(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func deleteMilestone(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -33,6 +33,6 @@ func deleteMilestone(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
client := ctx.Login.Client()
|
||||
|
||||
_, err = client.Repositories.DeleteMilestoneByName(requestCtx, ctx.Owner, ctx.Repo, ctx.Args().First())
|
||||
_, err = client.DeleteMilestoneByName(ctx.Owner, ctx.Repo, ctx.Args().First())
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@ import (
|
|||
|
||||
stdctx "context"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
)
|
||||
|
||||
var msIssuesFieldsFlag = flags.FieldsFlag(print.IssueFields, []string{
|
||||
|
|
@ -71,7 +70,7 @@ var CmdMilestoneRemoveIssue = cli.Command{
|
|||
Flags: flags.AllDefaultFlags,
|
||||
}
|
||||
|
||||
func runMilestoneIssueList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runMilestoneIssueList(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -97,12 +96,12 @@ func runMilestoneIssueList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
|
||||
milestone := ctx.Args().First()
|
||||
// make sure milestone exist
|
||||
_, _, err = client.Repositories.GetMilestoneByName(requestCtx, ctx.Owner, ctx.Repo, milestone)
|
||||
_, _, err = client.GetMilestoneByName(ctx.Owner, ctx.Repo, milestone)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
issues, _, err := client.Issues.ListRepoIssues(requestCtx, ctx.Owner, ctx.Repo, gitea.ListIssueOption{
|
||||
issues, _, err := client.ListRepoIssues(ctx.Owner, ctx.Repo, gitea.ListIssueOption{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
Milestones: []string{milestone},
|
||||
Type: kind,
|
||||
|
|
@ -119,7 +118,7 @@ func runMilestoneIssueList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
return print.IssuesPullsList(issues, ctx.Output, fields)
|
||||
}
|
||||
|
||||
func runMilestoneIssueAdd(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runMilestoneIssueAdd(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -140,12 +139,12 @@ func runMilestoneIssueAdd(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
// make sure milestone exist
|
||||
mile, _, err := client.Repositories.GetMilestoneByName(requestCtx, ctx.Owner, ctx.Repo, mileName)
|
||||
mile, _, err := client.GetMilestoneByName(ctx.Owner, ctx.Repo, mileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get milestone '%s': %w", mileName, err)
|
||||
}
|
||||
|
||||
_, _, err = client.Issues.EditIssue(requestCtx, ctx.Owner, ctx.Repo, idx, gitea.EditIssueOption{
|
||||
_, _, err = client.EditIssue(ctx.Owner, ctx.Repo, idx, gitea.EditIssueOption{
|
||||
Milestone: &mile.ID,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -154,7 +153,7 @@ func runMilestoneIssueAdd(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func runMilestoneIssueRemove(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runMilestoneIssueRemove(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -174,7 +173,7 @@ func runMilestoneIssueRemove(requestCtx stdctx.Context, cmd *cli.Command) error
|
|||
return fmt.Errorf("invalid issue index '%s': %w", issueIndex, err)
|
||||
}
|
||||
|
||||
issue, _, err := client.Issues.GetIssue(requestCtx, ctx.Owner, ctx.Repo, idx)
|
||||
issue, _, err := client.GetIssue(ctx.Owner, ctx.Repo, idx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get issue #%d: %w", idx, err)
|
||||
}
|
||||
|
|
@ -188,7 +187,7 @@ func runMilestoneIssueRemove(requestCtx stdctx.Context, cmd *cli.Command) error
|
|||
}
|
||||
|
||||
zero := int64(0)
|
||||
_, _, err = client.Issues.EditIssue(requestCtx, ctx.Owner, ctx.Repo, idx, gitea.EditIssueOption{
|
||||
_, _, err = client.EditIssue(ctx.Owner, ctx.Repo, idx, gitea.EditIssueOption{
|
||||
Milestone: &zero,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ package milestones
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ var CmdMilestonesList = cli.Command{
|
|||
}
|
||||
|
||||
// RunMilestonesList list milestones
|
||||
func RunMilestonesList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunMilestonesList(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -62,7 +62,7 @@ func RunMilestonesList(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
client := ctx.Login.Client()
|
||||
milestones, _, err := client.Repositories.ListMilestones(requestCtx, ctx.Owner, ctx.Repo, gitea.ListMilestoneOption{
|
||||
milestones, _, err := client.ListRepoMilestones(ctx.Owner, ctx.Repo, gitea.ListMilestoneOption{
|
||||
ListOptions: flags.GetListOptions(cmd),
|
||||
State: state,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ var CmdMilestonesReopen = cli.Command{
|
|||
Flags: flags.AllDefaultFlags,
|
||||
}
|
||||
|
||||
func editMilestoneStatus(requestCtx stdctx.Context, cmd *cli.Command, close bool) error {
|
||||
func editMilestoneStatus(_ stdctx.Context, cmd *cli.Command, close bool) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -58,7 +58,7 @@ func editMilestoneStatus(requestCtx stdctx.Context, cmd *cli.Command, close bool
|
|||
State: &state,
|
||||
Title: ms,
|
||||
}
|
||||
milestone, _, err := client.Repositories.EditMilestoneByName(requestCtx, ctx.Owner, ctx.Repo, ms, opts)
|
||||
milestone, _, err := client.EditMilestoneByName(ctx.Owner, ctx.Repo, ms, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"gitea.dev/tea/cmd/notifications"
|
||||
"code.gitea.io/tea/cmd/notifications"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ package notifications
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
|
|
@ -59,16 +59,16 @@ func RunNotificationsList(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
}
|
||||
|
||||
// listNotifications will get the notifications based on status and subject type
|
||||
func listNotifications(requestCtx stdctx.Context, cmd *cli.Command, status []gitea.NotifyStatus, subjects []gitea.NotifySubjectType) error {
|
||||
func listNotifications(_ stdctx.Context, cmd *cli.Command, status []gitea.NotifyStatus, subjects []gitea.NotifySubjectType) error {
|
||||
var news []*gitea.NotificationThread
|
||||
var err error
|
||||
|
||||
all := cmd.Bool("mine")
|
||||
ctx, err := context.InitCommandWithOptions(cmd, context.InitOptions{SkipLocalRepo: all})
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := ctx.Login.Client()
|
||||
all := ctx.Bool("mine")
|
||||
|
||||
// This enforces pagination (see https://github.com/go-gitea/gitea/issues/16733)
|
||||
listOpts := flags.GetListOptions(cmd)
|
||||
|
|
@ -87,7 +87,7 @@ func listNotifications(requestCtx stdctx.Context, cmd *cli.Command, status []git
|
|||
fields = append(fields, "repository")
|
||||
}
|
||||
|
||||
news, _, err = client.Notifications.List(requestCtx, gitea.ListNotificationOptions{
|
||||
news, _, err = client.ListNotifications(gitea.ListNotificationOptions{
|
||||
ListOptions: listOpts,
|
||||
Status: status,
|
||||
SubjectTypes: subjects,
|
||||
|
|
@ -96,7 +96,7 @@ func listNotifications(requestCtx stdctx.Context, cmd *cli.Command, status []git
|
|||
if err := ctx.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
news, _, err = client.Notifications.ListByRepo(requestCtx, ctx.Owner, ctx.Repo, gitea.ListNotificationOptions{
|
||||
news, _, err = client.ListRepoNotifications(ctx.Owner, ctx.Repo, gitea.ListNotificationOptions{
|
||||
ListOptions: listOpts,
|
||||
Status: status,
|
||||
SubjectTypes: subjects,
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package notifications
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/tea/modules/config"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
func TestRunNotificationsListMineDoesNotProbeGitRepository(t *testing.T) {
|
||||
gitPath := filepath.Join(t.TempDir(), "git")
|
||||
gitScript := "#!/bin/sh\necho 'git should not be called' >&2\nexit 1\n"
|
||||
if runtime.GOOS == "windows" {
|
||||
gitPath += ".bat"
|
||||
gitScript = "@echo git should not be called 1>&2\r\nexit /b 1\r\n"
|
||||
}
|
||||
require.NoError(t, os.WriteFile(gitPath, []byte(gitScript), 0o755))
|
||||
t.Setenv("PATH", filepath.Dir(gitPath))
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, "/api/v1/notifications", r.URL.Path)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`[]`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
config.SetConfigForTesting(config.LocalConfig{
|
||||
Logins: []config.Login{{
|
||||
Name: "default",
|
||||
URL: server.URL,
|
||||
Token: "token",
|
||||
User: "user",
|
||||
Default: true,
|
||||
}},
|
||||
})
|
||||
|
||||
cmd := cli.Command{
|
||||
Name: CmdNotificationsList.Name,
|
||||
Flags: CmdNotificationsList.Flags,
|
||||
}
|
||||
require.NoError(t, cmd.Set("mine", "true"))
|
||||
require.NoError(t, cmd.Set("output", "json"))
|
||||
|
||||
require.NoError(t, RunNotificationsList(stdctx.Background(), &cmd))
|
||||
}
|
||||
|
|
@ -7,12 +7,11 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/utils"
|
||||
)
|
||||
|
||||
// CmdNotificationsMarkRead represents a sub command of notifications to list read notifications
|
||||
|
|
@ -23,8 +22,8 @@ var CmdNotificationsMarkRead = cli.Command{
|
|||
Description: "Mark all filtered or a specific notification as read",
|
||||
ArgsUsage: "[all | <notification id>]",
|
||||
Flags: flags.NotificationFlags,
|
||||
Action: func(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommandWithOptions(cmd, context.InitOptions{SkipLocalRepo: cmd.Bool("mine")})
|
||||
Action: func(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -35,7 +34,7 @@ var CmdNotificationsMarkRead = cli.Command{
|
|||
if !ctx.IsSet(flags.NotificationStateFlag.Name) {
|
||||
filter = []string{string(gitea.NotifyStatusUnread)}
|
||||
}
|
||||
return markNotificationAs(requestCtx, ctx, filter, gitea.NotifyStatusRead)
|
||||
return markNotificationAs(ctx, filter, gitea.NotifyStatusRead)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -47,8 +46,8 @@ var CmdNotificationsMarkUnread = cli.Command{
|
|||
Description: "Mark all filtered or a specific notification as unread",
|
||||
ArgsUsage: "[all | <notification id>]",
|
||||
Flags: flags.NotificationFlags,
|
||||
Action: func(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommandWithOptions(cmd, context.InitOptions{SkipLocalRepo: cmd.Bool("mine")})
|
||||
Action: func(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -59,7 +58,7 @@ var CmdNotificationsMarkUnread = cli.Command{
|
|||
if !ctx.IsSet(flags.NotificationStateFlag.Name) {
|
||||
filter = []string{string(gitea.NotifyStatusRead)}
|
||||
}
|
||||
return markNotificationAs(requestCtx, ctx, filter, gitea.NotifyStatusUnread)
|
||||
return markNotificationAs(ctx, filter, gitea.NotifyStatusUnread)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -71,8 +70,8 @@ var CmdNotificationsMarkPinned = cli.Command{
|
|||
Description: "Mark all filtered or a specific notification as pinned",
|
||||
ArgsUsage: "[all | <notification id>]",
|
||||
Flags: flags.NotificationFlags,
|
||||
Action: func(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommandWithOptions(cmd, context.InitOptions{SkipLocalRepo: cmd.Bool("mine")})
|
||||
Action: func(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -83,7 +82,7 @@ var CmdNotificationsMarkPinned = cli.Command{
|
|||
if !ctx.IsSet(flags.NotificationStateFlag.Name) {
|
||||
filter = []string{string(gitea.NotifyStatusUnread)}
|
||||
}
|
||||
return markNotificationAs(requestCtx, ctx, filter, gitea.NotifyStatusPinned)
|
||||
return markNotificationAs(ctx, filter, gitea.NotifyStatusPinned)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -94,18 +93,18 @@ var CmdNotificationsUnpin = cli.Command{
|
|||
Description: "Marks all pinned or a specific notification as read",
|
||||
ArgsUsage: "[all | <notification id>]",
|
||||
Flags: flags.NotificationFlags,
|
||||
Action: func(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommandWithOptions(cmd, context.InitOptions{SkipLocalRepo: cmd.Bool("mine")})
|
||||
Action: func(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
filter := []string{string(gitea.NotifyStatusPinned)}
|
||||
// NOTE: we implicitly mark it as read, to match web UI semantics. marking as unread might be more useful?
|
||||
return markNotificationAs(requestCtx, ctx, filter, gitea.NotifyStatusRead)
|
||||
return markNotificationAs(ctx, filter, gitea.NotifyStatusRead)
|
||||
},
|
||||
}
|
||||
|
||||
func markNotificationAs(ctx stdctx.Context, cmd *context.TeaContext, filterStates []string, targetState gitea.NotifyStatus) (err error) {
|
||||
func markNotificationAs(cmd *context.TeaContext, filterStates []string, targetState gitea.NotifyStatus) (err error) {
|
||||
client := cmd.Login.Client()
|
||||
subject := cmd.Args().First()
|
||||
allRepos := cmd.Bool("mine")
|
||||
|
|
@ -120,12 +119,12 @@ func markNotificationAs(ctx stdctx.Context, cmd *context.TeaContext, filterState
|
|||
opts := gitea.MarkNotificationOptions{Status: states, ToStatus: targetState}
|
||||
|
||||
if allRepos {
|
||||
_, _, err = client.Notifications.MarkRead(ctx, opts)
|
||||
_, _, err = client.ReadNotifications(opts)
|
||||
} else {
|
||||
if err := cmd.Ensure(context.CtxRequirement{RemoteRepo: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
_, _, err = client.Notifications.MarkReadByRepo(ctx, cmd.Owner, cmd.Repo, opts)
|
||||
_, _, err = client.ReadRepoNotifications(cmd.Owner, cmd.Repo, opts)
|
||||
}
|
||||
|
||||
// TODO: print all affected notification subject URLs
|
||||
|
|
@ -136,12 +135,12 @@ func markNotificationAs(ctx stdctx.Context, cmd *context.TeaContext, filterState
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _, err = client.Notifications.MarkReadByID(ctx, id, targetState)
|
||||
_, _, err = client.ReadNotification(id, targetState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, _, err := client.Notifications.GetByID(ctx, id)
|
||||
n, _, err := client.GetNotification(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import (
|
|||
"path"
|
||||
"strings"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
local_git "gitea.dev/tea/modules/git"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
local_git "code.gitea.io/tea/modules/git"
|
||||
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
|
@ -27,7 +27,7 @@ var CmdOpen = cli.Command{
|
|||
Flags: append([]cli.Flag{}, flags.LoginRepoFlags...),
|
||||
}
|
||||
|
||||
func runOpen(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func runOpen(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ package cmd
|
|||
import (
|
||||
stdctx "context"
|
||||
|
||||
"gitea.dev/tea/cmd/organizations"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/tea/cmd/organizations"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -36,13 +36,17 @@ func runOrganizations(ctx stdctx.Context, cmd *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
if teaCtx.Args().Len() == 1 {
|
||||
org, _, err := teaCtx.Login.Client().Organizations.GetOrg(ctx, teaCtx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
print.OrganizationDetails(org)
|
||||
return nil
|
||||
return runOrganizationDetail(teaCtx)
|
||||
}
|
||||
return organizations.RunOrganizationList(ctx, cmd)
|
||||
}
|
||||
|
||||
func runOrganizationDetail(ctx *context.TeaContext) error {
|
||||
org, _, err := ctx.Login.Client().GetOrg(ctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
print.OrganizationDetails(org)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@ import (
|
|||
stdctx "context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/sdk"
|
||||
|
||||
"gitea.dev/tea/cmd/flags"
|
||||
"gitea.dev/tea/modules/context"
|
||||
"gitea.dev/tea/modules/print"
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/cmd/flags"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
"code.gitea.io/tea/modules/print"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -53,7 +52,7 @@ var CmdOrganizationCreate = cli.Command{
|
|||
}
|
||||
|
||||
// RunOrganizationCreate sets up a new organization
|
||||
func RunOrganizationCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
||||
func RunOrganizationCreate(_ stdctx.Context, cmd *cli.Command) error {
|
||||
ctx, err := context.InitCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -75,7 +74,7 @@ func RunOrganizationCreate(requestCtx stdctx.Context, cmd *cli.Command) error {
|
|||
return fmt.Errorf("unknown visibility '%s'", ctx.String("visibility"))
|
||||
}
|
||||
|
||||
org, _, err := ctx.Login.Client().Organizations.CreateOrg(requestCtx, gitea.CreateOrgOption{
|
||||
org, _, err := ctx.Login.Client().CreateOrg(gitea.CreateOrgOption{
|
||||
Name: ctx.Args().First(),
|
||||
FullName: ctx.String("full-name"),
|
||||
Description: ctx.String("description"),
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue