3 Commits

Author SHA1 Message Date
fff1af1029 use secrets for s3 info (#530) 2023-02-16 00:11:01 +01:00
f28f199e85 Changelog for v0.9.1 (#535)
Reviewed-on: https://gitea.com/gitea/tea/pulls/535
Reviewed-by: John Olheiser <john+gitea@jolheiser.com>
2023-02-16 06:22:31 +08:00
c00418e74c Print pull dont crash if it has TeamReviewRequests (#517)
partial backport of #515

Reviewed-on: https://gitea.com/gitea/tea/pulls/517
Reviewed-by: Norwin <noerw@noreply.gitea.io>
2022-09-29 20:35:57 +08:00
168 changed files with 1474 additions and 6223 deletions

View File

@ -1,20 +0,0 @@
{
"name": "Tea DevContainer",
"image": "mcr.microsoft.com/devcontainers/go:1.24-bullseye",
"features": {
"ghcr.io/devcontainers/features/git-lfs:1.2.4": {}
},
"customizations": {
"vscode": {
"settings": {},
"extensions": [
"editorconfig.editorconfig",
"golang.go",
"stylelint.vscode-stylelint",
"DavidAnson.vscode-markdownlint",
"ms-azuretools.vscode-docker",
"GitHub.vscode-pull-request-github"
]
}
}
}

219
.drone.yml Normal file
View File

@ -0,0 +1,219 @@
---
kind: pipeline
name: default
platform:
os: linux
arch: amd64
steps:
- name: vendor
pull: always
image: golang:1.18
environment:
GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not
commands:
- make vendor # use vendor folder as cache
- name: build
pull: always
image: golang:1.18
environment:
GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not
commands:
- make clean
- make vet
- make lint
- make fmt-check
- make misspell-check
- make build
when:
event:
- push
- tag
- pull_request
- name: unit-test
image: golang:1.18
commands:
- make unit-test-coverage
settings:
group: test
environment:
GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not
when:
branch:
- main
event:
- push
- pull_request
- name: release-test
image: golang:1.18
commands:
- make test
settings:
group: test
environment:
GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not
when:
branch:
- "release/*"
event:
- push
- pull_request
- name: tag-test
pull: always
image: golang:1.18
commands:
- make test
settings:
group: test
environment:
GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not
when:
event:
- tag
- name: static
image: golang:1.18
environment:
GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not
commands:
- make release
when:
event:
- push
- tag
- name: gpg-sign
pull: always
image: plugins/gpgsign:1
settings:
detach_sign: true
excludes:
- "dist/release/*.sha256"
files:
- "dist/release/*"
environment:
GPGSIGN_KEY:
from_secret: gpgsign_key
GPGSIGN_PASSPHRASE:
from_secret: gpgsign_passphrase
when:
event:
- push
- tag
- name: tag-release
pull: always
image: woodpeckerci/plugin-s3:latest
settings:
acl:
from_secret: aws_s3_acl
region:
from_secret: aws_s3_region
bucket:
from_secret: aws_s3_bucket
endpoint:
from_secret: aws_s3_endpoint
path_style:
from_secret: aws_s3_path_style
source: "dist/release/*"
strip_prefix: dist/release/
target: "/tea/${DRONE_TAG##v}"
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
event:
- tag
- name: release-branch-release
pull: always
image: woodpeckerci/plugin-s3:latest
settings:
acl:
from_secret: aws_s3_acl
region:
from_secret: aws_s3_region
bucket:
from_secret: aws_s3_bucket
endpoint:
from_secret: aws_s3_endpoint
path_style:
from_secret: aws_s3_path_style
source: "dist/release/*"
strip_prefix: dist/release/
target: "/tea/${DRONE_BRANCH##release/v}"
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
branch:
- "release/*"
event:
- push
- name: release
pull: always
image: woodpeckerci/plugin-s3:latest
settings:
acl:
from_secret: aws_s3_acl
region:
from_secret: aws_s3_region
bucket:
from_secret: aws_s3_bucket
endpoint:
from_secret: aws_s3_endpoint
path_style:
from_secret: aws_s3_path_style
source: "dist/release/*"
strip_prefix: dist/release/
target: /tea/main
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
branch:
- main
event:
- push
- name: gitea
pull: always
image: plugins/gitea-release:1
settings:
files:
- "dist/release/*"
base_url: https://gitea.com
api_key:
from_secret: gitea_token
when:
event:
- tag
- name: discord
pull: always
image: appleboy/drone-discord:1.0.0
environment:
DISCORD_WEBHOOK_ID:
from_secret: discord_webhook_id
DISCORD_WEBHOOK_TOKEN:
from_secret: discord_webhook_token
when:
event:
- push
- tag
- pull_request
status:
- changed
- failure

1
.envrc
View File

@ -1 +0,0 @@
use flake

View File

@ -8,7 +8,7 @@ labels:
### describe your environment ### describe your environment
- tea version used (`tea -v`): - tea version used (`tea -v`):
- [ ] I also reproduced the issue [with the latest main build](https://dl.gitea.com/tea/main/) - [ ] I also reproduced the issue [with the latest master build](https://dl.gitea.io/tea/master)
- Gitea version used: - Gitea version used:
- [ ] the issue only occurred after updating gitea recently - [ ] the issue only occurred after updating gitea recently
- operating system: - operating system:

View File

@ -1,76 +0,0 @@
name: goreleaser
on:
push:
branches: [ main ]
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- name: import gpg
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
- name: goreleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: "~> v1"
args: release --nightly
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_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 }}
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
release-image:
runs-on: ubuntu-latest
env:
DOCKER_ORG: gitea
DOCKER_LATEST: nightly
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # all history for all branches and tags
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker BuildX
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v6
env:
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
with:
context: .
file: ./Dockerfile
platforms: |
linux/amd64
linux/arm64
push: true
tags: |
gitea/tea:latest

View File

@ -1,41 +0,0 @@
name: goreleaser
on:
push:
tags:
- '*'
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: import gpg
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
- name: goreleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: "~> v1"
args: release
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_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 }}
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}

View File

@ -1,26 +0,0 @@
name: check-and-test
on:
- pull_request
jobs:
check-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: lint and build
run: |
make clean
make vet
make lint
make fmt-check
make misspell-check
make docs-check
make build
- name: test and coverage
run: |
make test
make unit-test-coverage

12
.gitignore vendored
View File

@ -1,6 +1,5 @@
/tea tea
/gitea-vet /gitea-vet
/gitea-vet.exe
.idea/ .idea/
.history/ .history/
@ -8,12 +7,3 @@ dist/
.vscode/ .vscode/
vendor/ vendor/
coverage.out
dist/
# Nix-specific
.direnv/
result
result-*

View File

@ -1,12 +0,0 @@
#!/bin/bash
set -e
if [ -z "$1" ]; then
echo "usage: $0 <path>"
exit 1
fi
SUM=$(shasum -a 256 "$1" | cut -d' ' -f1)
BASENAME=$(basename "$1")
echo -n "${SUM} ${BASENAME}" > "$1".sha256

View File

