You've already forked go-semantic-release
Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 80af337f3a | |||
| 8a8e746159 | |||
| ff1798b10b | |||
| fa40e6ee71 | |||
| 8a05b72ec8 | |||
| 732b1ee1a0 | |||
| 5636fecc14 | |||
| b13699d2f8 | |||
| f7f395c30f | |||
| 0bcede8594 | |||
| 34589749ba | |||
| b38abd00f2 | |||
| 913783cf08 | |||
| d701ce2352 | |||
| 4d0d1e4319 | |||
| c4cecdebb4 | |||
| ad8d69452d | |||
| 7f8ed11f79 | |||
| 6d1f8f0a9a | |||
| 3a93293318 | |||
| 1712dbdbaf | |||
| a442a82d15 | |||
| 70b6cbe8df | |||
| c981a99424 | |||
| a2b32024a1 | |||
| 8f5e47eecd | |||
| 274cabf05a | |||
| 77fb819342 | |||
| 0b309228d3 | |||
| 141f297c87 | |||
| 2236fe923c | |||
|
|
ade0e49736 | ||
|
|
ca6488ee78 | ||
|
|
979a378abd | ||
|
|
2c8d2d9ade | ||
|
|
8acb8b74b8 | ||
|
|
fd1063132f | ||
|
|
1d0c93b678 | ||
|
|
0c7338ab13 | ||
|
|
03f2eeadaa | ||
|
|
bcb21d917d | ||
|
|
ea2fbfba3d | ||
|
|
c5f993e7de | ||
|
|
ec8dc17df2 | ||
|
|
9e40e81fea | ||
|
|
2782fb5d03 | ||
|
|
0800219d60 | ||
|
|
f89150b698 | ||
|
|
780a6dbc2e | ||
|
|
2d7977993b | ||
|
|
9d7edbf756 | ||
|
|
d9e2f36927 | ||
|
|
a6783f23bd | ||
|
|
fbb3684f68 | ||
|
|
9bc3143f53 | ||
|
|
7b93801e88 | ||
|
|
749bbf720b | ||
|
|
d9e5dc4515 | ||
|
|
d66364e474 | ||
|
|
2fc6145149 | ||
|
|
a054cf9a60 | ||
|
|
155a16ddd5 | ||
|
|
d7878222bb | ||
|
|
f79466b238 | ||
|
|
5225b12c00 | ||
|
|
2cd24777b3 | ||
|
|
cb3084d0b7 | ||
|
|
795f5d54ef | ||
|
|
382cb54bcb | ||
|
|
3bc68d9794 | ||
|
|
c7d6c7cc7b |
@@ -1,2 +1,10 @@
|
|||||||
*
|
*
|
||||||
!build/
|
!build/
|
||||||
|
!cmd/
|
||||||
|
!internal/
|
||||||
|
!pkg/
|
||||||
|
!scripts/
|
||||||
|
!Dockerfile*
|
||||||
|
!.dockerignore
|
||||||
|
!go.mod
|
||||||
|
!go.sum
|
||||||
11
.githooks/commit-msg
Executable file
11
.githooks/commit-msg
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Run the script and get the return code if successful of if fails
|
||||||
|
./scripts/commit-filter-check.sh && rc=$? || rc=$?
|
||||||
|
echo return code : $rc
|
||||||
|
if [ ${rc} = 1 ]; then
|
||||||
|
echo "Script return code 1 so commit failed"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "No error returned so commit successful"
|
||||||
|
fi
|
||||||
70
.github/workflows/codeql-analysis.yml
vendored
Normal file
70
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ master ]
|
||||||
|
schedule:
|
||||||
|
- cron: '21 16 * * 5'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'go' ]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||||
|
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v2
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
||||||
24
.github/workflows/main.yml
vendored
24
.github/workflows/main.yml
vendored
@@ -8,7 +8,9 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go: ["1.13", "1.14", "1.15"]
|
go: ["1.18", "1.19"]
|
||||||
|
env:
|
||||||
|
DEFAULT_GO: "1.19"
|
||||||
name: Build with go version ${{ matrix.go }}
|
name: Build with go version ${{ matrix.go }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -22,9 +24,9 @@ jobs:
|
|||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v2
|
uses: golangci/golangci-lint-action@v3
|
||||||
with:
|
with:
|
||||||
version: v1.29
|
version: latest
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: go test ./...
|
run: go test ./...
|
||||||
@@ -39,8 +41,12 @@ jobs:
|
|||||||
GOOS=windows GOARCH=386 CGO_ENABLED=0 go build -o build/go-semantic-release.windows_i386.exe -ldflags "-w -s -X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
GOOS=windows GOARCH=386 CGO_ENABLED=0 go build -o build/go-semantic-release.windows_i386.exe -ldflags "-w -s -X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
||||||
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o build/go-semantic-release.windows_x86_64.exe -ldflags "-w -s -X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o build/go-semantic-release.windows_x86_64.exe -ldflags "-w -s -X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
||||||
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -o build/go-semantic-release.darwin_x86_64 -ldflags "-w -s -X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -o build/go-semantic-release.darwin_x86_64 -ldflags "-w -s -X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
||||||
- name: Build Docker image
|
- name: Build Docker image PR
|
||||||
if: matrix.go == '1.15' && github.repository == 'Nightapes/go-semantic-release'
|
if: github.ref != 'refs/heads/master'
|
||||||
|
run: |
|
||||||
|
docker build -t nightapes/go-semantic-release:development-${{matrix.go}} .
|
||||||
|
- name: Build Docker image master
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
run: |
|
run: |
|
||||||
docker login -u nightapes -p ${{ secrets.DOCKER_PASSWORD }}
|
docker login -u nightapes -p ${{ secrets.DOCKER_PASSWORD }}
|
||||||
docker login -u nightapes -p ${{ secrets.GITHUB_TOKEN }} docker.pkg.github.com
|
docker login -u nightapes -p ${{ secrets.GITHUB_TOKEN }} docker.pkg.github.com
|
||||||
@@ -49,7 +55,7 @@ jobs:
|
|||||||
docker tag nightapes/go-semantic-release:development-${{matrix.go}} docker.pkg.github.com/nightapes/go-semantic-release/go-semantic-release:development-${{matrix.go}}
|
docker tag nightapes/go-semantic-release:development-${{matrix.go}} docker.pkg.github.com/nightapes/go-semantic-release/go-semantic-release:development-${{matrix.go}}
|
||||||
docker push docker.pkg.github.com/nightapes/go-semantic-release/go-semantic-release:development-${{matrix.go}}
|
docker push docker.pkg.github.com/nightapes/go-semantic-release/go-semantic-release:development-${{matrix.go}}
|
||||||
- uses: actions/upload-artifact@v1
|
- uses: actions/upload-artifact@v1
|
||||||
if: matrix.go == '1.15'
|
if: matrix.go == env.DEFAULT_GO
|
||||||
with:
|
with:
|
||||||
name: build
|
name: build
|
||||||
path: build
|
path: build
|
||||||
@@ -65,7 +71,7 @@ jobs:
|
|||||||
name: build
|
name: build
|
||||||
path: build
|
path: build
|
||||||
- name: Release
|
- name: Release
|
||||||
if: github.repository == 'Nightapes/go-semantic-release'
|
if: github.ref == 'refs/heads/master'
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
@@ -73,8 +79,8 @@ jobs:
|
|||||||
docker login -u nightapes -p ${{ secrets.DOCKER_PASSWORD }}
|
docker login -u nightapes -p ${{ secrets.DOCKER_PASSWORD }}
|
||||||
docker login -u nightapes -p $GITHUB_TOKEN docker.pkg.github.com
|
docker login -u nightapes -p $GITHUB_TOKEN docker.pkg.github.com
|
||||||
./build/go-semantic-release-temp release --loglevel trace
|
./build/go-semantic-release-temp release --loglevel trace
|
||||||
- name: Release fork
|
- name: Release PR
|
||||||
if: github.repository != 'Nightapes/go-semantic-release'
|
if: github.ref != 'refs/heads/master'
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
33
.release.yml
33
.release.yml
@@ -1,30 +1,29 @@
|
|||||||
release: "github"
|
release: "gitea"
|
||||||
github:
|
gitea:
|
||||||
repo: "go-semantic-release"
|
repo: "go-semantic-release"
|
||||||
user: "nightapes"
|
user: "cybercinch"
|
||||||
|
url: "https://hub.cybercinch.nz"
|
||||||
commitFormat: angular
|
commitFormat: angular
|
||||||
branch:
|
branch:
|
||||||
master: release
|
master: release
|
||||||
beta: beta
|
develop: beta
|
||||||
assets:
|
assets:
|
||||||
- name: ./build/go-semantic-release.linux_x86_64
|
- path: ./build/go-semantic-release.linux_amd64
|
||||||
compress: true
|
compress: true
|
||||||
- name: ./build/go-semantic-release.windows_i386.exe
|
- path: ./build/go-semantic-release.linux_arm64
|
||||||
compress: true
|
compress: true
|
||||||
- name: ./build/go-semantic-release.windows_x86_64.exe
|
- path: ./build/go-semantic-release.windows_i386.exe
|
||||||
compress: true
|
compress: true
|
||||||
- name: ./build/go-semantic-release.darwin_x86_64
|
- path: ./build/go-semantic-release.windows_amd64.exe
|
||||||
|
compress: true
|
||||||
|
- path: ./build/go-semantic-release.darwin_amd64
|
||||||
compress: true
|
compress: true
|
||||||
changelog:
|
changelog:
|
||||||
docker:
|
docker:
|
||||||
latest: true
|
latest: true
|
||||||
repository: "nightapes/go-semantic-release"
|
repository: hub.cybercinch.nz/cybercinch/go-semantic-release
|
||||||
|
showAuthors: true
|
||||||
|
|
||||||
hooks:
|
hooks:
|
||||||
preRelease:
|
preRelease: []
|
||||||
- docker build -t nightapes/go-semantic-release:latest .
|
postRelease: []
|
||||||
- docker tag nightapes/go-semantic-release:latest docker.pkg.github.com/nightapes/go-semantic-release/go-semantic-release:$RELEASE_VERSION
|
|
||||||
- docker tag nightapes/go-semantic-release:latest nightapes/go-semantic-release:$RELEASE_VERSION
|
|
||||||
postRelease:
|
|
||||||
- docker push nightapes/go-semantic-release:latest
|
|
||||||
- docker push nightapes/go-semantic-release:$RELEASE_VERSION
|
|
||||||
- docker push docker.pkg.github.com/nightapes/go-semantic-release/go-semantic-release:$RELEASE_VERSION
|
|
||||||
|
|||||||
112
.woodpecker.yml
Normal file
112
.woodpecker.yml
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
variables:
|
||||||
|
- &platforms 'linux/arm64,linux/amd64'
|
||||||
|
- &docker_creds
|
||||||
|
username:
|
||||||
|
from_secret: hub_username_cybercinch
|
||||||
|
password:
|
||||||
|
from_secret: docker_password_cybercinch
|
||||||
|
- &pypi_creds
|
||||||
|
username:
|
||||||
|
from_secret: hub_username_cybercinch
|
||||||
|
password:
|
||||||
|
from_secret: docker_password_cybercinch
|
||||||
|
- build_args: &build_args
|
||||||
|
- TAG: ${CI_COMMIT_TAG}
|
||||||
|
clone:
|
||||||
|
git:
|
||||||
|
image: woodpeckerci/plugin-git
|
||||||
|
settings:
|
||||||
|
partial: false
|
||||||
|
tags: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
build-release:
|
||||||
|
image: docker.io/cybercinch/go-semrelease:golang1.20
|
||||||
|
pull: true
|
||||||
|
commands:
|
||||||
|
- >
|
||||||
|
GOOS=linux
|
||||||
|
GOARCH=amd64
|
||||||
|
CGO_ENABLED=0
|
||||||
|
GOFLAGS=-mod=vendor
|
||||||
|
go build -o build/go-semantic-release.linux_amd64 -ldflags "-w -s --X main.version=`go-semantic-release next`"
|
||||||
|
./cmd/go-semantic-release/
|
||||||
|
- >
|
||||||
|
GOOS=linux
|
||||||
|
GOARCH=arm64
|
||||||
|
CGO_ENABLED=0
|
||||||
|
GOFLAGS=-mod=vendor
|
||||||
|
go build -o build/go-semantic-release.linux_arm64 -ldflags "-w -s --X main.version=`go-semantic-release next`"
|
||||||
|
./cmd/go-semantic-release/
|
||||||
|
- >
|
||||||
|
GOOS=windows
|
||||||
|
GOARCH=386
|
||||||
|
CGO_ENABLED=0
|
||||||
|
GOFLAGS=-mod=vendor
|
||||||
|
go build -o build/go-semantic-release.windows_i386.exe -ldflags "-w -s -X main.version=`go-semantic-release next`"
|
||||||
|
./cmd/go-semantic-release/
|
||||||
|
- >
|
||||||
|
GOOS=windows
|
||||||
|
GOARCH=amd64
|
||||||
|
CGO_ENABLED=0
|
||||||
|
GOFLAGS=-mod=vendor
|
||||||
|
go build -o build/go-semantic-release.windows_amd64.exe -ldflags "-w -s -X main.version=`go-semantic-release next`"
|
||||||
|
./cmd/go-semantic-release/
|
||||||
|
- >
|
||||||
|
GOOS=darwin
|
||||||
|
GOARCH=amd64
|
||||||
|
CGO_ENABLED=0
|
||||||
|
GOFLAGS=-mod=vendor
|
||||||
|
go build -o build/go-semantic-release.darwin_amd64 -ldflags "-w -s -X main.version=`go-semantic-release next`"
|
||||||
|
./cmd/go-semantic-release/
|
||||||
|
- go-semantic-release --loglevel debug release # Actually make the release on Gitea. Uploading assets
|
||||||
|
environment:
|
||||||
|
GITEA_TOKEN:
|
||||||
|
from_secret: gitea_token
|
||||||
|
GITEA_URL:
|
||||||
|
from_secret: gitea_server_url
|
||||||
|
when:
|
||||||
|
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- manual
|
||||||
|
|
||||||
|
publish-docker-tagged:
|
||||||
|
image: woodpeckerci/plugin-docker-buildx
|
||||||
|
pull: true
|
||||||
|
settings:
|
||||||
|
<<: *docker_creds
|
||||||
|
registry: hub.cybercinch.nz
|
||||||
|
repo: hub.cybercinch.nz/cybercinch/${CI_REPO_NAME}
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
platforms: *platforms
|
||||||
|
build_args:
|
||||||
|
- TAG=${CI_COMMIT_TAG}
|
||||||
|
tags:
|
||||||
|
- latest
|
||||||
|
- ${CI_COMMIT_TAG}
|
||||||
|
when:
|
||||||
|
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
|
||||||
|
publish-docker-develop:
|
||||||
|
image: docker.io/cybercinch/woodpecker-plugin-depot
|
||||||
|
pull: true
|
||||||
|
settings:
|
||||||
|
<<: *docker_creds
|
||||||
|
token:
|
||||||
|
from_secret: depot_token
|
||||||
|
repohost: hub.cybercinch.nz
|
||||||
|
repo: cybercinch/${CI_REPO_NAME}
|
||||||
|
project:
|
||||||
|
from_secret: depot_project
|
||||||
|
dockerfile: Dockerfile.dev
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64
|
||||||
|
tags: ["develop"]
|
||||||
|
when:
|
||||||
|
branch: develop
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- manual
|
||||||
18
Dockerfile
18
Dockerfile
@@ -1,9 +1,21 @@
|
|||||||
FROM alpine:3.10.2
|
FROM alpine:3.14
|
||||||
|
ARG TARGETPLATFORM
|
||||||
|
# Set by build-arg
|
||||||
|
ARG TAG=v2.2.3
|
||||||
|
|
||||||
|
# Strip out the prefix
|
||||||
|
ENV PLAT=${TARGETPLATFORM//"linux/"/}
|
||||||
|
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
|
|
||||||
COPY ./build/go-semantic-release.linux_x86_64 .
|
ADD https://hub.cybercinch.nz/cybercinch/go-semantic-release/releases/download/${TAG}/go-semantic-release.linux_${PLAT}.zip /tmp
|
||||||
|
RUN apk add --no-cache unzip && \
|
||||||
|
unzip -d /tmp /tmp/go-semantic-release.linux_${PLAT}.zip && \
|
||||||
|
ls && \
|
||||||
|
ls /tmp && \
|
||||||
|
mv /tmp/go-semantic-release.linux_${PLAT} /usr/local/bin/go-semantic-release && \
|
||||||
|
rm -f /tmp/go-semantic-release.linux_${PLAT}.zip
|
||||||
|
|
||||||
USER 1000
|
USER 1000
|
||||||
|
|
||||||
ENTRYPOINT [ "./go-semantic-release.linux_x86_64" ]
|
ENTRYPOINT [ "go-semantic-release" ]
|
||||||
|
|||||||
23
Dockerfile.dev
Normal file
23
Dockerfile.dev
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
FROM golang:1.20 as build
|
||||||
|
|
||||||
|
WORKDIR /code
|
||||||
|
|
||||||
|
# Copy code into build container
|
||||||
|
COPY . /code/
|
||||||
|
|
||||||
|
RUN GOOS=linux \
|
||||||
|
GOARCH=amd64 \
|
||||||
|
CGO_ENABLED=0 \
|
||||||
|
go build -o build/go-semantic-release.linux_x86_64 -ldflags "-w -s --X main.version=`go-semantic-release next`" \
|
||||||
|
./cmd/go-semantic-release/
|
||||||
|
|
||||||
|
|
||||||
|
FROM alpine:3.14
|
||||||
|
|
||||||
|
WORKDIR /code
|
||||||
|
|
||||||
|
COPY --from=build /code/build/go-semantic-release.linux_x86_64 /usr/local/bin/go-semantic-release
|
||||||
|
|
||||||
|
USER 1000
|
||||||
|
|
||||||
|
ENTRYPOINT [ "go-semantic-release" ]
|
||||||
14
Makefile
Normal file
14
Makefile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
GOFLAGS=-mod=vendor go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/
|
||||||
|
|
||||||
|
lint:
|
||||||
|
golangci-lint run --print-issued-lines=false --fix ./...
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test --coverprofile coverage.out -v -parallel 20 ./...
|
||||||
77
README.md
77
README.md
@@ -9,7 +9,8 @@
|
|||||||
| `github` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: |
|
| `github` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: |
|
||||||
| `gitlab` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: |
|
| `gitlab` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: |
|
||||||
| `git` | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | |
|
| `git` | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | |
|
||||||
| `bitbucket` | Comming soon | :white_check_mark: | | | :white_check_mark: | |
|
| `bitbucket` | Comming soon | :white_check_mark: | | | :white_check_mark: | |
|
||||||
|
| `gitea` | Coming soon | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
|
|
||||||
|
|
||||||
## Supported CI Pipelines
|
## Supported CI Pipelines
|
||||||
@@ -56,6 +57,9 @@ hooks:
|
|||||||
- name: echo $RELEASE_VERSION
|
- name: echo $RELEASE_VERSION
|
||||||
postRelease:
|
postRelease:
|
||||||
- name: echo $RELEASE_VERSION
|
- name: echo $RELEASE_VERSION
|
||||||
|
integrations:
|
||||||
|
npm:
|
||||||
|
enabled: true
|
||||||
```
|
```
|
||||||
|
|
||||||
#### CommitFormat
|
#### CommitFormat
|
||||||
@@ -94,7 +98,7 @@ branch:
|
|||||||
|
|
||||||
#### Release
|
#### Release
|
||||||
|
|
||||||
At the moment we support releases to gitlab and github.
|
At the moment we support releases to gitlab, github and gitea.
|
||||||
|
|
||||||
##### Github
|
##### Github
|
||||||
|
|
||||||
@@ -125,6 +129,8 @@ gitlab:
|
|||||||
tagPrefix: ""
|
tagPrefix: ""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can find an example `.gitlab-ci.yml` in the [examples](examples/.gitlab-ci.yml) folder.
|
||||||
|
|
||||||
##### Git only
|
##### Git only
|
||||||
|
|
||||||
Only via https at the moment. You need write access to your git repository
|
Only via https at the moment. You need write access to your git repository
|
||||||
@@ -139,6 +145,20 @@ git:
|
|||||||
## Optional, if you want to change the default tag prefix ("v")
|
## Optional, if you want to change the default tag prefix ("v")
|
||||||
tagPrefix: ""
|
tagPrefix: ""
|
||||||
```
|
```
|
||||||
|
##### Gitea
|
||||||
|
|
||||||
|
You need to set the env `GITEA_TOKEN` with an access token.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
release: 'gitea'
|
||||||
|
gitea:
|
||||||
|
user: "<user/group"
|
||||||
|
repo: "<repositoryname>"
|
||||||
|
## URL of your Gitea instance
|
||||||
|
Url: <https://your.github>
|
||||||
|
## Optional, if you want to change the default tag prefix ("v")
|
||||||
|
tagPrefix: ""
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Assets
|
#### Assets
|
||||||
@@ -157,6 +177,26 @@ assets:
|
|||||||
#### Hooks
|
#### Hooks
|
||||||
|
|
||||||
Hooks will run when calling `release`. Hooks run only if a release will be triggered.
|
Hooks will run when calling `release`. Hooks run only if a release will be triggered.
|
||||||
|
You can define hooks which run before or after the release. The shell commands will run in order, you can access the current release version via
|
||||||
|
an environment variable `RELEASE_VERSION`
|
||||||
|
|
||||||
|
```yml
|
||||||
|
hooks:
|
||||||
|
preRelease:
|
||||||
|
- name: echo $RELEASE_VERSION
|
||||||
|
postRelease:
|
||||||
|
- name: echo $RELEASE_VERSION
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Integrations
|
||||||
|
|
||||||
|
Integrations are simple helpers to make integration with existing tools easier.
|
||||||
|
At the moment npm is supported, the integration will set the version before release to the `package.json`
|
||||||
|
```yml
|
||||||
|
integrations:
|
||||||
|
npm:
|
||||||
|
enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
#### Changelog
|
#### Changelog
|
||||||
|
|
||||||
@@ -218,6 +258,9 @@ changelog:
|
|||||||
printAll: false ## Print all valid commits to changelog
|
printAll: false ## Print all valid commits to changelog
|
||||||
title: "v{{.Version}} ({{.Now.Format "2006-01-02"}})" ## Used for releases (go template)
|
title: "v{{.Version}} ({{.Now.Format "2006-01-02"}})" ## Used for releases (go template)
|
||||||
templatePath: "./examples/changelog.tmpl" ## Path to a template file (go template)
|
templatePath: "./examples/changelog.tmpl" ## Path to a template file (go template)
|
||||||
|
showAuthors: false ## Show authors in changelog
|
||||||
|
showBodyAsHeader: false ## Show all bodies of the commits as header of changelog (useful for squash commit flow to show long text in release)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Docker
|
##### Docker
|
||||||
@@ -231,6 +274,18 @@ changelog:
|
|||||||
repository: ## Your docker repository, which is used for docker run
|
repository: ## Your docker repository, which is used for docker run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### NPM
|
||||||
|
|
||||||
|
You can print a help text for a npm package
|
||||||
|
|
||||||
|
```yml
|
||||||
|
changelog:
|
||||||
|
npm:
|
||||||
|
name: ## Name of the npm package
|
||||||
|
repository: ## Your docker repository, which is used for docker run
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Version
|
### Version
|
||||||
|
|
||||||
`go-semantic-release` has two modes for calculating the version: automatic or manual.
|
`go-semantic-release` has two modes for calculating the version: automatic or manual.
|
||||||
@@ -268,6 +323,24 @@ go build -ldflags "--X main.version=`./go-semantic-release next`"
|
|||||||
./go-semantic-release release
|
./go-semantic-release release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Write changelog to file
|
||||||
|
|
||||||
|
This will write all changes beginning from the last git tag til HEAD to a changelog file.
|
||||||
|
Default changelog file name if nothing is given via `--file`: `CHANGELOG.md`.
|
||||||
|
Note that per default the new changelog will be prepended to the existing file.
|
||||||
|
With `--max-file-size` a maximum sizes of the changelog file in megabytes can be specified.
|
||||||
|
If the size exceeds the limit, the current changelog file will be moved to a new file called `<filename>-<1-n>.<file extension>`. The new changelog will be written to the `<filename>`.
|
||||||
|
The default maximum file size limit is `10 megabytes`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./go-semantic-release changelog --max-file-size 10
|
||||||
|
```
|
||||||
|
|
||||||
|
This will overwrite the given changelog file if its existing, if not it will be created.
|
||||||
|
```bash
|
||||||
|
./go-semantic-release changelog --overwrite
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Build from source
|
## Build from source
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
changelogCmd.Flags().Bool("checks", false, "Check for missing values and envs")
|
changelogCmd.Flags().Bool("checks", false, "Check for missing values and envs")
|
||||||
|
changelogCmd.Flags().Bool("overwrite", false, "Overwrite the content of the changelog. Default is to prepend the new changelog to the existing file.")
|
||||||
changelogCmd.Flags().StringP("out", "o", "CHANGELOG.md", "Name of the file")
|
changelogCmd.Flags().StringP("out", "o", "CHANGELOG.md", "Name of the file")
|
||||||
|
changelogCmd.Flags().String("from", "", "Generate combined changelog from given version until latest version ")
|
||||||
|
changelogCmd.Flags().Int64("max-file-size", 10, "The max allowed file size in MB for a changelog file. If the file size is larger, the current file will be moved to a new file named <filename>-01.md. The next changelog will be written to de default file.")
|
||||||
rootCmd.AddCommand(changelogCmd)
|
rootCmd.AddCommand(changelogCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,6 +34,11 @@ var changelogCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overwrite, err := cmd.Flags().GetBool("overwrite")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
file, err := cmd.Flags().GetString("out")
|
file, err := cmd.Flags().GetString("out")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -41,6 +49,16 @@ var changelogCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fromVersion, err := cmd.Flags().GetString("from")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
maxFileSize, err := cmd.Flags().GetInt64("max-file-size")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
s, err := semanticrelease.New(readConfig(config), repository, configChecks)
|
s, err := semanticrelease.New(readConfig(config), repository, configChecks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -51,7 +69,7 @@ var changelogCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseVersion, err := s.GetNextVersion(provider, force)
|
releaseVersion, err := s.GetNextVersion(provider, force, fromVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -61,11 +79,6 @@ var changelogCmd = &cobra.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return s.WriteChangeLog(generatedChangelog.Content, file, overwrite, maxFileSize)
|
||||||
if err = s.WriteChangeLog(generatedChangelog.Content, file); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ var hooksCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseVersion, err := s.GetNextVersion(provider, force)
|
releaseVersion, err := s.GetNextVersion(provider, force, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
62
cmd/go-semantic-release/commands/integrations.go
Normal file
62
cmd/go-semantic-release/commands/integrations.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/integrations"
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/semanticrelease"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
integrationsCmd.Flags().Bool("checks", false, "Check for missing values and envs")
|
||||||
|
integrationsCmd.Flags().StringP("out", "o", "CHANGELOG.md", "Name of the file")
|
||||||
|
rootCmd.AddCommand(integrationsCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var integrationsCmd = &cobra.Command{
|
||||||
|
Use: "integrations",
|
||||||
|
Short: "Call integrations from config file manual",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
config, err := cmd.Flags().GetString("config")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
repository, err := cmd.Flags().GetString("repository")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
force, err := cmd.Flags().GetBool("no-cache")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
configChecks, err := cmd.Flags().GetBool("checks")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseConfig := readConfig(config)
|
||||||
|
|
||||||
|
s, err := semanticrelease.New(releaseConfig, repository, configChecks)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, err := s.GetCIProvider()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseVersion, err := s.GetNextVersion(provider, force, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debugf("Found %d commits till last release", len(releaseVersion.Commits))
|
||||||
|
|
||||||
|
i := integrations.New(&releaseConfig.Integrations, releaseVersion)
|
||||||
|
|
||||||
|
return i.Run()
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@ var lastCmd = &cobra.Command{
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseVersion, err := s.GetNextVersion(provider, force)
|
releaseVersion, err := s.GetNextVersion(provider, force, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ var nextCmd = &cobra.Command{
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseVersion, err := s.GetNextVersion(provider, force)
|
releaseVersion, err := s.GetNextVersion(provider, force, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
12
examples/.gitlab-ci.yml
Normal file
12
examples/.gitlab-ci.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
stages:
|
||||||
|
- release
|
||||||
|
|
||||||
|
release:
|
||||||
|
stage: release
|
||||||
|
image:
|
||||||
|
name: nightapes/go-semantic-release:latest
|
||||||
|
entrypoint: [""]
|
||||||
|
script:
|
||||||
|
- go-semantic-release next
|
||||||
|
only:
|
||||||
|
- master
|
||||||
29
examples/github-actions.yml
Normal file
29
examples/github-actions.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: Go
|
||||||
|
on: [ push, pull_request ]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Init go-semantic-release
|
||||||
|
run: |
|
||||||
|
wget https://github.com/Nightapes/go-semantic-release/releases/download/v2.0.1/go-semantic-release.linux_x86_64.zip
|
||||||
|
unzip go-semantic-release.linux_x86_64.zip
|
||||||
|
chmod +x go-semantic-release.linux_x86_64
|
||||||
|
|
||||||
|
- name: Build binary
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o <your-build-name>.linux_x86_64
|
||||||
|
GOOS=windows GOARCH=386 CGO_ENABLED=0 go build -o <your-build-name>.windows_i386.exe
|
||||||
|
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o <your-build-name>.windows_x86_64.exe
|
||||||
|
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -o <your-build-name>.darwin_x86_64
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: ./go-semantic-release.linux_x86_64 release --loglevel trace
|
||||||
64
go.mod
64
go.mod
@@ -1,26 +1,58 @@
|
|||||||
module github.com/Nightapes/go-semantic-release
|
module github.com/Nightapes/go-semantic-release
|
||||||
|
|
||||||
go 1.13
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/semver v1.5.0
|
github.com/Masterminds/semver v1.5.0
|
||||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
github.com/go-git/go-billy/v5 v5.4.1
|
||||||
github.com/go-git/go-billy/v5 v5.0.0
|
github.com/go-git/go-git/v5 v5.5.2
|
||||||
github.com/go-git/go-git/v5 v5.2.0
|
|
||||||
github.com/golang/protobuf v1.4.3 // indirect
|
|
||||||
github.com/google/go-github/v25 v25.1.3
|
github.com/google/go-github/v25 v25.1.3
|
||||||
github.com/imdario/mergo v0.3.11 // indirect
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.9.0
|
||||||
github.com/spf13/cobra v1.1.1
|
github.com/spf13/cobra v1.6.1
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
github.com/tidwall/sjson v1.2.5
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
|
golang.org/x/oauth2 v0.5.0
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3
|
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect
|
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||||
|
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.gitea.io/sdk/gitea v0.17.1
|
||||||
|
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||||
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
|
||||||
|
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||||
|
github.com/cloudflare/circl v1.3.2 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/emirpasic/gods v1.18.1 // indirect
|
||||||
|
github.com/go-git/gcfg v1.5.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.13 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||||
|
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||||
|
github.com/pjbgf/sha1cd v0.2.3 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/sergi/go-diff v1.3.1 // indirect
|
||||||
|
github.com/skeema/knownhosts v1.1.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/tidwall/gjson v1.14.4 // indirect
|
||||||
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
|
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||||
|
golang.org/x/crypto v0.17.0 // indirect
|
||||||
|
golang.org/x/mod v0.8.0 // indirect
|
||||||
|
golang.org/x/net v0.10.0 // indirect
|
||||||
|
golang.org/x/sys v0.15.0 // indirect
|
||||||
|
golang.org/x/tools v0.6.0 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/protobuf v1.28.1 // indirect
|
||||||
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
686
go.sum
686
go.sum
@@ -1,611 +1,217 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
code.gitea.io/sdk/gitea v0.17.1 h1:3jCPOG2ojbl8AcfaUCRYLT5MUcBMFwS0OSK2mA5Zok8=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
code.gitea.io/sdk/gitea v0.17.1/go.mod h1:aCnBqhHpoEWA180gMbaCtdX9Pl6BWBAuuP2miadoTNM=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
|
||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
|
||||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
|
||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
|
||||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
|
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
github.com/cloudflare/circl v1.3.2 h1:VWp8dY3yH69fdM7lM6A1+NhhVoDu9vqK0jOgmkQHFWk=
|
||||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
github.com/cloudflare/circl v1.3.2/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
|
||||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
|
||||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
|
||||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
|
||||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
|
||||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
|
||||||
github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI=
|
github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ=
|
||||||
github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs=
|
github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-git/go-git/v5 v5.5.2 h1:v8lgZa5k9ylUw+OR/roJHTxR4QItsNFI5nKtAXFuynw=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-git/go-git/v5 v5.5.2/go.mod h1:BE5hUJ5yaV2YMxhmaP4l6RBQ08kMxKSPD4BlxtH7OjI=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
|
||||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
|
||||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
||||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-github/v25 v25.1.3 h1:Ht4YIQgUh4l4lc80fvGnw60khXysXvlgPxPP8uJG3EA=
|
github.com/google/go-github/v25 v25.1.3 h1:Ht4YIQgUh4l4lc80fvGnw60khXysXvlgPxPP8uJG3EA=
|
||||||
github.com/google/go-github/v25 v25.1.3/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw=
|
github.com/google/go-github/v25 v25.1.3/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw=
|
||||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
|
||||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
|
||||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
|
||||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
|
||||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
|
||||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
|
||||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
|
||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
|
||||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
|
||||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
|
||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
|
||||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
|
||||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
|
||||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
|
||||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
|
||||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
|
||||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
|
||||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/pjbgf/sha1cd v0.2.3 h1:uKQP/7QOzNtKYH7UTohZLcjF5/55EnTw0jO/Ru4jZwI=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
|
||||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
|
||||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
|
||||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
|
||||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||||
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
|
|
||||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3 h1:BaN3BAqnopnKjvl+15DYP6LLrbBHfbfmlFYzmFj/Q9Q=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||||
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||||
|
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
|
||||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
|
||||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
||||||
|
|||||||
@@ -13,15 +13,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const breakingChangeKeywords = "BREAKING CHANGE"
|
const breakingChangeKeywords = "BREAKING CHANGE"
|
||||||
const defaultBreakingChangePrefix = breakingChangeKeywords + ":"
|
const defaultBreakingChangePrefix = breakingChangeKeywords + ":"
|
||||||
const footerTokenRegex = "^(?P<token>[^\\s][\\w\\- ]+[^\\s])<SEP>.*"
|
const footerTokenRegex = "^(?P<token>[^\\s*-][\\w\\- ]+[^\\s])<SEP>.*"
|
||||||
var defaultTokenSeparators = [2]string{ ": ", " #"}
|
|
||||||
|
var defaultTokenSeparators = [2]string{": ", " #"}
|
||||||
|
|
||||||
// Analyzer struct
|
// Analyzer struct
|
||||||
type Analyzer struct {
|
type Analyzer struct {
|
||||||
analyzeCommits analyzeCommits
|
analyzeCommits analyzeCommits
|
||||||
ChangelogConfig config.ChangelogConfig
|
ChangelogConfig config.ChangelogConfig
|
||||||
AnalyzerConfig config.AnalyzerConfig
|
AnalyzerConfig config.AnalyzerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rule for commits
|
// Rule for commits
|
||||||
@@ -40,7 +41,7 @@ type analyzeCommits interface {
|
|||||||
// New Analyzer struct for given commit format
|
// New Analyzer struct for given commit format
|
||||||
func New(format string, analyzerConfig config.AnalyzerConfig, chglogConfig config.ChangelogConfig) (*Analyzer, error) {
|
func New(format string, analyzerConfig config.AnalyzerConfig, chglogConfig config.ChangelogConfig) (*Analyzer, error) {
|
||||||
analyzer := &Analyzer{
|
analyzer := &Analyzer{
|
||||||
AnalyzerConfig: analyzerConfig,
|
AnalyzerConfig: analyzerConfig,
|
||||||
ChangelogConfig: chglogConfig,
|
ChangelogConfig: chglogConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,9 +112,9 @@ func getRegexMatchedMap(regEx, url string) (paramsMap map[string]string) {
|
|||||||
//
|
//
|
||||||
// getMessageBlocksFromTexts converts strings to an array of MessageBlock
|
// getMessageBlocksFromTexts converts strings to an array of MessageBlock
|
||||||
//
|
//
|
||||||
func getMessageBlocksFromTexts(txtArray, separators []string) []shared.MessageBlock {
|
func getMessageBlocksFromTexts(txtArray, separators []string) []shared.MessageBlock {
|
||||||
blocks := make([]shared.MessageBlock, len(txtArray))
|
blocks := make([]shared.MessageBlock, len(txtArray))
|
||||||
for i, line := range txtArray{
|
for i, line := range txtArray {
|
||||||
blocks[i] = parseMessageBlock(line, separators)
|
blocks[i] = parseMessageBlock(line, separators)
|
||||||
}
|
}
|
||||||
return blocks
|
return blocks
|
||||||
@@ -127,9 +128,9 @@ func parseMessageBlock(msg string, separators []string) shared.MessageBlock {
|
|||||||
Label: "",
|
Label: "",
|
||||||
Content: msg,
|
Content: msg,
|
||||||
}
|
}
|
||||||
if token, sep := findFooterToken(msg, separators); len(token) > 0{
|
if token, sep := findFooterToken(msg, separators); len(token) > 0 {
|
||||||
msgBlock.Label = token
|
msgBlock.Label = token
|
||||||
content := strings.Replace(msg, token + sep, "", 1)
|
content := strings.Replace(msg, token+sep, "", 1)
|
||||||
msgBlock.Content = strings.TrimSpace(content)
|
msgBlock.Content = strings.TrimSpace(content)
|
||||||
}
|
}
|
||||||
return msgBlock
|
return msgBlock
|
||||||
@@ -157,7 +158,7 @@ func findFooterToken(text string, separators []string) (token string, sep string
|
|||||||
// - A footer is detected when it starts with a token ending with a separator
|
// - A footer is detected when it starts with a token ending with a separator
|
||||||
// - A footer ends when another footer is found or text ends
|
// - A footer ends when another footer is found or text ends
|
||||||
//
|
//
|
||||||
func getDefaultMessageBlockMap(txtBlock string, tokenSep []string) map[string][]shared.MessageBlock{
|
func getDefaultMessageBlockMap(txtBlock string, tokenSep []string) map[string][]shared.MessageBlock {
|
||||||
msgBlockMap := make(map[string][]shared.MessageBlock)
|
msgBlockMap := make(map[string][]shared.MessageBlock)
|
||||||
footers := make([]string, 0)
|
footers := make([]string, 0)
|
||||||
body, footerBlock, line := "", "", ""
|
body, footerBlock, line := "", "", ""
|
||||||
@@ -168,7 +169,7 @@ func getDefaultMessageBlockMap(txtBlock string, tokenSep []string) map[string][]
|
|||||||
line = scanner.Text()
|
line = scanner.Text()
|
||||||
if token, _ := findFooterToken(line, tokenSep); len(token) > 0 {
|
if token, _ := findFooterToken(line, tokenSep); len(token) > 0 {
|
||||||
// if footer was already found from before
|
// if footer was already found from before
|
||||||
if len(footerBlock) > 0{
|
if len(footerBlock) > 0 {
|
||||||
footers = append(footers, strings.TrimSpace(footerBlock))
|
footers = append(footers, strings.TrimSpace(footerBlock))
|
||||||
}
|
}
|
||||||
footerFound = true
|
footerFound = true
|
||||||
@@ -178,7 +179,7 @@ func getDefaultMessageBlockMap(txtBlock string, tokenSep []string) map[string][]
|
|||||||
//'\n' is removed when reading from scanner
|
//'\n' is removed when reading from scanner
|
||||||
if !footerFound {
|
if !footerFound {
|
||||||
body += line + "\n"
|
body += line + "\n"
|
||||||
}else{
|
} else {
|
||||||
footerBlock += line + "\n"
|
footerBlock += line + "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,11 +188,11 @@ func getDefaultMessageBlockMap(txtBlock string, tokenSep []string) map[string][]
|
|||||||
}
|
}
|
||||||
|
|
||||||
body = strings.TrimSpace(body)
|
body = strings.TrimSpace(body)
|
||||||
if len(body) > 0{
|
if len(body) > 0 {
|
||||||
msgBlockMap["body"] = []shared.MessageBlock {{
|
msgBlockMap["body"] = []shared.MessageBlock{{
|
||||||
Label: "",
|
Label: "",
|
||||||
Content: body,
|
Content: body,
|
||||||
} }
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
footerBlocks := getMessageBlocksFromTexts(footers, tokenSep)
|
footerBlocks := getMessageBlocksFromTexts(footers, tokenSep)
|
||||||
|
|||||||
@@ -11,14 +11,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type angular struct {
|
type angular struct {
|
||||||
rules []Rule
|
rules []Rule
|
||||||
regex string
|
regex string
|
||||||
log *log.Entry
|
log *log.Entry
|
||||||
config config.AnalyzerConfig
|
config config.AnalyzerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANGULAR identifier
|
// ANGULAR identifier
|
||||||
const ANGULAR = "angular"
|
const ANGULAR = "angular"
|
||||||
|
|
||||||
var angularFooterTokenSep = defaultTokenSeparators
|
var angularFooterTokenSep = defaultTokenSeparators
|
||||||
|
|
||||||
func newAngular() *angular {
|
func newAngular() *angular {
|
||||||
@@ -99,17 +100,19 @@ func (a *angular) analyze(commit shared.Commit, rule Rule) *shared.AnalyzedCommi
|
|||||||
}
|
}
|
||||||
matches := getRegexMatchedMap(a.regex, header)
|
matches := getRegexMatchedMap(a.regex, header)
|
||||||
|
|
||||||
if len(matches) == 0 || matches["type"] != rule.Tag{
|
if len(matches) == 0 || matches["type"] != rule.Tag {
|
||||||
a.log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag)
|
a.log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
msgBlockMap := getDefaultMessageBlockMap(body, tokenSep)
|
msgBlockMap := getDefaultMessageBlockMap(body, tokenSep)
|
||||||
|
|
||||||
|
log.Debugf("Found commit from Author %s", commit.Author)
|
||||||
|
|
||||||
analyzed := &shared.AnalyzedCommit{
|
analyzed := &shared.AnalyzedCommit{
|
||||||
Commit: commit,
|
Commit: commit,
|
||||||
Tag: rule.Tag,
|
Tag: rule.Tag,
|
||||||
TagString: rule.TagString,
|
TagString: rule.TagString,
|
||||||
Scope: shared.Scope(matches["scope"]),
|
Scope: shared.Scope(matches["scope"]),
|
||||||
Subject: strings.TrimSpace(matches["subject"]),
|
Subject: strings.TrimSpace(matches["subject"]),
|
||||||
MessageBlocks: msgBlockMap,
|
MessageBlocks: msgBlockMap,
|
||||||
|
|||||||
@@ -11,21 +11,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type conventional struct {
|
type conventional struct {
|
||||||
rules []Rule
|
rules []Rule
|
||||||
regex string
|
regex string
|
||||||
log *log.Entry
|
log *log.Entry
|
||||||
config config.AnalyzerConfig
|
config config.AnalyzerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// CONVENTIONAL identifier
|
// CONVENTIONAL identifier
|
||||||
const CONVENTIONAL = "conventional"
|
const CONVENTIONAL = "conventional"
|
||||||
|
|
||||||
var conventionalFooterTokenSep = defaultTokenSeparators
|
var conventionalFooterTokenSep = defaultTokenSeparators
|
||||||
|
|
||||||
func newConventional(config config.AnalyzerConfig) *conventional {
|
func newConventional(config config.AnalyzerConfig) *conventional {
|
||||||
return &conventional{
|
return &conventional{
|
||||||
config: config,
|
config: config,
|
||||||
regex: `^(?P<type>\w*)(?:\((?P<scope>.*)\))?(?P<breaking>\!)?: (?P<subject>.*)`,
|
regex: `^(?P<type>\w*)(?:\((?P<scope>.*)\))?(?P<breaking>\!)?: (?P<subject>.*)`,
|
||||||
log: log.WithField("analyzer", CONVENTIONAL),
|
log: log.WithField("analyzer", CONVENTIONAL),
|
||||||
rules: []Rule{
|
rules: []Rule{
|
||||||
{
|
{
|
||||||
Tag: "feat",
|
Tag: "feat",
|
||||||
@@ -101,7 +102,7 @@ func (a *conventional) analyze(commit shared.Commit, rule Rule) *shared.Analyzed
|
|||||||
|
|
||||||
matches := getRegexMatchedMap(a.regex, header)
|
matches := getRegexMatchedMap(a.regex, header)
|
||||||
|
|
||||||
if len(matches) == 0 || matches["type"] != rule.Tag{
|
if len(matches) == 0 || matches["type"] != rule.Tag {
|
||||||
a.log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag)
|
a.log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -140,4 +141,3 @@ func (a *conventional) analyze(commit shared.Commit, rule Rule) *shared.Analyzed
|
|||||||
|
|
||||||
return analyzed
|
return analyzed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
@@ -21,20 +22,43 @@ const defaultCommitList string = `{{ range $index,$commit := .BreakingChanges -}
|
|||||||
{{ end -}}
|
{{ end -}}
|
||||||
* {{ if $commit.Scope }}**{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}**{{ end }} {{$commit.ParsedBreakingChangeMessage}}
|
* {{ if $commit.Scope }}**{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}**{{ end }} {{$commit.ParsedBreakingChangeMessage}}
|
||||||
introduced by commit:
|
introduced by commit:
|
||||||
{{$commit.ParsedMessage}} {{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})){{end}}
|
{{$commit.Subject}} {{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})){{end}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ range $key := .Order -}}
|
{{ range $key := .Order -}}
|
||||||
{{ $commits := index $.Commits $key -}}
|
{{ $commits := index $.Commits $key -}}
|
||||||
{{ if $commits -}}
|
{{ if $commits -}}
|
||||||
### {{ $key }}
|
### {{ $key }}
|
||||||
{{ range $index,$commit := $commits -}}
|
{{ range $index,$commit := $commits -}}
|
||||||
* {{ if $commit.Scope }}**{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}** {{end}}{{$commit.ParsedMessage}}{{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})){{end}}
|
* {{ if $commit.Scope }}**{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}** {{end}}{{$commit.Subject}}{{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})){{end}}
|
||||||
|
{{ if not $.ShowBodyAsHeader -}}
|
||||||
|
{{ if $commit.MessageBlocks.body -}}
|
||||||
|
{{ range $indexBlock,$bodyBlock := $commit.MessageBlocks.body -}}
|
||||||
|
{{ addPrefixToLines $bodyBlock.Content " > "}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ end -}}`
|
{{ end -}}`
|
||||||
const defaultCommitListSubTemplate string = `{{ define "commitList" }}` + defaultCommitList + "{{ end }}"
|
const defaultCommitListSubTemplate = `{{ define "commitList" }}` + defaultCommitList + "{{ end }}"
|
||||||
const defaultChangelogTitle string = `v{{.Version}} ({{.Now.Format "2006-01-02"}})`
|
const defaultChangelogTitle = `v{{.Version}} ({{.Now.Format "2006-01-02"}})`
|
||||||
const defaultChangelog string = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}})
|
const defaultChangelog = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}})
|
||||||
|
{{ if .ShowBodyAsHeader -}}
|
||||||
|
|
||||||
|
{{ range $key := .CommitsContent.Order -}}
|
||||||
|
{{ $commits := index $.CommitsContent.Commits $key -}}
|
||||||
|
{{ if $commits -}}
|
||||||
|
{{ range $index,$commit := $commits -}}
|
||||||
|
{{ if $commit.MessageBlocks.body -}}
|
||||||
|
{{ range $indexBlock,$bodyBlock := $commit.MessageBlocks.body -}}
|
||||||
|
{{ $bodyBlock.Content }}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
{{ template "commitList" .CommitsContent -}}
|
{{ template "commitList" .CommitsContent -}}
|
||||||
|
|
||||||
{{ if .HasDocker}}
|
{{ if .HasDocker}}
|
||||||
@@ -51,26 +75,55 @@ or
|
|||||||
{{$.Backtick}}docker run {{.DockerRepository}}:latest{{$.Backtick}}
|
{{$.Backtick}}docker run {{.DockerRepository}}:latest{{$.Backtick}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
||||||
|
{{ if .HasNPM}}
|
||||||
|
## NodeJS Package
|
||||||
|
|
||||||
|
New NodeJS package is released under [{{.NPMPackageName}}]({{.NPMRepository}})
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
{{$.Backtick}}yarn add {{.NPMPackageName}}@{{.Version}}{{$.Backtick}}
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
{{$.Backtick}}npm install -save {{.NPMPackageName}}@{{.Version}}{{$.Backtick}}
|
||||||
|
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
{{ if .ShowAuthors -}}
|
||||||
|
# Special Thanks
|
||||||
|
|
||||||
|
{{range $i,$a := .Authors}}{{if gt $i 0 }}, {{end}}{{$a}}{{end}}
|
||||||
|
{{ end -}}
|
||||||
`
|
`
|
||||||
|
|
||||||
type changelogContent struct {
|
type changelogContent struct {
|
||||||
Commits string
|
Commits string
|
||||||
CommitsContent commitsContent
|
CommitsContent commitsContent
|
||||||
Version string
|
Version string
|
||||||
Now time.Time
|
Now time.Time
|
||||||
Backtick string
|
Backtick string
|
||||||
|
ShowBodyAsHeader bool
|
||||||
HasDocker bool
|
HasDocker bool
|
||||||
HasDockerLatest bool
|
HasDockerLatest bool
|
||||||
DockerRepository string
|
DockerRepository string
|
||||||
|
HasNPM bool
|
||||||
|
IsYarn bool
|
||||||
|
NPMRepository string
|
||||||
|
NPMPackageName string
|
||||||
|
Authors []string
|
||||||
|
ShowAuthors bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type commitsContent struct {
|
type commitsContent struct {
|
||||||
Commits map[string][]shared.AnalyzedCommit
|
Commits map[string][]shared.AnalyzedCommit
|
||||||
BreakingChanges []shared.AnalyzedCommit
|
BreakingChanges []shared.AnalyzedCommit
|
||||||
Order []string
|
Order []string
|
||||||
Backtick string
|
ShowBodyAsHeader bool
|
||||||
HasURL bool
|
Backtick string
|
||||||
URL string
|
HasURL bool
|
||||||
|
URL string
|
||||||
}
|
}
|
||||||
|
|
||||||
//Changelog struct
|
//Changelog struct
|
||||||
@@ -105,8 +158,11 @@ func (c *Changelog) GenerateChangelog(templateConfig shared.ChangelogTemplateCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
authors := map[string]bool{}
|
||||||
|
|
||||||
for _, commits := range analyzedCommits {
|
for _, commits := range analyzedCommits {
|
||||||
for _, commit := range commits {
|
for _, commit := range commits {
|
||||||
|
authors[commit.Commit.Author] = true
|
||||||
if commit.Print {
|
if commit.Print {
|
||||||
if commit.IsBreaking {
|
if commit.IsBreaking {
|
||||||
commitsBreakingChange = append(commitsBreakingChange, commit)
|
commitsBreakingChange = append(commitsBreakingChange, commit)
|
||||||
@@ -121,22 +177,38 @@ func (c *Changelog) GenerateChangelog(templateConfig shared.ChangelogTemplateCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
commitsContent := commitsContent{
|
commitsContent := commitsContent{
|
||||||
Commits: commitsPerScope,
|
Commits: commitsPerScope,
|
||||||
BreakingChanges: commitsBreakingChange,
|
BreakingChanges: commitsBreakingChange,
|
||||||
Backtick: "`",
|
Backtick: "`",
|
||||||
Order: order,
|
Order: order,
|
||||||
HasURL: templateConfig.CommitURL != "",
|
ShowBodyAsHeader: c.config.Changelog.ShowBodyAsHeader,
|
||||||
URL: templateConfig.CommitURL,
|
HasURL: templateConfig.CommitURL != "",
|
||||||
|
URL: templateConfig.CommitURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
authorsNames := make([]string, len(authors))
|
||||||
|
i := 0
|
||||||
|
for k := range authors {
|
||||||
|
authorsNames[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(authorsNames)
|
||||||
|
|
||||||
changelogContent := changelogContent{
|
changelogContent := changelogContent{
|
||||||
CommitsContent: commitsContent,
|
CommitsContent: commitsContent,
|
||||||
Version: templateConfig.Version,
|
Version: templateConfig.Version,
|
||||||
Now: c.releaseTime,
|
Now: c.releaseTime,
|
||||||
Backtick: "`",
|
Backtick: "`",
|
||||||
HasDocker: c.config.Changelog.Docker.Repository != "",
|
HasDocker: c.config.Changelog.Docker.Repository != "",
|
||||||
HasDockerLatest: c.config.Changelog.Docker.Latest,
|
HasDockerLatest: c.config.Changelog.Docker.Latest,
|
||||||
DockerRepository: c.config.Changelog.Docker.Repository,
|
DockerRepository: c.config.Changelog.Docker.Repository,
|
||||||
|
HasNPM: c.config.Changelog.NPM.PackageName != "",
|
||||||
|
NPMPackageName: c.config.Changelog.NPM.PackageName,
|
||||||
|
NPMRepository: c.config.Changelog.NPM.Repository,
|
||||||
|
ShowBodyAsHeader: c.config.Changelog.ShowBodyAsHeader,
|
||||||
|
ShowAuthors: c.config.Changelog.ShowAuthors && len(authors) > 0,
|
||||||
|
Authors: authorsNames,
|
||||||
}
|
}
|
||||||
|
|
||||||
chglogTemplate := defaultCommitListSubTemplate + defaultChangelog
|
chglogTemplate := defaultCommitListSubTemplate + defaultChangelog
|
||||||
@@ -168,8 +240,8 @@ func (c *Changelog) GenerateChangelog(templateConfig shared.ChangelogTemplateCon
|
|||||||
log.Tracef("Commits %s", renderedCommitList)
|
log.Tracef("Commits %s", renderedCommitList)
|
||||||
changelogContent.Commits = renderedCommitList
|
changelogContent.Commits = renderedCommitList
|
||||||
|
|
||||||
extraFuncMap := template.FuncMap {
|
extraFuncMap := template.FuncMap{
|
||||||
"commitUrl": func() string {return templateConfig.CommitURL},
|
"commitUrl": func() string { return templateConfig.CommitURL },
|
||||||
}
|
}
|
||||||
log.Debugf("Render changelog")
|
log.Debugf("Render changelog")
|
||||||
renderedContent, err := generateTemplate(chglogTemplate, changelogContent, extraFuncMap)
|
renderedContent, err := generateTemplate(chglogTemplate, changelogContent, extraFuncMap)
|
||||||
@@ -180,10 +252,10 @@ func (c *Changelog) GenerateChangelog(templateConfig shared.ChangelogTemplateCon
|
|||||||
func generateTemplate(text string, values interface{}, extraFuncMap template.FuncMap) (string, error) {
|
func generateTemplate(text string, values interface{}, extraFuncMap template.FuncMap) (string, error) {
|
||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"replace": replace,
|
"replace": replace,
|
||||||
"lower": lower,
|
"lower": lower,
|
||||||
"upper": upper,
|
"upper": upper,
|
||||||
"capitalize": capitalize,
|
"capitalize": capitalize,
|
||||||
"addPrefixToLines": addPrefixToLines,
|
"addPrefixToLines": addPrefixToLines,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ func TestChangelog(t *testing.T) {
|
|||||||
analyzedCommits map[shared.Release][]shared.AnalyzedCommit
|
analyzedCommits map[shared.Release][]shared.AnalyzedCommit
|
||||||
result *shared.GeneratedChangelog
|
result *shared.GeneratedChangelog
|
||||||
hasError bool
|
hasError bool
|
||||||
|
showAuthors bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
testCase: "feat",
|
testCase: "feat",
|
||||||
@@ -41,7 +42,7 @@ func TestChangelog(t *testing.T) {
|
|||||||
Tag: "feat",
|
Tag: "feat",
|
||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
Subject: "my first commit",
|
Subject: "my first commit",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{},
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -52,6 +53,46 @@ func TestChangelog(t *testing.T) {
|
|||||||
},
|
},
|
||||||
hasError: false,
|
hasError: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
testCase: "feat with authors",
|
||||||
|
showAuthors: true,
|
||||||
|
analyzedCommits: map[shared.Release][]shared.AnalyzedCommit{
|
||||||
|
"minor": {
|
||||||
|
{
|
||||||
|
Commit: shared.Commit{
|
||||||
|
Message: "feat(internal/changelog): my first commit",
|
||||||
|
Author: "me",
|
||||||
|
Hash: "12345667",
|
||||||
|
},
|
||||||
|
Scope: "internal/changelog",
|
||||||
|
ParsedMessage: "my first commit",
|
||||||
|
Tag: "feat",
|
||||||
|
TagString: "Features",
|
||||||
|
Print: true,
|
||||||
|
Subject: "my first commit",
|
||||||
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Commit: shared.Commit{
|
||||||
|
Message: "feat(internal/changelog): my second commit",
|
||||||
|
Author: "secondAuthor",
|
||||||
|
Hash: "12345667",
|
||||||
|
},
|
||||||
|
Scope: "internal/changelog",
|
||||||
|
ParsedMessage: "my second commit",
|
||||||
|
Tag: "feat",
|
||||||
|
TagString: "Features",
|
||||||
|
Print: true,
|
||||||
|
Subject: "my second commit",
|
||||||
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: &shared.GeneratedChangelog{
|
||||||
|
Title: "v1.0.0 (2019-07-19)",
|
||||||
|
Content: "# v1.0.0 (2019-07-19)\n### Features\n* **`internal/changelog`** my first commit ([1234566](https://commit.url))\n* **`internal/changelog`** my second commit ([1234566](https://commit.url))\n# Special Thanks\n\nme, secondAuthor\n"},
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
testCase: "feat no scope",
|
testCase: "feat no scope",
|
||||||
analyzedCommits: map[shared.Release][]shared.AnalyzedCommit{
|
analyzedCommits: map[shared.Release][]shared.AnalyzedCommit{
|
||||||
@@ -66,7 +107,7 @@ func TestChangelog(t *testing.T) {
|
|||||||
Tag: "feat",
|
Tag: "feat",
|
||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
Subject: "my first commit",
|
Subject: "my first commit",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{},
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -92,7 +133,7 @@ func TestChangelog(t *testing.T) {
|
|||||||
Tag: "feat",
|
Tag: "feat",
|
||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
Subject: "my first commit",
|
Subject: "my first commit",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{},
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -107,10 +148,10 @@ func TestChangelog(t *testing.T) {
|
|||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
ParsedBreakingChangeMessage: "change api to v2",
|
ParsedBreakingChangeMessage: "change api to v2",
|
||||||
IsBreaking: true,
|
IsBreaking: true,
|
||||||
Subject: "my first break",
|
Subject: "my first break",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{
|
MessageBlocks: map[string][]shared.MessageBlock{
|
||||||
"body" : { shared.MessageBlock{
|
"body": {shared.MessageBlock{
|
||||||
Label: "BREAKING CHANGE",
|
Label: "BREAKING CHANGE",
|
||||||
Content: "change api to v2",
|
Content: "change api to v2",
|
||||||
},
|
},
|
||||||
@@ -141,10 +182,10 @@ func TestChangelog(t *testing.T) {
|
|||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
ParsedBreakingChangeMessage: "hey from the change",
|
ParsedBreakingChangeMessage: "hey from the change",
|
||||||
IsBreaking: true,
|
IsBreaking: true,
|
||||||
Subject: "my first break",
|
Subject: "my first break",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{
|
MessageBlocks: map[string][]shared.MessageBlock{
|
||||||
"body" : { shared.MessageBlock{
|
"body": {shared.MessageBlock{
|
||||||
Label: "BREAKING CHANGE",
|
Label: "BREAKING CHANGE",
|
||||||
Content: "hey from the change",
|
Content: "hey from the change",
|
||||||
},
|
},
|
||||||
@@ -162,7 +203,7 @@ func TestChangelog(t *testing.T) {
|
|||||||
Tag: "feat",
|
Tag: "feat",
|
||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
Subject: "my first commit",
|
Subject: "my first commit",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{},
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -176,12 +217,12 @@ func TestChangelog(t *testing.T) {
|
|||||||
Tag: "feat",
|
Tag: "feat",
|
||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
Subject: "my second commit",
|
Subject: "my second commit",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{},
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Commit: shared.Commit{
|
Commit: shared.Commit{
|
||||||
Message: "feat: my new commit \n\nBREAKING CHANGE: change api to v2",
|
Message: "feat: my first break \n\nBREAKING CHANGE: change api to v2",
|
||||||
Author: "me",
|
Author: "me",
|
||||||
Hash: "12345668",
|
Hash: "12345668",
|
||||||
},
|
},
|
||||||
@@ -191,15 +232,36 @@ func TestChangelog(t *testing.T) {
|
|||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
ParsedBreakingChangeMessage: "change api to v2",
|
ParsedBreakingChangeMessage: "change api to v2",
|
||||||
IsBreaking: true,
|
IsBreaking: true,
|
||||||
Subject: "my new commit",
|
Subject: "my first break",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{
|
MessageBlocks: map[string][]shared.MessageBlock{
|
||||||
"body": { shared.MessageBlock{
|
"body": {shared.MessageBlock{
|
||||||
Label: "BREAKING CHANGE",
|
Label: "BREAKING CHANGE",
|
||||||
Content: "change api to v2",
|
Content: "change api to v2",
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Commit: shared.Commit{
|
||||||
|
Message: "feat: my awesome features \n\n * Feature1: Lists in changelog \n* Feature2: Lists in changelog2",
|
||||||
|
Author: "me",
|
||||||
|
Hash: "12345668",
|
||||||
|
},
|
||||||
|
Scope: "",
|
||||||
|
ParsedMessage: "my awesome features",
|
||||||
|
Tag: "feat",
|
||||||
|
TagString: "Features",
|
||||||
|
Print: true,
|
||||||
|
ParsedBreakingChangeMessage: "",
|
||||||
|
IsBreaking: false,
|
||||||
|
Subject: "my awesome features",
|
||||||
|
MessageBlocks: map[string][]shared.MessageBlock{
|
||||||
|
"body": {shared.MessageBlock{
|
||||||
|
Label: "",
|
||||||
|
Content: "* Feature1: Lists in changelog \n* Feature2: Lists in changelog2",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Commit: shared.Commit{
|
Commit: shared.Commit{
|
||||||
Message: "feat!: my next commit",
|
Message: "feat!: my next commit",
|
||||||
@@ -212,45 +274,139 @@ func TestChangelog(t *testing.T) {
|
|||||||
TagString: "Features",
|
TagString: "Features",
|
||||||
Print: true,
|
Print: true,
|
||||||
ParsedBreakingChangeMessage: "my next commit",
|
ParsedBreakingChangeMessage: "my next commit",
|
||||||
IsBreaking: true,
|
IsBreaking: true,
|
||||||
Subject: "my next commit",
|
Subject: "my next commit",
|
||||||
MessageBlocks: map[string][]shared.MessageBlock{},
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
result: &shared.GeneratedChangelog{
|
result: &shared.GeneratedChangelog{
|
||||||
Title: "v1.0.0 (2019-07-19)",
|
Title: "v1.0.0 (2019-07-19)",
|
||||||
Content: "# v1.0.0 (2019-07-19)\n## BREAKING CHANGES\n* hey from the change \nintroduced by commit: \nmy first break ([1234566](https://commit.url))\n* change api to v2 \nintroduced by commit: \nmy first break ([1234566](https://commit.url))\n* my next commit \nintroduced by commit: \n ([1234566](https://commit.url))\n### Features\n* **`internal/changelog`** my first commit ([1234566](https://commit.url))\n* my first commit ([1234566](https://commit.url))\n",
|
Content: "# v1.0.0 (2019-07-19)\n## BREAKING CHANGES\n* hey from the change \nintroduced by commit: \nmy first break ([1234566](https://commit.url))\n* change api to v2 \nintroduced by commit: \nmy first break ([1234566](https://commit.url))\n* my next commit \nintroduced by commit: \nmy next commit ([1234566](https://commit.url))\n### Features\n* **`internal/changelog`** my first commit ([1234566](https://commit.url))\n* my second commit ([1234566](https://commit.url))\n* my awesome features ([1234566](https://commit.url))\n > * Feature1: Lists in changelog \n > * Feature2: Lists in changelog2\n"},
|
||||||
},
|
|
||||||
hasError: false,
|
hasError: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cl := changelog.New(&config.ReleaseConfig{}, []analyzer.Rule{
|
for _, testConfig := range testConfigs {
|
||||||
|
t.Run(testConfig.testCase, func(t *testing.T) {
|
||||||
|
cl := changelog.New(&config.ReleaseConfig{
|
||||||
|
Changelog: config.ChangelogConfig{
|
||||||
|
ShowBodyAsHeader: false,
|
||||||
|
ShowAuthors: testConfig.showAuthors,
|
||||||
|
},
|
||||||
|
}, []analyzer.Rule{
|
||||||
|
{
|
||||||
|
Tag: "feat",
|
||||||
|
TagString: "Features",
|
||||||
|
Release: "minor",
|
||||||
|
Changelog: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "fix",
|
||||||
|
TagString: "Bug fixes",
|
||||||
|
Release: "patch",
|
||||||
|
Changelog: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "build",
|
||||||
|
TagString: "Build",
|
||||||
|
Release: "none",
|
||||||
|
Changelog: false,
|
||||||
|
},
|
||||||
|
}, time.Date(2019, 7, 19, 0, 0, 0, 0, time.UTC))
|
||||||
|
|
||||||
|
generatedChangelog, err := cl.GenerateChangelog(templateConfig, testConfig.analyzedCommits)
|
||||||
|
assert.Equalf(t, testConfig.hasError, err != nil, "Testcase %s should have error: %t -> %s", testConfig.testCase, testConfig.hasError, err)
|
||||||
|
assert.Equalf(t, testConfig.result, generatedChangelog, "Testcase %s should have generated changelog", testConfig.testCase)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChangelogExtensions(t *testing.T) {
|
||||||
|
|
||||||
|
testConfigs := []struct {
|
||||||
|
testCase string
|
||||||
|
result *shared.GeneratedChangelog
|
||||||
|
releaseConfig *config.ReleaseConfig
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
Tag: "feat",
|
testCase: "docker",
|
||||||
TagString: "Features",
|
releaseConfig: &config.ReleaseConfig{
|
||||||
Release: "minor",
|
Changelog: config.ChangelogConfig{
|
||||||
Changelog: true,
|
Docker: config.ChangelogDocker{
|
||||||
|
Latest: true,
|
||||||
|
Repository: "mydocker.de",
|
||||||
|
},
|
||||||
|
NPM: config.ChangelogNPM{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: &shared.GeneratedChangelog{Title: "v1.0.0 (2019-07-19)", Content: "# v1.0.0 (2019-07-19)\n### Features\n* **`internal/changelog`** my first commit ([1234566](https://commit.url))\n\n## Docker image\n\nNew docker image is released under `mydocker.de:1.0.0`\n\n### Usage\n\n`docker run mydocker.de:1.0.0`\n\nor\n\n`docker run mydocker.de:latest`\n"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Tag: "fix",
|
testCase: "npm",
|
||||||
TagString: "Bug fixes",
|
releaseConfig: &config.ReleaseConfig{
|
||||||
Release: "patch",
|
Changelog: config.ChangelogConfig{
|
||||||
Changelog: true,
|
Docker: config.ChangelogDocker{},
|
||||||
|
NPM: config.ChangelogNPM{
|
||||||
|
Repository: "https://github.com/Nightapes/ngx-validators/packages/102720",
|
||||||
|
PackageName: "ngx-validators",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: &shared.GeneratedChangelog{Title: "v1.0.0 (2019-07-19)", Content: "# v1.0.0 (2019-07-19)\n### Features\n* **`internal/changelog`** my first commit ([1234566](https://commit.url))\n\n## NodeJS Package\n\nNew NodeJS package is released under [ngx-validators](https://github.com/Nightapes/ngx-validators/packages/102720)\n\n### Usage\n\n`yarn add ngx-validators@1.0.0`\n\nor\n\n`npm install -save ngx-validators@1.0.0`\n\n"},
|
||||||
},
|
},
|
||||||
{
|
}
|
||||||
Tag: "build",
|
|
||||||
TagString: "Build",
|
analyzedCommits := map[shared.Release][]shared.AnalyzedCommit{
|
||||||
Release: "none",
|
"minor": {
|
||||||
Changelog: false,
|
{
|
||||||
|
Commit: shared.Commit{
|
||||||
|
Message: "feat(internal/changelog): my first commit",
|
||||||
|
Author: "me",
|
||||||
|
Hash: "12345667",
|
||||||
|
},
|
||||||
|
Scope: "internal/changelog",
|
||||||
|
ParsedMessage: "my first commit",
|
||||||
|
Tag: "feat",
|
||||||
|
TagString: "Features",
|
||||||
|
Print: true,
|
||||||
|
Subject: "my first commit",
|
||||||
|
MessageBlocks: map[string][]shared.MessageBlock{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, time.Date(2019, 7, 19, 0, 0, 0, 0, time.UTC))
|
}
|
||||||
|
|
||||||
for _, config := range testConfigs {
|
for _, config := range testConfigs {
|
||||||
t.Run(config.testCase, func(t *testing.T) {
|
t.Run(config.testCase, func(t *testing.T) {
|
||||||
generatedChangelog, err := cl.GenerateChangelog(templateConfig, config.analyzedCommits)
|
templateConfig := shared.ChangelogTemplateConfig{
|
||||||
assert.Equalf(t, config.hasError, err != nil, "Testcase %s should have error: %t -> %s", config.testCase, config.hasError, err)
|
CommitURL: "https://commit.url",
|
||||||
|
CompareURL: "https://compare.url",
|
||||||
|
Hash: "hash",
|
||||||
|
Version: "1.0.0",
|
||||||
|
}
|
||||||
|
cl := changelog.New(config.releaseConfig, []analyzer.Rule{
|
||||||
|
{
|
||||||
|
Tag: "feat",
|
||||||
|
TagString: "Features",
|
||||||
|
Release: "minor",
|
||||||
|
Changelog: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "fix",
|
||||||
|
TagString: "Bug fixes",
|
||||||
|
Release: "patch",
|
||||||
|
Changelog: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "build",
|
||||||
|
TagString: "Build",
|
||||||
|
Release: "none",
|
||||||
|
Changelog: false,
|
||||||
|
},
|
||||||
|
}, time.Date(2019, 7, 19, 0, 0, 0, 0, time.UTC))
|
||||||
|
generatedChangelog, err := cl.GenerateChangelog(templateConfig, analyzedCommits)
|
||||||
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, config.result, generatedChangelog, "Testcase %s should have generated changelog", config.testCase)
|
assert.Equalf(t, config.result, generatedChangelog, "Testcase %s should have generated changelog", config.testCase)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
//ProviderConfig struct
|
// ProviderConfig struct
|
||||||
type ProviderConfig struct {
|
type ProviderConfig struct {
|
||||||
IsPR bool
|
IsPR bool
|
||||||
PR string
|
PR string
|
||||||
@@ -23,12 +23,12 @@ type ProviderConfig struct {
|
|||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
//Service interface
|
// Service interface
|
||||||
type Service interface {
|
type Service interface {
|
||||||
detect(envs map[string]string) (*ProviderConfig, error)
|
detect(envs map[string]string) (*ProviderConfig, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
//ReadAllEnvs as a map
|
// ReadAllEnvs as a map
|
||||||
func ReadAllEnvs() map[string]string {
|
func ReadAllEnvs() map[string]string {
|
||||||
envs := map[string]string{}
|
envs := map[string]string{}
|
||||||
for _, pair := range os.Environ() {
|
for _, pair := range os.Environ() {
|
||||||
@@ -38,13 +38,14 @@ func ReadAllEnvs() map[string]string {
|
|||||||
return envs
|
return envs
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetCIProvider get provider
|
// GetCIProvider get provider
|
||||||
func GetCIProvider(gitUtil *gitutil.GitUtil, configCheck bool, envs map[string]string) (*ProviderConfig, error) {
|
func GetCIProvider(gitUtil *gitutil.GitUtil, configCheck bool, envs map[string]string) (*ProviderConfig, error) {
|
||||||
|
|
||||||
services := []Service{
|
services := []Service{
|
||||||
Travis{},
|
Travis{},
|
||||||
GithubActions{},
|
GithubActions{},
|
||||||
GitlabCI{},
|
GitlabCI{},
|
||||||
|
WoodpeckerCI{},
|
||||||
Git{gitUtil: gitUtil}, // Git must be the last option to check
|
Git{gitUtil: gitUtil}, // Git must be the last option to check
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
internal/ci/woodpecker.go
Normal file
42
internal/ci/woodpecker.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package ci
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Travis struct
|
||||||
|
type WoodpeckerCI struct{}
|
||||||
|
|
||||||
|
// Detect if on travis
|
||||||
|
func (t WoodpeckerCI) detect(envs map[string]string) (*ProviderConfig, error) {
|
||||||
|
|
||||||
|
if envs["CI"] != "woodpecker" {
|
||||||
|
return nil, fmt.Errorf("not running on woodpecker")
|
||||||
|
}
|
||||||
|
|
||||||
|
isPR := false
|
||||||
|
|
||||||
|
value := envs["CI_COMMIT_PULL_REQUEST"]
|
||||||
|
pr := ""
|
||||||
|
|
||||||
|
if value == "" {
|
||||||
|
log.Debugf("CI_COMMIT_PULL_REQUEST=%s, not running on pr", value)
|
||||||
|
} else {
|
||||||
|
isPR = true
|
||||||
|
pr = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ProviderConfig{
|
||||||
|
Service: "woodpecker",
|
||||||
|
Name: "Woodpecker CI",
|
||||||
|
Commit: envs["CI_COMMIT_SHA"],
|
||||||
|
Tag: envs["CI_COMMIT_TAG"],
|
||||||
|
BuildURL: envs["CI_PIPELINE_URL"],
|
||||||
|
Branch: envs["CI_COMMIT_BRANCH"],
|
||||||
|
IsPR: isPR,
|
||||||
|
PR: pr,
|
||||||
|
PRBranch: envs["CI_COMMIT_SOURCE_BRANCH"],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -3,15 +3,15 @@ package gitutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/Masterminds/semver"
|
"github.com/Masterminds/semver"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/go-git/go-git/v5/plumbing/object"
|
"github.com/go-git/go-git/v5/plumbing/object"
|
||||||
"github.com/go-git/go-git/v5/plumbing/storer"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -77,14 +77,30 @@ func (g *GitUtil) GetBranch() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetLastVersion from git tags
|
// GetLastVersion from git tags
|
||||||
func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) {
|
func (g *GitUtil) GetVersion(version string) (*semver.Version, *plumbing.Reference, error) {
|
||||||
|
|
||||||
|
v, err := semver.NewVersion(version)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
tag, err := g.Repository.Tag(version)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Found old hash %s", tag.Hash().String())
|
||||||
|
return v, tag, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLastVersion from git tags
|
||||||
|
func (g *GitUtil) GetLastVersion() (*semver.Version, *plumbing.Reference, error) {
|
||||||
|
|
||||||
var tags []*semver.Version
|
var tags []*semver.Version
|
||||||
|
|
||||||
gitTags, err := g.Repository.Tags()
|
gitTags, err := g.Repository.Tags()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gitTags.ForEach(func(p *plumbing.Reference) error {
|
err = gitTags.ForEach(func(p *plumbing.Reference) error {
|
||||||
@@ -100,63 +116,75 @@ func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(sort.Reverse(semver.Collection(tags)))
|
sort.Sort(sort.Reverse(semver.Collection(tags)))
|
||||||
|
|
||||||
if len(tags) == 0 {
|
if len(tags) == 0 {
|
||||||
log.Debugf("Found no tags")
|
log.Debugf("Found no tags")
|
||||||
return nil, "", nil
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Found old version %s", tags[0].String())
|
log.Debugf("Found old version %s", tags[0].String())
|
||||||
|
|
||||||
tag, err := g.Repository.Tag(tags[0].Original())
|
tag, err := g.Repository.Tag(tags[0].Original())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Found old hash %s", tag.Hash().String())
|
log.Debugf("Found old hash %s", tag.Hash().String())
|
||||||
return tags[0], tag.Hash().String(), nil
|
return tags[0], tag, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommits from git hash to HEAD
|
// GetCommits from git hash to HEAD
|
||||||
func (g *GitUtil) GetCommits(lastTagHash string) ([]shared.Commit, error) {
|
func (g *GitUtil) GetCommits(lastTagHash *plumbing.Reference) ([]shared.Commit, error) {
|
||||||
|
|
||||||
ref, err := g.Repository.Head()
|
ref, err := g.Repository.Head()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
logOptions := &git.LogOptions{From: ref.Hash()}
|
||||||
|
|
||||||
cIter, err := g.Repository.Log(&git.LogOptions{From: ref.Hash(), Order: git.LogOrderCommitterTime})
|
if lastTagHash != nil {
|
||||||
|
logOptions = &git.LogOptions{From: lastTagHash.Hash()}
|
||||||
|
}
|
||||||
|
excludeIter, err := g.Repository.Log(logOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not get git log %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
seen := map[plumbing.Hash]struct{}{}
|
||||||
|
err = excludeIter.ForEach(func(c *object.Commit) error {
|
||||||
|
seen[c.Hash] = struct{}{}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isValid object.CommitFilter = func(commit *object.Commit) bool {
|
||||||
|
_, ok := seen[commit.Hash]
|
||||||
|
return !ok && len(commit.ParentHashes) < 2
|
||||||
|
}
|
||||||
|
|
||||||
|
startCommit, err := g.Repository.CommitObject(ref.Hash())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cIter := object.NewFilterCommitIter(startCommit, &isValid, nil)
|
||||||
|
|
||||||
commits := make(map[string]shared.Commit)
|
commits := make(map[string]shared.Commit)
|
||||||
var foundEnd bool
|
|
||||||
|
|
||||||
err = cIter.ForEach(func(c *object.Commit) error {
|
err = cIter.ForEach(func(c *object.Commit) error {
|
||||||
|
log.Debugf("Found commit with hash %s from %s", c.Hash.String(), c.Author.Name)
|
||||||
if c.Hash.String() == lastTagHash {
|
commits[c.Hash.String()] = shared.Commit{
|
||||||
log.Debugf("Found commit with hash %s, will stop here", c.Hash.String())
|
Message: c.Message,
|
||||||
foundEnd = true
|
Author: c.Author.Name,
|
||||||
return storer.ErrStop
|
Hash: c.Hash.String(),
|
||||||
}
|
|
||||||
|
|
||||||
if !foundEnd {
|
|
||||||
log.Tracef("Found commit with hash %s", c.Hash.String())
|
|
||||||
commits[c.Hash.String()] = shared.Commit{
|
|
||||||
Message: c.Message,
|
|
||||||
Author: c.Committer.Name,
|
|
||||||
Hash: c.Hash.String(),
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Could not read commits, check git clone depth in your ci")
|
return nil, errors.Wrap(err, "Could not read commits, check git clone depth in your ci")
|
||||||
}
|
}
|
||||||
|
|||||||
26
internal/integrations/integrations.go
Normal file
26
internal/integrations/integrations.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package integrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Integrations struct
|
||||||
|
type Integrations struct {
|
||||||
|
version *shared.ReleaseVersion
|
||||||
|
config *config.Integrations
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(config *config.Integrations, version *shared.ReleaseVersion) *Integrations {
|
||||||
|
return &Integrations{
|
||||||
|
config: config,
|
||||||
|
version: version,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Integrations) Run() error {
|
||||||
|
if i.config.NPM.Enabled {
|
||||||
|
return i.updateNPM()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
28
internal/integrations/npm.go
Normal file
28
internal/integrations/npm.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package integrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/tidwall/sjson"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *Integrations) updateNPM() error {
|
||||||
|
|
||||||
|
npmConfig := i.config.NPM
|
||||||
|
if npmConfig.Path == "" {
|
||||||
|
npmConfig.Path = "./package.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Set version %s to %s", i.version.Next.Version, npmConfig.Path)
|
||||||
|
data, err := ioutil.ReadFile(npmConfig.Path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newData, err := sjson.Set(string(data), "version", i.version.Next.Version)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioutil.WriteFile(npmConfig.Path, []byte(newData), 0777)
|
||||||
|
}
|
||||||
62
internal/integrations/npm_test.go
Normal file
62
internal/integrations/npm_test.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package integrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Masterminds/semver"
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIntegrations_updateNPM(t *testing.T) {
|
||||||
|
file, err := ioutil.TempFile("", "package")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.Remove(file.Name())
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(file.Name(), []byte(`{
|
||||||
|
"name": "test",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"nx": "nx"
|
||||||
|
}
|
||||||
|
}`), 0777)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testVersion, err := semver.NewVersion("1.2.0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
i := New(&config.Integrations{NPM: config.IntegrationNPM{
|
||||||
|
Enabled: true,
|
||||||
|
Path: file.Name(),
|
||||||
|
}}, &shared.ReleaseVersion{
|
||||||
|
Next: shared.ReleaseVersionEntry{
|
||||||
|
Version: testVersion,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.NoError(t, i.updateNPM())
|
||||||
|
updatedFile, err := ioutil.ReadFile(file.Name())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, `{
|
||||||
|
"name": "test",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"nx": "nx"
|
||||||
|
}
|
||||||
|
}`, string(updatedFile))
|
||||||
|
|
||||||
|
}
|
||||||
161
internal/releaser/gitea/gitea.go
Normal file
161
internal/releaser/gitea/gitea.go
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/assets"
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/releaser/util"
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
|
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GITEA identifer for gitea interface
|
||||||
|
const GITEA = "gitea"
|
||||||
|
|
||||||
|
// Client type struct
|
||||||
|
type GiteaClient struct {
|
||||||
|
client *gitea.Client
|
||||||
|
config *config.GiteaProvider
|
||||||
|
context context.Context
|
||||||
|
release *gitea.Release
|
||||||
|
baseURL string
|
||||||
|
log *log.Entry
|
||||||
|
}
|
||||||
|
|
||||||
|
// New initialize a new GiteaRelease
|
||||||
|
func New(c *config.GiteaProvider, checkConfig bool) (*GiteaClient, error) {
|
||||||
|
|
||||||
|
token, err := util.GetAccessToken("GITEA_TOKEN")
|
||||||
|
if err != nil && checkConfig {
|
||||||
|
return &GiteaClient{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.AccessToken = token
|
||||||
|
|
||||||
|
if c.URL == "" {
|
||||||
|
url, err := util.GetAccessToken("GITEA_URL")
|
||||||
|
if err != nil && checkConfig {
|
||||||
|
return &GiteaClient{}, err
|
||||||
|
}
|
||||||
|
c.URL = url
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
//httpClient := util.CreateBearerHTTPClient(ctx, c.AccessToken)
|
||||||
|
|
||||||
|
if c.Repo == "" && checkConfig {
|
||||||
|
return nil, fmt.Errorf("gitea repo is not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.User == "" && checkConfig {
|
||||||
|
return nil, fmt.Errorf("gitea user is not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.URL == "" && checkConfig {
|
||||||
|
return nil, fmt.Errorf("gitea url is not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := gitea.NewClient(c.URL,
|
||||||
|
gitea.SetToken(c.AccessToken),
|
||||||
|
// gitea.SetHTTPClient(p.HTTPClient()),
|
||||||
|
gitea.SetContext(ctx))
|
||||||
|
if err != nil {
|
||||||
|
return &GiteaClient{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GiteaClient{
|
||||||
|
config: c,
|
||||||
|
client: client,
|
||||||
|
context: ctx,
|
||||||
|
baseURL: c.URL,
|
||||||
|
log: log.WithField("releaser", GITEA),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommitURL for gitea
|
||||||
|
func (g *GiteaClient) GetCommitURL() string {
|
||||||
|
return fmt.Sprintf("%s/%s/%s/commit/{{hash}}", g.baseURL, g.config.User, g.config.Repo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCompareURL for gitea
|
||||||
|
func (g *GiteaClient) GetCompareURL(oldVersion, newVersion string) string {
|
||||||
|
return fmt.Sprintf("%s/%s/%s/compare/%s...%s", g.baseURL, g.config.User, g.config.Repo, oldVersion, newVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRelease creates release on remote
|
||||||
|
func (g *GiteaClient) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog, assets *assets.Set) error {
|
||||||
|
err := g.makeRelease(releaseVersion, generatedChangelog)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return g.uploadAssets(assets)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRelease creates release on remote
|
||||||
|
func (g *GiteaClient) makeRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error {
|
||||||
|
|
||||||
|
tagPrefix := config.DefaultTagPrefix
|
||||||
|
if g.config.TagPrefix != nil {
|
||||||
|
tagPrefix = *g.config.TagPrefix
|
||||||
|
}
|
||||||
|
tag := tagPrefix + releaseVersion.Next.Version.String()
|
||||||
|
g.log.Debugf("create release with version %s", tag)
|
||||||
|
|
||||||
|
prerelease := releaseVersion.Next.Version.Prerelease() != ""
|
||||||
|
|
||||||
|
opt := gitea.CreateReleaseOption{TagName: tag,
|
||||||
|
Target: releaseVersion.Branch,
|
||||||
|
Title: generatedChangelog.Title,
|
||||||
|
Note: generatedChangelog.Content,
|
||||||
|
IsPrerelease: prerelease}
|
||||||
|
// TODO Test if this prevents release double-up
|
||||||
|
release, _, err := g.client.CreateRelease(g.config.User, g.config.Repo, opt)
|
||||||
|
|
||||||
|
g.log.Debugf("Release response: %+v", *release)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
g.log.Debugf("Release Error response: %+v", err)
|
||||||
|
if strings.Contains(err.Error(), "Release is has no Tag") {
|
||||||
|
g.log.Infof("A release with tag %s already exits, will not perform a release or update", tag)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("could not create release: %s", err.Error())
|
||||||
|
}
|
||||||
|
g.release = release
|
||||||
|
g.log.Infof("Created release")
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadAssets uploads specified assets
|
||||||
|
func (g *GiteaClient) uploadAssets(assets *assets.Set) error {
|
||||||
|
if g.release != nil {
|
||||||
|
for _, asset := range assets.All() {
|
||||||
|
path, err := asset.GetPath()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, resp, err := g.client.CreateReleaseAttachment(g.config.User, g.config.Repo, g.release.ID, file, asset.GetName())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode >= http.StatusBadRequest {
|
||||||
|
return fmt.Errorf("could not upload asset %s: %s", asset.GetName(), resp.Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
239
internal/releaser/gitea/gitea_test.go
Normal file
239
internal/releaser/gitea/gitea_test.go
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver"
|
||||||
|
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testHelperMethodStruct struct {
|
||||||
|
config config.GiteaProvider
|
||||||
|
valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type testReleaseStruct struct {
|
||||||
|
config config.GiteaProvider
|
||||||
|
releaseVersion *shared.ReleaseVersion
|
||||||
|
generatedChangelog *shared.GeneratedChangelog
|
||||||
|
requestResponseBody string
|
||||||
|
requestResponseCode int
|
||||||
|
valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var testNewClient = []testHelperMethodStruct{
|
||||||
|
{config: config.GiteaProvider{
|
||||||
|
Repo: "foo",
|
||||||
|
User: "bar",
|
||||||
|
URL: "https://hub.cybercinch.nz",
|
||||||
|
},
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastVersion, _ = semver.NewVersion("1.0.0")
|
||||||
|
var newVersion, _ = semver.NewVersion("2.0.0")
|
||||||
|
|
||||||
|
var testReleases = []testReleaseStruct{
|
||||||
|
{
|
||||||
|
config: config.GiteaProvider{
|
||||||
|
Repo: "foo",
|
||||||
|
User: "bar",
|
||||||
|
},
|
||||||
|
releaseVersion: &shared.ReleaseVersion{
|
||||||
|
Last: shared.ReleaseVersionEntry{
|
||||||
|
Version: lastVersion,
|
||||||
|
Commit: "foo",
|
||||||
|
},
|
||||||
|
Next: shared.ReleaseVersionEntry{
|
||||||
|
Version: newVersion,
|
||||||
|
Commit: "bar",
|
||||||
|
},
|
||||||
|
Branch: "master",
|
||||||
|
},
|
||||||
|
generatedChangelog: &shared.GeneratedChangelog{
|
||||||
|
Title: "title",
|
||||||
|
Content: "content",
|
||||||
|
},
|
||||||
|
requestResponseBody: "{ \"url\": \"https://api.github.com/repos/octocat/Hello-World/releases/1\", \"html_url\": \"https://github.com/octocat/Hello-World/releases/v1.0.0\", \"assets_url\": \"https://api.github.com/repos/octocat/Hello-World/releases/1/assets\", \"upload_url\": \"https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}\", \"tarball_url\": \"https://api.github.com/repos/octocat/Hello-World/tarball/v1.0.0\", \"zipball_url\": \"https://api.github.com/repos/octocat/Hello-World/zipball/v1.0.0\", \"id\": 1, \"node_id\": \"MDc6UmVsZWFzZTE=\", \"tag_name\": \"v1.0.0\", \"target_commitish\": \"master\", \"name\": \"v1.0.0\", \"body\": \"Description of the release\", \"draft\": false, \"prerelease\": false, \"created_at\": \"2013-02-27T19:35:32Z\", \"published_at\": \"2013-02-27T19:35:32Z\", \"author\": { \"login\": \"octocat\", \"id\": 1, \"node_id\": \"MDQ6VXNlcjE=\", \"avatar_url\": \"https://github.com/images/error/octocat_happy.gif\", \"gravatar_id\": \"\", \"url\": \"https://api.github.com/users/octocat\", \"html_url\": \"https://github.com/octocat\", \"followers_url\": \"https://api.github.com/users/octocat/followers\", \"following_url\": \"https://api.github.com/users/octocat/following{/other_user}\", \"gists_url\": \"https://api.github.com/users/octocat/gists{/gist_id}\", \"starred_url\": \"https://api.github.com/users/octocat/starred{/owner}{/repo}\", \"subscriptions_url\": \"https://api.github.com/users/octocat/subscriptions\", \"organizations_url\": \"https://api.github.com/users/octocat/orgs\", \"repos_url\": \"https://api.github.com/users/octocat/repos\", \"events_url\": \"https://api.github.com/users/octocat/events{/privacy}\", \"received_events_url\": \"https://api.github.com/users/octocat/received_events\", \"type\": \"User\", \"site_admin\": false }, \"assets\": [ ]}",
|
||||||
|
requestResponseCode: 200,
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: config.GiteaProvider{
|
||||||
|
Repo: "foo",
|
||||||
|
User: "bar",
|
||||||
|
},
|
||||||
|
releaseVersion: &shared.ReleaseVersion{
|
||||||
|
Last: shared.ReleaseVersionEntry{
|
||||||
|
Version: lastVersion,
|
||||||
|
Commit: "foo",
|
||||||
|
},
|
||||||
|
Next: shared.ReleaseVersionEntry{
|
||||||
|
Version: newVersion,
|
||||||
|
Commit: "bar",
|
||||||
|
},
|
||||||
|
Branch: "master",
|
||||||
|
},
|
||||||
|
generatedChangelog: &shared.GeneratedChangelog{
|
||||||
|
Title: "title",
|
||||||
|
Content: "content",
|
||||||
|
},
|
||||||
|
requestResponseCode: 400,
|
||||||
|
valid: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func initHTTPServerMux() *httptest.Server {
|
||||||
|
// Take the request entries and return http mux
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/api/v1/version", func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
log.Infof("Got call from %s %s", req.Method, req.URL.String())
|
||||||
|
rw.WriteHeader(200)
|
||||||
|
rw.Header().Set("Content-Type", "application/json")
|
||||||
|
body := `{
|
||||||
|
"version": "1.21.10"
|
||||||
|
}`
|
||||||
|
if _, err := rw.Write([]byte(body)); err != nil {
|
||||||
|
log.Info(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/api/v1/repos/bar/foo/releases", func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
log.Infof("Got call from %s %s", req.Method, req.URL.String())
|
||||||
|
|
||||||
|
rw.WriteHeader(200)
|
||||||
|
body := `{
|
||||||
|
"url": "https://api.github.com/repos/octocat/Hello-World/releases/1",
|
||||||
|
"html_url": "https://github.com/octocat/Hello-World/releases/v1.0.0",
|
||||||
|
"assets_url": "https://api.github.com/repos/octocat/Hello-World/releases/1/assets",
|
||||||
|
"upload_url": "https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}",
|
||||||
|
"tarball_url": "https://api.github.com/repos/octocat/Hello-World/tarball/v1.0.0",
|
||||||
|
"zipball_url": "https://api.github.com/repos/octocat/Hello-World/zipball/v1.0.0",
|
||||||
|
"id": 1,
|
||||||
|
"node_id": "MDc6UmVsZWFzZTE=",
|
||||||
|
"tag_name": "v1.0.0",
|
||||||
|
"target_commitish": "master",
|
||||||
|
"name": "v1.0.0",
|
||||||
|
"body": "Description of the release",
|
||||||
|
"draft": false,
|
||||||
|
"prerelease": false,
|
||||||
|
"created_at": "2013-02-27T19:35:32Z",
|
||||||
|
"published_at": "2013-02-27T19:35:32Z",
|
||||||
|
"author": {
|
||||||
|
"login": "octocat",
|
||||||
|
"id": 1,
|
||||||
|
"node_id": "MDQ6VXNlcjE=",
|
||||||
|
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
||||||
|
"gravatar_id": "",
|
||||||
|
"url": "https://api.github.com/users/octocat",
|
||||||
|
"html_url": "https://github.com/octocat",
|
||||||
|
"followers_url": "https://api.github.com/users/octocat/followers",
|
||||||
|
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
||||||
|
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
||||||
|
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
||||||
|
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
||||||
|
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
||||||
|
"repos_url": "https://api.github.com/users/octocat/repos",
|
||||||
|
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
||||||
|
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
||||||
|
"type": "User",
|
||||||
|
"site_admin": false
|
||||||
|
},
|
||||||
|
"assets": []
|
||||||
|
}`
|
||||||
|
rw.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
if _, err := rw.Write([]byte(body)); err != nil {
|
||||||
|
log.Info(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewGitea(t *testing.T) {
|
||||||
|
for _, testOject := range testNewClient {
|
||||||
|
if testOject.valid {
|
||||||
|
os.Setenv("GITEA_TOKEN", "XXX")
|
||||||
|
}
|
||||||
|
server := initHTTPServerMux()
|
||||||
|
defer server.Close()
|
||||||
|
testOject.config.URL = server.URL
|
||||||
|
_, err := New(&testOject.config, true)
|
||||||
|
|
||||||
|
assert.Equal(t, testOject.valid, err == nil)
|
||||||
|
|
||||||
|
os.Unsetenv("GITEA_TOKEN")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetCommitURLGitea(t *testing.T) {
|
||||||
|
os.Setenv("GITEA_TOKEN", "XX")
|
||||||
|
for _, testOject := range testNewClient {
|
||||||
|
server := initHTTPServerMux()
|
||||||
|
defer server.Close()
|
||||||
|
testOject.config.URL = server.URL
|
||||||
|
client, _ := New(&testOject.config, false)
|
||||||
|
actualURL := client.GetCommitURL()
|
||||||
|
expectedURL := fmt.Sprintf("%s/%s/%s/commit/{{hash}}", testOject.config.URL, testOject.config.User, testOject.config.Repo)
|
||||||
|
assert.EqualValues(t, expectedURL, actualURL)
|
||||||
|
}
|
||||||
|
os.Unsetenv("GITEA_TOKEN")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetCompareURLGitea(t *testing.T) {
|
||||||
|
os.Setenv("GITEA_TOKEN", "XX")
|
||||||
|
for _, testOject := range testNewClient {
|
||||||
|
server := initHTTPServerMux()
|
||||||
|
defer server.Close()
|
||||||
|
testOject.config.URL = server.URL
|
||||||
|
client, _ := New(&testOject.config, false)
|
||||||
|
actualURL := client.GetCompareURL("1", "2")
|
||||||
|
expectedURL := fmt.Sprintf("%s/%s/%s/compare/%s...%s", testOject.config.URL, testOject.config.User, testOject.config.Repo, "1", "2")
|
||||||
|
assert.EqualValues(t, expectedURL, actualURL)
|
||||||
|
}
|
||||||
|
os.Unsetenv("GITEA_TOKEN")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateReleaseGitea(t *testing.T) {
|
||||||
|
os.Setenv("GITEA_TOKEN", "XX")
|
||||||
|
|
||||||
|
for _, testObject := range testReleases {
|
||||||
|
if testObject.valid {
|
||||||
|
server := initHTTPServerMux()
|
||||||
|
defer server.Close()
|
||||||
|
testObject.config.URL = server.URL
|
||||||
|
client, _ := New(&testObject.config, false)
|
||||||
|
err := client.makeRelease(testObject.releaseVersion, testObject.generatedChangelog)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, testObject.valid, err == nil)
|
||||||
|
} else {
|
||||||
|
server := initHTTPServerMux()
|
||||||
|
defer server.Close()
|
||||||
|
testObject.config.URL = server.URL
|
||||||
|
client, _ := New(&testObject.config, false)
|
||||||
|
server.Close() // Simulate error response
|
||||||
|
err := client.makeRelease(testObject.releaseVersion, testObject.generatedChangelog)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
assert.Error(t, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.Unsetenv("GITEA_TOKEN")
|
||||||
|
|
||||||
|
}
|
||||||
@@ -54,10 +54,13 @@ func New(c *config.GitHubProvider, checkConfig bool) (*Client, error) {
|
|||||||
if c.CustomURL == "" {
|
if c.CustomURL == "" {
|
||||||
client = github.NewClient(httpClient)
|
client = github.NewClient(httpClient)
|
||||||
} else {
|
} else {
|
||||||
if client, err = github.NewEnterpriseClient(c.CustomURL, c.CustomURL+"/api/v3/", httpClient); err != nil {
|
// v25.0 of google github does not append prefixes for base and upload URLs
|
||||||
|
if client, err = github.NewEnterpriseClient(c.CustomURL+"/api/v3/", c.CustomURL+"/api/uploads/", httpClient); err != nil {
|
||||||
return &Client{}, err
|
return &Client{}, err
|
||||||
}
|
}
|
||||||
baseURL = c.CustomURL
|
// note: do not append / to end of the url since all the url constructions using this
|
||||||
|
// assume no trailing /
|
||||||
|
baseURL = c.CustomURL + "/api/v3"
|
||||||
}
|
}
|
||||||
return &Client{
|
return &Client{
|
||||||
config: c,
|
config: c,
|
||||||
@@ -91,7 +94,7 @@ func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedC
|
|||||||
func (g *Client) makeRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error {
|
func (g *Client) makeRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error {
|
||||||
|
|
||||||
tagPrefix := config.DefaultTagPrefix
|
tagPrefix := config.DefaultTagPrefix
|
||||||
if g.config.TagPrefix != nil{
|
if g.config.TagPrefix != nil {
|
||||||
tagPrefix = *g.config.TagPrefix
|
tagPrefix = *g.config.TagPrefix
|
||||||
}
|
}
|
||||||
tag := tagPrefix + releaseVersion.Next.Version.String()
|
tag := tagPrefix + releaseVersion.Next.Version.String()
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ func TestGetCommitURL(t *testing.T) {
|
|||||||
client, _ := New(&testOject.config, false)
|
client, _ := New(&testOject.config, false)
|
||||||
actualURL := client.GetCommitURL()
|
actualURL := client.GetCommitURL()
|
||||||
if testOject.config.CustomURL != "" {
|
if testOject.config.CustomURL != "" {
|
||||||
expectedURL := fmt.Sprintf("%s/%s/%s/commit/{{hash}}", testOject.config.CustomURL, testOject.config.User, testOject.config.Repo)
|
expectedURL := fmt.Sprintf("%s/api/v3/%s/%s/commit/{{hash}}", testOject.config.CustomURL, testOject.config.User, testOject.config.Repo)
|
||||||
assert.EqualValues(t, expectedURL, actualURL)
|
assert.EqualValues(t, expectedURL, actualURL)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -154,7 +154,7 @@ func TestGetCompareURL(t *testing.T) {
|
|||||||
client, _ := New(&testOject.config, false)
|
client, _ := New(&testOject.config, false)
|
||||||
actualURL := client.GetCompareURL("1", "2")
|
actualURL := client.GetCompareURL("1", "2")
|
||||||
if testOject.config.CustomURL != "" {
|
if testOject.config.CustomURL != "" {
|
||||||
expectedURL := fmt.Sprintf("%s/%s/%s/compare/%s...%s", testOject.config.CustomURL, testOject.config.User, testOject.config.Repo, "1", "2")
|
expectedURL := fmt.Sprintf("%s/api/v3/%s/%s/compare/%s...%s", testOject.config.CustomURL, testOject.config.User, testOject.config.Repo, "1", "2")
|
||||||
assert.EqualValues(t, expectedURL, actualURL)
|
assert.EqualValues(t, expectedURL, actualURL)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -22,29 +22,29 @@ func TestGetCommitURL(t *testing.T) {
|
|||||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||||
client, err := New(&config.GitLabProvider{
|
client, err := New(&config.GitLabProvider{
|
||||||
CustomURL: "https://localhost/",
|
CustomURL: "https://127.0.0.1/",
|
||||||
Repo: "test/test",
|
Repo: "test/test",
|
||||||
}, true)
|
}, true)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "https://localhost/test/test/commit/{{hash}}", client.GetCommitURL())
|
assert.Equal(t, "https://127.0.0.1/test/test/commit/{{hash}}", client.GetCommitURL())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetCompareURL(t *testing.T) {
|
func TestGetCompareURL(t *testing.T) {
|
||||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||||
client, err := New(&config.GitLabProvider{
|
client, err := New(&config.GitLabProvider{
|
||||||
CustomURL: "https://localhost/",
|
CustomURL: "https://127.0.0.1/",
|
||||||
Repo: "test/test",
|
Repo: "test/test",
|
||||||
}, true)
|
}, true)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "https://localhost/test/test/compare/1.0.0...1.0.1", client.GetCompareURL("1.0.0", "1.0.1"))
|
assert.Equal(t, "https://127.0.0.1/test/test/compare/1.0.0...1.0.1", client.GetCompareURL("1.0.0", "1.0.1"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateConfig_EmptyRepro(t *testing.T) {
|
func TestValidateConfig_EmptyRepro(t *testing.T) {
|
||||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||||
_, err := New(&config.GitLabProvider{
|
_, err := New(&config.GitLabProvider{
|
||||||
CustomURL: "https://localhost/",
|
CustomURL: "https://127.0.0.1/",
|
||||||
}, true)
|
}, true)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ func TestValidateConfig_DefaultURL(t *testing.T) {
|
|||||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||||
config := &config.GitLabProvider{
|
config := &config.GitLabProvider{
|
||||||
Repo: "localhost/test",
|
Repo: "127.0.0.1/test",
|
||||||
}
|
}
|
||||||
_, err := New(config, true)
|
_, err := New(config, true)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -64,13 +64,13 @@ func TestValidateConfig_CustomURL(t *testing.T) {
|
|||||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||||
config := &config.GitLabProvider{
|
config := &config.GitLabProvider{
|
||||||
Repo: "/localhost/test/",
|
Repo: "/127.0.0.1/test/",
|
||||||
CustomURL: "https://localhost/",
|
CustomURL: "https://127.0.0.1/",
|
||||||
}
|
}
|
||||||
_, err := New(config, true)
|
_, err := New(config, true)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "https://localhost", config.CustomURL)
|
assert.Equal(t, "https://127.0.0.1", config.CustomURL)
|
||||||
assert.Equal(t, "localhost/test", config.Repo)
|
assert.Equal(t, "127.0.0.1/test", config.Repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateRelease(t *testing.T) {
|
func TestCreateRelease(t *testing.T) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/Nightapes/go-semantic-release/internal/assets"
|
"github.com/Nightapes/go-semantic-release/internal/assets"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/releaser/git"
|
"github.com/Nightapes/go-semantic-release/internal/releaser/git"
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/releaser/gitea"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/releaser/github"
|
"github.com/Nightapes/go-semantic-release/internal/releaser/github"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/releaser/gitlab"
|
"github.com/Nightapes/go-semantic-release/internal/releaser/gitlab"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||||
@@ -35,7 +36,7 @@ func New(c *config.ReleaseConfig, git *gitutil.GitUtil) *Releasers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetReleaser returns an initialized releaser
|
// GetReleaser returns an initialized releaser
|
||||||
func (r *Releasers) GetReleaser(checkConfig bool) (Releaser, error) {
|
func (r *Releasers) GetReleaser(checkConfig bool) (Releaser, error) {
|
||||||
switch r.config.Release {
|
switch r.config.Release {
|
||||||
case github.GITHUB:
|
case github.GITHUB:
|
||||||
@@ -44,6 +45,9 @@ func (r *Releasers) GetReleaser(checkConfig bool) (Releaser, error) {
|
|||||||
case gitlab.GITLAB:
|
case gitlab.GITLAB:
|
||||||
log.Debugf("initialize new %s-provider", gitlab.GITLAB)
|
log.Debugf("initialize new %s-provider", gitlab.GITLAB)
|
||||||
return gitlab.New(&r.config.GitLabProvider, checkConfig)
|
return gitlab.New(&r.config.GitLabProvider, checkConfig)
|
||||||
|
case gitea.GITEA:
|
||||||
|
log.Debugf("initialize new %s-provider", gitea.GITEA)
|
||||||
|
return gitea.New(&r.config.GiteaProvider, checkConfig)
|
||||||
case git.GITONLY:
|
case git.GITONLY:
|
||||||
log.Debugf("initialize new %s-provider", git.GITONLY)
|
log.Debugf("initialize new %s-provider", git.GITONLY)
|
||||||
return git.New(&r.config.GitProvider, r.git, checkConfig)
|
return git.New(&r.config.GitProvider, r.git, checkConfig)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func TestIsValidResult(t *testing.T) {
|
|||||||
assert.NoError(t, util.IsValidResult(&http.Response{StatusCode: 202}))
|
assert.NoError(t, util.IsValidResult(&http.Response{StatusCode: 202}))
|
||||||
assert.NoError(t, util.IsValidResult(&http.Response{StatusCode: 204}))
|
assert.NoError(t, util.IsValidResult(&http.Response{StatusCode: 204}))
|
||||||
|
|
||||||
u, err := url.Parse("https://localhost")
|
u, err := url.Parse("https://127.0.0.1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Error(t, util.IsValidResult(&http.Response{StatusCode: 500, Request: &http.Request{
|
assert.Error(t, util.IsValidResult(&http.Response{StatusCode: 500, Request: &http.Request{
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
|
|||||||
@@ -35,21 +35,21 @@ type ChangelogTemplateConfig struct {
|
|||||||
|
|
||||||
//AnalyzedCommit struct
|
//AnalyzedCommit struct
|
||||||
type AnalyzedCommit struct {
|
type AnalyzedCommit struct {
|
||||||
Commit Commit `yaml:"commit"`
|
Commit Commit `yaml:"commit"`
|
||||||
ParsedMessage string `yaml:"parsedMessage"`
|
ParsedMessage string `yaml:"parsedMessage"`
|
||||||
ParsedBreakingChangeMessage string `yaml:"parsedBreakingChangeMessage"`
|
ParsedBreakingChangeMessage string `yaml:"parsedBreakingChangeMessage"`
|
||||||
Tag string `yaml:"tag"`
|
Tag string `yaml:"tag"`
|
||||||
TagString string `yaml:"tagString"`
|
TagString string `yaml:"tagString"`
|
||||||
Scope Scope `yaml:"scope"`
|
Scope Scope `yaml:"scope"`
|
||||||
Subject string `yaml:"subject"`
|
Subject string `yaml:"subject"`
|
||||||
MessageBlocks map[string][]MessageBlock `yaml:"messageBlocks"`
|
MessageBlocks map[string][]MessageBlock `yaml:"messageBlocks"`
|
||||||
IsBreaking bool `yaml:"isBreaking"`
|
IsBreaking bool `yaml:"isBreaking"`
|
||||||
Print bool `yaml:"print"`
|
Print bool `yaml:"print"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageBlock represents a block in the body section of a commit message
|
// MessageBlock represents a block in the body section of a commit message
|
||||||
type MessageBlock struct {
|
type MessageBlock struct {
|
||||||
Label string `yaml:"label"`
|
Label string `yaml:"label"`
|
||||||
Content string `yaml:"content"`
|
Content string `yaml:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,26 +20,28 @@ type AnalyzerConfig struct {
|
|||||||
|
|
||||||
// ChangelogConfig struct
|
// ChangelogConfig struct
|
||||||
type ChangelogConfig struct {
|
type ChangelogConfig struct {
|
||||||
PrintAll bool `yaml:"printAll,omitempty"`
|
PrintAll bool `yaml:"printAll,omitempty"`
|
||||||
TemplateTitle string `yaml:"title,omitempty"`
|
TemplateTitle string `yaml:"title,omitempty"`
|
||||||
TemplatePath string `yaml:"templatePath,omitempty"`
|
TemplatePath string `yaml:"templatePath,omitempty"`
|
||||||
Docker ChangelogDocker `yaml:"docker,omitempty"`
|
ShowBodyAsHeader bool `yaml:"showBodyAsHeader,omitempty"`
|
||||||
NPM ChangelogNPM `yaml:"npm,omitempty"`
|
ShowAuthors bool `yaml:"showAuthors,omitempty"`
|
||||||
|
Docker ChangelogDocker `yaml:"docker,omitempty"`
|
||||||
|
NPM ChangelogNPM `yaml:"npm,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//ChangelogDocker type struct
|
// ChangelogDocker type struct
|
||||||
type ChangelogDocker struct {
|
type ChangelogDocker struct {
|
||||||
Latest bool `yaml:"latest"`
|
Latest bool `yaml:"latest"`
|
||||||
Repository string `yaml:"repository"`
|
Repository string `yaml:"repository"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//ChangelogNPM type struct
|
// ChangelogNPM type struct
|
||||||
type ChangelogNPM struct {
|
type ChangelogNPM struct {
|
||||||
YARN bool `yaml:"latest"`
|
Repository string `yaml:"repository"`
|
||||||
Repository string `yaml:"repository"`
|
PackageName string `yaml:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Asset type struct
|
// Asset type struct
|
||||||
type Asset struct {
|
type Asset struct {
|
||||||
Path string `yaml:"path"`
|
Path string `yaml:"path"`
|
||||||
Rename string `yaml:"rename,omitempty"`
|
Rename string `yaml:"rename,omitempty"`
|
||||||
@@ -56,6 +58,15 @@ type GitHubProvider struct {
|
|||||||
TagPrefix *string `yaml:"tagPrefix,omitempty"`
|
TagPrefix *string `yaml:"tagPrefix,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GiteaProvider struct
|
||||||
|
type GiteaProvider struct {
|
||||||
|
Repo string `yaml:"repo"`
|
||||||
|
User string `yaml:"user"`
|
||||||
|
URL string `yaml:"url,omitempty"`
|
||||||
|
AccessToken string
|
||||||
|
TagPrefix *string `yaml:"tagPrefix,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// GitLabProvider struct
|
// GitLabProvider struct
|
||||||
type GitLabProvider struct {
|
type GitLabProvider struct {
|
||||||
Repo string `yaml:"repo"`
|
Repo string `yaml:"repo"`
|
||||||
@@ -66,11 +77,11 @@ type GitLabProvider struct {
|
|||||||
|
|
||||||
// GitProvider struct
|
// GitProvider struct
|
||||||
type GitProvider struct {
|
type GitProvider struct {
|
||||||
Email string `yaml:"email"`
|
Email string `yaml:"email"`
|
||||||
Username string `yaml:"user"`
|
Username string `yaml:"user"`
|
||||||
Auth string `yaml:"auth"`
|
Auth string `yaml:"auth"`
|
||||||
SSH bool `yaml:"ssh"`
|
SSH bool `yaml:"ssh"`
|
||||||
TagPrefix *string `yaml:"tagPrefix,omitempty"`
|
TagPrefix *string `yaml:"tagPrefix,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooks struct
|
// Hooks struct
|
||||||
@@ -84,19 +95,32 @@ type Checksum struct {
|
|||||||
Algorithm string `yaml:"algorithm"`
|
Algorithm string `yaml:"algorithm"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checksum struct
|
||||||
|
type Integrations struct {
|
||||||
|
NPM IntegrationNPM `yaml:"npm"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checksum struct
|
||||||
|
type IntegrationNPM struct {
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
Path string `yaml:"path"`
|
||||||
|
}
|
||||||
|
|
||||||
// ReleaseConfig struct
|
// ReleaseConfig struct
|
||||||
type ReleaseConfig struct {
|
type ReleaseConfig struct {
|
||||||
CommitFormat string `yaml:"commitFormat"`
|
CommitFormat string `yaml:"commitFormat"`
|
||||||
Branch map[string]string `yaml:"branch"`
|
Branch map[string]string `yaml:"branch"`
|
||||||
Analyzer AnalyzerConfig `yaml:"analyzer"`
|
Analyzer AnalyzerConfig `yaml:"analyzer"`
|
||||||
Changelog ChangelogConfig `yaml:"changelog,omitempty"`
|
Changelog ChangelogConfig `yaml:"changelog,omitempty"`
|
||||||
Release string `yaml:"release,omitempty"`
|
Release string `yaml:"release,omitempty"`
|
||||||
|
GiteaProvider GiteaProvider `yaml:"gitea,omitempty"`
|
||||||
GitHubProvider GitHubProvider `yaml:"github,omitempty"`
|
GitHubProvider GitHubProvider `yaml:"github,omitempty"`
|
||||||
GitLabProvider GitLabProvider `yaml:"gitlab,omitempty"`
|
GitLabProvider GitLabProvider `yaml:"gitlab,omitempty"`
|
||||||
GitProvider GitProvider `yaml:"git,omitempty"`
|
GitProvider GitProvider `yaml:"git,omitempty"`
|
||||||
Assets []Asset `yaml:"assets"`
|
Assets []Asset `yaml:"assets"`
|
||||||
Checksum Checksum `yaml:"checksum,omitempty"`
|
Checksum Checksum `yaml:"checksum,omitempty"`
|
||||||
Hooks Hooks `yaml:"hooks"`
|
Hooks Hooks `yaml:"hooks"`
|
||||||
|
Integrations Integrations `yaml:"integrations"`
|
||||||
ReleaseTitle string `yaml:"title"`
|
ReleaseTitle string `yaml:"title"`
|
||||||
IsPreRelease bool
|
IsPreRelease bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
package semanticrelease
|
package semanticrelease
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"fmt"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/integrations"
|
||||||
|
|
||||||
"github.com/Masterminds/semver"
|
"github.com/Masterminds/semver"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
@@ -73,9 +79,9 @@ func (s *SemanticRelease) GetCIProvider() (*ci.ProviderConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetNextVersion from .version or calculate new from commits
|
// GetNextVersion from .version or calculate new from commits
|
||||||
func (s *SemanticRelease) GetNextVersion(provider *ci.ProviderConfig, force bool) (*shared.ReleaseVersion, error) {
|
func (s *SemanticRelease) GetNextVersion(provider *ci.ProviderConfig, force bool, from string) (*shared.ReleaseVersion, error) {
|
||||||
log.Debugf("Ignore .version file if exits, %t", force)
|
log.Debugf("Ignore .version file if exits, %t", force)
|
||||||
if !force {
|
if !force && from == "" {
|
||||||
releaseVersion, err := cache.Read(s.repository)
|
releaseVersion, err := cache.Read(s.repository)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -86,9 +92,20 @@ func (s *SemanticRelease) GetNextVersion(provider *ci.ProviderConfig, force bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastVersion, lastVersionHash, err := s.gitUtil.GetLastVersion()
|
var lastVersion *semver.Version
|
||||||
if err != nil {
|
var lastVersionHash *plumbing.Reference
|
||||||
return nil, err
|
var err error
|
||||||
|
|
||||||
|
if from == "" {
|
||||||
|
lastVersion, lastVersionHash, err = s.gitUtil.GetLastVersion()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastVersion, lastVersionHash, err = s.gitUtil.GetVersion(from)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firstRelease := false
|
firstRelease := false
|
||||||
@@ -101,7 +118,7 @@ func (s *SemanticRelease) GetNextVersion(provider *ci.ProviderConfig, force bool
|
|||||||
|
|
||||||
commits, err := s.gitUtil.GetCommits(lastVersionHash)
|
commits, err := s.gitUtil.GetCommits(lastVersionHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("could not get commits %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Found %d commits till last release", len(commits))
|
log.Debugf("Found %d commits till last release", len(commits))
|
||||||
@@ -130,12 +147,15 @@ func (s *SemanticRelease) GetNextVersion(provider *ci.ProviderConfig, force bool
|
|||||||
Version: &newVersion,
|
Version: &newVersion,
|
||||||
},
|
},
|
||||||
Last: shared.ReleaseVersionEntry{
|
Last: shared.ReleaseVersionEntry{
|
||||||
Commit: lastVersionHash,
|
Commit: "",
|
||||||
Version: lastVersion,
|
Version: lastVersion,
|
||||||
},
|
},
|
||||||
Branch: provider.Branch,
|
Branch: provider.Branch,
|
||||||
Commits: analyzedCommits,
|
Commits: analyzedCommits,
|
||||||
}
|
}
|
||||||
|
if lastVersionHash != nil {
|
||||||
|
releaseVersion.Last.Commit = lastVersionHash.Hash().String()
|
||||||
|
}
|
||||||
|
|
||||||
if firstRelease {
|
if firstRelease {
|
||||||
releaseVersion.Last.Version, _ = semver.NewVersion("0.0.0")
|
releaseVersion.Last.Version, _ = semver.NewVersion("0.0.0")
|
||||||
@@ -170,7 +190,7 @@ func (s *SemanticRelease) SetVersion(provider *ci.ProviderConfig, version string
|
|||||||
Version: newVersion,
|
Version: newVersion,
|
||||||
},
|
},
|
||||||
Last: shared.ReleaseVersionEntry{
|
Last: shared.ReleaseVersionEntry{
|
||||||
Commit: lastVersionHash,
|
Commit: lastVersionHash.Hash().String(),
|
||||||
Version: lastVersion,
|
Version: lastVersion,
|
||||||
},
|
},
|
||||||
Branch: provider.Branch,
|
Branch: provider.Branch,
|
||||||
@@ -189,8 +209,81 @@ func (s *SemanticRelease) GetChangelog(releaseVersion *shared.ReleaseVersion) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteChangeLog writes changelog content to the given file
|
// WriteChangeLog writes changelog content to the given file
|
||||||
func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error {
|
func (s *SemanticRelease) WriteChangeLog(changelogContent, file string, overwrite bool, maxChangelogFileSize int64) error {
|
||||||
return ioutil.WriteFile(file, []byte(changelogContent), 0644)
|
info, err := os.Stat(file)
|
||||||
|
if overwrite || err != nil {
|
||||||
|
return os.WriteFile(file, []byte(changelogContent), 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytesToMB(info.Size()) >= float64(maxChangelogFileSize) {
|
||||||
|
err := moveExistingChangelogFile(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prependToFile(changelogContent, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bytesToMB(bytes int64) float64 {
|
||||||
|
return float64(bytes) / 1024 / 1024 / 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
func moveExistingChangelogFile(file string) error {
|
||||||
|
filenameSeparated := strings.Split(filepath.Base(file), ".")
|
||||||
|
|
||||||
|
// check if file had several "." included.
|
||||||
|
// if yes the filename will be separated like this: "my.file.name", ".md"
|
||||||
|
if len(filenameSeparated) > 2 {
|
||||||
|
separatedFilenameWithExtension := make([]string, 0)
|
||||||
|
separatedFilenameWithExtension = append(separatedFilenameWithExtension, strings.Join(filenameSeparated[:len(filenameSeparated)-1], "."))
|
||||||
|
separatedFilenameWithExtension = append(separatedFilenameWithExtension, filenameSeparated[len(filenameSeparated)-1])
|
||||||
|
filenameSeparated = separatedFilenameWithExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
var newFileName string
|
||||||
|
counter := 1
|
||||||
|
for {
|
||||||
|
newFileName = buildNewFileName(filenameSeparated, counter)
|
||||||
|
if _, err := os.Stat(newFileName); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := os.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(newFileName, content, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = os.Create(file)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildNewFileName(currentFileNameSeparated []string, counter int) string {
|
||||||
|
if len(currentFileNameSeparated) == 1 {
|
||||||
|
return fmt.Sprintf("%s-%d", currentFileNameSeparated[0], counter)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileNameWithoutExtension := strings.Join(currentFileNameSeparated[:len(currentFileNameSeparated)-1], ".")
|
||||||
|
fileExtension := currentFileNameSeparated[len(currentFileNameSeparated)-1]
|
||||||
|
return fmt.Sprintf("%s-%d.%s", fileNameWithoutExtension, counter, fileExtension)
|
||||||
|
}
|
||||||
|
|
||||||
|
func prependToFile(newChangelogContent, file string) error {
|
||||||
|
currentContent, err := os.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
content := make([]byte, 0)
|
||||||
|
content = append(content, []byte(newChangelogContent)...)
|
||||||
|
content = append(content, []byte("\n---\n\n")...)
|
||||||
|
content = append(content, currentContent...)
|
||||||
|
return os.WriteFile(file, content, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release publish release to provider
|
// Release publish release to provider
|
||||||
@@ -209,7 +302,7 @@ func (s *SemanticRelease) Release(provider *ci.ProviderConfig, force bool) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseVersion, err := s.GetNextVersion(provider, force)
|
releaseVersion, err := s.GetNextVersion(provider, force, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("Could not get next version")
|
log.Debugf("Could not get next version")
|
||||||
return err
|
return err
|
||||||
@@ -226,6 +319,12 @@ func (s *SemanticRelease) Release(provider *ci.ProviderConfig, force bool) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
integrations := integrations.New(&s.config.Integrations, releaseVersion)
|
||||||
|
if err := integrations.Run(); err != nil {
|
||||||
|
log.Debugf("Error during integrations run")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
hook := hooks.New(s.config, releaseVersion)
|
hook := hooks.New(s.config, releaseVersion)
|
||||||
if err := hook.PreRelease(); err != nil {
|
if err := hook.PreRelease(); err != nil {
|
||||||
log.Debugf("Error during pre release hook")
|
log.Debugf("Error during pre release hook")
|
||||||
|
|||||||
83
pkg/semanticrelease/semantic-release_test.go
Normal file
83
pkg/semanticrelease/semantic-release_test.go
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package semanticrelease
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSemanticRelease_WriteChangeLog(t *testing.T) {
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
changelogContent string
|
||||||
|
file string
|
||||||
|
overwrite bool
|
||||||
|
maxChangelogFileSize int64
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
config *config.ReleaseConfig
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "MoveExisting",
|
||||||
|
args: args{
|
||||||
|
changelogContent: "go-semantic-release-rocks!",
|
||||||
|
file: "test1.changelog.md",
|
||||||
|
overwrite: false,
|
||||||
|
maxChangelogFileSize: 0,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ValidWithOverwrite",
|
||||||
|
args: args{
|
||||||
|
changelogContent: "go-semantic-release-rocks!",
|
||||||
|
file: "test2.changelog.md",
|
||||||
|
overwrite: true,
|
||||||
|
maxChangelogFileSize: 0,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := os.Create(tt.args.file)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
releaser := &SemanticRelease{}
|
||||||
|
if err := releaser.WriteChangeLog(tt.args.changelogContent, tt.args.file, tt.args.overwrite, tt.args.maxChangelogFileSize); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("WriteChangeLog() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
name := strings.Join(strings.Split(tt.args.file, ".")[:len(strings.Split(tt.args.file, "."))-1], ".")
|
||||||
|
|
||||||
|
files, err := filepath.Glob("./" + name + "*")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.wantErr && !tt.args.overwrite && tt.args.maxChangelogFileSize == 0 && len(files) <= 1 {
|
||||||
|
t.Errorf("WriteChangelog() = should create a copy of the existing changelog file")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.wantErr && tt.args.overwrite && len(files) > 1 {
|
||||||
|
t.Errorf("WriteChangelog() = should not create a copy of the changelog file")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, i := range files {
|
||||||
|
err := os.Remove(i)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
85
scripts/commit-filter-check.sh
Executable file
85
scripts/commit-filter-check.sh
Executable file
@@ -0,0 +1,85 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
commit_message_check (){
|
||||||
|
# Get the current branch and apply it to a variable
|
||||||
|
currentbranch=`git branch | grep \* | cut -d ' ' -f2`
|
||||||
|
|
||||||
|
# Gets the commits for the current branch and outputs to file
|
||||||
|
git log $currentbranch --pretty=format:"%H" --not master > shafile.txt
|
||||||
|
|
||||||
|
# loops through the file an gets the message
|
||||||
|
for i in `cat ./shafile.txt`;
|
||||||
|
do
|
||||||
|
# gets the git commit message based on the sha
|
||||||
|
gitmessage=`git log --format=%B -n 1 "$i"`
|
||||||
|
|
||||||
|
####################### TEST STRINGS comment out line 13 to use #########################################
|
||||||
|
#gitmessage="feat sdasdsadsaas (AEROGEAR-asdsada)"
|
||||||
|
#gitmessage="feat(some txt): some txt (AEROGEAR-****)"
|
||||||
|
#gitmessage="docs(some txt): some txt (AEROGEAR-1234)"
|
||||||
|
#gitmessage="fix(some txt): some txt (AEROGEAR-5678)"
|
||||||
|
#########################################################################################################
|
||||||
|
|
||||||
|
# Checks gitmessage for string feat, fix, docs and breaking, if the messagecheck var is empty if fails
|
||||||
|
messagecheck=`echo $gitmessage | grep -w "chore\|feat\|fix\|docs\|breaking"`
|
||||||
|
if [ -z "$messagecheck" ]
|
||||||
|
then
|
||||||
|
echo "Your commit message must begin with one of the following"
|
||||||
|
echo " feat(feature-name)"
|
||||||
|
echo " fix(fix-name)"
|
||||||
|
echo " docs(docs-change)"
|
||||||
|
echo " "
|
||||||
|
fi
|
||||||
|
if [ ${PerformProjectCheck} == "true" ]; then
|
||||||
|
#check the gitmessage for the Jira number
|
||||||
|
messagecheck=`echo $gitmessage | grep "(${ProjectID}-"`
|
||||||
|
if [ -z "$messagecheck" ]
|
||||||
|
then
|
||||||
|
echo "Your commit message must end with the following"
|
||||||
|
echo " (${ProjectID}-****)"
|
||||||
|
echo "Where **** is the Jira number"
|
||||||
|
echo " "
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
messagecheck=`echo $gitmessage | grep ": "`
|
||||||
|
if [ -z "$messagecheck" ]
|
||||||
|
then
|
||||||
|
echo "Your commit message has a formatting error please take note of special characters '():' position and use in the example below"
|
||||||
|
echo " type(some txt): some txt (${ProjectID}-****)"
|
||||||
|
echo "Where 'type' is fix, feat, docs or breaking and **** is the Jira number"
|
||||||
|
echo " "
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ${PerformProjectCheck} == "true" ]; then
|
||||||
|
# All checks run at the same time by pipeing from one grep to another
|
||||||
|
messagecheck=`echo $gitmessage | grep -w "chore\|feat\|fix\|docs\|breaking" | grep "(${ProjectID}-" | grep ": "`
|
||||||
|
else
|
||||||
|
# All checks run at the same time by pipeing from one grep to another
|
||||||
|
messagecheck=`echo $gitmessage | grep -w "chore\|feat\|fix\|docs\|breaking" | grep ": "`
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# check to see if the messagecheck var is empty
|
||||||
|
if [ -z "$messagecheck" ]
|
||||||
|
then
|
||||||
|
echo "The commit message with sha: '$i' failed "
|
||||||
|
echo "Please review the following :"
|
||||||
|
echo " "
|
||||||
|
echo $gitmessage
|
||||||
|
echo " "
|
||||||
|
rm shafile.txt >/dev/null 2>&1
|
||||||
|
set -o errexit
|
||||||
|
else
|
||||||
|
echo "$messagecheck"
|
||||||
|
echo "'$i' commit message passed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
rm shafile.txt >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ProjectID="NA" # Set to your Jira Project ID if want to track references to tickets.
|
||||||
|
PerformProjectCheck="false" # Set true if ProjectID is set and you want to ensure Jira ref is included on commit.
|
||||||
|
# Calling the function
|
||||||
|
commit_message_check
|
||||||
20
vendor/code.gitea.io/sdk/gitea/LICENSE
generated
vendored
Normal file
20
vendor/code.gitea.io/sdk/gitea/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Copyright (c) 2016 The Gitea Authors
|
||||||
|
Copyright (c) 2014 The Gogs Authors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
47
vendor/code.gitea.io/sdk/gitea/admin_cron.go
generated
vendored
Normal file
47
vendor/code.gitea.io/sdk/gitea/admin_cron.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CronTask represents a Cron task
|
||||||
|
type CronTask struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Schedule string `json:"schedule"`
|
||||||
|
Next time.Time `json:"next"`
|
||||||
|
Prev time.Time `json:"prev"`
|
||||||
|
ExecTimes int64 `json:"exec_times"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCronTaskOptions list options for ListCronTasks
|
||||||
|
type ListCronTaskOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCronTasks list available cron tasks
|
||||||
|
func (c *Client) ListCronTasks(opt ListCronTaskOptions) ([]*CronTask, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
ct := make([]*CronTask, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/admin/cron?%s", opt.getURLQuery().Encode()), jsonHeader, nil, &ct)
|
||||||
|
return ct, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunCronTasks run a cron task
|
||||||
|
func (c *Client) RunCronTasks(task string) (*Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&task); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("POST", fmt.Sprintf("/admin/cron/%s", task), jsonHeader, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
39
vendor/code.gitea.io/sdk/gitea/admin_org.go
generated
vendored
Normal file
39
vendor/code.gitea.io/sdk/gitea/admin_org.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AdminListOrgsOptions options for listing admin's organizations
|
||||||
|
type AdminListOrgsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminListOrgs lists all orgs
|
||||||
|
func (c *Client) AdminListOrgs(opt AdminListOrgsOptions) ([]*Organization, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
orgs := make([]*Organization, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/admin/orgs?%s", opt.getURLQuery().Encode()), nil, nil, &orgs)
|
||||||
|
return orgs, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminCreateOrg create an organization
|
||||||
|
func (c *Client) AdminCreateOrg(user string, opt CreateOrgOption) (*Organization, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
org := new(Organization)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/orgs", user), jsonHeader, bytes.NewReader(body), org)
|
||||||
|
return org, resp, err
|
||||||
|
}
|
||||||
25
vendor/code.gitea.io/sdk/gitea/admin_repo.go
generated
vendored
Normal file
25
vendor/code.gitea.io/sdk/gitea/admin_repo.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AdminCreateRepo create a repo
|
||||||
|
func (c *Client) AdminCreateRepo(user string, opt CreateRepoOption) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/repos", user), jsonHeader, bytes.NewReader(body), repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
130
vendor/code.gitea.io/sdk/gitea/admin_user.go
generated
vendored
Normal file
130
vendor/code.gitea.io/sdk/gitea/admin_user.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AdminListUsersOptions options for listing admin users
|
||||||
|
type AdminListUsersOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminListUsers lists all users
|
||||||
|
func (c *Client) AdminListUsers(opt AdminListUsersOptions) ([]*User, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
users := make([]*User, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/admin/users?%s", opt.getURLQuery().Encode()), nil, nil, &users)
|
||||||
|
return users, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateUserOption create user options
|
||||||
|
type CreateUserOption struct {
|
||||||
|
SourceID int64 `json:"source_id"`
|
||||||
|
LoginName string `json:"login_name"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
MustChangePassword *bool `json:"must_change_password"`
|
||||||
|
SendNotify bool `json:"send_notify"`
|
||||||
|
Visibility *VisibleType `json:"visibility"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateUserOption struct
|
||||||
|
func (opt CreateUserOption) Validate() error {
|
||||||
|
if len(opt.Email) == 0 {
|
||||||
|
return fmt.Errorf("email is empty")
|
||||||
|
}
|
||||||
|
if len(opt.Username) == 0 {
|
||||||
|
return fmt.Errorf("username is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminCreateUser create a user
|
||||||
|
func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, *Response, error) {
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
user := new(User)
|
||||||
|
resp, err := c.getParsedResponse("POST", "/admin/users", jsonHeader, bytes.NewReader(body), user)
|
||||||
|
return user, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditUserOption edit user options
|
||||||
|
type EditUserOption struct {
|
||||||
|
SourceID int64 `json:"source_id"`
|
||||||
|
LoginName string `json:"login_name"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
FullName *string `json:"full_name"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Description *string `json:"description"`
|
||||||
|
MustChangePassword *bool `json:"must_change_password"`
|
||||||
|
Website *string `json:"website"`
|
||||||
|
Location *string `json:"location"`
|
||||||
|
Active *bool `json:"active"`
|
||||||
|
Admin *bool `json:"admin"`
|
||||||
|
AllowGitHook *bool `json:"allow_git_hook"`
|
||||||
|
AllowImportLocal *bool `json:"allow_import_local"`
|
||||||
|
MaxRepoCreation *int `json:"max_repo_creation"`
|
||||||
|
ProhibitLogin *bool `json:"prohibit_login"`
|
||||||
|
AllowCreateOrganization *bool `json:"allow_create_organization"`
|
||||||
|
Restricted *bool `json:"restricted"`
|
||||||
|
Visibility *VisibleType `json:"visibility"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminEditUser modify user informations
|
||||||
|
func (c *Client) AdminEditUser(user string, opt EditUserOption) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PATCH", fmt.Sprintf("/admin/users/%s", user), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminDeleteUser delete one user according name
|
||||||
|
func (c *Client) AdminDeleteUser(user string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s", user), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminCreateUserPublicKey adds a public key for the user
|
||||||
|
func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*PublicKey, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
key := new(PublicKey)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/keys", user), jsonHeader, bytes.NewReader(body), key)
|
||||||
|
return key, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminDeleteUserPublicKey deletes a user's public key
|
||||||
|
func (c *Client) AdminDeleteUserPublicKey(user string, keyID int) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s/keys/%d", user, keyID), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
38
vendor/code.gitea.io/sdk/gitea/agent.go
generated
vendored
Normal file
38
vendor/code.gitea.io/sdk/gitea/agent.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh/agent"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hasAgent returns true if the ssh agent is available
|
||||||
|
func hasAgent() bool {
|
||||||
|
if _, err := os.Stat(os.Getenv("SSH_AUTH_SOCK")); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAgent returns a ssh agent
|
||||||
|
func GetAgent() (agent.Agent, error) {
|
||||||
|
if !hasAgent() {
|
||||||
|
return nil, fmt.Errorf("no ssh agent available")
|
||||||
|
}
|
||||||
|
|
||||||
|
sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return agent.NewClient(sshAgent), nil
|
||||||
|
}
|
||||||
28
vendor/code.gitea.io/sdk/gitea/agent_windows.go
generated
vendored
Normal file
28
vendor/code.gitea.io/sdk/gitea/agent_windows.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/davidmz/go-pageant"
|
||||||
|
"golang.org/x/crypto/ssh/agent"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hasAgent returns true if pageant is available
|
||||||
|
func hasAgent() bool {
|
||||||
|
return pageant.Available()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAgent returns a ssh agent
|
||||||
|
func GetAgent() (agent.Agent, error) {
|
||||||
|
if !hasAgent() {
|
||||||
|
return nil, fmt.Errorf("no pageant available")
|
||||||
|
}
|
||||||
|
|
||||||
|
return pageant.New(), nil
|
||||||
|
}
|
||||||
111
vendor/code.gitea.io/sdk/gitea/attachment.go
generated
vendored
Normal file
111
vendor/code.gitea.io/sdk/gitea/attachment.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea // import "code.gitea.io/sdk/gitea"
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"mime/multipart"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Attachment a generic attachment
|
||||||
|
type Attachment struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
DownloadCount int64 `json:"download_count"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
DownloadURL string `json:"browser_download_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListReleaseAttachmentsOptions options for listing release's attachments
|
||||||
|
type ListReleaseAttachmentsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListReleaseAttachments list release's attachments
|
||||||
|
func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt ListReleaseAttachmentsOptions) ([]*Attachment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
attachments := make([]*Attachment, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/%d/assets?%s", user, repo, release, opt.getURLQuery().Encode()),
|
||||||
|
nil, nil, &attachments)
|
||||||
|
return attachments, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReleaseAttachment returns the requested attachment
|
||||||
|
func (c *Client) GetReleaseAttachment(user, repo string, release, id int64) (*Attachment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
a := new(Attachment)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id),
|
||||||
|
nil, nil, &a)
|
||||||
|
return a, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateReleaseAttachment creates an attachment for the given release
|
||||||
|
func (c *Client) CreateReleaseAttachment(user, repo string, release int64, file io.Reader, filename string) (*Attachment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
// Write file to body
|
||||||
|
body := new(bytes.Buffer)
|
||||||
|
writer := multipart.NewWriter(body)
|
||||||
|
part, err := writer.CreateFormFile("attachment", filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = io.Copy(part, file); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err = writer.Close(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send request
|
||||||
|
attachment := new(Attachment)
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/%d/assets", user, repo, release),
|
||||||
|
http.Header{"Content-Type": {writer.FormDataContentType()}}, body, &attachment)
|
||||||
|
return attachment, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditAttachmentOptions options for editing attachments
|
||||||
|
type EditAttachmentOptions struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditReleaseAttachment updates the given attachment with the given options
|
||||||
|
func (c *Client) EditReleaseAttachment(user, repo string, release, attachment int64, form EditAttachmentOptions) (*Attachment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
attach := new(Attachment)
|
||||||
|
resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, attachment), jsonHeader, bytes.NewReader(body), attach)
|
||||||
|
return attach, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteReleaseAttachment deletes the given attachment including the uploaded file
|
||||||
|
func (c *Client) DeleteReleaseAttachment(user, repo string, release, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
499
vendor/code.gitea.io/sdk/gitea/client.go
generated
vendored
Normal file
499
vendor/code.gitea.io/sdk/gitea/client.go
generated
vendored
Normal file
@@ -0,0 +1,499 @@
|
|||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-version"
|
||||||
|
)
|
||||||
|
|
||||||
|
var jsonHeader = http.Header{"content-type": []string{"application/json"}}
|
||||||
|
|
||||||
|
// Version return the library version
|
||||||
|
func Version() string {
|
||||||
|
return "0.16.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client represents a thread-safe Gitea API client.
|
||||||
|
type Client struct {
|
||||||
|
url string
|
||||||
|
accessToken string
|
||||||
|
username string
|
||||||
|
password string
|
||||||
|
otp string
|
||||||
|
sudo string
|
||||||
|
userAgent string
|
||||||
|
debug bool
|
||||||
|
httpsigner *HTTPSign
|
||||||
|
client *http.Client
|
||||||
|
ctx context.Context
|
||||||
|
mutex sync.RWMutex
|
||||||
|
serverVersion *version.Version
|
||||||
|
getVersionOnce sync.Once
|
||||||
|
ignoreVersion bool // only set by SetGiteaVersion so don't need a mutex lock
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response represents the gitea response
|
||||||
|
type Response struct {
|
||||||
|
*http.Response
|
||||||
|
|
||||||
|
FirstPage int
|
||||||
|
PrevPage int
|
||||||
|
NextPage int
|
||||||
|
LastPage int
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientOption are functions used to init a new client
|
||||||
|
type ClientOption func(*Client) error
|
||||||
|
|
||||||
|
// NewClient initializes and returns a API client.
|
||||||
|
// Usage of all gitea.Client methods is concurrency-safe.
|
||||||
|
func NewClient(url string, options ...ClientOption) (*Client, error) {
|
||||||
|
client := &Client{
|
||||||
|
url: strings.TrimSuffix(url, "/"),
|
||||||
|
client: &http.Client{},
|
||||||
|
ctx: context.Background(),
|
||||||
|
}
|
||||||
|
for _, opt := range options {
|
||||||
|
if err := opt(client); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := client.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||||
|
if errors.Is(err, &ErrUnknownVersion{}) {
|
||||||
|
return client, err
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClientWithHTTP creates an API client with a custom http client
|
||||||
|
// Deprecated use SetHTTPClient option
|
||||||
|
func NewClientWithHTTP(url string, httpClient *http.Client) *Client {
|
||||||
|
client, _ := NewClient(url, SetHTTPClient(httpClient))
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetHTTPClient is an option for NewClient to set custom http client
|
||||||
|
func SetHTTPClient(httpClient *http.Client) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.SetHTTPClient(httpClient)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetHTTPClient replaces default http.Client with user given one.
|
||||||
|
func (c *Client) SetHTTPClient(client *http.Client) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.client = client
|
||||||
|
c.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetToken is an option for NewClient to set token
|
||||||
|
func SetToken(token string) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.mutex.Lock()
|
||||||
|
client.accessToken = token
|
||||||
|
client.mutex.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBasicAuth is an option for NewClient to set username and password
|
||||||
|
func SetBasicAuth(username, password string) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.SetBasicAuth(username, password)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseSSHCert is an option for NewClient to enable SSH certificate authentication via HTTPSign
|
||||||
|
// If you want to auth against the ssh-agent you'll need to set a principal, if you want to
|
||||||
|
// use a file on disk you'll need to specify sshKey.
|
||||||
|
// If you have an encrypted sshKey you'll need to also set the passphrase.
|
||||||
|
func UseSSHCert(principal, sshKey, passphrase string) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
if err := client.checkServerVersionGreaterThanOrEqual(version1_17_0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client.mutex.Lock()
|
||||||
|
defer client.mutex.Unlock()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
client.httpsigner, err = NewHTTPSignWithCert(principal, sshKey, passphrase)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseSSHPubkey is an option for NewClient to enable SSH pubkey authentication via HTTPSign
|
||||||
|
// If you want to auth against the ssh-agent you'll need to set a fingerprint, if you want to
|
||||||
|
// use a file on disk you'll need to specify sshKey.
|
||||||
|
// If you have an encrypted sshKey you'll need to also set the passphrase.
|
||||||
|
func UseSSHPubkey(fingerprint, sshKey, passphrase string) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
if err := client.checkServerVersionGreaterThanOrEqual(version1_17_0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client.mutex.Lock()
|
||||||
|
defer client.mutex.Unlock()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
client.httpsigner, err = NewHTTPSignWithPubkey(fingerprint, sshKey, passphrase)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBasicAuth sets username and password
|
||||||
|
func (c *Client) SetBasicAuth(username, password string) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.username, c.password = username, password
|
||||||
|
c.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOTP is an option for NewClient to set OTP for 2FA
|
||||||
|
func SetOTP(otp string) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.SetOTP(otp)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOTP sets OTP for 2FA
|
||||||
|
func (c *Client) SetOTP(otp string) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.otp = otp
|
||||||
|
c.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContext is an option for NewClient to set the default context
|
||||||
|
func SetContext(ctx context.Context) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.SetContext(ctx)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContext set default context witch is used for http requests
|
||||||
|
func (c *Client) SetContext(ctx context.Context) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.ctx = ctx
|
||||||
|
c.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSudo is an option for NewClient to set sudo header
|
||||||
|
func SetSudo(sudo string) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.SetSudo(sudo)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSudo sets username to impersonate.
|
||||||
|
func (c *Client) SetSudo(sudo string) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.sudo = sudo
|
||||||
|
c.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserAgent is an option for NewClient to set user-agent header
|
||||||
|
func SetUserAgent(userAgent string) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.SetUserAgent(userAgent)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserAgent sets the user-agent to send with every request.
|
||||||
|
func (c *Client) SetUserAgent(userAgent string) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.userAgent = userAgent
|
||||||
|
c.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDebugMode is an option for NewClient to enable debug mode
|
||||||
|
func SetDebugMode() ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.mutex.Lock()
|
||||||
|
client.debug = true
|
||||||
|
client.mutex.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newResponse(r *http.Response) *Response {
|
||||||
|
response := &Response{Response: r}
|
||||||
|
response.parseLinkHeader()
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Response) parseLinkHeader() {
|
||||||
|
link := r.Header.Get("Link")
|
||||||
|
if link == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
links := strings.Split(link, ",")
|
||||||
|
for _, l := range links {
|
||||||
|
u, param, ok := strings.Cut(l, ";")
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
u = strings.Trim(u, " <>")
|
||||||
|
|
||||||
|
key, value, ok := strings.Cut(strings.TrimSpace(param), "=")
|
||||||
|
if !ok || key != "rel" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
value = strings.Trim(value, "\"")
|
||||||
|
|
||||||
|
parsed, err := url.Parse(u)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
page := parsed.Query().Get("page")
|
||||||
|
if page == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch value {
|
||||||
|
case "first":
|
||||||
|
r.FirstPage, _ = strconv.Atoi(page)
|
||||||
|
case "prev":
|
||||||
|
r.PrevPage, _ = strconv.Atoi(page)
|
||||||
|
case "next":
|
||||||
|
r.NextPage, _ = strconv.Atoi(page)
|
||||||
|
case "last":
|
||||||
|
r.LastPage, _ = strconv.Atoi(page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *Response, error) {
|
||||||
|
c.mutex.RLock()
|
||||||
|
debug := c.debug
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("%s: %s\nBody: %v\n", method, c.url+path, body)
|
||||||
|
}
|
||||||
|
req, err := http.NewRequestWithContext(c.ctx, method, c.url+path, body)
|
||||||
|
|
||||||
|
client := c.client // client ref can change from this point on so safe it
|
||||||
|
c.mutex.RUnlock()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("Response: %v\n\n", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, newResponse(resp), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*Response, error) {
|
||||||
|
c.mutex.RLock()
|
||||||
|
debug := c.debug
|
||||||
|
if debug {
|
||||||
|
var bodyStr string
|
||||||
|
if body != nil {
|
||||||
|
bs, _ := io.ReadAll(body)
|
||||||
|
body = bytes.NewReader(bs)
|
||||||
|
bodyStr = string(bs)
|
||||||
|
}
|
||||||
|
fmt.Printf("%s: %s\nHeader: %v\nBody: %s\n", method, c.url+"/api/v1"+path, header, bodyStr)
|
||||||
|
}
|
||||||
|
req, err := http.NewRequestWithContext(c.ctx, method, c.url+"/api/v1"+path, body)
|
||||||
|
if err != nil {
|
||||||
|
c.mutex.RUnlock()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(c.accessToken) != 0 {
|
||||||
|
req.Header.Set("Authorization", "token "+c.accessToken)
|
||||||
|
}
|
||||||
|
if len(c.otp) != 0 {
|
||||||
|
req.Header.Set("X-GITEA-OTP", c.otp)
|
||||||
|
}
|
||||||
|
if len(c.username) != 0 {
|
||||||
|
req.SetBasicAuth(c.username, c.password)
|
||||||
|
}
|
||||||
|
if len(c.sudo) != 0 {
|
||||||
|
req.Header.Set("Sudo", c.sudo)
|
||||||
|
}
|
||||||
|
if len(c.userAgent) != 0 {
|
||||||
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := c.client // client ref can change from this point on so safe it
|
||||||
|
c.mutex.RUnlock()
|
||||||
|
|
||||||
|
for k, v := range header {
|
||||||
|
req.Header[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.httpsigner != nil {
|
||||||
|
err = c.SignRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("Response: %v\n\n", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newResponse(resp), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts a response for a HTTP status code indicating an error condition
|
||||||
|
// (non-2XX) to a well-known error value and response body. For non-problematic
|
||||||
|
// (2XX) status codes nil will be returned. Note that on a non-2XX response, the
|
||||||
|
// response body stream will have been read and, hence, is closed on return.
|
||||||
|
func statusCodeToErr(resp *Response) (body []byte, err error) {
|
||||||
|
// no error
|
||||||
|
if resp.StatusCode/100 == 2 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// error: body will be read for details
|
||||||
|
//
|
||||||
|
defer resp.Body.Close()
|
||||||
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("body read on HTTP error %d: %v", resp.StatusCode, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to unmarshal and get an error message
|
||||||
|
errMap := make(map[string]interface{})
|
||||||
|
if err = json.Unmarshal(data, &errMap); err != nil {
|
||||||
|
// when the JSON can't be parsed, data was probably empty or a
|
||||||
|
// plain string, so we try to return a helpful error anyway
|
||||||
|
path := resp.Request.URL.Path
|
||||||
|
method := resp.Request.Method
|
||||||
|
header := resp.Request.Header
|
||||||
|
return data, fmt.Errorf("Unknown API Error: %d\nRequest: '%s' with '%s' method '%s' header and '%s' body", resp.StatusCode, path, method, header, string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg, ok := errMap["message"]; ok {
|
||||||
|
return data, fmt.Errorf("%v", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no error message, at least give status and data
|
||||||
|
return data, fmt.Errorf("%s: %s", resp.Status, string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getResponseReader(method, path string, header http.Header, body io.Reader) (io.ReadCloser, *Response, error) {
|
||||||
|
resp, err := c.doRequest(method, path, header, body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for errors
|
||||||
|
data, err := statusCodeToErr(resp)
|
||||||
|
if err != nil {
|
||||||
|
return io.NopCloser(bytes.NewReader(data)), resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Body, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, *Response, error) {
|
||||||
|
resp, err := c.doRequest(method, path, header, body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// check for errors
|
||||||
|
data, err := statusCodeToErr(resp)
|
||||||
|
if err != nil {
|
||||||
|
return data, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// success (2XX), read body
|
||||||
|
data, err = io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getParsedResponse(method, path string, header http.Header, body io.Reader, obj interface{}) (*Response, error) {
|
||||||
|
data, resp, err := c.getResponse(method, path, header, body)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
return resp, json.Unmarshal(data, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getStatusCode(method, path string, header http.Header, body io.Reader) (int, *Response, error) {
|
||||||
|
resp, err := c.doRequest(method, path, header, body)
|
||||||
|
if err != nil {
|
||||||
|
return -1, resp, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
return resp.StatusCode, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// pathEscapeSegments escapes segments of a path while not escaping forward slash
|
||||||
|
func pathEscapeSegments(path string) string {
|
||||||
|
slice := strings.Split(path, "/")
|
||||||
|
for index := range slice {
|
||||||
|
slice[index] = url.PathEscape(slice[index])
|
||||||
|
}
|
||||||
|
escapedPath := strings.Join(slice, "/")
|
||||||
|
return escapedPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// escapeValidatePathSegments is a help function to validate and encode url path segments
|
||||||
|
func escapeValidatePathSegments(seg ...*string) error {
|
||||||
|
for i := range seg {
|
||||||
|
if seg[i] == nil || len(*seg[i]) == 0 {
|
||||||
|
return fmt.Errorf("path segment [%d] is empty", i)
|
||||||
|
}
|
||||||
|
*seg[i] = url.PathEscape(*seg[i])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
9
vendor/code.gitea.io/sdk/gitea/doc.go
generated
vendored
Normal file
9
vendor/code.gitea.io/sdk/gitea/doc.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2016 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package gitea implements a client for the Gitea API.
|
||||||
|
// The version corresponds to the highest supported version
|
||||||
|
// of the gitea API, but backwards-compatibility is mostly
|
||||||
|
// given.
|
||||||
|
package gitea // import "code.gitea.io/sdk/gitea"
|
||||||
51
vendor/code.gitea.io/sdk/gitea/fork.go
generated
vendored
Normal file
51
vendor/code.gitea.io/sdk/gitea/fork.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2016 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListForksOptions options for listing repository's forks
|
||||||
|
type ListForksOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListForks list a repository's forks
|
||||||
|
func (c *Client) ListForks(user, repo string, opt ListForksOptions) ([]*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
forks := make([]*Repository, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/forks?%s", user, repo, opt.getURLQuery().Encode()),
|
||||||
|
nil, nil, &forks)
|
||||||
|
return forks, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateForkOption options for creating a fork
|
||||||
|
type CreateForkOption struct {
|
||||||
|
// organization name, if forking into an organization
|
||||||
|
Organization *string `json:"organization"`
|
||||||
|
// name of the forked repository
|
||||||
|
Name *string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateFork create a fork of a repository
|
||||||
|
func (c *Client) CreateFork(user, repo string, form CreateForkOption) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
fork := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/forks", user, repo), jsonHeader, bytes.NewReader(body), &fork)
|
||||||
|
return fork, resp, err
|
||||||
|
}
|
||||||
28
vendor/code.gitea.io/sdk/gitea/git_blob.go
generated
vendored
Normal file
28
vendor/code.gitea.io/sdk/gitea/git_blob.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GitBlobResponse represents a git blob
|
||||||
|
type GitBlobResponse struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
Encoding string `json:"encoding"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlob get the blob of a repository file
|
||||||
|
func (c *Client) GetBlob(user, repo, sha string) (*GitBlobResponse, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &sha); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
blob := new(GitBlobResponse)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/blobs/%s", user, repo, sha), nil, nil, blob)
|
||||||
|
return blob, resp, err
|
||||||
|
}
|
||||||
71
vendor/code.gitea.io/sdk/gitea/git_hook.go
generated
vendored
Normal file
71
vendor/code.gitea.io/sdk/gitea/git_hook.go
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GitHook represents a Git repository hook
|
||||||
|
type GitHook struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
Content string `json:"content,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoGitHooksOptions options for listing repository's githooks
|
||||||
|
type ListRepoGitHooksOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoGitHooks list all the Git hooks of one repository
|
||||||
|
func (c *Client) ListRepoGitHooks(user, repo string, opt ListRepoGitHooksOptions) ([]*GitHook, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
hooks := make([]*GitHook, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks)
|
||||||
|
return hooks, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepoGitHook get a Git hook of a repository
|
||||||
|
func (c *Client) GetRepoGitHook(user, repo, id string) (*GitHook, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &id); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h := new(GitHook)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil, h)
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditGitHookOption options when modifying one Git hook
|
||||||
|
type EditGitHookOption struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditRepoGitHook modify one Git hook of a repository
|
||||||
|
func (c *Client) EditRepoGitHook(user, repo, id string, opt EditGitHookOption) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PATCH", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRepoGitHook delete one Git hook from a repository
|
||||||
|
func (c *Client) DeleteRepoGitHook(user, repo, id string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
20
vendor/code.gitea.io/sdk/gitea/helper.go
generated
vendored
Normal file
20
vendor/code.gitea.io/sdk/gitea/helper.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
// OptionalBool convert a bool to a bool reference
|
||||||
|
func OptionalBool(v bool) *bool {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptionalString convert a string to a string reference
|
||||||
|
func OptionalString(v string) *string {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptionalInt64 convert a int64 to a int64 reference
|
||||||
|
func OptionalInt64(v int64) *int64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
196
vendor/code.gitea.io/sdk/gitea/hook.go
generated
vendored
Normal file
196
vendor/code.gitea.io/sdk/gitea/hook.go
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hook a hook is a web hook when one repository changed
|
||||||
|
type Hook struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
URL string `json:"-"`
|
||||||
|
Config map[string]string `json:"config"`
|
||||||
|
Events []string `json:"events"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
Updated time.Time `json:"updated_at"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// HookType represent all webhook types gitea currently offer
|
||||||
|
type HookType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// HookTypeDingtalk webhook that dingtalk understand
|
||||||
|
HookTypeDingtalk HookType = "dingtalk"
|
||||||
|
// HookTypeDiscord webhook that discord understand
|
||||||
|
HookTypeDiscord HookType = "discord"
|
||||||
|
// HookTypeGitea webhook that gitea understand
|
||||||
|
HookTypeGitea HookType = "gitea"
|
||||||
|
// HookTypeGogs webhook that gogs understand
|
||||||
|
HookTypeGogs HookType = "gogs"
|
||||||
|
// HookTypeMsteams webhook that msteams understand
|
||||||
|
HookTypeMsteams HookType = "msteams"
|
||||||
|
// HookTypeSlack webhook that slack understand
|
||||||
|
HookTypeSlack HookType = "slack"
|
||||||
|
// HookTypeTelegram webhook that telegram understand
|
||||||
|
HookTypeTelegram HookType = "telegram"
|
||||||
|
// HookTypeFeishu webhook that feishu understand
|
||||||
|
HookTypeFeishu HookType = "feishu"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListHooksOptions options for listing hooks
|
||||||
|
type ListHooksOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrgHooks list all the hooks of one organization
|
||||||
|
func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
hooks := make([]*Hook, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks?%s", org, opt.getURLQuery().Encode()), nil, nil, &hooks)
|
||||||
|
return hooks, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoHooks list all the hooks of one repository
|
||||||
|
func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
hooks := make([]*Hook, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks)
|
||||||
|
return hooks, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrgHook get a hook of an organization
|
||||||
|
func (c *Client) GetOrgHook(org string, id int64) (*Hook, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h := new(Hook)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil, h)
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepoHook get a hook of a repository
|
||||||
|
func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h := new(Hook)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil, h)
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateHookOption options when create a hook
|
||||||
|
type CreateHookOption struct {
|
||||||
|
Type HookType `json:"type"`
|
||||||
|
Config map[string]string `json:"config"`
|
||||||
|
Events []string `json:"events"`
|
||||||
|
BranchFilter string `json:"branch_filter"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
AuthorizationHeader string `json:"authorization_header"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateHookOption struct
|
||||||
|
func (opt CreateHookOption) Validate() error {
|
||||||
|
if len(opt.Type) == 0 {
|
||||||
|
return fmt.Errorf("hook type needed")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOrgHook create one hook for an organization, with options
|
||||||
|
func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h := new(Hook)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/orgs/%s/hooks", org), jsonHeader, bytes.NewReader(body), h)
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRepoHook create one hook for a repository, with options
|
||||||
|
func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h := new(Hook)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/hooks", user, repo), jsonHeader, bytes.NewReader(body), h)
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditHookOption options when modify one hook
|
||||||
|
type EditHookOption struct {
|
||||||
|
Config map[string]string `json:"config"`
|
||||||
|
Events []string `json:"events"`
|
||||||
|
BranchFilter string `json:"branch_filter"`
|
||||||
|
Active *bool `json:"active"`
|
||||||
|
AuthorizationHeader string `json:"authorization_header"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditOrgHook modify one hook of an organization, with hook id and options
|
||||||
|
func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PATCH", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditRepoHook modify one hook of a repository, with hook id and options
|
||||||
|
func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PATCH", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOrgHook delete one hook from an organization, with hook id
|
||||||
|
func (c *Client) DeleteOrgHook(org string, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRepoHook delete one hook from a repository, with hook id
|
||||||
|
func (c *Client) DeleteRepoHook(user, repo string, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
59
vendor/code.gitea.io/sdk/gitea/hook_validate.go
generated
vendored
Normal file
59
vendor/code.gitea.io/sdk/gitea/hook_validate.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VerifyWebhookSignature verifies that a payload matches the X-Gitea-Signature based on a secret
|
||||||
|
func VerifyWebhookSignature(secret, expected string, payload []byte) (bool, error) {
|
||||||
|
hash := hmac.New(sha256.New, []byte(secret))
|
||||||
|
if _, err := hash.Write(payload); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
expectedSum, err := hex.DecodeString(expected)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return hmac.Equal(hash.Sum(nil), expectedSum), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyWebhookSignatureMiddleware is a http.Handler for verifying X-Gitea-Signature on incoming webhooks
|
||||||
|
func VerifyWebhookSignatureMiddleware(secret string) func(http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
if _, err := io.Copy(&b, r.Body); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := r.Header.Get("X-Gitea-Signature")
|
||||||
|
if expected == "" {
|
||||||
|
http.Error(w, "no signature found", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ok, err := VerifyWebhookSignature(secret, expected, b.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
http.Error(w, "invalid payload", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Body = io.NopCloser(&b)
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
253
vendor/code.gitea.io/sdk/gitea/httpsign.go
generated
vendored
Normal file
253
vendor/code.gitea.io/sdk/gitea/httpsign.go
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-fed/httpsig"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HTTPSign contains the signer used for signing requests
|
||||||
|
type HTTPSign struct {
|
||||||
|
ssh.Signer
|
||||||
|
cert bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTPSignConfig contains the configuration for creating a HTTPSign
|
||||||
|
type HTTPSignConfig struct {
|
||||||
|
fingerprint string
|
||||||
|
principal string
|
||||||
|
pubkey bool
|
||||||
|
cert bool
|
||||||
|
sshKey string
|
||||||
|
passphrase string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHTTPSignWithPubkey can be used to create a HTTPSign with a public key
|
||||||
|
// if no fingerprint is specified it returns the first public key found
|
||||||
|
func NewHTTPSignWithPubkey(fingerprint, sshKey, passphrase string) (*HTTPSign, error) {
|
||||||
|
return newHTTPSign(&HTTPSignConfig{
|
||||||
|
fingerprint: fingerprint,
|
||||||
|
pubkey: true,
|
||||||
|
sshKey: sshKey,
|
||||||
|
passphrase: passphrase,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHTTPSignWithCert can be used to create a HTTPSign with a certificate
|
||||||
|
// if no principal is specified it returns the first certificate found
|
||||||
|
func NewHTTPSignWithCert(principal, sshKey, passphrase string) (*HTTPSign, error) {
|
||||||
|
return newHTTPSign(&HTTPSignConfig{
|
||||||
|
principal: principal,
|
||||||
|
cert: true,
|
||||||
|
sshKey: sshKey,
|
||||||
|
passphrase: passphrase,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHTTPSign returns a new HTTPSign
|
||||||
|
// It will check the ssh-agent or a local file is config.sshKey is set.
|
||||||
|
// Depending on the configuration it will either use a certificate or a public key
|
||||||
|
func newHTTPSign(config *HTTPSignConfig) (*HTTPSign, error) {
|
||||||
|
var signer ssh.Signer
|
||||||
|
|
||||||
|
if config.sshKey != "" {
|
||||||
|
priv, err := os.ReadFile(config.sshKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.passphrase == "" {
|
||||||
|
signer, err = ssh.ParsePrivateKey(priv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
signer, err = ssh.ParsePrivateKeyWithPassphrase(priv, []byte(config.passphrase))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.cert {
|
||||||
|
certbytes, err := os.ReadFile(config.sshKey + "-cert.pub")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pub, _, _, _, err := ssh.ParseAuthorizedKey(certbytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cert, ok := pub.(*ssh.Certificate)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("failed to parse certificate")
|
||||||
|
}
|
||||||
|
|
||||||
|
signer, err = ssh.NewCertSigner(cert, signer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if no sshKey is specified, check if we have a ssh-agent and use it
|
||||||
|
agent, err := GetAgent()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signers, err := agent.Signers()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(signers) == 0 {
|
||||||
|
return nil, fmt.Errorf("no signers found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.cert {
|
||||||
|
signer = findCertSigner(signers, config.principal)
|
||||||
|
if signer == nil {
|
||||||
|
return nil, fmt.Errorf("no certificate found for %s", config.principal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.pubkey {
|
||||||
|
signer = findPubkeySigner(signers, config.fingerprint)
|
||||||
|
if signer == nil {
|
||||||
|
return nil, fmt.Errorf("no public key found for %s", config.fingerprint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &HTTPSign{
|
||||||
|
Signer: signer,
|
||||||
|
cert: config.cert,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignRequest signs a HTTP request
|
||||||
|
func (c *Client) SignRequest(r *http.Request) error {
|
||||||
|
var contents []byte
|
||||||
|
|
||||||
|
headersToSign := []string{httpsig.RequestTarget, "(created)", "(expires)"}
|
||||||
|
|
||||||
|
if c.httpsigner.cert {
|
||||||
|
// add our certificate to the headers to sign
|
||||||
|
pubkey, _ := ssh.ParsePublicKey(c.httpsigner.Signer.PublicKey().Marshal())
|
||||||
|
if cert, ok := pubkey.(*ssh.Certificate); ok {
|
||||||
|
certString := base64.RawStdEncoding.EncodeToString(cert.Marshal())
|
||||||
|
r.Header.Add("x-ssh-certificate", certString)
|
||||||
|
|
||||||
|
headersToSign = append(headersToSign, "x-ssh-certificate")
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("no ssh certificate found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have a body, the Digest header will be added and we'll include this also in
|
||||||
|
// our signature.
|
||||||
|
if r.Body != nil {
|
||||||
|
body, err := r.GetBody()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getBody() failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
contents, err = io.ReadAll(body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed reading body: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
headersToSign = append(headersToSign, "Digest")
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a signer for the request and headers, the signature will be valid for 10 seconds
|
||||||
|
signer, _, err := httpsig.NewSSHSigner(c.httpsigner.Signer, httpsig.DigestSha512, headersToSign, httpsig.Signature, 10)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("httpsig.NewSSHSigner failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sign the request, use the fingerprint if we don't have a certificate
|
||||||
|
keyID := "gitea"
|
||||||
|
if !c.httpsigner.cert {
|
||||||
|
keyID = ssh.FingerprintSHA256(c.httpsigner.Signer.PublicKey())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = signer.SignRequest(keyID, r, contents)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("httpsig.Signrequest failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// findCertSigner returns the Signer containing a valid certificate
|
||||||
|
// if no principal is specified it returns the first certificate found
|
||||||
|
func findCertSigner(sshsigners []ssh.Signer, principal string) ssh.Signer {
|
||||||
|
for _, s := range sshsigners {
|
||||||
|
// Check if the key is a certificate
|
||||||
|
if !strings.Contains(s.PublicKey().Type(), "cert-v01@openssh.com") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the ssh.Signer to a ssh.Certificate
|
||||||
|
mpubkey, _ := ssh.ParsePublicKey(s.PublicKey().Marshal())
|
||||||
|
cryptopub := mpubkey.(crypto.PublicKey)
|
||||||
|
cert := cryptopub.(*ssh.Certificate)
|
||||||
|
t := time.Unix(int64(cert.ValidBefore), 0)
|
||||||
|
|
||||||
|
// make sure the certificate is at least 10 seconds valid
|
||||||
|
if time.Until(t) <= time.Second*10 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if principal == "" {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range cert.ValidPrincipals {
|
||||||
|
if p == principal {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// findPubkeySigner returns the Signer containing a valid public key
|
||||||
|
// if no fingerprint is specified it returns the first public key found
|
||||||
|
func findPubkeySigner(sshsigners []ssh.Signer, fingerprint string) ssh.Signer {
|
||||||
|
for _, s := range sshsigners {
|
||||||
|
// Check if the key is a certificate
|
||||||
|
if strings.Contains(s.PublicKey().Type(), "cert-v01@openssh.com") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if fingerprint == "" {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.TrimSpace(string(ssh.MarshalAuthorizedKey(s.PublicKey()))) == fingerprint {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
if ssh.FingerprintSHA256(s.PublicKey()) == fingerprint {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
309
vendor/code.gitea.io/sdk/gitea/issue.go
generated
vendored
Normal file
309
vendor/code.gitea.io/sdk/gitea/issue.go
generated
vendored
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PullRequestMeta PR info if an issue is a PR
|
||||||
|
type PullRequestMeta struct {
|
||||||
|
HasMerged bool `json:"merged"`
|
||||||
|
Merged *time.Time `json:"merged_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepositoryMeta basic repository information
|
||||||
|
type RepositoryMeta struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Owner string `json:"owner"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue represents an issue in a repository
|
||||||
|
type Issue struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
Index int64 `json:"number"`
|
||||||
|
Poster *User `json:"user"`
|
||||||
|
OriginalAuthor string `json:"original_author"`
|
||||||
|
OriginalAuthorID int64 `json:"original_author_id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Ref string `json:"ref"`
|
||||||
|
Labels []*Label `json:"labels"`
|
||||||
|
Milestone *Milestone `json:"milestone"`
|
||||||
|
Assignees []*User `json:"assignees"`
|
||||||
|
// Whether the issue is open or closed
|
||||||
|
State StateType `json:"state"`
|
||||||
|
IsLocked bool `json:"is_locked"`
|
||||||
|
Comments int `json:"comments"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
Updated time.Time `json:"updated_at"`
|
||||||
|
Closed *time.Time `json:"closed_at"`
|
||||||
|
Deadline *time.Time `json:"due_date"`
|
||||||
|
PullRequest *PullRequestMeta `json:"pull_request"`
|
||||||
|
Repository *RepositoryMeta `json:"repository"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIssueOption list issue options
|
||||||
|
type ListIssueOption struct {
|
||||||
|
ListOptions
|
||||||
|
State StateType
|
||||||
|
Type IssueType
|
||||||
|
Labels []string
|
||||||
|
Milestones []string
|
||||||
|
KeyWord string
|
||||||
|
Since time.Time
|
||||||
|
Before time.Time
|
||||||
|
// filter by created by username
|
||||||
|
CreatedBy string
|
||||||
|
// filter by assigned to username
|
||||||
|
AssignedBy string
|
||||||
|
// filter by username mentioned
|
||||||
|
MentionedBy string
|
||||||
|
// filter by owner (only works on ListIssues on User)
|
||||||
|
Owner string
|
||||||
|
// filter by team (requires organization owner parameter to be provided and only works on ListIssues on User)
|
||||||
|
Team string
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateType issue state type
|
||||||
|
type StateType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// StateOpen pr/issue is opend
|
||||||
|
StateOpen StateType = "open"
|
||||||
|
// StateClosed pr/issue is closed
|
||||||
|
StateClosed StateType = "closed"
|
||||||
|
// StateAll is all
|
||||||
|
StateAll StateType = "all"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IssueType is issue a pull or only an issue
|
||||||
|
type IssueType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// IssueTypeAll pr and issue
|
||||||
|
IssueTypeAll IssueType = ""
|
||||||
|
// IssueTypeIssue only issues
|
||||||
|
IssueTypeIssue IssueType = "issues"
|
||||||
|
// IssueTypePull only pulls
|
||||||
|
IssueTypePull IssueType = "pulls"
|
||||||
|
)
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *ListIssueOption) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
|
||||||
|
if len(opt.State) > 0 {
|
||||||
|
query.Add("state", string(opt.State))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opt.Labels) > 0 {
|
||||||
|
query.Add("labels", strings.Join(opt.Labels, ","))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opt.KeyWord) > 0 {
|
||||||
|
query.Add("q", opt.KeyWord)
|
||||||
|
}
|
||||||
|
|
||||||
|
query.Add("type", string(opt.Type))
|
||||||
|
|
||||||
|
if len(opt.Milestones) > 0 {
|
||||||
|
query.Add("milestones", strings.Join(opt.Milestones, ","))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !opt.Since.IsZero() {
|
||||||
|
query.Add("since", opt.Since.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
if !opt.Before.IsZero() {
|
||||||
|
query.Add("before", opt.Before.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opt.CreatedBy) > 0 {
|
||||||
|
query.Add("created_by", opt.CreatedBy)
|
||||||
|
}
|
||||||
|
if len(opt.AssignedBy) > 0 {
|
||||||
|
query.Add("assigned_by", opt.AssignedBy)
|
||||||
|
}
|
||||||
|
if len(opt.MentionedBy) > 0 {
|
||||||
|
query.Add("mentioned_by", opt.MentionedBy)
|
||||||
|
}
|
||||||
|
if len(opt.Owner) > 0 {
|
||||||
|
query.Add("owner", opt.Owner)
|
||||||
|
}
|
||||||
|
if len(opt.Team) > 0 {
|
||||||
|
query.Add("team", opt.MentionedBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIssues returns all issues assigned the authenticated user
|
||||||
|
func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
issues := make([]*Issue, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse("/repos/issues/search")
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues)
|
||||||
|
if e := c.checkServerVersionGreaterThanOrEqual(version1_12_0); e != nil {
|
||||||
|
for i := 0; i < len(issues); i++ {
|
||||||
|
if issues[i].Repository != nil {
|
||||||
|
issues[i].Repository.Owner = strings.Split(issues[i].Repository.FullName, "/")[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := range issues {
|
||||||
|
c.issueBackwardsCompatibility(issues[i])
|
||||||
|
}
|
||||||
|
return issues, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoIssues returns all issues for a given repository
|
||||||
|
func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
issues := make([]*Issue, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues", owner, repo))
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues)
|
||||||
|
if e := c.checkServerVersionGreaterThanOrEqual(version1_12_0); e != nil {
|
||||||
|
for i := 0; i < len(issues); i++ {
|
||||||
|
if issues[i].Repository != nil {
|
||||||
|
issues[i].Repository.Owner = strings.Split(issues[i].Repository.FullName, "/")[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := range issues {
|
||||||
|
c.issueBackwardsCompatibility(issues[i])
|
||||||
|
}
|
||||||
|
return issues, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIssue returns a single issue for a given repository
|
||||||
|
func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
issue := new(Issue)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue)
|
||||||
|
if e := c.checkServerVersionGreaterThanOrEqual(version1_12_0); e != nil && issue.Repository != nil {
|
||||||
|
issue.Repository.Owner = strings.Split(issue.Repository.FullName, "/")[0]
|
||||||
|
}
|
||||||
|
c.issueBackwardsCompatibility(issue)
|
||||||
|
return issue, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateIssueOption options to create one issue
|
||||||
|
type CreateIssueOption struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Ref string `json:"ref"`
|
||||||
|
Assignees []string `json:"assignees"`
|
||||||
|
Deadline *time.Time `json:"due_date"`
|
||||||
|
// milestone id
|
||||||
|
Milestone int64 `json:"milestone"`
|
||||||
|
// list of label ids
|
||||||
|
Labels []int64 `json:"labels"`
|
||||||
|
Closed bool `json:"closed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateIssueOption struct
|
||||||
|
func (opt CreateIssueOption) Validate() error {
|
||||||
|
if len(strings.TrimSpace(opt.Title)) == 0 {
|
||||||
|
return fmt.Errorf("title is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateIssue create a new issue for a given repository
|
||||||
|
func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
issue := new(Issue)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues", owner, repo),
|
||||||
|
jsonHeader, bytes.NewReader(body), issue)
|
||||||
|
c.issueBackwardsCompatibility(issue)
|
||||||
|
return issue, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditIssueOption options for editing an issue
|
||||||
|
type EditIssueOption struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Body *string `json:"body"`
|
||||||
|
Ref *string `json:"ref"`
|
||||||
|
Assignees []string `json:"assignees"`
|
||||||
|
Milestone *int64 `json:"milestone"`
|
||||||
|
State *StateType `json:"state"`
|
||||||
|
Deadline *time.Time `json:"due_date"`
|
||||||
|
RemoveDeadline *bool `json:"unset_due_date"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the EditIssueOption struct
|
||||||
|
func (opt EditIssueOption) Validate() error {
|
||||||
|
if len(opt.Title) != 0 && len(strings.TrimSpace(opt.Title)) == 0 {
|
||||||
|
return fmt.Errorf("title is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditIssue modify an existing issue for a given repository
|
||||||
|
func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
issue := new(Issue)
|
||||||
|
resp, err := c.getParsedResponse("PATCH",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index),
|
||||||
|
jsonHeader, bytes.NewReader(body), issue)
|
||||||
|
c.issueBackwardsCompatibility(issue)
|
||||||
|
return issue, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIssue delete a issue from a repository
|
||||||
|
func (c *Client) DeleteIssue(user, repo string, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/issues/%d", user, repo, id),
|
||||||
|
nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) issueBackwardsCompatibility(issue *Issue) {
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_12_0) != nil {
|
||||||
|
c.mutex.RLock()
|
||||||
|
issue.HTMLURL = fmt.Sprintf("%s/%s/issues/%d", c.url, issue.Repository.FullName, issue.Index)
|
||||||
|
c.mutex.RUnlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
154
vendor/code.gitea.io/sdk/gitea/issue_comment.go
generated
vendored
Normal file
154
vendor/code.gitea.io/sdk/gitea/issue_comment.go
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Comment represents a comment on a commit or issue
|
||||||
|
type Comment struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
PRURL string `json:"pull_request_url"`
|
||||||
|
IssueURL string `json:"issue_url"`
|
||||||
|
Poster *User `json:"user"`
|
||||||
|
OriginalAuthor string `json:"original_author"`
|
||||||
|
OriginalAuthorID int64 `json:"original_author_id"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
Updated time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIssueCommentOptions list comment options
|
||||||
|
type ListIssueCommentOptions struct {
|
||||||
|
ListOptions
|
||||||
|
Since time.Time
|
||||||
|
Before time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *ListIssueCommentOptions) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
if !opt.Since.IsZero() {
|
||||||
|
query.Add("since", opt.Since.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
if !opt.Before.IsZero() {
|
||||||
|
query.Add("before", opt.Before.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIssueComments list comments on an issue.
|
||||||
|
func (c *Client) ListIssueComments(owner, repo string, index int64, opt ListIssueCommentOptions) ([]*Comment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index))
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
comments := make([]*Comment, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &comments)
|
||||||
|
return comments, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoIssueComments list comments for a given repo.
|
||||||
|
func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentOptions) ([]*Comment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/comments", owner, repo))
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
comments := make([]*Comment, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &comments)
|
||||||
|
return comments, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIssueComment get a comment for a given repo by id.
|
||||||
|
func (c *Client) GetIssueComment(owner, repo string, id int64) (*Comment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
comment := new(Comment)
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return comment, nil, err
|
||||||
|
}
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, id), nil, nil, &comment)
|
||||||
|
return comment, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateIssueCommentOption options for creating a comment on an issue
|
||||||
|
type CreateIssueCommentOption struct {
|
||||||
|
Body string `json:"body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateIssueCommentOption struct
|
||||||
|
func (opt CreateIssueCommentOption) Validate() error {
|
||||||
|
if len(opt.Body) == 0 {
|
||||||
|
return fmt.Errorf("body is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateIssueComment create comment on an issue.
|
||||||
|
func (c *Client) CreateIssueComment(owner, repo string, index int64, opt CreateIssueCommentOption) (*Comment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
comment := new(Comment)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index), jsonHeader, bytes.NewReader(body), comment)
|
||||||
|
return comment, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditIssueCommentOption options for editing a comment
|
||||||
|
type EditIssueCommentOption struct {
|
||||||
|
Body string `json:"body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the EditIssueCommentOption struct
|
||||||
|
func (opt EditIssueCommentOption) Validate() error {
|
||||||
|
if len(opt.Body) == 0 {
|
||||||
|
return fmt.Errorf("body is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditIssueComment edits an issue comment.
|
||||||
|
func (c *Client) EditIssueComment(owner, repo string, commentID int64, opt EditIssueCommentOption) (*Comment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
comment := new(Comment)
|
||||||
|
resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, commentID), jsonHeader, bytes.NewReader(body), comment)
|
||||||
|
return comment, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIssueComment deletes an issue comment.
|
||||||
|
func (c *Client) DeleteIssueComment(owner, repo string, commentID int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, commentID), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
211
vendor/code.gitea.io/sdk/gitea/issue_label.go
generated
vendored
Normal file
211
vendor/code.gitea.io/sdk/gitea/issue_label.go
generated
vendored
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Label a label to an issue or a pr
|
||||||
|
type Label struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
// example: 00aabb
|
||||||
|
Color string `json:"color"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListLabelsOptions options for listing repository's labels
|
||||||
|
type ListLabelsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoLabels list labels of one repository
|
||||||
|
func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*Label, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
labels := make([]*Label, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels?%s", owner, repo, opt.getURLQuery().Encode()), nil, nil, &labels)
|
||||||
|
return labels, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepoLabel get one label of repository by repo it
|
||||||
|
func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
label := new(Label)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil, label)
|
||||||
|
return label, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateLabelOption options for creating a label
|
||||||
|
type CreateLabelOption struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
// example: #00aabb
|
||||||
|
Color string `json:"color"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateLabelOption struct
|
||||||
|
func (opt CreateLabelOption) Validate() error {
|
||||||
|
aw, err := regexp.MatchString("^#?[0-9,a-f,A-F]{6}$", opt.Color)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !aw {
|
||||||
|
return fmt.Errorf("invalid color format")
|
||||||
|
}
|
||||||
|
if len(strings.TrimSpace(opt.Name)) == 0 {
|
||||||
|
return fmt.Errorf("empty name not allowed")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateLabel create one label of repository
|
||||||
|
func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if len(opt.Color) == 6 {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
opt.Color = "#" + opt.Color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
label := new(Label)
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/labels", owner, repo),
|
||||||
|
jsonHeader, bytes.NewReader(body), label)
|
||||||
|
return label, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditLabelOption options for editing a label
|
||||||
|
type EditLabelOption struct {
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Color *string `json:"color"`
|
||||||
|
Description *string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the EditLabelOption struct
|
||||||
|
func (opt EditLabelOption) Validate() error {
|
||||||
|
if opt.Color != nil {
|
||||||
|
aw, err := regexp.MatchString("^#?[0-9,a-f,A-F]{6}$", *opt.Color)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !aw {
|
||||||
|
return fmt.Errorf("invalid color format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if opt.Name != nil {
|
||||||
|
if len(strings.TrimSpace(*opt.Name)) == 0 {
|
||||||
|
return fmt.Errorf("empty name not allowed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditLabel modify one label with options
|
||||||
|
func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*Label, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
label := new(Label)
|
||||||
|
resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), label)
|
||||||
|
return label, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteLabel delete one label of repository by id
|
||||||
|
func (c *Client) DeleteLabel(owner, repo string, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIssueLabels get labels of one issue via issue id
|
||||||
|
func (c *Client) GetIssueLabels(owner, repo string, index int64, opts ListLabelsOptions) ([]*Label, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
labels := make([]*Label, 0, 5)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels?%s", owner, repo, index, opts.getURLQuery().Encode()), nil, nil, &labels)
|
||||||
|
return labels, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueLabelsOption a collection of labels
|
||||||
|
type IssueLabelsOption struct {
|
||||||
|
// list of label IDs
|
||||||
|
Labels []int64 `json:"labels"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddIssueLabels add one or more labels to one issue
|
||||||
|
func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
var labels []*Label
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels)
|
||||||
|
return labels, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceIssueLabels replace old labels of issue with new labels
|
||||||
|
func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
var labels []*Label
|
||||||
|
resp, err := c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels)
|
||||||
|
return labels, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIssueLabel delete one label of one issue by issue id and label id
|
||||||
|
// TODO: maybe we need delete by label name and issue id
|
||||||
|
func (c *Client) DeleteIssueLabel(owner, repo string, index, label int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, label), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearIssueLabels delete all the labels of one issue.
|
||||||
|
func (c *Client) ClearIssueLabels(owner, repo string, index int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
237
vendor/code.gitea.io/sdk/gitea/issue_milestone.go
generated
vendored
Normal file
237
vendor/code.gitea.io/sdk/gitea/issue_milestone.go
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Milestone milestone is a collection of issues on one repository
|
||||||
|
type Milestone struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
State StateType `json:"state"`
|
||||||
|
OpenIssues int `json:"open_issues"`
|
||||||
|
ClosedIssues int `json:"closed_issues"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
Updated *time.Time `json:"updated_at"`
|
||||||
|
Closed *time.Time `json:"closed_at"`
|
||||||
|
Deadline *time.Time `json:"due_on"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMilestoneOption list milestone options
|
||||||
|
type ListMilestoneOption struct {
|
||||||
|
ListOptions
|
||||||
|
// open, closed, all
|
||||||
|
State StateType
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *ListMilestoneOption) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
if opt.State != "" {
|
||||||
|
query.Add("state", string(opt.State))
|
||||||
|
}
|
||||||
|
if len(opt.Name) != 0 {
|
||||||
|
query.Add("name", opt.Name)
|
||||||
|
}
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoMilestones list all the milestones of one repository
|
||||||
|
func (c *Client) ListRepoMilestones(owner, repo string, opt ListMilestoneOption) ([]*Milestone, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
milestones := make([]*Milestone, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/milestones", owner, repo))
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &milestones)
|
||||||
|
return milestones, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMilestone get one milestone by repo name and milestone id
|
||||||
|
func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
milestone := new(Milestone)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil, milestone)
|
||||||
|
return milestone, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMilestoneByName get one milestone by repo and milestone name
|
||||||
|
func (c *Client) GetMilestoneByName(owner, repo, name string) (*Milestone, *Response, error) {
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
|
||||||
|
// backwards compatibility mode
|
||||||
|
m, resp, err := c.resolveMilestoneByName(owner, repo, name)
|
||||||
|
return m, resp, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
milestone := new(Milestone)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%s", owner, repo, name), nil, nil, milestone)
|
||||||
|
return milestone, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMilestoneOption options for creating a milestone
|
||||||
|
type CreateMilestoneOption struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
State StateType `json:"state"`
|
||||||
|
Deadline *time.Time `json:"due_on"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateMilestoneOption struct
|
||||||
|
func (opt CreateMilestoneOption) Validate() error {
|
||||||
|
if len(strings.TrimSpace(opt.Title)) == 0 {
|
||||||
|
return fmt.Errorf("title is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMilestone create one milestone with options
|
||||||
|
func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption) (*Milestone, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
milestone := new(Milestone)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/milestones", owner, repo), jsonHeader, bytes.NewReader(body), milestone)
|
||||||
|
|
||||||
|
// make creating closed milestones need gitea >= v1.13.0
|
||||||
|
// this make it backwards compatible
|
||||||
|
if err == nil && opt.State == StateClosed && milestone.State != StateClosed {
|
||||||
|
closed := StateClosed
|
||||||
|
return c.EditMilestone(owner, repo, milestone.ID, EditMilestoneOption{
|
||||||
|
State: &closed,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return milestone, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditMilestoneOption options for editing a milestone
|
||||||
|
type EditMilestoneOption struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Description *string `json:"description"`
|
||||||
|
State *StateType `json:"state"`
|
||||||
|
Deadline *time.Time `json:"due_on"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the EditMilestoneOption struct
|
||||||
|
func (opt EditMilestoneOption) Validate() error {
|
||||||
|
if len(opt.Title) != 0 && len(strings.TrimSpace(opt.Title)) == 0 {
|
||||||
|
return fmt.Errorf("title is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditMilestone modify milestone with options
|
||||||
|
func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOption) (*Milestone, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
milestone := new(Milestone)
|
||||||
|
resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), milestone)
|
||||||
|
return milestone, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditMilestoneByName modify milestone with options
|
||||||
|
func (c *Client) EditMilestoneByName(owner, repo, name string, opt EditMilestoneOption) (*Milestone, *Response, error) {
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
|
||||||
|
// backwards compatibility mode
|
||||||
|
m, _, err := c.resolveMilestoneByName(owner, repo, name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return c.EditMilestone(owner, repo, m.ID, opt)
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
milestone := new(Milestone)
|
||||||
|
resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/milestones/%s", owner, repo, name), jsonHeader, bytes.NewReader(body), milestone)
|
||||||
|
return milestone, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMilestone delete one milestone by id
|
||||||
|
func (c *Client) DeleteMilestone(owner, repo string, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMilestoneByName delete one milestone by name
|
||||||
|
func (c *Client) DeleteMilestoneByName(owner, repo, name string) (*Response, error) {
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
|
||||||
|
// backwards compatibility mode
|
||||||
|
m, _, err := c.resolveMilestoneByName(owner, repo, name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.DeleteMilestone(owner, repo, m.ID)
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%s", owner, repo, name), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolveMilestoneByName is a fallback method to find milestone id by name
|
||||||
|
func (c *Client) resolveMilestoneByName(owner, repo, name string) (*Milestone, *Response, error) {
|
||||||
|
for i := 1; ; i++ {
|
||||||
|
miles, resp, err := c.ListRepoMilestones(owner, repo, ListMilestoneOption{
|
||||||
|
ListOptions: ListOptions{
|
||||||
|
Page: i,
|
||||||
|
},
|
||||||
|
State: "all",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if len(miles) == 0 {
|
||||||
|
return nil, nil, fmt.Errorf("milestone '%s' do not exist", name)
|
||||||
|
}
|
||||||
|
for _, m := range miles {
|
||||||
|
if strings.EqualFold(strings.TrimSpace(m.Title), strings.TrimSpace(name)) {
|
||||||
|
return m, resp, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
104
vendor/code.gitea.io/sdk/gitea/issue_reaction.go
generated
vendored
Normal file
104
vendor/code.gitea.io/sdk/gitea/issue_reaction.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reaction contain one reaction
|
||||||
|
type Reaction struct {
|
||||||
|
User *User `json:"user"`
|
||||||
|
Reaction string `json:"content"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIssueReactions get a list reactions of an issue
|
||||||
|
func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
reactions := make([]*Reaction, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index), nil, nil, &reactions)
|
||||||
|
return reactions, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIssueCommentReactions get a list of reactions from a comment of an issue
|
||||||
|
func (c *Client) GetIssueCommentReactions(owner, repo string, commentID int64) ([]*Reaction, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
reactions := make([]*Reaction, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID), nil, nil, &reactions)
|
||||||
|
return reactions, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// editReactionOption contain the reaction type
|
||||||
|
type editReactionOption struct {
|
||||||
|
Reaction string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostIssueReaction add a reaction to an issue
|
||||||
|
func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction string) (*Reaction, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
reactionResponse := new(Reaction)
|
||||||
|
body, err := json.Marshal(&editReactionOption{Reaction: reaction})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index),
|
||||||
|
jsonHeader, bytes.NewReader(body), reactionResponse)
|
||||||
|
return reactionResponse, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIssueReaction remove a reaction from an issue
|
||||||
|
func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&editReactionOption{Reaction: reaction})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostIssueCommentReaction add a reaction to a comment of an issue
|
||||||
|
func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Reaction, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
reactionResponse := new(Reaction)
|
||||||
|
body, err := json.Marshal(&editReactionOption{Reaction: reaction})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID),
|
||||||
|
jsonHeader, bytes.NewReader(body), reactionResponse)
|
||||||
|
return reactionResponse, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIssueCommentReaction remove a reaction from a comment of an issue
|
||||||
|
func (c *Client) DeleteIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&editReactionOption{Reaction: reaction})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID),
|
||||||
|
jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
57
vendor/code.gitea.io/sdk/gitea/issue_stopwatch.go
generated
vendored
Normal file
57
vendor/code.gitea.io/sdk/gitea/issue_stopwatch.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StopWatch represents a running stopwatch of an issue / pr
|
||||||
|
type StopWatch struct {
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
Seconds int64 `json:"seconds"`
|
||||||
|
Duration string `json:"duration"`
|
||||||
|
IssueIndex int64 `json:"issue_index"`
|
||||||
|
IssueTitle string `json:"issue_title"`
|
||||||
|
RepoOwnerName string `json:"repo_owner_name"`
|
||||||
|
RepoName string `json:"repo_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMyStopwatches list all stopwatches
|
||||||
|
func (c *Client) GetMyStopwatches() ([]*StopWatch, *Response, error) {
|
||||||
|
stopwatches := make([]*StopWatch, 0, 1)
|
||||||
|
resp, err := c.getParsedResponse("GET", "/user/stopwatches", nil, nil, &stopwatches)
|
||||||
|
return stopwatches, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIssueStopwatch delete / cancel a specific stopwatch
|
||||||
|
func (c *Client) DeleteIssueStopwatch(owner, repo string, index int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/delete", owner, repo, index), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartIssueStopWatch starts a stopwatch for an existing issue for a given
|
||||||
|
// repository
|
||||||
|
func (c *Client) StartIssueStopWatch(owner, repo string, index int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/start", owner, repo, index), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopIssueStopWatch stops an existing stopwatch for an issue in a given
|
||||||
|
// repository
|
||||||
|
func (c *Client) StopIssueStopWatch(owner, repo string, index int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/stop", owner, repo, index), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
87
vendor/code.gitea.io/sdk/gitea/issue_subscription.go
generated
vendored
Normal file
87
vendor/code.gitea.io/sdk/gitea/issue_subscription.go
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetIssueSubscribers get list of users who subscribed on an issue
|
||||||
|
func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
subscribers := make([]*User, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions", owner, repo, index), nil, nil, &subscribers)
|
||||||
|
return subscribers, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddIssueSubscription Subscribe user to issue
|
||||||
|
func (c *Client) AddIssueSubscription(owner, repo string, index int64, user string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
if status == http.StatusCreated {
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
if status == http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("already subscribed")
|
||||||
|
}
|
||||||
|
return resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIssueSubscription unsubscribe user from issue
|
||||||
|
func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
if status == http.StatusCreated {
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
if status == http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("already unsubscribed")
|
||||||
|
}
|
||||||
|
return resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckIssueSubscription check if current user is subscribed to an issue
|
||||||
|
func (c *Client) CheckIssueSubscription(owner, repo string, index int64) (*WatchInfo, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
wi := new(WatchInfo)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/check", owner, repo, index), nil, nil, wi)
|
||||||
|
return wi, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueSubscribe subscribe current user to an issue
|
||||||
|
func (c *Client) IssueSubscribe(owner, repo string, index int64) (*Response, error) {
|
||||||
|
u, _, err := c.GetMyUserInfo()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.AddIssueSubscription(owner, repo, index, u.UserName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueUnSubscribe unsubscribe current user from an issue
|
||||||
|
func (c *Client) IssueUnSubscribe(owner, repo string, index int64) (*Response, error) {
|
||||||
|
u, _, err := c.GetMyUserInfo()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.DeleteIssueSubscription(owner, repo, index, u.UserName)
|
||||||
|
}
|
||||||
97
vendor/code.gitea.io/sdk/gitea/issue_template.go
generated
vendored
Normal file
97
vendor/code.gitea.io/sdk/gitea/issue_template.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IssueTemplate provides metadata and content on an issue template.
|
||||||
|
// There are two types of issue templates: .Markdown- and .Form-based.
|
||||||
|
type IssueTemplate struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
About string `json:"about"`
|
||||||
|
Filename string `json:"file_name"`
|
||||||
|
IssueTitle string `json:"title"`
|
||||||
|
IssueLabels []string `json:"labels"`
|
||||||
|
IssueRef string `json:"ref"`
|
||||||
|
// If non-nil, this is a form-based template
|
||||||
|
Form []IssueFormElement `json:"body"`
|
||||||
|
// Should only be used when .Form is nil.
|
||||||
|
MarkdownContent string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueFormElement describes a part of a IssueTemplate form
|
||||||
|
type IssueFormElement struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Type IssueFormElementType `json:"type"`
|
||||||
|
Attributes IssueFormElementAttributes `json:"attributes"`
|
||||||
|
Validations IssueFormElementValidations `json:"validations"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueFormElementAttributes contains the combined set of attributes available on all element types.
|
||||||
|
type IssueFormElementAttributes struct {
|
||||||
|
// required for all element types.
|
||||||
|
// A brief description of the expected user input, which is also displayed in the form.
|
||||||
|
Label string `json:"label"`
|
||||||
|
// required for element types "dropdown", "checkboxes"
|
||||||
|
// for dropdown, contains the available options
|
||||||
|
Options []string `json:"options"`
|
||||||
|
// for element types "markdown", "textarea", "input"
|
||||||
|
// Text that is pre-filled in the input
|
||||||
|
Value string `json:"value"`
|
||||||
|
// for element types "textarea", "input", "dropdown", "checkboxes"
|
||||||
|
// A description of the text area to provide context or guidance, which is displayed in the form.
|
||||||
|
Description string `json:"description"`
|
||||||
|
// for element types "textarea", "input"
|
||||||
|
// A semi-opaque placeholder that renders in the text area when empty.
|
||||||
|
Placeholder string `json:"placeholder"`
|
||||||
|
// for element types "textarea"
|
||||||
|
// A language specifier. If set, the input is rendered as codeblock with syntax highlighting.
|
||||||
|
SyntaxHighlighting string `json:"render"`
|
||||||
|
// for element types "dropdown"
|
||||||
|
Multiple bool `json:"multiple"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueFormElementValidations contains the combined set of validations available on all element types.
|
||||||
|
type IssueFormElementValidations struct {
|
||||||
|
// for all element types
|
||||||
|
Required bool `json:"required"`
|
||||||
|
// for element types "input"
|
||||||
|
IsNumber bool `json:"is_number"`
|
||||||
|
// for element types "input"
|
||||||
|
Regex string `json:"regex"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueFormElementType is an enum
|
||||||
|
type IssueFormElementType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// IssueFormElementMarkdown is markdown rendered to the form for context, but omitted in the resulting issue
|
||||||
|
IssueFormElementMarkdown IssueFormElementType = "markdown"
|
||||||
|
// IssueFormElementTextarea is a multi line input
|
||||||
|
IssueFormElementTextarea IssueFormElementType = "textarea"
|
||||||
|
// IssueFormElementInput is a single line input
|
||||||
|
IssueFormElementInput IssueFormElementType = "input"
|
||||||
|
// IssueFormElementDropdown is a select form
|
||||||
|
IssueFormElementDropdown IssueFormElementType = "dropdown"
|
||||||
|
// IssueFormElementCheckboxes are a multi checkbox input
|
||||||
|
IssueFormElementCheckboxes IssueFormElementType = "checkboxes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetIssueTemplates lists all issue templates of the repository
|
||||||
|
func (c *Client) GetIssueTemplates(owner, repo string) ([]*IssueTemplate, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
templates := new([]*IssueTemplate)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issue_templates", owner, repo), nil, nil, templates)
|
||||||
|
return *templates, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsForm tells if this template is a form instead of a markdown-based template.
|
||||||
|
func (t IssueTemplate) IsForm() bool {
|
||||||
|
return t.Form != nil
|
||||||
|
}
|
||||||
142
vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go
generated
vendored
Normal file
142
vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TrackedTime worked time for an issue / pr
|
||||||
|
type TrackedTime struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
// Time in seconds
|
||||||
|
Time int64 `json:"time"`
|
||||||
|
// deprecated (only for backwards compatibility)
|
||||||
|
UserID int64 `json:"user_id"`
|
||||||
|
UserName string `json:"user_name"`
|
||||||
|
// deprecated (only for backwards compatibility)
|
||||||
|
IssueID int64 `json:"issue_id"`
|
||||||
|
Issue *Issue `json:"issue"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTrackedTimesOptions options for listing repository's tracked times
|
||||||
|
type ListTrackedTimesOptions struct {
|
||||||
|
ListOptions
|
||||||
|
Since time.Time
|
||||||
|
Before time.Time
|
||||||
|
// User filter is only used by ListRepoTrackedTimes !!!
|
||||||
|
User string
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *ListTrackedTimesOptions) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
|
||||||
|
if !opt.Since.IsZero() {
|
||||||
|
query.Add("since", opt.Since.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
if !opt.Before.IsZero() {
|
||||||
|
query.Add("before", opt.Before.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opt.User) != 0 {
|
||||||
|
query.Add("user", opt.User)
|
||||||
|
}
|
||||||
|
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoTrackedTimes list tracked times of a repository
|
||||||
|
func (c *Client) ListRepoTrackedTimes(owner, repo string, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/times", owner, repo))
|
||||||
|
opt.setDefaults()
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
times := make([]*TrackedTime, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, ×)
|
||||||
|
return times, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMyTrackedTimes list tracked times of the current user
|
||||||
|
func (c *Client) GetMyTrackedTimes() ([]*TrackedTime, *Response, error) {
|
||||||
|
times := make([]*TrackedTime, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", "/user/times", jsonHeader, nil, ×)
|
||||||
|
return times, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTimeOption options for adding time to an issue
|
||||||
|
type AddTimeOption struct {
|
||||||
|
// time in seconds
|
||||||
|
Time int64 `json:"time"`
|
||||||
|
// optional
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
// optional
|
||||||
|
User string `json:"user_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the AddTimeOption struct
|
||||||
|
func (opt AddTimeOption) Validate() error {
|
||||||
|
if opt.Time == 0 {
|
||||||
|
return fmt.Errorf("no time to add")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTime adds time to issue with the given index
|
||||||
|
func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*TrackedTime, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
t := new(TrackedTime)
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index),
|
||||||
|
jsonHeader, bytes.NewReader(body), t)
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIssueTrackedTimes list tracked times of a single issue for a given repository
|
||||||
|
func (c *Client) ListIssueTrackedTimes(owner, repo string, index int64, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index))
|
||||||
|
opt.setDefaults()
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
times := make([]*TrackedTime, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, ×)
|
||||||
|
return times, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetIssueTime reset tracked time of a single issue for a given repository
|
||||||
|
func (c *Client) ResetIssueTime(owner, repo string, index int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), jsonHeader, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTime delete a specific tracked time by id of a single issue for a given repository
|
||||||
|
func (c *Client) DeleteTime(owner, repo string, index, timeID int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times/%d", owner, repo, index, timeID), jsonHeader, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
40
vendor/code.gitea.io/sdk/gitea/list_options.go
generated
vendored
Normal file
40
vendor/code.gitea.io/sdk/gitea/list_options.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListOptions options for using Gitea's API pagination
|
||||||
|
type ListOptions struct {
|
||||||
|
// Setting Page to -1 disables pagination on endpoints that support it.
|
||||||
|
// Page numbering starts at 1.
|
||||||
|
Page int
|
||||||
|
// The default value depends on the server config DEFAULT_PAGING_NUM
|
||||||
|
// The highest valid value depends on the server config MAX_RESPONSE_ITEMS
|
||||||
|
PageSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o ListOptions) getURLQuery() url.Values {
|
||||||
|
query := make(url.Values)
|
||||||
|
query.Add("page", fmt.Sprintf("%d", o.Page))
|
||||||
|
query.Add("limit", fmt.Sprintf("%d", o.PageSize))
|
||||||
|
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
// setDefaults applies default pagination options.
|
||||||
|
// If .Page is set to -1, it will disable pagination.
|
||||||
|
// WARNING: This function is not idempotent, make sure to never call this method twice!
|
||||||
|
func (o *ListOptions) setDefaults() {
|
||||||
|
if o.Page < 0 {
|
||||||
|
o.Page, o.PageSize = 0, 0
|
||||||
|
return
|
||||||
|
} else if o.Page == 0 {
|
||||||
|
o.Page = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
257
vendor/code.gitea.io/sdk/gitea/notifications.go
generated
vendored
Normal file
257
vendor/code.gitea.io/sdk/gitea/notifications.go
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NotificationThread expose Notification on API
|
||||||
|
type NotificationThread struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Repository *Repository `json:"repository"`
|
||||||
|
Subject *NotificationSubject `json:"subject"`
|
||||||
|
Unread bool `json:"unread"`
|
||||||
|
Pinned bool `json:"pinned"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotificationSubject contains the notification subject (Issue/Pull/Commit)
|
||||||
|
type NotificationSubject struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
LatestCommentURL string `json:"latest_comment_url"`
|
||||||
|
LatestCommentHTMLURL string `json:"latest_comment_html_url"`
|
||||||
|
Type NotifySubjectType `json:"type"`
|
||||||
|
State NotifySubjectState `json:"state"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyStatus notification status type
|
||||||
|
type NotifyStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NotifyStatusUnread was not read
|
||||||
|
NotifyStatusUnread NotifyStatus = "unread"
|
||||||
|
// NotifyStatusRead was already read by user
|
||||||
|
NotifyStatusRead NotifyStatus = "read"
|
||||||
|
// NotifyStatusPinned notification is pinned by user
|
||||||
|
NotifyStatusPinned NotifyStatus = "pinned"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NotifySubjectType represent type of notification subject
|
||||||
|
type NotifySubjectType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NotifySubjectIssue an issue is subject of an notification
|
||||||
|
NotifySubjectIssue NotifySubjectType = "Issue"
|
||||||
|
// NotifySubjectPull an pull is subject of an notification
|
||||||
|
NotifySubjectPull NotifySubjectType = "Pull"
|
||||||
|
// NotifySubjectCommit an commit is subject of an notification
|
||||||
|
NotifySubjectCommit NotifySubjectType = "Commit"
|
||||||
|
// NotifySubjectRepository an repository is subject of an notification
|
||||||
|
NotifySubjectRepository NotifySubjectType = "Repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NotifySubjectState reflect state of notification subject
|
||||||
|
type NotifySubjectState string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NotifySubjectOpen if subject is a pull/issue and is open at the moment
|
||||||
|
NotifySubjectOpen NotifySubjectState = "open"
|
||||||
|
// NotifySubjectClosed if subject is a pull/issue and is closed at the moment
|
||||||
|
NotifySubjectClosed NotifySubjectState = "closed"
|
||||||
|
// NotifySubjectMerged if subject is a pull and got merged
|
||||||
|
NotifySubjectMerged NotifySubjectState = "merged"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListNotificationOptions represents the filter options
|
||||||
|
type ListNotificationOptions struct {
|
||||||
|
ListOptions
|
||||||
|
Since time.Time
|
||||||
|
Before time.Time
|
||||||
|
Status []NotifyStatus
|
||||||
|
SubjectTypes []NotifySubjectType
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkNotificationOptions represents the filter & modify options
|
||||||
|
type MarkNotificationOptions struct {
|
||||||
|
LastReadAt time.Time
|
||||||
|
Status []NotifyStatus
|
||||||
|
ToStatus NotifyStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode encode options to url query
|
||||||
|
func (opt *ListNotificationOptions) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
if !opt.Since.IsZero() {
|
||||||
|
query.Add("since", opt.Since.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
if !opt.Before.IsZero() {
|
||||||
|
query.Add("before", opt.Before.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
for _, s := range opt.Status {
|
||||||
|
query.Add("status-types", string(s))
|
||||||
|
}
|
||||||
|
for _, s := range opt.SubjectTypes {
|
||||||
|
query.Add("subject-type", string(s))
|
||||||
|
}
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateUserOption struct
|
||||||
|
func (opt ListNotificationOptions) Validate(c *Client) error {
|
||||||
|
if len(opt.Status) != 0 {
|
||||||
|
return c.checkServerVersionGreaterThanOrEqual(version1_12_3)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode encode options to url query
|
||||||
|
func (opt *MarkNotificationOptions) QueryEncode() string {
|
||||||
|
query := make(url.Values)
|
||||||
|
if !opt.LastReadAt.IsZero() {
|
||||||
|
query.Add("last_read_at", opt.LastReadAt.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
for _, s := range opt.Status {
|
||||||
|
query.Add("status-types", string(s))
|
||||||
|
}
|
||||||
|
if len(opt.ToStatus) != 0 {
|
||||||
|
query.Add("to-status", string(opt.ToStatus))
|
||||||
|
}
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateUserOption struct
|
||||||
|
func (opt MarkNotificationOptions) Validate(c *Client) error {
|
||||||
|
if len(opt.Status) != 0 || len(opt.ToStatus) != 0 {
|
||||||
|
return c.checkServerVersionGreaterThanOrEqual(version1_12_3)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckNotifications list users's notification threads
|
||||||
|
func (c *Client) CheckNotifications() (int64, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
new := struct {
|
||||||
|
New int64 `json:"new"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
resp, err := c.getParsedResponse("GET", "/notifications/new", jsonHeader, nil, &new)
|
||||||
|
return new.New, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNotification get notification thread by ID
|
||||||
|
func (c *Client) GetNotification(id int64) (*NotificationThread, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
thread := new(NotificationThread)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/notifications/threads/%d", id), nil, nil, thread)
|
||||||
|
return thread, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadNotification mark notification thread as read by ID
|
||||||
|
// It optionally takes a second argument if status has to be set other than 'read'
|
||||||
|
// The relevant notification will be returned as the first parameter when the Gitea server is 1.16.0 or higher.
|
||||||
|
func (c *Client) ReadNotification(id int64, status ...NotifyStatus) (*NotificationThread, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link := fmt.Sprintf("/notifications/threads/%d", id)
|
||||||
|
if len(status) != 0 {
|
||||||
|
link += fmt.Sprintf("?to-status=%s", status[0])
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err == nil {
|
||||||
|
thread := &NotificationThread{}
|
||||||
|
resp, err := c.getParsedResponse("PATCH", link, nil, nil, thread)
|
||||||
|
return thread, resp, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PATCH", link, nil, nil)
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNotifications list users's notification threads
|
||||||
|
func (c *Client) ListNotifications(opt ListNotificationOptions) ([]*NotificationThread, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse("/notifications")
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
threads := make([]*NotificationThread, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &threads)
|
||||||
|
return threads, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadNotifications mark notification threads as read
|
||||||
|
// The relevant notifications will only be returned as the first parameter when the Gitea server is 1.16.0 or higher.
|
||||||
|
func (c *Client) ReadNotifications(opt MarkNotificationOptions) ([]*NotificationThread, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse("/notifications")
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err == nil {
|
||||||
|
threads := make([]*NotificationThread, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("PUT", link.String(), nil, nil, &threads)
|
||||||
|
return threads, resp, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", link.String(), nil, nil)
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoNotifications list users's notification threads on a specific repo
|
||||||
|
func (c *Client) ListRepoNotifications(owner, repo string, opt ListNotificationOptions) ([]*NotificationThread, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, repo))
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
threads := make([]*NotificationThread, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &threads)
|
||||||
|
return threads, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadRepoNotifications mark notification threads as read on a specific repo
|
||||||
|
// The relevant notifications will only be returned as the first parameter when the Gitea server is 1.16.0 or higher.
|
||||||
|
func (c *Client) ReadRepoNotifications(owner, repo string, opt MarkNotificationOptions) ([]*NotificationThread, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, repo))
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err == nil {
|
||||||
|
threads := make([]*NotificationThread, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("PUT", link.String(), nil, nil, &threads)
|
||||||
|
return threads, resp, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", link.String(), nil, nil)
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
93
vendor/code.gitea.io/sdk/gitea/oauth2.go
generated
vendored
Normal file
93
vendor/code.gitea.io/sdk/gitea/oauth2.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Oauth2 represents an Oauth2 Application
|
||||||
|
type Oauth2 struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ClientID string `json:"client_id"`
|
||||||
|
ClientSecret string `json:"client_secret"`
|
||||||
|
RedirectURIs []string `json:"redirect_uris"`
|
||||||
|
ConfidentialClient bool `json:"confidential_client"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOauth2Option for listing Oauth2 Applications
|
||||||
|
type ListOauth2Option struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOauth2Option required options for creating an Application
|
||||||
|
type CreateOauth2Option struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
ConfidentialClient bool `json:"confidential_client"`
|
||||||
|
RedirectURIs []string `json:"redirect_uris"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOauth2 create an Oauth2 Application and returns a completed Oauth2 object.
|
||||||
|
func (c *Client) CreateOauth2(opt CreateOauth2Option) (*Oauth2, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
oauth := new(Oauth2)
|
||||||
|
resp, err := c.getParsedResponse("POST", "/user/applications/oauth2", jsonHeader, bytes.NewReader(body), oauth)
|
||||||
|
return oauth, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOauth2 a specific Oauth2 Application by ID and return a completed Oauth2 object.
|
||||||
|
func (c *Client) UpdateOauth2(oauth2id int64, opt CreateOauth2Option) (*Oauth2, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
oauth := new(Oauth2)
|
||||||
|
resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), jsonHeader, bytes.NewReader(body), oauth)
|
||||||
|
return oauth, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOauth2 a specific Oauth2 Application by ID.
|
||||||
|
func (c *Client) GetOauth2(oauth2id int64) (*Oauth2, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
oauth2s := &Oauth2{}
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), nil, nil, &oauth2s)
|
||||||
|
return oauth2s, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOauth2 all of your Oauth2 Applications.
|
||||||
|
func (c *Client) ListOauth2(opt ListOauth2Option) ([]*Oauth2, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
oauth2s := make([]*Oauth2, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/applications/oauth2?%s", opt.getURLQuery().Encode()), nil, nil, &oauth2s)
|
||||||
|
return oauth2s, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOauth2 delete an Oauth2 application by ID
|
||||||
|
func (c *Client) DeleteOauth2(oauth2id int64) (*Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
155
vendor/code.gitea.io/sdk/gitea/org.go
generated
vendored
Normal file
155
vendor/code.gitea.io/sdk/gitea/org.go
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Organization represents an organization
|
||||||
|
type Organization struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
UserName string `json:"username"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
AvatarURL string `json:"avatar_url"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Website string `json:"website"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
Visibility string `json:"visibility"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// VisibleType defines the visibility
|
||||||
|
type VisibleType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// VisibleTypePublic Visible for everyone
|
||||||
|
VisibleTypePublic VisibleType = "public"
|
||||||
|
|
||||||
|
// VisibleTypeLimited Visible for every connected user
|
||||||
|
VisibleTypeLimited VisibleType = "limited"
|
||||||
|
|
||||||
|
// VisibleTypePrivate Visible only for organization's members
|
||||||
|
VisibleTypePrivate VisibleType = "private"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListOrgsOptions options for listing organizations
|
||||||
|
type ListOrgsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMyOrgs list all of current user's organizations
|
||||||
|
func (c *Client) ListMyOrgs(opt ListOrgsOptions) ([]*Organization, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
orgs := make([]*Organization, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/orgs?%s", opt.getURLQuery().Encode()), nil, nil, &orgs)
|
||||||
|
return orgs, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListUserOrgs list all of some user's organizations
|
||||||
|
func (c *Client) ListUserOrgs(user string, opt ListOrgsOptions) ([]*Organization, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
orgs := make([]*Organization, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs?%s", user, opt.getURLQuery().Encode()), nil, nil, &orgs)
|
||||||
|
return orgs, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrg get one organization by name
|
||||||
|
func (c *Client) GetOrg(orgname string) (*Organization, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&orgname); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
org := new(Organization)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s", orgname), nil, nil, org)
|
||||||
|
return org, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOrgOption options for creating an organization
|
||||||
|
type CreateOrgOption struct {
|
||||||
|
Name string `json:"username"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Website string `json:"website"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
Visibility VisibleType `json:"visibility"`
|
||||||
|
RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkVisibilityOpt check if mode exist
|
||||||
|
func checkVisibilityOpt(v VisibleType) bool {
|
||||||
|
return v == VisibleTypePublic || v == VisibleTypeLimited || v == VisibleTypePrivate
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateOrgOption struct
|
||||||
|
func (opt CreateOrgOption) Validate() error {
|
||||||
|
if len(opt.Name) == 0 {
|
||||||
|
return fmt.Errorf("empty org name")
|
||||||
|
}
|
||||||
|
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
|
||||||
|
return fmt.Errorf("infalid bisibility option")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOrg creates an organization
|
||||||
|
func (c *Client) CreateOrg(opt CreateOrgOption) (*Organization, *Response, error) {
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
org := new(Organization)
|
||||||
|
resp, err := c.getParsedResponse("POST", "/orgs", jsonHeader, bytes.NewReader(body), org)
|
||||||
|
return org, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditOrgOption options for editing an organization
|
||||||
|
type EditOrgOption struct {
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Website string `json:"website"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
Visibility VisibleType `json:"visibility"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the EditOrgOption struct
|
||||||
|
func (opt EditOrgOption) Validate() error {
|
||||||
|
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
|
||||||
|
return fmt.Errorf("infalid bisibility option")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditOrg modify one organization via options
|
||||||
|
func (c *Client) EditOrg(orgname string, opt EditOrgOption) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&orgname); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PATCH", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOrg deletes an organization
|
||||||
|
func (c *Client) DeleteOrg(orgname string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&orgname); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
29
vendor/code.gitea.io/sdk/gitea/org_action.go
generated
vendored
Normal file
29
vendor/code.gitea.io/sdk/gitea/org_action.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListOrgMembershipOption list OrgMembership options
|
||||||
|
type ListOrgActionSecretOption struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrgMembership list an organization's members
|
||||||
|
func (c *Client) ListOrgActionSecret(org string, opt ListOrgActionSecretOption) ([]*Secret, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
secrets := make([]*Secret, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/actions/secrets", org))
|
||||||
|
link.RawQuery = opt.getURLQuery().Encode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &secrets)
|
||||||
|
return secrets, resp, err
|
||||||
|
}
|
||||||
142
vendor/code.gitea.io/sdk/gitea/org_member.go
generated
vendored
Normal file
142
vendor/code.gitea.io/sdk/gitea/org_member.go
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeleteOrgMembership remove a member from an organization
|
||||||
|
func (c *Client) DeleteOrgMembership(org, user string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/members/%s", org, user), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrgMembershipOption list OrgMembership options
|
||||||
|
type ListOrgMembershipOption struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrgMembership list an organization's members
|
||||||
|
func (c *Client) ListOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
users := make([]*User, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/members", org))
|
||||||
|
link.RawQuery = opt.getURLQuery().Encode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users)
|
||||||
|
return users, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPublicOrgMembership list an organization's members
|
||||||
|
func (c *Client) ListPublicOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
users := make([]*User, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/public_members", org))
|
||||||
|
link.RawQuery = opt.getURLQuery().Encode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users)
|
||||||
|
return users, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckOrgMembership Check if a user is a member of an organization
|
||||||
|
func (c *Client) CheckOrgMembership(org, user string) (bool, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/members/%s", org, user), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, resp, err
|
||||||
|
}
|
||||||
|
switch status {
|
||||||
|
case http.StatusNoContent:
|
||||||
|
return true, resp, nil
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return false, resp, nil
|
||||||
|
default:
|
||||||
|
return false, resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckPublicOrgMembership Check if a user is a member of an organization
|
||||||
|
func (c *Client) CheckPublicOrgMembership(org, user string) (bool, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, resp, err
|
||||||
|
}
|
||||||
|
switch status {
|
||||||
|
case http.StatusNoContent:
|
||||||
|
return true, resp, nil
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return false, resp, nil
|
||||||
|
default:
|
||||||
|
return false, resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPublicOrgMembership publicize/conceal a user's membership
|
||||||
|
func (c *Client) SetPublicOrgMembership(org, user string, visible bool) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
status int
|
||||||
|
err error
|
||||||
|
resp *Response
|
||||||
|
)
|
||||||
|
if visible {
|
||||||
|
status, resp, err = c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil)
|
||||||
|
} else {
|
||||||
|
status, resp, err = c.getStatusCode("DELETE", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
switch status {
|
||||||
|
case http.StatusNoContent:
|
||||||
|
return resp, nil
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return resp, fmt.Errorf("forbidden")
|
||||||
|
default:
|
||||||
|
return resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrgPermissions represents the permissions for an user in an organization
|
||||||
|
type OrgPermissions struct {
|
||||||
|
CanCreateRepository bool `json:"can_create_repository"`
|
||||||
|
CanRead bool `json:"can_read"`
|
||||||
|
CanWrite bool `json:"can_write"`
|
||||||
|
IsAdmin bool `json:"is_admin"`
|
||||||
|
IsOwner bool `json:"is_owner"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrgPermissions returns user permissions for specific organization.
|
||||||
|
func (c *Client) GetOrgPermissions(org, user string) (*OrgPermissions, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
perm := &OrgPermissions{}
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs/%s/permissions", user, org), jsonHeader, nil, &perm)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return perm, resp, nil
|
||||||
|
}
|
||||||
285
vendor/code.gitea.io/sdk/gitea/org_team.go
generated
vendored
Normal file
285
vendor/code.gitea.io/sdk/gitea/org_team.go
generated
vendored
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Team represents a team in an organization
|
||||||
|
type Team struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Organization *Organization `json:"organization"`
|
||||||
|
Permission AccessMode `json:"permission"`
|
||||||
|
CanCreateOrgRepo bool `json:"can_create_org_repo"`
|
||||||
|
IncludesAllRepositories bool `json:"includes_all_repositories"`
|
||||||
|
Units []RepoUnitType `json:"units"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoUnitType represent all unit types of a repo gitea currently offer
|
||||||
|
type RepoUnitType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RepoUnitCode represent file view of a repository
|
||||||
|
RepoUnitCode RepoUnitType = "repo.code"
|
||||||
|
// RepoUnitIssues represent issues of a repository
|
||||||
|
RepoUnitIssues RepoUnitType = "repo.issues"
|
||||||
|
// RepoUnitPulls represent pulls of a repository
|
||||||
|
RepoUnitPulls RepoUnitType = "repo.pulls"
|
||||||
|
// RepoUnitExtIssues represent external issues of a repository
|
||||||
|
RepoUnitExtIssues RepoUnitType = "repo.ext_issues"
|
||||||
|
// RepoUnitWiki represent wiki of a repository
|
||||||
|
RepoUnitWiki RepoUnitType = "repo.wiki"
|
||||||
|
// RepoUnitExtWiki represent external wiki of a repository
|
||||||
|
RepoUnitExtWiki RepoUnitType = "repo.ext_wiki"
|
||||||
|
// RepoUnitReleases represent releases of a repository
|
||||||
|
RepoUnitReleases RepoUnitType = "repo.releases"
|
||||||
|
// RepoUnitProjects represent projects of a repository
|
||||||
|
RepoUnitProjects RepoUnitType = "repo.projects"
|
||||||
|
// RepoUnitPackages represents packages of a repository
|
||||||
|
RepoUnitPackages RepoUnitType = "repo.packages"
|
||||||
|
// RepoUnitActions represents actions of a repository
|
||||||
|
RepoUnitActions RepoUnitType = "repo.actions"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListTeamsOptions options for listing teams
|
||||||
|
type ListTeamsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrgTeams lists all teams of an organization
|
||||||
|
func (c *Client) ListOrgTeams(org string, opt ListTeamsOptions) ([]*Team, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
teams := make([]*Team, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams?%s", org, opt.getURLQuery().Encode()), nil, nil, &teams)
|
||||||
|
return teams, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMyTeams lists all the teams of the current user
|
||||||
|
func (c *Client) ListMyTeams(opt *ListTeamsOptions) ([]*Team, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
teams := make([]*Team, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/teams?%s", opt.getURLQuery().Encode()), nil, nil, &teams)
|
||||||
|
return teams, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTeam gets a team by ID
|
||||||
|
func (c *Client) GetTeam(id int64) (*Team, *Response, error) {
|
||||||
|
t := new(Team)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d", id), nil, nil, t)
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchTeamsOptions options for searching teams.
|
||||||
|
type SearchTeamsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
Query string
|
||||||
|
IncludeDescription bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o SearchTeamsOptions) getURLQuery() url.Values {
|
||||||
|
query := make(url.Values)
|
||||||
|
query.Add("page", fmt.Sprintf("%d", o.Page))
|
||||||
|
query.Add("limit", fmt.Sprintf("%d", o.PageSize))
|
||||||
|
query.Add("q", o.Query)
|
||||||
|
query.Add("include_desc", fmt.Sprintf("%t", o.IncludeDescription))
|
||||||
|
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
// TeamSearchResults is the JSON struct that is returned from Team search API.
|
||||||
|
type TeamSearchResults struct {
|
||||||
|
OK bool `json:"ok"`
|
||||||
|
Error string `json:"error"`
|
||||||
|
Data []*Team `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchOrgTeams search for teams in a org.
|
||||||
|
func (c *Client) SearchOrgTeams(org string, opt *SearchTeamsOptions) ([]*Team, *Response, error) {
|
||||||
|
responseBody := TeamSearchResults{}
|
||||||
|
opt.setDefaults()
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams/search?%s", org, opt.getURLQuery().Encode()), nil, nil, &responseBody)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
if !responseBody.OK {
|
||||||
|
return nil, resp, fmt.Errorf("gitea error: %v", responseBody.Error)
|
||||||
|
}
|
||||||
|
return responseBody.Data, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTeamOption options for creating a team
|
||||||
|
type CreateTeamOption struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Permission AccessMode `json:"permission"`
|
||||||
|
CanCreateOrgRepo bool `json:"can_create_org_repo"`
|
||||||
|
IncludesAllRepositories bool `json:"includes_all_repositories"`
|
||||||
|
Units []RepoUnitType `json:"units"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateTeamOption struct
|
||||||
|
func (opt *CreateTeamOption) Validate() error {
|
||||||
|
if opt.Permission == AccessModeOwner {
|
||||||
|
opt.Permission = AccessModeAdmin
|
||||||
|
} else if opt.Permission != AccessModeRead && opt.Permission != AccessModeWrite && opt.Permission != AccessModeAdmin {
|
||||||
|
return fmt.Errorf("permission mode invalid")
|
||||||
|
}
|
||||||
|
if len(opt.Name) == 0 {
|
||||||
|
return fmt.Errorf("name required")
|
||||||
|
}
|
||||||
|
if len(opt.Name) > 30 {
|
||||||
|
return fmt.Errorf("name to long")
|
||||||
|
}
|
||||||
|
if len(opt.Description) > 255 {
|
||||||
|
return fmt.Errorf("description to long")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTeam creates a team for an organization
|
||||||
|
func (c *Client) CreateTeam(org string, opt CreateTeamOption) (*Team, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := (&opt).Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
t := new(Team)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/orgs/%s/teams", org), jsonHeader, bytes.NewReader(body), t)
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditTeamOption options for editing a team
|
||||||
|
type EditTeamOption struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description *string `json:"description"`
|
||||||
|
Permission AccessMode `json:"permission"`
|
||||||
|
CanCreateOrgRepo *bool `json:"can_create_org_repo"`
|
||||||
|
IncludesAllRepositories *bool `json:"includes_all_repositories"`
|
||||||
|
Units []RepoUnitType `json:"units"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the EditTeamOption struct
|
||||||
|
func (opt *EditTeamOption) Validate() error {
|
||||||
|
if opt.Permission == AccessModeOwner {
|
||||||
|
opt.Permission = AccessModeAdmin
|
||||||
|
} else if opt.Permission != AccessModeRead && opt.Permission != AccessModeWrite && opt.Permission != AccessModeAdmin {
|
||||||
|
return fmt.Errorf("permission mode invalid")
|
||||||
|
}
|
||||||
|
if len(opt.Name) == 0 {
|
||||||
|
return fmt.Errorf("name required")
|
||||||
|
}
|
||||||
|
if len(opt.Name) > 30 {
|
||||||
|
return fmt.Errorf("name to long")
|
||||||
|
}
|
||||||
|
if opt.Description != nil && len(*opt.Description) > 255 {
|
||||||
|
return fmt.Errorf("description to long")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditTeam edits a team of an organization
|
||||||
|
func (c *Client) EditTeam(id int64, opt EditTeamOption) (*Response, error) {
|
||||||
|
if err := (&opt).Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PATCH", fmt.Sprintf("/teams/%d", id), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTeam deletes a team of an organization
|
||||||
|
func (c *Client) DeleteTeam(id int64) (*Response, error) {
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d", id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTeamMembersOptions options for listing team's members
|
||||||
|
type ListTeamMembersOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTeamMembers lists all members of a team
|
||||||
|
func (c *Client) ListTeamMembers(id int64, opt ListTeamMembersOptions) ([]*User, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
members := make([]*User, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members?%s", id, opt.getURLQuery().Encode()), nil, nil, &members)
|
||||||
|
return members, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTeamMember gets a member of a team
|
||||||
|
func (c *Client) GetTeamMember(id int64, user string) (*User, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
m := new(User)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil, m)
|
||||||
|
return m, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTeamMember adds a member to a team
|
||||||
|
func (c *Client) AddTeamMember(id int64, user string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTeamMember removes a member from a team
|
||||||
|
func (c *Client) RemoveTeamMember(id int64, user string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTeamRepositoriesOptions options for listing team's repositories
|
||||||
|
type ListTeamRepositoriesOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTeamRepositories lists all repositories of a team
|
||||||
|
func (c *Client) ListTeamRepositories(id int64, opt ListTeamRepositoriesOptions) ([]*Repository, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
repos := make([]*Repository, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/repos?%s", id, opt.getURLQuery().Encode()), nil, nil, &repos)
|
||||||
|
return repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTeamRepository adds a repository to a team
|
||||||
|
func (c *Client) AddTeamRepository(id int64, org, repo string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTeamRepository removes a repository from a team
|
||||||
|
func (c *Client) RemoveTeamRepository(id int64, org, repo string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
93
vendor/code.gitea.io/sdk/gitea/package.go
generated
vendored
Normal file
93
vendor/code.gitea.io/sdk/gitea/package.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Package represents a package
|
||||||
|
type Package struct {
|
||||||
|
// the package's id
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
// the package's owner
|
||||||
|
Owner User `json:"owner"`
|
||||||
|
// the repo this package belongs to (if any)
|
||||||
|
Repository *string `json:"repository"`
|
||||||
|
// the package's creator
|
||||||
|
Creator User `json:"creator"`
|
||||||
|
// the type of package:
|
||||||
|
Type string `json:"type"`
|
||||||
|
// the name of the package
|
||||||
|
Name string `json:"name"`
|
||||||
|
// the version of the package
|
||||||
|
Version string `json:"version"`
|
||||||
|
// the date the package was uploaded
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PackageFile represents a file from a package
|
||||||
|
type PackageFile struct {
|
||||||
|
// the file's ID
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
// the size of the file in bytes
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
// the name of the file
|
||||||
|
Name string `json:"name"`
|
||||||
|
// the md5 hash of the file
|
||||||
|
MD5 string `json:"md5"`
|
||||||
|
// the sha1 hash of the file
|
||||||
|
SHA1 string `json:"sha1"`
|
||||||
|
// the sha256 hash of the file
|
||||||
|
SHA256 string `json:"sha256"`
|
||||||
|
// the sha512 hash of the file
|
||||||
|
SHA512 string `json:"sha512"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPackagesOptions options for listing packages
|
||||||
|
type ListPackagesOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPackages lists all the packages owned by a given owner (user, organisation)
|
||||||
|
func (c *Client) ListPackages(owner string, opt ListPackagesOptions) ([]*Package, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
packages := make([]*Package, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/packages/%s?%s", owner, opt.getURLQuery().Encode()), nil, nil, &packages)
|
||||||
|
return packages, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPackage gets the details of a specific package version
|
||||||
|
func (c *Client) GetPackage(owner, packageType, name, version string) (*Package, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &packageType, &name, &version); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
foundPackage := new(Package)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/packages/%s/%s/%s/%s", owner, packageType, name, version), nil, nil, foundPackage)
|
||||||
|
return foundPackage, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePackage deletes a specific package version
|
||||||
|
func (c *Client) DeletePackage(owner, packageType, name, version string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &packageType, &name, &version); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/packages/%s/%s/%s/%s", owner, packageType, name, version), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPackageFiles lists the files within a package
|
||||||
|
func (c *Client) ListPackageFiles(owner, packageType, name, version string) ([]*PackageFile, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &packageType, &name, &version); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
packageFiles := make([]*PackageFile, 0)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/packages/%s/%s/%s/%s/files", owner, packageType, name, version), nil, nil, &packageFiles)
|
||||||
|
return packageFiles, resp, err
|
||||||
|
}
|
||||||
383
vendor/code.gitea.io/sdk/gitea/pull.go
generated
vendored
Normal file
383
vendor/code.gitea.io/sdk/gitea/pull.go
generated
vendored
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PRBranchInfo information about a branch
|
||||||
|
type PRBranchInfo struct {
|
||||||
|
Name string `json:"label"`
|
||||||
|
Ref string `json:"ref"`
|
||||||
|
Sha string `json:"sha"`
|
||||||
|
RepoID int64 `json:"repo_id"`
|
||||||
|
Repository *Repository `json:"repo"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullRequest represents a pull request
|
||||||
|
type PullRequest struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Index int64 `json:"number"`
|
||||||
|
Poster *User `json:"user"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Labels []*Label `json:"labels"`
|
||||||
|
Milestone *Milestone `json:"milestone"`
|
||||||
|
Assignee *User `json:"assignee"`
|
||||||
|
Assignees []*User `json:"assignees"`
|
||||||
|
State StateType `json:"state"`
|
||||||
|
IsLocked bool `json:"is_locked"`
|
||||||
|
Comments int `json:"comments"`
|
||||||
|
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
DiffURL string `json:"diff_url"`
|
||||||
|
PatchURL string `json:"patch_url"`
|
||||||
|
|
||||||
|
Mergeable bool `json:"mergeable"`
|
||||||
|
HasMerged bool `json:"merged"`
|
||||||
|
Merged *time.Time `json:"merged_at"`
|
||||||
|
MergedCommitID *string `json:"merge_commit_sha"`
|
||||||
|
MergedBy *User `json:"merged_by"`
|
||||||
|
AllowMaintainerEdit bool `json:"allow_maintainer_edit"`
|
||||||
|
|
||||||
|
Base *PRBranchInfo `json:"base"`
|
||||||
|
Head *PRBranchInfo `json:"head"`
|
||||||
|
MergeBase string `json:"merge_base"`
|
||||||
|
|
||||||
|
Deadline *time.Time `json:"due_date"`
|
||||||
|
Created *time.Time `json:"created_at"`
|
||||||
|
Updated *time.Time `json:"updated_at"`
|
||||||
|
Closed *time.Time `json:"closed_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangedFile is a changed file in a diff
|
||||||
|
type ChangedFile struct {
|
||||||
|
Filename string `json:"filename"`
|
||||||
|
PreviousFilename string `json:"previous_filename"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Additions int `json:"additions"`
|
||||||
|
Deletions int `json:"deletions"`
|
||||||
|
Changes int `json:"changes"`
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
ContentsURL string `json:"contents_url"`
|
||||||
|
RawURL string `json:"raw_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPullRequestsOptions options for listing pull requests
|
||||||
|
type ListPullRequestsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
State StateType `json:"state"`
|
||||||
|
// oldest, recentupdate, leastupdate, mostcomment, leastcomment, priority
|
||||||
|
Sort string
|
||||||
|
Milestone int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergeStyle is used specify how a pull is merged
|
||||||
|
type MergeStyle string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// MergeStyleMerge merge pull as usual
|
||||||
|
MergeStyleMerge MergeStyle = "merge"
|
||||||
|
// MergeStyleRebase rebase pull
|
||||||
|
MergeStyleRebase MergeStyle = "rebase"
|
||||||
|
// MergeStyleRebaseMerge rebase and merge pull
|
||||||
|
MergeStyleRebaseMerge MergeStyle = "rebase-merge"
|
||||||
|
// MergeStyleSquash squash and merge pull
|
||||||
|
MergeStyleSquash MergeStyle = "squash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *ListPullRequestsOptions) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
if len(opt.State) > 0 {
|
||||||
|
query.Add("state", string(opt.State))
|
||||||
|
}
|
||||||
|
if len(opt.Sort) > 0 {
|
||||||
|
query.Add("sort", opt.Sort)
|
||||||
|
}
|
||||||
|
if opt.Milestone > 0 {
|
||||||
|
query.Add("milestone", fmt.Sprintf("%d", opt.Milestone))
|
||||||
|
}
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoPullRequests list PRs of one repository
|
||||||
|
func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOptions) ([]*PullRequest, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
prs := make([]*PullRequest, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", owner, repo))
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &prs)
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
|
||||||
|
for i := range prs {
|
||||||
|
if err := fixPullHeadSha(c, prs[i]); err != nil {
|
||||||
|
return prs, resp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prs, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPullRequest get information of one PR
|
||||||
|
func (c *Client) GetPullRequest(owner, repo string, index int64) (*PullRequest, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pr := new(PullRequest)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index), nil, nil, pr)
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
|
||||||
|
if err := fixPullHeadSha(c, pr); err != nil {
|
||||||
|
return pr, resp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pr, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePullRequestOption options when creating a pull request
|
||||||
|
type CreatePullRequestOption struct {
|
||||||
|
Head string `json:"head"`
|
||||||
|
Base string `json:"base"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Assignee string `json:"assignee"`
|
||||||
|
Assignees []string `json:"assignees"`
|
||||||
|
Milestone int64 `json:"milestone"`
|
||||||
|
Labels []int64 `json:"labels"`
|
||||||
|
Deadline *time.Time `json:"due_date"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePullRequest create pull request with options
|
||||||
|
func (c *Client) CreatePullRequest(owner, repo string, opt CreatePullRequestOption) (*PullRequest, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pr := new(PullRequest)
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/pulls", owner, repo),
|
||||||
|
jsonHeader, bytes.NewReader(body), pr)
|
||||||
|
return pr, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditPullRequestOption options when modify pull request
|
||||||
|
type EditPullRequestOption struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Base string `json:"base"`
|
||||||
|
Assignee string `json:"assignee"`
|
||||||
|
Assignees []string `json:"assignees"`
|
||||||
|
Milestone int64 `json:"milestone"`
|
||||||
|
Labels []int64 `json:"labels"`
|
||||||
|
State *StateType `json:"state"`
|
||||||
|
Deadline *time.Time `json:"due_date"`
|
||||||
|
RemoveDeadline *bool `json:"unset_due_date"`
|
||||||
|
AllowMaintainerEdit *bool `json:"allow_maintainer_edit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the EditPullRequestOption struct
|
||||||
|
func (opt EditPullRequestOption) Validate(c *Client) error {
|
||||||
|
if len(opt.Title) != 0 && len(strings.TrimSpace(opt.Title)) == 0 {
|
||||||
|
return fmt.Errorf("title is empty")
|
||||||
|
}
|
||||||
|
if len(opt.Base) != 0 {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return fmt.Errorf("can not change base gitea to old")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditPullRequest modify pull request with PR id and options
|
||||||
|
func (c *Client) EditPullRequest(owner, repo string, index int64, opt EditPullRequestOption) (*PullRequest, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pr := new(PullRequest)
|
||||||
|
resp, err := c.getParsedResponse("PATCH",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index),
|
||||||
|
jsonHeader, bytes.NewReader(body), pr)
|
||||||
|
return pr, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergePullRequestOption options when merging a pull request
|
||||||
|
type MergePullRequestOption struct {
|
||||||
|
Style MergeStyle `json:"Do"`
|
||||||
|
MergeCommitID string `json:"MergeCommitID"`
|
||||||
|
Title string `json:"MergeTitleField"`
|
||||||
|
Message string `json:"MergeMessageField"`
|
||||||
|
DeleteBranchAfterMerge bool `json:"delete_branch_after_merge"`
|
||||||
|
ForceMerge bool `json:"force_merge"`
|
||||||
|
HeadCommitId string `json:"head_commit_id"`
|
||||||
|
MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the MergePullRequestOption struct
|
||||||
|
func (opt MergePullRequestOption) Validate(c *Client) error {
|
||||||
|
if opt.Style == MergeStyleSquash {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_5); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergePullRequest merge a PR to repository by PR id
|
||||||
|
func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePullRequestOption) (bool, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("POST", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), jsonHeader, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return false, resp, err
|
||||||
|
}
|
||||||
|
return status == 200, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPullRequestMerged test if one PR is merged to one repository
|
||||||
|
func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return status == 204, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullRequestDiffOptions options for GET /repos/<owner>/<repo>/pulls/<idx>.[diff|patch]
|
||||||
|
type PullRequestDiffOptions struct {
|
||||||
|
// Include binary file changes when requesting a .diff
|
||||||
|
Binary bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode converts the options to a query string
|
||||||
|
func (o PullRequestDiffOptions) QueryEncode() string {
|
||||||
|
query := make(url.Values)
|
||||||
|
query.Add("binary", fmt.Sprintf("%v", o.Binary))
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
type pullRequestDiffType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
pullRequestDiffTypeDiff pullRequestDiffType = "diff"
|
||||||
|
pullRequestDiffTypePatch pullRequestDiffType = "patch"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getPullRequestDiffOrPatch gets the patch or diff file as bytes for a PR
|
||||||
|
func (c *Client) getPullRequestDiffOrPatch(owner, repo string, kind pullRequestDiffType, index int64, opts PullRequestDiffOptions) ([]byte, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
r, _, err2 := c.GetRepo(owner, repo)
|
||||||
|
if err2 != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if r.Private {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("/%s/%s/pulls/%d.%s?%s", owner, repo, index, kind, opts.QueryEncode())
|
||||||
|
return c.getWebResponse("GET", url, nil)
|
||||||
|
}
|
||||||
|
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d.%s", owner, repo, index, kind), nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPullRequestPatch gets the git patchset of a PR
|
||||||
|
func (c *Client) GetPullRequestPatch(owner, repo string, index int64) ([]byte, *Response, error) {
|
||||||
|
return c.getPullRequestDiffOrPatch(owner, repo, pullRequestDiffTypePatch, index, PullRequestDiffOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPullRequestDiff gets the diff of a PR. For Gitea >= 1.16, you must set includeBinary to get an applicable diff
|
||||||
|
func (c *Client) GetPullRequestDiff(owner, repo string, index int64, opts PullRequestDiffOptions) ([]byte, *Response, error) {
|
||||||
|
return c.getPullRequestDiffOrPatch(owner, repo, pullRequestDiffTypeDiff, index, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPullRequestCommitsOptions options for listing pull requests
|
||||||
|
type ListPullRequestCommitsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPullRequestCommits list commits for a pull request
|
||||||
|
func (c *Client) ListPullRequestCommits(owner, repo string, index int64, opt ListPullRequestCommitsOptions) ([]*Commit, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/commits", owner, repo, index))
|
||||||
|
opt.setDefaults()
|
||||||
|
commits := make([]*Commit, 0, opt.PageSize)
|
||||||
|
link.RawQuery = opt.getURLQuery().Encode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &commits)
|
||||||
|
return commits, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixPullHeadSha is a workaround for https://github.com/go-gitea/gitea/issues/12675
|
||||||
|
// When no head sha is available, this is because the branch got deleted in the base repo.
|
||||||
|
// pr.Head.Ref points in this case not to the head repo branch name, but the base repo ref,
|
||||||
|
// which stays available to resolve the commit sha. This is fixed for gitea >= 1.14.0
|
||||||
|
func fixPullHeadSha(client *Client, pr *PullRequest) error {
|
||||||
|
if pr.Base != nil && pr.Base.Repository != nil && pr.Base.Repository.Owner != nil &&
|
||||||
|
pr.Head != nil && pr.Head.Ref != "" && pr.Head.Sha == "" {
|
||||||
|
owner := pr.Base.Repository.Owner.UserName
|
||||||
|
repo := pr.Base.Repository.Name
|
||||||
|
refs, _, err := client.GetRepoRefs(owner, repo, pr.Head.Ref)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if len(refs) == 0 {
|
||||||
|
return fmt.Errorf("unable to resolve PR ref '%s'", pr.Head.Ref)
|
||||||
|
}
|
||||||
|
pr.Head.Sha = refs[0].Object.SHA
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPullRequestFilesOptions options for listing pull request files
|
||||||
|
type ListPullRequestFilesOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPullRequestFiles list changed files for a pull request
|
||||||
|
func (c *Client) ListPullRequestFiles(owner, repo string, index int64, opt ListPullRequestFilesOptions) ([]*ChangedFile, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/files", owner, repo, index))
|
||||||
|
opt.setDefaults()
|
||||||
|
files := make([]*ChangedFile, 0, opt.PageSize)
|
||||||
|
link.RawQuery = opt.getURLQuery().Encode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &files)
|
||||||
|
return files, resp, err
|
||||||
|
}
|
||||||
325
vendor/code.gitea.io/sdk/gitea/pull_review.go
generated
vendored
Normal file
325
vendor/code.gitea.io/sdk/gitea/pull_review.go
generated
vendored
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReviewStateType review state type
|
||||||
|
type ReviewStateType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ReviewStateApproved pr is approved
|
||||||
|
ReviewStateApproved ReviewStateType = "APPROVED"
|
||||||
|
// ReviewStatePending pr state is pending
|
||||||
|
ReviewStatePending ReviewStateType = "PENDING"
|
||||||
|
// ReviewStateComment is a comment review
|
||||||
|
ReviewStateComment ReviewStateType = "COMMENT"
|
||||||
|
// ReviewStateRequestChanges changes for pr are requested
|
||||||
|
ReviewStateRequestChanges ReviewStateType = "REQUEST_CHANGES"
|
||||||
|
// ReviewStateRequestReview review is requested from user
|
||||||
|
ReviewStateRequestReview ReviewStateType = "REQUEST_REVIEW"
|
||||||
|
// ReviewStateUnknown state of pr is unknown
|
||||||
|
ReviewStateUnknown ReviewStateType = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
// PullReview represents a pull request review
|
||||||
|
type PullReview struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Reviewer *User `json:"user"`
|
||||||
|
ReviewerTeam *Team `json:"team"`
|
||||||
|
State ReviewStateType `json:"state"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
CommitID string `json:"commit_id"`
|
||||||
|
// Stale indicates if the pull has changed since the review
|
||||||
|
Stale bool `json:"stale"`
|
||||||
|
// Official indicates if the review counts towards the required approval limit, if PR base is a protected branch
|
||||||
|
Official bool `json:"official"`
|
||||||
|
Dismissed bool `json:"dismissed"`
|
||||||
|
CodeCommentsCount int `json:"comments_count"`
|
||||||
|
Submitted time.Time `json:"submitted_at"`
|
||||||
|
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
HTMLPullURL string `json:"pull_request_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullReviewComment represents a comment on a pull request review
|
||||||
|
type PullReviewComment struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Reviewer *User `json:"user"`
|
||||||
|
ReviewID int64 `json:"pull_request_review_id"`
|
||||||
|
Resolver *User `json:"resolver"`
|
||||||
|
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
Updated time.Time `json:"updated_at"`
|
||||||
|
|
||||||
|
Path string `json:"path"`
|
||||||
|
CommitID string `json:"commit_id"`
|
||||||
|
OrigCommitID string `json:"original_commit_id"`
|
||||||
|
DiffHunk string `json:"diff_hunk"`
|
||||||
|
LineNum uint64 `json:"position"`
|
||||||
|
OldLineNum uint64 `json:"original_position"`
|
||||||
|
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
HTMLPullURL string `json:"pull_request_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePullReviewOptions are options to create a pull review
|
||||||
|
type CreatePullReviewOptions struct {
|
||||||
|
State ReviewStateType `json:"event"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
CommitID string `json:"commit_id"`
|
||||||
|
Comments []CreatePullReviewComment `json:"comments"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePullReviewComment represent a review comment for creation api
|
||||||
|
type CreatePullReviewComment struct {
|
||||||
|
// the tree path
|
||||||
|
Path string `json:"path"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
// if comment to old file line or 0
|
||||||
|
OldLineNum int64 `json:"old_position"`
|
||||||
|
// if comment to new file line or 0
|
||||||
|
NewLineNum int64 `json:"new_position"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubmitPullReviewOptions are options to submit a pending pull review
|
||||||
|
type SubmitPullReviewOptions struct {
|
||||||
|
State ReviewStateType `json:"event"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DismissPullReviewOptions are options to dismiss a pull review
|
||||||
|
type DismissPullReviewOptions struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullReviewRequestOptions are options to add or remove pull review requests
|
||||||
|
type PullReviewRequestOptions struct {
|
||||||
|
Reviewers []string `json:"reviewers"`
|
||||||
|
TeamReviewers []string `json:"team_reviewers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPullReviewsOptions options for listing PullReviews
|
||||||
|
type ListPullReviewsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreatePullReviewOptions struct
|
||||||
|
func (opt CreatePullReviewOptions) Validate() error {
|
||||||
|
if opt.State != ReviewStateApproved && len(opt.Comments) == 0 && len(strings.TrimSpace(opt.Body)) == 0 {
|
||||||
|
return fmt.Errorf("body is empty")
|
||||||
|
}
|
||||||
|
for i := range opt.Comments {
|
||||||
|
if err := opt.Comments[i].Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the SubmitPullReviewOptions struct
|
||||||
|
func (opt SubmitPullReviewOptions) Validate() error {
|
||||||
|
if opt.State != ReviewStateApproved && len(strings.TrimSpace(opt.Body)) == 0 {
|
||||||
|
return fmt.Errorf("body is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreatePullReviewComment struct
|
||||||
|
func (opt CreatePullReviewComment) Validate() error {
|
||||||
|
if len(strings.TrimSpace(opt.Body)) == 0 {
|
||||||
|
return fmt.Errorf("body is empty")
|
||||||
|
}
|
||||||
|
if opt.NewLineNum != 0 && opt.OldLineNum != 0 {
|
||||||
|
return fmt.Errorf("old and new line num are set, cant identify the code comment position")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPullReviews lists all reviews of a pull request
|
||||||
|
func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullReviewsOptions) ([]*PullReview, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
rs := make([]*PullReview, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews", owner, repo, index))
|
||||||
|
link.RawQuery = opt.ListOptions.getURLQuery().Encode()
|
||||||
|
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &rs)
|
||||||
|
return rs, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPullReview gets a specific review of a pull request
|
||||||
|
func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(PullReview)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id), jsonHeader, nil, &r)
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPullReviewComments lists all comments of a pull request review
|
||||||
|
func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([]*PullReviewComment, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
rcl := make([]*PullReviewComment, 0, 4)
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/comments", owner, repo, index, id))
|
||||||
|
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &rcl)
|
||||||
|
return rcl, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePullReview delete a specific review from a pull request
|
||||||
|
func (c *Client) DeletePullReview(owner, repo string, index, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id), jsonHeader, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePullReview create a review to an pull request
|
||||||
|
func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePullReviewOptions) (*PullReview, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(PullReview)
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews", owner, repo, index),
|
||||||
|
jsonHeader, bytes.NewReader(body), r)
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubmitPullReview submit a pending review to an pull request
|
||||||
|
func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt SubmitPullReviewOptions) (*PullReview, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(PullReview)
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id),
|
||||||
|
jsonHeader, bytes.NewReader(body), r)
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateReviewRequests create review requests to an pull request
|
||||||
|
func (c *Client) CreateReviewRequests(owner, repo string, index int64, opt PullReviewRequestOptions) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, resp, err := c.getResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, index),
|
||||||
|
jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteReviewRequests delete review requests to an pull request
|
||||||
|
func (c *Client) DeleteReviewRequests(owner, repo string, index int64, opt PullReviewRequestOptions) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, resp, err := c.getResponse("DELETE",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, index),
|
||||||
|
jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DismissPullReview dismiss a review for a pull request
|
||||||
|
func (c *Client) DismissPullReview(owner, repo string, index, id int64, opt DismissPullReviewOptions) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, resp, err := c.getResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/dismissals", owner, repo, index, id),
|
||||||
|
jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnDismissPullReview cancel to dismiss a review for a pull request
|
||||||
|
func (c *Client) UnDismissPullReview(owner, repo string, index, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, resp, err := c.getResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/undismissals", owner, repo, index, id),
|
||||||
|
jsonHeader, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
202
vendor/code.gitea.io/sdk/gitea/release.go
generated
vendored
Normal file
202
vendor/code.gitea.io/sdk/gitea/release.go
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
// Copyright 2016 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Release represents a repository release
|
||||||
|
type Release struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
TagName string `json:"tag_name"`
|
||||||
|
Target string `json:"target_commitish"`
|
||||||
|
Title string `json:"name"`
|
||||||
|
Note string `json:"body"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
TarURL string `json:"tarball_url"`
|
||||||
|
ZipURL string `json:"zipball_url"`
|
||||||
|
IsDraft bool `json:"draft"`
|
||||||
|
IsPrerelease bool `json:"prerelease"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
PublishedAt time.Time `json:"published_at"`
|
||||||
|
Publisher *User `json:"author"`
|
||||||
|
Attachments []*Attachment `json:"assets"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListReleasesOptions options for listing repository's releases
|
||||||
|
type ListReleasesOptions struct {
|
||||||
|
ListOptions
|
||||||
|
IsDraft *bool
|
||||||
|
IsPreRelease *bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *ListReleasesOptions) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
|
||||||
|
if opt.IsDraft != nil {
|
||||||
|
query.Add("draft", fmt.Sprintf("%t", *opt.IsDraft))
|
||||||
|
}
|
||||||
|
if opt.IsPreRelease != nil {
|
||||||
|
query.Add("pre-release", fmt.Sprintf("%t", *opt.IsPreRelease))
|
||||||
|
}
|
||||||
|
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListReleases list releases of a repository
|
||||||
|
func (c *Client) ListReleases(owner, repo string, opt ListReleasesOptions) ([]*Release, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
releases := make([]*Release, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases?%s", owner, repo, opt.QueryEncode()),
|
||||||
|
nil, nil, &releases)
|
||||||
|
return releases, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRelease get a release of a repository by id
|
||||||
|
func (c *Client) GetRelease(owner, repo string, id int64) (*Release, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
r := new(Release)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/%d", owner, repo, id),
|
||||||
|
jsonHeader, nil, &r)
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReleaseByTag get a release of a repository by tag
|
||||||
|
func (c *Client) GetReleaseByTag(owner, repo, tag string) (*Release, *Response, error) {
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
|
||||||
|
return c.fallbackGetReleaseByTag(owner, repo, tag)
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &tag); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
r := new(Release)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/tags/%s", owner, repo, tag),
|
||||||
|
nil, nil, &r)
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateReleaseOption options when creating a release
|
||||||
|
type CreateReleaseOption struct {
|
||||||
|
TagName string `json:"tag_name"`
|
||||||
|
Target string `json:"target_commitish"`
|
||||||
|
Title string `json:"name"`
|
||||||
|
Note string `json:"body"`
|
||||||
|
IsDraft bool `json:"draft"`
|
||||||
|
IsPrerelease bool `json:"prerelease"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateReleaseOption struct
|
||||||
|
func (opt CreateReleaseOption) Validate() error {
|
||||||
|
if len(strings.TrimSpace(opt.Title)) == 0 {
|
||||||
|
return fmt.Errorf("title is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRelease create a release
|
||||||
|
func (c *Client) CreateRelease(owner, repo string, opt CreateReleaseOption) (*Release, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
r := new(Release)
|
||||||
|
resp, err := c.getParsedResponse("POST",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases", owner, repo),
|
||||||
|
jsonHeader, bytes.NewReader(body), r)
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditReleaseOption options when editing a release
|
||||||
|
type EditReleaseOption struct {
|
||||||
|
TagName string `json:"tag_name"`
|
||||||
|
Target string `json:"target_commitish"`
|
||||||
|
Title string `json:"name"`
|
||||||
|
Note string `json:"body"`
|
||||||
|
IsDraft *bool `json:"draft"`
|
||||||
|
IsPrerelease *bool `json:"prerelease"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditRelease edit a release
|
||||||
|
func (c *Client) EditRelease(owner, repo string, id int64, form EditReleaseOption) (*Release, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
r := new(Release)
|
||||||
|
resp, err := c.getParsedResponse("PATCH",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/%d", owner, repo, id),
|
||||||
|
jsonHeader, bytes.NewReader(body), r)
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRelease delete a release from a repository, keeping its tag
|
||||||
|
func (c *Client) DeleteRelease(user, repo string, id int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
|
||||||
|
nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteReleaseByTag deletes a release frm a repository by tag
|
||||||
|
func (c *Client) DeleteReleaseByTag(user, repo, tag string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/tags/%s", user, repo, tag),
|
||||||
|
nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallbackGetReleaseByTag is fallback for old gitea installations ( < 1.13.0 )
|
||||||
|
func (c *Client) fallbackGetReleaseByTag(owner, repo, tag string) (*Release, *Response, error) {
|
||||||
|
for i := 1; ; i++ {
|
||||||
|
rl, resp, err := c.ListReleases(owner, repo, ListReleasesOptions{ListOptions: ListOptions{Page: i}})
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
if len(rl) == 0 {
|
||||||
|
return nil,
|
||||||
|
newResponse(&http.Response{StatusCode: 404}),
|
||||||
|
fmt.Errorf("release with tag '%s' not found", tag)
|
||||||
|
}
|
||||||
|
for _, r := range rl {
|
||||||
|
if r.TagName == tag {
|
||||||
|
return r, resp, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
546
vendor/code.gitea.io/sdk/gitea/repo.go
generated
vendored
Normal file
546
vendor/code.gitea.io/sdk/gitea/repo.go
generated
vendored
Normal file
@@ -0,0 +1,546 @@
|
|||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Permission represents a set of permissions
|
||||||
|
type Permission struct {
|
||||||
|
Admin bool `json:"admin"`
|
||||||
|
Push bool `json:"push"`
|
||||||
|
Pull bool `json:"pull"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InternalTracker represents settings for internal tracker
|
||||||
|
type InternalTracker struct {
|
||||||
|
// Enable time tracking (Built-in issue tracker)
|
||||||
|
EnableTimeTracker bool `json:"enable_time_tracker"`
|
||||||
|
// Let only contributors track time (Built-in issue tracker)
|
||||||
|
AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"`
|
||||||
|
// Enable dependencies for issues and pull requests (Built-in issue tracker)
|
||||||
|
EnableIssueDependencies bool `json:"enable_issue_dependencies"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExternalTracker represents settings for external tracker
|
||||||
|
type ExternalTracker struct {
|
||||||
|
// URL of external issue tracker.
|
||||||
|
ExternalTrackerURL string `json:"external_tracker_url"`
|
||||||
|
// External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index.
|
||||||
|
ExternalTrackerFormat string `json:"external_tracker_format"`
|
||||||
|
// External Issue Tracker Number Format, either `numeric` or `alphanumeric`
|
||||||
|
ExternalTrackerStyle string `json:"external_tracker_style"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExternalWiki represents setting for external wiki
|
||||||
|
type ExternalWiki struct {
|
||||||
|
// URL of external wiki.
|
||||||
|
ExternalWikiURL string `json:"external_wiki_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repository represents a repository
|
||||||
|
type Repository struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Owner *User `json:"owner"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Empty bool `json:"empty"`
|
||||||
|
Private bool `json:"private"`
|
||||||
|
Fork bool `json:"fork"`
|
||||||
|
Template bool `json:"template"`
|
||||||
|
Parent *Repository `json:"parent"`
|
||||||
|
Mirror bool `json:"mirror"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
SSHURL string `json:"ssh_url"`
|
||||||
|
CloneURL string `json:"clone_url"`
|
||||||
|
OriginalURL string `json:"original_url"`
|
||||||
|
Website string `json:"website"`
|
||||||
|
Stars int `json:"stars_count"`
|
||||||
|
Forks int `json:"forks_count"`
|
||||||
|
Watchers int `json:"watchers_count"`
|
||||||
|
OpenIssues int `json:"open_issues_count"`
|
||||||
|
OpenPulls int `json:"open_pr_counter"`
|
||||||
|
Releases int `json:"release_counter"`
|
||||||
|
DefaultBranch string `json:"default_branch"`
|
||||||
|
Archived bool `json:"archived"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
Updated time.Time `json:"updated_at"`
|
||||||
|
Permissions *Permission `json:"permissions,omitempty"`
|
||||||
|
HasIssues bool `json:"has_issues"`
|
||||||
|
InternalTracker *InternalTracker `json:"internal_tracker,omitempty"`
|
||||||
|
ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"`
|
||||||
|
HasWiki bool `json:"has_wiki"`
|
||||||
|
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"`
|
||||||
|
HasPullRequests bool `json:"has_pull_requests"`
|
||||||
|
HasProjects bool `json:"has_projects"`
|
||||||
|
HasReleases bool `json:"has_releases,omitempty"`
|
||||||
|
HasPackages bool `json:"has_packages,omitempty"`
|
||||||
|
HasActions bool `json:"has_actions,omitempty"`
|
||||||
|
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
|
||||||
|
AllowMerge bool `json:"allow_merge_commits"`
|
||||||
|
AllowRebase bool `json:"allow_rebase"`
|
||||||
|
AllowRebaseMerge bool `json:"allow_rebase_explicit"`
|
||||||
|
AllowSquash bool `json:"allow_squash_merge"`
|
||||||
|
AvatarURL string `json:"avatar_url"`
|
||||||
|
Internal bool `json:"internal"`
|
||||||
|
MirrorInterval string `json:"mirror_interval"`
|
||||||
|
MirrorUpdated time.Time `json:"mirror_updated,omitempty"`
|
||||||
|
DefaultMergeStyle MergeStyle `json:"default_merge_style"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoType represent repo type
|
||||||
|
type RepoType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RepoTypeNone dont specify a type
|
||||||
|
RepoTypeNone RepoType = ""
|
||||||
|
// RepoTypeSource is the default repo type
|
||||||
|
RepoTypeSource RepoType = "source"
|
||||||
|
// RepoTypeFork is a repo witch was forked from an other one
|
||||||
|
RepoTypeFork RepoType = "fork"
|
||||||
|
// RepoTypeMirror represents an mirror repo
|
||||||
|
RepoTypeMirror RepoType = "mirror"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TrustModel represent how git signatures are handled in a repository
|
||||||
|
type TrustModel string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TrustModelDefault use TM set by global config
|
||||||
|
TrustModelDefault TrustModel = "default"
|
||||||
|
// TrustModelCollaborator gpg signature has to be owned by a repo collaborator
|
||||||
|
TrustModelCollaborator TrustModel = "collaborator"
|
||||||
|
// TrustModelCommitter gpg signature has to match committer
|
||||||
|
TrustModelCommitter TrustModel = "committer"
|
||||||
|
// TrustModelCollaboratorCommitter gpg signature has to match committer and owned by a repo collaborator
|
||||||
|
TrustModelCollaboratorCommitter TrustModel = "collaboratorcommitter"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListReposOptions options for listing repositories
|
||||||
|
type ListReposOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMyRepos lists all repositories for the authenticated user that has access to.
|
||||||
|
func (c *Client) ListMyRepos(opt ListReposOptions) ([]*Repository, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
repos := make([]*Repository, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/repos?%s", opt.getURLQuery().Encode()), nil, nil, &repos)
|
||||||
|
return repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListUserRepos list all repositories of one user by user's name
|
||||||
|
func (c *Client) ListUserRepos(user string, opt ListReposOptions) ([]*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
repos := make([]*Repository, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos?%s", user, opt.getURLQuery().Encode()), nil, nil, &repos)
|
||||||
|
return repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrgReposOptions options for a organization's repositories
|
||||||
|
type ListOrgReposOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrgRepos list all repositories of one organization by organization's name
|
||||||
|
func (c *Client) ListOrgRepos(org string, opt ListOrgReposOptions) ([]*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
repos := make([]*Repository, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos?%s", org, opt.getURLQuery().Encode()), nil, nil, &repos)
|
||||||
|
return repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchRepoOptions options for searching repositories
|
||||||
|
type SearchRepoOptions struct {
|
||||||
|
ListOptions
|
||||||
|
|
||||||
|
// The keyword to query
|
||||||
|
Keyword string
|
||||||
|
// Limit search to repositories with keyword as topic
|
||||||
|
KeywordIsTopic bool
|
||||||
|
// Include search of keyword within repository description
|
||||||
|
KeywordInDescription bool
|
||||||
|
|
||||||
|
/*
|
||||||
|
User Filter
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Repo Owner
|
||||||
|
OwnerID int64
|
||||||
|
// Stared By UserID
|
||||||
|
StarredByUserID int64
|
||||||
|
|
||||||
|
/*
|
||||||
|
Repo Attributes
|
||||||
|
*/
|
||||||
|
|
||||||
|
// pubic, private or all repositories (defaults to all)
|
||||||
|
IsPrivate *bool
|
||||||
|
// archived, non-archived or all repositories (defaults to all)
|
||||||
|
IsArchived *bool
|
||||||
|
// Exclude template repos from search
|
||||||
|
ExcludeTemplate bool
|
||||||
|
// Filter by "fork", "source", "mirror"
|
||||||
|
Type RepoType
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sort Filters
|
||||||
|
*/
|
||||||
|
|
||||||
|
// sort repos by attribute. Supported values are "alpha", "created", "updated", "size", and "id". Default is "alpha"
|
||||||
|
Sort string
|
||||||
|
// sort order, either "asc" (ascending) or "desc" (descending). Default is "asc", ignored if "sort" is not specified.
|
||||||
|
Order string
|
||||||
|
// Repo owner to prioritize in the results
|
||||||
|
PrioritizedByOwnerID int64
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cover EdgeCases
|
||||||
|
*/
|
||||||
|
// if set all other options are ignored and this string is used as query
|
||||||
|
RawQuery string
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *SearchRepoOptions) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
if opt.Keyword != "" {
|
||||||
|
query.Add("q", opt.Keyword)
|
||||||
|
}
|
||||||
|
if opt.KeywordIsTopic {
|
||||||
|
query.Add("topic", "true")
|
||||||
|
}
|
||||||
|
if opt.KeywordInDescription {
|
||||||
|
query.Add("includeDesc", "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
// User Filter
|
||||||
|
if opt.OwnerID > 0 {
|
||||||
|
query.Add("uid", fmt.Sprintf("%d", opt.OwnerID))
|
||||||
|
query.Add("exclusive", "true")
|
||||||
|
}
|
||||||
|
if opt.StarredByUserID > 0 {
|
||||||
|
query.Add("starredBy", fmt.Sprintf("%d", opt.StarredByUserID))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repo Attributes
|
||||||
|
if opt.IsPrivate != nil {
|
||||||
|
query.Add("is_private", fmt.Sprintf("%v", opt.IsPrivate))
|
||||||
|
}
|
||||||
|
if opt.IsArchived != nil {
|
||||||
|
query.Add("archived", fmt.Sprintf("%v", opt.IsArchived))
|
||||||
|
}
|
||||||
|
if opt.ExcludeTemplate {
|
||||||
|
query.Add("template", "false")
|
||||||
|
}
|
||||||
|
if len(opt.Type) != 0 {
|
||||||
|
query.Add("mode", string(opt.Type))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort Filters
|
||||||
|
if opt.Sort != "" {
|
||||||
|
query.Add("sort", opt.Sort)
|
||||||
|
}
|
||||||
|
if opt.PrioritizedByOwnerID > 0 {
|
||||||
|
query.Add("priority_owner_id", fmt.Sprintf("%d", opt.PrioritizedByOwnerID))
|
||||||
|
}
|
||||||
|
if opt.Order != "" {
|
||||||
|
query.Add("order", opt.Order)
|
||||||
|
}
|
||||||
|
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
type searchRepoResponse struct {
|
||||||
|
Repos []*Repository `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchRepos searches for repositories matching the given filters
|
||||||
|
func (c *Client) SearchRepos(opt SearchRepoOptions) ([]*Repository, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
repos := new(searchRepoResponse)
|
||||||
|
|
||||||
|
link, _ := url.Parse("/repos/search")
|
||||||
|
|
||||||
|
if len(opt.RawQuery) != 0 {
|
||||||
|
link.RawQuery = opt.RawQuery
|
||||||
|
} else {
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
// IsPrivate only works on gitea >= 1.12.0
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil && opt.IsPrivate != nil {
|
||||||
|
if *opt.IsPrivate {
|
||||||
|
// private repos only not supported on gitea <= 1.11.x
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
newQuery := link.Query()
|
||||||
|
newQuery.Add("private", "false")
|
||||||
|
link.RawQuery = newQuery.Encode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &repos)
|
||||||
|
return repos.Repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRepoOption options when creating repository
|
||||||
|
type CreateRepoOption struct {
|
||||||
|
// Name of the repository to create
|
||||||
|
Name string `json:"name"`
|
||||||
|
// Description of the repository to create
|
||||||
|
Description string `json:"description"`
|
||||||
|
// Whether the repository is private
|
||||||
|
Private bool `json:"private"`
|
||||||
|
// Issue Label set to use
|
||||||
|
IssueLabels string `json:"issue_labels"`
|
||||||
|
// Whether the repository should be auto-intialized?
|
||||||
|
AutoInit bool `json:"auto_init"`
|
||||||
|
// Whether the repository is template
|
||||||
|
Template bool `json:"template"`
|
||||||
|
// Gitignores to use
|
||||||
|
Gitignores string `json:"gitignores"`
|
||||||
|
// License to use
|
||||||
|
License string `json:"license"`
|
||||||
|
// Readme of the repository to create
|
||||||
|
Readme string `json:"readme"`
|
||||||
|
// DefaultBranch of the repository (used when initializes and in template)
|
||||||
|
DefaultBranch string `json:"default_branch"`
|
||||||
|
// TrustModel of the repository
|
||||||
|
TrustModel TrustModel `json:"trust_model"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateRepoOption struct
|
||||||
|
func (opt CreateRepoOption) Validate(c *Client) error {
|
||||||
|
if len(strings.TrimSpace(opt.Name)) == 0 {
|
||||||
|
return fmt.Errorf("name is empty")
|
||||||
|
}
|
||||||
|
if len(opt.Name) > 100 {
|
||||||
|
return fmt.Errorf("name has more than 100 chars")
|
||||||
|
}
|
||||||
|
if len(opt.Description) > 2048 {
|
||||||
|
return fmt.Errorf("description has more than 2048 chars")
|
||||||
|
}
|
||||||
|
if len(opt.DefaultBranch) > 100 {
|
||||||
|
return fmt.Errorf("default branch name has more than 100 chars")
|
||||||
|
}
|
||||||
|
if len(opt.TrustModel) != 0 {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRepo creates a repository for authenticated user.
|
||||||
|
func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, *Response, error) {
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", "/user/repos", jsonHeader, bytes.NewReader(body), repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOrgRepo creates an organization repository for authenticated user.
|
||||||
|
func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/org/%s/repos", org), jsonHeader, bytes.NewReader(body), repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepo returns information of a repository of given owner.
|
||||||
|
func (c *Client) GetRepo(owner, reponame string) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &reponame); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s", owner, reponame), nil, nil, repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepoByID returns information of a repository by a giver repository ID.
|
||||||
|
func (c *Client) GetRepoByID(id int64) (*Repository, *Response, error) {
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repositories/%d", id), nil, nil, repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditRepoOption options when editing a repository's properties
|
||||||
|
type EditRepoOption struct {
|
||||||
|
// name of the repository
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
// a short description of the repository.
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
// a URL with more information about the repository.
|
||||||
|
Website *string `json:"website,omitempty"`
|
||||||
|
// either `true` to make the repository private or `false` to make it public.
|
||||||
|
// Note: you will get a 422 error if the organization restricts changing repository visibility to organization
|
||||||
|
// owners and a non-owner tries to change the value of private.
|
||||||
|
Private *bool `json:"private,omitempty"`
|
||||||
|
// either `true` to make this repository a template or `false` to make it a normal repository
|
||||||
|
Template *bool `json:"template,omitempty"`
|
||||||
|
// either `true` to enable issues for this repository or `false` to disable them.
|
||||||
|
HasIssues *bool `json:"has_issues,omitempty"`
|
||||||
|
// set this structure to configure internal issue tracker (requires has_issues)
|
||||||
|
InternalTracker *InternalTracker `json:"internal_tracker,omitempty"`
|
||||||
|
// set this structure to use external issue tracker (requires has_issues)
|
||||||
|
ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"`
|
||||||
|
// either `true` to enable the wiki for this repository or `false` to disable it.
|
||||||
|
HasWiki *bool `json:"has_wiki,omitempty"`
|
||||||
|
// set this structure to use external wiki instead of internal (requires has_wiki)
|
||||||
|
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"`
|
||||||
|
// sets the default branch for this repository.
|
||||||
|
DefaultBranch *string `json:"default_branch,omitempty"`
|
||||||
|
// either `true` to allow pull requests, or `false` to prevent pull request.
|
||||||
|
HasPullRequests *bool `json:"has_pull_requests,omitempty"`
|
||||||
|
// either `true` to enable project unit, or `false` to disable them.
|
||||||
|
HasProjects *bool `json:"has_projects,omitempty"`
|
||||||
|
// either `true` to enable release, or `false` to disable them.
|
||||||
|
HasReleases *bool `json:"has_releases,omitempty"`
|
||||||
|
// either `true` to enable packages, or `false` to disable them.
|
||||||
|
HasPackages *bool `json:"has_packages,omitempty"`
|
||||||
|
// either `true` to enable actions, or `false` to disable them.
|
||||||
|
HasActions *bool `json:"has_actions,omitempty"`
|
||||||
|
// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.
|
||||||
|
IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace_conflicts,omitempty"`
|
||||||
|
// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.
|
||||||
|
AllowMerge *bool `json:"allow_merge_commits,omitempty"`
|
||||||
|
// either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. `has_pull_requests` must be `true`.
|
||||||
|
AllowRebase *bool `json:"allow_rebase,omitempty"`
|
||||||
|
// either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. `has_pull_requests` must be `true`.
|
||||||
|
AllowRebaseMerge *bool `json:"allow_rebase_explicit,omitempty"`
|
||||||
|
// either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. `has_pull_requests` must be `true`.
|
||||||
|
AllowSquash *bool `json:"allow_squash_merge,omitempty"`
|
||||||
|
// set to `true` to archive this repository.
|
||||||
|
Archived *bool `json:"archived,omitempty"`
|
||||||
|
// set to a string like `8h30m0s` to set the mirror interval time
|
||||||
|
MirrorInterval *string `json:"mirror_interval,omitempty"`
|
||||||
|
// either `true` to allow mark pr as merged manually, or `false` to prevent it. `has_pull_requests` must be `true`.
|
||||||
|
AllowManualMerge *bool `json:"allow_manual_merge,omitempty"`
|
||||||
|
// either `true` to enable AutodetectManualMerge, or `false` to prevent it. `has_pull_requests` must be `true`, Note: In some special cases, misjudgments can occur.
|
||||||
|
AutodetectManualMerge *bool `json:"autodetect_manual_merge,omitempty"`
|
||||||
|
// set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", or "squash". `has_pull_requests` must be `true`.
|
||||||
|
DefaultMergeStyle *MergeStyle `json:"default_merge_style,omitempty"`
|
||||||
|
// set to `true` to archive this repository.
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditRepo edit the properties of a repository
|
||||||
|
func (c *Client) EditRepo(owner, reponame string, opt EditRepoOption) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &reponame); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s", owner, reponame), jsonHeader, bytes.NewReader(body), repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRepo deletes a repository of user or organization.
|
||||||
|
func (c *Client) DeleteRepo(owner, repo string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MirrorSync adds a mirrored repository to the mirror sync queue.
|
||||||
|
func (c *Client) MirrorSync(owner, repo string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/mirror-sync", owner, repo), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepoLanguages return language stats of a repo
|
||||||
|
func (c *Client) GetRepoLanguages(owner, repo string) (map[string]int64, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
langMap := make(map[string]int64)
|
||||||
|
|
||||||
|
data, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/languages", owner, repo), jsonHeader, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(data, &langMap); err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return langMap, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArchiveType represent supported archive formats by gitea
|
||||||
|
type ArchiveType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ZipArchive represent zip format
|
||||||
|
ZipArchive ArchiveType = ".zip"
|
||||||
|
// TarGZArchive represent tar.gz format
|
||||||
|
TarGZArchive ArchiveType = ".tar.gz"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetArchive get an archive of a repository by git reference
|
||||||
|
// e.g.: ref -> master, 70b7c74b33, v1.2.1, ...
|
||||||
|
func (c *Client) GetArchive(owner, repo, ref string, ext ArchiveType) ([]byte, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
ref = pathEscapeSegments(ref)
|
||||||
|
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, ref, ext), nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetArchiveReader gets a `git archive` for a particular tree-ish git reference
|
||||||
|
// such as a branch name (`master`), a commit hash (`70b7c74b33`), a tag
|
||||||
|
// (`v1.2.1`). The archive is returned as a byte stream in a ReadCloser. It is
|
||||||
|
// the responsibility of the client to close the reader.
|
||||||
|
func (c *Client) GetArchiveReader(owner, repo, ref string, ext ArchiveType) (io.ReadCloser, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
ref = pathEscapeSegments(ref)
|
||||||
|
resp, err := c.doRequest("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, ref, ext), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := statusCodeToErr(resp); err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Body, resp, nil
|
||||||
|
}
|
||||||
143
vendor/code.gitea.io/sdk/gitea/repo_branch.go
generated
vendored
Normal file
143
vendor/code.gitea.io/sdk/gitea/repo_branch.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PayloadUser represents the author or committer of a commit
|
||||||
|
type PayloadUser struct {
|
||||||
|
// Full name of the commit author
|
||||||
|
Name string `json:"name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
UserName string `json:"username"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PayloadCommit represents a commit
|
||||||
|
type PayloadCommit struct {
|
||||||
|
// sha1 hash of the commit
|
||||||
|
ID string `json:"id"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Author *PayloadUser `json:"author"`
|
||||||
|
Committer *PayloadUser `json:"committer"`
|
||||||
|
Verification *PayloadCommitVerification `json:"verification"`
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
Added []string `json:"added"`
|
||||||
|
Removed []string `json:"removed"`
|
||||||
|
Modified []string `json:"modified"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PayloadCommitVerification represents the GPG verification of a commit
|
||||||
|
type PayloadCommitVerification struct {
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
Signature string `json:"signature"`
|
||||||
|
Payload string `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Branch represents a repository branch
|
||||||
|
type Branch struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Commit *PayloadCommit `json:"commit"`
|
||||||
|
Protected bool `json:"protected"`
|
||||||
|
RequiredApprovals int64 `json:"required_approvals"`
|
||||||
|
EnableStatusCheck bool `json:"enable_status_check"`
|
||||||
|
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||||
|
UserCanPush bool `json:"user_can_push"`
|
||||||
|
UserCanMerge bool `json:"user_can_merge"`
|
||||||
|
EffectiveBranchProtectionName string `json:"effective_branch_protection_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoBranchesOptions options for listing a repository's branches
|
||||||
|
type ListRepoBranchesOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoBranches list all the branches of one repository
|
||||||
|
func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions) ([]*Branch, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
branches := make([]*Branch, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &branches)
|
||||||
|
return branches, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepoBranch get one branch's information of one repository
|
||||||
|
func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
b := new(Branch)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil, &b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return b, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRepoBranch delete a branch in a repository
|
||||||
|
func (c *Client) DeleteRepoBranch(user, repo, branch string) (bool, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, resp, err
|
||||||
|
}
|
||||||
|
return status == 204, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBranchOption options when creating a branch in a repository
|
||||||
|
type CreateBranchOption struct {
|
||||||
|
// Name of the branch to create
|
||||||
|
BranchName string `json:"new_branch_name"`
|
||||||
|
// Name of the old branch to create from (optional)
|
||||||
|
OldBranchName string `json:"old_branch_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the CreateBranchOption struct
|
||||||
|
func (opt CreateBranchOption) Validate() error {
|
||||||
|
if len(opt.BranchName) == 0 {
|
||||||
|
return fmt.Errorf("BranchName is empty")
|
||||||
|
}
|
||||||
|
if len(opt.BranchName) > 100 {
|
||||||
|
return fmt.Errorf("BranchName to long")
|
||||||
|
}
|
||||||
|
if len(opt.OldBranchName) > 100 {
|
||||||
|
return fmt.Errorf("OldBranchName to long")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBranch creates a branch for a user's repository
|
||||||
|
func (c *Client) CreateBranch(owner, repo string, opt CreateBranchOption) (*Branch, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
branch := new(Branch)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/branches", owner, repo), jsonHeader, bytes.NewReader(body), branch)
|
||||||
|
return branch, resp, err
|
||||||
|
}
|
||||||
173
vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go
generated
vendored
Normal file
173
vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BranchProtection represents a branch protection for a repository
|
||||||
|
type BranchProtection struct {
|
||||||
|
BranchName string `json:"branch_name"`
|
||||||
|
RuleName string `json:"rule_name"`
|
||||||
|
EnablePush bool `json:"enable_push"`
|
||||||
|
EnablePushWhitelist bool `json:"enable_push_whitelist"`
|
||||||
|
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||||
|
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||||
|
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
|
||||||
|
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
|
||||||
|
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||||
|
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||||
|
EnableStatusCheck bool `json:"enable_status_check"`
|
||||||
|
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||||
|
RequiredApprovals int64 `json:"required_approvals"`
|
||||||
|
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
|
||||||
|
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||||
|
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||||
|
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
|
||||||
|
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"`
|
||||||
|
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
|
||||||
|
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
|
||||||
|
RequireSignedCommits bool `json:"require_signed_commits"`
|
||||||
|
ProtectedFilePatterns string `json:"protected_file_patterns"`
|
||||||
|
UnprotectedFilePatterns string `json:"unprotected_file_patterns"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
Updated time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBranchProtectionOption options for creating a branch protection
|
||||||
|
type CreateBranchProtectionOption struct {
|
||||||
|
BranchName string `json:"branch_name"`
|
||||||
|
RuleName string `json:"rule_name"`
|
||||||
|
EnablePush bool `json:"enable_push"`
|
||||||
|
EnablePushWhitelist bool `json:"enable_push_whitelist"`
|
||||||
|
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||||
|
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||||
|
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
|
||||||
|
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
|
||||||
|
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||||
|
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||||
|
EnableStatusCheck bool `json:"enable_status_check"`
|
||||||
|
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||||
|
RequiredApprovals int64 `json:"required_approvals"`
|
||||||
|
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
|
||||||
|
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||||
|
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||||
|
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
|
||||||
|
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"`
|
||||||
|
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
|
||||||
|
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
|
||||||
|
RequireSignedCommits bool `json:"require_signed_commits"`
|
||||||
|
ProtectedFilePatterns string `json:"protected_file_patterns"`
|
||||||
|
UnprotectedFilePatterns string `json:"unprotected_file_patterns"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditBranchProtectionOption options for editing a branch protection
|
||||||
|
type EditBranchProtectionOption struct {
|
||||||
|
EnablePush *bool `json:"enable_push"`
|
||||||
|
EnablePushWhitelist *bool `json:"enable_push_whitelist"`
|
||||||
|
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||||
|
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||||
|
PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"`
|
||||||
|
EnableMergeWhitelist *bool `json:"enable_merge_whitelist"`
|
||||||
|
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||||
|
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||||
|
EnableStatusCheck *bool `json:"enable_status_check"`
|
||||||
|
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||||
|
RequiredApprovals *int64 `json:"required_approvals"`
|
||||||
|
EnableApprovalsWhitelist *bool `json:"enable_approvals_whitelist"`
|
||||||
|
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||||
|
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||||
|
BlockOnRejectedReviews *bool `json:"block_on_rejected_reviews"`
|
||||||
|
BlockOnOfficialReviewRequests *bool `json:"block_on_official_review_requests"`
|
||||||
|
BlockOnOutdatedBranch *bool `json:"block_on_outdated_branch"`
|
||||||
|
DismissStaleApprovals *bool `json:"dismiss_stale_approvals"`
|
||||||
|
RequireSignedCommits *bool `json:"require_signed_commits"`
|
||||||
|
ProtectedFilePatterns *string `json:"protected_file_patterns"`
|
||||||
|
UnprotectedFilePatterns *string `json:"unprotected_file_patterns"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListBranchProtectionsOptions list branch protection options
|
||||||
|
type ListBranchProtectionsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListBranchProtections list branch protections for a repo
|
||||||
|
func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtectionsOptions) ([]*BranchProtection, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
bps := make([]*BranchProtection, 0, opt.PageSize)
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/branch_protections", owner, repo))
|
||||||
|
link.RawQuery = opt.getURLQuery().Encode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &bps)
|
||||||
|
return bps, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBranchProtection gets a branch protection
|
||||||
|
func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtection, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
bp := new(BranchProtection)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, nil, bp)
|
||||||
|
return bp, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBranchProtection creates a branch protection for a repo
|
||||||
|
func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProtectionOption) (*BranchProtection, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
bp := new(BranchProtection)
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/branch_protections", owner, repo), jsonHeader, bytes.NewReader(body), bp)
|
||||||
|
return bp, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditBranchProtection edits a branch protection for a repo
|
||||||
|
func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchProtectionOption) (*BranchProtection, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
bp := new(BranchProtection)
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, bytes.NewReader(body), bp)
|
||||||
|
return bp, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteBranchProtection deletes a branch protection for a repo
|
||||||
|
func (c *Client) DeleteBranchProtection(owner, repo, name string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
163
vendor/code.gitea.io/sdk/gitea/repo_collaborator.go
generated
vendored
Normal file
163
vendor/code.gitea.io/sdk/gitea/repo_collaborator.go
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListCollaboratorsOptions options for listing a repository's collaborators
|
||||||
|
type ListCollaboratorsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// CollaboratorPermissionResult result type for CollaboratorPermission
|
||||||
|
type CollaboratorPermissionResult struct {
|
||||||
|
Permission AccessMode `json:"permission"`
|
||||||
|
Role string `json:"role_name"`
|
||||||
|
User *User `json:"user"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCollaborators list a repository's collaborators
|
||||||
|
func (c *Client) ListCollaborators(user, repo string, opt ListCollaboratorsOptions) ([]*User, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
collaborators := make([]*User, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/collaborators?%s", user, repo, opt.getURLQuery().Encode()),
|
||||||
|
nil, nil, &collaborators)
|
||||||
|
return collaborators, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCollaborator check if a user is a collaborator of a repository
|
||||||
|
func (c *Client) IsCollaborator(user, repo, collaborator string) (bool, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &collaborator); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, resp, err
|
||||||
|
}
|
||||||
|
if status == 204 {
|
||||||
|
return true, resp, nil
|
||||||
|
}
|
||||||
|
return false, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CollaboratorPermission gets collaborator permission of a repository
|
||||||
|
func (c *Client) CollaboratorPermission(user, repo, collaborator string) (*CollaboratorPermissionResult, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &collaborator); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
rv := new(CollaboratorPermissionResult)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/collaborators/%s/permission", user, repo, collaborator),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
rv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
rv = nil
|
||||||
|
}
|
||||||
|
return rv, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddCollaboratorOption options when adding a user as a collaborator of a repository
|
||||||
|
type AddCollaboratorOption struct {
|
||||||
|
Permission *AccessMode `json:"permission"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccessMode represent the grade of access you have to something
|
||||||
|
type AccessMode string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// AccessModeNone no access
|
||||||
|
AccessModeNone AccessMode = "none"
|
||||||
|
// AccessModeRead read access
|
||||||
|
AccessModeRead AccessMode = "read"
|
||||||
|
// AccessModeWrite write access
|
||||||
|
AccessModeWrite AccessMode = "write"
|
||||||
|
// AccessModeAdmin admin access
|
||||||
|
AccessModeAdmin AccessMode = "admin"
|
||||||
|
// AccessModeOwner owner
|
||||||
|
AccessModeOwner AccessMode = "owner"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Validate the AddCollaboratorOption struct
|
||||||
|
func (opt *AddCollaboratorOption) Validate() error {
|
||||||
|
if opt.Permission != nil {
|
||||||
|
if *opt.Permission == AccessModeOwner {
|
||||||
|
*opt.Permission = AccessModeAdmin
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if *opt.Permission == AccessModeNone {
|
||||||
|
opt.Permission = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if *opt.Permission != AccessModeRead && *opt.Permission != AccessModeWrite && *opt.Permission != AccessModeAdmin {
|
||||||
|
return fmt.Errorf("permission mode invalid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddCollaborator add some user as a collaborator of a repository
|
||||||
|
func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollaboratorOption) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &collaborator); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := (&opt).Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteCollaborator remove a collaborator from a repository
|
||||||
|
func (c *Client) DeleteCollaborator(user, repo, collaborator string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &collaborator); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReviewers return all users that can be requested to review in this repo
|
||||||
|
func (c *Client) GetReviewers(user, repo string) ([]*User, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
reviewers := make([]*User, 0, 5)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/reviewers", user, repo), nil, nil, &reviewers)
|
||||||
|
return reviewers, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAssignees return all users that have write access and can be assigned to issues
|
||||||
|
func (c *Client) GetAssignees(user, repo string) ([]*User, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
assignees := make([]*User, 0, 5)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/assignees", user, repo), nil, nil, &assignees)
|
||||||
|
return assignees, resp, err
|
||||||
|
}
|
||||||
141
vendor/code.gitea.io/sdk/gitea/repo_commit.go
generated
vendored
Normal file
141
vendor/code.gitea.io/sdk/gitea/repo_commit.go
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
// Copyright 2018 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Identity for a person's identity like an author or committer
|
||||||
|
type Identity struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitMeta contains meta information of a commit in terms of API.
|
||||||
|
type CommitMeta struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitUser contains information of a user in the context of a commit.
|
||||||
|
type CommitUser struct {
|
||||||
|
Identity
|
||||||
|
Date string `json:"date"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoCommit contains information of a commit in the context of a repository.
|
||||||
|
type RepoCommit struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Author *CommitUser `json:"author"`
|
||||||
|
Committer *CommitUser `json:"committer"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Tree *CommitMeta `json:"tree"`
|
||||||
|
Verification *PayloadCommitVerification `json:"verification"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitStats contains stats from a Git commit
|
||||||
|
type CommitStats struct {
|
||||||
|
Total int `json:"total"`
|
||||||
|
Additions int `json:"additions"`
|
||||||
|
Deletions int `json:"deletions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit contains information generated from a Git commit.
|
||||||
|
type Commit struct {
|
||||||
|
*CommitMeta
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
RepoCommit *RepoCommit `json:"commit"`
|
||||||
|
Author *User `json:"author"`
|
||||||
|
Committer *User `json:"committer"`
|
||||||
|
Parents []*CommitMeta `json:"parents"`
|
||||||
|
Files []*CommitAffectedFiles `json:"files"`
|
||||||
|
Stats *CommitStats `json:"stats"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE
|
||||||
|
type CommitDateOptions struct {
|
||||||
|
Author time.Time `json:"author"`
|
||||||
|
Committer time.Time `json:"committer"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitAffectedFiles store information about files affected by the commit
|
||||||
|
type CommitAffectedFiles struct {
|
||||||
|
Filename string `json:"filename"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSingleCommit returns a single commit
|
||||||
|
func (c *Client) GetSingleCommit(user, repo, commitID string) (*Commit, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &commitID); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
commit := new(Commit)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/commits/%s", user, repo, commitID), nil, nil, &commit)
|
||||||
|
return commit, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommitOptions list commit options
|
||||||
|
type ListCommitOptions struct {
|
||||||
|
ListOptions
|
||||||
|
// SHA or branch to start listing commits from (usually 'master')
|
||||||
|
SHA string
|
||||||
|
// Path indicates that only commits that include the path's file/dir should be returned.
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *ListCommitOptions) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
if opt.SHA != "" {
|
||||||
|
query.Add("sha", opt.SHA)
|
||||||
|
}
|
||||||
|
if opt.Path != "" {
|
||||||
|
query.Add("path", opt.Path)
|
||||||
|
}
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoCommits return list of commits from a repo
|
||||||
|
func (c *Client) ListRepoCommits(user, repo string, opt ListCommitOptions) ([]*Commit, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/commits", user, repo))
|
||||||
|
opt.setDefaults()
|
||||||
|
commits := make([]*Commit, 0, opt.PageSize)
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &commits)
|
||||||
|
return commits, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommitDiff returns the commit's raw diff.
|
||||||
|
func (c *Client) GetCommitDiff(user, repo, commitID string) ([]byte, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/git/commits/%s.%s", user, repo, commitID, pullRequestDiffTypeDiff), nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommitPatch returns the commit's raw patch.
|
||||||
|
func (c *Client) GetCommitPatch(user, repo, commitID string) ([]byte, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/git/commits/%s.%s", user, repo, commitID, pullRequestDiffTypePatch), nil, nil)
|
||||||
|
}
|
||||||
277
vendor/code.gitea.io/sdk/gitea/repo_file.go
generated
vendored
Normal file
277
vendor/code.gitea.io/sdk/gitea/repo_file.go
generated
vendored
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FileOptions options for all file APIs
|
||||||
|
type FileOptions struct {
|
||||||
|
// message (optional) for the commit of this file. if not supplied, a default message will be used
|
||||||
|
Message string `json:"message"`
|
||||||
|
// branch (optional) to base this file from. if not given, the default branch is used
|
||||||
|
BranchName string `json:"branch"`
|
||||||
|
// new_branch (optional) will make a new branch from `branch` before creating the file
|
||||||
|
NewBranchName string `json:"new_branch"`
|
||||||
|
// `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
|
||||||
|
Author Identity `json:"author"`
|
||||||
|
Committer Identity `json:"committer"`
|
||||||
|
Dates CommitDateOptions `json:"dates"`
|
||||||
|
// Add a Signed-off-by trailer by the committer at the end of the commit log message.
|
||||||
|
Signoff bool `json:"signoff"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateFileOptions options for creating files
|
||||||
|
// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
|
||||||
|
type CreateFileOptions struct {
|
||||||
|
FileOptions
|
||||||
|
// content must be base64 encoded
|
||||||
|
// required: true
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteFileOptions options for deleting files (used for other File structs below)
|
||||||
|
// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
|
||||||
|
type DeleteFileOptions struct {
|
||||||
|
FileOptions
|
||||||
|
// sha is the SHA for the file that already exists
|
||||||
|
// required: true
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateFileOptions options for updating files
|
||||||
|
// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
|
||||||
|
type UpdateFileOptions struct {
|
||||||
|
FileOptions
|
||||||
|
// sha is the SHA for the file that already exists
|
||||||
|
// required: true
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
// content must be base64 encoded
|
||||||
|
// required: true
|
||||||
|
Content string `json:"content"`
|
||||||
|
// from_path (optional) is the path of the original file which will be moved/renamed to the path in the URL
|
||||||
|
FromPath string `json:"from_path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileLinksResponse contains the links for a repo's file
|
||||||
|
type FileLinksResponse struct {
|
||||||
|
Self *string `json:"self"`
|
||||||
|
GitURL *string `json:"git"`
|
||||||
|
HTMLURL *string `json:"html"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
|
||||||
|
type ContentsResponse struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
// `type` will be `file`, `dir`, `symlink`, or `submodule`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
// `encoding` is populated when `type` is `file`, otherwise null
|
||||||
|
Encoding *string `json:"encoding"`
|
||||||
|
// `content` is populated when `type` is `file`, otherwise null
|
||||||
|
Content *string `json:"content"`
|
||||||
|
// `target` is populated when `type` is `symlink`, otherwise null
|
||||||
|
Target *string `json:"target"`
|
||||||
|
URL *string `json:"url"`
|
||||||
|
HTMLURL *string `json:"html_url"`
|
||||||
|
GitURL *string `json:"git_url"`
|
||||||
|
DownloadURL *string `json:"download_url"`
|
||||||
|
// `submodule_git_url` is populated when `type` is `submodule`, otherwise null
|
||||||
|
SubmoduleGitURL *string `json:"submodule_git_url"`
|
||||||
|
Links *FileLinksResponse `json:"_links"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileCommitResponse contains information generated from a Git commit for a repo's file.
|
||||||
|
type FileCommitResponse struct {
|
||||||
|
CommitMeta
|
||||||
|
HTMLURL string `json:"html_url"`
|
||||||
|
Author *CommitUser `json:"author"`
|
||||||
|
Committer *CommitUser `json:"committer"`
|
||||||
|
Parents []*CommitMeta `json:"parents"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Tree *CommitMeta `json:"tree"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileResponse contains information about a repo's file
|
||||||
|
type FileResponse struct {
|
||||||
|
Content *ContentsResponse `json:"content"`
|
||||||
|
Commit *FileCommitResponse `json:"commit"`
|
||||||
|
Verification *PayloadCommitVerification `json:"verification"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileDeleteResponse contains information about a repo's file that was deleted
|
||||||
|
type FileDeleteResponse struct {
|
||||||
|
Content interface{} `json:"content"` // to be set to nil
|
||||||
|
Commit *FileCommitResponse `json:"commit"`
|
||||||
|
Verification *PayloadCommitVerification `json:"verification"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFile downloads a file of repository, ref can be branch/tag/commit.
|
||||||
|
// it optional can resolve lfs pointers and server the file instead
|
||||||
|
// e.g.: ref -> master, filepath -> README.md (no leading slash)
|
||||||
|
func (c *Client) GetFile(owner, repo, ref, filepath string, resolveLFS ...bool) ([]byte, *Response, error) {
|
||||||
|
reader, resp, err := c.GetFileReader(owner, repo, ref, filepath, resolveLFS...)
|
||||||
|
if reader == nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
data, err2 := io.ReadAll(reader)
|
||||||
|
if err2 != nil {
|
||||||
|
return nil, resp, err2
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFileReader return reader for download a file of repository, ref can be branch/tag/commit.
|
||||||
|
// it optional can resolve lfs pointers and server the file instead
|
||||||
|
// e.g.: ref -> master, filepath -> README.md (no leading slash)
|
||||||
|
func (c *Client) GetFileReader(owner, repo, ref, filepath string, resolveLFS ...bool) (io.ReadCloser, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve lfs
|
||||||
|
if len(resolveLFS) != 0 && resolveLFS[0] {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_17_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return c.getResponseReader("GET", fmt.Sprintf("/repos/%s/%s/media/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// normal get
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
|
||||||
|
ref = pathEscapeSegments(ref)
|
||||||
|
return c.getResponseReader("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", owner, repo, ref, filepath), nil, nil)
|
||||||
|
}
|
||||||
|
return c.getResponseReader("GET", fmt.Sprintf("/repos/%s/%s/raw/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContents get the metadata and contents of a file in a repository
|
||||||
|
// ref is optional
|
||||||
|
func (c *Client) GetContents(owner, repo, ref, filepath string) (*ContentsResponse, *Response, error) {
|
||||||
|
data, resp, err := c.getDirOrFileContents(owner, repo, ref, filepath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
cr := new(ContentsResponse)
|
||||||
|
if json.Unmarshal(data, &cr) != nil {
|
||||||
|
return nil, resp, fmt.Errorf("expect file, got directory")
|
||||||
|
}
|
||||||
|
return cr, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListContents gets a list of entries in a dir
|
||||||
|
// ref is optional
|
||||||
|
func (c *Client) ListContents(owner, repo, ref, filepath string) ([]*ContentsResponse, *Response, error) {
|
||||||
|
data, resp, err := c.getDirOrFileContents(owner, repo, ref, filepath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
crl := make([]*ContentsResponse, 0)
|
||||||
|
if json.Unmarshal(data, &crl) != nil {
|
||||||
|
return nil, resp, fmt.Errorf("expect directory, got file")
|
||||||
|
}
|
||||||
|
return crl, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getDirOrFileContents(owner, repo, ref, filepath string) ([]byte, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
filepath = pathEscapeSegments(strings.TrimPrefix(filepath, "/"))
|
||||||
|
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), jsonHeader, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateFile create a file in a repository
|
||||||
|
func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions) (*FileResponse, *Response, error) {
|
||||||
|
var err error
|
||||||
|
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
|
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
fr := new(FileResponse)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body), fr)
|
||||||
|
return fr, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateFile update a file in a repository
|
||||||
|
func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions) (*FileResponse, *Response, error) {
|
||||||
|
var err error
|
||||||
|
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
|
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
fr := new(FileResponse)
|
||||||
|
resp, err := c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body), fr)
|
||||||
|
return fr, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteFile delete a file from repository
|
||||||
|
func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) (*Response, error) {
|
||||||
|
var err error
|
||||||
|
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
filepath = pathEscapeSegments(filepath)
|
||||||
|
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
if status != 200 && status != 204 {
|
||||||
|
return resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) setDefaultBranchForOldVersions(owner, repo, branch string) (string, error) {
|
||||||
|
if len(branch) == 0 {
|
||||||
|
// Gitea >= 1.12.0 Use DefaultBranch on "", mimic this for older versions
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_12_0) != nil {
|
||||||
|
r, _, err := c.GetRepo(owner, repo)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return r.DefaultBranch, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return branch, nil
|
||||||
|
}
|
||||||
91
vendor/code.gitea.io/sdk/gitea/repo_key.go
generated
vendored
Normal file
91
vendor/code.gitea.io/sdk/gitea/repo_key.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeployKey a deploy key
|
||||||
|
type DeployKey struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
KeyID int64 `json:"key_id"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Fingerprint string `json:"fingerprint"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
ReadOnly bool `json:"read_only"`
|
||||||
|
Repository *Repository `json:"repository,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListDeployKeysOptions options for listing a repository's deploy keys
|
||||||
|
type ListDeployKeysOptions struct {
|
||||||
|
ListOptions
|
||||||
|
KeyID int64
|
||||||
|
Fingerprint string
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryEncode turns options into querystring argument
|
||||||
|
func (opt *ListDeployKeysOptions) QueryEncode() string {
|
||||||
|
query := opt.getURLQuery()
|
||||||
|
if opt.KeyID > 0 {
|
||||||
|
query.Add("key_id", fmt.Sprintf("%d", opt.KeyID))
|
||||||
|
}
|
||||||
|
if len(opt.Fingerprint) > 0 {
|
||||||
|
query.Add("fingerprint", opt.Fingerprint)
|
||||||
|
}
|
||||||
|
return query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListDeployKeys list all the deploy keys of one repository
|
||||||
|
func (c *Client) ListDeployKeys(user, repo string, opt ListDeployKeysOptions) ([]*DeployKey, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/keys", user, repo))
|
||||||
|
opt.setDefaults()
|
||||||
|
link.RawQuery = opt.QueryEncode()
|
||||||
|
keys := make([]*DeployKey, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &keys)
|
||||||
|
return keys, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDeployKey get one deploy key with key id
|
||||||
|
func (c *Client) GetDeployKey(user, repo string, keyID int64) (*DeployKey, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
key := new(DeployKey)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys/%d", user, repo, keyID), nil, nil, &key)
|
||||||
|
return key, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDeployKey options when create one deploy key
|
||||||
|
func (c *Client) CreateDeployKey(user, repo string, opt CreateKeyOption) (*DeployKey, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
key := new(DeployKey)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/keys", user, repo), jsonHeader, bytes.NewReader(body), key)
|
||||||
|
return key, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteDeployKey delete deploy key with key id
|
||||||
|
func (c *Client) DeleteDeployKey(owner, repo string, keyID int64) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/keys/%d", owner, repo, keyID), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
132
vendor/code.gitea.io/sdk/gitea/repo_migrate.go
generated
vendored
Normal file
132
vendor/code.gitea.io/sdk/gitea/repo_migrate.go
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GitServiceType represents a git service
|
||||||
|
type GitServiceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// GitServicePlain represents a plain git service
|
||||||
|
GitServicePlain GitServiceType = "git"
|
||||||
|
// GitServiceGithub represents github.com
|
||||||
|
GitServiceGithub GitServiceType = "github"
|
||||||
|
// GitServiceGitlab represents a gitlab service
|
||||||
|
GitServiceGitlab GitServiceType = "gitlab"
|
||||||
|
// GitServiceGitea represents a gitea service
|
||||||
|
GitServiceGitea GitServiceType = "gitea"
|
||||||
|
// GitServiceGogs represents a gogs service
|
||||||
|
GitServiceGogs GitServiceType = "gogs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MigrateRepoOption options for migrating a repository from an external service
|
||||||
|
type MigrateRepoOption struct {
|
||||||
|
RepoName string `json:"repo_name"`
|
||||||
|
RepoOwner string `json:"repo_owner"`
|
||||||
|
// deprecated use RepoOwner
|
||||||
|
RepoOwnerID int64 `json:"uid"`
|
||||||
|
CloneAddr string `json:"clone_addr"`
|
||||||
|
Service GitServiceType `json:"service"`
|
||||||
|
AuthUsername string `json:"auth_username"`
|
||||||
|
AuthPassword string `json:"auth_password"`
|
||||||
|
AuthToken string `json:"auth_token"`
|
||||||
|
Mirror bool `json:"mirror"`
|
||||||
|
Private bool `json:"private"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Wiki bool `json:"wiki"`
|
||||||
|
Milestones bool `json:"milestones"`
|
||||||
|
Labels bool `json:"labels"`
|
||||||
|
Issues bool `json:"issues"`
|
||||||
|
PullRequests bool `json:"pull_requests"`
|
||||||
|
Releases bool `json:"releases"`
|
||||||
|
MirrorInterval string `json:"mirror_interval"`
|
||||||
|
LFS bool `json:"lfs"`
|
||||||
|
LFSEndpoint string `json:"lfs_endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the MigrateRepoOption struct
|
||||||
|
func (opt *MigrateRepoOption) Validate(c *Client) error {
|
||||||
|
// check user options
|
||||||
|
if len(opt.CloneAddr) == 0 {
|
||||||
|
return fmt.Errorf("CloneAddr required")
|
||||||
|
}
|
||||||
|
if len(opt.RepoName) == 0 {
|
||||||
|
return fmt.Errorf("RepoName required")
|
||||||
|
} else if len(opt.RepoName) > 100 {
|
||||||
|
return fmt.Errorf("RepoName to long")
|
||||||
|
}
|
||||||
|
if len(opt.Description) > 2048 {
|
||||||
|
return fmt.Errorf("Description to long")
|
||||||
|
}
|
||||||
|
switch opt.Service {
|
||||||
|
case GitServiceGithub:
|
||||||
|
if len(opt.AuthToken) == 0 {
|
||||||
|
return fmt.Errorf("github requires token authentication")
|
||||||
|
}
|
||||||
|
case GitServiceGitlab, GitServiceGitea:
|
||||||
|
if len(opt.AuthToken) == 0 {
|
||||||
|
return fmt.Errorf("%s requires token authentication", opt.Service)
|
||||||
|
}
|
||||||
|
// Gitlab is supported since 1.12.0 but api cant handle it until 1.13.0
|
||||||
|
// https://github.com/go-gitea/gitea/pull/12672
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
|
||||||
|
return fmt.Errorf("migrate from service %s need gitea >= 1.13.0", opt.Service)
|
||||||
|
}
|
||||||
|
case GitServiceGogs:
|
||||||
|
if len(opt.AuthToken) == 0 {
|
||||||
|
return fmt.Errorf("gogs requires token authentication")
|
||||||
|
}
|
||||||
|
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
|
||||||
|
return fmt.Errorf("migrate from service gogs need gitea >= 1.14.0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MigrateRepo migrates a repository from other Git hosting sources for the authenticated user.
|
||||||
|
//
|
||||||
|
// To migrate a repository for a organization, the authenticated user must be a
|
||||||
|
// owner of the specified organization.
|
||||||
|
func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, *Response, error) {
|
||||||
|
if err := opt.Validate(c); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
if len(opt.AuthToken) != 0 {
|
||||||
|
// gitea <= 1.12 dont understand AuthToken
|
||||||
|
opt.AuthUsername = opt.AuthToken
|
||||||
|
opt.AuthPassword, opt.AuthToken = "", ""
|
||||||
|
}
|
||||||
|
if len(opt.RepoOwner) != 0 {
|
||||||
|
// gitea <= 1.12 dont understand RepoOwner
|
||||||
|
u, _, err := c.GetUserInfo(opt.RepoOwner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.RepoOwnerID = u.ID
|
||||||
|
} else if opt.RepoOwnerID == 0 {
|
||||||
|
// gitea <= 1.12 require RepoOwnerID
|
||||||
|
u, _, err := c.GetMyUserInfo()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.RepoOwnerID = u.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", "/repos/migrate", jsonHeader, bytes.NewReader(body), repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
45
vendor/code.gitea.io/sdk/gitea/repo_mirror.go
generated
vendored
Normal file
45
vendor/code.gitea.io/sdk/gitea/repo_mirror.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreatePushMirrorOption struct {
|
||||||
|
Interval string `json:"interval"`
|
||||||
|
RemoteAddress string `json:"remote_address"`
|
||||||
|
RemotePassword string `json:"remote_password"`
|
||||||
|
RemoteUsername string `json:"remote_username"`
|
||||||
|
SyncONCommit bool `json:"sync_on_commit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushMirrorResponse returns a git push mirror
|
||||||
|
type PushMirrorResponse struct {
|
||||||
|
Created string `json:"created"`
|
||||||
|
Interval string `json:"interval"`
|
||||||
|
LastError string `json:"last_error"`
|
||||||
|
LastUpdate string `json:"last_update"`
|
||||||
|
RemoteAddress string `json:"remote_address"`
|
||||||
|
RemoteName string `json:"remote_name"`
|
||||||
|
RepoName string `json:"repo_name"`
|
||||||
|
SyncONCommit bool `json:"sync_on_commit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushMirrors add a push mirror to the repository
|
||||||
|
func (c *Client) PushMirrors(user, repo string, opt CreatePushMirrorOption) (*PushMirrorResponse, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pm := new(PushMirrorResponse)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/push_mirrors", user, repo), jsonHeader, bytes.NewReader(body), &pm)
|
||||||
|
return pm, resp, err
|
||||||
|
}
|
||||||
78
vendor/code.gitea.io/sdk/gitea/repo_refs.go
generated
vendored
Normal file
78
vendor/code.gitea.io/sdk/gitea/repo_refs.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reference represents a Git reference.
|
||||||
|
type Reference struct {
|
||||||
|
Ref string `json:"ref"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Object *GitObject `json:"object"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GitObject represents a Git object.
|
||||||
|
type GitObject struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepoRef get one ref's information of one repository
|
||||||
|
func (c *Client) GetRepoRef(user, repo, ref string) (*Reference, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
ref = strings.TrimPrefix(ref, "refs/")
|
||||||
|
ref = pathEscapeSegments(ref)
|
||||||
|
r := new(Reference)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil, &r)
|
||||||
|
if _, ok := err.(*json.UnmarshalTypeError); ok {
|
||||||
|
// Multiple refs
|
||||||
|
return nil, resp, errors.New("no exact match found for this ref")
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRepoRefs get list of ref's information of one repository
|
||||||
|
func (c *Client) GetRepoRefs(user, repo, ref string) ([]*Reference, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
ref = strings.TrimPrefix(ref, "refs/")
|
||||||
|
ref = pathEscapeSegments(ref)
|
||||||
|
|
||||||
|
data, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to unmarshal single returned ref.
|
||||||
|
r := new(Reference)
|
||||||
|
refErr := json.Unmarshal(data, r)
|
||||||
|
if refErr == nil {
|
||||||
|
return []*Reference{r}, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to unmarshal multiple refs.
|
||||||
|
var rs []*Reference
|
||||||
|
refsErr := json.Unmarshal(data, &rs)
|
||||||
|
if refsErr == nil {
|
||||||
|
if len(rs) == 0 {
|
||||||
|
return nil, resp, errors.New("unexpected response: an array of refs with length 0")
|
||||||
|
}
|
||||||
|
return rs, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, resp, fmt.Errorf("unmarshalling failed for both single and multiple refs: %s and %s", refErr, refsErr)
|
||||||
|
}
|
||||||
96
vendor/code.gitea.io/sdk/gitea/repo_stars.go
generated
vendored
Normal file
96
vendor/code.gitea.io/sdk/gitea/repo_stars.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListStargazersOptions options for listing a repository's stargazers
|
||||||
|
type ListStargazersOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoStargazers list a repository's stargazers
|
||||||
|
func (c *Client) ListRepoStargazers(user, repo string, opt ListStargazersOptions) ([]*User, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
stargazers := make([]*User, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/stargazers?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &stargazers)
|
||||||
|
return stargazers, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStarredRepos returns the repos that the given user has starred
|
||||||
|
func (c *Client) GetStarredRepos(user string) ([]*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repos := make([]*Repository, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/starred", user), jsonHeader, nil, &repos)
|
||||||
|
return repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMyStarredRepos returns the repos that the authenticated user has starred
|
||||||
|
func (c *Client) GetMyStarredRepos() ([]*Repository, *Response, error) {
|
||||||
|
repos := make([]*Repository, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", "/user/starred", jsonHeader, nil, &repos)
|
||||||
|
return repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRepoStarring returns whether the authenticated user has starred the repo or not
|
||||||
|
func (c *Client) IsRepoStarring(user, repo string) (bool, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("GET", fmt.Sprintf("/user/starred/%s/%s", user, repo), jsonHeader, nil)
|
||||||
|
if resp != nil {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return false, resp, nil
|
||||||
|
case http.StatusNoContent:
|
||||||
|
return true, resp, nil
|
||||||
|
default:
|
||||||
|
return false, resp, fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StarRepo star specified repo as the authenticated user
|
||||||
|
func (c *Client) StarRepo(user, repo string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/user/starred/%s/%s", user, repo), jsonHeader, nil)
|
||||||
|
if resp != nil {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case http.StatusNoContent:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return resp, fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnStarRepo remove star to specified repo as the authenticated user
|
||||||
|
func (c *Client) UnStarRepo(user, repo string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/starred/%s/%s", user, repo), jsonHeader, nil)
|
||||||
|
if resp != nil {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case http.StatusNoContent:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return resp, fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
130
vendor/code.gitea.io/sdk/gitea/repo_tag.go
generated
vendored
Normal file
130
vendor/code.gitea.io/sdk/gitea/repo_tag.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tag represents a repository tag
|
||||||
|
type Tag struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Commit *CommitMeta `json:"commit"`
|
||||||
|
ZipballURL string `json:"zipball_url"`
|
||||||
|
TarballURL string `json:"tarball_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnnotatedTag represents an annotated tag
|
||||||
|
type AnnotatedTag struct {
|
||||||
|
Tag string `json:"tag"`
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Tagger *CommitUser `json:"tagger"`
|
||||||
|
Object *AnnotatedTagObject `json:"object"`
|
||||||
|
Verification *PayloadCommitVerification `json:"verification"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnnotatedTagObject contains meta information of the tag object
|
||||||
|
type AnnotatedTagObject struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoTagsOptions options for listing a repository's tags
|
||||||
|
type ListRepoTagsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoTags list all the branches of one repository
|
||||||
|
func (c *Client) ListRepoTags(user, repo string, opt ListRepoTagsOptions) ([]*Tag, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
tags := make([]*Tag, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/tags?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &tags)
|
||||||
|
return tags, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTag get the tag of a repository
|
||||||
|
func (c *Client) GetTag(user, repo, tag string) (*Tag, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
t := new(Tag)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/tags/%s", user, repo, tag), nil, nil, &t)
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAnnotatedTag get the tag object of an annotated tag (not lightweight tags) of a repository
|
||||||
|
func (c *Client) GetAnnotatedTag(user, repo, sha string) (*AnnotatedTag, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &sha); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
t := new(AnnotatedTag)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/tags/%s", user, repo, sha), nil, nil, &t)
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTagOption options when creating a tag
|
||||||
|
type CreateTagOption struct {
|
||||||
|
TagName string `json:"tag_name"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates CreateTagOption
|
||||||
|
func (opt CreateTagOption) Validate() error {
|
||||||
|
if len(opt.TagName) == 0 {
|
||||||
|
return fmt.Errorf("TagName is required")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTag create a new git tag in a repository
|
||||||
|
func (c *Client) CreateTag(user, repo string, opt CreateTagOption) (*Tag, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
t := new(Tag)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/tags", user, repo), jsonHeader, bytes.NewReader(body), &t)
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTag deletes a tag from a repository, if no release refers to it
|
||||||
|
func (c *Client) DeleteTag(user, repo, tag string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/tags/%s", user, repo, tag),
|
||||||
|
nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
65
vendor/code.gitea.io/sdk/gitea/repo_team.go
generated
vendored
Normal file
65
vendor/code.gitea.io/sdk/gitea/repo_team.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetRepoTeams return teams from a repository
|
||||||
|
func (c *Client) GetRepoTeams(user, repo string) ([]*Team, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
teams := make([]*Team, 0, 5)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/teams", user, repo), nil, nil, &teams)
|
||||||
|
return teams, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRepoTeam add a team to a repository
|
||||||
|
func (c *Client) AddRepoTeam(user, repo, team string) (*Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &team); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/teams/%s", user, repo, team), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveRepoTeam delete a team from a repository
|
||||||
|
func (c *Client) RemoveRepoTeam(user, repo, team string) (*Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &team); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/teams/%s", user, repo, team), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckRepoTeam check if team is assigned to repo by name and return it.
|
||||||
|
// If not assigned, it will return nil.
|
||||||
|
func (c *Client) CheckRepoTeam(user, repo, team string) (*Team, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &team); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
t := new(Team)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/teams/%s", user, repo, team), nil, nil, &t)
|
||||||
|
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||||
|
// if not found it's not an error, it indicates it's not assigned
|
||||||
|
return nil, resp, nil
|
||||||
|
}
|
||||||
|
return t, resp, err
|
||||||
|
}
|
||||||
65
vendor/code.gitea.io/sdk/gitea/repo_template.go
generated
vendored
Normal file
65
vendor/code.gitea.io/sdk/gitea/repo_template.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateRepoFromTemplateOption options when creating repository using a template
|
||||||
|
type CreateRepoFromTemplateOption struct {
|
||||||
|
// Owner is the organization or person who will own the new repository
|
||||||
|
Owner string `json:"owner"`
|
||||||
|
// Name of the repository to create
|
||||||
|
Name string `json:"name"`
|
||||||
|
// Description of the repository to create
|
||||||
|
Description string `json:"description"`
|
||||||
|
// Private is whether the repository is private
|
||||||
|
Private bool `json:"private"`
|
||||||
|
// GitContent include git content of default branch in template repo
|
||||||
|
GitContent bool `json:"git_content"`
|
||||||
|
// Topics include topics of template repo
|
||||||
|
Topics bool `json:"topics"`
|
||||||
|
// GitHooks include git hooks of template repo
|
||||||
|
GitHooks bool `json:"git_hooks"`
|
||||||
|
// Webhooks include webhooks of template repo
|
||||||
|
Webhooks bool `json:"webhooks"`
|
||||||
|
// Avatar include avatar of the template repo
|
||||||
|
Avatar bool `json:"avatar"`
|
||||||
|
// Labels include labels of template repo
|
||||||
|
Labels bool `json:"labels"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates CreateRepoFromTemplateOption
|
||||||
|
func (opt CreateRepoFromTemplateOption) Validate() error {
|
||||||
|
if len(opt.Owner) == 0 {
|
||||||
|
return fmt.Errorf("field Owner is required")
|
||||||
|
}
|
||||||
|
if len(opt.Name) == 0 {
|
||||||
|
return fmt.Errorf("field Name is required")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRepoFromTemplate create a repository using a template
|
||||||
|
func (c *Client) CreateRepoFromTemplate(templateOwner, templateRepo string, opt CreateRepoFromTemplateOption) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&templateOwner, &templateRepo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/generate", templateOwner, templateRepo), jsonHeader, bytes.NewReader(body), &repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
68
vendor/code.gitea.io/sdk/gitea/repo_topics.go
generated
vendored
Normal file
68
vendor/code.gitea.io/sdk/gitea/repo_topics.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListRepoTopicsOptions options for listing repo's topics
|
||||||
|
type ListRepoTopicsOptions struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// topicsList represents a list of repo's topics
|
||||||
|
type topicsList struct {
|
||||||
|
Topics []string `json:"topics"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoTopics list all repository's topics
|
||||||
|
func (c *Client) ListRepoTopics(user, repo string, opt ListRepoTopicsOptions) ([]string, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
|
||||||
|
list := new(topicsList)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/topics?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, list)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return list.Topics, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRepoTopics replaces the list of repo's topics
|
||||||
|
func (c *Client) SetRepoTopics(user, repo string, list []string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l := topicsList{Topics: list}
|
||||||
|
body, err := json.Marshal(&l)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/topics", user, repo), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRepoTopic adds a topic to a repo's topics list
|
||||||
|
func (c *Client) AddRepoTopic(user, repo, topic string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &topic); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/topics/%s", user, repo, topic), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRepoTopic deletes a topic from repo's topics list
|
||||||
|
func (c *Client) DeleteRepoTopic(user, repo, topic string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &topic); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/topics/%s", user, repo, topic), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
62
vendor/code.gitea.io/sdk/gitea/repo_transfer.go
generated
vendored
Normal file
62
vendor/code.gitea.io/sdk/gitea/repo_transfer.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TransferRepoOption options when transfer a repository's ownership
|
||||||
|
type TransferRepoOption struct {
|
||||||
|
// required: true
|
||||||
|
NewOwner string `json:"new_owner"`
|
||||||
|
// ID of the team or teams to add to the repository. Teams can only be added to organization-owned repositories.
|
||||||
|
TeamIDs *[]int64 `json:"team_ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TransferRepo transfers the ownership of a repository
|
||||||
|
func (c *Client) TransferRepo(owner, reponame string, opt TransferRepoOption) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &reponame); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/transfer", owner, reponame), jsonHeader, bytes.NewReader(body), repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcceptRepoTransfer accepts a repo transfer.
|
||||||
|
func (c *Client) AcceptRepoTransfer(owner, reponame string) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &reponame); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/transfer/accept", owner, reponame), jsonHeader, nil, repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RejectRepoTransfer rejects a repo transfer.
|
||||||
|
func (c *Client) RejectRepoTransfer(owner, reponame string) (*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &reponame); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/transfer/reject", owner, reponame), jsonHeader, nil, repo)
|
||||||
|
return repo, resp, err
|
||||||
|
}
|
||||||
44
vendor/code.gitea.io/sdk/gitea/repo_tree.go
generated
vendored
Normal file
44
vendor/code.gitea.io/sdk/gitea/repo_tree.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GitEntry represents a git tree
|
||||||
|
type GitEntry struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GitTreeResponse returns a git tree
|
||||||
|
type GitTreeResponse struct {
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Entries []GitEntry `json:"tree"`
|
||||||
|
Truncated bool `json:"truncated"`
|
||||||
|
Page int `json:"page"`
|
||||||
|
TotalCount int `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrees downloads a file of repository, ref can be branch/tag/commit.
|
||||||
|
// e.g.: ref -> master, tree -> macaron.go(no leading slash)
|
||||||
|
func (c *Client) GetTrees(user, repo, ref string, recursive bool) (*GitTreeResponse, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &ref); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
trees := new(GitTreeResponse)
|
||||||
|
path := fmt.Sprintf("/repos/%s/%s/git/trees/%s", user, repo, ref)
|
||||||
|
if recursive {
|
||||||
|
path += "?recursive=1"
|
||||||
|
}
|
||||||
|
resp, err := c.getParsedResponse("GET", path, nil, nil, trees)
|
||||||
|
return trees, resp, err
|
||||||
|
}
|
||||||
87
vendor/code.gitea.io/sdk/gitea/repo_watch.go
generated
vendored
Normal file
87
vendor/code.gitea.io/sdk/gitea/repo_watch.go
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WatchInfo represents an API watch status of one repository
|
||||||
|
type WatchInfo struct {
|
||||||
|
Subscribed bool `json:"subscribed"`
|
||||||
|
Ignored bool `json:"ignored"`
|
||||||
|
Reason interface{} `json:"reason"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
RepositoryURL string `json:"repository_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWatchedRepos list all the watched repos of user
|
||||||
|
func (c *Client) GetWatchedRepos(user string) ([]*Repository, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
repos := make([]*Repository, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/subscriptions", user), nil, nil, &repos)
|
||||||
|
return repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMyWatchedRepos list repositories watched by the authenticated user
|
||||||
|
func (c *Client) GetMyWatchedRepos() ([]*Repository, *Response, error) {
|
||||||
|
repos := make([]*Repository, 0, 10)
|
||||||
|
resp, err := c.getParsedResponse("GET", "/user/subscriptions", nil, nil, &repos)
|
||||||
|
return repos, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckRepoWatch check if the current user is watching a repo
|
||||||
|
func (c *Client) CheckRepoWatch(owner, repo string) (bool, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/subscription", owner, repo), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, resp, err
|
||||||
|
}
|
||||||
|
switch status {
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return false, resp, nil
|
||||||
|
case http.StatusOK:
|
||||||
|
return true, resp, nil
|
||||||
|
default:
|
||||||
|
return false, resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WatchRepo start to watch a repository
|
||||||
|
func (c *Client) WatchRepo(owner, repo string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/subscription", owner, repo), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
if status == http.StatusOK {
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
return resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnWatchRepo stop to watch a repository
|
||||||
|
func (c *Client) UnWatchRepo(owner, repo string) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/subscription", owner, repo), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
if status == http.StatusNoContent {
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
return resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
14
vendor/code.gitea.io/sdk/gitea/secret.go
generated
vendored
Normal file
14
vendor/code.gitea.io/sdk/gitea/secret.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Secret struct {
|
||||||
|
// the secret's name
|
||||||
|
Name string `json:"name"`
|
||||||
|
// Date and Time of secret creation
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
78
vendor/code.gitea.io/sdk/gitea/settings.go
generated
vendored
Normal file
78
vendor/code.gitea.io/sdk/gitea/settings.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
// GlobalUISettings represent the global ui settings of a gitea instance witch is exposed by API
|
||||||
|
type GlobalUISettings struct {
|
||||||
|
DefaultTheme string `json:"default_theme"`
|
||||||
|
AllowedReactions []string `json:"allowed_reactions"`
|
||||||
|
CustomEmojis []string `json:"custom_emojis"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalRepoSettings represent the global repository settings of a gitea instance witch is exposed by API
|
||||||
|
type GlobalRepoSettings struct {
|
||||||
|
MirrorsDisabled bool `json:"mirrors_disabled"`
|
||||||
|
HTTPGitDisabled bool `json:"http_git_disabled"`
|
||||||
|
MigrationsDisabled bool `json:"migrations_disabled"`
|
||||||
|
StarsDisabled bool `json:"stars_disabled"`
|
||||||
|
TimeTrackingDisabled bool `json:"time_tracking_disabled"`
|
||||||
|
LFSDisabled bool `json:"lfs_disabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalAPISettings contains global api settings exposed by it
|
||||||
|
type GlobalAPISettings struct {
|
||||||
|
MaxResponseItems int `json:"max_response_items"`
|
||||||
|
DefaultPagingNum int `json:"default_paging_num"`
|
||||||
|
DefaultGitTreesPerPage int `json:"default_git_trees_per_page"`
|
||||||
|
DefaultMaxBlobSize int64 `json:"default_max_blob_size"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalAttachmentSettings contains global Attachment settings exposed by API
|
||||||
|
type GlobalAttachmentSettings struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
AllowedTypes string `json:"allowed_types"`
|
||||||
|
MaxSize int64 `json:"max_size"`
|
||||||
|
MaxFiles int `json:"max_files"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGlobalUISettings get global ui settings witch are exposed by API
|
||||||
|
func (c *Client) GetGlobalUISettings() (*GlobalUISettings, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
conf := new(GlobalUISettings)
|
||||||
|
resp, err := c.getParsedResponse("GET", "/settings/ui", jsonHeader, nil, &conf)
|
||||||
|
return conf, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGlobalRepoSettings get global repository settings witch are exposed by API
|
||||||
|
func (c *Client) GetGlobalRepoSettings() (*GlobalRepoSettings, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
conf := new(GlobalRepoSettings)
|
||||||
|
resp, err := c.getParsedResponse("GET", "/settings/repository", jsonHeader, nil, &conf)
|
||||||
|
return conf, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGlobalAPISettings get global api settings witch are exposed by it
|
||||||
|
func (c *Client) GetGlobalAPISettings() (*GlobalAPISettings, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
conf := new(GlobalAPISettings)
|
||||||
|
resp, err := c.getParsedResponse("GET", "/settings/api", jsonHeader, nil, &conf)
|
||||||
|
return conf, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGlobalAttachmentSettings get global repository settings witch are exposed by API
|
||||||
|
func (c *Client) GetGlobalAttachmentSettings() (*GlobalAttachmentSettings, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
conf := new(GlobalAttachmentSettings)
|
||||||
|
resp, err := c.getParsedResponse("GET", "/settings/attachment", jsonHeader, nil, &conf)
|
||||||
|
return conf, resp, err
|
||||||
|
}
|
||||||
108
vendor/code.gitea.io/sdk/gitea/status.go
generated
vendored
Normal file
108
vendor/code.gitea.io/sdk/gitea/status.go
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gitea
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StatusState holds the state of a Status
|
||||||
|
// It can be "pending", "success", "error", "failure", and "warning"
|
||||||
|
type StatusState string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// StatusPending is for when the Status is Pending
|
||||||
|
StatusPending StatusState = "pending"
|
||||||
|
// StatusSuccess is for when the Status is Success
|
||||||
|
StatusSuccess StatusState = "success"
|
||||||
|
// StatusError is for when the Status is Error
|
||||||
|
StatusError StatusState = "error"
|
||||||
|
// StatusFailure is for when the Status is Failure
|
||||||
|
StatusFailure StatusState = "failure"
|
||||||
|
// StatusWarning is for when the Status is Warning
|
||||||
|
StatusWarning StatusState = "warning"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Status holds a single Status of a single Commit
|
||||||
|
type Status struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
State StatusState `json:"status"`
|
||||||
|
TargetURL string `json:"target_url"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Context string `json:"context"`
|
||||||
|
Creator *User `json:"creator"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
Updated time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateStatusOption holds the information needed to create a new Status for a Commit
|
||||||
|
type CreateStatusOption struct {
|
||||||
|
State StatusState `json:"state"`
|
||||||
|
TargetURL string `json:"target_url"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Context string `json:"context"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateStatus creates a new Status for a given Commit
|
||||||
|
func (c *Client) CreateStatus(owner, repo, sha string, opts CreateStatusOption) (*Status, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
status := new(Status)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/statuses/%s", owner, repo, url.QueryEscape(sha)), jsonHeader, bytes.NewReader(body), status)
|
||||||
|
return status, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListStatusesOption options for listing a repository's commit's statuses
|
||||||
|
type ListStatusesOption struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListStatuses returns all statuses for a given Commit by ref
|
||||||
|
func (c *Client) ListStatuses(owner, repo, ref string, opt ListStatusesOption) ([]*Status, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &ref); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
statuses := make([]*Status, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/statuses?%s", owner, repo, ref, opt.getURLQuery().Encode()), jsonHeader, nil, &statuses)
|
||||||
|
return statuses, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CombinedStatus holds the combined state of several statuses for a single commit
|
||||||
|
type CombinedStatus struct {
|
||||||
|
State StatusState `json:"state"`
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
TotalCount int `json:"total_count"`
|
||||||
|
Statuses []*Status `json:"statuses"`
|
||||||
|
Repository *Repository `json:"repository"`
|
||||||
|
CommitURL string `json:"commit_url"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCombinedStatus returns the CombinedStatus for a given Commit
|
||||||
|
func (c *Client) GetCombinedStatus(owner, repo, ref string) (*CombinedStatus, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo, &ref); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
status := new(CombinedStatus)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/status", owner, repo, ref), jsonHeader, nil, status)
|
||||||
|
|
||||||
|
// gitea api return empty body if nothing here jet
|
||||||
|
if resp != nil && resp.StatusCode == 200 && err != nil {
|
||||||
|
return status, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return status, resp, err
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user