Merge remote-tracking branch 'upstream/main'

This commit is contained in:
Anthony Wang 2022-10-18 18:25:01 +00:00
commit e78dd699de
No known key found for this signature in database
GPG Key ID: 42A5B952E6DD8D38
470 changed files with 13897 additions and 8766 deletions

View File

@ -100,7 +100,7 @@ steps:
- name: checks-backend - name: checks-backend
image: golang:1.19 image: golang:1.19
commands: commands:
- make checks-backend - make --always-make checks-backend # ensure the 'go-licenses' make target runs
depends_on: [deps-backend] depends_on: [deps-backend]
volumes: volumes:
- name: deps - name: deps
@ -112,16 +112,11 @@ steps:
- make test-frontend - make test-frontend
depends_on: [lint-frontend] depends_on: [lint-frontend]
- name: generate-frontend
image: golang:1.19
commands:
- make generate-frontend
- name: build-frontend - name: build-frontend
image: node:18 image: node:18
commands: commands:
- make frontend - make frontend
depends_on: [deps-frontend, generate-frontend] depends_on: [deps-frontend]
- name: build-backend-no-gcc - name: build-backend-no-gcc
image: golang:1.18 # this step is kept as the lowest version of golang that we support image: golang:1.18 # this step is kept as the lowest version of golang that we support
@ -549,16 +544,11 @@ steps:
commands: commands:
- make deps-frontend - make deps-frontend
- name: generate-frontend
image: golang:1.18
commands:
- make generate-frontend
- name: build-frontend - name: build-frontend
image: node:18 image: node:18
commands: commands:
- make frontend - make frontend
depends_on: [deps-frontend, generate-frontend] depends_on: [deps-frontend]
- name: deps-backend - name: deps-backend
image: golang:1.18 image: golang:1.18
@ -571,9 +561,9 @@ steps:
# TODO: We should probably build all dependencies into a test image # TODO: We should probably build all dependencies into a test image
- name: test-e2e - name: test-e2e
image: mcr.microsoft.com/playwright:v1.24.0-focal image: mcr.microsoft.com/playwright:v1.27.0-focal
commands: commands:
- curl -sLO https://go.dev/dl/go1.18.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz - curl -sLO https://go.dev/dl/go1.19.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
- groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea - groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea
- apt-get -qq update && apt-get -qqy install build-essential - apt-get -qq update && apt-get -qqy install build-essential
- export TEST_PGSQL_SCHEMA='' - export TEST_PGSQL_SCHEMA=''
@ -636,6 +626,8 @@ steps:
commit_message: "[skip ci] Updated translations via Crowdin" commit_message: "[skip ci] Updated translations via Crowdin"
remote: "git@github.com:go-gitea/gitea.git" remote: "git@github.com:go-gitea/gitea.git"
environment: environment:
DRONE_COMMIT_AUTHOR_EMAIL: "teabot@gitea.io"
DRONE_COMMIT_AUTHOR: GiteaBot
GIT_PUSH_SSH_KEY: GIT_PUSH_SSH_KEY:
from_secret: git_push_ssh_key from_secret: git_push_ssh_key
@ -680,12 +672,14 @@ steps:
pull: always pull: always
settings: settings:
author_email: "teabot@gitea.io" author_email: "teabot@gitea.io"
author_name: GiteaBot author_name: "GiteaBot"
branch: main branch: main
commit: true commit: true
commit_message: "[skip ci] Updated licenses and gitignores " commit_message: "[skip ci] Updated licenses and gitignores"
remote: "git@github.com:go-gitea/gitea.git" remote: "git@github.com:go-gitea/gitea.git"
environment: environment:
DRONE_COMMIT_AUTHOR_EMAIL: "teabot@gitea.io"
DRONE_COMMIT_AUTHOR: "GiteaBot"
GIT_PUSH_SSH_KEY: GIT_PUSH_SSH_KEY:
from_secret: git_push_ssh_key from_secret: git_push_ssh_key

View File

@ -185,6 +185,7 @@ rules:
linebreak-style: [2, unix] linebreak-style: [2, unix]
lines-around-comment: [0] lines-around-comment: [0]
lines-between-class-members: [0] lines-between-class-members: [0]
logical-assignment-operators: [0]
max-classes-per-file: [0] max-classes-per-file: [0]
max-depth: [0] max-depth: [0]
max-len: [0] max-len: [0]
@ -245,7 +246,7 @@ rules:
no-floating-decimal: [0] no-floating-decimal: [0]
no-func-assign: [2] no-func-assign: [2]
no-global-assign: [2] no-global-assign: [2]
no-implicit-coercion: [0] no-implicit-coercion: [2]
no-implicit-globals: [0] no-implicit-globals: [0]
no-implied-eval: [2] no-implied-eval: [2]
no-import-assign: [2] no-import-assign: [2]
@ -322,7 +323,7 @@ rules:
no-unused-private-class-members: [2] no-unused-private-class-members: [2]
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}] no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}] no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
no-useless-backreference: [0] no-useless-backreference: [2]
no-useless-call: [2] no-useless-call: [2]
no-useless-catch: [2] no-useless-catch: [2]
no-useless-computed-key: [2] no-useless-computed-key: [2]
@ -353,7 +354,7 @@ rules:
prefer-named-capture-group: [0] prefer-named-capture-group: [0]
prefer-numeric-literals: [2] prefer-numeric-literals: [2]
prefer-object-has-own: [0] prefer-object-has-own: [0]
prefer-object-spread: [0] prefer-object-spread: [2]
prefer-promise-reject-errors: [2, {allowEmptyReject: false}] prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
prefer-regex-literals: [2] prefer-regex-literals: [2]
prefer-rest-params: [2] prefer-rest-params: [2]
@ -455,6 +456,7 @@ rules:
unicorn/no-static-only-class: [2] unicorn/no-static-only-class: [2]
unicorn/no-thenable: [2] unicorn/no-thenable: [2]
unicorn/no-this-assignment: [2] unicorn/no-this-assignment: [2]
unicorn/no-unnecessary-await: [2]
unicorn/no-unreadable-array-destructuring: [0] unicorn/no-unreadable-array-destructuring: [0]
unicorn/no-unreadable-iife: [2] unicorn/no-unreadable-iife: [2]
unicorn/no-unsafe-regex: [0] unicorn/no-unsafe-regex: [0]
@ -519,6 +521,7 @@ rules:
unicorn/require-number-to-fixed-digits-argument: [2] unicorn/require-number-to-fixed-digits-argument: [2]
unicorn/require-post-message-target-origin: [0] unicorn/require-post-message-target-origin: [0]
unicorn/string-content: [0] unicorn/string-content: [0]
unicorn/switch-case-braces: [0]
unicorn/template-indent: [2] unicorn/template-indent: [2]
unicorn/text-encoding-identifier-case: [0] unicorn/text-encoding-identifier-case: [0]
unicorn/throw-new-error: [2] unicorn/throw-new-error: [2]

1
.gitattributes vendored
View File