@ -1,124 +0,0 @@
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- darwin
- linux
- windows
- freebsd
goarch:
- amd64
- arm
- arm64
goarm:
- "5"
- "6"
- "7"
ignore:
- goos: darwin
goarch: arm
- goos: darwin
goarch: ppc64le
- goos: darwin
goarch: s390x
- goos: windows
goarch: ppc64le
- goos: windows
goarch: s390x
- goos: windows
goarch: arm
goarm: "5"
- goos: windows
goarch: arm
goarm: "6"
- goos: windows
goarch: arm
goarm: "7"
- goos: windows
goarch: arm64
- goos: freebsd
goarch: ppc64le
- goos: freebsd
goarch: s390x
- goos: freebsd
goarch: arm
goarm: "5"
- goos: freebsd
goarch: arm
goarm: "6"
- goos: freebsd
goarch: arm
goarm: "7"
- goos: freebsd
goarch: arm64
flags:
- -trimpath
ldflags:
- -s -w -X main.Version={{ .Version }}
binary: >-
{{ .ProjectName }}-
{{- .Version }}-
{{- .Os }}-
{{- if eq .Arch "amd64" }}amd64
{{- else if eq .Arch "amd64_v1" }}amd64
{{- else if eq .Arch "386" }}386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}-{{ .Arm }}{{ end }}
no_unique_dist_dir: true
hooks:
post:
- cmd: xz -k -9 {{ .Path }}
dir: ./dist/
- cmd: sh .goreleaser.checksum.sh {{ .Path }}
- cmd: sh .goreleaser.checksum.sh {{ .Path }}.xz
blobs:
-
provider: s3
bucket: "{{ .Env.S3_BUCKET }}"
region: "{{ .Env.S3_REGION }}"
folder: "tea/{{.Version}}"
extra_files:
- glob: ./**.xz
- glob: ./**.sha256
archives:
- format: binary
name_template: "{{ .Binary }}"
allow_different_binary_count: true
checksum:
name_template: 'checksums.txt'
extra_files:
- glob: ./**.xz
force_token: gitea
signs:
-
signature: "${artifact}.sig"
artifacts: checksum
stdin: '{{ .Env.GPGSIGN_PASSPHRASE }}'
args: ["--batch", "-u", "{{ .Env.GPG_FINGERPRINT }}", "--output", "${signature}", "--detach-sign", "${artifact}"]
snapshot:
name_template: "{{ .Branch }}-devel"
nightly:
name_template: "{{ .Branch }}"
gitea_urls:
api: https://gitea.com/api/v1
download: https://gitea.com
release:
extra_files:
- glob: ./**.xz
- glob: ./**.xz.sha256
# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

View File

@ -7,6 +7,7 @@
- [Bug reports](#bug-reports) - [Bug reports](#bug-reports)
- [Discuss your design](#discuss-your-design) - [Discuss your design](#discuss-your-design)
- [Testing redux](#testing-redux) - [Testing redux](#testing-redux)
- [Vendoring](#vendoring)
- [Code review](#code-review) - [Code review](#code-review)
- [Styleguide](#styleguide) - [Styleguide](#styleguide)
- [Sign-off your work](#sign-off-your-work) - [Sign-off your work](#sign-off-your-work)
@ -59,6 +60,20 @@ high-level discussions.
Before sending code out for review, run all the test by executing: `make test` Before sending code out for review, run all the test by executing: `make test`
Since TEA is an cli tool it should be obvious to test your feature locally first. Since TEA is an cli tool it should be obvious to test your feature locally first.
## Vendoring
We keep a cached copy of dependencies within the `vendor/` directory,
managing updates via [dep](https://github.com/golang/dep).
Pull requests should only include `vendor/` updates if they are part of
the same change, be it a bugfix or a feature addition.
The `vendor/` update needs to be justified as part of the PR description,
and must be verified by the reviewers and/or merger to always reference
an existing upstream commit.
You can find more information on how to get started with it on the [dep project website](https://golang.github.io/dep/docs/introduction.html).
## Code review ## Code review
Changes to TEA must be reviewed before they are accepted—no matter who Changes to TEA must be reviewed before they are accepted—no matter who
@ -160,7 +175,7 @@ maintainers](MAINTAINERS). Every PR **MUST** be reviewed by at least
two maintainers (or owners) before it can get merged. A maintainer two maintainers (or owners) before it can get merged. A maintainer
should be a contributor of Gitea (or Gogs) and contributed at least should be a contributor of Gitea (or Gogs) and contributed at least
4 accepted PRs. A contributor should apply as a maintainer in the 4 accepted PRs. A contributor should apply as a maintainer in the
[Discord](https://discord.gg/Gitea) #develop channel. The owners [Discord](https://discord.gg/NsatcWJ) #develop channel. The owners
or the team maintainers may invite the contributor. A maintainer or the team maintainers may invite the contributor. A maintainer
should spend some time on code reviews. If a maintainer has no should spend some time on code reviews. If a maintainer has no
time to do that, they should apply to leave the maintainers team time to do that, they should apply to leave the maintainers team
@ -193,7 +208,7 @@ https://help.github.com/articles/securing-your-account-with-two-factor-authentic
After the election, the new owners should proactively agree After the election, the new owners should proactively agree
with our [CONTRIBUTING](CONTRIBUTING.md) requirements in the with our [CONTRIBUTING](CONTRIBUTING.md) requirements in the
[Discord](https://discord.gg/Gitea) #general channel. Below are the [Discord](https://discord.gg/NsatcWJ) #general channel. Below are the
words to speak: words to speak:
``` ```
@ -221,8 +236,8 @@ Code that you contribute should use the standard copyright header:
``` ```
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
``` ```
Files in the repository contain copyright from the year they are added Files in the repository contain copyright from the year they are added

View File

@ -1,12 +1,25 @@
FROM docker.io/chainguard/go:latest AS build ARG GOVERSION="1.16.2"
COPY . /build/
WORKDIR /build
RUN make build && mkdir -p /app/.config/tea
FROM docker.io/chainguard/busybox:latest-glibc FROM golang:${GOVERSION}-alpine AS buildenv
COPY --from=build /build/tea /bin/tea
COPY --from=build --chown=65532:65532 /app /app ARG GOOS="linux"
VOLUME [ "/app" ]
COPY . $GOPATH/src/
WORKDIR $GOPATH/src
RUN apk add --quiet --no-cache \
build-base \
make \
git && \
make clean build STATIC=true
FROM scratch
ARG VERSION="0.7.0"
LABEL org.opencontainers.image.title="tea - CLI for Gitea - git with a cup of tea"
LABEL org.opencontainers.image.description="A command line tool to interact with Gitea servers"
LABEL org.opencontainers.image.version="${VERSION}"
LABEL org.opencontainers.image.authors="Tamás Gérczei <tamas@gerczei.eu>"
LABEL org.opencontainers.image.vendor="The Gitea Authors"
COPY --from=buildenv /go/src/tea /
ENV HOME="/app" ENV HOME="/app"
ENTRYPOINT ["/bin/sh", "-c"] ENTRYPOINT ["/tea"]
CMD [ "tea" ]

View File

@ -1,4 +1,5 @@
Copyright (c) 2016 The Gitea Authors Copyright (c) 2016 The Gitea Authors
Copyright (c) 2015 The Gogs Authors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,10 +1,13 @@
DIST := dist DIST := dist
export GO111MODULE=on
export CGO_ENABLED=0
GO ?= go GO ?= go
SHASUM ?= shasum -a 256 SHASUM ?= shasum -a 256
export PATH := $($(GO) env GOPATH)/bin:$(PATH) export PATH := $($(GO) env GOPATH)/bin:$(PATH)
GOFILES := $(shell find . -name "*.go" -type f ! -path "*/bindata.go") GOFILES := $(shell find . -name "*.go" -type f ! -path "./vendor/*" ! -path "*/bindata.go")
GOFMT ?= gofmt -s GOFMT ?= gofmt -s
ifneq ($(DRONE_TAG),) ifneq ($(DRONE_TAG),)
@ -14,7 +17,7 @@ else
ifneq ($(DRONE_BRANCH),) ifneq ($(DRONE_BRANCH),)
VERSION ?= $(subst release/v,,$(DRONE_BRANCH)) VERSION ?= $(subst release/v,,$(DRONE_BRANCH))
else else
VERSION ?= main VERSION ?= master
endif endif
TEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//') TEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')
endif endif
@ -22,21 +25,22 @@ TEA_VERSION_TAG ?= $(shell sed 's/+/_/' <<< $(TEA_VERSION))
TAGS ?= TAGS ?=
SDK ?= $(shell $(GO) list -f '{{.Version}}' -m code.gitea.io/sdk/gitea) SDK ?= $(shell $(GO) list -f '{{.Version}}' -m code.gitea.io/sdk/gitea)
LDFLAGS := -X "code.gitea.io/tea/cmd.Version=$(TEA_VERSION)" -X "code.gitea.io/tea/cmd.Tags=$(TAGS)" -X "code.gitea.io/tea/cmd.SDK=$(SDK)" -s -w LDFLAGS := -X "main.Version=$(TEA_VERSION)" -X "main.Tags=$(TAGS)" -X "main.SDK=$(SDK)" -s -w
# override to allow passing additional goflags via make CLI # override to allow passing additional goflags via make CLI
override GOFLAGS := $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' override GOFLAGS := $(GOFLAGS) -mod=vendor -tags '$(TAGS)' -ldflags '$(LDFLAGS)'
PACKAGES ?= $(shell $(GO) list ./...) PACKAGES ?= $(shell $(GO) list ./... | grep -v /vendor/)
SOURCES ?= $(shell find . -name "*.go" -type f) SOURCES ?= $(shell find . -name "*.go" -type f)
# OS specific vars. # OS specific vars.
ifeq ($(OS), Windows_NT) ifeq ($(OS), Windows_NT)
EXECUTABLE := tea.exe EXECUTABLE := tea.exe
VET_TOOL := gitea-vet.exe
else else
EXECUTABLE := tea EXECUTABLE := tea
VET_TOOL := gitea-vet ifneq ($(shell uname -s), OpenBSD)
override BUILDMODE := -buildmode=pie
endif
endif endif
.PHONY: all .PHONY: all
@ -44,7 +48,7 @@ all: build
.PHONY: clean .PHONY: clean
clean: clean:
$(GO) clean -i ./... $(GO) clean -mod=vendor -i ./...
rm -rf $(EXECUTABLE) $(DIST) rm -rf $(EXECUTABLE) $(DIST)
.PHONY: fmt .PHONY: fmt
@ -54,22 +58,22 @@ fmt:
.PHONY: vet .PHONY: vet
vet: vet:
# Default vet # Default vet
$(GO) vet $(PACKAGES) $(GO) vet -mod=vendor $(PACKAGES)
# Custom vet # Custom vet
$(GO) build code.gitea.io/gitea-vet $(GO) build -mod=vendor code.gitea.io/gitea-vet
$(GO) vet -vettool=$(VET_TOOL) $(PACKAGES) $(GO) vet -vettool=gitea-vet $(PACKAGES)
.PHONY: lint .PHONY: lint
lint: install-lint-tools lint: install-lint-tools
$(GO) run github.com/mgechev/revive@v1.3.2 -config .revive.toml ./... || exit 1 revive -config .revive.toml -exclude=./vendor/... ./... || exit 1
.PHONY: misspell-check .PHONY: misspell-check
misspell-check: install-lint-tools misspell-check: install-lint-tools
$(GO) run github.com/client9/misspell/cmd/misspell@latest -error -i unknwon,destory $(GOFILES) misspell -error -i unknwon,destory $(GOFILES)
.PHONY: misspell .PHONY: misspell
misspell: install-lint-tools misspell: install-lint-tools
$(GO) run github.com/client9/misspell/cmd/misspell@latest -w -i unknwon $(GOFILES) misspell -w -i unknwon $(GOFILES)
.PHONY: fmt-check .PHONY: fmt-check
fmt-check: fmt-check:
@ -81,38 +85,25 @@ fmt-check:
exit 1; \ exit 1; \
fi; fi;
.PHONY: docs
docs:
$(GO) run docs/docs.go --out docs/CLI.md
.PHONY: docs-check
docs-check:
@DIFF=$$($(GO) run docs/docs.go | diff docs/CLI.md -); \
if [ -n "$$DIFF" ]; then \
echo "Please run 'make docs' and commit the result:"; \
echo "$$DIFF"; \
exit 1; \
fi;
.PHONY: test .PHONY: test
test: test:
$(GO) test -tags='sqlite sqlite_unlock_notify' $(PACKAGES) $(GO) test -mod=vendor -tags='sqlite sqlite_unlock_notify' $(PACKAGES)
.PHONY: unit-test-coverage .PHONY: unit-test-coverage
unit-test-coverage: unit-test-coverage:
$(GO) test -tags='sqlite sqlite_unlock_notify' -cover -coverprofile coverage.out $(PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1 $(GO) test -mod=vendor -tags='sqlite sqlite_unlock_notify' -cover -coverprofile coverage.out $(PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
.PHONY: tidy .PHONY: vendor
tidy: vendor:
$(GO) mod tidy $(GO) mod tidy && $(GO) mod vendor
.PHONY: check .PHONY: check
check: test check: test
.PHONY: install .PHONY: install
install: $(SOURCES) install: $(SOURCES)
@echo "installing to $(shell $(GO) env GOPATH)/bin/$(EXECUTABLE)" @echo "installing to $(GOPATH)/bin/$(EXECUTABLE)"
$(GO) install -v $(BUILDMODE) $(GOFLAGS) $(GO) install -v $(BUILDMODE) $(GOFLAGS)
.PHONY: build .PHONY: build
build: $(EXECUTABLE) build: $(EXECUTABLE)
@ -124,9 +115,37 @@ $(EXECUTABLE): $(SOURCES)
build-image: build-image:
docker build --build-arg VERSION=$(TEA_VERSION) -t gitea/tea:$(TEA_VERSION_TAG) . docker build --build-arg VERSION=$(TEA_VERSION) -t gitea/tea:$(TEA_VERSION_TAG) .
.PHONY: release
release: release-dirs install-release-tools release-os release-compress release-check
.PHONY: release-dirs
release-dirs:
mkdir -p $(DIST)/binaries $(DIST)/release
.PHONY: release-os
release-os:
CGO_ENABLED=0 gox -verbose -cgo=false $(GOFLAGS) -osarch='!darwin/386 !darwin/arm' -os="windows linux darwin" -arch="386 amd64 arm arm64" -output="$(DIST)/release/tea-$(VERSION)-{{.OS}}-{{.Arch}}"
.PHONY: release-compress
release-compress: install-release-tools
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done;
.PHONY: release-check
release-check: install-release-tools
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "checksumming $${file}" && $(SHASUM) `echo $${file} | sed 's/^..//'` > $${file}.sha256; done;
### tools
install-release-tools:
@hash gox > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install github.com/mitchellh/gox@latest; \
fi
@hash gxz > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install github.com/ulikunitz/xz/cmd/gxz@latest; \
fi
install-lint-tools: install-lint-tools:
@hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install github.com/mgechev/revive@v1.3.2; \ $(GO) install github.com/mgechev/revive@latest; \
fi fi
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install github.com/client9/misspell/cmd/misspell@latest; \ $(GO) install github.com/client9/misspell/cmd/misspell@latest; \

View File

@ -1,12 +1,8 @@
# <img alt='tea logo' src='https://gitea.com/repo-avatars/550-80a3a8c2ab0e2c2d69f296b7f8582485' height="40"/> *T E A* # <img alt='' src='https://gitea.com/repo-avatars/550-80a3a8c2ab0e2c2d69f296b7f8582485' height="40"/> *T E A*
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Release](https://raster.shields.io/badge/dynamic/json.svg?label=release&url=https://gitea.com/api/v1/repos/gitea/tea/releases&query=$[0].tag_name)](https://gitea.com/gitea/tea/releases) [![Build Status](https://drone.gitea.com/api/badges/gitea/tea/status.svg)](https://drone.gitea.com/gitea/tea) [![Join the chat at https://img.shields.io/discord/322538954119184384.svg](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/Gitea) [![Go Report Card](https://goreportcard.com/badge/code.gitea.io/tea)](https://goreportcard.com/report/code.gitea.io/tea) [![GoDoc](https://godoc.org/code.gitea.io/tea?status.svg)](https://godoc.org/code.gitea.io/tea)
[![Release](https://raster.shields.io/badge/dynamic/json.svg?label=release&url=https://gitea.com/api/v1/repos/gitea/tea/releases&query=$[0].tag_name)](https://gitea.com/gitea/tea/releases)
[![Join the chat at https://img.shields.io/discord/322538954119184384.svg](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/Gitea)
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/tea)](https://goreportcard.com/report/code.gitea.io/tea) [![GoDoc](https://pkg.go.dev/badge/code.gitea.io/tea?status.svg)](https://godoc.org/code.gitea.io/tea)
![Tea Release Status](https://gitea.com/gitea/tea/actions/workflows/release-nightly.yml/badge.svg)
## The official CLI for Gitea ### The official CLI for Gitea
![demo gif](./demo.gif) ![demo gif](./demo.gif)
@ -29,16 +25,15 @@
COMMANDS COMMANDS
help, h Shows a list of commands or help for one command help, h Shows a list of commands or help for one command
ENTITIES: ENTITIES:
issues, issue, i List, create and update issues issues, issue, i List, create and update issues
pulls, pull, pr Manage and checkout pull requests pulls, pull, pr Manage and checkout pull requests
labels, label Manage issue labels labels, label Manage issue labels
milestones, milestone, ms List and create milestones milestones, milestone, ms List and create milestones
releases, release, r Manage releases releases, release, r Manage releases
release assets, release asset, r a Manage release attachments times, time, t Operate on tracked times of a repository's issues & pulls
times, time, t Operate on tracked times of a repository's issues & pulls organizations, organization, org List, create, delete organizations
organizations, organization, org List, create, delete organizations repos, repo Show repository details
repos, repo Show repository details comment, c Add a comment to an issue / pr
comment, c Add a comment to an issue / pr
HELPERS: HELPERS:
open, o Open something of the repository in web browser open, o Open something of the repository in web browser
notifications, notification, n Show notifications notifications, notification, n Show notifications
@ -74,7 +69,7 @@
ABOUT ABOUT
Written & maintained by The Gitea Authors. Written & maintained by The Gitea Authors.
If you find a bug or want to contribute, we'll welcome you at https://gitea.com/gitea/tea. If you find a bug or want to contribute, we'll welcome you at https://gitea.com/gitea/tea.
More info about Gitea itself on https://about.gitea.com. More info about Gitea itself on https://gitea.io.
``` ```
- [Compare features with other git forge CLIs](./FEATURE-COMPARISON.md) - [Compare features with other git forge CLIs](./FEATURE-COMPARISON.md)
@ -85,22 +80,20 @@
There are different ways to get `tea`: There are different ways to get `tea`:
1. Install via your system package manager: 1. Install via your system package manager:
- macOS via `brew` (official): - macOS via `brew` (gitea-maintained):
```sh ```sh
brew tap gitea/tap https://gitea.com/gitea/homebrew-gitea
brew install tea brew install tea
``` ```
- arch linux ([gitea-tea-git](https://aur.archlinux.org/packages/gitea-tea-git), thirdparty) - arch linux ([gitea-tea-git](https://aur.archlinux.org/packages/gitea-tea-git), thirdparty)
- alpine linux ([tea](https://pkgs.alpinelinux.org/packages?name=tea&branch=edge), thirdparty) - alpine linux ([tea](https://pkgs.alpinelinux.org/packages?name=tea&branch=edge), thirdparty)
- Windows via `MSYS2` ([tea](https://packages.msys2.org/base/mingw-w64-tea), thirdparty)
2. Use the prebuilt binaries from [dl.gitea.com](https://dl.gitea.com/tea/) 2. Use the prebuilt binaries from [dl.gitea.io](https://dl.gitea.io/tea/)
3. Install from source: [see *Compilation*](#compilation) 3. Install from source: [see *Compilation*](#compilation)
4. Docker (thirdparty): [tgerczei/tea](https://hub.docker.com/r/tgerczei/tea) 4. Docker (thirdparty): [tgerczei/tea](https://hub.docker.com/r/tgerczei/tea)
5. asdf (thirdparty): [mvaldes14/asdf-tea](https://github.com/mvaldes14/asdf-tea)
## Compilation ## Compilation
Make sure you have a current go version installed (1.13 or newer). Make sure you have a current go version installed (1.13 or newer).
@ -112,15 +105,10 @@ Make sure you have a current go version installed (1.13 or newer).
make make
``` ```
Note that GNU Make (gmake on OpenBSD) is required. Note that GNU Make (gmake on OpenBSD) is required.
If you want to install the compiled program you have to execute the following command:
```sh
make install
```
This installs the binary into the "bin" folder inside of your GOPATH folder (`go env GOPATH`). It is possible that this folder isn't in your PATH Environment Variable.
- For a quick installation without `git` & `make`, set $version and exec: - For a quick installation without `git` & `make`:
```sh ```sh
go install code.gitea.io/tea@${version} go install code.gitea.io/tea@latest
``` ```
## Contributing ## Contributing
@ -129,6 +117,7 @@ Fork -> Patch -> Push -> Pull Request
- `make test` run testsuite - `make test` run testsuite
- `make vet` run checks (check the order of imports; preventing failure on CI pipeline beforehand) - `make vet` run checks (check the order of imports; preventing failure on CI pipeline beforehand)
- `make vendor` when adding new dependencies
- ... (for other development tasks, check the `Makefile`) - ... (for other development tasks, check the `Makefile`)
**Please** read the [CONTRIBUTING](CONTRIBUTING.md) documentation, it will tell you about internal structures and concepts. **Please** read the [CONTRIBUTING](CONTRIBUTING.md) documentation, it will tell you about internal structures and concepts.

View File

@ -1,6 +1,6 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//go:build vendor //go:build vendor
// +build vendor // +build vendor

View File

@ -1,15 +1,14 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/admin/users" "code.gitea.io/tea/cmd/admin/users"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdAdmin represents the namespace of admin commands. // CmdAdmin represents the namespace of admin commands.
@ -19,10 +18,10 @@ var CmdAdmin = cli.Command{
Usage: "Operations requiring admin access on the Gitea instance", Usage: "Operations requiring admin access on the Gitea instance",
Aliases: []string{"a"}, Aliases: []string{"a"},
Category: catMisc, Category: catMisc,
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(cmd *cli.Context) error {
return cli.ShowSubcommandHelp(cmd) return cli.ShowSubcommandHelp(cmd)
}, },
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&cmdAdminUsers, &cmdAdminUsers,
}, },
} }
@ -31,19 +30,19 @@ var cmdAdminUsers = cli.Command{
Name: "users", Name: "users",
Aliases: []string{"u"}, Aliases: []string{"u"},
Usage: "Manage registered users", Usage: "Manage registered users",
Action: func(ctx stdctx.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
if cmd.Args().Len() == 1 { if ctx.Args().Len() == 1 {
return runAdminUserDetail(ctx, cmd, cmd.Args().First()) return runAdminUserDetail(ctx, ctx.Args().First())
} }
return users.RunUserList(ctx, cmd) return users.RunUserList(ctx)
}, },
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&users.CmdUserList, &users.CmdUserList,
}, },
Flags: users.CmdUserList.Flags, Flags: users.CmdUserList.Flags,
} }
func runAdminUserDetail(_ stdctx.Context, cmd *cli.Command, u string) error { func runAdminUserDetail(cmd *cli.Context, u string) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
client := ctx.Login.Client() client := ctx.Login.Client()
user, _, err := client.GetUserInfo(u) user, _, err := client.GetUserInfo(u)

View File

@ -1,17 +1,16 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package users package users
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
var userFieldsFlag = flags.FieldsFlag(print.UserFields, []string{ var userFieldsFlag = flags.FieldsFlag(print.UserFields, []string{
@ -33,7 +32,7 @@ var CmdUserList = cli.Command{
} }
// RunUserList list users // RunUserList list users
func RunUserList(_ stdctx.Context, cmd *cli.Command) error { func RunUserList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
fields, err := userFieldsFlag.GetValues(cmd) fields, err := userFieldsFlag.GetValues(cmd)

View File

@ -1,28 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"code.gitea.io/tea/cmd/attachments"
"code.gitea.io/tea/cmd/flags"
"github.com/urfave/cli/v3"
)
// CmdReleaseAttachments represents a release attachment (file attachment)
var CmdReleaseAttachments = cli.Command{
Name: "assets",
Aliases: []string{"asset", "a"},
Category: catEntities,
Usage: "Manage release assets",
Description: "Manage release assets",
ArgsUsage: " ", // command does not accept arguments
Action: attachments.RunReleaseAttachmentList,
Commands: []*cli.Command{
&attachments.CmdReleaseAttachmentList,
&attachments.CmdReleaseAttachmentCreate,
&attachments.CmdReleaseAttachmentDelete,
},
Flags: flags.AllDefaultFlags,
}

View File

@ -1,65 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package attachments
import (
stdctx "context"
"fmt"
"os"
"path/filepath"
"code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context"
"github.com/urfave/cli/v3"
)
// CmdReleaseAttachmentCreate represents a sub command of Release Attachments to create a release attachment
var CmdReleaseAttachmentCreate = cli.Command{
Name: "create",
Aliases: []string{"c"},
Usage: "Create one or more release attachments",
Description: `Create one or more release attachments`,
ArgsUsage: "<release-tag> <asset> [<asset>...]",
Action: runReleaseAttachmentCreate,
Flags: flags.AllDefaultFlags,
}
func runReleaseAttachmentCreate(_ stdctx.Context, cmd *cli.Command) error {
ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client()
if ctx.Args().Len() < 2 {
return fmt.Errorf("No release tag or assets specified.\nUsage:\t%s", ctx.Command.UsageText)
}
tag := ctx.Args().First()
if len(tag) == 0 {
return fmt.Errorf("Release tag needed to create attachment")
}
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
if err != nil {
return err
}
for _, asset := range ctx.Args().Slice()[1:] {
var file *os.File
if file, err = os.Open(asset); err != nil {
return err
}
filePath := filepath.Base(asset)
if _, _, err = ctx.Login.Client().CreateReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, file, filePath); err != nil {
file.Close()
return err
}
file.Close()
}
return nil
}

View File

@ -1,101 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package attachments
import (
stdctx "context"
"fmt"
"code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3"
)
// CmdReleaseAttachmentDelete represents a sub command of Release Attachments to delete a release attachment
var CmdReleaseAttachmentDelete = cli.Command{
Name: "delete",
Aliases: []string{"rm"},
Usage: "Delete one or more release attachments",
Description: `Delete one or more release attachments`,
ArgsUsage: "<release tag> <attachment name> [<attachment name>...]",
Action: runReleaseAttachmentDelete,
Flags: append([]cli.Flag{
&cli.BoolFlag{
Name: "confirm",
Aliases: []string{"y"},
Usage: "Confirm deletion (required)",
},
}, flags.AllDefaultFlags...),
}
func runReleaseAttachmentDelete(_ stdctx.Context, cmd *cli.Command) error {
ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client()
if ctx.Args().Len() < 2 {
return fmt.Errorf("No release tag or attachment names specified.\nUsage:\t%s", ctx.Command.UsageText)
}
tag := ctx.Args().First()
if len(tag) == 0 {
return fmt.Errorf("Release tag needed to delete attachment")
}
if !ctx.Bool("confirm") {
fmt.Println("Are you sure? Please confirm with -y or --confirm.")
return nil
}
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
if err != nil {
return err
}
existing, _, err := client.ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
ListOptions: gitea.ListOptions{Page: -1},
})
if err != nil {
return err
}
for _, name := range ctx.Args().Slice()[1:] {
var attachment *gitea.Attachment
for _, a := range existing {
if a.Name == name {
attachment = a
}
}
if attachment == nil {
return fmt.Errorf("Release does not have attachment named '%s'", name)
}
_, err = client.DeleteReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, attachment.ID)
if err != nil {
return err
}
}
return nil
}
func getReleaseAttachmentByName(owner, repo string, release int64, name string, client *gitea.Client) (*gitea.Attachment, error) {
al, _, err := client.ListReleaseAttachments(owner, repo, release, gitea.ListReleaseAttachmentsOptions{
ListOptions: gitea.ListOptions{Page: -1},
})
if err != nil {
return nil, err
}
if len(al) == 0 {
return nil, fmt.Errorf("Release does not have any attachments")
}
for _, a := range al {
if a.Name == name {
return a, nil
}
}
return nil, fmt.Errorf("Attachment does not exist")
}

View File

@ -1,75 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package attachments
import (
stdctx "context"
"fmt"
"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"
)
// CmdReleaseAttachmentList represents a sub command of release attachment to list release attachments
var CmdReleaseAttachmentList = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "List Release Attachments",
Description: "List Release Attachments",
ArgsUsage: "<release-tag>", // command does not accept arguments
Action: RunReleaseAttachmentList,
Flags: append([]cli.Flag{
&flags.PaginationPageFlag,
&flags.PaginationLimitFlag,
}, flags.AllDefaultFlags...),
}
// RunReleaseAttachmentList list release attachments
func RunReleaseAttachmentList(_ stdctx.Context, cmd *cli.Command) error {
ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client()
tag := ctx.Args().First()
if len(tag) == 0 {
return fmt.Errorf("Release tag needed to list attachments")
}
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
if err != nil {
return err
}
attachments, _, err := ctx.Login.Client().ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
ListOptions: ctx.GetListOptions(),
})
if err != nil {
return err
}
print.ReleaseAttachmentsList(attachments, ctx.Output)
return nil
}
func getReleaseByTag(owner, repo, tag string, client *gitea.Client) (*gitea.Release, error) {
rl, _, err := client.ListReleases(owner, repo, gitea.ListReleasesOptions{
ListOptions: gitea.ListOptions{Page: -1},
})
if err != nil {
return nil, err
}
if len(rl) == 0 {
return nil, fmt.Errorf("Repo does not have any release")
}
for _, r := range rl {
if r.TagName == tag {
return r, nil
}
}
return nil, fmt.Errorf("Release tag does not exist")
}

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
"context"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
@ -12,7 +12,7 @@ import (
"os/exec" "os/exec"
"github.com/adrg/xdg" "github.com/adrg/xdg"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdAutocomplete manages autocompletion // CmdAutocomplete manages autocompletion
@ -32,9 +32,9 @@ var CmdAutocomplete = cli.Command{
Action: runAutocompleteAdd, Action: runAutocompleteAdd,
} }
func runAutocompleteAdd(_ context.Context, cmd *cli.Command) error { func runAutocompleteAdd(ctx *cli.Context) error {
var remoteFile, localFile, cmds string var remoteFile, localFile, cmds string
shell := cmd.Args().First() shell := ctx.Args().First()
switch shell { switch shell {
case "zsh": case "zsh":
@ -56,10 +56,10 @@ func runAutocompleteAdd(_ context.Context, cmd *cli.Command) error {
// fish is different, in that urfave/cli provides a generator for the shell script needed. // fish is different, in that urfave/cli provides a generator for the shell script needed.
// this also means that the fish completion can become out of sync with the tea binary! // this also means that the fish completion can become out of sync with the tea binary!
// writing to this directory suffices, as fish reads files there on startup, no cmds needed. // writing to this directory suffices, as fish reads files there on startup, no cmds needed.
return writeFishAutoCompleteFile(cmd) return writeFishAutoCompleteFile(ctx)
default: default:
return fmt.Errorf("Must specify valid %s", cmd.ArgsUsage) return fmt.Errorf("Must specify valid %s", ctx.Command.ArgsUsage)
} }
localPath, err := xdg.ConfigFile("tea/" + localFile) localPath, err := xdg.ConfigFile("tea/" + localFile)
@ -72,7 +72,7 @@ func runAutocompleteAdd(_ context.Context, cmd *cli.Command) error {
return err return err
} }
if cmd.Bool("install") { if ctx.Bool("install") {
fmt.Println("Installing in your shellrc") fmt.Println("Installing in your shellrc")
installer := exec.Command(shell, "-c", cmds) installer := exec.Command(shell, "-c", cmds)
if shell == "powershell" { if shell == "powershell" {
@ -110,14 +110,14 @@ func writeRemoteAutoCompleteFile(file, destPath string) error {
return err return err
} }
func writeFishAutoCompleteFile(cmd *cli.Command) error { func writeFishAutoCompleteFile(ctx *cli.Context) error {
// NOTE: to make sure this file is in sync with tea commands, we'd need to // NOTE: to make sure this file is in sync with tea commands, we'd need to
// - check if the file exists // - check if the file exists
// - if it does, check if the tea version that wrote it is the currently running version // - if it does, check if the tea version that wrote it is the currently running version
// - if not, rewrite the file // - if not, rewrite the file
// on each application run // on each application run
// NOTE: this generates a completion that also suggests file names, which looks kinda messy.. // NOTE: this generates a completion that also suggests file names, which looks kinda messy..
script, err := cmd.ToFishCompletion() script, err := ctx.App.ToFishCompletion()
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,38 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"context"
"code.gitea.io/tea/cmd/branches"
"github.com/urfave/cli/v3"
)
// CmdBranches represents to login a gitea server.
var CmdBranches = cli.Command{
Name: "branches",
Aliases: []string{"branch", "b"},
Category: catEntities,
Usage: "Consult branches",
Description: `Lists branches when called without argument. If a branch is provided, will show it in detail.`,
ArgsUsage: "[<branch name>]",
Action: runBranches,
Commands: []*cli.Command{
&branches.CmdBranchesList,
&branches.CmdBranchesProtect,
&branches.CmdBranchesUnprotect,
},
Flags: append([]cli.Flag{
&cli.BoolFlag{
Name: "comments",
Usage: "Whether to display comments (will prompt if not provided & run interactively)",
},
}, branches.CmdBranchesList.Flags...),
}
func runBranches(ctx context.Context, cmd *cli.Command) error {
return branches.RunBranchesList(ctx, cmd)
}

View File

@ -1,75 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package branches
import (
stdctx "context"
"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"
)
var branchFieldsFlag = flags.FieldsFlag(print.BranchFields, []string{
"name", "protected", "user-can-merge", "user-can-push",
})
// CmdBranchesListFlags Flags for command list
var CmdBranchesListFlags = append([]cli.Flag{
branchFieldsFlag,
&flags.PaginationPageFlag,
&flags.PaginationLimitFlag,
}, flags.AllDefaultFlags...)
// CmdBranchesList represents a sub command of branches to list branches
var CmdBranchesList = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "List branches of the repository",
Description: `List branches of the repository`,
ArgsUsage: " ", // command does not accept arguments
Action: RunBranchesList,
Flags: CmdBranchesListFlags,
}
// RunBranchesList list branches
func RunBranchesList(_ stdctx.Context, cmd *cli.Command) error {
ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
owner := ctx.Owner
if ctx.IsSet("owner") {
owner = ctx.String("owner")
}
var branches []*gitea.Branch
var protections []*gitea.BranchProtection
var err error
branches, _, err = ctx.Login.Client().ListRepoBranches(owner, ctx.Repo, gitea.ListRepoBranchesOptions{
ListOptions: ctx.GetListOptions(),
})
if err != nil {
return err
}
protections, _, err = ctx.Login.Client().ListBranchProtections(owner, ctx.Repo, gitea.ListBranchProtectionsOptions{
ListOptions: ctx.GetListOptions(),
})
if err != nil {
return err
}
fields, err := branchFieldsFlag.GetValues(cmd)
if err != nil {
return err
}
print.BranchesList(branches, protections, ctx.Output, fields)
return nil
}

View File

@ -1,102 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package branches
import (
stdctx "context"
"fmt"
"code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3"
)
// CmdBranchesProtectFlags Flags for command protect/unprotect
var CmdBranchesProtectFlags = append([]cli.Flag{
branchFieldsFlag,
&flags.PaginationPageFlag,
&flags.PaginationLimitFlag,
}, flags.AllDefaultFlags...)
// CmdBranchesProtect represents a sub command of branches to protect a branch
var CmdBranchesProtect = cli.Command{
Name: "protect",
Aliases: []string{"P"},
Usage: "Protect branches",
Description: `Block actions push/merge on specified branches`,
ArgsUsage: "<branch>",
Action: RunBranchesProtect,
Flags: CmdBranchesProtectFlags,
}
// CmdBranchesUnprotect represents a sub command of branches to protect a branch
var CmdBranchesUnprotect = cli.Command{
Name: "unprotect",
Aliases: []string{"U"},
Usage: "Unprotect branches",
Description: `Suppress existing protections on specified branches`,
ArgsUsage: "<branch>",
Action: RunBranchesProtect,
Flags: CmdBranchesProtectFlags,
}
// RunBranchesProtect function to protect/unprotect a list of branches
func RunBranchesProtect(_ stdctx.Context, cmd *cli.Command) error {
ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
if !cmd.Args().Present() {
return fmt.Errorf("must specify at least one branch")
}
owner := ctx.Owner
if ctx.IsSet("owner") {
owner = ctx.String("owner")
}
for _, branch := range ctx.Args().Slice() {
var err error
command := ctx.Command.Name
if command == "protect" {
_, _, err = ctx.Login.Client().CreateBranchProtection(owner, ctx.Repo, gitea.CreateBranchProtectionOption{
BranchName: branch,
RuleName: "",
EnablePush: false,
EnablePushWhitelist: false,
PushWhitelistUsernames: []string{},
PushWhitelistTeams: []string{},
PushWhitelistDeployKeys: false,
EnableMergeWhitelist: false,
MergeWhitelistUsernames: []string{},
MergeWhitelistTeams: []string{},
EnableStatusCheck: false,
StatusCheckContexts: []string{},
RequiredApprovals: 1,
EnableApprovalsWhitelist: false,
ApprovalsWhitelistUsernames: []string{},
ApprovalsWhitelistTeams: []string{},
BlockOnRejectedReviews: false,
BlockOnOfficialReviewRequests: false,
BlockOnOutdatedBranch: false,
DismissStaleApprovals: false,
RequireSignedCommits: false,
ProtectedFilePatterns: "",
UnprotectedFilePatterns: "",
})
} else if command == "unprotect" {
_, err = ctx.Login.Client().DeleteBranchProtection(owner, ctx.Repo, branch)
} else {
return fmt.Errorf("command %s is not supported", command)
}
if err != nil {
return err
}
}
return nil
}

View File

@ -1,5 +1,6 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd

View File

@ -1,10 +1,10 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -15,7 +15,7 @@ import (
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdRepoClone represents a sub command of repos to create a local copy // CmdRepoClone represents a sub command of repos to create a local copy
@ -46,18 +46,18 @@ When a host is specified in the repo-slug, it will override the login specified
}, },
} }
func runRepoClone(ctx stdctx.Context, cmd *cli.Command) error { func runRepoClone(cmd *cli.Context) error {
teaCmd := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
args := teaCmd.Args() args := ctx.Args()
if args.Len() < 1 { if args.Len() < 1 {
return cli.ShowCommandHelp(ctx, cmd, "clone") return cli.ShowCommandHelp(cmd, "clone")
} }
dir := args.Get(1) dir := args.Get(1)
var ( var (
login *config.Login = teaCmd.Login login *config.Login = ctx.Login
owner string = teaCmd.Login.User owner string = ctx.Login.User
repo string repo string
) )
@ -82,7 +82,7 @@ func runRepoClone(ctx stdctx.Context, cmd *cli.Command) error {
owner, owner,
repo, repo,
interact.PromptPassword, interact.PromptPassword,
teaCmd.Int("depth"), ctx.Int("depth"),
) )
return err return err

View File

@ -1,133 +0,0 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
// Tea is command line tool for Gitea.
package cmd // import "code.gitea.io/tea"
import (
"fmt"
"runtime"
"strings"
"github.com/urfave/cli/v3"
)
// Version holds the current tea version
var Version = "development"
// Tags holds the build tags used
var Tags = ""
// SDK holds the sdk version from go.mod
var SDK = ""
// App creates and returns a tea Command with all subcommands set
// it was separated from main so docs can be generated for it
func App() *cli.Command {
// make parsing tea --version easier, by printing /just/ the version string
cli.VersionPrinter = func(c *cli.Command) { fmt.Fprintln(c.Writer, c.Version) }
return &cli.Command{
Name: "tea",
Usage: "command line tool to interact with Gitea",
Description: appDescription,
CustomHelpTemplate: helpTemplate,
Version: formatVersion(),
Commands: []*cli.Command{
&CmdLogin,
&CmdLogout,
&CmdAutocomplete,
&CmdWhoami,
&CmdIssues,
&CmdPulls,
&CmdLabels,
&CmdMilestones,
&CmdReleases,
&CmdTrackedTimes,
&CmdOrgs,
&CmdRepos,
&CmdBranches,
&CmdAddComment,
&CmdOpen,
&CmdNotifications,
&CmdRepoClone,
&CmdAdmin,
},
EnableShellCompletion: true,
}
}
func formatVersion() string {
version := fmt.Sprintf("Version: %s\tgolang: %s",
bold(Version),
strings.ReplaceAll(runtime.Version(), "go", ""))
if len(Tags) != 0 {
version += fmt.Sprintf("\tbuilt with: %s", strings.Replace(Tags, " ", ", ", -1))
}
if len(SDK) != 0 {
version += fmt.Sprintf("\tgo-sdk: %s", SDK)
}
return version
}
var appDescription = `tea is a productivity helper for Gitea. It can be used to manage most entities on
one or multiple Gitea instances & provides local helpers like 'tea pr checkout'.
tea tries to make use of context provided by the repository in $PWD if available.
tea works best in a upstream/fork workflow, when the local main branch tracks the
upstream repo. tea assumes that local git state is published on the remote before
doing operations with tea. Configuration is persisted in $XDG_CONFIG_HOME/tea.
`
var helpTemplate = bold(`
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}`) + `
{{if .Version}}{{if not .HideVersion}}version {{.Version}}{{end}}{{end}}
USAGE
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .Commands}} command [subcommand] [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
DESCRIPTION
{{.Description | nindent 3 | trim}}{{end}}{{if .VisibleCommands}}
COMMANDS{{range .VisibleCategories}}{{if .Name}}
{{.Name}}:{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
OPTIONS
{{range $index, $option := .VisibleFlags}}{{if $index}}
{{end}}{{$option}}{{end}}{{end}}
EXAMPLES
tea login add # add a login once to get started
tea pulls # list open pulls for the repo in $PWD
tea pulls --repo $HOME/foo # list open pulls for the repo in $HOME/foo
tea pulls --remote upstream # list open pulls for the repo pointed at by
# your local "upstream" git remote
# list open pulls for any gitea repo at the given login instance
tea pulls --repo gitea/tea --login gitea.com
tea milestone issues 0.7.0 # view open issues for milestone '0.7.0'
tea issue 189 # view contents of issue 189
tea open 189 # open web ui for issue 189
tea open milestones # open web ui for milestones
# send gitea desktop notifications every 5 minutes (bash + libnotify)
while :; do tea notifications --mine -o simple | xargs -i notify-send {}; sleep 300; done
ABOUT
Written & maintained by The Gitea Authors.
If you find a bug or want to contribute, we'll welcome you at https://gitea.com/gitea/tea.
More info about Gitea itself on https://about.gitea.com.
`
func bold(t string) string {
return fmt.Sprintf("\033[1m%s\033[0m", t)
}

View File

@ -1,12 +1,12 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"fmt" "fmt"
"io" "io/ioutil"
"strings" "strings"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -18,7 +18,7 @@ import (
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdAddComment is the main command to operate with notifications // CmdAddComment is the main command to operate with notifications
@ -33,7 +33,7 @@ var CmdAddComment = cli.Command{
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }
func runAddComment(_ stdctx.Context, cmd *cli.Command) error { func runAddComment(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
@ -50,7 +50,7 @@ func runAddComment(_ stdctx.Context, cmd *cli.Command) error {
body := strings.Join(ctx.Args().Tail(), " ") body := strings.Join(ctx.Args().Tail(), " ")
if interact.IsStdinPiped() { if interact.IsStdinPiped() {
// custom solution until https://github.com/AlecAivazis/survey/issues/328 is fixed // custom solution until https://github.com/AlecAivazis/survey/issues/328 is fixed
if bodyStdin, err := io.ReadAll(ctx.Reader); err != nil { if bodyStdin, err := ioutil.ReadAll(ctx.App.Reader); err != nil {
return err return err
} else if len(bodyStdin) != 0 { } else if len(bodyStdin) != 0 {
body = strings.Join([]string{body, string(bodyStdin)}, "\n\n") body = strings.Join([]string{body, string(bodyStdin)}, "\n\n")

View File

@ -1,5 +1,6 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package flags package flags
@ -8,7 +9,7 @@ import (
"strings" "strings"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CsvFlag is a wrapper around cli.StringFlag, with an added GetValues() method // CsvFlag is a wrapper around cli.StringFlag, with an added GetValues() method
@ -38,8 +39,8 @@ func NewCsvFlag(name, usage string, aliases, availableValues, defaults []string)
} }
// GetValues returns the value of the flag, parsed as a commaseparated list // GetValues returns the value of the flag, parsed as a commaseparated list
func (f CsvFlag) GetValues(cmd *cli.Command) ([]string, error) { func (f CsvFlag) GetValues(ctx *cli.Context) ([]string, error) {
val := cmd.String(f.Name) val := ctx.String(f.Name)
selection := strings.Split(val, ",") selection := strings.Split(val, ",")
if f.AvailableFields != nil && val != "" { if f.AvailableFields != nil && val != "" {
for _, field := range selection { for _, field := range selection {

View File

@ -1,10 +1,11 @@
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package flags package flags
import ( import (
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// LoginFlag provides flag to specify tea login profile // LoginFlag provides flag to specify tea login profile
@ -32,7 +33,7 @@ var RemoteFlag = cli.StringFlag{
var OutputFlag = cli.StringFlag{ var OutputFlag = cli.StringFlag{
Name: "output", Name: "output",
Aliases: []string{"o"}, Aliases: []string{"o"},
Usage: "Output format. (simple, table, csv, tsv, yaml, json)", Usage: "Output format. (csv, simple, table, tsv, yaml)",
} }
// PaginationPageFlag provides flag for pagination options // PaginationPageFlag provides flag for pagination options

View File

@ -1,19 +1,19 @@
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package flags package flags
import ( import (
"fmt" "fmt"
"strings" "strings"
"time"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"github.com/araddon/dateparse" "github.com/araddon/dateparse"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// StateFlag provides flag to specify issue/pr state, defaulting to "open" // StateFlag provides flag to specify issue/pr state, defaulting to "open"
@ -70,10 +70,6 @@ var IssueListingFlags = append([]cli.Flag{
Name: "mentions", Name: "mentions",
Aliases: []string{"M"}, Aliases: []string{"M"},
}, },
&cli.StringFlag{
Name: "owner",
Aliases: []string{"org"},
},
&cli.StringFlag{ &cli.StringFlag{
Name: "from", Name: "from",
Aliases: []string{"F"}, Aliases: []string{"F"},
@ -88,8 +84,8 @@ var IssueListingFlags = append([]cli.Flag{
&PaginationLimitFlag, &PaginationLimitFlag,
}, AllDefaultFlags...) }, AllDefaultFlags...)
// issuePRFlags defines shared flags between flags IssuePRCreateFlags and IssuePREditFlags // IssuePREditFlags defines flags for properties of issues and PRs
var issuePRFlags = append([]cli.Flag{ var IssuePREditFlags = append([]cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "title", Name: "title",
Aliases: []string{"t"}, Aliases: []string{"t"},
@ -98,25 +94,6 @@ var issuePRFlags = append([]cli.Flag{
Name: "description", Name: "description",
Aliases: []string{"d"}, Aliases: []string{"d"},
}, },
&cli.StringFlag{
Name: "referenced-version",
Aliases: []string{"v"},
Usage: "commit-hash or tag name to assign",
},
&cli.StringFlag{
Name: "milestone",
Aliases: []string{"m"},
Usage: "Milestone to assign",
},
&cli.StringFlag{
Name: "deadline",
Aliases: []string{"D"},
Usage: "Deadline timestamp to assign",
},
}, LoginRepoFlags...)
// IssuePRCreateFlags defines flags for creation of issues and PRs
var IssuePRCreateFlags = append([]cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "assignees", Name: "assignees",
Aliases: []string{"a"}, Aliases: []string{"a"},
@ -127,10 +104,20 @@ var IssuePRCreateFlags = append([]cli.Flag{
Aliases: []string{"L"}, Aliases: []string{"L"},
Usage: "Comma-separated list of labels to assign", Usage: "Comma-separated list of labels to assign",
}, },
}, issuePRFlags...) &cli.StringFlag{
Name: "deadline",
Aliases: []string{"D"},
Usage: "Deadline timestamp to assign",
},
&cli.StringFlag{
Name: "milestone",
Aliases: []string{"m"},
Usage: "Milestone to assign",
},
}, LoginRepoFlags...)
// GetIssuePRCreateFlags parses all IssuePREditFlags // GetIssuePREditFlags parses all IssuePREditFlags
func GetIssuePRCreateFlags(ctx *context.TeaContext) (*gitea.CreateIssueOption, error) { func GetIssuePREditFlags(ctx *context.TeaContext) (*gitea.CreateIssueOption, error) {
opts := gitea.CreateIssueOption{ opts := gitea.CreateIssueOption{
Title: ctx.String("title"), Title: ctx.String("title"),
Body: ctx.String("description"), Body: ctx.String("description"),
@ -172,67 +159,3 @@ func GetIssuePRCreateFlags(ctx *context.TeaContext) (*gitea.CreateIssueOption, e
return &opts, nil return &opts, nil
} }
// IssuePREditFlags defines flags for editing properties of issues and PRs
var IssuePREditFlags = append([]cli.Flag{
&cli.StringFlag{
Name: "add-assignees",
Aliases: []string{"a"},
Usage: "Comma-separated list of usernames to assign",
},
&cli.StringFlag{
Name: "add-labels",
Aliases: []string{"L"},
Usage: "Comma-separated list of labels to assign. Takes precedence over --remove-labels",
},
&cli.StringFlag{
Name: "remove-labels",
Usage: "Comma-separated list of labels to remove",
},
}, issuePRFlags...)
// GetIssuePREditFlags parses all IssuePREditFlags
func GetIssuePREditFlags(ctx *context.TeaContext) (*task.EditIssueOption, error) {
opts := task.EditIssueOption{}
if ctx.IsSet("title") {
val := ctx.String("title")
opts.Title = &val
}
if ctx.IsSet("description") {
val := ctx.String("description")
opts.Body = &val
}
if ctx.IsSet("referenced-version") {
val := ctx.String("referenced-version")
opts.Ref = &val
}
if ctx.IsSet("milestone") {
val := ctx.String("milestone")
opts.Milestone = &val
}
if ctx.IsSet("deadline") {
date := ctx.String("deadline")
if date == "" {
opts.Deadline = &time.Time{}
} else {
t, err := dateparse.ParseAny(date)
if err != nil {
return nil, err
}
opts.Deadline = &t
}
}
if ctx.IsSet("add-assignees") {
val := ctx.String("add-assignees")
opts.AddAssignees = strings.Split(val, ",")
}
if ctx.IsSet("add-labels") {
val := ctx.String("add-labels")
opts.AddLabels = strings.Split(val, ",")
}
if ctx.IsSet("remove-labels") {
val := ctx.String("remove-labels")
opts.RemoveLabels = strings.Split(val, ",")
}
return &opts, nil
}

View File

@ -1,10 +1,10 @@
// Copyright 2018 The Gitea Authors. All rights reserved. // Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/issues" "code.gitea.io/tea/cmd/issues"
@ -13,7 +13,7 @@ import (
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdIssues represents to login a gitea server. // CmdIssues represents to login a gitea server.
@ -25,10 +25,9 @@ var CmdIssues = cli.Command{
Description: `Lists issues when called without argument. If issue index is provided, will show it in detail.`, Description: `Lists issues when called without argument. If issue index is provided, will show it in detail.`,
ArgsUsage: "[<issue index>]", ArgsUsage: "[<issue index>]",
Action: runIssues, Action: runIssues,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&issues.CmdIssuesList, &issues.CmdIssuesList,
&issues.CmdIssuesCreate, &issues.CmdIssuesCreate,
&issues.CmdIssuesEdit,
&issues.CmdIssuesReopen, &issues.CmdIssuesReopen,
&issues.CmdIssuesClose, &issues.CmdIssuesClose,
}, },
@ -40,14 +39,14 @@ var CmdIssues = cli.Command{
}, issues.CmdIssuesList.Flags...), }, issues.CmdIssuesList.Flags...),
} }
func runIssues(ctx stdctx.Context, cmd *cli.Command) error { func runIssues(ctx *cli.Context) error {
if cmd.Args().Len() == 1 { if ctx.Args().Len() == 1 {
return runIssueDetail(ctx, cmd, cmd.Args().First()) return runIssueDetail(ctx, ctx.Args().First())
} }
return issues.RunIssuesList(ctx, cmd) return issues.RunIssuesList(ctx)
} }
func runIssueDetail(_ stdctx.Context, cmd *cli.Command, index string) error { func runIssueDetail(cmd *cli.Context, index string) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,10 +1,10 @@
// Copyright 2018 The Gitea Authors. All rights reserved. // Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package issues package issues
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -13,47 +13,40 @@ import (
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdIssuesClose represents a sub command of issues to close an issue // CmdIssuesClose represents a sub command of issues to close an issue
var CmdIssuesClose = cli.Command{ var CmdIssuesClose = cli.Command{
Name: "close", Name: "close",
Usage: "Change state of one ore more issues to 'closed'", Usage: "Change state of an issue to 'closed'",
Description: `Change state of one ore more issues to 'closed'`, Description: `Change state of an issue to 'closed'`,
ArgsUsage: "<issue index> [<issue index>...]", ArgsUsage: "<issue index>",
Action: func(ctx stdctx.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
var s = gitea.StateClosed var s = gitea.StateClosed
return editIssueState(ctx, cmd, gitea.EditIssueOption{State: &s}) return editIssueState(ctx, gitea.EditIssueOption{State: &s})
}, },
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }
// editIssueState abstracts the arg parsing to edit the given issue // editIssueState abstracts the arg parsing to edit the given issue
func editIssueState(_ stdctx.Context, cmd *cli.Command, opts gitea.EditIssueOption) error { func editIssueState(cmd *cli.Context, opts gitea.EditIssueOption) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
if ctx.Args().Len() == 0 { if ctx.Args().Len() == 0 {
return fmt.Errorf(ctx.Command.ArgsUsage) return fmt.Errorf(ctx.Command.ArgsUsage)
} }
indices, err := utils.ArgsToIndices(ctx.Args().Slice()) index, err := utils.ArgToIndex(ctx.Args().First())
if err != nil { if err != nil {
return err return err
} }
client := ctx.Login.Client() issue, _, err := ctx.Login.Client().EditIssue(ctx.Owner, ctx.Repo, index, opts)
for _, index := range indices { if err != nil {
issue, _, err := client.EditIssue(ctx.Owner, ctx.Repo, index, opts) return err
if err != nil {
return err
}
if len(indices) > 1 {
fmt.Println(issue.HTMLURL)
} else {
print.IssueDetails(issue, nil)
}
} }
print.IssueDetails(issue, nil)
return nil return nil
} }

View File

@ -1,17 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package issues package issues
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/interact" "code.gitea.io/tea/modules/interact"
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdIssuesCreate represents a sub command of issues to create issue // CmdIssuesCreate represents a sub command of issues to create issue
@ -22,10 +21,10 @@ var CmdIssuesCreate = cli.Command{
Description: `Create an issue on repository`, Description: `Create an issue on repository`,
ArgsUsage: " ", // command does not accept arguments ArgsUsage: " ", // command does not accept arguments
Action: runIssuesCreate, Action: runIssuesCreate,
Flags: flags.IssuePRCreateFlags, Flags: flags.IssuePREditFlags,
} }
func runIssuesCreate(_ stdctx.Context, cmd *cli.Command) error { func runIssuesCreate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
@ -33,7 +32,7 @@ func runIssuesCreate(_ stdctx.Context, cmd *cli.Command) error {
return interact.CreateIssue(ctx.Login, ctx.Owner, ctx.Repo) return interact.CreateIssue(ctx.Login, ctx.Owner, ctx.Repo)
} }
opts, err := flags.GetIssuePRCreateFlags(ctx) opts, err := flags.GetIssuePREditFlags(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,72 +0,0 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package issues
import (
"fmt"
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"
)
// CmdIssuesEdit is the subcommand of issues to edit issues
var CmdIssuesEdit = cli.Command{
Name: "edit",
Aliases: []string{"e"},
Usage: "Edit one or more issues",
Description: `Edit one or more issues. To unset a property again,
use an empty string (eg. --milestone "").`,
ArgsUsage: "<idx> [<idx>...]",
Action: runIssuesEdit,
Flags: flags.IssuePREditFlags,
}
func runIssuesEdit(_ stdctx.Context, cmd *cli.Command) error {
ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
if !cmd.Args().Present() {
return fmt.Errorf("must specify at least one issue index")
}
opts, err := flags.GetIssuePREditFlags(ctx)
if err != nil {
return err
}
indices, err := utils.ArgsToIndices(ctx.Args().Slice())
if err != nil {
return err
}
client := ctx.Login.Client()
for _, opts.Index = range indices {
if ctx.NumFlags() == 0 {
var err error
opts, err = interact.EditIssue(*ctx, opts.Index)
if err != nil {
return err
}
}
issue, err := task.EditIssue(ctx, client, *opts)
if err != nil {
return err
}
if ctx.Args().Len() > 1 {
fmt.Println(issue.HTMLURL)
} else {
print.IssueDetails(issue, nil)
}
}
return nil
}

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package issues package issues
import ( import (
stdctx "context"
"fmt" "fmt"
"time" "time"
@ -14,11 +14,11 @@ import (
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/araddon/dateparse" "github.com/araddon/dateparse"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
var issueFieldsFlag = flags.FieldsFlag(print.IssueFields, []string{ var issueFieldsFlag = flags.FieldsFlag(print.IssueFields, []string{
"index", "title", "state", "author", "milestone", "labels", "owner", "repo", "index", "title", "state", "author", "milestone", "labels",
}) })
// CmdIssuesList represents a sub command of issues to list issues // CmdIssuesList represents a sub command of issues to list issues
@ -33,8 +33,9 @@ var CmdIssuesList = cli.Command{
} }
// RunIssuesList list issues // RunIssuesList list issues
func RunIssuesList(_ stdctx.Context, cmd *cli.Command) error { func RunIssuesList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
state := gitea.StateOpen state := gitea.StateOpen
switch ctx.String("state") { switch ctx.String("state") {
@ -74,52 +75,27 @@ func RunIssuesList(_ stdctx.Context, cmd *cli.Command) error {
return err return err
} }
} }
owner := ctx.Owner
if ctx.IsSet("owner") {
owner = ctx.String("owner")
}
// ignore error, as we don't do any input validation on these flags // ignore error, as we don't do any input validation on these flags
labels, _ := flags.LabelFilterFlag.GetValues(cmd) labels, _ := flags.LabelFilterFlag.GetValues(cmd)
milestones, _ := flags.MilestoneFilterFlag.GetValues(cmd) milestones, _ := flags.MilestoneFilterFlag.GetValues(cmd)
var issues []*gitea.Issue
if ctx.Repo != "" {
issues, _, err = ctx.Login.Client().ListRepoIssues(owner, ctx.Repo, gitea.ListIssueOption{
ListOptions: ctx.GetListOptions(),
State: state,
Type: kind,
KeyWord: ctx.String("keyword"),
CreatedBy: ctx.String("author"),
AssignedBy: ctx.String("assigned-to"),
MentionedBy: ctx.String("mentions"),
Labels: labels,
Milestones: milestones,
Since: from,
Before: until,
})
if err != nil { issues, _, err := ctx.Login.Client().ListRepoIssues(ctx.Owner, ctx.Repo, gitea.ListIssueOption{
return err ListOptions: ctx.GetListOptions(),
} State: state,
} else { Type: kind,
issues, _, err = ctx.Login.Client().ListIssues(gitea.ListIssueOption{ KeyWord: ctx.String("keyword"),
ListOptions: ctx.GetListOptions(), CreatedBy: ctx.String("author"),
State: state, AssignedBy: ctx.String("assigned-to"),
Type: kind, MentionedBy: ctx.String("mentions"),
KeyWord: ctx.String("keyword"), Labels: labels,
CreatedBy: ctx.String("author"), Milestones: milestones,
AssignedBy: ctx.String("assigned-to"), Since: from,
MentionedBy: ctx.String("mentions"), Before: until,
Labels: labels, })
Milestones: milestones,
Since: from,
Before: until,
Owner: owner,
})
if err != nil { if err != nil {
return err return err
}
} }
fields, err := issueFieldsFlag.GetValues(cmd) fields, err := issueFieldsFlag.GetValues(cmd)

View File

@ -1,27 +1,26 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package issues package issues
import ( import (
"context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdIssuesReopen represents a sub command of issues to open an issue // CmdIssuesReopen represents a sub command of issues to open an issue
var CmdIssuesReopen = cli.Command{ var CmdIssuesReopen = cli.Command{
Name: "reopen", Name: "reopen",
Aliases: []string{"open"}, Aliases: []string{"open"},
Usage: "Change state of one or more issues to 'open'", Usage: "Change state of an issue to 'open'",
Description: `Change state of one or more issues to 'open'`, Description: `Change state of an issue to 'open'`,
ArgsUsage: "<issue index> [<issue index>...]", ArgsUsage: "<issue index>",
Action: func(ctx context.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
var s = gitea.StateOpen var s = gitea.StateOpen
return editIssueState(ctx, cmd, gitea.EditIssueOption{State: &s}) return editIssueState(ctx, gitea.EditIssueOption{State: &s})
}, },
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }

View File

@ -1,14 +1,14 @@
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
"context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/labels" "code.gitea.io/tea/cmd/labels"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLabels represents to operate repositories' labels. // CmdLabels represents to operate repositories' labels.
@ -20,7 +20,7 @@ var CmdLabels = cli.Command{
Description: `Manage issue labels`, Description: `Manage issue labels`,
ArgsUsage: " ", // command does not accept arguments ArgsUsage: " ", // command does not accept arguments
Action: runLabels, Action: runLabels,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&labels.CmdLabelsList, &labels.CmdLabelsList,
&labels.CmdLabelCreate, &labels.CmdLabelCreate,
&labels.CmdLabelUpdate, &labels.CmdLabelUpdate,
@ -29,13 +29,13 @@ var CmdLabels = cli.Command{
Flags: labels.CmdLabelsList.Flags, Flags: labels.CmdLabelsList.Flags,
} }
func runLabels(ctx context.Context, cmd *cli.Command) error { func runLabels(ctx *cli.Context) error {
if cmd.Args().Len() == 1 { if ctx.Args().Len() == 1 {
return runLabelsDetails(cmd) return runLabelsDetails(ctx)
} }
return labels.RunLabelsList(ctx, cmd) return labels.RunLabelsList(ctx)
} }
func runLabelsDetails(cmd *cli.Command) error { func runLabelsDetails(ctx *cli.Context) error {
return fmt.Errorf("Not yet implemented") return fmt.Errorf("Not yet implemented")
} }

View File

@ -1,11 +1,11 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package labels package labels
import ( import (
"bufio" "bufio"
stdctx "context"
"log" "log"
"os" "os"
"strings" "strings"
@ -14,7 +14,7 @@ import (
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLabelCreate represents a sub command of labels to create label. // CmdLabelCreate represents a sub command of labels to create label.
@ -45,7 +45,7 @@ var CmdLabelCreate = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runLabelCreate(_ stdctx.Context, cmd *cli.Command) error { func runLabelCreate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,5 +1,6 @@
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package labels package labels

View File

@ -1,15 +1,14 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package labels package labels
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLabelDelete represents a sub command of labels to delete label. // CmdLabelDelete represents a sub command of labels to delete label.
@ -28,7 +27,7 @@ var CmdLabelDelete = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runLabelDelete(_ stdctx.Context, cmd *cli.Command) error { func runLabelDelete(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,18 +1,17 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package labels package labels
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLabelsList represents a sub command of labels to list labels // CmdLabelsList represents a sub command of labels to list labels
@ -35,7 +34,7 @@ var CmdLabelsList = cli.Command{
} }
// RunLabelsList list labels. // RunLabelsList list labels.
func RunLabelsList(_ stdctx.Context, cmd *cli.Command) error { func RunLabelsList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,16 +1,15 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package labels package labels
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLabelUpdate represents a sub command of labels to update label. // CmdLabelUpdate represents a sub command of labels to update label.
@ -40,7 +39,7 @@ var CmdLabelUpdate = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runLabelUpdate(_ stdctx.Context, cmd *cli.Command) error { func runLabelUpdate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,17 +1,17 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
"context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/login" "code.gitea.io/tea/cmd/login"
"code.gitea.io/tea/modules/config" "code.gitea.io/tea/modules/config"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLogin represents to login a gitea server. // CmdLogin represents to login a gitea server.
@ -23,22 +23,20 @@ var CmdLogin = cli.Command{
Description: `Log in to a Gitea server`, Description: `Log in to a Gitea server`,
ArgsUsage: "[<login name>]", ArgsUsage: "[<login name>]",
Action: runLogins, Action: runLogins,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&login.CmdLoginList, &login.CmdLoginList,
&login.CmdLoginAdd, &login.CmdLoginAdd,
&login.CmdLoginEdit, &login.CmdLoginEdit,
&login.CmdLoginDelete, &login.CmdLoginDelete,
&login.CmdLoginSetDefault, &login.CmdLoginSetDefault,
&login.CmdLoginHelper,
&login.CmdLoginOAuthRefresh,
}, },
} }
func runLogins(ctx context.Context, cmd *cli.Command) error { func runLogins(ctx *cli.Context) error {
if cmd.Args().Len() == 1 { if ctx.Args().Len() == 1 {
return runLoginDetail(cmd.Args().First()) return runLoginDetail(ctx.Args().First())
} }
return login.RunLoginList(ctx, cmd) return login.RunLoginList(ctx)
} }
func runLoginDetail(name string) error { func runLoginDetail(name string) error {

View File

@ -1,16 +1,14 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package login package login
import ( import (
"context"
"code.gitea.io/tea/modules/auth"
"code.gitea.io/tea/modules/interact" "code.gitea.io/tea/modules/interact"
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLoginAdd represents to login a gitea server. // CmdLoginAdd represents to login a gitea server.
@ -29,133 +27,56 @@ var CmdLoginAdd = cli.Command{
Name: "url", Name: "url",
Aliases: []string{"u"}, Aliases: []string{"u"},
Value: "https://gitea.com", Value: "https://gitea.com",
Sources: cli.EnvVars("GITEA_SERVER_URL"), EnvVars: []string{"GITEA_SERVER_URL"},
Usage: "Server URL", Usage: "Server URL",
}, },
&cli.BoolFlag{
Name: "no-version-check",
Aliases: []string{"nv"},
Usage: "Do not check version of Gitea instance",
},
&cli.StringFlag{ &cli.StringFlag{
Name: "token", Name: "token",
Aliases: []string{"t"}, Aliases: []string{"t"},
Value: "", Value: "",
Sources: cli.EnvVars("GITEA_SERVER_TOKEN"), EnvVars: []string{"GITEA_SERVER_TOKEN"},
Usage: "Access token. Can be obtained from Settings > Applications", Usage: "Access token. Can be obtained from Settings > Applications",
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "user", Name: "user",
Value: "", Value: "",
Sources: cli.EnvVars("GITEA_SERVER_USER"), EnvVars: []string{"GITEA_SERVER_USER"},
Usage: "User for basic auth (will create token)", Usage: "User for basic auth (will create token)",
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "password", Name: "password",
Aliases: []string{"pwd"}, Aliases: []string{"pwd"},
Value: "", Value: "",
Sources: cli.EnvVars("GITEA_SERVER_PASSWORD"), EnvVars: []string{"GITEA_SERVER_PASSWORD"},
Usage: "Password for basic auth (will create token)", Usage: "Password for basic auth (will create token)",
}, },
&cli.StringFlag{
Name: "otp",
Sources: cli.EnvVars("GITEA_SERVER_OTP"),
Usage: "OTP token for auth, if necessary",
},
&cli.StringFlag{
Name: "scopes",
Sources: cli.EnvVars("GITEA_SCOPES"),
Usage: "Token scopes to add when creating a new token, separated by a comma",
},
&cli.StringFlag{ &cli.StringFlag{
Name: "ssh-key", Name: "ssh-key",
Aliases: []string{"s"}, Aliases: []string{"s"},
Usage: "Path to a SSH key/certificate to use, overrides auto-discovery", Usage: "Path to a SSH key to use, overrides auto-discovery",
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "insecure", Name: "insecure",
Aliases: []string{"i"}, Aliases: []string{"i"},
Usage: "Disable TLS verification", Usage: "Disable TLS verification",
}, },
&cli.StringFlag{
Name: "ssh-agent-principal",
Aliases: []string{"c"},
Usage: "Use SSH certificate with specified principal to login (needs a running ssh-agent with certificate loaded)",
},
&cli.StringFlag{
Name: "ssh-agent-key",
Aliases: []string{"a"},
Usage: "Use SSH public key or SSH fingerprint to login (needs a running ssh-agent with ssh key loaded)",
},
&cli.BoolFlag{
Name: "helper",
Aliases: []string{"j"},
Usage: "Add helper",
},
&cli.BoolFlag{
Name: "oauth",
Aliases: []string{"o"},
Usage: "Use interactive OAuth2 flow for authentication",
},
&cli.StringFlag{
Name: "client-id",
Usage: "OAuth client ID (for use with --oauth)",
},
&cli.StringFlag{
Name: "redirect-url",
Usage: "OAuth redirect URL (for use with --oauth)",
},
}, },
Action: runLoginAdd, Action: runLoginAdd,
} }
func runLoginAdd(_ context.Context, cmd *cli.Command) error { func runLoginAdd(ctx *cli.Context) error {
// if no args create login interactive // if no args create login interactive
if cmd.NumFlags() == 0 { if ctx.NumFlags() == 0 {
return interact.CreateLogin() return interact.CreateLogin()
} }
// if OAuth flag is provided, use OAuth2 PKCE flow
if cmd.Bool("oauth") {
opts := auth.OAuthOptions{
Name: cmd.String("name"),
URL: cmd.String("url"),
Insecure: cmd.Bool("insecure"),
}
// Only set clientID if provided
if cmd.String("client-id") != "" {
opts.ClientID = cmd.String("client-id")
}
// Only set redirect URL if provided
if cmd.String("redirect-url") != "" {
opts.RedirectURL = cmd.String("redirect-url")
}
return auth.OAuthLoginWithFullOptions(opts)
}
sshAgent := false
if cmd.String("ssh-agent-key") != "" || cmd.String("ssh-agent-principal") != "" {
sshAgent = true
}
// else use args to add login // else use args to add login
return task.CreateLogin( return task.CreateLogin(
cmd.String("name"), ctx.String("name"),
cmd.String("token"), ctx.String("token"),
cmd.String("user"), ctx.String("user"),
cmd.String("password"), ctx.String("password"),
cmd.String("otp"), ctx.String("ssh-key"),
cmd.String("scopes"), ctx.String("url"),
cmd.String("ssh-key"), ctx.Bool("insecure"))
cmd.String("url"),
cmd.String("ssh-agent-principal"),
cmd.String("ssh-agent-key"),
cmd.Bool("insecure"),
sshAgent,
!cmd.Bool("no-version-check"),
cmd.Bool("helper"),
)
} }

View File

@ -1,16 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package login package login
import ( import (
"context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/config" "code.gitea.io/tea/modules/config"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLoginSetDefault represents to login a gitea server. // CmdLoginSetDefault represents to login a gitea server.
@ -23,8 +23,8 @@ var CmdLoginSetDefault = cli.Command{
Flags: []cli.Flag{&flags.OutputFlag}, Flags: []cli.Flag{&flags.OutputFlag},
} }
func runLoginSetDefault(_ context.Context, cmd *cli.Command) error { func runLoginSetDefault(ctx *cli.Context) error {
if cmd.Args().Len() == 0 { if ctx.Args().Len() == 0 {
l, err := config.GetDefaultLogin() l, err := config.GetDefaultLogin()
if err != nil { if err != nil {
return err return err
@ -33,6 +33,6 @@ func runLoginSetDefault(_ context.Context, cmd *cli.Command) error {
return nil return nil
} }
name := cmd.Args().First() name := ctx.Args().First()
return config.SetDefaultLogin(name) return config.SetDefaultLogin(name)
} }

View File

@ -1,16 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package login package login
import ( import (
"context"
"errors" "errors"
"log" "log"
"code.gitea.io/tea/modules/config" "code.gitea.io/tea/modules/config"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLoginDelete is a command to delete a login // CmdLoginDelete is a command to delete a login
@ -24,7 +24,7 @@ var CmdLoginDelete = cli.Command{
} }
// RunLoginDelete runs the action of a login delete command // RunLoginDelete runs the action of a login delete command
func RunLoginDelete(_ context.Context, cmd *cli.Command) error { func RunLoginDelete(ctx *cli.Context) error {
logins, err := config.GetLogins() logins, err := config.GetLogins()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -32,8 +32,8 @@ func RunLoginDelete(_ context.Context, cmd *cli.Command) error {
var name string var name string
if len(cmd.Args().First()) != 0 { if len(ctx.Args().First()) != 0 {
name = cmd.Args().First() name = ctx.Args().First()
} else if len(logins) == 1 { } else if len(logins) == 1 {
name = logins[0].Name name = logins[0].Name
} else { } else {

View File

@ -1,19 +1,15 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package login package login
import ( import (
"context"
"log"
"os"
"os/exec"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/config" "code.gitea.io/tea/modules/config"
"github.com/skratchdot/open-golang/open" "github.com/skratchdot/open-golang/open"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLoginEdit represents to login a gitea server. // CmdLoginEdit represents to login a gitea server.
@ -27,15 +23,6 @@ var CmdLoginEdit = cli.Command{
Flags: []cli.Flag{&flags.OutputFlag}, Flags: []cli.Flag{&flags.OutputFlag},
} }
func runLoginEdit(_ context.Context, _ *cli.Command) error { func runLoginEdit(_ *cli.Context) error {
if e, ok := os.LookupEnv("EDITOR"); ok && e != "" {
cmd := exec.Command(e, config.GetConfigPath())
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Fatal(err.Error())
}
}
return open.Start(config.GetConfigPath()) return open.Start(config.GetConfigPath())
} }

View File

@ -1,131 +0,0 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package login
import (
"bufio"
"context"
"fmt"
"log"
"net/url"
"os"
"strings"
"time"
"code.gitea.io/tea/modules/auth"
"code.gitea.io/tea/modules/config"
"code.gitea.io/tea/modules/task"
"github.com/urfave/cli/v3"
)
// CmdLoginHelper represents to login a gitea helper.
var CmdLoginHelper = cli.Command{
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"},
Action: func(_ context.Context, _ *cli.Command) error {
return nil
},
},
{
Name: "setup",
Description: "Setup helper to tea authenticate",
Action: func(_ context.Context, _ *cli.Command) error {
logins, err := config.GetLogins()
if err != nil {
return err
}
for _, login := range logins {
added, err := task.SetupHelper(login)
if err != nil {
return err
} else if added {
fmt.Printf("Added \"%s\"\n", login.Name)
} else {
fmt.Printf("\"%s\" has already been added!\n", login.Name)
}
}
return nil
},
},
{
Name: "get",
Description: "Get token to auth",
Action: func(_ context.Context, cmd *cli.Command) error {
wants := map[string]string{}
s := bufio.NewScanner(os.Stdin)
for s.Scan() {
line := s.Text()
if line == "" {
break
}
parts := strings.SplitN(line, "=", 2)
if len(parts) < 2 {
continue
}
key, value := parts[0], parts[1]
if key == "url" {
u, err := url.Parse(value)
if err != nil {
return err
}
wants["protocol"] = u.Scheme
wants["host"] = u.Host
wants["path"] = u.Path
wants["username"] = u.User.Username()
wants["password"], _ = u.User.Password()
} else {
wants[key] = value
}
}
if len(wants["host"]) == 0 {
log.Fatal("Require hostname")
} else if len(wants["protocol"]) == 0 {
wants["protocol"] = "http"
}
userConfig := config.GetLoginByHost(wants["host"])
if userConfig == nil {
log.Fatal("host not exists")
} else if len(userConfig.Token) == 0 {
log.Fatal("User no set")
}
host, err := url.Parse(userConfig.URL)
if err != nil {
return err
}
if userConfig.TokenExpiry > 0 && time.Now().Unix() > userConfig.TokenExpiry {
// Token is expired, refresh it
err = auth.RefreshAccessToken(userConfig)
if err != nil {
return err
}
// Once token is refreshed, get the latest from the updated config
refreshedConfig := config.GetLoginByHost(wants["host"])
if refreshedConfig != nil {
userConfig = refreshedConfig
}
}
_, err = fmt.Fprintf(os.Stdout, "protocol=%s\nhost=%s\nusername=%s\npassword=%s\n", host.Scheme, host.Host, userConfig.User, userConfig.Token)
if err != nil {
return err
}
return nil
},
},
},
}

View File

@ -1,16 +1,15 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package login package login
import ( import (
"context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/config" "code.gitea.io/tea/modules/config"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLoginList represents to login a gitea server. // CmdLoginList represents to login a gitea server.
@ -25,7 +24,7 @@ var CmdLoginList = cli.Command{
} }
// RunLoginList list all logins // RunLoginList list all logins
func RunLoginList(_ context.Context, cmd *cli.Command) error { func RunLoginList(cmd *cli.Context) error {
logins, err := config.GetLogins() logins, err := config.GetLogins()
if err != nil { if err != nil {
return err return err

View File

@ -1,59 +0,0 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package login
import (
"context"
"fmt"
"code.gitea.io/tea/modules/auth"
"code.gitea.io/tea/modules/config"
"github.com/urfave/cli/v3"
)
// CmdLoginOAuthRefresh represents a command to refresh an OAuth token
var CmdLoginOAuthRefresh = cli.Command{
Name: "oauth-refresh",
Usage: "Refresh an OAuth token",
Description: "Manually refresh an expired OAuth token. Usually only used when troubleshooting authentication.",
ArgsUsage: "[<login name>]",
Action: runLoginOAuthRefresh,
}
func runLoginOAuthRefresh(_ context.Context, cmd *cli.Command) error {
var loginName string
// Get login name from args or use default
if cmd.Args().Len() > 0 {
loginName = cmd.Args().First()
} else {
// Get default login
login, err := config.GetDefaultLogin()
if err != nil {
return fmt.Errorf("no login specified and no default login found: %s", err)
}
loginName = login.Name
}
// Get the login from config
login := config.GetLoginByName(loginName)
if login == nil {
return fmt.Errorf("login '%s' not found", loginName)
}
// Check if the login has a refresh token
if login.RefreshToken == "" {
return fmt.Errorf("login '%s' does not have a refresh token. It may have been created using a different authentication method", loginName)
}
// Refresh the token
err := auth.RefreshAccessToken(login)
if err != nil {
return fmt.Errorf("failed to refresh token: %s", err)
}
fmt.Printf("Successfully refreshed OAuth token for %s\n", loginName)
return nil
}

View File

@ -1,12 +1,13 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
"code.gitea.io/tea/cmd/login" "code.gitea.io/tea/cmd/login"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdLogout represents to logout a gitea server. // CmdLogout represents to logout a gitea server.

View File

@ -1,15 +1,15 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/milestones" "code.gitea.io/tea/cmd/milestones"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
) )
// CmdMilestones represents to operate repositories milestones. // CmdMilestones represents to operate repositories milestones.
@ -21,7 +21,7 @@ var CmdMilestones = cli.Command{
Description: `List and create milestones`, Description: `List and create milestones`,
ArgsUsage: "[<milestone name>]", ArgsUsage: "[<milestone name>]",
Action: runMilestones, Action: runMilestones,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&milestones.CmdMilestonesList, &milestones.CmdMilestonesList,
&milestones.CmdMilestonesCreate, &milestones.CmdMilestonesCreate,
&milestones.CmdMilestonesClose, &milestones.CmdMilestonesClose,
@ -32,14 +32,14 @@ var CmdMilestones = cli.Command{
Flags: milestones.CmdMilestonesList.Flags, Flags: milestones.CmdMilestonesList.Flags,
} }
func runMilestones(ctx stdctx.Context, cmd *cli.Command) error { func runMilestones(ctx *cli.Context) error {
if cmd.Args().Len() == 1 { if ctx.Args().Len() == 1 {
return runMilestoneDetail(ctx, cmd, cmd.Args().First()) return runMilestoneDetail(ctx, ctx.Args().First())
} }
return milestones.RunMilestonesList(ctx, cmd) return milestones.RunMilestonesList(ctx)
} }
func runMilestoneDetail(_ stdctx.Context, cmd *cli.Command, name string) error { func runMilestoneDetail(cmd *cli.Context, name string) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,26 +1,26 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package milestones package milestones
import ( import (
"context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
) )
// CmdMilestonesClose represents a sub command of milestones to close an milestone // CmdMilestonesClose represents a sub command of milestones to close an milestone
var CmdMilestonesClose = cli.Command{ var CmdMilestonesClose = cli.Command{
Name: "close", Name: "close",
Usage: "Change state of one or more milestones to 'closed'", Usage: "Change state of an milestone to 'closed'",
Description: `Change state of one or more milestones to 'closed'`, Description: `Change state of an milestone to 'closed'`,
ArgsUsage: "<milestone name> [<milestone name>...]", ArgsUsage: "<milestone name>",
Action: func(ctx context.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
if cmd.Bool("force") { if ctx.Bool("force") {
return deleteMilestone(ctx, cmd) return deleteMilestone(ctx)
} }
return editMilestoneStatus(ctx, cmd, true) return editMilestoneStatus(ctx, true)
}, },
Flags: append([]cli.Flag{ Flags: append([]cli.Flag{
&cli.BoolFlag{ &cli.BoolFlag{

View File

@ -1,20 +1,20 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package milestones package milestones
import ( import (
"time" "time"
stdctx "context"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/interact" "code.gitea.io/tea/modules/interact"
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"code.gitea.io/sdk/gitea"
"github.com/araddon/dateparse" "github.com/araddon/dateparse"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdMilestonesCreate represents a sub command of milestones to create milestone // CmdMilestonesCreate represents a sub command of milestones to create milestone
@ -49,7 +49,7 @@ var CmdMilestonesCreate = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runMilestonesCreate(_ stdctx.Context, cmd *cli.Command) error { func runMilestonesCreate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
date := ctx.String("deadline") date := ctx.String("deadline")

View File

@ -1,15 +1,14 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package milestones package milestones
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdMilestonesDelete represents a sub command of milestones to delete an milestone // CmdMilestonesDelete represents a sub command of milestones to delete an milestone
@ -23,7 +22,7 @@ var CmdMilestonesDelete = cli.Command{
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }
func deleteMilestone(_ stdctx.Context, cmd *cli.Command) error { func deleteMilestone(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,19 +1,19 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package milestones package milestones
import ( import (
"fmt" "fmt"
stdctx "context"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v2"
) )
var msIssuesFieldsFlag = flags.FieldsFlag(print.IssueFields, []string{ var msIssuesFieldsFlag = flags.FieldsFlag(print.IssueFields, []string{
@ -28,7 +28,7 @@ var CmdMilestonesIssues = cli.Command{
Description: "manage issue/pull of an milestone", Description: "manage issue/pull of an milestone",
ArgsUsage: "<milestone name>", ArgsUsage: "<milestone name>",
Action: runMilestoneIssueList, Action: runMilestoneIssueList,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&CmdMilestoneAddIssue, &CmdMilestoneAddIssue,
&CmdMilestoneRemoveIssue, &CmdMilestoneRemoveIssue,
}, },
@ -70,7 +70,7 @@ var CmdMilestoneRemoveIssue = cli.Command{
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }
func runMilestoneIssueList(_ stdctx.Context, cmd *cli.Command) error { func runMilestoneIssueList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()
@ -120,7 +120,7 @@ func runMilestoneIssueList(_ stdctx.Context, cmd *cli.Command) error {
return nil return nil
} }
func runMilestoneIssueAdd(_ stdctx.Context, cmd *cli.Command) error { func runMilestoneIssueAdd(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()
@ -147,7 +147,7 @@ func runMilestoneIssueAdd(_ stdctx.Context, cmd *cli.Command) error {
return err return err
} }
func runMilestoneIssueRemove(_ stdctx.Context, cmd *cli.Command) error { func runMilestoneIssueRemove(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,17 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package milestones package milestones
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
var fieldsFlag = flags.FieldsFlag(print.MilestoneFields, []string{ var fieldsFlag = flags.FieldsFlag(print.MilestoneFields, []string{
@ -39,7 +38,7 @@ var CmdMilestonesList = cli.Command{
} }
// RunMilestonesList list milestones // RunMilestonesList list milestones
func RunMilestonesList(_ stdctx.Context, cmd *cli.Command) error { func RunMilestonesList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,61 +1,43 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package milestones package milestones
import ( import (
stdctx "context"
"fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdMilestonesReopen represents a sub command of milestones to open an milestone // CmdMilestonesReopen represents a sub command of milestones to open an milestone
var CmdMilestonesReopen = cli.Command{ var CmdMilestonesReopen = cli.Command{
Name: "reopen", Name: "reopen",
Aliases: []string{"open"}, Aliases: []string{"open"},
Usage: "Change state of one or more milestones to 'open'", Usage: "Change state of an milestone to 'open'",
Description: `Change state of one or more milestones to 'open'`, Description: `Change state of an milestone to 'open'`,
ArgsUsage: "<milestone name> [<milestone name> ...]", ArgsUsage: "<milestone name>",
Action: func(ctx stdctx.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
return editMilestoneStatus(ctx, cmd, false) return editMilestoneStatus(ctx, false)
}, },
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }
func editMilestoneStatus(_ stdctx.Context, cmd *cli.Command, close bool) error { func editMilestoneStatus(cmd *cli.Context, close bool) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
if ctx.Args().Len() == 0 { client := ctx.Login.Client()
return fmt.Errorf(ctx.Command.ArgsUsage)
}
state := gitea.StateOpen state := gitea.StateOpen
if close { if close {
state = gitea.StateClosed state = gitea.StateClosed
} }
_, _, err := client.EditMilestoneByName(ctx.Owner, ctx.Repo, ctx.Args().First(), gitea.EditMilestoneOption{
State: &state,
Title: ctx.Args().First(),
})
client := ctx.Login.Client() return err
for _, ms := range ctx.Args().Slice() {
opts := gitea.EditMilestoneOption{
State: &state,
Title: ms,
}
milestone, _, err := client.EditMilestoneByName(ctx.Owner, ctx.Repo, ms, opts)
if err != nil {
return err
}
if ctx.Args().Len() > 1 {
fmt.Printf("%s/milestone/%d\n", ctx.GetRemoteRepoHTMLURL(), milestone.ID)
} else {
print.MilestoneDetails(milestone)
}
}
return nil
} }

View File

@ -1,12 +1,13 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
"code.gitea.io/tea/cmd/notifications" "code.gitea.io/tea/cmd/notifications"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdNotifications is the main command to operate with notifications // CmdNotifications is the main command to operate with notifications
@ -17,7 +18,7 @@ var CmdNotifications = cli.Command{
Usage: "Show notifications", Usage: "Show notifications",
Description: "Show notifications, by default based on the current repo if available", Description: "Show notifications, by default based on the current repo if available",
Action: notifications.RunNotificationsList, Action: notifications.RunNotificationsList,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&notifications.CmdNotificationsList, &notifications.CmdNotificationsList,
&notifications.CmdNotificationsMarkRead, &notifications.CmdNotificationsMarkRead,
&notifications.CmdNotificationsMarkUnread, &notifications.CmdNotificationsMarkUnread,

View File

@ -1,10 +1,10 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package notifications package notifications
import ( import (
stdctx "context"
"log" "log"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -12,7 +12,7 @@ import (
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
var notifyFieldsFlag = flags.FieldsFlag(print.NotificationFields, []string{ var notifyFieldsFlag = flags.FieldsFlag(print.NotificationFields, []string{
@ -37,9 +37,9 @@ var CmdNotificationsList = cli.Command{
} }
// RunNotificationsList list notifications // RunNotificationsList list notifications
func RunNotificationsList(ctx stdctx.Context, cmd *cli.Command) error { func RunNotificationsList(ctx *cli.Context) error {
var states []gitea.NotifyStatus var states []gitea.NotifyStatus
statesStr, err := flags.NotificationStateFlag.GetValues(cmd) statesStr, err := flags.NotificationStateFlag.GetValues(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -48,7 +48,7 @@ func RunNotificationsList(ctx stdctx.Context, cmd *cli.Command) error {
} }
var types []gitea.NotifySubjectType var types []gitea.NotifySubjectType
typesStr, err := notifyTypeFlag.GetValues(cmd) typesStr, err := notifyTypeFlag.GetValues(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -56,11 +56,11 @@ func RunNotificationsList(ctx stdctx.Context, cmd *cli.Command) error {
types = append(types, gitea.NotifySubjectType(t)) types = append(types, gitea.NotifySubjectType(t))
} }
return listNotifications(ctx, cmd, states, types) return listNotifications(ctx, states, types)
} }
// listNotifications will get the notifications based on status and subject type // listNotifications will get the notifications based on status and subject type
func listNotifications(_ stdctx.Context, cmd *cli.Command, status []gitea.NotifyStatus, subjects []gitea.NotifySubjectType) error { func listNotifications(cmd *cli.Context, status []gitea.NotifyStatus, subjects []gitea.NotifySubjectType) error {
var news []*gitea.NotificationThread var news []*gitea.NotificationThread
var err error var err error

View File

@ -1,17 +1,17 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package notifications package notifications
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdNotificationsMarkRead represents a sub command of notifications to list read notifications // CmdNotificationsMarkRead represents a sub command of notifications to list read notifications
@ -22,16 +22,16 @@ var CmdNotificationsMarkRead = cli.Command{
Description: "Mark all filtered or a specific notification as read", Description: "Mark all filtered or a specific notification as read",
ArgsUsage: "[all | <notification id>]", ArgsUsage: "[all | <notification id>]",
Flags: flags.NotificationFlags, Flags: flags.NotificationFlags,
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
ctx := context.InitCommand(cmd) cmd := context.InitCommand(ctx)
filter, err := flags.NotificationStateFlag.GetValues(cmd) filter, err := flags.NotificationStateFlag.GetValues(ctx)
if err != nil { if err != nil {
return err return err
} }
if !ctx.IsSet(flags.NotificationStateFlag.Name) { if !cmd.IsSet(flags.NotificationStateFlag.Name) {
filter = []string{string(gitea.NotifyStatusUnread)} filter = []string{string(gitea.NotifyStatusUnread)}
} }
return markNotificationAs(ctx, filter, gitea.NotifyStatusRead) return markNotificationAs(cmd, filter, gitea.NotifyStatusRead)
}, },
} }
@ -43,16 +43,16 @@ var CmdNotificationsMarkUnread = cli.Command{
Description: "Mark all filtered or a specific notification as unread", Description: "Mark all filtered or a specific notification as unread",
ArgsUsage: "[all | <notification id>]", ArgsUsage: "[all | <notification id>]",
Flags: flags.NotificationFlags, Flags: flags.NotificationFlags,
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
ctx := context.InitCommand(cmd) cmd := context.InitCommand(ctx)
filter, err := flags.NotificationStateFlag.GetValues(cmd) filter, err := flags.NotificationStateFlag.GetValues(ctx)
if err != nil { if err != nil {
return err return err
} }
if !ctx.IsSet(flags.NotificationStateFlag.Name) { if !cmd.IsSet(flags.NotificationStateFlag.Name) {
filter = []string{string(gitea.NotifyStatusRead)} filter = []string{string(gitea.NotifyStatusRead)}
} }
return markNotificationAs(ctx, filter, gitea.NotifyStatusUnread) return markNotificationAs(cmd, filter, gitea.NotifyStatusUnread)
}, },
} }
@ -64,16 +64,16 @@ var CmdNotificationsMarkPinned = cli.Command{
Description: "Mark all filtered or a specific notification as pinned", Description: "Mark all filtered or a specific notification as pinned",
ArgsUsage: "[all | <notification id>]", ArgsUsage: "[all | <notification id>]",
Flags: flags.NotificationFlags, Flags: flags.NotificationFlags,
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
ctx := context.InitCommand(cmd) cmd := context.InitCommand(ctx)
filter, err := flags.NotificationStateFlag.GetValues(cmd) filter, err := flags.NotificationStateFlag.GetValues(ctx)
if err != nil { if err != nil {
return err return err
} }
if !ctx.IsSet(flags.NotificationStateFlag.Name) { if !cmd.IsSet(flags.NotificationStateFlag.Name) {
filter = []string{string(gitea.NotifyStatusUnread)} filter = []string{string(gitea.NotifyStatusUnread)}
} }
return markNotificationAs(ctx, filter, gitea.NotifyStatusPinned) return markNotificationAs(cmd, filter, gitea.NotifyStatusPinned)
}, },
} }
@ -84,11 +84,11 @@ var CmdNotificationsUnpin = cli.Command{
Description: "Marks all pinned or a specific notification as read", Description: "Marks all pinned or a specific notification as read",
ArgsUsage: "[all | <notification id>]", ArgsUsage: "[all | <notification id>]",
Flags: flags.NotificationFlags, Flags: flags.NotificationFlags,
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
ctx := context.InitCommand(cmd) cmd := context.InitCommand(ctx)
filter := []string{string(gitea.NotifyStatusPinned)} filter := []string{string(gitea.NotifyStatusPinned)}
// NOTE: we implicitly mark it as read, to match web UI semantics. marking as unread might be more useful? // NOTE: we implicitly mark it as read, to match web UI semantics. marking as unread might be more useful?
return markNotificationAs(ctx, filter, gitea.NotifyStatusRead) return markNotificationAs(cmd, filter, gitea.NotifyStatusRead)
}, },
} }

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"path" "path"
"strings" "strings"
@ -13,7 +13,7 @@ import (
local_git "code.gitea.io/tea/modules/git" local_git "code.gitea.io/tea/modules/git"
"github.com/skratchdot/open-golang/open" "github.com/skratchdot/open-golang/open"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdOpen represents a sub command of issues to open issue on the web browser // CmdOpen represents a sub command of issues to open issue on the web browser
@ -27,7 +27,7 @@ var CmdOpen = cli.Command{
Flags: append([]cli.Flag{}, flags.LoginRepoFlags...), Flags: append([]cli.Flag{}, flags.LoginRepoFlags...),
} }
func runOpen(_ stdctx.Context, cmd *cli.Command) error { func runOpen(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
@ -74,5 +74,6 @@ func runOpen(_ stdctx.Context, cmd *cli.Command) error {
suffix = number suffix = number
} }
return open.Run(path.Join(ctx.GetRemoteRepoHTMLURL(), suffix)) u := path.Join(ctx.Login.URL, ctx.Owner, ctx.Repo, suffix)
return open.Run(u)
} }

View File

@ -1,16 +1,15 @@
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/organizations" "code.gitea.io/tea/cmd/organizations"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdOrgs represents handle organization // CmdOrgs represents handle organization
@ -22,7 +21,7 @@ var CmdOrgs = cli.Command{
Description: "Show organization details", Description: "Show organization details",
ArgsUsage: "[<organization>]", ArgsUsage: "[<organization>]",
Action: runOrganizations, Action: runOrganizations,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&organizations.CmdOrganizationList, &organizations.CmdOrganizationList,
&organizations.CmdOrganizationCreate, &organizations.CmdOrganizationCreate,
&organizations.CmdOrganizationDelete, &organizations.CmdOrganizationDelete,
@ -30,12 +29,12 @@ var CmdOrgs = cli.Command{
Flags: organizations.CmdOrganizationList.Flags, Flags: organizations.CmdOrganizationList.Flags,
} }
func runOrganizations(ctx stdctx.Context, cmd *cli.Command) error { func runOrganizations(cmd *cli.Context) error {
teaCtx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
if teaCtx.Args().Len() == 1 { if ctx.Args().Len() == 1 {
return runOrganizationDetail(teaCtx) return runOrganizationDetail(ctx)
} }
return organizations.RunOrganizationList(ctx, cmd) return organizations.RunOrganizationList(cmd)
} }
func runOrganizationDetail(ctx *context.TeaContext) error { func runOrganizationDetail(ctx *context.TeaContext) error {

View File

@ -1,18 +1,18 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package organizations package organizations
import ( import (
"fmt" "fmt"
stdctx "context"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"github.com/urfave/cli/v3"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v2"
) )
// CmdOrganizationCreate represents a sub command of organizations to delete a given user organization // CmdOrganizationCreate represents a sub command of organizations to delete a given user organization
@ -52,7 +52,7 @@ var CmdOrganizationCreate = cli.Command{
} }
// RunOrganizationCreate sets up a new organization // RunOrganizationCreate sets up a new organization
func RunOrganizationCreate(_ stdctx.Context, cmd *cli.Command) error { func RunOrganizationCreate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
if ctx.Args().Len() < 1 { if ctx.Args().Len() < 1 {

View File

@ -1,15 +1,15 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package organizations package organizations
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdOrganizationDelete represents a sub command of organizations to delete a given user organization // CmdOrganizationDelete represents a sub command of organizations to delete a given user organization
@ -27,7 +27,7 @@ var CmdOrganizationDelete = cli.Command{
} }
// RunOrganizationDelete delete user organization // RunOrganizationDelete delete user organization
func RunOrganizationDelete(_ stdctx.Context, cmd *cli.Command) error { func RunOrganizationDelete(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,16 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package organizations package organizations
import ( import (
stdctx "context"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"github.com/urfave/cli/v3"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v2"
) )
// CmdOrganizationList represents a sub command of organizations to list users organizations // CmdOrganizationList represents a sub command of organizations to list users organizations
@ -28,7 +28,7 @@ var CmdOrganizationList = cli.Command{
} }
// RunOrganizationList list user organizations // RunOrganizationList list user organizations
func RunOrganizationList(_ stdctx.Context, cmd *cli.Command) error { func RunOrganizationList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,10 +1,10 @@
// Copyright 2018 The Gitea Authors. All rights reserved. // Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/pulls" "code.gitea.io/tea/cmd/pulls"
@ -15,7 +15,7 @@ import (
"code.gitea.io/tea/modules/workaround" "code.gitea.io/tea/modules/workaround"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdPulls is the main command to operate on PRs // CmdPulls is the main command to operate on PRs
@ -33,7 +33,7 @@ var CmdPulls = cli.Command{
Usage: "Whether to display comments (will prompt if not provided & run interactively)", Usage: "Whether to display comments (will prompt if not provided & run interactively)",
}, },
}, pulls.CmdPullsList.Flags...), }, pulls.CmdPullsList.Flags...),
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&pulls.CmdPullsList, &pulls.CmdPullsList,
&pulls.CmdPullsCheckout, &pulls.CmdPullsCheckout,
&pulls.CmdPullsClean, &pulls.CmdPullsClean,
@ -47,14 +47,14 @@ var CmdPulls = cli.Command{
}, },
} }
func runPulls(ctx stdctx.Context, cmd *cli.Command) error { func runPulls(ctx *cli.Context) error {
if cmd.Args().Len() == 1 { if ctx.Args().Len() == 1 {
return runPullDetail(ctx, cmd, cmd.Args().First()) return runPullDetail(ctx, ctx.Args().First())
} }
return pulls.RunPullsList(ctx, cmd) return pulls.RunPullsList(ctx)
} }
func runPullDetail(_ stdctx.Context, cmd *cli.Command, index string) error { func runPullDetail(cmd *cli.Context, index string) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
idx, err := utils.ArgToIndex(index) idx, err := utils.ArgToIndex(index)

View File

@ -1,5 +1,6 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
@ -7,14 +8,13 @@ import (
"fmt" "fmt"
"strings" "strings"
stdctx "context"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v2"
) )
// CmdPullsApprove approves a PR // CmdPullsApprove approves a PR
@ -24,7 +24,7 @@ var CmdPullsApprove = cli.Command{
Usage: "Approve a pull request", Usage: "Approve a pull request",
Description: "Approve a pull request", Description: "Approve a pull request",
ArgsUsage: "<pull index> [<comment>]", ArgsUsage: "<pull index> [<comment>]",
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -13,7 +13,7 @@ import (
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdPullsCheckout is a command to locally checkout the given PR // CmdPullsCheckout is a command to locally checkout the given PR
@ -33,7 +33,7 @@ var CmdPullsCheckout = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runPullsCheckout(_ stdctx.Context, cmd *cli.Command) error { func runPullsCheckout(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{ ctx.Ensure(context.CtxRequirement{
LocalRepo: true, LocalRepo: true,

View File

@ -1,19 +1,19 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
"fmt" "fmt"
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/interact" "code.gitea.io/tea/modules/interact"
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
) )
// CmdPullsClean removes the remote and local feature branches, if a PR is merged. // CmdPullsClean removes the remote and local feature branches, if a PR is merged.
@ -31,7 +31,7 @@ var CmdPullsClean = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runPullsClean(_ stdctx.Context, cmd *cli.Command) error { func runPullsClean(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{LocalRepo: true}) ctx.Ensure(context.CtxRequirement{LocalRepo: true})
if ctx.Args().Len() != 1 { if ctx.Args().Len() != 1 {

View File

@ -1,26 +1,25 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
"context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdPullsClose closes a given open pull request // CmdPullsClose closes a given open pull request
var CmdPullsClose = cli.Command{ var CmdPullsClose = cli.Command{
Name: "close", Name: "close",
Usage: "Change state of one or more pull requests to 'closed'", Usage: "Change state of a pull request to 'closed'",
Description: `Change state of one or more pull requests to 'closed'`, Description: `Change state of a pull request to 'closed'`,
ArgsUsage: "<pull index> [<pull index>...]", ArgsUsage: "<pull index>",
Action: func(ctx context.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
var s = gitea.StateClosed var s = gitea.StateClosed
return editPullState(ctx, cmd, gitea.EditPullRequestOption{State: &s}) return editPullState(ctx, gitea.EditPullRequestOption{State: &s})
}, },
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }

View File

@ -1,16 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/interact" "code.gitea.io/tea/modules/interact"
"code.gitea.io/tea/modules/task" "code.gitea.io/tea/modules/task"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
) )
// CmdPullsCreate creates a pull request // CmdPullsCreate creates a pull request
@ -30,16 +30,10 @@ var CmdPullsCreate = cli.Command{
Aliases: []string{"b"}, Aliases: []string{"b"},
Usage: "Branch name of the PR target (default is repos default branch)", Usage: "Branch name of the PR target (default is repos default branch)",
}, },
&cli.BoolFlag{ }, flags.IssuePREditFlags...),
Name: "allow-maintainer-edits",
Aliases: []string{"edits"},
Usage: "Enable maintainers to push to the base branch of created pull",
Value: true,
},
}, flags.IssuePRCreateFlags...),
} }
func runPullsCreate(_ stdctx.Context, cmd *cli.Command) error { func runPullsCreate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
// no args -> interactive mode // no args -> interactive mode
@ -48,7 +42,7 @@ func runPullsCreate(_ stdctx.Context, cmd *cli.Command) error {
} }
// else use args to create PR // else use args to create PR
opts, err := flags.GetIssuePRCreateFlags(ctx) opts, err := flags.GetIssuePREditFlags(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -57,7 +51,6 @@ func runPullsCreate(_ stdctx.Context, cmd *cli.Command) error {
ctx, ctx,
ctx.String("base"), ctx.String("base"),
ctx.String("head"), ctx.String("head"),
ctx.Bool("allow-maintainer-edits"),
opts, opts,
) )
} }

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
@ -12,34 +12,27 @@ import (
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// editPullState abstracts the arg parsing to edit the given pull request // editPullState abstracts the arg parsing to edit the given pull request
func editPullState(_ stdctx.Context, cmd *cli.Command, opts gitea.EditPullRequestOption) error { func editPullState(cmd *cli.Context, opts gitea.EditPullRequestOption) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
if ctx.Args().Len() == 0 { if ctx.Args().Len() == 0 {
return fmt.Errorf("Please provide a Pull Request index") return fmt.Errorf("Please provide a Pull Request index")
} }
indices, err := utils.ArgsToIndices(ctx.Args().Slice()) index, err := utils.ArgToIndex(ctx.Args().First())
if err != nil { if err != nil {
return err return err
} }
client := ctx.Login.Client() pr, _, err := ctx.Login.Client().EditPullRequest(ctx.Owner, ctx.Repo, index, opts)
for _, index := range indices { if err != nil {
pr, _, err := client.EditPullRequest(ctx.Owner, ctx.Repo, index, opts) return err
if err != nil {
return err
}
if len(indices) > 1 {
fmt.Println(pr.HTMLURL)
} else {
print.PullDetails(pr, nil, nil)
}
} }
print.PullDetails(pr, nil, nil)
return nil return nil
} }

View File

@ -1,16 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
stdctx "context"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"github.com/urfave/cli/v3"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v2"
) )
var pullFieldsFlag = flags.FieldsFlag(print.PullFields, []string{ var pullFieldsFlag = flags.FieldsFlag(print.PullFields, []string{
@ -29,7 +29,7 @@ var CmdPullsList = cli.Command{
} }
// RunPullsList return list of pulls // RunPullsList return list of pulls
func RunPullsList(_ stdctx.Context, cmd *cli.Command) error { func RunPullsList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,18 +1,18 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
stdctx "context" "fmt"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/interact"
"code.gitea.io/tea/modules/task"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
) )
// CmdPullsMerge merges a PR // CmdPullsMerge merges a PR
@ -40,13 +40,12 @@ var CmdPullsMerge = cli.Command{
Usage: "Merge commit message", Usage: "Merge commit message",
}, },
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
if ctx.Args().Len() != 1 { if ctx.Args().Len() != 1 {
// If no PR index is provided, try interactive mode return fmt.Errorf("Must specify a PR index")
return interact.MergePull(ctx)
} }
idx, err := utils.ArgToIndex(ctx.Args().First()) idx, err := utils.ArgToIndex(ctx.Args().First())
@ -54,10 +53,18 @@ var CmdPullsMerge = cli.Command{
return err return err
} }
return task.PullMerge(ctx.Login, ctx.Owner, ctx.Repo, idx, gitea.MergePullRequestOption{ success, _, err := ctx.Login.Client().MergePullRequest(ctx.Owner, ctx.Repo, idx, gitea.MergePullRequestOption{
Style: gitea.MergeStyle(ctx.String("style")), Style: gitea.MergeStyle(ctx.String("style")),
Title: ctx.String("title"), Title: ctx.String("title"),
Message: ctx.String("message"), Message: ctx.String("message"),
}) })
if err != nil {
return err
}
if !success {
return fmt.Errorf("Failed to merge PR. Is it still open?")
}
return nil
}, },
} }

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
stdctx "context"
"fmt" "fmt"
"strings" "strings"
@ -14,7 +14,7 @@ import (
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdPullsReject requests changes to a PR // CmdPullsReject requests changes to a PR
@ -23,7 +23,7 @@ var CmdPullsReject = cli.Command{
Usage: "Request changes to a pull request", Usage: "Request changes to a pull request",
Description: "Request changes to a pull request", Description: "Request changes to a pull request",
ArgsUsage: "<pull index> <reason>", ArgsUsage: "<pull index> <reason>",
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,27 +1,26 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
"context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdPullsReopen reopens a given closed pull request // CmdPullsReopen reopens a given closed pull request
var CmdPullsReopen = cli.Command{ var CmdPullsReopen = cli.Command{
Name: "reopen", Name: "reopen",
Aliases: []string{"open"}, Aliases: []string{"open"},
Usage: "Change state of one or more pull requests to 'open'", Usage: "Change state of a pull request to 'open'",
Description: `Change state of one or more pull requests to 'open'`, Description: `Change state of a pull request to 'open'`,
ArgsUsage: "<pull index> [<pull index>...]", ArgsUsage: "<pull index>",
Action: func(ctx context.Context, cmd *cli.Command) error { Action: func(ctx *cli.Context) error {
var s = gitea.StateOpen var s = gitea.StateOpen
return editPullState(ctx, cmd, gitea.EditPullRequestOption{State: &s}) return editPullState(ctx, gitea.EditPullRequestOption{State: &s})
}, },
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package pulls package pulls
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -12,7 +12,7 @@ import (
"code.gitea.io/tea/modules/interact" "code.gitea.io/tea/modules/interact"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdPullsReview starts an interactive review session // CmdPullsReview starts an interactive review session
@ -21,7 +21,7 @@ var CmdPullsReview = cli.Command{
Usage: "Interactively review a pull request", Usage: "Interactively review a pull request",
Description: "Interactively review a pull request", Description: "Interactively review a pull request",
ArgsUsage: "<pull index>", ArgsUsage: "<pull index>",
Action: func(_ stdctx.Context, cmd *cli.Command) error { Action: func(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,5 +1,6 @@
// Copyright 2018 The Gitea Authors. All rights reserved. // Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
@ -7,7 +8,7 @@ import (
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/cmd/releases" "code.gitea.io/tea/cmd/releases"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdReleases represents to login a gitea server. // CmdReleases represents to login a gitea server.
@ -20,12 +21,11 @@ var CmdReleases = cli.Command{
Description: "Manage releases", Description: "Manage releases",
ArgsUsage: " ", // command does not accept arguments ArgsUsage: " ", // command does not accept arguments
Action: releases.RunReleasesList, Action: releases.RunReleasesList,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&releases.CmdReleaseList, &releases.CmdReleaseList,
&releases.CmdReleaseCreate, &releases.CmdReleaseCreate,
&releases.CmdReleaseDelete, &releases.CmdReleaseDelete,
&releases.CmdReleaseEdit, &releases.CmdReleaseEdit,
&CmdReleaseAttachments,
}, },
Flags: flags.AllDefaultFlags, Flags: flags.AllDefaultFlags,
} }

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package releases package releases
import ( import (
stdctx "context"
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
@ -14,7 +14,7 @@ import (
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdReleaseCreate represents a sub command of Release to create release // CmdReleaseCreate represents a sub command of Release to create release
@ -44,11 +44,6 @@ var CmdReleaseCreate = cli.Command{
Aliases: []string{"n"}, Aliases: []string{"n"},
Usage: "Release notes", Usage: "Release notes",
}, },
&cli.StringFlag{
Name: "note-file",
Aliases: []string{"f"},
Usage: "Release notes file name. If set, --note is ignored.",
},
&cli.BoolFlag{ &cli.BoolFlag{
Name: "draft", Name: "draft",
Aliases: []string{"d"}, Aliases: []string{"d"},
@ -67,7 +62,7 @@ var CmdReleaseCreate = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runReleaseCreate(_ stdctx.Context, cmd *cli.Command) error { func runReleaseCreate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
@ -79,24 +74,15 @@ func runReleaseCreate(_ stdctx.Context, cmd *cli.Command) error {
tag = cmd.Args().First() tag = cmd.Args().First()
} }
notestring := ctx.String("note")
notefile := ctx.String("note-file")
if notefile != "" {
notebytes, err := os.ReadFile(notefile)
if err != nil {
return fmt.Errorf("unable to read the note file")
}
notestring = string(notebytes)
}
release, resp, err := ctx.Login.Client().CreateRelease(ctx.Owner, ctx.Repo, gitea.CreateReleaseOption{ release, resp, err := ctx.Login.Client().CreateRelease(ctx.Owner, ctx.Repo, gitea.CreateReleaseOption{
TagName: tag, TagName: tag,
Target: ctx.String("target"), Target: ctx.String("target"),
Title: ctx.String("title"), Title: ctx.String("title"),
Note: notestring, Note: ctx.String("note"),
IsDraft: ctx.Bool("draft"), IsDraft: ctx.Bool("draft"),
IsPrerelease: ctx.Bool("prerelease"), IsPrerelease: ctx.Bool("prerelease"),
}) })
if err != nil { if err != nil {
if resp != nil && resp.StatusCode == http.StatusConflict { if resp != nil && resp.StatusCode == http.StatusConflict {
return fmt.Errorf("There already is a release for this tag") return fmt.Errorf("There already is a release for this tag")

View File

@ -1,25 +1,25 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package releases package releases
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdReleaseDelete represents a sub command of Release to delete a release // CmdReleaseDelete represents a sub command of Release to delete a release
var CmdReleaseDelete = cli.Command{ var CmdReleaseDelete = cli.Command{
Name: "delete", Name: "delete",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
Usage: "Delete one or more releases", Usage: "Delete a release",
Description: `Delete one or more releases`, Description: `Delete a release`,
ArgsUsage: "<release tag> [<release tag>...]", ArgsUsage: "<release tag>",
Action: runReleaseDelete, Action: runReleaseDelete,
Flags: append([]cli.Flag{ Flags: append([]cli.Flag{
&cli.BoolFlag{ &cli.BoolFlag{
@ -34,13 +34,14 @@ var CmdReleaseDelete = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runReleaseDelete(_ stdctx.Context, cmd *cli.Command) error { func runReleaseDelete(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()
if !ctx.Args().Present() { tag := ctx.Args().First()
fmt.Println("Release tag needed to edit") if len(tag) == 0 {
fmt.Println("Release tag needed to delete")
return nil return nil
} }
@ -49,20 +50,18 @@ func runReleaseDelete(_ stdctx.Context, cmd *cli.Command) error {
return nil return nil
} }
for _, tag := range ctx.Args().Slice() { release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client) if err != nil {
if err != nil { return err
return err }
} _, err = client.DeleteRelease(ctx.Owner, ctx.Repo, release.ID)
_, err = client.DeleteRelease(ctx.Owner, ctx.Repo, release.ID) if err != nil {
if err != nil { return err
return err }
}
if ctx.Bool("delete-tag") { if ctx.Bool("delete-tag") {
_, err = client.DeleteTag(ctx.Owner, ctx.Repo, tag) _, err = client.DeleteTag(ctx.Owner, ctx.Repo, tag)
return err return err
}
} }
return nil return nil

View File

@ -1,5 +1,6 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package releases package releases
@ -7,21 +8,20 @@ import (
"fmt" "fmt"
"strings" "strings"
stdctx "context"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"github.com/urfave/cli/v3"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v2"
) )
// CmdReleaseEdit represents a sub command of Release to edit releases // CmdReleaseEdit represents a sub command of Release to edit releases
var CmdReleaseEdit = cli.Command{ var CmdReleaseEdit = cli.Command{
Name: "edit", Name: "edit",
Aliases: []string{"e"}, Aliases: []string{"e"},
Usage: "Edit one or more releases", Usage: "Edit a release",
Description: `Edit one or more releases`, Description: `Edit a release`,
ArgsUsage: "<release tag> [<release tag>...]", ArgsUsage: "<release tag>",
Action: runReleaseEdit, Action: runReleaseEdit,
Flags: append([]cli.Flag{ Flags: append([]cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
@ -57,11 +57,21 @@ var CmdReleaseEdit = cli.Command{
}, flags.AllDefaultFlags...), }, flags.AllDefaultFlags...),
} }
func runReleaseEdit(_ stdctx.Context, cmd *cli.Command) error { func runReleaseEdit(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()
tag := ctx.Args().First()
if len(tag) == 0 {
fmt.Println("Release tag needed to edit")
return nil
}
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
if err != nil {
return err
}
var isDraft, isPre *bool var isDraft, isPre *bool
if ctx.IsSet("draft") { if ctx.IsSet("draft") {
isDraft = gitea.OptionalBool(strings.ToLower(ctx.String("draft"))[:1] == "t") isDraft = gitea.OptionalBool(strings.ToLower(ctx.String("draft"))[:1] == "t")
@ -70,28 +80,13 @@ func runReleaseEdit(_ stdctx.Context, cmd *cli.Command) error {
isPre = gitea.OptionalBool(strings.ToLower(ctx.String("prerelease"))[:1] == "t") isPre = gitea.OptionalBool(strings.ToLower(ctx.String("prerelease"))[:1] == "t")
} }
if !ctx.Args().Present() { _, _, err = client.EditRelease(ctx.Owner, ctx.Repo, release.ID, gitea.EditReleaseOption{
fmt.Println("Release tag needed to edit") TagName: ctx.String("tag"),
return nil Target: ctx.String("target"),
} Title: ctx.String("title"),
Note: ctx.String("note"),
for _, tag := range ctx.Args().Slice() { IsDraft: isDraft,
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client) IsPrerelease: isPre,
if err != nil { })
return err return err
}
_, _, err = client.EditRelease(ctx.Owner, ctx.Repo, release.ID, gitea.EditReleaseOption{
TagName: ctx.String("tag"),
Target: ctx.String("target"),
Title: ctx.String("title"),
Note: ctx.String("note"),
IsDraft: isDraft,
IsPrerelease: isPre,
})
if err != nil {
return err
}
}
return nil
} }

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package releases package releases
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -12,7 +12,7 @@ import (
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdReleaseList represents a sub command of Release to list releases // CmdReleaseList represents a sub command of Release to list releases
@ -30,7 +30,7 @@ var CmdReleaseList = cli.Command{
} }
// RunReleasesList list releases // RunReleasesList list releases
func RunReleasesList(_ stdctx.Context, cmd *cli.Command) error { func RunReleasesList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,18 +1,17 @@
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/repos" "code.gitea.io/tea/cmd/repos"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdRepos represents to login a gitea server. // CmdRepos represents to login a gitea server.
@ -24,26 +23,24 @@ var CmdRepos = cli.Command{
Description: "Show repository details", Description: "Show repository details",
ArgsUsage: "[<repo owner>/<repo name>]", ArgsUsage: "[<repo owner>/<repo name>]",
Action: runRepos, Action: runRepos,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&repos.CmdReposList, &repos.CmdReposList,
&repos.CmdReposSearch, &repos.CmdReposSearch,
&repos.CmdRepoCreate, &repos.CmdRepoCreate,
&repos.CmdRepoCreateFromTemplate, &repos.CmdRepoCreateFromTemplate,
&repos.CmdRepoFork, &repos.CmdRepoFork,
&repos.CmdRepoMigrate,
&repos.CmdRepoRm,
}, },
Flags: repos.CmdReposListFlags, Flags: repos.CmdReposListFlags,
} }
func runRepos(ctx stdctx.Context, cmd *cli.Command) error { func runRepos(ctx *cli.Context) error {
if cmd.Args().Len() == 1 { if ctx.Args().Len() == 1 {
return runRepoDetail(ctx, cmd, cmd.Args().First()) return runRepoDetail(ctx, ctx.Args().First())
} }
return repos.RunReposList(ctx, cmd) return repos.RunReposList(ctx)
} }
func runRepoDetail(_ stdctx.Context, cmd *cli.Command, path string) error { func runRepoDetail(cmd *cli.Context, path string) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
client := ctx.Login.Client() client := ctx.Login.Client()
repoOwner, repoName := utils.GetOwnerAndRepo(path, ctx.Owner) repoOwner, repoName := utils.GetOwnerAndRepo(path, ctx.Owner)

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repos package repos
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -12,7 +12,7 @@ import (
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdRepoCreate represents a sub command of repos to create one // CmdRepoCreate represents a sub command of repos to create one
@ -91,7 +91,7 @@ var CmdRepoCreate = cli.Command{
}, flags.LoginOutputFlags...), }, flags.LoginOutputFlags...),
} }
func runRepoCreate(_ stdctx.Context, cmd *cli.Command) error { func runRepoCreate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
client := ctx.Login.Client() client := ctx.Login.Client()
var ( var (

View File

@ -1,19 +1,19 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repos package repos
import ( import (
"fmt" "fmt"
stdctx "context"
"code.gitea.io/sdk/gitea"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3"
"code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v2"
) )
// CmdRepoCreateFromTemplate represents a sub command of repos to generate one from a template repo // CmdRepoCreateFromTemplate represents a sub command of repos to generate one from a template repo
@ -82,7 +82,7 @@ var CmdRepoCreateFromTemplate = cli.Command{
}, flags.LoginOutputFlags...), }, flags.LoginOutputFlags...),
} }
func runRepoCreateFromTemplate(_ stdctx.Context, cmd *cli.Command) error { func runRepoCreateFromTemplate(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,86 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repos
import (
stdctx "context"
"fmt"
"code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context"
"github.com/AlecAivazis/survey/v2"
"github.com/urfave/cli/v3"
)
// CmdRepoRm represents a sub command of repos to delete an existing repo
var CmdRepoRm = cli.Command{
Name: "delete",
Aliases: []string{"rm"},
Usage: "Delete an existing repository",
Description: "Removes a repository from Create a repository from an existing repo",
ArgsUsage: " ", // command does not accept arguments
Action: runRepoDelete,
Flags: append([]cli.Flag{
&cli.StringFlag{
Name: "name",
Aliases: []string{""},
Required: true,
Usage: "name of the repo",
},
&cli.StringFlag{
Name: "owner",
Aliases: []string{"O"},
Required: false,
Usage: "owner of the repo",
},
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Required: false,
Value: false,
Usage: "Force the deletion and don't ask for confirmation",
},
}, flags.LoginOutputFlags...),
}
func runRepoDelete(_ stdctx.Context, cmd *cli.Command) error {
ctx := context.InitCommand(cmd)
client := ctx.Login.Client()
var owner string
if ctx.IsSet("owner") {
owner = ctx.String("owner")
} else {
owner = ctx.Login.User
}
repoName := ctx.String("name")
repoSlug := fmt.Sprintf("%s/%s", owner, repoName)
if !ctx.Bool("force") {
var enteredRepoSlug string
promptRepoName := &survey.Input{
Message: fmt.Sprintf("Confirm the deletion of the repository '%s' by typing its name: ", repoSlug),
}
if err := survey.AskOne(promptRepoName, &enteredRepoSlug, survey.WithValidator(survey.Required)); err != nil {
return err
}
if enteredRepoSlug != repoSlug {
return fmt.Errorf("Entered wrong repository name '%s', expected '%s'", enteredRepoSlug, repoSlug)
}
}
_, err := client.DeleteRepo(owner, repoName)
if err != nil {
return err
}
fmt.Printf("Successfully deleted %s/%s\n", owner, repoName)
return nil
}

View File

@ -1,5 +1,6 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repos package repos
@ -7,7 +8,7 @@ import (
"fmt" "fmt"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
var typeFilterFlag = cli.StringFlag{ var typeFilterFlag = cli.StringFlag{
@ -17,8 +18,8 @@ var typeFilterFlag = cli.StringFlag{
Usage: "Filter by type: fork, mirror, source", Usage: "Filter by type: fork, mirror, source",
} }
func getTypeFilter(cmd *cli.Command) (filter gitea.RepoType, err error) { func getTypeFilter(ctx *cli.Context) (filter gitea.RepoType, err error) {
t := cmd.String("type") t := ctx.String("type")
filter = gitea.RepoTypeNone filter = gitea.RepoTypeNone
switch t { switch t {
case "": case "":

View File

@ -1,10 +1,10 @@
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repos package repos
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
@ -12,7 +12,7 @@ import (
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdRepoFork represents a sub command of repos to fork an existing repo // CmdRepoFork represents a sub command of repos to fork an existing repo
@ -32,7 +32,7 @@ var CmdRepoFork = cli.Command{
}, flags.LoginRepoFlags...), }, flags.LoginRepoFlags...),
} }
func runRepoFork(_ stdctx.Context, cmd *cli.Command) error { func runRepoFork(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,17 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repos package repos
import ( import (
stdctx "context"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
var repoFieldsFlag = flags.FieldsFlag(print.RepoFields, []string{ var repoFieldsFlag = flags.FieldsFlag(print.RepoFields, []string{
@ -49,9 +48,9 @@ var CmdReposList = cli.Command{
} }
// RunReposList list repositories // RunReposList list repositories
func RunReposList(_ stdctx.Context, cmd *cli.Command) error { func RunReposList(cmd *cli.Context) error {
teaCmd := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
client := teaCmd.Login.Client() client := ctx.Login.Client()
typeFilter, err := getTypeFilter(cmd) typeFilter, err := getTypeFilter(cmd)
if err != nil { if err != nil {
@ -59,20 +58,20 @@ func RunReposList(_ stdctx.Context, cmd *cli.Command) error {
} }
var rps []*gitea.Repository var rps []*gitea.Repository
if teaCmd.Bool("starred") { if ctx.Bool("starred") {
user, _, err := client.GetMyUserInfo() user, _, err := client.GetMyUserInfo()
if err != nil { if err != nil {
return err return err
} }
rps, _, err = client.SearchRepos(gitea.SearchRepoOptions{ rps, _, err = client.SearchRepos(gitea.SearchRepoOptions{
ListOptions: teaCmd.GetListOptions(), ListOptions: ctx.GetListOptions(),
StarredByUserID: user.ID, StarredByUserID: user.ID,
}) })
} else if teaCmd.Bool("watched") { } else if ctx.Bool("watched") {
rps, _, err = client.GetMyWatchedRepos() // TODO: this does not expose pagination.. rps, _, err = client.GetMyWatchedRepos() // TODO: this does not expose pagination..
} else { } else {
rps, _, err = client.ListMyRepos(gitea.ListReposOptions{ rps, _, err = client.ListMyRepos(gitea.ListReposOptions{
ListOptions: teaCmd.GetListOptions(), ListOptions: ctx.GetListOptions(),
}) })
} }
@ -90,7 +89,7 @@ func RunReposList(_ stdctx.Context, cmd *cli.Command) error {
return err return err
} }
print.ReposList(reposFiltered, teaCmd.Output, fields) print.ReposList(reposFiltered, ctx.Output, fields)
return nil return nil
} }

View File

@ -1,173 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repos
import (
"fmt"
stdctx "context"
"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"
)
// CmdRepoMigrate represents a sub command of repos to migrate one
var CmdRepoMigrate = cli.Command{
Name: "migrate",
Aliases: []string{"m"},
Usage: "Migrate a repository",
Description: "Migrate a repository and or mirror it.",
ArgsUsage: " ", // command does not accept arguments
Action: runRepoMigrate,
Flags: append([]cli.Flag{
&cli.StringFlag{
Name: "name",
Usage: "Name of the repository",
Required: true,
},
&cli.StringFlag{
Name: "owner",
Usage: "Owner of the repository",
Required: true,
},
&cli.StringFlag{
Name: "clone-url",
Usage: "Clone URL of the repository",
Required: true,
},
&cli.StringFlag{
Name: "service",
Usage: string("Service to migrate from. Supported services are: " + gitea.GitServicePlain +
", " + gitea.GitServiceGitea + ", " + gitea.GitServiceGitlab + ", " + gitea.GitServiceGogs),
Required: true,
},
&cli.BoolFlag{
Name: "mirror",
Usage: "Mirror the repository",
},
&cli.BoolFlag{
Name: "private",
Usage: "Make the repository private",
},
&cli.BoolFlag{
Name: "template",
Usage: "Make the repository a template",
},
&cli.BoolFlag{
Name: "wiki",
Usage: "Copy the wiki",
},
&cli.BoolFlag{
Name: "issues",
Usage: "Copy the issues",
},
&cli.BoolFlag{
Name: "labels",
Usage: "Copy the lables",
},
&cli.BoolFlag{
Name: "pull-requests",
Usage: "Copy the pull requests",
},
&cli.BoolFlag{
Name: "releases",
Usage: "Copy the releases",
},
&cli.BoolFlag{
Name: "milestones",
Usage: "Copy the milestones",
},
&cli.StringFlag{
Name: "mirror-interval",
Usage: "Interval to mirror the repository.",
},
&cli.BoolFlag{
Name: "lfs",
Usage: "Copy the LFS objects",
},
&cli.StringFlag{
Name: "lfs-endpoint",
Usage: "LFS endpoint to use",
},
&cli.StringFlag{
Name: "auth-user",
Usage: "Username to use for authentication.",
},
&cli.StringFlag{
Name: "auth-password",
Usage: "Password to use for authentication.",
},
&cli.StringFlag{
Name: "auth-token",
Usage: "Token to use for authentication.",
},
}, flags.LoginOutputFlags...),
}
func runRepoMigrate(_ stdctx.Context, cmd *cli.Command) error {
ctx := context.InitCommand(cmd)
client := ctx.Login.Client()
var (
repo *gitea.Repository
err error
service gitea.GitServiceType
)
if ctx.IsSet("service") {
switch ctx.String("service") {
case "git":
service = gitea.GitServicePlain
case "gitea":
service = gitea.GitServiceGitea
case "gitlab":
service = gitea.GitServiceGitlab
case "gogs":
service = gitea.GitServiceGogs
case "github":
service = gitea.GitServiceGithub
default:
return fmt.Errorf("unknown git service type '%s'", ctx.String("service"))
}
}
opts := gitea.MigrateRepoOption{
RepoName: ctx.String("name"),
RepoOwner: ctx.String("owner"),
CloneAddr: ctx.String("clone-url"),
Service: service,
AuthUsername: ctx.String("auth-user"),
AuthPassword: ctx.String("auth-password"),
AuthToken: ctx.String("auth-token"),
Mirror: ctx.Bool("mirror"),
Private: ctx.Bool("private"),
Description: ctx.String("description"),
Wiki: ctx.Bool("wiki"),
Milestones: ctx.Bool("milestones"),
Labels: ctx.Bool("labels"),
Issues: ctx.Bool("issues"),
PullRequests: ctx.Bool("pull-requests"),
Releases: ctx.Bool("releases"),
MirrorInterval: ctx.String("mirror-interval"),
LFS: ctx.Bool("lfs"),
LFSEndpoint: ctx.String("lfs-endpoint"),
}
repo, _, err = client.MigrateRepo(opts)
if err != nil {
return err
}
topics, _, err := client.ListRepoTopics(repo.Owner.UserName, repo.Name, gitea.ListRepoTopicsOptions{})
if err != nil {
return err
}
print.RepoDetails(repo, topics)
fmt.Printf("%s\n", repo.HTMLURL)
return nil
}

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repos package repos
import ( import (
stdctx "context"
"fmt" "fmt"
"strings" "strings"
@ -13,7 +13,7 @@ import (
"code.gitea.io/tea/modules/print" "code.gitea.io/tea/modules/print"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdReposSearch represents a sub command of repos to find them // CmdReposSearch represents a sub command of repos to find them
@ -56,14 +56,14 @@ var CmdReposSearch = cli.Command{
}, flags.LoginOutputFlags...), }, flags.LoginOutputFlags...),
} }
func runReposSearch(_ stdctx.Context, cmd *cli.Command) error { func runReposSearch(cmd *cli.Context) error {
teaCmd := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
client := teaCmd.Login.Client() client := ctx.Login.Client()
var ownerID int64 var ownerID int64
if teaCmd.IsSet("owner") { if ctx.IsSet("owner") {
// test if owner is a organisation // test if owner is a organisation
org, _, err := client.GetOrg(teaCmd.String("owner")) org, _, err := client.GetOrg(ctx.String("owner"))
if err != nil { if err != nil {
// HACK: the client does not return a response on 404, so we can't check res.StatusCode // HACK: the client does not return a response on 404, so we can't check res.StatusCode
if err.Error() != "404 Not Found" { if err.Error() != "404 Not Found" {
@ -71,7 +71,7 @@ func runReposSearch(_ stdctx.Context, cmd *cli.Command) error {
} }
// if owner is no org, its a user // if owner is no org, its a user
user, _, err := client.GetUserInfo(teaCmd.String("owner")) user, _, err := client.GetUserInfo(ctx.String("owner"))
if err != nil { if err != nil {
return err return err
} }
@ -82,14 +82,14 @@ func runReposSearch(_ stdctx.Context, cmd *cli.Command) error {
} }
var isArchived *bool var isArchived *bool
if teaCmd.IsSet("archived") { if ctx.IsSet("archived") {
archived := strings.ToLower(teaCmd.String("archived"))[:1] == "t" archived := strings.ToLower(ctx.String("archived"))[:1] == "t"
isArchived = &archived isArchived = &archived
} }
var isPrivate *bool var isPrivate *bool
if teaCmd.IsSet("private") { if ctx.IsSet("private") {
private := strings.ToLower(teaCmd.String("private"))[:1] == "t" private := strings.ToLower(ctx.String("private"))[:1] == "t"
isPrivate = &private isPrivate = &private
} }
@ -99,8 +99,8 @@ func runReposSearch(_ stdctx.Context, cmd *cli.Command) error {
} }
var keyword string var keyword string
if teaCmd.Args().Present() { if ctx.Args().Present() {
keyword = strings.Join(teaCmd.Args().Slice(), " ") keyword = strings.Join(ctx.Args().Slice(), " ")
} }
user, _, err := client.GetMyUserInfo() user, _, err := client.GetMyUserInfo()
@ -109,14 +109,14 @@ func runReposSearch(_ stdctx.Context, cmd *cli.Command) error {
} }
rps, _, err := client.SearchRepos(gitea.SearchRepoOptions{ rps, _, err := client.SearchRepos(gitea.SearchRepoOptions{
ListOptions: teaCmd.GetListOptions(), ListOptions: ctx.GetListOptions(),
OwnerID: ownerID, OwnerID: ownerID,
IsPrivate: isPrivate, IsPrivate: isPrivate,
IsArchived: isArchived, IsArchived: isArchived,
Type: mode, Type: mode,
Keyword: keyword, Keyword: keyword,
KeywordInDescription: true, KeywordInDescription: true,
KeywordIsTopic: teaCmd.Bool("topic"), KeywordIsTopic: ctx.Bool("topic"),
PrioritizedByOwnerID: user.ID, PrioritizedByOwnerID: user.ID,
}) })
if err != nil { if err != nil {
@ -127,6 +127,6 @@ func runReposSearch(_ stdctx.Context, cmd *cli.Command) error {
if err != nil { if err != nil {
return err return err
} }
print.ReposList(rps, teaCmd.Output, fields) print.ReposList(rps, ctx.Output, fields)
return nil return nil
} }

View File

@ -1,11 +1,12 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd package cmd
import ( import (
"code.gitea.io/tea/cmd/times" "code.gitea.io/tea/cmd/times"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdTrackedTimes represents the command to operate repositories' times. // CmdTrackedTimes represents the command to operate repositories' times.
@ -19,7 +20,7 @@ var CmdTrackedTimes = cli.Command{
times might be listed.`, times might be listed.`,
ArgsUsage: "[username | #issue]", ArgsUsage: "[username | #issue]",
Action: times.RunTimesList, Action: times.RunTimesList,
Commands: []*cli.Command{ Subcommands: []*cli.Command{
&times.CmdTrackedTimesAdd, &times.CmdTrackedTimesAdd,
&times.CmdTrackedTimesDelete, &times.CmdTrackedTimesDelete,
&times.CmdTrackedTimesReset, &times.CmdTrackedTimesReset,

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package times package times
import ( import (
stdctx "context"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -14,7 +14,7 @@ import (
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdTrackedTimesAdd represents a sub command of times to add time to an issue // CmdTrackedTimesAdd represents a sub command of times to add time to an issue
@ -31,7 +31,7 @@ var CmdTrackedTimesAdd = cli.Command{
Flags: flags.LoginRepoFlags, Flags: flags.LoginRepoFlags,
} }
func runTrackedTimesAdd(_ stdctx.Context, cmd *cli.Command) error { func runTrackedTimesAdd(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package times package times
import ( import (
stdctx "context"
"fmt" "fmt"
"strconv" "strconv"
@ -12,7 +12,7 @@ import (
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdTrackedTimesDelete is a sub command of CmdTrackedTimes, and removes time from an issue // CmdTrackedTimesDelete is a sub command of CmdTrackedTimes, and removes time from an issue
@ -25,7 +25,7 @@ var CmdTrackedTimesDelete = cli.Command{
Flags: flags.LoginRepoFlags, Flags: flags.LoginRepoFlags,
} }
func runTrackedTimesDelete(_ stdctx.Context, cmd *cli.Command) error { func runTrackedTimesDelete(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,10 +1,10 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package times package times
import ( import (
stdctx "context"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -16,7 +16,7 @@ import (
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/araddon/dateparse" "github.com/araddon/dateparse"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// NOTE: not using NewCsvFlag, as we don't want an alias & default value. // NOTE: not using NewCsvFlag, as we don't want an alias & default value.
@ -69,7 +69,7 @@ Depending on your permissions on the repository, only your own tracked times mig
} }
// RunTimesList list repositories // RunTimesList list repositories
func RunTimesList(_ stdctx.Context, cmd *cli.Command) error { func RunTimesList(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()

View File

@ -1,17 +1,17 @@
// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package times package times
import ( import (
stdctx "context"
"fmt" "fmt"
"code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/cmd/flags"
"code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/context"
"code.gitea.io/tea/modules/utils" "code.gitea.io/tea/modules/utils"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v2"
) )
// CmdTrackedTimesReset is a subcommand of CmdTrackedTimes, and // CmdTrackedTimesReset is a subcommand of CmdTrackedTimes, and
@ -24,7 +24,7 @@ var CmdTrackedTimesReset = cli.Command{
Flags: flags.LoginRepoFlags, Flags: flags.LoginRepoFlags,
} }
func runTrackedTimesReset(_ stdctx.Context, cmd *cli.Command) error { func runTrackedTimesReset(cmd *cli.Context) error {
ctx := context.InitCommand(cmd) ctx := context.InitCommand(cmd)
ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
client := ctx.Login.Client() client := ctx.Login.Client()

Some files were not shown because too many files have changed in this diff Show More