@ -1,5 +1,6 @@
* text=auto eol=lf * text=auto eol=lf
*.tmpl linguist-language=Handlebars *.tmpl linguist-language=Handlebars
/assets/*.json linguist-generated
/public/vendor/** -text -eol linguist-vendored /public/vendor/** -text -eol linguist-vendored
/vendor/** -text -eol linguist-vendored /vendor/** -text -eol linguist-vendored
/web_src/fomantic/build/** linguist-generated /web_src/fomantic/build/** linguist-generated

40
.gitpod.yml Normal file
View File

@ -0,0 +1,40 @@
tasks:
- name: Setup
init: |
make deps
make build
command: |
gp sync-done setup
exit 0
- name: Run frontend
command: |
gp sync-await setup
make watch-frontend
- name: Run backend
command: |
gp sync-await setup
mkdir -p custom/conf/
echo -e "[server]\nROOT_URL=$(gp url 3000)/" > custom/conf/app.ini
echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini
export TAGS="sqlite sqlite_unlock_notify"
make watch-backend
- name: Run docs
before: sudo bash -c "$(grep 'https://github.com/gohugoio/hugo/releases/download' Makefile | tr -d '\')" # install hugo
command: cd docs && make clean update && hugo server -D -F --baseUrl $(gp url 1313) --liveReloadPort=443 --appendPort=false --bind=0.0.0.0
vscode:
extensions:
- editorconfig.editorconfig
- dbaeumer.vscode-eslint
- golang.go
- stylelint.vscode-stylelint
- DavidAnson.vscode-markdownlint
- johnsoncodehk.volar
- ms-azuretools.vscode-docker
- zixuanchen.vitest-explorer
ports:
- name: Gitea
port: 3000
- name: Docs
port: 1313

View File

@ -12,7 +12,6 @@ linters:
- dupl - dupl
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time. #- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
- gofmt - gofmt
- misspell
- gocritic - gocritic
- bidichk - bidichk
- ineffassign - ineffassign
@ -148,9 +147,6 @@ issues:
- path: models/issue_comment_list.go - path: models/issue_comment_list.go
linters: linters:
- dupl - dupl
- linters:
- misspell
text: '`Unknwon` is a misspelling of `Unknown`'
- path: models/update.go - path: models/update.go
linters: linters:
- unused - unused

View File

@ -4,6 +4,86 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.17.3](https://github.com/go-gitea/gitea/releases/tag/v1.17.3) - 2022-10-15
* SECURITY
* Sanitize and Escape refs in git backend (#21464) (#21463)
* Bump `golang.org/x/text` (#21412) (#21413)
* Update bluemonday (#21281) (#21287)
* ENHANCEMENTS
* Fix empty container layer history and UI (#21251) (#21278)
* Use en-US as fallback when using other default language (#21200) (#21256)
* Make the vscode clone link respect transport protocol (#20557) (#21128)
* BUGFIXES
* Do DB update after merge in hammer context (#21401) (#21416)
* Add Num{Issues,Pulls} stats checks (#21404) (#21414)
* Stop logging CheckPath returns error: context canceled (#21064) (#21405)
* Parse OAuth Authorization header when request omits client secret (#21351) (#21374)
* Ignore port for loopback redirect URIs (#21293) (#21373)
* Set SemverCompatible to false for Conan packages (#21275) (#21366)
* Tag list should include draft releases with existing tags (#21263) (#21365)
* Fix linked account translation (#21331) (#21334)
* Make NuGet service index publicly accessible (#21242) (#21277)
* Foreign ID conflicts if ID is 0 for each item (#21271) (#21272)
* Use absolute links in feeds (#21229) (#21265)
* Prevent invalid behavior for file reviewing when loading more files (#21230) (#21234)
* Respect `REQUIRE_SIGNIN_VIEW` for packages (#20873) (#21232)
* Treat git object mode 40755 as directory (#21195) (#21218)
* Allow uppercase ASCII alphabet in PyPI package names (#21095) (#21217)
* Fix limited user cannot view himself's profile (#21212)
* Fix template bug of admin monitor (#21209)
* Fix reaction of issues (#21185) (#21196)
* Fix CSV diff for added/deleted files (#21189) (#21193)
* Fix pagination limit parameter problem (#21111)
* TESTING
* Fix missing m.Run() in TestMain (#21341)
* BUILD
* Use Go 1.19 fmt for Gitea 1.17, sync emoji data (#21239)
## [1.17.2](https://github.com/go-gitea/gitea/releases/tag/v1.17.2) - 2022-09-06
* SECURITY
* Double check CloneURL is acceptable (#20869) (#20892)
* Add more checks in migration code (#21011) (#21050)
* ENHANCEMENTS
* Fix hard-coded timeout and error panic in API archive download endpoint (#20925) (#21051)
* Improve arc-green code theme (#21039) (#21042)
* Enable contenthash in filename for dynamic assets (#20813) (#20932)
* Don't open new page for ext wiki on same repository (#20725) (#20910)
* Disable doctor logging on panic (#20847) (#20898)
* Remove calls to load Mirrors in user.Dashboard (#20855) (#20897)
* Update codemirror to 5.65.8 (#20875)
* Rework repo buttons (#20602, #20718) (#20719)
* BUGFIXES
* Ensure delete user deletes all comments (#21067) (#21068)
* Delete unreferenced packages when deleting a package version (#20977) (#21060)
* Redirect if user does not exist on admin pages (#20981) (#21059)
* Set uploadpack.allowFilter etc on gitea serv to enable partial clones with ssh (#20902) (#21058)
* Fix 500 on time in timeline API (#21052) (#21057)
* Fill the specified ref in webhook test payload (#20961) (#21055)
* Add another index for Action table on postgres (#21033) (#21054)
* Fix broken insecureskipverify handling in redis connection uris (#20967) (#21053)
* Add Dev, Peer and Optional dependencies to npm PackageMetadataVersion (#21017) (#21044)
* Do not add links to Posters or Assignees with ID < 0 (#20577) (#21037)
* Fix modified due date message (#20388) (#21032)
* Fix missed sort bug (#21006)
* Fix input.value attr for RequiredClaimName/Value (#20946) (#21001)
* Change review buttons to icons to make space for text (#20934) (#20978)
* Fix download archiver of a commit (#20962) (#20971)
* Return 404 NotFound if requested attachment does not exist (#20886) (#20941)
* Set no-tags in git fetch on compare (#20893) (#20936)
* Allow multiple metadata files for Maven packages (#20674) (#20916)
* Increase Content field size of gpg_key and public_key to MEDIUMTEXT (#20896) (#20911)
* Fix mirror address setting not working (#20850) (#20904)
* Fix push mirror address backend get error Address cause setting page display error (#20593) (#20901)
* Fix panic when an invalid oauth2 name is passed (#20820) (#20900)
* In PushMirrorsIterate and MirrorsIterate if limit is negative do not set it (#20837) (#20899)
* Ensure that graceful start-up is informed of unused SSH listener (#20877) (#20888)
* Pad GPG Key ID with preceding zeroes (#20878) (#20885)
* Fix SQL Query for `SearchTeam` (#20844) (#20872)
* Fix the mode of custom dir to 0700 in docker-rootless (#20861) (#20867)
* Fix UI mis-align for PR commit history (#20845) (#20859)
## [1.17.1](https://github.com/go-gitea/gitea/releases/tag/1.17.1) - 2022-08-17 ## [1.17.1](https://github.com/go-gitea/gitea/releases/tag/1.17.1) - 2022-08-17
* SECURITY * SECURITY

View File

@ -146,6 +146,16 @@ If your PR could cause a breaking change you must add a BREAKING section to this
To explain how this could affect users and how to mitigate these changes. To explain how this could affect users and how to mitigate these changes.
Once code review starts on your PR, do not rebase nor squash your branch as it makes it
difficult to review the new changes. Only if there is a need, sync your branch by merging
the base branch into yours. Don't worry about merge commits messing up your tree as
the final merge process squashes all commits into one, with the visible commit message (first
line) being the PR title + PR index and description being the PR's first comment.
Once your PR gets the `lgtm/done` label, don't worry about keeping it up-to-date or breaking
builds (unless there's a merge conflict or a request is made by a maintainer to make
modifications). It is the maintainer team's responsibility from this point to get it merged.
## Styleguide ## Styleguide
For imports you should use the following format (*without* the comments) For imports you should use the following format (*without* the comments)
@ -170,17 +180,22 @@ import (
To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts: To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts:
- **integration:** Integration tests
- **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging). - **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
- **models/fixtures:** Sample model data used in integration tests. - **models/fixtures:** Sample model data used in integration tests.
- **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step. - **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step.
- **modules:** Different modules to handle specific functionality in Gitea. - **modules:** Different modules to handle specific functionality in Gitea. Shall only depend on other modules but not other packages (models, services).
- **public:** Frontend files (javascript, images, css, etc.) - **public:** Frontend files (javascript, images, css, etc.)
- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers - **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers.
- **services:** Support functions for common routing operations. Uses models and modules to handle the request. - **services:** Support functions for common routing operations. Uses models and modules to handle the request.
- **templates:** Golang templates for generating the html output. - **templates:** Golang templates for generating the html output.
- **tests/e2e:** End to end tests
- **tests/integration:** Integration tests
- **vendor:** External code that Gitea depends on. - **vendor:** External code that Gitea depends on.
## Documentation
If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated.
## API v1 ## API v1
The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [GitHub API v3](https://developer.github.com/v3/). The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [GitHub API v3](https://developer.github.com/v3/).
@ -229,27 +244,6 @@ An endpoint which changes/edits an object expects all fields to be optional (exc
- support pagination (`page` & `limit` options in query) - support pagination (`page` & `limit` options in query)
- set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444)) - set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
## Large Character Comments
Throughout the codebase there are large-text comments for sections of code, e.g.:
```go
// __________ .__
// \______ \ _______ _|__| ______ _ __
// | _// __ \ \/ / |/ __ \ \/ \/ /
// | | \ ___/\ /| \ ___/\ /
// |____|_ /\___ >\_/ |__|\___ >\/\_/
// \/ \/ \/
```
These were created using the `figlet` tool with the `graffiti` font.
A simple way of creating these is to use the following:
```bash
figlet -f graffiti Review | sed -e's+^+// +' - | xclip -sel clip -in
```
## Backports and Frontports ## Backports and Frontports
Occasionally backports of PRs are required. Occasionally backports of PRs are required.

View File

@ -130,6 +130,7 @@ TEST_TAGS ?= sqlite sqlite_unlock_notify
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR) TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR)
GO_DIRS := cmd tests models modules routers build services tools GO_DIRS := cmd tests models modules routers build services tools
WEB_DIRS := web_src/js web_src/less
GO_SOURCES := $(wildcard *.go) GO_SOURCES := $(wildcard *.go)
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go) GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go)
@ -263,11 +264,24 @@ clean:
.PHONY: fmt .PHONY: fmt
fmt: fmt:
@MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}' GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl')) $(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
@# strip whitespace after '{{' and before `}}` unless there is only whitespace before it @# strip whitespace after '{{' and before `}}` unless there is only whitespace before it
@$(SED_INPLACE) -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' $(TEMPLATES) @$(SED_INPLACE) -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' $(TEMPLATES)
.PHONY: fmt-check
fmt-check: fmt
@diff=$$(git diff $(GO_SOURCES) templates $(WEB_DIRS)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi
.PHONY: misspell-check
misspell-check:
go run $(MISSPELL_PACKAGE) -error $(GO_DIRS) $(WEB_DIRS)
.PHONY: vet .PHONY: vet
vet: vet:
@echo "Running go vet..." @echo "Running go vet..."
@ -311,22 +325,6 @@ errcheck:
@echo "Running errcheck..." @echo "Running errcheck..."
$(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES) $(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES)
.PHONY: fmt-check
fmt-check:
@# get all go files and run gitea-fmt (with gofmt) on them
@diff=$$(MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -l '{file-list}'); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi
@diff2=$$(git diff templates); \
if [ -n "$$diff2" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff2}"; \
exit 1; \
fi
.PHONY: checks .PHONY: checks
checks: checks-frontend checks-backend checks: checks-frontend checks-backend
@ -334,14 +332,14 @@ checks: checks-frontend checks-backend
checks-frontend: lockfile-check svg-check checks-frontend: lockfile-check svg-check
.PHONY: checks-backend .PHONY: checks-backend
checks-backend: tidy-check swagger-check swagger-validate checks-backend: tidy-check swagger-check fmt-check misspell-check swagger-validate
.PHONY: lint .PHONY: lint
lint: lint-frontend lint-backend lint: lint-frontend lint-backend
.PHONY: lint-frontend .PHONY: lint-frontend
lint-frontend: node_modules lint-frontend: node_modules
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e/*.test.e2e.js tests/e2e/utils_e2e.js npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e
npx stylelint --color --max-warnings=0 web_src/less npx stylelint --color --max-warnings=0 web_src/less
npx spectral lint -q -F hint $(SWAGGER_SPEC) npx spectral lint -q -F hint $(SWAGGER_SPEC)
npx markdownlint docs *.md npx markdownlint docs *.md
@ -372,7 +370,7 @@ test-backend:
.PHONY: test-frontend .PHONY: test-frontend
test-frontend: node_modules test-frontend: node_modules
@NODE_OPTIONS="--experimental-vm-modules --no-warnings" npx jest --color npx vitest
.PHONY: test-check .PHONY: test-check
test-check: test-check:
@ -406,6 +404,7 @@ unit-test-coverage:
tidy: tidy:
$(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2)) $(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2))
$(GO) mod tidy -compat=$(MIN_GO_VERSION) $(GO) mod tidy -compat=$(MIN_GO_VERSION)
@$(MAKE) --no-print-directory $(GO_LICENSE_FILE)
vendor: go.mod go.sum vendor: go.mod go.sum
$(GO) mod vendor $(GO) mod vendor
@ -413,7 +412,7 @@ vendor: go.mod go.sum
.PHONY: tidy-check .PHONY: tidy-check
tidy-check: tidy tidy-check: tidy
@diff=$$(git diff go.mod go.sum); \ @diff=$$(git diff go.mod go.sum $(GO_LICENSE_FILE)); \
if [ -n "$$diff" ]; then \ if [ -n "$$diff" ]; then \
echo "Please run 'make tidy' and commit the result:"; \ echo "Please run 'make tidy' and commit the result:"; \
echo "$${diff}"; \ echo "$${diff}"; \
@ -709,17 +708,14 @@ install: $(wildcard *.go)
build: frontend backend build: frontend backend
.PHONY: frontend .PHONY: frontend
frontend: generate-frontend $(WEBPACK_DEST) frontend: $(WEBPACK_DEST)
.PHONY: backend .PHONY: backend
backend: go-check generate-backend $(EXECUTABLE) backend: go-check generate-backend $(EXECUTABLE)
# We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend # We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend
.PHONY: generate .PHONY: generate
generate: generate-backend generate-frontend generate: generate-backend
.PHONY: generate-frontend
generate-frontend: $(GO_LICENSE_FILE)
.PHONY: generate-backend .PHONY: generate-backend
generate-backend: $(TAGS_PREREQ) generate-go generate-backend: $(TAGS_PREREQ) generate-go

View File

@ -33,6 +33,12 @@
<a href="https://opensource.org/licenses/MIT" title="License: MIT"> <a href="https://opensource.org/licenses/MIT" title="License: MIT">
<img src="https://img.shields.io/badge/License-MIT-blue.svg"> <img src="https://img.shields.io/badge/License-MIT-blue.svg">
</a> </a>
<a href="https://gitpod.io/#https://github.com/go-gitea/gitea">
<img
src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod"
alt="Contribute with Gitpod"
/>
</a>
<a href="https://crowdin.com/project/gitea" title="Crowdin"> <a href="https://crowdin.com/project/gitea" title="Crowdin">
<img src="https://badges.crowdin.net/gitea/localized.svg"> <img src="https://badges.crowdin.net/gitea/localized.svg">
</a> </a>
@ -145,6 +151,7 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
<a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
<a href="https://cynkra.com/" target="_blank"><img src="https://images.opencollective.com/cynkra/logo/square/64/192.png"></a>
## FAQ ## FAQ

View File

@ -33,6 +33,12 @@
<a href="https://opensource.org/licenses/MIT" title="License: MIT"> <a href="https://opensource.org/licenses/MIT" title="License: MIT">
<img src="https://img.shields.io/badge/License-MIT-blue.svg"> <img src="https://img.shields.io/badge/License-MIT-blue.svg">
</a> </a>
<a href="https://gitpod.io/#https://github.com/go-gitea/gitea">
<img
src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod"
alt="Contribute with Gitpod"
/>
</a>
<a href="https://crowdin.com/project/gitea" title="Crowdin"> <a href="https://crowdin.com/project/gitea" title="Crowdin">
<img src="https://badges.crowdin.net/gitea/localized.svg"> <img src="https://badges.crowdin.net/gitea/localized.svg">
</a> </a>

File diff suppressed because one or more lines are too long

View File

@ -20,7 +20,7 @@ import (
) )
// Windows has a limitation for command line arguments, the size can not exceed 32KB. // Windows has a limitation for command line arguments, the size can not exceed 32KB.
// So we have to feed the files to some tools (like gofmt/misspell) batch by batch // So we have to feed the files to some tools (like gofmt) batch by batch
// We also introduce a `gitea-fmt` command, it does better import formatting than gofmt/goimports. `gitea-fmt` calls `gofmt` internally. // We also introduce a `gitea-fmt` command, it does better import formatting than gofmt/goimports. `gitea-fmt` calls `gofmt` internally.
@ -195,7 +195,6 @@ Options:
Commands: Commands:
%[1]s gofmt ... %[1]s gofmt ...
%[1]s misspell ...
Arguments: Arguments:
{file-list} the file list {file-list} the file list
@ -206,6 +205,17 @@ Example:
`, "file-batch-exec") `, "file-batch-exec")
} }
func getGoVersion() string {
goModFile, err := os.ReadFile("go.mod")
if err != nil {
log.Fatalf(`Faild to read "go.mod": %v`, err)
os.Exit(1)
}
goModVersionRegex := regexp.MustCompile(`go \d+\.\d+`)
goModVersionLine := goModVersionRegex.Find(goModFile)
return string(goModVersionLine[3:])
}
func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) { func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) {
fileFilter := mainOptions["file-filter"] fileFilter := mainOptions["file-filter"]
if fileFilter == "" { if fileFilter == "" {
@ -228,9 +238,9 @@ func containsString(a []string, s string) bool {
return false return false
} }
func giteaFormatGoImports(files []string, hasChangedFiles, doWriteFile bool) error { func giteaFormatGoImports(files []string, doWriteFile bool) error {
for _, file := range files { for _, file := range files {
if err := codeformat.FormatGoImports(file, hasChangedFiles, doWriteFile); err != nil { if err := codeformat.FormatGoImports(file, doWriteFile); err != nil {
log.Printf("failed to format go imports: %s, err=%v", file, err) log.Printf("failed to format go imports: %s, err=%v", file, err)
return err return err
} }
@ -269,10 +279,8 @@ func main() {
if containsString(subArgs, "-d") { if containsString(subArgs, "-d") {
log.Print("the -d option is not supported by gitea-fmt") log.Print("the -d option is not supported by gitea-fmt")
} }
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-l"), containsString(subArgs, "-w"))) cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-w")))
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", "1.17"}, substArgs...))) cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", getGoVersion()}, substArgs...)))
case "misspell":
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("MISSPELL_PACKAGE")}, substArgs...)))
default: default:
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs) log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
} }

View File

@ -7,7 +7,6 @@ package codeformat
import ( import (
"bytes" "bytes"
"errors" "errors"
"fmt"
"io" "io"
"os" "os"
"sort" "sort"
@ -159,7 +158,7 @@ func formatGoImports(contentBytes []byte) ([]byte, error) {
} }
// FormatGoImports format the imports by our rules (see unit tests) // FormatGoImports format the imports by our rules (see unit tests)
func FormatGoImports(file string, doChangedFiles, doWriteFile bool) error { func FormatGoImports(file string, doWriteFile bool) error {
f, err := os.Open(file) f, err := os.Open(file)
if err != nil { if err != nil {
return err return err
@ -183,10 +182,6 @@ func FormatGoImports(file string, doChangedFiles, doWriteFile bool) error {
return nil return nil
} }
if doChangedFiles {
fmt.Println(file)
}
if doWriteFile { if doWriteFile {
f, err = os.OpenFile(file, os.O_TRUNC|os.O_WRONLY, 0o644) f, err = os.OpenFile(file, os.O_TRUNC|os.O_WRONLY, 0o644)
if err != nil { if err != nil {

View File

@ -203,7 +203,7 @@ func setPort(port string) error {
defaultLocalURL += ":" + setting.HTTPPort + "/" defaultLocalURL += ":" + setting.HTTPPort + "/"
// Save LOCAL_ROOT_URL if port changed // Save LOCAL_ROOT_URL if port changed
setting.CreateOrAppendToCustomConf(func(cfg *ini.File) { setting.CreateOrAppendToCustomConf("server.LOCAL_ROOT_URL", func(cfg *ini.File) {
cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL) cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
}) })
} }

View File

@ -2,14 +2,43 @@
DIR=/var/lib/gitea DIR=/var/lib/gitea
USER=git USER=git
HOME=/home/${USER}
GITEA_WORK_DIR=${DIR}
EXECUTABLE=/usr/local/bin/gitea
export USER
export HOME
export GITEA_WORK_DIR
name=$RC_SVCNAME
cfgfile="/etc/$RC_SVCNAME/app.ini"
command="${EXECUTABLE}"
command_user="${USER}"
command_args="web -c /etc/$RC_SVCNAME/app.ini"
command_background="yes"
pidfile="/run/$RC_SVCNAME/$RC_SVCNAME.pid"
start_stop_daemon_args="--user ${USER} --chdir ${DIR}" start_stop_daemon_args="--user ${USER} --chdir ${DIR}"
command="/usr/local/bin/gitea"
command_args="web -c /etc/gitea/app.ini"
command_background=yes
pidfile=/run/gitea.pid
depend() depend()
{ {
need net need net
###
# Don't forget to add the database service requirements
###
#after postgresql
#after mysql
#after mariadb
#after memcached
#after redis
}
start_pre()
{
checkpath --directory --owner $command_user:$command_user --mode 0750 \
/run/$RC_SVCNAME /var/log/$RC_SVCNAME
##
# If you want to bind Gitea to a port below 1024, uncomment
# the value below
##
#setcap cap_net_bind_service=+ep "${EXECUTABLE}"
} }

View File

@ -14,7 +14,6 @@ import (
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"net/url"
"os" "os"
"os/exec" "os/exec"
"os/user" "os/user"
@ -62,11 +61,7 @@ func runPR() {
} }
setting.AppWorkPath = curDir setting.AppWorkPath = curDir
setting.StaticRootPath = curDir setting.StaticRootPath = curDir
setting.GravatarSourceURL, err = url.Parse("https://secure.gravatar.com/avatar/") setting.GravatarSource = "https://secure.gravatar.com/avatar/"
if err != nil {
log.Fatalf("url.Parse: %v\n", err)
}
setting.AppURL = "http://localhost:8080/" setting.AppURL = "http://localhost:8080/"
setting.HTTPPort = "8080" setting.HTTPPort = "8080"
setting.SSH.Domain = "localhost" setting.SSH.Domain = "localhost"

View File

@ -49,12 +49,8 @@ After=network.target
### ###
[Service] [Service]
# Modify these two values and uncomment them if you have # Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that
# repos with lots of files and get an HTTP error 500 because # LimitNOFILE=524288:524288
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
RestartSec=2s RestartSec=2s
Type=simple Type=simple
User=git User=git

View File

@ -379,14 +379,19 @@ LOG_SQL = false ; if unset defaults to true
;; Whether the installer is disabled (set to true to disable the installer) ;; Whether the installer is disabled (set to true to disable the installer)
INSTALL_LOCK = false INSTALL_LOCK = false
;; ;;
;; Global secret key that will be used - if blank will be regenerated. ;; Global secret key that will be used
;; This key is VERY IMPORTANT. If you lose it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
SECRET_KEY = SECRET_KEY =
;; ;;
;; Alternative location to specify secret key, instead of this file; you cannot specify both this and SECRET_KEY, and must pick one
;; This key is VERY IMPORTANT. If you lose it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
;SECRET_KEY_URI = file:/etc/gitea/secret_key
;;
;; Secret used to validate communication within Gitea binary. ;; Secret used to validate communication within Gitea binary.
INTERNAL_TOKEN= INTERNAL_TOKEN=
;; ;;
;; Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: file:/etc/gitea/internal_token) ;; Alternative location to specify internal token, instead of this file; you cannot specify both this and INTERNAL_TOKEN, and must pick one
;INTERNAL_TOKEN_URI = ;e.g. /etc/gitea/internal_token ;INTERNAL_TOKEN_URI = file:/etc/gitea/internal_token
;; ;;
;; How long to remember that a user is logged in before requiring relogin (in days) ;; How long to remember that a user is logged in before requiring relogin (in days)
;LOGIN_REMEMBER_DAYS = 7 ;LOGIN_REMEMBER_DAYS = 7
@ -882,7 +887,7 @@ ROUTER = console
;USE_COMPAT_SSH_URI = false ;USE_COMPAT_SSH_URI = false
;; ;;
;; Close issues as long as a commit on any branch marks it as fixed ;; Close issues as long as a commit on any branch marks it as fixed
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki ;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects
;DISABLED_REPO_UNITS = ;DISABLED_REPO_UNITS =
;; ;;
;; Comma separated list of default repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects. ;; Comma separated list of default repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects.

View File

@ -18,7 +18,7 @@ params:
description: Git with a cup of tea description: Git with a cup of tea
author: The Gitea Authors author: The Gitea Authors
website: https://docs.gitea.io website: https://docs.gitea.io
version: 1.17.1 version: 1.17.3
minGoVersion: 1.18 minGoVersion: 1.18
goVersion: 1.19 goVersion: 1.19
minNodeVersion: 14 minNodeVersion: 14

View File

@ -494,7 +494,8 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
## Security (`security`) ## Security (`security`)
- `INSTALL_LOCK`: **false**: Controls access to the installation page. When set to "true", the installation page is not accessible. - `INSTALL_LOCK`: **false**: Controls access to the installation page. When set to "true", the installation page is not accessible.
- `SECRET_KEY`: **\<random at every install\>**: Global secret key. This should be changed. - `SECRET_KEY`: **\<random at every install\>**: Global secret key. This key is VERY IMPORTANT, if you lost it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
- `SECRET_KEY_URI`: **<empty>**: Instead of defining SECRET_KEY, this option can be used to use the key stored in a file (example value: `file:/etc/gitea/secret_key`). It shouldn't be lost like SECRET_KEY.
- `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days. - `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days.
- `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username. - `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username.
- `COOKIE_REMEMBER_NAME`: **gitea\_incredible**: Name of cookie used to store authentication - `COOKIE_REMEMBER_NAME`: **gitea\_incredible**: Name of cookie used to store authentication
@ -520,7 +521,7 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to Gitea repositories you should set the environment appropriately. - `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to Gitea repositories you should set the environment appropriately.
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server. - `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary. - `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`) - `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining INTERNAL_TOKEN in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
- `PASSWORD_HASH_ALGO`: **pbkdf2**: The hash algorithm to use \[argon2, pbkdf2, scrypt, bcrypt\], argon2 will spend more memory than others. - `PASSWORD_HASH_ALGO`: **pbkdf2**: The hash algorithm to use \[argon2, pbkdf2, scrypt, bcrypt\], argon2 will spend more memory than others.
- `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie. - `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie.
- `MIN_PASSWORD_LENGTH`: **6**: Minimum password length for new users. - `MIN_PASSWORD_LENGTH`: **6**: Minimum password length for new users.
@ -536,9 +537,9 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
## Camo (`camo`) ## Camo (`camo`)
- `ENABLED`: **false**: Enable media proxy, we support images only at the moment. - `ENABLED`: **false**: Enable media proxy, we support images only at the moment.
- `SERVER_URL`: **<empty>**: url of camo server, it **is required** if camo is enabled. - `SERVER_URL`: **<empty>**: URL of camo server, it **is required** if camo is enabled.
- `HMAC_KEY`: **<empty>**: Provide the HMAC key for encoding urls, it **is required** if camo is enabled. - `HMAC_KEY`: **<empty>**: Provide the HMAC key for encoding URLs, it **is required** if camo is enabled.
- `ALLWAYS`: **false**: Set to true to use camo for https too lese only non https urls are proxyed - `ALLWAYS`: **false**: Set to true to use camo for both HTTP and HTTPS content, otherwise only non-HTTPS URLs are proxied
## OpenID (`openid`) ## OpenID (`openid`)
@ -852,7 +853,7 @@ Default templates for project boards:
- `SCHEDULE` accept formats - `SCHEDULE` accept formats
- Full crontab specs, e.g. `* * * * * ?` - Full crontab specs, e.g. `* * * * * ?`
- Descriptors, e.g. `@midnight`, `@every 1h30m` ... - Descriptors, e.g. `@midnight`, `@every 1h30m` ...
- See more: [cron decument](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14) - See more: [cron documentation](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14)
### Basic cron tasks - enabled by default ### Basic cron tasks - enabled by default

View File

@ -67,22 +67,18 @@ Some actions should allow for rollback when database record insertion/update/del
So services must be allowed to create a database transaction. Here is some example, So services must be allowed to create a database transaction. Here is some example,
```go ```go
// servcies/repository/repo.go // services/repository/repository.go
func CreateXXXX() error {\ func CreateXXXX() error {
ctx, committer, err := db.TxContext() return db.WithTx(func(ctx context.Context) error {
if err != nil { e := db.GetEngine(ctx)
return err // do something, if err is returned, it will rollback automatically
} if err := issues.UpdateIssue(ctx, repoID); err != nil {
defer committer.Close() // ...
return err
// do something, if return err, it will rollback automatically when `committer.Close()` is invoked. }
if err := issues.UpdateIssue(ctx, repoID); err != nil { // ...
// ... return nil
} })
// ......
return committer.Commit()
} }
``` ```
@ -94,14 +90,14 @@ If the function will be used in the transaction, just let `context.Context` as t
func UpdateIssue(ctx context.Context, repoID int64) error { func UpdateIssue(ctx context.Context, repoID int64) error {
e := db.GetEngine(ctx) e := db.GetEngine(ctx)
// ...... // ...
} }
``` ```
### Package Name ### Package Name
For the top level package, use a plural as package name, i.e. `services`, `models`, for sub packages, use singular, For the top level package, use a plural as package name, i.e. `services`, `models`, for sub packages, use singular,
i.e. `servcies/user`, `models/repository`. i.e. `services/user`, `models/repository`.
### Import Alias ### Import Alias

View File

@ -21,7 +21,7 @@ menu:
## Background ## Background
Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue2](https://vuejs.org/v2/guide/) for its frontend. Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue3](https://vuejs.org/) for its frontend.
The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template). The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template).
@ -44,7 +44,7 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h
4. jQuery events across different features could use their own namespaces if there are potential conflicts. 4. jQuery events across different features could use their own namespaces if there are potential conflicts.
5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names with 2-3 feature related keywords to overwrite framework styles. 5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names with 2-3 feature related keywords to overwrite framework styles.
6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}` 6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}`
7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future). 7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue3.
### Framework Usage ### Framework Usage
@ -97,6 +97,6 @@ However, there are still some special cases, so the current guideline is:
A lot of legacy code already existed before this document's written. It's recommended to refactor legacy code to follow the guidelines. A lot of legacy code already existed before this document's written. It's recommended to refactor legacy code to follow the guidelines.
### Vue2/Vue3 and JSX ### Vue3 and JSX
Gitea is using Vue2 now, we plan to upgrade to Vue3. We decided not to introduce JSX to keep the HTML and the JavaScript code separated. Gitea is using Vue3 now. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.

View File

@ -19,6 +19,12 @@ menu:
{{< toc >}} {{< toc >}}
## Quickstart
To get a quick working development environment you could use Gitpod.
[![Open in Gitpod](/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/go-gitea/gitea)
## Installing go ## Installing go
You should [install go](https://golang.org/doc/install) and set up your go You should [install go](https://golang.org/doc/install) and set up your go
@ -171,7 +177,7 @@ server as mentioned above.
### Working on JS and CSS ### Working on JS and CSS
Frontend development should follow [Guidelines for Frontend Development](./guidelines-frontend.md) Frontend development should follow [Guidelines for Frontend Development]({{< relref "doc/developers/guidelines-frontend.en-us.md" >}})
To build with frontend resources, either use the `watch-frontend` target mentioned above or just build once: To build with frontend resources, either use the `watch-frontend` target mentioned above or just build once:

View File

@ -21,7 +21,7 @@ menu:
To help decide if Gitea is suited for your needs, here is how it compares to other Git self hosted options. To help decide if Gitea is suited for your needs, here is how it compares to other Git self hosted options.
Be warned that we don't regularly check for feature changes in other products, so this list may be outdated. If you find anything that needs to be updated in the table below, please report it in an [issue on GitHub](https://github.com/go-gitea/gitea/issues). Be warned that we don't regularly check for feature changes in other products, so this list may be outdated. If you find anything that needs to be updated in the table below, please [open an issue](https://github.com/go-gitea/gitea/issues/new/choose).
_Symbols used in table:_ _Symbols used in table:_
@ -33,103 +33,111 @@ _Symbols used in table:_
## General Features ## General Features
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE | | Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
| ----------------------------------- | ---------------------------------------------------| ---- | --------- | --------- | --------- | -------------- | ------------ | | ------------------------------------------------ | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
| Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | | Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
| Low resource usage (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | | Low RAM/ CPU usage | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
| Multiple database support | ✓ | ✓ | ✘ | | | ✓ | ✓ | | Multiple database support | ✓ | ✓ | ✘ | | | ✓ | ✓ |
| Multiple OS support | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | | Multiple OS support | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ |
| Easy upgrade process | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ | | Easy upgrades | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Telemetry | **✘** | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
| Orgmode support | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? | | Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? | | WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? | | Extensive API | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Static Git-powered pages | [](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Built-in Package/Container Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ | | Sync commits to an external repo (push mirror) | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Sync commits from an external repo (pull mirror) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ? |
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Light and Dark Theme | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ? |
| Built-in Package/Container Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Custom Theme Support | ✓ | ✓ | ✘ | ✘ | ✘ | ✓ | ✘ |
| External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? | | CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
| Built-in CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | 'GitHub / GitLab pages' | [](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Subgroups: groups within groups | [](https://github.com/go-gitea/gitea/issues/1872) | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ | | Repo-specific wiki (as a repo itself) | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
| Mermaid diagrams in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Math syntax in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| RSS Feeds | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ✘ |
| Built-in CI/CD | [](https://github.com/go-gitea/gitea/issues/13539) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Subgroups: groups within groups | [](https://github.com/go-gitea/gitea/issues/1872) | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
| Interaction with other instances | [/](https://github.com/go-gitea/gitea/issues/18240) | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
| Mermaid diagrams in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Math syntax in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
## Code management ## Code management
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE | | Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
| -------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ | | ------------------------------------------- | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ | | Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Group Milestones | [](https://github.com/go-gitea/gitea/issues/14622) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Granular user roles (Code, Issues, Wiki, …) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Verified Committer | | ✘ | ? | ✓ | ✓ | ✓ | ✘ | | Verified Committer | | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| SSH Signed Commits | ✓ | ✘ | ✘ | ✘ | ✘ | ? | ? | | SSH Signed Commits | ✓ | ✘ | ✓ | ✘ | ✘ | ? | ? |
| Reject unsigned commits | [](https://github.com/go-gitea/gitea/pull/9708) | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Reject unsigned commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Migrating repos from other services | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Web code editor | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Commit graph | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Web code editor | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Template Repositories | [](https://github.com/go-gitea/gitea/pull/8768) | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ | | Commit graph | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Template Repositories | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
| Git Blame | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Visual comparison of image changes | ✓ | ✘ | ✓ | ? | ? | ? | ? |
## Issue Tracker ## Issue Tracker
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE | | Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
| ------------------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | ----------------------------------------------------------------------- | --------- | -------------- | ------------ | | ----------------------------- | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ | | Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | | Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | | Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Multiple assignees for issues | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ | | Multiple assignees for issues | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
| Related issues | ✘ | ✘ | | [](https://docs.gitlab.com/ce/user/project/issues/related_issues.html) | ✓ | ✘ | ✘ | | Related issues | ✘ | ✘ | | ✓ | ✓ | ✘ | ✘ |
| Confidential issues | [](https://github.com/go-gitea/gitea/issues/3217) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Confidential issues | [](https://github.com/go-gitea/gitea/issues/3217) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Lock Discussion | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Lock Discussion | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Issue Boards (Kanban) | [](https://github.com/go-gitea/gitea/pull/8346) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Issue Boards (Kanban) | [/](https://github.com/go-gitea/gitea/issues/14710) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Create new branches from issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | Create branch from issue | [](https://github.com/go-gitea/gitea/issues/20226) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Convert comment to new issue | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Global issue search | [](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | | Global issue search | [/](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Create issue via email | [](https://github.com/go-gitea/gitea/issues/6226) | [](https://github.com/gogs/gogs/issues/2602) | ✘ | ✘ | ✓ | ✓ | ✘ | | Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
| Service Desk | [](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | [](https://gitlab.com/groups/gitlab-org/-/epics/3103) | ✓ | ✘ | ✘ | | Create issue via email | [](https://github.com/go-gitea/gitea/issues/6226) | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ |
| Service Desk | [](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
## Pull/Merge requests ## Pull/Merge requests
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE | | Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
| ----------------------------------------------- | -------------------------------------------------- | ---- | --------- | --------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------ | ------------ | | ----------------------------------------------- | -------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Squash merging | ✓ | ✘ | ✓ | [](https://docs.gitlab.com/ce/user/project/merge_requests/squash_and_merge.html) | ✓ | ✓ | ✓ | | Squash merging | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Rebase merging | ✓ | ✓ | ✓ | ✘ | | ✘ | ✓ | | Rebase merging | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Pull/Merge request approval | ✓ | ✘ | | ✓ | ✓ | ✓ | ✓ | | Pull/Merge request approval | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Merge conflict resolution | [](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Merge conflict resolution | [](https://github.com/go-gitea/gitea/issues/9014) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | | ✓ | ✓ | ✓ | | Restrict push and merge access to certain users | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Revert specific commits or a merge request | [](https://github.com/go-gitea/gitea/issues/5158) | | ✓ | ✓ | ✓ | ✓ | ✘ | | Revert specific commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | | Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
| Cherry-picking changes | [](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✘ | | ✓ | ✘ | ✘ | | Cherry-picking changes | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | [/](https://jira.atlassian.com/plugins/servlet/mobile#issue/BCLOUD-8323) | ✘ | | Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | / | ✘ |
## 3rd-party integrations ## 3rd-party integrations
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE | | Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
| ---------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ | | ---------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
| Webhook support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Webhooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Custom Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
| LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | | LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| SAML 2.0 service provider | [](https://github.com/go-gitea/gitea/issues/5512) | [](https://github.com/gogs/gogs/issues/1221) | ✓ | ✓ | ✓ | ✓ | ✘ | | SAML 2.0 service provider | [](https://github.com/go-gitea/gitea/issues/5512) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| OpenId Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ | | OpenID Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
| OAuth 2.0 integration (external authorization) | ✓ | ✘ | | ✓ | ✓ | ? | ✓ | | OAuth 2.0 integration (external authorization) | ✓ | ✘ | | ✓ | ✓ | ? | ✓ |
| Act as OAuth 2.0 provider | [](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | Act as OAuth 2.0 provider | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | | Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
| Mattermost/Slack integration | ✓ | ✓ | | ✓ | ✓ | | ✓ | | Integration with the most common services | ✓ | / | | ✓ | ✓ | | ✓ |
| Discord integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | | Incorporate external CI/CD | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Microsoft Teams integration | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| External CI/CD status display | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |

View File

@ -214,13 +214,13 @@ Our translations are currently crowd-sourced on our [Crowdin project](https://cr
Whether you want to change a translation or add a new one, it will need to be there as all translations are overwritten in our CI via the Crowdin integration. Whether you want to change a translation or add a new one, it will need to be there as all translations are overwritten in our CI via the Crowdin integration.
## Hooks aren't running ## Push Hook / Webhook aren't running
If Gitea is not running hooks, a common cause is incorrect setup of SSH keys. If you can push but can't see push activities on the home dashboard, or the push doesn't trigger webhook, there are a few possibilities:
See [SSH Issues](#ssh-issues) for more information. 1. The git hooks are out of sync: run "Resynchronize pre-receive, update and post-receive hooks of all repositories" on the site admin panel
2. The git repositories (and hooks) are stored on some filesystems (ex: mounted by NAS) which don't support script execution, make sure the filesystem supports `chmod a+x any-script`
You can also try logging into the administration panel and running the `Resynchronize pre-receive, update and post-receive hooks of all repositories.` option. 3. If you are using docker, make sure Docker Server (not the client) >= 20.10.6
## SSH issues ## SSH issues

View File

@ -97,12 +97,12 @@ chown root:git /etc/gitea
chmod 770 /etc/gitea chmod 770 /etc/gitea
``` ```
**NOTE:** `/etc/gitea` is temporarily set with write permissions for user `git` so that the web installer can write the configuration file. After the installation is finished, it is recommended to set permissions to read-only using: > **NOTE:** `/etc/gitea` is temporarily set with write permissions for user `git` so that the web installer can write the configuration file. After the installation is finished, it is recommended to set permissions to read-only using:
>
```sh > ```sh
chmod 750 /etc/gitea > chmod 750 /etc/gitea
chmod 640 /etc/gitea/app.ini > chmod 640 /etc/gitea/app.ini
``` > ```
If you don't want the web installer to be able to write to the config file, it is possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`) however you will need to edit your config file manually to: If you don't want the web installer to be able to write to the config file, it is possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`) however you will need to edit your config file manually to:

View File

@ -127,6 +127,10 @@ npm dist-tag add test_package@1.0.2 release
The tag name must not be a valid version. All tag names which are parsable as a version are rejected. The tag name must not be a valid version. All tag names which are parsable as a version are rejected.
## Search packages
The registry supports [searching](https://docs.npmjs.com/cli/v7/commands/npm-search/) but does not support special search qualifiers like `author:gitea`.
## Supported commands ## Supported commands
``` ```
@ -136,4 +140,5 @@ npm publish
npm unpublish npm unpublish
npm dist-tag npm dist-tag
npm view npm view
npm search
``` ```

View File

@ -14,7 +14,7 @@ menu:
# NuGet Packages Repository # NuGet Packages Repository
Publish [NuGet](https://www.nuget.org/) packages for your user or organization. The package registry supports [NuGet Symbol Packages](https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg) too. Publish [NuGet](https://www.nuget.org/) packages for your user or organization. The package registry supports the V2 and V3 API protocol and you can work with [NuGet Symbol Packages](https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg) too.
**Table of Contents** **Table of Contents**

View File

@ -1,6 +1,8 @@
--- ---
date: "2021-09-02T16:00:00+08:00" date: "2021-09-02T16:00:00+08:00"
title: "Upgrade from an old Gitea" title: "Upgrade from an old Gitea"
aliases:
- /en-us/upgrade/
slug: "upgrade-from-gitea" slug: "upgrade-from-gitea"
weight: 10 weight: 10
toc: false toc: false

View File

@ -13,6 +13,12 @@ menu:
identifier: "reverse-proxies" identifier: "reverse-proxies"
--- ---
# 反向代理
**目录**
{{< toc >}}
## 使用 Nginx 作为反向代理服务 ## 使用 Nginx 作为反向代理服务
如果您想使用 Nginx 作为 Gitea 的反向代理服务,您可以参照以下 `nginx.conf` 配置中 `server``http` 部分: 如果您想使用 Nginx 作为 Gitea 的反向代理服务,您可以参照以下 `nginx.conf` 配置中 `server``http` 部分:
@ -24,6 +30,10 @@ server {
location / { location / {
proxy_pass http://localhost:3000; proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
} }
} }
``` ```
@ -41,6 +51,10 @@ server {
location /git/ { location /git/ {
# 注意: 反向代理后端 URL 的最后需要有一个路径符号 # 注意: 反向代理后端 URL 的最后需要有一个路径符号
proxy_pass http://localhost:3000/; proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
} }
} }
``` ```

View File

@ -287,7 +287,7 @@ You can try it out using [the online demo](https://try.gitea.io/).
- UI frameworks: - UI frameworks:
- [jQuery](https://jquery.com) - [jQuery](https://jquery.com)
- [Fomantic UI](https://fomantic-ui.com) - [Fomantic UI](https://fomantic-ui.com)
- [Vue2](https://vuejs.org) - [Vue3](https://vuejs.org)
- and various components (see package.json) - and various components (see package.json)
- Editors: - Editors:
- [CodeMirror](https://codemirror.net) - [CodeMirror](https://codemirror.net)

View File

@ -258,7 +258,7 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide
- Interface graphique : - Interface graphique :
- [jQuery](https://jquery.com) - [jQuery](https://jquery.com)
- [Fomantic UI](https://fomantic-ui.com) - [Fomantic UI](https://fomantic-ui.com)
- [Vue2](https://vuejs.org) - [Vue3](https://vuejs.org)
- [CodeMirror](https://codemirror.net) - [CodeMirror](https://codemirror.net)
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) - [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
- [Monaco Editor](https://microsoft.github.io/monaco-editor) - [Monaco Editor](https://microsoft.github.io/monaco-editor)

View File

@ -52,7 +52,7 @@ Gitea的首要目标是创建一个极易安装运行非常快速安装和
- UI 框架: - UI 框架:
- [jQuery](https://jquery.com) - [jQuery](https://jquery.com)
- [Fomantic UI](https://fomantic-ui.com) - [Fomantic UI](https://fomantic-ui.com)
- [Vue2](https://vuejs.org) - [Vue3](https://vuejs.org)
- 更多组件参见 package.json - 更多组件参见 package.json
- 编辑器: - 编辑器:
- [CodeMirror](https://codemirror.net) - [CodeMirror](https://codemirror.net)

View File

@ -271,7 +271,7 @@ Gitea 是從 [Gogs](http://gogs.io) Fork 出來的,請閱讀部落格文章 [G
- UI 元件: - UI 元件:
- [jQuery](https://jquery.com) - [jQuery](https://jquery.com)
- [Fomantic UI](https://fomantic-ui.com) - [Fomantic UI](https://fomantic-ui.com)
- [Vue2](https://vuejs.org) - [Vue3](https://vuejs.org)
- [CodeMirror](https://codemirror.net) - [CodeMirror](https://codemirror.net)
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) - [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
- [Monaco Editor](https://microsoft.github.io/monaco-editor) - [Monaco Editor](https://microsoft.github.io/monaco-editor)

View File

@ -10,3 +10,7 @@ https://gitea-docs.netlify.com/* https://docs.gitea.io/:splat 302!
/en-us/ci-cd/ /en-us/integrations/ 302! /en-us/ci-cd/ /en-us/integrations/ 302!
/en-us/third-party-tools/ /en-us/integrations/ 302! /en-us/third-party-tools/ /en-us/integrations/ 302!
/en-us/make/ /en-us/hacking-on-gitea/ 302! /en-us/make/ /en-us/hacking-on-gitea/ 302!
/en-us/upgrade/ /en-us/upgrade-from-gitea/ 302!
/fr-fr/upgrade/ /fr-fr/upgrade-from-gitea/ 302!
/zh-cn/upgrade/ /zh-cn/upgrade-from-gitea/ 302!
/zh-tw/upgrade/ /zh-tw/upgrade-from-gitea/ 302!

23
docs/static/open-in-gitpod.svg vendored Normal file
View File

@ -0,0 +1,23 @@
<svg width="160" height="45" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d)">
<rect x="2" y="2" width="156" height="40" rx="16" fill="#F9F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.425 11.174c.604 1.114.233 2.53-.83 3.164l-6.986 4.166a.378.378 0 00-.18.325v6.748c0 .134.069.258.18.325l5.714 3.407c.11.066.244.066.354 0l5.714-3.407a.378.378 0 00.18-.325V21.29l-4.986 2.936c-1.067.628-2.416.231-3.015-.886-.6-1.118-.22-2.532.846-3.16l7.008-4.127c2.048-1.206 4.576.345 4.576 2.806v6.718c0 1.803-.924 3.467-2.42 4.36l-5.713 3.407a4.596 4.596 0 01-4.734 0l-5.714-3.408C18.924 29.044 18 27.38 18 25.576V18.83c0-1.803.924-3.467 2.42-4.36l6.985-4.165c1.063-.634 2.415-.245 3.02.87z" fill="url(#paint0_linear)"/>
<path fill="#F9F9F9" d="M47 12.5h95v-1H47z"/>
<path d="M52.538 27.752c2.744 0 4.844-1.876 4.844-5.152 0-3.108-2.1-5.152-4.844-5.152s-4.802 2.002-4.802 5.152c0 3.29 2.058 5.152 4.802 5.152zm0-1.554c-1.736 0-2.912-1.316-2.912-3.598 0-2.226 1.162-3.598 2.912-3.598s2.954 1.4 2.954 3.598c0 2.31-1.218 3.598-2.954 3.598zm7.89 4.158V27.22c0-.196-.013-.378-.055-.658.434.7 1.022 1.19 2.17 1.19 1.736 0 3.066-1.414 3.066-3.626 0-2.17-1.19-3.682-2.996-3.682-1.078 0-1.806.476-2.24 1.204.042-.28.056-.462.056-.672v-.308H58.72v9.688h1.708zm1.695-3.948c-1.036 0-1.764-.938-1.764-2.31 0-1.414.742-2.296 1.764-2.296 1.092 0 1.75.952 1.75 2.296 0 1.372-.7 2.31-1.75 2.31zm7.866 1.344c1.848 0 3.052-1.078 3.192-2.478h-1.736c-.112.714-.714 1.134-1.456 1.134-1.036 0-1.722-.826-1.736-1.904h4.97v-.378c0-2.226-1.204-3.682-3.29-3.682-1.988 0-3.43 1.47-3.43 3.626 0 2.366 1.442 3.682 3.486 3.682zm-1.75-4.48c.098-.896.756-1.554 1.68-1.554.924 0 1.526.63 1.554 1.554H68.24zm8.006 4.228v-4.004c0-.952.616-1.694 1.456-1.694.798 0 1.288.63 1.288 1.638v4.06h1.708v-4.312c0-1.68-.896-2.744-2.408-2.744-1.078 0-1.722.518-2.1 1.204.042-.266.056-.476.056-.672v-.308h-1.708V27.5h1.708zm8.911-7.868h1.792V17.84h-1.792v1.792zm.042 1.036V27.5h1.708v-6.832h-1.708zm5.097 6.832v-4.004c0-.952.616-1.694 1.456-1.694.798 0 1.288.63 1.288 1.638v4.06h1.708v-4.312c0-1.68-.896-2.744-2.408-2.744-1.078 0-1.722.518-2.1 1.204.042-.266.056-.476.056-.672v-.308h-1.708V27.5h1.708zm13.238.252c1.526 0 2.52-.658 2.982-1.54-.07.322-.098.644-.098.98v.308h1.68v-5.222h-4.34v1.554h2.66v.07c0 1.4-1.134 2.296-2.59 2.296-1.792 0-3.024-1.372-3.024-3.598s1.26-3.598 3.066-3.598c1.302 0 2.17.756 2.296 1.736h1.89c-.182-1.904-1.764-3.29-4.214-3.29-2.954 0-4.928 2.128-4.928 5.152 0 3.136 1.848 5.152 4.62 5.152zm6.063-8.12h1.792V17.84h-1.792v1.792zm.042 1.036V27.5h1.708v-6.832h-1.708zm6.413 6.958c.434 0 .84-.07 1.008-.126v-1.288c-.168.028-.35.042-.518.042-.728 0-1.008-.42-1.008-1.134v-3.094h1.68v-1.358h-1.68v-2.464h-1.708v2.464h-1.554v1.358h1.554v3.346c0 1.526.77 2.254 2.226 2.254zm3.961 2.73V27.22c0-.196-.014-.378-.056-.658.434.7 1.022 1.19 2.17 1.19 1.736 0 3.066-1.414 3.066-3.626 0-2.17-1.19-3.682-2.996-3.682-1.078 0-1.806.476-2.24 1.204.042-.28.056-.462.056-.672v-.308h-1.708v9.688h1.708zm1.694-3.948c-1.036 0-1.764-.938-1.764-2.31 0-1.414.742-2.296 1.764-2.296 1.092 0 1.75.952 1.75 2.296 0 1.372-.7 2.31-1.75 2.31zm7.88 1.344c2.058 0 3.514-1.372 3.514-3.64 0-2.24-1.456-3.668-3.514-3.668-2.044 0-3.5 1.428-3.5 3.668 0 2.268 1.442 3.64 3.5 3.64zm0-1.344c-1.064 0-1.764-.84-1.764-2.296 0-1.484.728-2.31 1.764-2.31 1.05 0 1.778.826 1.778 2.31 0 1.456-.714 2.296-1.778 2.296zm7.551 1.344c1.26 0 1.876-.686 2.142-1.19-.056.238-.056.42-.056.658v.28h1.708v-9.8h-1.708v3.276c0 .21 0 .42.056.672-.392-.658-1.05-1.204-2.114-1.204-1.596 0-3.15 1.218-3.15 3.668 0 2.408 1.316 3.64 3.122 3.64zm.406-1.344c-1.022 0-1.792-.896-1.792-2.31 0-1.358.77-2.296 1.792-2.296s1.778.896 1.778 2.296c0 1.372-.756 2.31-1.778 2.31z" fill="#12100C"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="33.806" y1="13.629" x2="22.389" y2="30.86" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFB45B"/>
<stop offset="1" stop-color="#FF8A00"/>
</linearGradient>
<filter id="filter0_d" x="0" y=".5" width="160" height="44" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy=".5"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

86
go.mod
View File

@ -15,10 +15,10 @@ require (
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
github.com/PuerkitoBio/goquery v1.8.0 github.com/PuerkitoBio/goquery v1.8.0
github.com/alecthomas/chroma v0.10.0 github.com/alecthomas/chroma/v2 v2.3.0
github.com/blevesearch/bleve/v2 v2.3.2 github.com/blevesearch/bleve/v2 v2.3.4
github.com/buildkite/terminal-to-html/v3 v3.7.0 github.com/buildkite/terminal-to-html/v3 v3.7.0
github.com/caddyserver/certmagic v0.17.0 github.com/caddyserver/certmagic v0.17.2
github.com/chi-middleware/proxy v1.1.1 github.com/chi-middleware/proxy v1.1.1
github.com/denisenkom/go-mssqldb v0.12.2 github.com/denisenkom/go-mssqldb v0.12.2
github.com/djherbis/buffer v1.2.0 github.com/djherbis/buffer v1.2.0
@ -31,46 +31,46 @@ require (
github.com/felixge/fgprof v0.9.3 github.com/felixge/fgprof v0.9.3
github.com/fsnotify/fsnotify v1.5.4 github.com/fsnotify/fsnotify v1.5.4
github.com/gliderlabs/ssh v0.3.5 github.com/gliderlabs/ssh v0.3.5
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535 github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778
github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/chi/v5 v5.0.7
github.com/go-chi/cors v1.2.1 github.com/go-chi/cors v1.2.1
github.com/go-enry/go-enry/v2 v2.8.2 github.com/go-enry/go-enry/v2 v2.8.3
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
github.com/go-git/go-billy/v5 v5.3.1 github.com/go-git/go-billy/v5 v5.3.1
github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf
github.com/go-ldap/ldap/v3 v3.4.4 github.com/go-ldap/ldap/v3 v3.4.4
github.com/go-redis/redis/v8 v8.11.5 github.com/go-redis/redis/v8 v8.11.5
github.com/go-sql-driver/mysql v1.6.0 github.com/go-sql-driver/mysql v1.6.0
github.com/go-swagger/go-swagger v0.30.0 github.com/go-swagger/go-swagger v0.30.3
github.com/go-testfixtures/testfixtures/v3 v3.8.1 github.com/go-testfixtures/testfixtures/v3 v3.8.1
github.com/gobwas/glob v0.2.3 github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
github.com/golang-jwt/jwt/v4 v4.4.2 github.com/golang-jwt/jwt/v4 v4.4.2
github.com/google/go-github/v45 v45.0.0 github.com/google/go-github/v45 v45.2.0
github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40 github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/gorilla/feeds v1.1.1 github.com/gorilla/feeds v1.1.1
github.com/gorilla/sessions v1.2.1 github.com/gorilla/sessions v1.2.1
github.com/hashicorp/go-version v1.4.0 github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/golang-lru v0.5.4 github.com/hashicorp/golang-lru v0.5.4
github.com/huandu/xstrings v1.3.2 github.com/huandu/xstrings v1.3.2
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
github.com/klauspost/compress v1.15.9 github.com/klauspost/compress v1.15.11
github.com/klauspost/cpuid/v2 v2.1.1 github.com/klauspost/cpuid/v2 v2.1.1
github.com/lib/pq v1.10.6 github.com/lib/pq v1.10.7
github.com/markbates/goth v1.73.0 github.com/markbates/goth v1.73.0
github.com/mattn/go-isatty v0.0.16 github.com/mattn/go-isatty v0.0.16
github.com/mattn/go-sqlite3 v1.14.13 github.com/mattn/go-sqlite3 v1.14.15
github.com/mholt/archiver/v3 v3.5.1 github.com/mholt/archiver/v3 v3.5.1
github.com/microcosm-cc/bluemonday v1.0.19 github.com/microcosm-cc/bluemonday v1.0.20
github.com/minio/minio-go/v7 v7.0.35 github.com/minio/minio-go/v7 v7.0.39
github.com/msteinert/pam v1.0.0 github.com/msteinert/pam v1.1.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/niklasfasching/go-org v1.6.5 github.com/niklasfasching/go-org v1.6.5
github.com/oliamb/cutter v0.2.2 github.com/oliamb/cutter v0.2.2
@ -79,27 +79,27 @@ require (
github.com/pquerna/otp v1.3.0 github.com/pquerna/otp v1.3.0
github.com/prometheus/client_golang v1.13.0 github.com/prometheus/client_golang v1.13.0
github.com/quasoft/websspi v1.1.2 github.com/quasoft/websspi v1.1.2
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 github.com/santhosh-tekuri/jsonschema/v5 v5.0.1
github.com/sergi/go-diff v1.2.0 github.com/sergi/go-diff v1.2.0
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0
github.com/syndtr/goleveldb v1.0.0 github.com/syndtr/goleveldb v1.0.0
github.com/tstranex/u2f v1.0.0 github.com/tstranex/u2f v1.0.0
github.com/unrolled/render v1.5.0 github.com/unrolled/render v1.5.0
github.com/urfave/cli v1.22.9 github.com/urfave/cli v1.22.10
github.com/valyala/fastjson v1.6.3 github.com/valyala/fastjson v1.6.3
github.com/xanzy/go-gitlab v0.73.1 github.com/xanzy/go-gitlab v0.73.1
github.com/yohcop/openid-go v1.0.0 github.com/yohcop/openid-go v1.0.0
github.com/yuin/goldmark v1.4.13 github.com/yuin/goldmark v1.5.2
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87
github.com/yuin/goldmark-meta v1.1.0 github.com/yuin/goldmark-meta v1.1.0
go.jolheiser.com/hcaptcha v0.0.4 go.jolheiser.com/hcaptcha v0.0.4
go.jolheiser.com/pwn v0.0.3 go.jolheiser.com/pwn v0.0.3
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b golang.org/x/net v0.0.0-20220927171203-f486391704dc
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
golang.org/x/text v0.3.7 golang.org/x/text v0.3.8
golang.org/x/tools v0.1.12 golang.org/x/tools v0.1.12
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.67.0 gopkg.in/ini.v1 v1.67.0
@ -118,9 +118,9 @@ require (
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.2 // indirect github.com/Masterminds/sprig/v3 v3.2.2 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 // indirect github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad // indirect
github.com/RoaringBitmap/roaring v0.9.4 // indirect github.com/RoaringBitmap/roaring v1.2.1 // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect github.com/andybalholm/brotli v1.0.4 // indirect
github.com/andybalholm/cascadia v1.3.1 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect
@ -129,21 +129,22 @@ require (
github.com/aymerick/douceur v0.2.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/bits-and-blooms/bitset v1.2.2 // indirect github.com/bits-and-blooms/bitset v1.3.3 // indirect
github.com/blevesearch/bleve_index_api v1.0.1 // indirect github.com/blevesearch/bleve_index_api v1.0.3 // indirect
github.com/blevesearch/geo v0.1.14 // indirect
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
github.com/blevesearch/gtreap v0.1.1 // indirect github.com/blevesearch/gtreap v0.1.1 // indirect
github.com/blevesearch/mmap-go v1.0.3 // indirect github.com/blevesearch/mmap-go v1.0.4 // indirect
github.com/blevesearch/scorch_segment_api/v2 v2.1.0 // indirect github.com/blevesearch/scorch_segment_api/v2 v2.1.2 // indirect
github.com/blevesearch/segment v0.9.0 // indirect github.com/blevesearch/segment v0.9.0 // indirect
github.com/blevesearch/snowballstem v0.9.0 // indirect github.com/blevesearch/snowballstem v0.9.0 // indirect
github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect
github.com/blevesearch/vellum v1.0.7 // indirect github.com/blevesearch/vellum v1.0.8 // indirect
github.com/blevesearch/zapx/v11 v11.3.3 // indirect github.com/blevesearch/zapx/v11 v11.3.5 // indirect
github.com/blevesearch/zapx/v12 v12.3.3 // indirect github.com/blevesearch/zapx/v12 v12.3.5 // indirect
github.com/blevesearch/zapx/v13 v13.3.3 // indirect github.com/blevesearch/zapx/v13 v13.3.5 // indirect
github.com/blevesearch/zapx/v14 v14.3.3 // indirect github.com/blevesearch/zapx/v14 v14.3.5 // indirect
github.com/blevesearch/zapx/v15 v15.3.3 // indirect github.com/blevesearch/zapx/v15 v15.3.5 // indirect
github.com/boombuler/barcode v1.0.1 // indirect github.com/boombuler/barcode v1.0.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
@ -168,7 +169,7 @@ require (
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/fullstorydev/grpcurl v1.8.1 // indirect github.com/fullstorydev/grpcurl v1.8.1 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1 // indirect github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
github.com/go-enry/go-oniguruma v1.2.1 // indirect github.com/go-enry/go-oniguruma v1.2.1 // indirect
github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/gcfg v1.5.0 // indirect
@ -187,6 +188,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
@ -220,7 +222,7 @@ require (
github.com/magiconair/properties v1.8.6 // indirect github.com/magiconair/properties v1.8.6 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/markbates/going v1.0.0 // indirect github.com/markbates/going v1.0.0 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mholt/acmez v1.0.4 // indirect github.com/mholt/acmez v1.0.4 // indirect
github.com/miekg/dns v1.1.50 // indirect github.com/miekg/dns v1.1.50 // indirect
@ -238,12 +240,12 @@ require (
github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect
github.com/pierrec/lz4/v4 v4.1.15 // indirect github.com/pierrec/lz4/v4 v4.1.17 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect
github.com/rivo/uniseg v0.3.4 // indirect github.com/rivo/uniseg v0.4.2 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/rs/xid v1.4.0 // indirect github.com/rs/xid v1.4.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
@ -283,7 +285,7 @@ require (
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.23.0 // indirect go.uber.org/zap v1.23.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
google.golang.org/grpc v1.47.0 // indirect google.golang.org/grpc v1.47.0 // indirect

170
go.sum
View File

@ -136,22 +136,24 @@ github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuN
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg= github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY=
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I= github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo=
github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
github.com/RoaringBitmap/roaring v1.2.1 h1:58/LJlg/81wfEHd5L9qsHduznOIhyv4qb1yWcSvVq9A=
github.com/RoaringBitmap/roaring v1.2.1/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
@ -160,9 +162,12 @@ github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s= github.com/alecthomas/chroma/v2 v2.3.0 h1:83xfxrnjv8eK+Cf8qZDzNo3PPF9IbTWHs7z28GY6D0U=
github.com/alecthomas/chroma/v2 v2.3.0/go.mod h1:mZxeWZlxP2Dy+/8cBob2PYd8O2DwNAzave5AY7A2eQw=
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -217,28 +222,31 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE= github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk= github.com/bits-and-blooms/bitset v1.3.3 h1:R1XWiopGiXf66xygsiLpzLo67xEYvMkHw3w+rCOSAwg=
github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.3.3/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM= github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
github.com/blevesearch/bleve/v2 v2.3.2 h1:BJUnMhi2nrkl+vboHmKfW+9l+tJSj39HeWa5c3BN3/Y= github.com/blevesearch/bleve/v2 v2.3.4 h1:SSb7/cwGzo85LWX1jchIsXM8ZiNNMX3shT5lROM63ew=
github.com/blevesearch/bleve/v2 v2.3.2/go.mod h1:96+xE5pZUOsr3Y4vHzV1cBC837xZCpwLlX0hrrxnvIg= github.com/blevesearch/bleve/v2 v2.3.4/go.mod h1:Ot0zYum8XQRfPcwhae8bZmNyYubynsoMjVvl1jPqL30=
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
github.com/blevesearch/bleve_index_api v1.0.1 h1:nx9++0hnyiGOHJwQQYfsUGzpRdEVE5LsylmmngQvaFk= github.com/blevesearch/bleve_index_api v1.0.3 h1:DDSWaPXOZZJ2BB73ZTWjKxydAugjwywcqU+91AAqcAg=
github.com/blevesearch/bleve_index_api v1.0.1/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= github.com/blevesearch/bleve_index_api v1.0.3/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
github.com/blevesearch/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A= github.com/blevesearch/geo v0.1.13/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
github.com/blevesearch/geo v0.1.14 h1:TTDpJN6l9ck/cUYbXSn4aCElNls0Whe44rcQKsB7EfU=
github.com/blevesearch/geo v0.1.14/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
github.com/blevesearch/goleveldb v1.0.1/go.mod h1:WrU8ltZbIp0wAoig/MHbrPCXSOLpe79nz5lv5nqfYrQ= github.com/blevesearch/goleveldb v1.0.1/go.mod h1:WrU8ltZbIp0wAoig/MHbrPCXSOLpe79nz5lv5nqfYrQ=
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y= github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk= github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA= github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
github.com/blevesearch/mmap-go v1.0.3 h1:7QkALgFNooSq3a46AE+pWeKASAZc9SiNFJhDGF1NDx4= github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
github.com/blevesearch/mmap-go v1.0.3/go.mod h1:pYvKl/grLQrBxuaRYgoTssa4rVujYYeenDp++2E+yvs= github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU= github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
github.com/blevesearch/scorch_segment_api/v2 v2.1.0 h1:NFwteOpZEvJk5Vg0H6gD0hxupsG3JYocE4DBvsA2GZI= github.com/blevesearch/scorch_segment_api/v2 v2.1.2 h1:TAte9VZLWda5WAVlZTTZ+GCzEHqGJb4iB2aiZSA6Iv8=
github.com/blevesearch/scorch_segment_api/v2 v2.1.0/go.mod h1:uch7xyyO/Alxkuxa+CGs79vw0QY8BENSBjg6Mw5L5DE= github.com/blevesearch/scorch_segment_api/v2 v2.1.2/go.mod h1:rvoQXZGq8drq7vXbNeyiRzdEOwZkjkiYGf1822i6CRA=
github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac= github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac=
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ= github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg= github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg=
@ -248,23 +256,23 @@ github.com/blevesearch/upsidedown_store_api v1.0.1 h1:1SYRwyoFLwG3sj0ed89RLtM15a
github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q= github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
github.com/blevesearch/vellum v1.0.3/go.mod h1:2u5ax02KeDuNWu4/C+hVQMD6uLN4txH1JbtpaDNLJRo= github.com/blevesearch/vellum v1.0.3/go.mod h1:2u5ax02KeDuNWu4/C+hVQMD6uLN4txH1JbtpaDNLJRo=
github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRvNBlNMrEVgY= github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRvNBlNMrEVgY=
github.com/blevesearch/vellum v1.0.7 h1:+vn8rfyCRHxKVRgDLeR0FAXej2+6mEb5Q15aQE/XESQ= github.com/blevesearch/vellum v1.0.8 h1:iMGh4lfxza4BnWO/UJTMPlI3HsK9YawjPv+TteVa9ck=
github.com/blevesearch/vellum v1.0.7/go.mod h1:doBZpmRhwTsASB4QdUZANlJvqVAUdUyX0ZK7QJCTeBE= github.com/blevesearch/vellum v1.0.8/go.mod h1:+cpRi/tqq49xUYSQN2P7A5zNSNrS+MscLeeaZ3J46UA=
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM= github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
github.com/blevesearch/zapx/v11 v11.3.3 h1:8vQMO5hdA2qPCmicIMuKS+qcvUAEh6Vcb0uve4Nh8e4= github.com/blevesearch/zapx/v11 v11.3.5 h1:eBQWQ7huA+mzm0sAGnZDwgGGli7S45EO+N+ObFWssbI=
github.com/blevesearch/zapx/v11 v11.3.3/go.mod h1:YzTfUm4kS3e8OmTXDHVV8OzC5MWPO/VPJZQgPNVb4Lc= github.com/blevesearch/zapx/v11 v11.3.5/go.mod h1:5UdIa/HRMdeRCiLQOyFESsnqBGiip7vQmYReA9toevU=
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A= github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
github.com/blevesearch/zapx/v12 v12.3.3 h1:MQO5YNI8MqdPz12ALCoXiJw5cl9QQamYZSp285Z/+Mo= github.com/blevesearch/zapx/v12 v12.3.5 h1:5pX2hU+R1aZihT7ac1dNWh1n4wqkIM9pZzWp0ANED9s=
github.com/blevesearch/zapx/v12 v12.3.3/go.mod h1:RMl6lOZqF+sTxKvhQDJ5yK2LT3Mu7E2p/jGdjAaiRxs= github.com/blevesearch/zapx/v12 v12.3.5/go.mod h1:ANcthYRZQycpbRut/6ArF5gP5HxQyJqiFcuJCBju/ss=
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ= github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
github.com/blevesearch/zapx/v13 v13.3.3 h1:TS4xpMK1ARPYHq+1WwuEOKMOiwvKpTK3RuWOkKlI7BE= github.com/blevesearch/zapx/v13 v13.3.5 h1:eJ3gbD+Nu8p36/O6lhfdvWQ4pxsGYSuTOBrLLPVWJ74=
github.com/blevesearch/zapx/v13 v13.3.3/go.mod h1:eppobNM35U4C22yDvTuxV9xPqo10pwfP/jugL4INWG4= github.com/blevesearch/zapx/v13 v13.3.5/go.mod h1:FV+dRnScFgKnRDIp08RQL4JhVXt1x2HE3AOzqYa6fjo=
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g= github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
github.com/blevesearch/zapx/v14 v14.3.3 h1:dqqAzGphKl0yehHKKntDHKlEMhi9B/tJrD4OsWpY7YE= github.com/blevesearch/zapx/v14 v14.3.5 h1:hEvVjZaagFCvOUJrlFQ6/Z6Jjy0opM3g7TMEo58TwP4=
github.com/blevesearch/zapx/v14 v14.3.3/go.mod h1:zXNcVzukh0AvG57oUtT1T0ndi09H0kELNaNmekEy0jw= github.com/blevesearch/zapx/v14 v14.3.5/go.mod h1:954A/eKFb+pg/ncIYWLWCKY+mIjReM9FGTGIO2Wu1cU=
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A= github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
github.com/blevesearch/zapx/v15 v15.3.3 h1:60oE+qsJkveLenJmbc0eaH59GWYCbJJsPDV6Z5hEoYY= github.com/blevesearch/zapx/v15 v15.3.5 h1:NVD0qq8vRk66ImJn1KloXT5ckqPDUZT7VbVJs9jKlac=
github.com/blevesearch/zapx/v15 v15.3.3/go.mod h1:C+f/97ZzTzK6vt/7sVlZdzZxKu+5+j4SrGCvr9dJzaY= github.com/blevesearch/zapx/v15 v15.3.5/go.mod h1:QMUh2hXCaYIWFKPYGavq/Iga2zbHWZ9DZAa9uFbWyvg=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
@ -276,8 +284,8 @@ github.com/buildkite/terminal-to-html/v3 v3.7.0/go.mod h1:g0ME1XqbkBSgXR9YmlIHcJ
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw=
github.com/caddyserver/certmagic v0.17.0 h1:AHHvvmv6SNcq0vK5BgCevQqYMV8GNprVk6FWZzx8d+Q= github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE=
github.com/caddyserver/certmagic v0.17.0/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM= github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo= github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A=
@ -465,10 +473,10 @@ github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1 h1:PkPVIQGt76HHFWSeUINXCfYpEnzlSS+AQyuXi7oJ/gM= github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18 h1:A48SbkWKEciiJMbbcPzaRj9aizPUABzXFvCM3LtGGf8=
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1/go.mod h1:KHkKFKZvc05lr79+RGoq/zG8YjWi3+FK60Bxd+mpCew= github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18/go.mod h1:dd3ZgjjloBsKPDpqA2kf2VWhF0A1eKUItOBh0/QcDWI=
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d h1:Z/oRXMlZHjvjIqDma1FrIGL3iE5YL7MUI0bwYEZ6qbA= github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778 h1:0tV3i8tE1NghMC4rXZXfD39KUbkKgIyLTsvOEmMOPCQ=
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA= github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA=
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
@ -477,8 +485,8 @@ github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-enry/go-enry/v2 v2.8.2 h1:uiGmC+3K8sVd/6DOe2AOJEOihJdqda83nPyJNtMR8RI= github.com/go-enry/go-enry/v2 v2.8.3 h1:BwvNrN58JqBJhyyVdZSl5QD3xoxEEGYUrRyPh31FGhw=
github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-enry/v2 v2.8.3/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8= github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8=
@ -556,8 +564,8 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-swagger/go-swagger v0.30.0 h1:HakSyutD7Ek9ndkR8Fxy6WAoQtgu7UcAmZCTa6SzawA= github.com/go-swagger/go-swagger v0.30.3 h1:HuzvdMRed/9Q8vmzVcfNBQByZVtT79DNZxZ18OprdoI=
github.com/go-swagger/go-swagger v0.30.0/go.mod h1:GhZVX/KIBM4VpGp4P7AJOIrlTuBeRVPS+j9kk6rFmfY= github.com/go-swagger/go-swagger v0.30.3/go.mod h1:neDPes8r8PCz2JPvHRDj8BTULLh4VJUt7n6MpQqxhHM=
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0= github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
github.com/go-testfixtures/testfixtures/v3 v3.8.1 h1:uonwvepqRvSgddcrReZQhojTlWlmOlHkYAb9ZaOMWgU= github.com/go-testfixtures/testfixtures/v3 v3.8.1 h1:uonwvepqRvSgddcrReZQhojTlWlmOlHkYAb9ZaOMWgU=
github.com/go-testfixtures/testfixtures/v3 v3.8.1/go.mod h1:Kdu7YeMC0KRXVHdaQ91Vmx3pcjoTF63h4f1qTJDdXLA= github.com/go-testfixtures/testfixtures/v3 v3.8.1/go.mod h1:Kdu7YeMC0KRXVHdaQ91Vmx3pcjoTF63h4f1qTJDdXLA=
@ -617,6 +625,8 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -684,8 +694,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
github.com/google/go-github/v45 v45.0.0 h1:LU0WBjYidxIVyx7PZeWb+FP4JZJ3Wh3FQgdumnGqiLs= github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI=
github.com/google/go-github/v45 v45.0.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28=
github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M= github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M=
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/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
@ -693,6 +703,7 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M= github.com/google/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@ -923,6 +934,7 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@ -958,8 +970,8 @@ github.com/kisom/goutils v1.4.3/go.mod h1:Lp5qrquG7yhYnWzZCI/68Pa/GpFynw//od6EkG
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
@ -998,8 +1010,8 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis= github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
@ -1049,15 +1061,15 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I= github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@ -1066,8 +1078,8 @@ github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80=
github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY= github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY=
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c= github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y=
github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE= github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
@ -1075,8 +1087,8 @@ github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.35 h1:JuPPxWLdxQmNLSaS8AWZnO5HBadeI1xg6FGrEELQEVU= github.com/minio/minio-go/v7 v7.0.39 h1:upnbu1jCGOqEvrGSpRauSN9ZG7RCHK7VHxXS8Vmg2zk=
github.com/minio/minio-go/v7 v7.0.35/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw= github.com/minio/minio-go/v7 v7.0.39/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw=
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@ -1116,8 +1128,8 @@ github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450/go.mod h1:skjdDftzkF
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/msteinert/pam v1.0.0 h1:4XoXKtMCH3+e6GIkW41uxm6B37eYqci/DH3gzSq7ocg= github.com/msteinert/pam v1.1.0 h1:VhLun/0n0kQYxiRBJJvVpC2jR6d21SWJFjpvUVj20Kc=
github.com/msteinert/pam v1.0.0/go.mod h1:M4FPeAW8g2ITO68W8gACDz13NDJyOQM9IQsQhrR6TOI= github.com/msteinert/pam v1.1.0/go.mod h1:M4FPeAW8g2ITO68W8gACDz13NDJyOQM9IQsQhrR6TOI=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
@ -1197,8 +1209,8 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -1269,8 +1281,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s= github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
@ -1294,8 +1306,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE= github.com/santhosh-tekuri/jsonschema/v5 v5.0.1 h1:HNLA3HtUIROrQwG1cuu5EYuqk3UEoJ61Dr/9xkd6sok=
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= github.com/santhosh-tekuri/jsonschema/v5 v5.0.1/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
@ -1430,8 +1442,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc= github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
@ -1467,11 +1479,11 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.5/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594 h1:yHfZyN55+5dp1wG7wDKv8HQ044moxkyGq12KFFMFDxg= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87 h1:Py16JEzkSdKAtEFJjiaYLYBOWGXc1r/xHj/Q/5lA37k=
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594/go.mod h1:U9ihbh+1ZN7fR5Se3daSPoz1CGF9IYtSvWwVQtnzGHU= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
@ -1596,8 +1608,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -1708,8 +1720,9 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ=
golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
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-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1734,8 +1747,8 @@ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8= golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1863,8 +1876,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY= golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
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/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -1878,16 +1891,17 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -1,12 +0,0 @@
export default {
rootDir: 'web_src',
setupFilesAfterEnv: ['jest-extended/all'],
testEnvironment: 'jest-environment-jsdom',
testMatch: ['<rootDir>/**/*.test.js'],
testTimeout: 20000,
transform: {
'\\.svg$': '<rootDir>/js/testUtils/jestRawLoader.js',
},
verbose: false,
};

View File

@ -18,13 +18,11 @@ import (
type ActionList []*Action type ActionList []*Action
func (actions ActionList) getUserIDs() []int64 { func (actions ActionList) getUserIDs() []int64 {
userIDs := make(map[int64]struct{}, len(actions)) userIDs := make(container.Set[int64], len(actions))
for _, action := range actions { for _, action := range actions {
if _, ok := userIDs[action.ActUserID]; !ok { userIDs.Add(action.ActUserID)
userIDs[action.ActUserID] = struct{}{}
}
} }
return container.KeysInt64(userIDs) return userIDs.Values()
} }
func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) { func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) {
@ -48,13 +46,11 @@ func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.
} }
func (actions ActionList) getRepoIDs() []int64 { func (actions ActionList) getRepoIDs() []int64 {
repoIDs := make(map[int64]struct{}, len(actions)) repoIDs := make(container.Set[int64], len(actions))
for _, action := range actions { for _, action := range actions {
if _, ok := repoIDs[action.RepoID]; !ok { repoIDs.Add(action.RepoID)
repoIDs[action.RepoID] = struct{}{}
}
} }
return container.KeysInt64(repoIDs) return repoIDs.Values()
} }
func (actions ActionList) loadRepositories(ctx context.Context) error { func (actions ActionList) loadRepositories(ctx context.Context) error {

View File

@ -200,7 +200,7 @@ func CreateOrUpdateIssueNotifications(issueID, commentID, notificationAuthorID,
func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error { func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error {
// init // init
var toNotify map[int64]struct{} var toNotify container.Set[int64]
notifications, err := getNotificationsByIssueID(ctx, issueID) notifications, err := getNotificationsByIssueID(ctx, issueID)
if err != nil { if err != nil {
return err return err
@ -212,33 +212,27 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
} }
if receiverID > 0 { if receiverID > 0 {
toNotify = make(map[int64]struct{}, 1) toNotify = make(container.Set[int64], 1)
toNotify[receiverID] = struct{}{} toNotify.Add(receiverID)
} else { } else {
toNotify = make(map[int64]struct{}, 32) toNotify = make(container.Set[int64], 32)
issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true) issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true)
if err != nil { if err != nil {
return err return err
} }
for _, id := range issueWatches { toNotify.AddMultiple(issueWatches...)
toNotify[id] = struct{}{}
}
if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) { if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) {
repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID) repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID)
if err != nil { if err != nil {
return err return err
} }
for _, id := range repoWatches { toNotify.AddMultiple(repoWatches...)
toNotify[id] = struct{}{}
}
} }
issueParticipants, err := issue.GetParticipantIDsByIssue(ctx) issueParticipants, err := issue.GetParticipantIDsByIssue(ctx)
if err != nil { if err != nil {
return err return err
} }
for _, id := range issueParticipants { toNotify.AddMultiple(issueParticipants...)
toNotify[id] = struct{}{}
}
// dont notify user who cause notification // dont notify user who cause notification
delete(toNotify, notificationAuthorID) delete(toNotify, notificationAuthorID)
@ -248,7 +242,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
return err return err
} }
for _, id := range issueUnWatches { for _, id := range issueUnWatches {
delete(toNotify, id) toNotify.Remove(id)
} }
} }
@ -499,16 +493,14 @@ func (nl NotificationList) LoadAttributes() error {
} }
func (nl NotificationList) getPendingRepoIDs() []int64 { func (nl NotificationList) getPendingRepoIDs() []int64 {
ids := make(map[int64]struct{}, len(nl)) ids := make(container.Set[int64], len(nl))
for _, notification := range nl { for _, notification := range nl {
if notification.Repository != nil { if notification.Repository != nil {
continue continue
} }
if _, ok := ids[notification.RepoID]; !ok { ids.Add(notification.RepoID)
ids[notification.RepoID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
// LoadRepos loads repositories from database // LoadRepos loads repositories from database
@ -575,16 +567,14 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error)
} }
func (nl NotificationList) getPendingIssueIDs() []int64 { func (nl NotificationList) getPendingIssueIDs() []int64 {
ids := make(map[int64]struct{}, len(nl)) ids := make(container.Set[int64], len(nl))
for _, notification := range nl { for _, notification := range nl {
if notification.Issue != nil { if notification.Issue != nil {
continue continue
} }
if _, ok := ids[notification.IssueID]; !ok { ids.Add(notification.IssueID)
ids[notification.IssueID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
// LoadIssues loads issues from database // LoadIssues loads issues from database
@ -661,16 +651,14 @@ func (nl NotificationList) Without(failures []int) NotificationList {
} }
func (nl NotificationList) getPendingCommentIDs() []int64 { func (nl NotificationList) getPendingCommentIDs() []int64 {
ids := make(map[int64]struct{}, len(nl)) ids := make(container.Set[int64], len(nl))
for _, notification := range nl { for _, notification := range nl {
if notification.CommentID == 0 || notification.Comment != nil { if notification.CommentID == 0 || notification.Comment != nil {
continue continue
} }
if _, ok := ids[notification.CommentID]; !ok { ids.Add(notification.CommentID)
ids[notification.CommentID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
// LoadComments loads comments from database // LoadComments loads comments from database
@ -818,7 +806,7 @@ func getNotificationByID(ctx context.Context, notificationID int64) (*Notificati
} }
if !ok { if !ok {
return nil, db.ErrNotExist{ID: notificationID} return nil, db.ErrNotExist{Resource: "notification", ID: notificationID}
} }
return notification, nil return notification, nil

View File

@ -1,117 +0,0 @@
// 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 admin_test
import (
"testing"
"code.gitea.io/gitea/models/admin"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
)
func TestNotice_TrStr(t *testing.T) {
notice := &admin.Notice{
Type: admin.NoticeRepository,
Description: "test description",
}
assert.Equal(t, "admin.notices.type_1", notice.TrStr())
}
func TestCreateNotice(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
noticeBean := &admin.Notice{
Type: admin.NoticeRepository,
Description: "test description",
}
unittest.AssertNotExistsBean(t, noticeBean)
assert.NoError(t, admin.CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description))
unittest.AssertExistsAndLoadBean(t, noticeBean)
}
func TestCreateRepositoryNotice(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
noticeBean := &admin.Notice{
Type: admin.NoticeRepository,
Description: "test description",
}
unittest.AssertNotExistsBean(t, noticeBean)
assert.NoError(t, admin.CreateRepositoryNotice(noticeBean.Description))
unittest.AssertExistsAndLoadBean(t, noticeBean)
}
// TODO TestRemoveAllWithNotice
func TestCountNotices(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
assert.Equal(t, int64(3), admin.CountNotices())
}
func TestNotices(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
notices, err := admin.Notices(1, 2)
assert.NoError(t, err)
if assert.Len(t, notices, 2) {
assert.Equal(t, int64(3), notices[0].ID)
assert.Equal(t, int64(2), notices[1].ID)
}
notices, err = admin.Notices(2, 2)
assert.NoError(t, err)
if assert.Len(t, notices, 1) {
assert.Equal(t, int64(1), notices[0].ID)
}
}
func TestDeleteNotice(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3})
assert.NoError(t, admin.DeleteNotice(3))
unittest.AssertNotExistsBean(t, &admin.Notice{ID: 3})
}
func TestDeleteNotices(t *testing.T) {
// delete a non-empty range
assert.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3})
assert.NoError(t, admin.DeleteNotices(1, 2))
unittest.AssertNotExistsBean(t, &admin.Notice{ID: 1})
unittest.AssertNotExistsBean(t, &admin.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3})
}
func TestDeleteNotices2(t *testing.T) {
// delete an empty range
assert.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3})
assert.NoError(t, admin.DeleteNotices(3, 2))
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3})
}
func TestDeleteNoticesByIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3})
assert.NoError(t, admin.DeleteNoticesByIDs([]int64{1, 3}))
unittest.AssertNotExistsBean(t, &admin.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2})
unittest.AssertNotExistsBean(t, &admin.Notice{ID: 3})
}

View File

@ -167,6 +167,10 @@ func (err ErrTaskDoesNotExist) Error() string {
err.ID, err.RepoID, err.Type) err.ID, err.RepoID, err.Type)
} }
func (err ErrTaskDoesNotExist) Unwrap() error {
return util.ErrNotExist
}
// GetMigratingTask returns the migrating task by repo's id // GetMigratingTask returns the migrating task by repo's id
func GetMigratingTask(repoID int64) (*Task, error) { func GetMigratingTask(repoID int64) (*Task, error) {
task := Task{ task := Task{

View File

@ -4,7 +4,11 @@
package asymkey package asymkey
import "fmt" import (
"fmt"
"code.gitea.io/gitea/modules/util"
)
// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error. // ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
type ErrKeyUnableVerify struct { type ErrKeyUnableVerify struct {
@ -36,6 +40,10 @@ func (err ErrKeyNotExist) Error() string {
return fmt.Sprintf("public key does not exist [id: %d]", err.ID) return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
} }
func (err ErrKeyNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error. // ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error.
type ErrKeyAlreadyExist struct { type ErrKeyAlreadyExist struct {
OwnerID int64 OwnerID int64
@ -54,6 +62,10 @@ func (err ErrKeyAlreadyExist) Error() string {
err.OwnerID, err.Fingerprint, err.Content) err.OwnerID, err.Fingerprint, err.Content)
} }
func (err ErrKeyAlreadyExist) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error. // ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
type ErrKeyNameAlreadyUsed struct { type ErrKeyNameAlreadyUsed struct {
OwnerID int64 OwnerID int64
@ -70,6 +82,10 @@ func (err ErrKeyNameAlreadyUsed) Error() string {
return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name) return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
} }
func (err ErrKeyNameAlreadyUsed) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error. // ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
type ErrGPGNoEmailFound struct { type ErrGPGNoEmailFound struct {
FailedEmails []string FailedEmails []string
@ -132,6 +148,10 @@ func (err ErrGPGKeyNotExist) Error() string {
return fmt.Sprintf("public gpg key does not exist [id: %d]", err.ID) return fmt.Sprintf("public gpg key does not exist [id: %d]", err.ID)
} }
func (err ErrGPGKeyNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrGPGKeyImportNotExist represents a "GPGKeyImportNotExist" kind of error. // ErrGPGKeyImportNotExist represents a "GPGKeyImportNotExist" kind of error.
type ErrGPGKeyImportNotExist struct { type ErrGPGKeyImportNotExist struct {
ID string ID string
@ -147,6 +167,10 @@ func (err ErrGPGKeyImportNotExist) Error() string {
return fmt.Sprintf("public gpg key import does not exist [id: %s]", err.ID) return fmt.Sprintf("public gpg key import does not exist [id: %s]", err.ID)
} }
func (err ErrGPGKeyImportNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error. // ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error.
type ErrGPGKeyIDAlreadyUsed struct { type ErrGPGKeyIDAlreadyUsed struct {
KeyID string KeyID string
@ -162,6 +186,10 @@ func (err ErrGPGKeyIDAlreadyUsed) Error() string {
return fmt.Sprintf("public key already exists [key_id: %s]", err.KeyID) return fmt.Sprintf("public key already exists [key_id: %s]", err.KeyID)
} }
func (err ErrGPGKeyIDAlreadyUsed) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error. // ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
type ErrGPGKeyAccessDenied struct { type ErrGPGKeyAccessDenied struct {
UserID int64 UserID int64
@ -180,6 +208,10 @@ func (err ErrGPGKeyAccessDenied) Error() string {
err.UserID, err.KeyID) err.UserID, err.KeyID)
} }
func (err ErrGPGKeyAccessDenied) Unwrap() error {
return util.ErrPermissionDenied
}
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error. // ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
type ErrKeyAccessDenied struct { type ErrKeyAccessDenied struct {
UserID int64 UserID int64
@ -198,6 +230,10 @@ func (err ErrKeyAccessDenied) Error() string {
err.UserID, err.KeyID, err.Note) err.UserID, err.KeyID, err.Note)
} }
func (err ErrKeyAccessDenied) Unwrap() error {
return util.ErrPermissionDenied
}
// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error. // ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
type ErrDeployKeyNotExist struct { type ErrDeployKeyNotExist struct {
ID int64 ID int64
@ -215,6 +251,10 @@ func (err ErrDeployKeyNotExist) Error() string {
return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID) return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
} }
func (err ErrDeployKeyNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error. // ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
type ErrDeployKeyAlreadyExist struct { type ErrDeployKeyAlreadyExist struct {
KeyID int64 KeyID int64
@ -231,6 +271,10 @@ func (err ErrDeployKeyAlreadyExist) Error() string {
return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID) return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
} }
func (err ErrDeployKeyAlreadyExist) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error. // ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
type ErrDeployKeyNameAlreadyUsed struct { type ErrDeployKeyNameAlreadyUsed struct {
RepoID int64 RepoID int64
@ -247,6 +291,10 @@ func (err ErrDeployKeyNameAlreadyUsed) Error() string {
return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name) return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
} }
func (err ErrDeployKeyNameAlreadyUsed) Unwrap() error {
return util.ErrNotExist
}
// ErrSSHInvalidTokenSignature represents a "ErrSSHInvalidTokenSignature" kind of error. // ErrSSHInvalidTokenSignature represents a "ErrSSHInvalidTokenSignature" kind of error.
type ErrSSHInvalidTokenSignature struct { type ErrSSHInvalidTokenSignature struct {
Wrapped error Wrapped error
@ -262,3 +310,7 @@ func IsErrSSHInvalidTokenSignature(err error) bool {
func (err ErrSSHInvalidTokenSignature) Error() string { func (err ErrSSHInvalidTokenSignature) Error() string {
return "the provided signature does not sign the token with the provided key" return "the provided signature does not sign the token with the provided key"
} }
func (err ErrSSHInvalidTokenSignature) Unwrap() error {
return util.ErrInvalidArgument
}

View File

@ -10,6 +10,7 @@ import (
"encoding/base32" "encoding/base32"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"net"
"net/url" "net/url"
"strings" "strings"
@ -56,6 +57,18 @@ func (app *OAuth2Application) PrimaryRedirectURI() string {
// ContainsRedirectURI checks if redirectURI is allowed for app // ContainsRedirectURI checks if redirectURI is allowed for app
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool { func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
uri, err := url.Parse(redirectURI)
// ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
if err == nil && uri.Scheme == "http" && uri.Port() != "" {
ip := net.ParseIP(uri.Hostname())
if ip != nil && ip.IsLoopback() {
// strip port
uri.Host = uri.Hostname()
if util.IsStringInSlice(uri.String(), app.RedirectURIs, true) {
return true
}
}
}
return util.IsStringInSlice(redirectURI, app.RedirectURIs, true) return util.IsStringInSlice(redirectURI, app.RedirectURIs, true)
} }
@ -212,7 +225,8 @@ func updateOAuth2Application(ctx context.Context, app *OAuth2Application) error
func deleteOAuth2Application(ctx context.Context, id, userid int64) error { func deleteOAuth2Application(ctx context.Context, id, userid int64) error {
sess := db.GetEngine(ctx) sess := db.GetEngine(ctx)
if deleted, err := sess.Delete(&OAuth2Application{ID: id, UID: userid}); err != nil { // the userid could be 0 if the app is instance-wide
if deleted, err := sess.Where(builder.Eq{"id": id, "uid": userid}).Delete(&OAuth2Application{}); err != nil {
return err return err
} else if deleted == 0 { } else if deleted == 0 {
return ErrOAuthApplicationNotFound{ID: id} return ErrOAuthApplicationNotFound{ID: id}
@ -463,7 +477,7 @@ func GetOAuth2GrantsByUserID(ctx context.Context, uid int64) ([]*OAuth2Grant, er
// RevokeOAuth2Grant deletes the grant with grantID and userID // RevokeOAuth2Grant deletes the grant with grantID and userID
func RevokeOAuth2Grant(ctx context.Context, grantID, userID int64) error { func RevokeOAuth2Grant(ctx context.Context, grantID, userID int64) error {
_, err := db.DeleteByBean(ctx, &OAuth2Grant{ID: grantID, UserID: userID}) _, err := db.GetEngine(ctx).Where(builder.Eq{"id": grantID, "user_id": userID}).Delete(&OAuth2Grant{})
return err return err
} }
@ -472,7 +486,7 @@ type ErrOAuthClientIDInvalid struct {
ClientID string ClientID string
} }
// IsErrOauthClientIDInvalid checks if an error is a ErrReviewNotExist. // IsErrOauthClientIDInvalid checks if an error is a ErrOAuthClientIDInvalid.
func IsErrOauthClientIDInvalid(err error) bool { func IsErrOauthClientIDInvalid(err error) bool {
_, ok := err.(ErrOAuthClientIDInvalid) _, ok := err.(ErrOAuthClientIDInvalid)
return ok return ok
@ -483,6 +497,11 @@ func (err ErrOAuthClientIDInvalid) Error() string {
return fmt.Sprintf("Client ID invalid [Client ID: %s]", err.ClientID) return fmt.Sprintf("Client ID invalid [Client ID: %s]", err.ClientID)
} }
// Unwrap unwraps this as a ErrNotExist err
func (err ErrOAuthClientIDInvalid) Unwrap() error {
return util.ErrNotExist
}
// ErrOAuthApplicationNotFound will be thrown if id cannot be found // ErrOAuthApplicationNotFound will be thrown if id cannot be found
type ErrOAuthApplicationNotFound struct { type ErrOAuthApplicationNotFound struct {
ID int64 ID int64
@ -499,6 +518,11 @@ func (err ErrOAuthApplicationNotFound) Error() string {
return fmt.Sprintf("OAuth application not found [ID: %d]", err.ID) return fmt.Sprintf("OAuth application not found [ID: %d]", err.ID)
} }
// Unwrap unwraps this as a ErrNotExist err
func (err ErrOAuthApplicationNotFound) Unwrap() error {
return util.ErrNotExist
}
// GetActiveOAuth2ProviderSources returns all actived LoginOAuth2 sources // GetActiveOAuth2ProviderSources returns all actived LoginOAuth2 sources
func GetActiveOAuth2ProviderSources() ([]*Source, error) { func GetActiveOAuth2ProviderSources() ([]*Source, error) {
sources := make([]*Source, 0, 1) sources := make([]*Source, 0, 1)

View File

@ -43,6 +43,26 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) {
assert.False(t, app.ContainsRedirectURI("d")) assert.False(t, app.ContainsRedirectURI("d"))
} }
func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
app := &auth_model.OAuth2Application{
RedirectURIs: []string{"http://127.0.0.1/", "http://::1/", "http://192.168.0.1/", "http://intranet/", "https://127.0.0.1/"},
}
// http loopback uris should ignore port
// https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1:3456/"))
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
assert.True(t, app.ContainsRedirectURI("http://[::1]:3456/"))
// not http
assert.False(t, app.ContainsRedirectURI("https://127.0.0.1:3456/"))
// not loopback
assert.False(t, app.ContainsRedirectURI("http://192.168.0.1:9954/"))
assert.False(t, app.ContainsRedirectURI("http://intranet:3456/"))
// unparseable
assert.False(t, app.ContainsRedirectURI(":"))
}
func TestOAuth2Application_ValidateClientSecret(t *testing.T) { func TestOAuth2Application_ValidateClientSecret(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})

View File

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/xorm" "xorm.io/xorm"
"xorm.io/xorm/convert" "xorm.io/xorm/convert"
@ -372,6 +373,11 @@ func (err ErrSourceNotExist) Error() string {
return fmt.Sprintf("login source does not exist [id: %d]", err.ID) return fmt.Sprintf("login source does not exist [id: %d]", err.ID)
} }
// Unwrap unwraps this as a ErrNotExist err
func (err ErrSourceNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrSourceAlreadyExist represents a "SourceAlreadyExist" kind of error. // ErrSourceAlreadyExist represents a "SourceAlreadyExist" kind of error.
type ErrSourceAlreadyExist struct { type ErrSourceAlreadyExist struct {
Name string Name string
@ -387,6 +393,11 @@ func (err ErrSourceAlreadyExist) Error() string {
return fmt.Sprintf("login source already exists [name: %s]", err.Name) return fmt.Sprintf("login source already exists [name: %s]", err.Name)
} }
// Unwrap unwraps this as a ErrExist err
func (err ErrSourceAlreadyExist) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrSourceInUse represents a "SourceInUse" kind of error. // ErrSourceInUse represents a "SourceInUse" kind of error.
type ErrSourceInUse struct { type ErrSourceInUse struct {
ID int64 ID int64

View File

@ -35,6 +35,10 @@ func (err ErrAccessTokenNotExist) Error() string {
return fmt.Sprintf("access token does not exist [sha: %s]", err.Token) return fmt.Sprintf("access token does not exist [sha: %s]", err.Token)
} }
func (err ErrAccessTokenNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error. // ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error.
type ErrAccessTokenEmpty struct{} type ErrAccessTokenEmpty struct{}
@ -48,6 +52,10 @@ func (err ErrAccessTokenEmpty) Error() string {
return "access token is empty" return "access token is empty"
} }
func (err ErrAccessTokenEmpty) Unwrap() error {
return util.ErrInvalidArgument
}
var successfulAccessTokenCache *lru.Cache var successfulAccessTokenCache *lru.Cache
// AccessToken represents a personal access token. // AccessToken represents a personal access token.

View File

@ -41,6 +41,11 @@ func (err ErrTwoFactorNotEnrolled) Error() string {
return fmt.Sprintf("user not enrolled in 2FA [uid: %d]", err.UID) return fmt.Sprintf("user not enrolled in 2FA [uid: %d]", err.UID)
} }
// Unwrap unwraps this as a ErrNotExist err
func (err ErrTwoFactorNotEnrolled) Unwrap() error {
return util.ErrNotExist
}
// TwoFactor represents a two-factor authentication token. // TwoFactor represents a two-factor authentication token.
type TwoFactor struct { type TwoFactor struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`

View File

@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"github.com/duo-labs/webauthn/webauthn" "github.com/duo-labs/webauthn/webauthn"
"xorm.io/xorm" "xorm.io/xorm"
@ -29,6 +30,11 @@ func (err ErrWebAuthnCredentialNotExist) Error() string {
return fmt.Sprintf("WebAuthn credential does not exist [credential_id: %x]", err.CredentialID) return fmt.Sprintf("WebAuthn credential does not exist [credential_id: %x]", err.CredentialID)
} }
// Unwrap unwraps this as a ErrNotExist err
func (err ErrWebAuthnCredentialNotExist) Unwrap() error {
return util.ErrNotExist
}
// IsErrWebAuthnCredentialNotExist checks if an error is a ErrWebAuthnCredentialNotExist. // IsErrWebAuthnCredentialNotExist checks if an error is a ErrWebAuthnCredentialNotExist.
func IsErrWebAuthnCredentialNotExist(err error) bool { func IsErrWebAuthnCredentialNotExist(err error) bool {
_, ok := err.(ErrWebAuthnCredentialNotExist) _, ok := err.(ErrWebAuthnCredentialNotExist)

View File

@ -13,6 +13,7 @@ import (
"sync" "sync"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -72,7 +73,7 @@ func GetEmailForHash(md5Sum string) (string, error) {
// LibravatarURL returns the URL for the given email. Slow due to the DNS lookup. // LibravatarURL returns the URL for the given email. Slow due to the DNS lookup.
// This function should only be called if a federated avatar service is enabled. // This function should only be called if a federated avatar service is enabled.
func LibravatarURL(email string) (*url.URL, error) { func LibravatarURL(email string) (*url.URL, error) {
urlStr, err := setting.LibravatarService.FromEmail(email) urlStr, err := system_model.LibravatarService.FromEmail(email)
if err != nil { if err != nil {
log.Error("LibravatarService.FromEmail(email=%s): error %v", email, err) log.Error("LibravatarService.FromEmail(email=%s): error %v", email, err)
return nil, err return nil, err
@ -149,8 +150,10 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
return DefaultAvatarLink() return DefaultAvatarLink()
} }
enableFederatedAvatar, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar)
var err error var err error
if setting.EnableFederatedAvatar && setting.LibravatarService != nil { if enableFederatedAvatar != nil && enableFederatedAvatar.GetValueBool() && system_model.LibravatarService != nil {
emailHash := saveEmailHash(email) emailHash := saveEmailHash(email)
if final { if final {
// for final link, we can spend more time on slow external query // for final link, we can spend more time on slow external query
@ -166,12 +169,16 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
urlStr += "?size=" + strconv.Itoa(size) urlStr += "?size=" + strconv.Itoa(size)
} }
return urlStr return urlStr
} else if !setting.DisableGravatar { }
disableGravatar, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar)
if disableGravatar != nil && !disableGravatar.GetValueBool() {
// copy GravatarSourceURL, because we will modify its Path. // copy GravatarSourceURL, because we will modify its Path.
avatarURLCopy := *setting.GravatarSourceURL avatarURLCopy := *system_model.GravatarSourceURL
avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email)) avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email))
return generateRecognizedAvatarURL(avatarURLCopy, size) return generateRecognizedAvatarURL(avatarURLCopy, size)
} }
return DefaultAvatarLink() return DefaultAvatarLink()
} }

View File

@ -2,12 +2,13 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package avatars package avatars_test
import ( import (
"net/url"
"testing" "testing"
avatars_model "code.gitea.io/gitea/models/avatars"
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -15,40 +16,43 @@ import (
const gravatarSource = "https://secure.gravatar.com/avatar/" const gravatarSource = "https://secure.gravatar.com/avatar/"
func disableGravatar() { func disableGravatar(t *testing.T) {
setting.EnableFederatedAvatar = false err := system_model.SetSettingNoVersion(system_model.KeyPictureEnableFederatedAvatar, "false")
setting.LibravatarService = nil assert.NoError(t, err)
setting.DisableGravatar = true err = system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "true")
assert.NoError(t, err)
system_model.LibravatarService = nil
} }
func enableGravatar(t *testing.T) { func enableGravatar(t *testing.T) {
setting.DisableGravatar = false err := system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "false")
var err error assert.NoError(t, err)
setting.GravatarSourceURL, err = url.Parse(gravatarSource) setting.GravatarSource = gravatarSource
err = system_model.Init()
assert.NoError(t, err) assert.NoError(t, err)
} }
func TestHashEmail(t *testing.T) { func TestHashEmail(t *testing.T) {
assert.Equal(t, assert.Equal(t,
"d41d8cd98f00b204e9800998ecf8427e", "d41d8cd98f00b204e9800998ecf8427e",
HashEmail(""), avatars_model.HashEmail(""),
) )
assert.Equal(t, assert.Equal(t,
"353cbad9b58e69c96154ad99f92bedc7", "353cbad9b58e69c96154ad99f92bedc7",
HashEmail("gitea@example.com"), avatars_model.HashEmail("gitea@example.com"),
) )
} }
func TestSizedAvatarLink(t *testing.T) { func TestSizedAvatarLink(t *testing.T) {
setting.AppSubURL = "/testsuburl" setting.AppSubURL = "/testsuburl"
disableGravatar() disableGravatar(t)
assert.Equal(t, "/testsuburl/assets/img/avatar_default.png", assert.Equal(t, "/testsuburl/assets/img/avatar_default.png",
GenerateEmailAvatarFastLink("gitea@example.com", 100)) avatars_model.GenerateEmailAvatarFastLink("gitea@example.com", 100))
enableGravatar(t) enableGravatar(t)
assert.Equal(t, assert.Equal(t,
"https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100", "https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100",
GenerateEmailAvatarFastLink("gitea@example.com", 100), avatars_model.GenerateEmailAvatarFastLink("gitea@example.com", 100),
) )
} }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package admin_test package avatars_test
import ( import (
"path/filepath" "path/filepath"

View File

@ -225,7 +225,7 @@ func NamesToBean(names ...string) ([]interface{}, error) {
for _, name := range names { for _, name := range names {
bean, ok := beanMap[strings.ToLower(strings.TrimSpace(name))] bean, ok := beanMap[strings.ToLower(strings.TrimSpace(name))]
if !ok { if !ok {
return nil, fmt.Errorf("No table found that matches: %s", name) return nil, fmt.Errorf("no table found that matches: %s", name)
} }
if !gotBean[bean] { if !gotBean[bean] {
beans = append(beans, bean) beans = append(beans, bean)

View File

@ -6,6 +6,8 @@ package db
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/util"
) )
// ErrCancelled represents an error due to context cancellation // ErrCancelled represents an error due to context cancellation
@ -45,7 +47,8 @@ func (err ErrSSHDisabled) Error() string {
// ErrNotExist represents a non-exist error. // ErrNotExist represents a non-exist error.
type ErrNotExist struct { type ErrNotExist struct {
ID int64 Resource string
ID int64
} }
// IsErrNotExist checks if an error is an ErrNotExist // IsErrNotExist checks if an error is an ErrNotExist
@ -55,5 +58,18 @@ func IsErrNotExist(err error) bool {
} }
func (err ErrNotExist) Error() string { func (err ErrNotExist) Error() string {
return fmt.Sprintf("record does not exist [id: %d]", err.ID) name := "record"
if err.Resource != "" {
name = err.Resource
}
if err.ID != 0 {
return fmt.Sprintf("%s does not exist [id: %d]", name, err.ID)
}
return fmt.Sprintf("%s does not exist", name)
}
// Unwrap unwraps this as a ErrNotExist err
func (err ErrNotExist) Unwrap() error {
return util.ErrNotExist
} }

View File

@ -8,45 +8,15 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"code.gitea.io/gitea/modules/setting"
) )
// ResourceIndex represents a resource index which could be used as issue/release and others // ResourceIndex represents a resource index which could be used as issue/release and others
// We can create different tables i.e. issue_index, release_index and etc. // We can create different tables i.e. issue_index, release_index, etc.
type ResourceIndex struct { type ResourceIndex struct {
GroupID int64 `xorm:"pk"` GroupID int64 `xorm:"pk"`
MaxIndex int64 `xorm:"index"` MaxIndex int64 `xorm:"index"`
} }
// UpsertResourceIndex the function will not return until it acquires the lock or receives an error.
func UpsertResourceIndex(ctx context.Context, tableName string, groupID int64) (err error) {
// An atomic UPSERT operation (INSERT/UPDATE) is the only operation
// that ensures that the key is actually locked.
switch {
case setting.Database.UseSQLite3 || setting.Database.UsePostgreSQL:
_, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+
"VALUES (?,1) ON CONFLICT (group_id) DO UPDATE SET max_index = %s.max_index+1",
tableName, tableName), groupID)
case setting.Database.UseMySQL:
_, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+
"VALUES (?,1) ON DUPLICATE KEY UPDATE max_index = max_index+1", tableName),
groupID)
case setting.Database.UseMSSQL:
// https://weblogs.sqlteam.com/dang/2009/01/31/upsert-race-condition-with-merge/
_, err = Exec(ctx, fmt.Sprintf("MERGE %s WITH (HOLDLOCK) as target "+
"USING (SELECT ? AS group_id) AS src "+
"ON src.group_id = target.group_id "+
"WHEN MATCHED THEN UPDATE SET target.max_index = target.max_index+1 "+
"WHEN NOT MATCHED THEN INSERT (group_id, max_index) "+
"VALUES (src.group_id, 1);", tableName),
groupID)
default:
return fmt.Errorf("database type not supported")
}
return err
}
var ( var (
// ErrResouceOutdated represents an error when request resource outdated // ErrResouceOutdated represents an error when request resource outdated
ErrResouceOutdated = errors.New("resource outdated") ErrResouceOutdated = errors.New("resource outdated")
@ -59,53 +29,85 @@ const (
MaxDupIndexAttempts = 3 MaxDupIndexAttempts = 3
) )
// GetNextResourceIndex retried 3 times to generate a resource index // SyncMaxResourceIndex sync the max index with the resource
func GetNextResourceIndex(tableName string, groupID int64) (int64, error) { func SyncMaxResourceIndex(ctx context.Context, tableName string, groupID, maxIndex int64) (err error) {
for i := 0; i < MaxDupIndexAttempts; i++ { e := GetEngine(ctx)
idx, err := getNextResourceIndex(tableName, groupID)
if err == ErrResouceOutdated { // try to update the max_index and acquire the write-lock for the record
continue res, err := e.Exec(fmt.Sprintf("UPDATE %s SET max_index=? WHERE group_id=? AND max_index<?", tableName), maxIndex, groupID, maxIndex)
} if err != nil {
if err != nil { return err
return 0, err
}
return idx, nil
} }
return 0, ErrGetResourceIndexFailed affected, err := res.RowsAffected()
if err != nil {
return err
}
if affected == 0 {
// if nothing is updated, the record might not exist or might be larger, it's safe to try to insert it again and then check whether the record exists
_, errIns := e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) VALUES (?, ?)", tableName), groupID, maxIndex)
var savedIdx int64
has, err := e.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id=?", tableName), groupID).Get(&savedIdx)
if err != nil {
return err
}
// if the record still doesn't exist, there must be some errors (insert error)
if !has {
if errIns == nil {
return errors.New("impossible error when SyncMaxResourceIndex, insert succeeded but no record is saved")
}
return errIns
}
}
return nil
} }
// DeleteResouceIndex delete resource index // GetNextResourceIndex generates a resource index, it must run in the same transaction where the resource is created
func DeleteResouceIndex(ctx context.Context, tableName string, groupID int64) error { func GetNextResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
_, err := Exec(ctx, fmt.Sprintf("DELETE FROM %s WHERE group_id=?", tableName), groupID) e := GetEngine(ctx)
return err
}
// getNextResourceIndex return the next index // try to update the max_index to next value, and acquire the write-lock for the record
func getNextResourceIndex(tableName string, groupID int64) (int64, error) { res, err := e.Exec(fmt.Sprintf("UPDATE %s SET max_index=max_index+1 WHERE group_id=?", tableName), groupID)
ctx, commiter, err := TxContext()
if err != nil { if err != nil {
return 0, err return 0, err
} }
defer commiter.Close() affected, err := res.RowsAffected()
var preIdx int64 if err != nil {
if _, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&preIdx); err != nil {
return 0, err return 0, err
} }
if affected == 0 {
if err := UpsertResourceIndex(ctx, tableName, groupID); err != nil { // this slow path is only for the first time of creating a resource index
return 0, err _, errIns := e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) VALUES (?, 0)", tableName), groupID)
res, err = e.Exec(fmt.Sprintf("UPDATE %s SET max_index=max_index+1 WHERE group_id=?", tableName), groupID)
if err != nil {
return 0, err
}
affected, err = res.RowsAffected()
if err != nil {
return 0, err
}
// if the update still can not update any records, the record must not exist and there must be some errors (insert error)
if affected == 0 {
if errIns == nil {
return 0, errors.New("impossible error when GetNextResourceIndex, insert and update both succeeded but no record is updated")
}
return 0, errIns
}
} }
var curIdx int64 // now, the new index is in database (protected by the transaction and write-lock)
has, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ? AND max_index=?", tableName), groupID, preIdx+1).Get(&curIdx) var newIdx int64
has, err := e.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id=?", tableName), groupID).Get(&newIdx)
if err != nil { if err != nil {
return 0, err return 0, err
} }
if !has { if !has {
return 0, ErrResouceOutdated return 0, errors.New("impossible error when GetNextResourceIndex, upsert succeeded but no record can be selected")
} }
if err := commiter.Commit(); err != nil { return newIdx, nil
return 0, err }
}
return curIdx, nil // DeleteResourceIndex delete resource index
func DeleteResourceIndex(ctx context.Context, tableName string, groupID int64) error {
_, err := Exec(ctx, fmt.Sprintf("DELETE FROM %s WHERE group_id=?", tableName), groupID)
return err
} }

127
models/db/index_test.go Normal file
View File

@ -0,0 +1,127 @@
// 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 db_test
import (
"context"
"errors"
"fmt"
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
)
type TestIndex db.ResourceIndex
func getCurrentResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
e := db.GetEngine(ctx)
var idx int64
has, err := e.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id=?", tableName), groupID).Get(&idx)
if err != nil {
return 0, err
}
if !has {
return 0, errors.New("no record")
}
return idx, nil
}
func TestSyncMaxResourceIndex(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
xe := unittest.GetXORMEngine()
assert.NoError(t, xe.Sync(&TestIndex{}))
err := db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 51)
assert.NoError(t, err)
// sync new max index
maxIndex, err := getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 51, maxIndex)
// smaller index doesn't change
err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 30)
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 51, maxIndex)
// larger index changes
err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 62)
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 62, maxIndex)
// commit transaction
err = db.WithTx(func(ctx context.Context) error {
err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 73)
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 73, maxIndex)
return nil
})
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 73, maxIndex)
// rollback transaction
err = db.WithTx(func(ctx context.Context) error {
err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 84)
maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 84, maxIndex)
return errors.New("test rollback")
})
assert.Error(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 73, maxIndex) // the max index doesn't change because the transaction was rolled back
}
func TestGetNextResourceIndex(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
xe := unittest.GetXORMEngine()
assert.NoError(t, xe.Sync(&TestIndex{}))
// create a new record
maxIndex, err := db.GetNextResourceIndex(db.DefaultContext, "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 1, maxIndex)
// increase the existing record
maxIndex, err = db.GetNextResourceIndex(db.DefaultContext, "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 2, maxIndex)
// commit transaction
err = db.WithTx(func(ctx context.Context) error {
maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 3, maxIndex)
return nil
})
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 3, maxIndex)
// rollback transaction
err = db.WithTx(func(ctx context.Context) error {
maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 4, maxIndex)
return errors.New("test rollback")
})
assert.Error(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 3, maxIndex) // the max index doesn't change because the transaction was rolled back
}

View File

@ -5,16 +5,17 @@
package db package db
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
"strings" "strings"
"unicode/utf8" "unicode/utf8"
"code.gitea.io/gitea/modules/util"
) )
var ( var (
// ErrNameEmpty name is empty error // ErrNameEmpty name is empty error
ErrNameEmpty = errors.New("Name is empty") ErrNameEmpty = util.SilentWrap{Message: "name is empty", Err: util.ErrInvalidArgument}
// AlphaDashDotPattern characters prohibited in a user name (anything except A-Za-z0-9_.-) // AlphaDashDotPattern characters prohibited in a user name (anything except A-Za-z0-9_.-)
AlphaDashDotPattern = regexp.MustCompile(`[^\w-\.@]`) // Ugly hack to allow remote usernames to contain @ AlphaDashDotPattern = regexp.MustCompile(`[^\w-\.@]`) // Ugly hack to allow remote usernames to contain @
@ -35,6 +36,11 @@ func (err ErrNameReserved) Error() string {
return fmt.Sprintf("name is reserved [name: %s]", err.Name) return fmt.Sprintf("name is reserved [name: %s]", err.Name)
} }
// Unwrap unwraps this as a ErrInvalid err
func (err ErrNameReserved) Unwrap() error {
return util.ErrInvalidArgument
}
// ErrNamePatternNotAllowed represents a "pattern not allowed" error. // ErrNamePatternNotAllowed represents a "pattern not allowed" error.
type ErrNamePatternNotAllowed struct { type ErrNamePatternNotAllowed struct {
Pattern string Pattern string
@ -50,6 +56,11 @@ func (err ErrNamePatternNotAllowed) Error() string {
return fmt.Sprintf("name pattern is not allowed [pattern: %s]", err.Pattern) return fmt.Sprintf("name pattern is not allowed [pattern: %s]", err.Pattern)
} }
// Unwrap unwraps this as a ErrInvalid err
func (err ErrNamePatternNotAllowed) Unwrap() error {
return util.ErrInvalidArgument
}
// ErrNameCharsNotAllowed represents a "character not allowed in name" error. // ErrNameCharsNotAllowed represents a "character not allowed in name" error.
type ErrNameCharsNotAllowed struct { type ErrNameCharsNotAllowed struct {
Name string Name string
@ -62,7 +73,12 @@ func IsErrNameCharsNotAllowed(err error) bool {
} }
func (err ErrNameCharsNotAllowed) Error() string { func (err ErrNameCharsNotAllowed) Error() string {
return fmt.Sprintf("User name is invalid [%s]: must be valid alpha or numeric or dash(-_) or dot characters", err.Name) return fmt.Sprintf("name is invalid [%s]: must be valid alpha or numeric or dash(-_) or dot characters", err.Name)
}
// Unwrap unwraps this as a ErrInvalid err
func (err ErrNameCharsNotAllowed) Unwrap() error {
return util.ErrInvalidArgument
} }
// IsUsableName checks if name is reserved or pattern of name is not allowed // IsUsableName checks if name is reserved or pattern of name is not allowed

View File

@ -10,6 +10,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/util"
) )
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error. // ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
@ -63,8 +64,8 @@ type ErrNoPendingRepoTransfer struct {
RepoID int64 RepoID int64
} }
func (e ErrNoPendingRepoTransfer) Error() string { func (err ErrNoPendingRepoTransfer) Error() string {
return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", e.RepoID) return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", err.RepoID)
} }
// IsErrNoPendingTransfer is an error type when a repository has no pending // IsErrNoPendingTransfer is an error type when a repository has no pending
@ -74,6 +75,10 @@ func IsErrNoPendingTransfer(err error) bool {
return ok return ok
} }
func (err ErrNoPendingRepoTransfer) Unwrap() error {
return util.ErrNotExist
}
// ErrRepoTransferInProgress represents the state of a repository that has an // ErrRepoTransferInProgress represents the state of a repository that has an
// ongoing transfer // ongoing transfer
type ErrRepoTransferInProgress struct { type ErrRepoTransferInProgress struct {
@ -91,6 +96,10 @@ func (err ErrRepoTransferInProgress) Error() string {
return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name) return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name)
} }
func (err ErrRepoTransferInProgress) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error. // ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
type ErrInvalidCloneAddr struct { type ErrInvalidCloneAddr struct {
Host string Host string
@ -124,6 +133,10 @@ func (err *ErrInvalidCloneAddr) Error() string {
return fmt.Sprintf("migration/cloning from '%s' is not allowed", err.Host) return fmt.Sprintf("migration/cloning from '%s' is not allowed", err.Host)
} }
func (err *ErrInvalidCloneAddr) Unwrap() error {
return util.ErrInvalidArgument
}
// ErrUpdateTaskNotExist represents a "UpdateTaskNotExist" kind of error. // ErrUpdateTaskNotExist represents a "UpdateTaskNotExist" kind of error.
type ErrUpdateTaskNotExist struct { type ErrUpdateTaskNotExist struct {
UUID string UUID string
@ -139,6 +152,10 @@ func (err ErrUpdateTaskNotExist) Error() string {
return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID) return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID)
} }
func (err ErrUpdateTaskNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrInvalidTagName represents a "InvalidTagName" kind of error. // ErrInvalidTagName represents a "InvalidTagName" kind of error.
type ErrInvalidTagName struct { type ErrInvalidTagName struct {
TagName string TagName string
@ -154,6 +171,10 @@ func (err ErrInvalidTagName) Error() string {
return fmt.Sprintf("release tag name is not valid [tag_name: %s]", err.TagName) return fmt.Sprintf("release tag name is not valid [tag_name: %s]", err.TagName)
} }
func (err ErrInvalidTagName) Unwrap() error {
return util.ErrInvalidArgument
}
// ErrProtectedTagName represents a "ProtectedTagName" kind of error. // ErrProtectedTagName represents a "ProtectedTagName" kind of error.
type ErrProtectedTagName struct { type ErrProtectedTagName struct {
TagName string TagName string
@ -169,6 +190,10 @@ func (err ErrProtectedTagName) Error() string {
return fmt.Sprintf("release tag name is protected [tag_name: %s]", err.TagName) return fmt.Sprintf("release tag name is protected [tag_name: %s]", err.TagName)
} }
func (err ErrProtectedTagName) Unwrap() error {
return util.ErrPermissionDenied
}
// ErrRepoFileAlreadyExists represents a "RepoFileAlreadyExist" kind of error. // ErrRepoFileAlreadyExists represents a "RepoFileAlreadyExist" kind of error.
type ErrRepoFileAlreadyExists struct { type ErrRepoFileAlreadyExists struct {
Path string Path string
@ -184,6 +209,10 @@ func (err ErrRepoFileAlreadyExists) Error() string {
return fmt.Sprintf("repository file already exists [path: %s]", err.Path) return fmt.Sprintf("repository file already exists [path: %s]", err.Path)
} }
func (err ErrRepoFileAlreadyExists) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrRepoFileDoesNotExist represents a "RepoFileDoesNotExist" kind of error. // ErrRepoFileDoesNotExist represents a "RepoFileDoesNotExist" kind of error.
type ErrRepoFileDoesNotExist struct { type ErrRepoFileDoesNotExist struct {
Path string Path string
@ -200,6 +229,10 @@ func (err ErrRepoFileDoesNotExist) Error() string {
return fmt.Sprintf("repository file does not exist [path: %s]", err.Path) return fmt.Sprintf("repository file does not exist [path: %s]", err.Path)
} }
func (err ErrRepoFileDoesNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrFilenameInvalid represents a "FilenameInvalid" kind of error. // ErrFilenameInvalid represents a "FilenameInvalid" kind of error.
type ErrFilenameInvalid struct { type ErrFilenameInvalid struct {
Path string Path string
@ -215,6 +248,10 @@ func (err ErrFilenameInvalid) Error() string {
return fmt.Sprintf("path contains a malformed path component [path: %s]", err.Path) return fmt.Sprintf("path contains a malformed path component [path: %s]", err.Path)
} }
func (err ErrFilenameInvalid) Unwrap() error {
return util.ErrInvalidArgument
}
// ErrUserCannotCommit represents "UserCannotCommit" kind of error. // ErrUserCannotCommit represents "UserCannotCommit" kind of error.
type ErrUserCannotCommit struct { type ErrUserCannotCommit struct {
UserName string UserName string
@ -230,6 +267,10 @@ func (err ErrUserCannotCommit) Error() string {
return fmt.Sprintf("user cannot commit to repo [user: %s]", err.UserName) return fmt.Sprintf("user cannot commit to repo [user: %s]", err.UserName)
} }
func (err ErrUserCannotCommit) Unwrap() error {
return util.ErrPermissionDenied
}
// ErrFilePathInvalid represents a "FilePathInvalid" kind of error. // ErrFilePathInvalid represents a "FilePathInvalid" kind of error.
type ErrFilePathInvalid struct { type ErrFilePathInvalid struct {
Message string Message string
@ -251,6 +292,10 @@ func (err ErrFilePathInvalid) Error() string {
return fmt.Sprintf("path is invalid [path: %s]", err.Path) return fmt.Sprintf("path is invalid [path: %s]", err.Path)
} }
func (err ErrFilePathInvalid) Unwrap() error {
return util.ErrInvalidArgument
}
// ErrFilePathProtected represents a "FilePathProtected" kind of error. // ErrFilePathProtected represents a "FilePathProtected" kind of error.
type ErrFilePathProtected struct { type ErrFilePathProtected struct {
Message string Message string
@ -270,6 +315,10 @@ func (err ErrFilePathProtected) Error() string {
return fmt.Sprintf("path is protected and can not be changed [path: %s]", err.Path) return fmt.Sprintf("path is protected and can not be changed [path: %s]", err.Path)
} }
func (err ErrFilePathProtected) Unwrap() error {
return util.ErrPermissionDenied
}
// __________ .__ // __________ .__
// \______ \____________ ____ ____ | |__ // \______ \____________ ____ ____ | |__
// | | _/\_ __ \__ \ / \_/ ___\| | \ // | | _/\_ __ \__ \ / \_/ ___\| | \
@ -292,6 +341,10 @@ func (err ErrBranchDoesNotExist) Error() string {
return fmt.Sprintf("branch does not exist [name: %s]", err.BranchName) return fmt.Sprintf("branch does not exist [name: %s]", err.BranchName)
} }
func (err ErrBranchDoesNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrBranchAlreadyExists represents an error that branch with such name already exists. // ErrBranchAlreadyExists represents an error that branch with such name already exists.
type ErrBranchAlreadyExists struct { type ErrBranchAlreadyExists struct {
BranchName string BranchName string
@ -307,6 +360,10 @@ func (err ErrBranchAlreadyExists) Error() string {
return fmt.Sprintf("branch already exists [name: %s]", err.BranchName) return fmt.Sprintf("branch already exists [name: %s]", err.BranchName)
} }
func (err ErrBranchAlreadyExists) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrBranchNameConflict represents an error that branch name conflicts with other branch. // ErrBranchNameConflict represents an error that branch name conflicts with other branch.
type ErrBranchNameConflict struct { type ErrBranchNameConflict struct {
BranchName string BranchName string
@ -322,6 +379,10 @@ func (err ErrBranchNameConflict) Error() string {
return fmt.Sprintf("branch conflicts with existing branch [name: %s]", err.BranchName) return fmt.Sprintf("branch conflicts with existing branch [name: %s]", err.BranchName)
} }
func (err ErrBranchNameConflict) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrBranchesEqual represents an error that branch name conflicts with other branch. // ErrBranchesEqual represents an error that branch name conflicts with other branch.
type ErrBranchesEqual struct { type ErrBranchesEqual struct {
BaseBranchName string BaseBranchName string
@ -338,6 +399,10 @@ func (err ErrBranchesEqual) Error() string {
return fmt.Sprintf("branches are equal [head: %sm base: %s]", err.HeadBranchName, err.BaseBranchName) return fmt.Sprintf("branches are equal [head: %sm base: %s]", err.HeadBranchName, err.BaseBranchName)
} }
func (err ErrBranchesEqual) Unwrap() error {
return util.ErrInvalidArgument
}
// ErrDisallowedToMerge represents an error that a branch is protected and the current user is not allowed to modify it. // ErrDisallowedToMerge represents an error that a branch is protected and the current user is not allowed to modify it.
type ErrDisallowedToMerge struct { type ErrDisallowedToMerge struct {
Reason string Reason string
@ -353,6 +418,10 @@ func (err ErrDisallowedToMerge) Error() string {
return fmt.Sprintf("not allowed to merge [reason: %s]", err.Reason) return fmt.Sprintf("not allowed to merge [reason: %s]", err.Reason)
} }
func (err ErrDisallowedToMerge) Unwrap() error {
return util.ErrPermissionDenied
}
// ErrTagAlreadyExists represents an error that tag with such name already exists. // ErrTagAlreadyExists represents an error that tag with such name already exists.
type ErrTagAlreadyExists struct { type ErrTagAlreadyExists struct {
TagName string TagName string
@ -368,6 +437,10 @@ func (err ErrTagAlreadyExists) Error() string {
return fmt.Sprintf("tag already exists [name: %s]", err.TagName) return fmt.Sprintf("tag already exists [name: %s]", err.TagName)
} }
func (err ErrTagAlreadyExists) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrSHADoesNotMatch represents a "SHADoesNotMatch" kind of error. // ErrSHADoesNotMatch represents a "SHADoesNotMatch" kind of error.
type ErrSHADoesNotMatch struct { type ErrSHADoesNotMatch struct {
Path string Path string
@ -400,6 +473,10 @@ func (err ErrSHANotFound) Error() string {
return fmt.Sprintf("sha not found [%s]", err.SHA) return fmt.Sprintf("sha not found [%s]", err.SHA)
} }
func (err ErrSHANotFound) Unwrap() error {
return util.ErrNotExist
}
// ErrCommitIDDoesNotMatch represents a "CommitIDDoesNotMatch" kind of error. // ErrCommitIDDoesNotMatch represents a "CommitIDDoesNotMatch" kind of error.
type ErrCommitIDDoesNotMatch struct { type ErrCommitIDDoesNotMatch struct {
GivenCommitID string GivenCommitID string
@ -446,6 +523,10 @@ func (err ErrInvalidMergeStyle) Error() string {
err.ID, err.Style) err.ID, err.Style)
} }
func (err ErrInvalidMergeStyle) Unwrap() error {
return util.ErrInvalidArgument
}
// ErrMergeConflicts represents an error if merging fails with a conflict // ErrMergeConflicts represents an error if merging fails with a conflict
type ErrMergeConflicts struct { type ErrMergeConflicts struct {
Style repo_model.MergeStyle Style repo_model.MergeStyle

View File

@ -3,9 +3,12 @@
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
repo_id: 1 repo_id: 1
issue_id: 1 issue_id: 1
release_id: 0
uploader_id: 0
comment_id: 0 comment_id: 0
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800
- -
@ -13,9 +16,12 @@
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12
repo_id: 2 repo_id: 2
issue_id: 4 issue_id: 4
release_id: 0
uploader_id: 0
comment_id: 0 comment_id: 0
name: attach2 name: attach2
download_count: 1 download_count: 1
size: 0
created_unix: 946684800 created_unix: 946684800
- -
@ -23,9 +29,12 @@
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a13 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a13
repo_id: 1 repo_id: 1
issue_id: 2 issue_id: 2
release_id: 0
uploader_id: 0
comment_id: 1 comment_id: 1
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800
- -
@ -33,9 +42,12 @@
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14
repo_id: 1 repo_id: 1
issue_id: 3 issue_id: 3
release_id: 0
uploader_id: 0
comment_id: 1 comment_id: 1
name: attach2 name: attach2
download_count: 1 download_count: 1
size: 0
created_unix: 946684800 created_unix: 946684800
- -
@ -43,9 +55,12 @@
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a15 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a15
repo_id: 2 repo_id: 2
issue_id: 4 issue_id: 4
release_id: 0
uploader_id: 0
comment_id: 0 comment_id: 0
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800
- -
@ -53,9 +68,12 @@
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a16 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a16
repo_id: 1 repo_id: 1
issue_id: 5 issue_id: 5
release_id: 0
uploader_id: 0
comment_id: 2 comment_id: 2
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800
- -
@ -63,9 +81,12 @@
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17
repo_id: 1 repo_id: 1
issue_id: 5 issue_id: 5
release_id: 0
uploader_id: 0
comment_id: 2 comment_id: 2
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800
- -
@ -73,34 +94,49 @@
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18
repo_id: 3 repo_id: 3
issue_id: 6 issue_id: 6
release_id: 0
uploader_id: 0
comment_id: 0 comment_id: 0
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800
- -
id: 9 id: 9
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a19 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a19
repo_id: 1 repo_id: 1
issue_id: 0
release_id: 1 release_id: 1
uploader_id: 0
comment_id: 0
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800
- -
id: 10 id: 10
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a20 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a20
repo_id: 0 # TestGetAttachment/NotLinked repo_id: 0 # TestGetAttachment/NotLinked
issue_id: 0
release_id: 0
uploader_id: 8 uploader_id: 8
comment_id: 0
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800
- -
id: 11 id: 11
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a21 uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a21
repo_id: 40 repo_id: 40
issue_id: 0
release_id: 2 release_id: 2
uploader_id: 0
comment_id: 0
name: attach1 name: attach1
download_count: 0 download_count: 0
size: 0
created_unix: 946684800 created_unix: 946684800

View File

@ -3,208 +3,287 @@
repo_id: 1 repo_id: 1
index: 1 index: 1
poster_id: 1 poster_id: 1
original_author_id: 0
name: issue1 name: issue1
content: content for the first issue content: content for the first issue
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 2 num_comments: 2
created_unix: 946684800 created_unix: 946684800
updated_unix: 978307200 updated_unix: 978307200
is_locked: false
- -
id: 2 id: 2
repo_id: 1 repo_id: 1
index: 2 index: 2
poster_id: 1 poster_id: 1
original_author_id: 0
name: issue2 name: issue2
content: content for the second issue content: content for the second issue
milestone_id: 1 milestone_id: 1
priority: 0
is_closed: false is_closed: false
is_pull: true is_pull: true
num_comments: 0
created_unix: 946684810 created_unix: 946684810
updated_unix: 978307190 updated_unix: 978307190
is_locked: false
- -
id: 3 id: 3
repo_id: 1 repo_id: 1
index: 3 index: 3
poster_id: 1 poster_id: 1
original_author_id: 0
name: issue3 name: issue3
content: content for the third issue content: content for the third issue
milestone_id: 3 milestone_id: 3
priority: 0
is_closed: false is_closed: false
is_pull: true is_pull: true
num_comments: 0
created_unix: 946684820 created_unix: 946684820
updated_unix: 978307180 updated_unix: 978307180
is_locked: false
- -
id: 4 id: 4
repo_id: 2 repo_id: 2
index: 1 index: 1
poster_id: 2 poster_id: 2
original_author_id: 0
name: issue4 name: issue4
content: content for the fourth issue content: content for the fourth issue
milestone_id: 0
priority: 0
is_closed: true is_closed: true
is_pull: false is_pull: false
num_comments: 0
created_unix: 946684830 created_unix: 946684830
updated_unix: 978307200 updated_unix: 978307200
is_locked: false
- -
id: 5 id: 5
repo_id: 1 repo_id: 1
index: 4 index: 4
poster_id: 2 poster_id: 2
original_author_id: 0
name: issue5 name: issue5
content: content for the fifth issue content: content for the fifth issue
milestone_id: 0
priority: 0
is_closed: true is_closed: true
is_pull: false is_pull: false
num_comments: 0
created_unix: 946684840 created_unix: 946684840
updated_unix: 978307200 updated_unix: 978307200
is_locked: false
- -
id: 6 id: 6
repo_id: 3 repo_id: 3
index: 1 index: 1
poster_id: 1 poster_id: 1
original_author_id: 0
name: issue6 name: issue6
content: content6 content: content6
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 0 num_comments: 0
created_unix: 946684850 created_unix: 946684850
updated_unix: 978307200 updated_unix: 978307200
is_locked: false
- -
id: 7 id: 7
repo_id: 2 repo_id: 2
index: 2 index: 2
poster_id: 2 poster_id: 2
original_author_id: 0
name: issue7 name: issue7
content: content for the seventh issue content: content for the seventh issue
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 0
created_unix: 946684830 created_unix: 946684830
updated_unix: 978307200 updated_unix: 978307200
is_locked: false
- -
id: 8 id: 8
repo_id: 10 repo_id: 10
index: 1 index: 1
poster_id: 11 poster_id: 11
original_author_id: 0
name: pr2 name: pr2
content: a pull request content: a pull request
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: true is_pull: true
num_comments: 0
created_unix: 946684820 created_unix: 946684820
updated_unix: 978307180 updated_unix: 978307180
is_locked: false
- -
id: 9 id: 9
repo_id: 48 repo_id: 48
index: 1 index: 1
poster_id: 11 poster_id: 11
original_author_id: 0
name: pr1 name: pr1
content: a pull request content: a pull request
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: true is_pull: true
num_comments: 0
created_unix: 946684820 created_unix: 946684820
updated_unix: 978307180 updated_unix: 978307180
is_locked: false
- -
id: 10 id: 10
repo_id: 42 repo_id: 42
index: 1 index: 1
poster_id: 500 poster_id: 500
original_author_id: 0
name: issue from deleted account name: issue from deleted account
content: content from deleted account content: content from deleted account
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 0
deadline_unix: 1019307200
created_unix: 946684830 created_unix: 946684830
updated_unix: 999307200 updated_unix: 999307200
deadline_unix: 1019307200 is_locked: false
- -
id: 11 id: 11
repo_id: 1 repo_id: 1
index: 5 index: 5
poster_id: 1 poster_id: 1
original_author_id: 0
name: pull5 name: pull5
content: content for the a pull request content: content for the a pull request
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: true is_pull: true
num_comments: 0
created_unix: 1579194806 created_unix: 1579194806
updated_unix: 1579194806 updated_unix: 1579194806
is_locked: false
- -
id: 12 id: 12
repo_id: 3 repo_id: 3
index: 2 index: 2
poster_id: 2 poster_id: 2
original_author_id: 0
name: pull6 name: pull6
content: content for the a pull request content: content for the a pull request
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: true is_pull: true
num_comments: 0
created_unix: 1602935696 created_unix: 1602935696
updated_unix: 1602935696 updated_unix: 1602935696
is_locked: false
- -
id: 13 id: 13
repo_id: 50 repo_id: 50
index: 1 index: 1
poster_id: 2 poster_id: 2
original_author_id: 0
name: issue in active repo name: issue in active repo
content: we'll be testing github issue 13171 with this. content: we'll be testing github issue 13171 with this.
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 0
created_unix: 1602935696 created_unix: 1602935696
updated_unix: 1602935696 updated_unix: 1602935696
is_locked: false
- -
id: 14 id: 14
repo_id: 51 repo_id: 51
index: 1 index: 1
poster_id: 2 poster_id: 2
original_author_id: 0
name: issue in archived repo name: issue in archived repo
content: we'll be testing github issue 13171 with this. content: we'll be testing github issue 13171 with this.
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 0
created_unix: 1602935696 created_unix: 1602935696
updated_unix: 1602935696 updated_unix: 1602935696
is_locked: false
- -
id: 15 id: 15
repo_id: 5 repo_id: 5
index: 1 index: 1
poster_id: 2 poster_id: 2
original_author_id: 0
name: issue in repo not linked to team1 name: issue in repo not linked to team1
content: content content: content
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 0
created_unix: 1602935696 created_unix: 1602935696
updated_unix: 1602935696 updated_unix: 1602935696
is_locked: false
- -
id: 16 id: 16
repo_id: 32 repo_id: 32
index: 1 index: 1
poster_id: 2 poster_id: 2
original_author_id: 0
name: just a normal issue name: just a normal issue
content: content content: content
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 0
created_unix: 1602935696 created_unix: 1602935696
updated_unix: 1602935696 updated_unix: 1602935696
is_locked: false
- -
id: 17 id: 17
repo_id: 32 repo_id: 32
index: 2 index: 2
poster_id: 15 poster_id: 15
original_author_id: 0
name: a issue with a assignment name: a issue with a assignment
content: content content: content
milestone_id: 0
priority: 0
is_closed: false is_closed: false
is_pull: false is_pull: false
num_comments: 0
created_unix: 1602935696 created_unix: 1602935696
updated_unix: 1602935696 updated_unix: 1602935696
is_locked: false

View File

@ -15,10 +15,11 @@
color: '#000000' color: '#000000'
num_issues: 1 num_issues: 1
num_closed_issues: 1 num_closed_issues: 1
- -
id: 3 id: 3
repo_id: 0 repo_id: 0
org_id: 3 org_id: 3
name: orglabel3 name: orglabel3
color: '#abcdef' color: '#abcdef'
num_issues: 0 num_issues: 0
@ -32,7 +33,7 @@
color: '#000000' color: '#000000'
num_issues: 1 num_issues: 1
num_closed_issues: 0 num_closed_issues: 0
- -
id: 5 id: 5
repo_id: 10 repo_id: 10

View File

@ -6,6 +6,7 @@
is_closed: false is_closed: false
num_issues: 1 num_issues: 1
num_closed_issues: 0 num_closed_issues: 0
completeness: 0
deadline_unix: 253370764800 deadline_unix: 253370764800
- -
@ -16,6 +17,7 @@
is_closed: false is_closed: false
num_issues: 0 num_issues: 0
num_closed_issues: 0 num_closed_issues: 0
completeness: 0
deadline_unix: 253370764800 deadline_unix: 253370764800
- -
@ -26,6 +28,7 @@
is_closed: true is_closed: true
num_issues: 1 num_issues: 1
num_closed_issues: 0 num_closed_issues: 0
completeness: 0
deadline_unix: 253370764800 deadline_unix: 253370764800
- -
@ -36,14 +39,16 @@
is_closed: false is_closed: false
num_issues: 0 num_issues: 0
num_closed_issues: 0 num_closed_issues: 0
completeness: 0
deadline_unix: 253370764800 deadline_unix: 253370764800
- -
id: 5 id: 5
repo_id: 10 repo_id: 10
name: milestone of repo 10 name: milestone of repo 10
content: for testing with PRs content: for testing with PRs
is_closed: false is_closed: false
num_issues: 0 num_issues: 0
num_closed_issues: 0 num_closed_issues: 0
completeness: 0
deadline_unix: 253370764800 deadline_unix: 253370764800

View File

@ -4,6 +4,6 @@
name: "Test" name: "Test"
client_id: "da7da3ba-9a13-4167-856f-3899de0b0138" client_id: "da7da3ba-9a13-4167-856f-3899de0b0138"
client_secret: "$2a$10$UYRgUSgekzBp6hYe8pAdc.cgB4Gn06QRKsORUnIYTYQADs.YR/uvi" # bcrypt of "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA= client_secret: "$2a$10$UYRgUSgekzBp6hYe8pAdc.cgB4Gn06QRKsORUnIYTYQADs.YR/uvi" # bcrypt of "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=
redirect_uris: '["a"]' redirect_uris: '["a", "https://example.com/xyzzy"]'
created_unix: 1546869730 created_unix: 1546869730
updated_unix: 1546869730 updated_unix: 1546869730

View File

@ -60,8 +60,8 @@
head_repo_id: 1 head_repo_id: 1
base_repo_id: 1 base_repo_id: 1
head_branch: pr-to-update head_branch: pr-to-update
base_branch: branch1 base_branch: branch2
merge_base: 1234567890abcdef merge_base: 985f0301dba5e7b34be866819cd15ad3d8f508ee
has_merged: false has_merged: false
- -

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
-
id: 1
setting_key: 'disable_gravatar'
setting_value: 'false'
version: 1
created: 1653533198
updated: 1653533198
-
id: 2
setting_key: 'enable_federated_avatar'
setting_value: 'false'
version: 1
created: 1653533198
updated: 1653533198

View File

@ -6,6 +6,7 @@
authorize: 4 # owner authorize: 4 # owner
num_repos: 3 num_repos: 3
num_members: 1 num_members: 1
includes_all_repositories: false
can_create_org_repo: true can_create_org_repo: true
- -
@ -16,6 +17,7 @@
authorize: 2 # write authorize: 2 # write
num_repos: 1 num_repos: 1
num_members: 2 num_members: 2
includes_all_repositories: false
can_create_org_repo: false can_create_org_repo: false
- -
@ -26,6 +28,7 @@
authorize: 4 # owner authorize: 4 # owner
num_repos: 0 num_repos: 0
num_members: 1 num_members: 1
includes_all_repositories: false
can_create_org_repo: true can_create_org_repo: true
- -
@ -36,6 +39,7 @@
authorize: 4 # owner authorize: 4 # owner
num_repos: 0 num_repos: 0
num_members: 1 num_members: 1
includes_all_repositories: false
can_create_org_repo: true can_create_org_repo: true
- -
@ -46,6 +50,7 @@
authorize: 4 # owner authorize: 4 # owner
num_repos: 2 num_repos: 2
num_members: 2 num_members: 2
includes_all_repositories: false
can_create_org_repo: true can_create_org_repo: true
- -
@ -56,6 +61,7 @@
authorize: 4 # owner authorize: 4 # owner
num_repos: 2 num_repos: 2
num_members: 2 num_members: 2
includes_all_repositories: false
can_create_org_repo: true can_create_org_repo: true
- -
@ -66,6 +72,7 @@
authorize: 2 # write authorize: 2 # write
num_repos: 1 num_repos: 1
num_members: 1 num_members: 1
includes_all_repositories: false
can_create_org_repo: false can_create_org_repo: false
- -
@ -76,6 +83,7 @@
authorize: 2 # write authorize: 2 # write
num_repos: 1 num_repos: 1
num_members: 1 num_members: 1
includes_all_repositories: false
can_create_org_repo: false can_create_org_repo: false
- -
@ -86,6 +94,7 @@
authorize: 1 # read authorize: 1 # read
num_repos: 1 num_repos: 1
num_members: 2 num_members: 2
includes_all_repositories: false
can_create_org_repo: false can_create_org_repo: false
- -
@ -93,9 +102,10 @@
org_id: 25 org_id: 25
lower_name: notowners lower_name: notowners
name: NotOwners name: NotOwners
authorize: 1 # owner authorize: 1 # read
num_repos: 0 num_repos: 0
num_members: 1 num_members: 1
includes_all_repositories: false
can_create_org_repo: false can_create_org_repo: false
- -
@ -106,6 +116,7 @@
authorize: 1 # read authorize: 1 # read
num_repos: 0 num_repos: 0
num_members: 0 num_members: 0
includes_all_repositories: false
can_create_org_repo: false can_create_org_repo: false
- -
@ -116,6 +127,7 @@
authorize: 3 # admin authorize: 3 # admin
num_repos: 0 num_repos: 0
num_members: 1 num_members: 1
includes_all_repositories: false
can_create_org_repo: true can_create_org_repo: true
- -
@ -126,4 +138,5 @@
authorize: 3 # admin authorize: 3 # admin
num_repos: 0 num_repos: 0
num_members: 1 num_members: 1
includes_all_repositories: false
can_create_org_repo: false can_create_org_repo: false

View File

@ -8,18 +8,22 @@
name: database name: database
repo_count: 1 repo_count: 1
- id: 3 -
id: 3
name: SQL name: SQL
repo_count: 1 repo_count: 1
- id: 4 -
id: 4
name: graphql name: graphql
repo_count: 1 repo_count: 1
- id: 5 -
id: 5
name: topicname1 name: topicname1
repo_count: 1 repo_count: 1
- id: 6 -
id: 6
name: topicname2 name: topicname2
repo_count: 2 repo_count: 2

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
- id: 1 -
name: "WebAuthn credential" id: 1
name: WebAuthn credential
user_id: 32 user_id: 32
attestation_type: none attestation_type: none
sign_count: 0 sign_count: 0

View File

@ -6,6 +6,8 @@ package foreignreference
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/util"
) )
// ErrLocalIndexNotExist represents a "LocalIndexNotExist" kind of error. // ErrLocalIndexNotExist represents a "LocalIndexNotExist" kind of error.
@ -25,6 +27,10 @@ func (err ErrLocalIndexNotExist) Error() string {
return fmt.Sprintf("repository %d has no LocalIndex for ForeignIndex %d of type %s", err.RepoID, err.ForeignIndex, err.Type) return fmt.Sprintf("repository %d has no LocalIndex for ForeignIndex %d of type %s", err.RepoID, err.ForeignIndex, err.Type)
} }
func (err ErrLocalIndexNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrForeignIndexNotExist represents a "ForeignIndexNotExist" kind of error. // ErrForeignIndexNotExist represents a "ForeignIndexNotExist" kind of error.
type ErrForeignIndexNotExist struct { type ErrForeignIndexNotExist struct {
RepoID int64 RepoID int64
@ -41,3 +47,7 @@ func IsErrForeignIndexNotExist(err error) bool {
func (err ErrForeignIndexNotExist) Error() string { func (err ErrForeignIndexNotExist) Error() string {
return fmt.Sprintf("repository %d has no ForeignIndex for LocalIndex %d of type %s", err.RepoID, err.LocalIndex, err.Type) return fmt.Sprintf("repository %d has no ForeignIndex for LocalIndex %d of type %s", err.RepoID, err.LocalIndex, err.Type)
} }
func (err ErrForeignIndexNotExist) Unwrap() error {
return util.ErrNotExist
}

View File

@ -6,7 +6,6 @@ package git
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -17,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder" "xorm.io/builder"
) )
@ -38,6 +38,10 @@ func (err ErrLFSLockNotExist) Error() string {
return fmt.Sprintf("lfs lock does not exist [id: %d, rid: %d, path: %s]", err.ID, err.RepoID, err.Path) return fmt.Sprintf("lfs lock does not exist [id: %d, rid: %d, path: %s]", err.ID, err.RepoID, err.Path)
} }
func (err ErrLFSLockNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error. // ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error.
type ErrLFSUnauthorizedAction struct { type ErrLFSUnauthorizedAction struct {
RepoID int64 RepoID int64
@ -58,6 +62,10 @@ func (err ErrLFSUnauthorizedAction) Error() string {
return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID) return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID)
} }
func (err ErrLFSUnauthorizedAction) Unwrap() error {
return util.ErrPermissionDenied
}
// ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error. // ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error.
type ErrLFSLockAlreadyExist struct { type ErrLFSLockAlreadyExist struct {
RepoID int64 RepoID int64
@ -74,6 +82,10 @@ func (err ErrLFSLockAlreadyExist) Error() string {
return fmt.Sprintf("lfs lock already exists [rid: %d, path: %s]", err.RepoID, err.Path) return fmt.Sprintf("lfs lock already exists [rid: %d, path: %s]", err.RepoID, err.Path)
} }
func (err ErrLFSLockAlreadyExist) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrLFSFileLocked represents a "LFSFileLocked" kind of error. // ErrLFSFileLocked represents a "LFSFileLocked" kind of error.
type ErrLFSFileLocked struct { type ErrLFSFileLocked struct {
RepoID int64 RepoID int64
@ -91,6 +103,10 @@ func (err ErrLFSFileLocked) Error() string {
return fmt.Sprintf("File is lfs locked [repo: %d, locked by: %s, path: %s]", err.RepoID, err.UserName, err.Path) return fmt.Sprintf("File is lfs locked [repo: %d, locked by: %s, path: %s]", err.RepoID, err.UserName, err.Path)
} }
func (err ErrLFSFileLocked) Unwrap() error {
return util.ErrPermissionDenied
}
// LFSMetaObject stores metadata for LFS tracked files. // LFSMetaObject stores metadata for LFS tracked files.
type LFSMetaObject struct { type LFSMetaObject struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
@ -114,7 +130,7 @@ type LFSTokenResponse struct {
// ErrLFSObjectNotExist is returned from lfs models functions in order // ErrLFSObjectNotExist is returned from lfs models functions in order
// to differentiate between database and missing object errors. // to differentiate between database and missing object errors.
var ErrLFSObjectNotExist = errors.New("LFS Meta object does not exist") var ErrLFSObjectNotExist = db.ErrNotExist{Resource: "LFS Meta object"}
// NewLFSMetaObject stores a given populated LFSMetaObject structure in the database // NewLFSMetaObject stores a given populated LFSMetaObject structure in the database
// if it is not already present. // if it is not already present.

View File

@ -28,6 +28,7 @@ import (
"code.gitea.io/gitea/modules/references" "code.gitea.io/gitea/modules/references"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder" "xorm.io/builder"
"xorm.io/xorm" "xorm.io/xorm"
@ -49,6 +50,10 @@ func (err ErrCommentNotExist) Error() string {
return fmt.Sprintf("comment does not exist [id: %d, issue_id: %d]", err.ID, err.IssueID) return fmt.Sprintf("comment does not exist [id: %d, issue_id: %d]", err.ID, err.IssueID)
} }
func (err ErrCommentNotExist) Unwrap() error {
return util.ErrNotExist
}
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference. // CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
type CommentType int type CommentType int

View File

@ -17,13 +17,11 @@ import (
type CommentList []*Comment type CommentList []*Comment
func (comments CommentList) getPosterIDs() []int64 { func (comments CommentList) getPosterIDs() []int64 {
posterIDs := make(map[int64]struct{}, len(comments)) posterIDs := make(container.Set[int64], len(comments))
for _, comment := range comments { for _, comment := range comments {
if _, ok := posterIDs[comment.PosterID]; !ok { posterIDs.Add(comment.PosterID)
posterIDs[comment.PosterID] = struct{}{}
}
} }
return container.KeysInt64(posterIDs) return posterIDs.Values()
} }
func (comments CommentList) loadPosters(ctx context.Context) error { func (comments CommentList) loadPosters(ctx context.Context) error {
@ -70,13 +68,11 @@ func (comments CommentList) getCommentIDs() []int64 {
} }
func (comments CommentList) getLabelIDs() []int64 { func (comments CommentList) getLabelIDs() []int64 {
ids := make(map[int64]struct{}, len(comments)) ids := make(container.Set[int64], len(comments))
for _, comment := range comments { for _, comment := range comments {
if _, ok := ids[comment.LabelID]; !ok { ids.Add(comment.LabelID)
ids[comment.LabelID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
func (comments CommentList) loadLabels(ctx context.Context) error { //nolint func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
@ -120,13 +116,11 @@ func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
} }
func (comments CommentList) getMilestoneIDs() []int64 { func (comments CommentList) getMilestoneIDs() []int64 {
ids := make(map[int64]struct{}, len(comments)) ids := make(container.Set[int64], len(comments))
for _, comment := range comments { for _, comment := range comments {
if _, ok := ids[comment.MilestoneID]; !ok { ids.Add(comment.MilestoneID)
ids[comment.MilestoneID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
func (comments CommentList) loadMilestones(ctx context.Context) error { func (comments CommentList) loadMilestones(ctx context.Context) error {
@ -163,13 +157,11 @@ func (comments CommentList) loadMilestones(ctx context.Context) error {
} }
func (comments CommentList) getOldMilestoneIDs() []int64 { func (comments CommentList) getOldMilestoneIDs() []int64 {
ids := make(map[int64]struct{}, len(comments)) ids := make(container.Set[int64], len(comments))
for _, comment := range comments { for _, comment := range comments {
if _, ok := ids[comment.OldMilestoneID]; !ok { ids.Add(comment.OldMilestoneID)
ids[comment.OldMilestoneID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
func (comments CommentList) loadOldMilestones(ctx context.Context) error { func (comments CommentList) loadOldMilestones(ctx context.Context) error {
@ -206,13 +198,11 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error {
} }
func (comments CommentList) getAssigneeIDs() []int64 { func (comments CommentList) getAssigneeIDs() []int64 {
ids := make(map[int64]struct{}, len(comments)) ids := make(container.Set[int64], len(comments))
for _, comment := range comments { for _, comment := range comments {
if _, ok := ids[comment.AssigneeID]; !ok { ids.Add(comment.AssigneeID)
ids[comment.AssigneeID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
func (comments CommentList) loadAssignees(ctx context.Context) error { func (comments CommentList) loadAssignees(ctx context.Context) error {
@ -259,16 +249,14 @@ func (comments CommentList) loadAssignees(ctx context.Context) error {
// getIssueIDs returns all the issue ids on this comment list which issue hasn't been loaded // getIssueIDs returns all the issue ids on this comment list which issue hasn't been loaded
func (comments CommentList) getIssueIDs() []int64 { func (comments CommentList) getIssueIDs() []int64 {
ids := make(map[int64]struct{}, len(comments)) ids := make(container.Set[int64], len(comments))
for _, comment := range comments { for _, comment := range comments {
if comment.Issue != nil { if comment.Issue != nil {
continue continue
} }
if _, ok := ids[comment.IssueID]; !ok { ids.Add(comment.IssueID)
ids[comment.IssueID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
// Issues returns all the issues of comments // Issues returns all the issues of comments
@ -334,16 +322,14 @@ func (comments CommentList) loadIssues(ctx context.Context) error {
} }
func (comments CommentList) getDependentIssueIDs() []int64 { func (comments CommentList) getDependentIssueIDs() []int64 {
ids := make(map[int64]struct{}, len(comments)) ids := make(container.Set[int64], len(comments))
for _, comment := range comments { for _, comment := range comments {
if comment.DependentIssue != nil { if comment.DependentIssue != nil {
continue continue
} }
if _, ok := ids[comment.DependentIssueID]; !ok { ids.Add(comment.DependentIssueID)
ids[comment.DependentIssueID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
func (comments CommentList) loadDependentIssues(ctx context.Context) error { func (comments CommentList) loadDependentIssues(ctx context.Context) error {
@ -439,13 +425,11 @@ func (comments CommentList) loadAttachments(ctx context.Context) (err error) {
} }
func (comments CommentList) getReviewIDs() []int64 { func (comments CommentList) getReviewIDs() []int64 {
ids := make(map[int64]struct{}, len(comments)) ids := make(container.Set[int64], len(comments))
for _, comment := range comments { for _, comment := range comments {
if _, ok := ids[comment.ReviewID]; !ok { ids.Add(comment.ReviewID)
ids[comment.ReviewID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
func (comments CommentList) loadReviews(ctx context.Context) error { //nolint func (comments CommentList) loadReviews(ctx context.Context) error { //nolint

View File

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder" "xorm.io/builder"
) )
@ -201,6 +202,10 @@ func (err ErrIssueContentHistoryNotExist) Error() string {
return fmt.Sprintf("issue content history does not exist [id: %d]", err.ID) return fmt.Sprintf("issue content history does not exist [id: %d]", err.ID)
} }
func (err ErrIssueContentHistoryNotExist) Unwrap() error {
return util.ErrNotExist
}
// GetIssueContentHistoryByID get issue content history // GetIssueContentHistoryByID get issue content history
func GetIssueContentHistoryByID(dbCtx context.Context, id int64) (*ContentHistory, error) { func GetIssueContentHistoryByID(dbCtx context.Context, id int64) (*ContentHistory, error) {
h := &ContentHistory{} h := &ContentHistory{}

View File

@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
) )
// ErrDependencyExists represents a "DependencyAlreadyExists" kind of error. // ErrDependencyExists represents a "DependencyAlreadyExists" kind of error.
@ -29,6 +30,10 @@ func (err ErrDependencyExists) Error() string {
return fmt.Sprintf("issue dependency does already exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) return fmt.Sprintf("issue dependency does already exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID)
} }
func (err ErrDependencyExists) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error. // ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error.
type ErrDependencyNotExists struct { type ErrDependencyNotExists struct {
IssueID int64 IssueID int64
@ -45,6 +50,10 @@ func (err ErrDependencyNotExists) Error() string {
return fmt.Sprintf("issue dependency does not exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) return fmt.Sprintf("issue dependency does not exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID)
} }
func (err ErrDependencyNotExists) Unwrap() error {
return util.ErrNotExist
}
// ErrCircularDependency represents a "DependencyCircular" kind of error. // ErrCircularDependency represents a "DependencyCircular" kind of error.
type ErrCircularDependency struct { type ErrCircularDependency struct {
IssueID int64 IssueID int64
@ -91,6 +100,10 @@ func (err ErrUnknownDependencyType) Error() string {
return fmt.Sprintf("unknown dependency type [type: %d]", err.Type) return fmt.Sprintf("unknown dependency type [type: %d]", err.Type)
} }
func (err ErrUnknownDependencyType) Unwrap() error {
return util.ErrInvalidArgument
}
// IssueDependency represents an issue dependency // IssueDependency represents an issue dependency
type IssueDependency struct { type IssueDependency struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`

View File

@ -13,7 +13,6 @@ import (
"strconv" "strconv"
"strings" "strings"
admin_model "code.gitea.io/gitea/models/admin"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/foreignreference" "code.gitea.io/gitea/models/foreignreference"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
@ -21,6 +20,7 @@ import (
access_model "code.gitea.io/gitea/models/perm/access" access_model "code.gitea.io/gitea/models/perm/access"
project_model "code.gitea.io/gitea/models/project" project_model "code.gitea.io/gitea/models/project"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
@ -52,6 +52,10 @@ func (err ErrIssueNotExist) Error() string {
return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index)
} }
func (err ErrIssueNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrIssueIsClosed represents a "IssueIsClosed" kind of error. // ErrIssueIsClosed represents a "IssueIsClosed" kind of error.
type ErrIssueIsClosed struct { type ErrIssueIsClosed struct {
ID int64 ID int64
@ -1064,19 +1068,19 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
// NewIssue creates new issue with labels for repository. // NewIssue creates new issue with labels for repository.
func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) { func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
if err != nil {
return fmt.Errorf("generate issue index failed: %v", err)
}
issue.Index = idx
ctx, committer, err := db.TxContext() ctx, committer, err := db.TxContext()
if err != nil { if err != nil {
return err return err
} }
defer committer.Close() defer committer.Close()
idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID)
if err != nil {
return fmt.Errorf("generate issue index failed: %w", err)
}
issue.Index = idx
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
Repo: repo, Repo: repo,
Issue: issue, Issue: issue,
@ -1186,6 +1190,7 @@ type IssuesOptions struct { //nolint
PosterID int64 PosterID int64
MentionedID int64 MentionedID int64
ReviewRequestedID int64 ReviewRequestedID int64
SubscriberID int64
MilestoneIDs []int64 MilestoneIDs []int64
ProjectID int64 ProjectID int64
ProjectBoardID int64 ProjectBoardID int64
@ -1299,6 +1304,10 @@ func (opts *IssuesOptions) setupSessionNoLimit(sess *xorm.Session) {
applyReviewRequestedCondition(sess, opts.ReviewRequestedID) applyReviewRequestedCondition(sess, opts.ReviewRequestedID)
} }
if opts.SubscriberID > 0 {
applySubscribedCondition(sess, opts.SubscriberID)
}
if len(opts.MilestoneIDs) > 0 { if len(opts.MilestoneIDs) > 0 {
sess.In("issue.milestone_id", opts.MilestoneIDs) sess.In("issue.milestone_id", opts.MilestoneIDs)
} }
@ -1463,6 +1472,37 @@ func applyReviewRequestedCondition(sess *xorm.Session, reviewRequestedID int64)
reviewRequestedID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, reviewRequestedID) reviewRequestedID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, reviewRequestedID)
} }
func applySubscribedCondition(sess *xorm.Session, subscriberID int64) *xorm.Session {
return sess.And(
builder.
NotIn("issue.id",
builder.Select("issue_id").
From("issue_watch").
Where(builder.Eq{"is_watching": false, "user_id": subscriberID}),
),
).And(
builder.Or(
builder.In("issue.id", builder.
Select("issue_id").
From("issue_watch").
Where(builder.Eq{"is_watching": true, "user_id": subscriberID}),
),
builder.In("issue.id", builder.
Select("issue_id").
From("comment").
Where(builder.Eq{"poster_id": subscriberID}),
),
builder.Eq{"issue.poster_id": subscriberID},
builder.In("issue.repo_id", builder.
Select("id").
From("watch").
Where(builder.And(builder.Eq{"user_id": subscriberID},
builder.In("mode", repo_model.WatchModeNormal, repo_model.WatchModeAuto))),
),
),
)
}
// CountIssuesByRepo map from repoID to number of issues matching the options // CountIssuesByRepo map from repoID to number of issues matching the options
func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) { func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) {
e := db.GetEngine(db.DefaultContext) e := db.GetEngine(db.DefaultContext)
@ -2435,7 +2475,7 @@ func DeleteOrphanedIssues() error {
// Remove issue attachment files. // Remove issue attachment files.
for i := range attachmentPaths { for i := range attachmentPaths {
admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i]) system_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i])
} }
return nil return nil
} }

View File

@ -15,16 +15,12 @@ func RecalculateIssueIndexForRepo(repoID int64) error {
} }
defer committer.Close() defer committer.Close()
if err := db.UpsertResourceIndex(ctx, "issue_index", repoID); err != nil {
return err
}
var max int64 var max int64
if _, err := db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil { if _, err = db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil {
return err return err
} }
if _, err := db.GetEngine(ctx).Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil { if err = db.SyncMaxResourceIndex(ctx, "issue_index", repoID, max); err != nil {
return err return err
} }

View File

@ -22,16 +22,16 @@ type IssueList []*Issue
// get the repo IDs to be loaded later, these IDs are for issue.Repo and issue.PullRequest.HeadRepo // get the repo IDs to be loaded later, these IDs are for issue.Repo and issue.PullRequest.HeadRepo
func (issues IssueList) getRepoIDs() []int64 { func (issues IssueList) getRepoIDs() []int64 {
repoIDs := make(map[int64]struct{}, len(issues)) repoIDs := make(container.Set[int64], len(issues))
for _, issue := range issues { for _, issue := range issues {
if issue.Repo == nil { if issue.Repo == nil {
repoIDs[issue.RepoID] = struct{}{} repoIDs.Add(issue.RepoID)
} }
if issue.PullRequest != nil && issue.PullRequest.HeadRepo == nil { if issue.PullRequest != nil && issue.PullRequest.HeadRepo == nil {
repoIDs[issue.PullRequest.HeadRepoID] = struct{}{} repoIDs.Add(issue.PullRequest.HeadRepoID)
} }
} }
return container.KeysInt64(repoIDs) return repoIDs.Values()
} }
func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Repository, error) { func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Repository, error) {
@ -79,13 +79,11 @@ func (issues IssueList) LoadRepositories() ([]*repo_model.Repository, error) {
} }
func (issues IssueList) getPosterIDs() []int64 { func (issues IssueList) getPosterIDs() []int64 {
posterIDs := make(map[int64]struct{}, len(issues)) posterIDs := make(container.Set[int64], len(issues))
for _, issue := range issues { for _, issue := range issues {
if _, ok := posterIDs[issue.PosterID]; !ok { posterIDs.Add(issue.PosterID)
posterIDs[issue.PosterID] = struct{}{}
}
} }
return container.KeysInt64(posterIDs) return posterIDs.Values()
} }
func (issues IssueList) loadPosters(ctx context.Context) error { func (issues IssueList) loadPosters(ctx context.Context) error {
@ -185,13 +183,11 @@ func (issues IssueList) loadLabels(ctx context.Context) error {
} }
func (issues IssueList) getMilestoneIDs() []int64 { func (issues IssueList) getMilestoneIDs() []int64 {
ids := make(map[int64]struct{}, len(issues)) ids := make(container.Set[int64], len(issues))
for _, issue := range issues { for _, issue := range issues {
if _, ok := ids[issue.MilestoneID]; !ok { ids.Add(issue.MilestoneID)
ids[issue.MilestoneID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
func (issues IssueList) loadMilestones(ctx context.Context) error { func (issues IssueList) loadMilestones(ctx context.Context) error {
@ -224,14 +220,11 @@ func (issues IssueList) loadMilestones(ctx context.Context) error {
} }
func (issues IssueList) getProjectIDs() []int64 { func (issues IssueList) getProjectIDs() []int64 {
ids := make(map[int64]struct{}, len(issues)) ids := make(container.Set[int64], len(issues))
for _, issue := range issues { for _, issue := range issues {
projectID := issue.ProjectID() ids.Add(issue.ProjectID())
if _, ok := ids[projectID]; !ok {
ids[projectID] = struct{}{}
}
} }
return container.KeysInt64(ids) return ids.Values()
} }
func (issues IssueList) loadProjects(ctx context.Context) error { func (issues IssueList) loadProjects(ctx context.Context) error {

View File

@ -131,7 +131,11 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu
r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}) r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo})
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}) d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
idx, err := db.GetNextResourceIndex("issue_index", r.ID) ctx, committer, err := db.TxContext()
assert.NoError(t, err)
defer committer.Close()
idx, err := db.GetNextResourceIndex(ctx, "issue_index", r.ID)
assert.NoError(t, err) assert.NoError(t, err)
i := &issues_model.Issue{ i := &issues_model.Issue{
RepoID: r.ID, RepoID: r.ID,
@ -143,9 +147,6 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu
Index: idx, Index: idx,
} }
ctx, committer, err := db.TxContext()
assert.NoError(t, err)
defer committer.Close()
err = issues_model.NewIssueWithIndex(ctx, d, issues_model.NewIssueOptions{ err = issues_model.NewIssueWithIndex(ctx, d, issues_model.NewIssueOptions{
Repo: r, Repo: r,
Issue: i, Issue: i,

View File

@ -38,6 +38,10 @@ func (err ErrRepoLabelNotExist) Error() string {
return fmt.Sprintf("label does not exist [label_id: %d, repo_id: %d]", err.LabelID, err.RepoID) return fmt.Sprintf("label does not exist [label_id: %d, repo_id: %d]", err.LabelID, err.RepoID)
} }
func (err ErrRepoLabelNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrOrgLabelNotExist represents a "OrgLabelNotExist" kind of error. // ErrOrgLabelNotExist represents a "OrgLabelNotExist" kind of error.
type ErrOrgLabelNotExist struct { type ErrOrgLabelNotExist struct {
LabelID int64 LabelID int64
@ -54,6 +58,10 @@ func (err ErrOrgLabelNotExist) Error() string {
return fmt.Sprintf("label does not exist [label_id: %d, org_id: %d]", err.LabelID, err.OrgID) return fmt.Sprintf("label does not exist [label_id: %d, org_id: %d]", err.LabelID, err.OrgID)
} }
func (err ErrOrgLabelNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrLabelNotExist represents a "LabelNotExist" kind of error. // ErrLabelNotExist represents a "LabelNotExist" kind of error.
type ErrLabelNotExist struct { type ErrLabelNotExist struct {
LabelID int64 LabelID int64
@ -69,6 +77,10 @@ func (err ErrLabelNotExist) Error() string {
return fmt.Sprintf("label does not exist [label_id: %d]", err.LabelID) return fmt.Sprintf("label does not exist [label_id: %d]", err.LabelID)
} }
func (err ErrLabelNotExist) Unwrap() error {
return util.ErrNotExist
}
// LabelColorPattern is a regexp witch can validate LabelColor // LabelColorPattern is a regexp witch can validate LabelColor
var LabelColorPattern = regexp.MustCompile("^#?(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})$") var LabelColorPattern = regexp.MustCompile("^#?(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})$")

View File

@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder" "xorm.io/builder"
) )
@ -39,6 +40,10 @@ func (err ErrMilestoneNotExist) Error() string {
return fmt.Sprintf("milestone does not exist [id: %d, repo_id: %d]", err.ID, err.RepoID) return fmt.Sprintf("milestone does not exist [id: %d, repo_id: %d]", err.ID, err.RepoID)
} }
func (err ErrMilestoneNotExist) Unwrap() error {
return util.ErrNotExist
}
// Milestone represents a milestone of repository. // Milestone represents a milestone of repository.
type Milestone struct { type Milestone struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`

View File

@ -46,6 +46,10 @@ func (err ErrPullRequestNotExist) Error() string {
err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch)
} }
func (err ErrPullRequestNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrPullRequestAlreadyExists represents a "PullRequestAlreadyExists"-error // ErrPullRequestAlreadyExists represents a "PullRequestAlreadyExists"-error
type ErrPullRequestAlreadyExists struct { type ErrPullRequestAlreadyExists struct {
ID int64 ID int64
@ -68,6 +72,10 @@ func (err ErrPullRequestAlreadyExists) Error() string {
err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch)
} }
func (err ErrPullRequestAlreadyExists) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrPullRequestHeadRepoMissing represents a "ErrPullRequestHeadRepoMissing" error // ErrPullRequestHeadRepoMissing represents a "ErrPullRequestHeadRepoMissing" error
type ErrPullRequestHeadRepoMissing struct { type ErrPullRequestHeadRepoMissing struct {
ID int64 ID int64
@ -490,13 +498,6 @@ func (pr *PullRequest) SetMerged(ctx context.Context) (bool, error) {
// NewPullRequest creates new pull request with labels for repository. // NewPullRequest creates new pull request with labels for repository.
func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) { func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
if err != nil {
return fmt.Errorf("generate pull request index failed: %v", err)
}
issue.Index = idx
ctx, committer, err := db.TxContext() ctx, committer, err := db.TxContext()
if err != nil { if err != nil {
return err return err
@ -504,6 +505,13 @@ func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue
defer committer.Close() defer committer.Close()
ctx.WithContext(outerCtx) ctx.WithContext(outerCtx)
idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID)
if err != nil {
return fmt.Errorf("generate pull request index failed: %v", err)
}
issue.Index = idx
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
Repo: repo, Repo: repo,
Issue: issue, Issue: issue,

View File

@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder" "xorm.io/builder"
) )
@ -34,6 +35,10 @@ func (err ErrForbiddenIssueReaction) Error() string {
return fmt.Sprintf("'%s' is not an allowed reaction", err.Reaction) return fmt.Sprintf("'%s' is not an allowed reaction", err.Reaction)
} }
func (err ErrForbiddenIssueReaction) Unwrap() error {
return util.ErrPermissionDenied
}
// ErrReactionAlreadyExist is used when a existing reaction was try to created // ErrReactionAlreadyExist is used when a existing reaction was try to created
type ErrReactionAlreadyExist struct { type ErrReactionAlreadyExist struct {
Reaction string Reaction string
@ -49,6 +54,10 @@ func (err ErrReactionAlreadyExist) Error() string {
return fmt.Sprintf("reaction '%s' already exists", err.Reaction) return fmt.Sprintf("reaction '%s' already exists", err.Reaction)
} }
func (err ErrReactionAlreadyExist) Unwrap() error {
return util.ErrAlreadyExist
}
// Reaction represents a reactions on issues and comments. // Reaction represents a reactions on issues and comments.
type Reaction struct { type Reaction struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
@ -211,7 +220,7 @@ type ReactionOptions struct {
// CreateReaction creates reaction for issue or comment. // CreateReaction creates reaction for issue or comment.
func CreateReaction(opts *ReactionOptions) (*Reaction, error) { func CreateReaction(opts *ReactionOptions) (*Reaction, error) {
if !setting.UI.ReactionsMap[opts.Type] { if !setting.UI.ReactionsLookup.Contains(opts.Type) {
return nil, ErrForbiddenIssueReaction{opts.Type} return nil, ErrForbiddenIssueReaction{opts.Type}
} }
@ -316,16 +325,14 @@ func (list ReactionList) GroupByType() map[string]ReactionList {
} }
func (list ReactionList) getUserIDs() []int64 { func (list ReactionList) getUserIDs() []int64 {
userIDs := make(map[int64]struct{}, len(list)) userIDs := make(container.Set[int64], len(list))
for _, reaction := range list { for _, reaction := range list {
if reaction.OriginalAuthor != "" { if reaction.OriginalAuthor != "" {
continue continue
} }
if _, ok := userIDs[reaction.UserID]; !ok { userIDs.Add(reaction.UserID)
userIDs[reaction.UserID] = struct{}{}
}
} }
return container.KeysInt64(userIDs) return userIDs.Values()
} }
func valuesUser(m map[int64]*user_model.User) []*user_model.User { func valuesUser(m map[int64]*user_model.User) []*user_model.User {

View File

@ -39,6 +39,10 @@ func (err ErrReviewNotExist) Error() string {
return fmt.Sprintf("review does not exist [id: %d]", err.ID) return fmt.Sprintf("review does not exist [id: %d]", err.ID)
} }
func (err ErrReviewNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrNotValidReviewRequest an not allowed review request modify // ErrNotValidReviewRequest an not allowed review request modify
type ErrNotValidReviewRequest struct { type ErrNotValidReviewRequest struct {
Reason string Reason string
@ -59,6 +63,10 @@ func (err ErrNotValidReviewRequest) Error() string {
err.RepoID) err.RepoID)
} }
func (err ErrNotValidReviewRequest) Unwrap() error {
return util.ErrInvalidArgument
}
// ReviewType defines the sort of feedback a review gives // ReviewType defines the sort of feedback a review gives
type ReviewType int type ReviewType int

View File

@ -25,6 +25,10 @@ func (err ErrIssueStopwatchNotExist) Error() string {
return fmt.Sprintf("issue stopwatch doesn't exist[uid: %d, issue_id: %d", err.UserID, err.IssueID) return fmt.Sprintf("issue stopwatch doesn't exist[uid: %d, issue_id: %d", err.UserID, err.IssueID)
} }
func (err ErrIssueStopwatchNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrIssueStopwatchAlreadyExist represents an error that stopwatch is already exist // ErrIssueStopwatchAlreadyExist represents an error that stopwatch is already exist
type ErrIssueStopwatchAlreadyExist struct { type ErrIssueStopwatchAlreadyExist struct {
UserID int64 UserID int64
@ -35,6 +39,10 @@ func (err ErrIssueStopwatchAlreadyExist) Error() string {
return fmt.Sprintf("issue stopwatch already exists[uid: %d, issue_id: %d", err.UserID, err.IssueID) return fmt.Sprintf("issue stopwatch already exists[uid: %d, issue_id: %d", err.UserID, err.IssueID)
} }
func (err ErrIssueStopwatchAlreadyExist) Unwrap() error {
return util.ErrAlreadyExist
}
// Stopwatch represents a stopwatch for time tracking. // Stopwatch represents a stopwatch for time tracking.
type Stopwatch struct { type Stopwatch struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`

View File

@ -236,7 +236,7 @@ func DeleteIssueUserTimes(issue *Issue, user *user_model.User) error {
return err return err
} }
if removedTime == 0 { if removedTime == 0 {
return db.ErrNotExist{} return db.ErrNotExist{Resource: "tracked_time"}
} }
if err := issue.LoadRepo(ctx); err != nil { if err := issue.LoadRepo(ctx); err != nil {
@ -296,7 +296,7 @@ func deleteTimes(ctx context.Context, opts FindTrackedTimesOptions) (removedTime
func deleteTime(ctx context.Context, t *TrackedTime) error { func deleteTime(ctx context.Context, t *TrackedTime) error {
if t.Deleted { if t.Deleted {
return db.ErrNotExist{ID: t.ID} return db.ErrNotExist{Resource: "tracked_time", ID: t.ID}
} }
t.Deleted = true t.Deleted = true
_, err := db.GetEngine(ctx).ID(t.ID).Cols("deleted").Update(t) _, err := db.GetEngine(ctx).ID(t.ID).Cols("deleted").Update(t)
@ -310,7 +310,7 @@ func GetTrackedTimeByID(id int64) (*TrackedTime, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
return nil, db.ErrNotExist{ID: id} return nil, db.ErrNotExist{Resource: "tracked_time", ID: id}
} }
return time, nil return time, nil
} }

View File

@ -14,6 +14,8 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
_ "code.gitea.io/gitea/models/system"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
) )
@ -99,9 +100,9 @@ func InsertIssueComments(comments []*issues_model.Comment) error {
return nil return nil
} }
issueIDs := make(map[int64]bool) issueIDs := make(container.Set[int64])
for _, comment := range comments { for _, comment := range comments {
issueIDs[comment.IssueID] = true issueIDs.Add(comment.IssueID)
} }
ctx, committer, err := db.TxContext() ctx, committer, err := db.TxContext()

View File

@ -413,6 +413,10 @@ var migrations = []Migration{
NewMigration("Add badges to users", createUserBadgesTable), NewMigration("Add badges to users", createUserBadgesTable),
// v225 -> v226 // v225 -> v226
NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", alterPublicGPGKeyContentFieldsToMediumText), NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", alterPublicGPGKeyContentFieldsToMediumText),
// v226 -> v227
NewMigration("Conan and generic packages do not need to be semantically versioned", fixPackageSemverField),
// v227 -> v228
NewMigration("Create key/value table for system settings", createSystemSettingsTable),
} }
// GetCurrentDBVersion returns the current db version // GetCurrentDBVersion returns the current db version

View File

@ -13,6 +13,7 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -39,7 +40,7 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
} }
log.Info("%d User Avatar(s) to migrate ...", count) log.Info("%d User Avatar(s) to migrate ...", count)
deleteList := make(map[string]struct{}) deleteList := make(container.Set[string])
start := 0 start := 0
migrated := 0 migrated := 0
for { for {
@ -86,7 +87,7 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
return fmt.Errorf("[user: %s] user table update: %v", user.LowerName, err) return fmt.Errorf("[user: %s] user table update: %v", user.LowerName, err)
} }
deleteList[filepath.Join(setting.Avatar.Path, oldAvatar)] = struct{}{} deleteList.Add(filepath.Join(setting.Avatar.Path, oldAvatar))
migrated++ migrated++
select { select {
case <-ticker.C: case <-ticker.C:

15
models/migrations/v226.go Normal file
View File

@ -0,0 +1,15 @@
// 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 migrations
import (
"xorm.io/builder"
"xorm.io/xorm"
)
func fixPackageSemverField(x *xorm.Engine) error {
_, err := x.Exec(builder.Update(builder.Eq{"semver_compatible": false}).From("`package`").Where(builder.In("`type`", "conan", "generic")))
return err
}

64
models/migrations/v227.go Normal file
View File

@ -0,0 +1,64 @@
// 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 migrations
import (
"fmt"
"strconv"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/xorm"
)
type SystemSetting struct {
ID int64 `xorm:"pk autoincr"`
SettingKey string `xorm:"varchar(255) unique"` // ensure key is always lowercase
SettingValue string `xorm:"text"`
Version int `xorm:"version"` // prevent to override
Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"`
}
func insertSettingsIfNotExist(x *xorm.Engine, sysSettings []*SystemSetting) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
for _, setting := range sysSettings {
exist, err := sess.Table("system_setting").Where("setting_key=?", setting.SettingKey).Exist()
if err != nil {
return err
}
if !exist {
if _, err := sess.Insert(setting); err != nil {
return err
}
}
}
return sess.Commit()
}
func createSystemSettingsTable(x *xorm.Engine) error {
if err := x.Sync2(new(SystemSetting)); err != nil {
return fmt.Errorf("sync2: %v", err)
}
// migrate xx to database
sysSettings := []*SystemSetting{
{
SettingKey: "picture.disable_gravatar",
SettingValue: strconv.FormatBool(setting.DisableGravatar),
},
{
SettingKey: "picture.enable_federated_avatar",
SettingValue: strconv.FormatBool(setting.EnableFederatedAvatar),
},
}
return insertSettingsIfNotExist(x, sysSettings)
}

View File

@ -18,6 +18,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder" "xorm.io/builder"
) )
@ -45,6 +46,10 @@ func (err ErrOrgNotExist) Error() string {
return fmt.Sprintf("org does not exist [id: %d, name: %s]", err.ID, err.Name) return fmt.Sprintf("org does not exist [id: %d, name: %s]", err.ID, err.Name)
} }
func (err ErrOrgNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrLastOrgOwner represents a "LastOrgOwner" kind of error. // ErrLastOrgOwner represents a "LastOrgOwner" kind of error.
type ErrLastOrgOwner struct { type ErrLastOrgOwner struct {
UID int64 UID int64
@ -73,6 +78,10 @@ func (err ErrUserNotAllowedCreateOrg) Error() string {
return "user is not allowed to create organizations" return "user is not allowed to create organizations"
} }
func (err ErrUserNotAllowedCreateOrg) Unwrap() error {
return util.ErrPermissionDenied
}
// Organization represents an organization // Organization represents an organization
type Organization user_model.User type Organization user_model.User

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder" "xorm.io/builder"
) )
@ -43,6 +44,10 @@ func (err ErrTeamAlreadyExist) Error() string {
return fmt.Sprintf("team already exists [org_id: %d, name: %s]", err.OrgID, err.Name) return fmt.Sprintf("team already exists [org_id: %d, name: %s]", err.OrgID, err.Name)
} }
func (err ErrTeamAlreadyExist) Unwrap() error {
return util.ErrAlreadyExist
}
// ErrTeamNotExist represents a "TeamNotExist" error // ErrTeamNotExist represents a "TeamNotExist" error
type ErrTeamNotExist struct { type ErrTeamNotExist struct {
OrgID int64 OrgID int64
@ -60,6 +65,10 @@ func (err ErrTeamNotExist) Error() string {
return fmt.Sprintf("team does not exist [org_id %d, team_id %d, name: %s]", err.OrgID, err.TeamID, err.Name) return fmt.Sprintf("team does not exist [org_id %d, team_id %d, name: %s]", err.OrgID, err.TeamID, err.Name)
} }
func (err ErrTeamNotExist) Unwrap() error {
return util.ErrNotExist
}
// OwnerTeamName return the owner team name // OwnerTeamName return the owner team name
const OwnerTeamName = "Owners" const OwnerTeamName = "Owners"

View File

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/modules/container"
conan_module "code.gitea.io/gitea/modules/packages/conan" conan_module "code.gitea.io/gitea/modules/packages/conan"
"xorm.io/builder" "xorm.io/builder"
@ -88,7 +89,7 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er
return nil, err return nil, err
} }
unique := make(map[string]bool) unique := make(container.Set[string])
for _, info := range results { for _, info := range results {
recipe := fmt.Sprintf("%s/%s", info.Name, info.Version) recipe := fmt.Sprintf("%s/%s", info.Name, info.Version)
@ -111,7 +112,7 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er
} }
} }
unique[recipe] = true unique.Add(recipe)
} }
recipes := make([]string, 0, len(unique)) recipes := make([]string, 0, len(unique))

View File

@ -55,6 +55,10 @@ func (err ErrProjectNotExist) Error() string {
return fmt.Sprintf("projects does not exist [id: %d]", err.ID) return fmt.Sprintf("projects does not exist [id: %d]", err.ID)
} }
func (err ErrProjectNotExist) Unwrap() error {
return util.ErrNotExist
}
// ErrProjectBoardNotExist represents a "ProjectBoardNotExist" kind of error. // ErrProjectBoardNotExist represents a "ProjectBoardNotExist" kind of error.
type ErrProjectBoardNotExist struct { type ErrProjectBoardNotExist struct {
BoardID int64 BoardID int64
@ -70,6 +74,10 @@ func (err ErrProjectBoardNotExist) Error() string {
return fmt.Sprintf("project board does not exist [id: %d]", err.BoardID) return fmt.Sprintf("project board does not exist [id: %d]", err.BoardID)
} }
func (err ErrProjectBoardNotExist) Unwrap() error {
return util.ErrNotExist
}
// Project represents a project board // Project represents a project board
type Project struct { type Project struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`

View File

@ -90,7 +90,7 @@ func DeleteScheduledAutoMerge(ctx context.Context, pullID int64) error {
if err != nil { if err != nil {
return err return err
} else if !exist { } else if !exist {
return db.ErrNotExist{ID: pullID} return db.ErrNotExist{Resource: "auto_merge", ID: pullID}
} }
_, err = db.GetEngine(ctx).ID(scheduledPRM.ID).Delete(&AutoMerge{}) _, err = db.GetEngine(ctx).ID(scheduledPRM.ID).Delete(&AutoMerge{})

View File

@ -22,6 +22,7 @@ import (
access_model "code.gitea.io/gitea/models/perm/access" access_model "code.gitea.io/gitea/models/perm/access"
project_model "code.gitea.io/gitea/models/project" project_model "code.gitea.io/gitea/models/project"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/models/webhook"
@ -32,9 +33,13 @@ import (
"xorm.io/builder" "xorm.io/builder"
) )
// NewRepoContext creates a new repository context // ItemsPerPage maximum items per page in forks, watchers and stars of a repo
func NewRepoContext() { var ItemsPerPage = 40
// Init initialize model
func Init() error {
unit.LoadUnitConfig() unit.LoadUnitConfig()
return system_model.Init()
} }
// DeleteRepository deletes a repository for a user or organization. // DeleteRepository deletes a repository for a user or organization.
@ -163,7 +168,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
} }
// Delete issue index // Delete issue index
if err := db.DeleteResouceIndex(ctx, "issue_index", repoID); err != nil { if err := db.DeleteResourceIndex(ctx, "issue_index", repoID); err != nil {
return err return err
} }
@ -267,36 +272,36 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
// Remove repository files. // Remove repository files.
repoPath := repo.RepoPath() repoPath := repo.RepoPath()
admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete repository files", repoPath) system_model.RemoveAllWithNotice(db.DefaultContext, "Delete repository files", repoPath)
// Remove wiki files // Remove wiki files
if repo.HasWiki() { if repo.HasWiki() {
admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete repository wiki", repo.WikiPath()) system_model.RemoveAllWithNotice(db.DefaultContext, "Delete repository wiki", repo.WikiPath())
} }
// Remove archives // Remove archives
for _, archive := range archivePaths { for _, archive := range archivePaths {
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.RepoArchives, "Delete repo archive file", archive) system_model.RemoveStorageWithNotice(db.DefaultContext, storage.RepoArchives, "Delete repo archive file", archive)
} }
// Remove lfs objects // Remove lfs objects
for _, lfsObj := range lfsPaths { for _, lfsObj := range lfsPaths {
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.LFS, "Delete orphaned LFS file", lfsObj) system_model.RemoveStorageWithNotice(db.DefaultContext, storage.LFS, "Delete orphaned LFS file", lfsObj)
} }
// Remove issue attachment files. // Remove issue attachment files.
for _, attachment := range attachmentPaths { for _, attachment := range attachmentPaths {
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", attachment) system_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", attachment)
} }
// Remove release attachment files. // Remove release attachment files.
for _, releaseAttachment := range releaseAttachments { for _, releaseAttachment := range releaseAttachments {
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete release attachment", releaseAttachment) system_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete release attachment", releaseAttachment)
} }
// Remove attachment with no issue_id and release_id. // Remove attachment with no issue_id and release_id.
for _, newAttachment := range newAttachmentPaths { for _, newAttachment := range newAttachmentPaths {
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", newAttachment) system_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", newAttachment)
} }
if len(repo.Avatar) > 0 { if len(repo.Avatar) > 0 {
@ -438,15 +443,27 @@ func CheckRepoStats(ctx context.Context) error {
repoStatsCorrectNumStars, repoStatsCorrectNumStars,
"repository count 'num_stars'", "repository count 'num_stars'",
}, },
// Repository.NumIssues
{
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", false, false),
repoStatsCorrectNumIssues,
"repository count 'num_issues'",
},
// Repository.NumClosedIssues // Repository.NumClosedIssues
{ {
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, false), statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, false),
repoStatsCorrectNumClosedIssues, repoStatsCorrectNumClosedIssues,
"repository count 'num_closed_issues'", "repository count 'num_closed_issues'",
}, },
// Repository.NumPulls
{
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", false, true),
repoStatsCorrectNumPulls,
"repository count 'num_pulls'",
},
// Repository.NumClosedPulls // Repository.NumClosedPulls
{ {
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true), statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true),
repoStatsCorrectNumClosedPulls, repoStatsCorrectNumClosedPulls,
"repository count 'num_closed_pulls'", "repository count 'num_closed_pulls'",
}, },

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