Merge branch 'main' into access-token-scope
This commit is contained in:
commit
fca8b7974e
698 changed files with 14614 additions and 10619 deletions
28
.drone.yml
28
.drone.yml
|
@ -100,7 +100,7 @@ steps:
|
|||
- name: checks-backend
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- make checks-backend
|
||||
- make --always-make checks-backend # ensure the 'go-licenses' make target runs
|
||||
depends_on: [deps-backend]
|
||||
volumes:
|
||||
- name: deps
|
||||
|
@ -112,16 +112,11 @@ steps:
|
|||
- make test-frontend
|
||||
depends_on: [lint-frontend]
|
||||
|
||||
- name: generate-frontend
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- make generate-frontend
|
||||
|
||||
- name: build-frontend
|
||||
image: node:18
|
||||
commands:
|
||||
- make frontend
|
||||
depends_on: [deps-frontend, generate-frontend]
|
||||
depends_on: [deps-frontend]
|
||||
|
||||
- name: build-backend-no-gcc
|
||||
image: golang:1.18 # this step is kept as the lowest version of golang that we support
|
||||
|
@ -549,16 +544,11 @@ steps:
|
|||
commands:
|
||||
- make deps-frontend
|
||||
|
||||
- name: generate-frontend
|
||||
image: golang:1.18
|
||||
commands:
|
||||
- make generate-frontend
|
||||
|
||||
- name: build-frontend
|
||||
image: node:18
|
||||
commands:
|
||||
- make frontend
|
||||
depends_on: [deps-frontend, generate-frontend]
|
||||
depends_on: [deps-frontend]
|
||||
|
||||
- name: deps-backend
|
||||
image: golang:1.18
|
||||
|
@ -571,9 +561,9 @@ steps:
|
|||
|
||||
# TODO: We should probably build all dependencies into a test image
|
||||
- name: test-e2e
|
||||
image: mcr.microsoft.com/playwright:v1.24.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.27.1-focal
|
||||
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
|
||||
- apt-get -qq update && apt-get -qqy install build-essential
|
||||
- export TEST_PGSQL_SCHEMA=''
|
||||
|
@ -636,6 +626,8 @@ steps:
|
|||
commit_message: "[skip ci] Updated translations via Crowdin"
|
||||
remote: "git@github.com:go-gitea/gitea.git"
|
||||
environment:
|
||||
DRONE_COMMIT_AUTHOR_EMAIL: "teabot@gitea.io"
|
||||
DRONE_COMMIT_AUTHOR: GiteaBot
|
||||
GIT_PUSH_SSH_KEY:
|
||||
from_secret: git_push_ssh_key
|
||||
|
||||
|
@ -680,12 +672,14 @@ steps:
|
|||
pull: always
|
||||
settings:
|
||||
author_email: "teabot@gitea.io"
|
||||
author_name: GiteaBot
|
||||
author_name: "GiteaBot"
|
||||
branch: main
|
||||
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"
|
||||
environment:
|
||||
DRONE_COMMIT_AUTHOR_EMAIL: "teabot@gitea.io"
|
||||
DRONE_COMMIT_AUTHOR: "GiteaBot"
|
||||
GIT_PUSH_SSH_KEY:
|
||||
from_secret: git_push_ssh_key
|
||||
|
||||
|
|
|
@ -35,9 +35,6 @@ overrides:
|
|||
rules:
|
||||
import/no-unresolved: [0]
|
||||
import/no-extraneous-dependencies: [0]
|
||||
- files: ["*.test.js"]
|
||||
env:
|
||||
jest: true
|
||||
- files: ["*.config.js"]
|
||||
rules:
|
||||
import/no-unused-modules: [0]
|
||||
|
@ -185,6 +182,7 @@ rules:
|
|||
linebreak-style: [2, unix]
|
||||
lines-around-comment: [0]
|
||||
lines-between-class-members: [0]
|
||||
logical-assignment-operators: [0]
|
||||
max-classes-per-file: [0]
|
||||
max-depth: [0]
|
||||
max-len: [0]
|
||||
|
@ -245,7 +243,7 @@ rules:
|
|||
no-floating-decimal: [0]
|
||||
no-func-assign: [2]
|
||||
no-global-assign: [2]
|
||||
no-implicit-coercion: [0]
|
||||
no-implicit-coercion: [2]
|
||||
no-implicit-globals: [0]
|
||||
no-implied-eval: [2]
|
||||
no-import-assign: [2]
|
||||
|
@ -256,7 +254,7 @@ rules:
|
|||
no-irregular-whitespace: [2]
|
||||
no-iterator: [2]
|
||||
no-label-var: [2]
|
||||
no-labels: [2]
|
||||
no-labels: [0]
|
||||
no-lone-blocks: [2]
|
||||
no-lonely-if: [0]
|
||||
no-loop-func: [0]
|
||||
|
@ -322,7 +320,7 @@ rules:
|
|||
no-unused-private-class-members: [2]
|
||||
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-useless-backreference: [0]
|
||||
no-useless-backreference: [2]
|
||||
no-useless-call: [2]
|
||||
no-useless-catch: [2]
|
||||
no-useless-computed-key: [2]
|
||||
|
@ -335,7 +333,7 @@ rules:
|
|||
no-void: [2]
|
||||
no-warning-comments: [0]
|
||||
no-whitespace-before-property: [2]
|
||||
no-with: [2]
|
||||
no-with: [0]
|
||||
nonblock-statement-body-position: [2]
|
||||
object-curly-newline: [0]
|
||||
object-curly-spacing: [2, never]
|
||||
|
@ -353,7 +351,7 @@ rules:
|
|||
prefer-named-capture-group: [0]
|
||||
prefer-numeric-literals: [2]
|
||||
prefer-object-has-own: [0]
|
||||
prefer-object-spread: [0]
|
||||
prefer-object-spread: [2]
|
||||
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
|
||||
prefer-regex-literals: [2]
|
||||
prefer-rest-params: [2]
|
||||
|
@ -380,11 +378,11 @@ rules:
|
|||
sonarjs/no-duplicated-branches: [0]
|
||||
sonarjs/no-element-overwrite: [2]
|
||||
sonarjs/no-empty-collection: [2]
|
||||
sonarjs/no-extra-arguments: [0]
|
||||
sonarjs/no-extra-arguments: [2]
|
||||
sonarjs/no-gratuitous-expressions: [2]
|
||||
sonarjs/no-identical-conditions: [2]
|
||||
sonarjs/no-identical-expressions: [0]
|
||||
sonarjs/no-identical-functions: [0]
|
||||
sonarjs/no-identical-expressions: [2]
|
||||
sonarjs/no-identical-functions: [2, 5]
|
||||
sonarjs/no-ignored-return: [2]
|
||||
sonarjs/no-inverted-boolean-check: [2]
|
||||
sonarjs/no-nested-switch: [0]
|
||||
|
@ -396,7 +394,7 @@ rules:
|
|||
sonarjs/no-small-switch: [0]
|
||||
sonarjs/no-unused-collection: [2]
|
||||
sonarjs/no-use-of-empty-return-value: [2]
|
||||
sonarjs/no-useless-catch: [0]
|
||||
sonarjs/no-useless-catch: [2]
|
||||
sonarjs/non-existent-operator: [2]
|
||||
sonarjs/prefer-immediate-return: [0]
|
||||
sonarjs/prefer-object-literal: [0]
|
||||
|
@ -455,6 +453,7 @@ rules:
|
|||
unicorn/no-static-only-class: [2]
|
||||
unicorn/no-thenable: [2]
|
||||
unicorn/no-this-assignment: [2]
|
||||
unicorn/no-unnecessary-await: [2]
|
||||
unicorn/no-unreadable-array-destructuring: [0]
|
||||
unicorn/no-unreadable-iife: [2]
|
||||
unicorn/no-unsafe-regex: [0]
|
||||
|
@ -519,6 +518,7 @@ rules:
|
|||
unicorn/require-number-to-fixed-digits-argument: [2]
|
||||
unicorn/require-post-message-target-origin: [0]
|
||||
unicorn/string-content: [0]
|
||||
unicorn/switch-case-braces: [0]
|
||||
unicorn/template-indent: [2]
|
||||
unicorn/text-encoding-identifier-case: [0]
|
||||
unicorn/throw-new-error: [2]
|
||||
|
|
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -1,5 +1,6 @@
|
|||
* text=auto eol=lf
|
||||
*.tmpl linguist-language=Handlebars
|
||||
/assets/*.json linguist-generated
|
||||
/public/vendor/** -text -eol linguist-vendored
|
||||
/vendor/** -text -eol linguist-vendored
|
||||
/web_src/fomantic/build/** linguist-generated
|
||||
|
|
42
.gitpod.yml
Normal file
42
.gitpod.yml
Normal file
|
@ -0,0 +1,42 @@
|
|||
tasks:
|
||||
- name: Setup
|
||||
init: |
|
||||
cp -r contrib/ide/vscode .vscode
|
||||
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
|
||||
- alexcvzz.vscode-sqlite
|
||||
|
||||
ports:
|
||||
- name: Gitea
|
||||
port: 3000
|
||||
- name: Docs
|
||||
port: 1313
|
|
@ -12,7 +12,6 @@ linters:
|
|||
- dupl
|
||||
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
|
||||
- gofmt
|
||||
- misspell
|
||||
- gocritic
|
||||
- bidichk
|
||||
- ineffassign
|
||||
|
@ -148,9 +147,6 @@ issues:
|
|||
- path: models/issue_comment_list.go
|
||||
linters:
|
||||
- dupl
|
||||
- linters:
|
||||
- misspell
|
||||
text: '`Unknwon` is a misspelling of `Unknown`'
|
||||
- path: models/update.go
|
||||
linters:
|
||||
- unused
|
||||
|
|
|
@ -16,6 +16,7 @@ rules:
|
|||
declaration-empty-line-before: null
|
||||
function-no-unknown: null
|
||||
hue-degree-notation: null
|
||||
import-notation: string
|
||||
indentation: 2
|
||||
max-line-length: null
|
||||
no-descending-specificity: null
|
||||
|
|
80
CHANGELOG.md
80
CHANGELOG.md
|
@ -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
|
||||
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
|
||||
|
||||
* SECURITY
|
||||
|
|
|
@ -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.
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
- **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/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.
|
||||
- **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.)
|
||||
- **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.
|
||||
- **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.
|
||||
|
||||
## 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
|
||||
|
||||
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)
|
||||
- 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
|
||||
|
||||
Occasionally backports of PRs are required.
|
||||
|
|
|
@ -49,3 +49,4 @@ silentcode <silentcode@senga.org> (@silentcodeg)
|
|||
Wim <wim@42.be> (@42wim)
|
||||
xinyu <xinyu@nerv.org.cn> (@penlinux)
|
||||
Jason Song <i@wolfogre.com> (@wolfogre)
|
||||
Yarden Shoham <hrsi88@gmail.com> (@yardenshoham)
|
||||
|
|
48
Makefile
48
Makefile
|
@ -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)
|
||||
|
||||
GO_DIRS := cmd tests models modules routers build services tools
|
||||
WEB_DIRS := web_src/js web_src/less
|
||||
|
||||
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)
|
||||
|
@ -263,11 +264,24 @@ clean:
|
|||
|
||||
.PHONY: 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'))
|
||||
@# strip whitespace after '{{' and before `}}` unless there is only whitespace before it
|
||||
@$(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
|
||||
vet:
|
||||
@echo "Running go vet..."
|
||||
|
@ -311,22 +325,6 @@ errcheck:
|
|||
@echo "Running errcheck..."
|
||||
$(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
|
||||
checks: checks-frontend checks-backend
|
||||
|
||||
|
@ -334,14 +332,14 @@ checks: checks-frontend checks-backend
|
|||
checks-frontend: lockfile-check svg-check
|
||||
|
||||
.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
|
||||
lint: lint-frontend lint-backend
|
||||
|
||||
.PHONY: lint-frontend
|
||||
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 spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||
npx markdownlint docs *.md
|
||||
|
@ -372,7 +370,7 @@ test-backend:
|
|||
|
||||
.PHONY: test-frontend
|
||||
test-frontend: node_modules
|
||||
@NODE_OPTIONS="--experimental-vm-modules --no-warnings" npx jest --color
|
||||
npx vitest
|
||||
|
||||
.PHONY: test-check
|
||||
test-check:
|
||||
|
@ -406,6 +404,7 @@ unit-test-coverage:
|
|||
tidy:
|
||||
$(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)
|
||||
@$(MAKE) --no-print-directory $(GO_LICENSE_FILE)
|
||||
|
||||
vendor: go.mod go.sum
|
||||
$(GO) mod vendor
|
||||
|
@ -413,7 +412,7 @@ vendor: go.mod go.sum
|
|||
|
||||
.PHONY: tidy-check
|
||||
tidy-check: tidy
|
||||
@diff=$$(git diff go.mod go.sum); \
|
||||
@diff=$$(git diff go.mod go.sum $(GO_LICENSE_FILE)); \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "Please run 'make tidy' and commit the result:"; \
|
||||
echo "$${diff}"; \
|
||||
|
@ -709,17 +708,14 @@ install: $(wildcard *.go)
|
|||
build: frontend backend
|
||||
|
||||
.PHONY: frontend
|
||||
frontend: generate-frontend $(WEBPACK_DEST)
|
||||
frontend: $(WEBPACK_DEST)
|
||||
|
||||
.PHONY: backend
|
||||
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
|
||||
.PHONY: generate
|
||||
generate: generate-backend generate-frontend
|
||||
|
||||
.PHONY: generate-frontend
|
||||
generate-frontend: $(GO_LICENSE_FILE)
|
||||
generate: generate-backend
|
||||
|
||||
.PHONY: generate-backend
|
||||
generate-backend: $(TAGS_PREREQ) generate-go
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||
</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">
|
||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||
</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/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://cynkra.com/" target="_blank"><img src="https://images.opencollective.com/cynkra/logo/square/64/192.png"></a>
|
||||
|
||||
## FAQ
|
||||
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||
</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">
|
||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||
</a>
|
||||
|
|
18
assets/go-licenses.json
generated
18
assets/go-licenses.json
generated
File diff suppressed because one or more lines are too long
|
@ -20,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
// 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.
|
||||
|
||||
|
@ -195,7 +195,6 @@ Options:
|
|||
|
||||
Commands:
|
||||
%[1]s gofmt ...
|
||||
%[1]s misspell ...
|
||||
|
||||
Arguments:
|
||||
{file-list} the file list
|
||||
|
@ -206,6 +205,17 @@ Example:
|
|||
`, "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) {
|
||||
fileFilter := mainOptions["file-filter"]
|
||||
if fileFilter == "" {
|
||||
|
@ -228,9 +238,9 @@ func containsString(a []string, s string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func giteaFormatGoImports(files []string, hasChangedFiles, doWriteFile bool) error {
|
||||
func giteaFormatGoImports(files []string, doWriteFile bool) error {
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
@ -269,10 +279,8 @@ func main() {
|
|||
if containsString(subArgs, "-d") {
|
||||
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, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", "1.17"}, substArgs...)))
|
||||
case "misspell":
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("MISSPELL_PACKAGE")}, substArgs...)))
|
||||
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-w")))
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", getGoVersion()}, substArgs...)))
|
||||
default:
|
||||
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ package codeformat
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
|
@ -159,7 +158,7 @@ func formatGoImports(contentBytes []byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -183,10 +182,6 @@ func FormatGoImports(file string, doChangedFiles, doWriteFile bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if doChangedFiles {
|
||||
fmt.Println(file)
|
||||
}
|
||||
|
||||
if doWriteFile {
|
||||
f, err = os.OpenFile(file, os.O_TRUNC|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
|
|
|
@ -588,7 +588,7 @@ func runCreateUser(c *cli.Context) error {
|
|||
}
|
||||
|
||||
if err := user_model.CreateUser(u, overwriteDefault); err != nil {
|
||||
return fmt.Errorf("CreateUser: %v", err)
|
||||
return fmt.Errorf("CreateUser: %w", err)
|
||||
}
|
||||
|
||||
if c.Bool("access-token") {
|
||||
|
@ -735,7 +735,7 @@ func runRepoSyncReleases(_ *cli.Context) error {
|
|||
Private: true,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("SearchRepositoryByName: %v", err)
|
||||
return fmt.Errorf("SearchRepositoryByName: %w", err)
|
||||
}
|
||||
if len(repos) == 0 {
|
||||
break
|
||||
|
|
|
@ -68,7 +68,7 @@ Ensure you are running in the correct environment or set the correct configurati
|
|||
If this is the intended configuration file complete the [database] section.`, setting.CustomConf)
|
||||
}
|
||||
if err := db.InitEngine(ctx); err != nil {
|
||||
return fmt.Errorf("unable to initialize the database using the configuration in %q. Error: %v", setting.CustomConf, err)
|
||||
return fmt.Errorf("unable to initialize the database using the configuration in %q. Error: %w", setting.CustomConf, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -146,6 +146,10 @@ It can be used for backup and capture Gitea server image to send to maintainer`,
|
|||
Name: "skip-package-data",
|
||||
Usage: "Skip package data",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "skip-index",
|
||||
Usage: "Skip bleve index data",
|
||||
},
|
||||
cli.GenericFlag{
|
||||
Name: "type",
|
||||
Value: outputTypeEnum,
|
||||
|
@ -327,6 +331,11 @@ func runDump(ctx *cli.Context) error {
|
|||
excludes = append(excludes, opts.ProviderConfig)
|
||||
}
|
||||
|
||||
if ctx.IsSet("skip-index") && ctx.Bool("skip-index") {
|
||||
excludes = append(excludes, setting.Indexer.RepoPath)
|
||||
excludes = append(excludes, setting.Indexer.IssuePath)
|
||||
}
|
||||
|
||||
excludes = append(excludes, setting.RepoRootPath)
|
||||
excludes = append(excludes, setting.LFS.Path)
|
||||
excludes = append(excludes, setting.Attachment.Path)
|
||||
|
|
|
@ -166,7 +166,7 @@ func runDumpRepository(ctx *cli.Context) error {
|
|||
// make sure the directory doesn't exist or is empty, prevent from deleting user files
|
||||
repoDir := ctx.String("repo_dir")
|
||||
if exists, err := util.IsExist(repoDir); err != nil {
|
||||
return fmt.Errorf("unable to stat repo_dir %q: %v", repoDir, err)
|
||||
return fmt.Errorf("unable to stat repo_dir %q: %w", repoDir, err)
|
||||
} else if exists {
|
||||
if isDir, _ := util.IsDir(repoDir); !isDir {
|
||||
return fmt.Errorf("repo_dir %q already exists but it's not a directory", repoDir)
|
||||
|
|
|
@ -186,11 +186,11 @@ func runViewDo(c *cli.Context) error {
|
|||
|
||||
data, err := assets[0].Section.Asset(assets[0].Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %v", assets[0].Path, err)
|
||||
return fmt.Errorf("%s: %w", assets[0].Path, err)
|
||||
}
|
||||
|
||||
if _, err = os.Stdout.Write(data); err != nil {
|
||||
return fmt.Errorf("%s: %v", assets[0].Path, err)
|
||||
return fmt.Errorf("%s: %w", assets[0].Path, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -251,11 +251,11 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
|||
|
||||
data, err := a.Section.Asset(a.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %v", a.Path, err)
|
||||
return fmt.Errorf("%s: %w", a.Path, err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("%s: %v", dir, err)
|
||||
return fmt.Errorf("%s: %w", dir, err)
|
||||
}
|
||||
|
||||
perms := os.ModePerm & 0o666
|
||||
|
@ -263,7 +263,7 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
|||
fi, err := os.Lstat(dest)
|
||||
if err != nil {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("%s: %v", dest, err)
|
||||
return fmt.Errorf("%s: %w", dest, err)
|
||||
}
|
||||
} else if !overwrite && !rename {
|
||||
fmt.Printf("%s already exists; skipped.\n", dest)
|
||||
|
@ -272,7 +272,7 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
|||
return fmt.Errorf("%s already exists, but it's not a regular file", dest)
|
||||
} else if rename {
|
||||
if err := util.Rename(dest, dest+".bak"); err != nil {
|
||||
return fmt.Errorf("Error creating backup for %s: %v", dest, err)
|
||||
return fmt.Errorf("Error creating backup for %s: %w", dest, err)
|
||||
}
|
||||
// Attempt to respect file permissions mask (even if user:group will be set anew)
|
||||
perms = fi.Mode()
|
||||
|
@ -280,12 +280,12 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
|||
|
||||
file, err := os.OpenFile(dest, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, perms)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %v", dest, err)
|
||||
return fmt.Errorf("%s: %w", dest, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if _, err = file.Write(data); err != nil {
|
||||
return fmt.Errorf("%s: %v", dest, err)
|
||||
return fmt.Errorf("%s: %w", dest, err)
|
||||
}
|
||||
|
||||
fmt.Println(dest)
|
||||
|
@ -325,7 +325,7 @@ func getPatterns(args []string) ([]glob.Glob, error) {
|
|||
pat := make([]glob.Glob, len(args))
|
||||
for i := range args {
|
||||
if g, err := glob.Compile(args[i], '/'); err != nil {
|
||||
return nil, fmt.Errorf("'%s': Invalid glob pattern: %v", args[i], err)
|
||||
return nil, fmt.Errorf("'%s': Invalid glob pattern: %w", args[i], err)
|
||||
} else {
|
||||
pat[i] = g
|
||||
}
|
||||
|
|
|
@ -312,7 +312,7 @@ func runHookPostReceive(c *cli.Context) error {
|
|||
|
||||
// First of all run update-server-info no matter what
|
||||
if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil {
|
||||
return fmt.Errorf("Failed to call 'git update-server-info': %v", err)
|
||||
return fmt.Errorf("Failed to call 'git update-server-info': %w", err)
|
||||
}
|
||||
|
||||
// Now if we're an internal don't do anything else
|
||||
|
|
|
@ -203,7 +203,7 @@ func setPort(port string) error {
|
|||
defaultLocalURL += ":" + setting.HTTPPort + "/"
|
||||
|
||||
// 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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,14 +2,43 @@
|
|||
|
||||
DIR=/var/lib/gitea
|
||||
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}"
|
||||
command="/usr/local/bin/gitea"
|
||||
command_args="web -c /etc/gitea/app.ini"
|
||||
command_background=yes
|
||||
pidfile=/run/gitea.pid
|
||||
|
||||
depend()
|
||||
{
|
||||
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}"
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
|
@ -34,6 +33,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers"
|
||||
markup_service "code.gitea.io/gitea/services/markup"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/config"
|
||||
|
@ -62,11 +62,7 @@ func runPR() {
|
|||
}
|
||||
setting.AppWorkPath = curDir
|
||||
setting.StaticRootPath = curDir
|
||||
setting.GravatarSourceURL, err = url.Parse("https://secure.gravatar.com/avatar/")
|
||||
if err != nil {
|
||||
log.Fatalf("url.Parse: %v\n", err)
|
||||
}
|
||||
|
||||
setting.GravatarSource = "https://secure.gravatar.com/avatar/"
|
||||
setting.AppURL = "http://localhost:8080/"
|
||||
setting.HTTPPort = "8080"
|
||||
setting.SSH.Domain = "localhost"
|
||||
|
@ -117,7 +113,7 @@ func runPR() {
|
|||
log.Printf("[PR] Setting up router\n")
|
||||
// routers.GlobalInit()
|
||||
external.RegisterRenderers()
|
||||
markup.Init()
|
||||
markup.Init(markup_service.ProcessorHelper())
|
||||
c := routers.NormalRoutes(graceful.GetManager().HammerContext())
|
||||
|
||||
log.Printf("[PR] Ready for testing !\n")
|
||||
|
|
|
@ -49,12 +49,8 @@ After=network.target
|
|||
###
|
||||
|
||||
[Service]
|
||||
# Modify these two values and uncomment them if you have
|
||||
# repos with lots of files and get an HTTP error 500 because
|
||||
# of that
|
||||
###
|
||||
#LimitMEMLOCK=infinity
|
||||
#LimitNOFILE=65535
|
||||
# Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that
|
||||
# LimitNOFILE=524288:524288
|
||||
RestartSec=2s
|
||||
Type=simple
|
||||
User=git
|
||||
|
|
|
@ -379,14 +379,19 @@ LOG_SQL = false ; if unset defaults to true
|
|||
;; Whether the installer is disabled (set to true to disable the installer)
|
||||
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 =
|
||||
;;
|
||||
;; 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.
|
||||
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)
|
||||
;INTERNAL_TOKEN_URI = ;e.g. /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 = file:/etc/gitea/internal_token
|
||||
;;
|
||||
;; How long to remember that a user is logged in before requiring relogin (in days)
|
||||
;LOGIN_REMEMBER_DAYS = 7
|
||||
|
@ -882,7 +887,7 @@ ROUTER = console
|
|||
;USE_COMPAT_SSH_URI = false
|
||||
;;
|
||||
;; 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 =
|
||||
;;
|
||||
;; Comma separated list of default repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects.
|
||||
|
@ -2191,7 +2196,8 @@ ROUTER = console
|
|||
;SHOW_FOOTER_VERSION = true
|
||||
;; Show template execution time in the footer
|
||||
;SHOW_FOOTER_TEMPLATE_LOAD_TIME = true
|
||||
|
||||
;; Generate sitemap. Defaults to `true`.
|
||||
; ENABLE_SITEMAP = true
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -18,7 +18,7 @@ params:
|
|||
description: Git with a cup of tea
|
||||
author: The Gitea Authors
|
||||
website: https://docs.gitea.io
|
||||
version: 1.17.1
|
||||
version: 1.17.3
|
||||
minGoVersion: 1.18
|
||||
goVersion: 1.19
|
||||
minNodeVersion: 14
|
||||
|
|
|
@ -494,7 +494,8 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
|
|||
## Security (`security`)
|
||||
|
||||
- `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.
|
||||
- `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
|
||||
|
@ -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.
|
||||
- `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_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.
|
||||
- `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie.
|
||||
- `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`)
|
||||
|
||||
- `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.
|
||||
- `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
|
||||
- `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.
|
||||
- `ALLWAYS`: **false**: Set to true to use camo for both HTTP and HTTPS content, otherwise only non-HTTPS URLs are proxied
|
||||
|
||||
## OpenID (`openid`)
|
||||
|
||||
|
@ -809,9 +810,9 @@ Default templates for project boards:
|
|||
- `STACKTRACE_LEVEL`: **log.STACKTRACE_LEVEL**: Sets the log level at which to log stack traces.
|
||||
- `MODE`: **name**: Sets the mode of this sublogger - Defaults to the provided subsection name. This allows you to have two different file loggers at different levels.
|
||||
- `EXPRESSION`: **""**: A regular expression to match either the function name, file or message. Defaults to empty. Only log messages that match the expression will be saved in the logger.
|
||||
- `FLAGS`: **stdflags**: A comma separated string representing the log flags. Defaults to `stdflags` which represents the prefix: `2009/01/23 01:23:23 ...a/b/c/d.go:23:runtime.Caller() [I]: message`. `none` means don't prefix log lines. See `modules/log/base.go` for more information.
|
||||
- `FLAGS`: **stdflags**: A comma separated string representing the log flags. Defaults to `stdflags` which represents the prefix: `2009/01/23 01:23:23 ...a/b/c/d.go:23:runtime.Caller() [I]: message`. `none` means don't prefix log lines. See `modules/log/flags.go` for more information.
|
||||
- `PREFIX`: **""**: An additional prefix for every log line in this logger. Defaults to empty.
|
||||
- `COLORIZE`: **false**: Colorize the log lines by default
|
||||
- `COLORIZE`: **false**: Whether to colorize the log lines
|
||||
|
||||
### Console log mode (`log.console`, `log.console.*`, or `MODE=console`)
|
||||
|
||||
|
@ -1232,3 +1233,4 @@ PROXY_HOSTS = *.github.com
|
|||
- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.
|
||||
- `SHOW_FOOTER_VERSION`: **true**: Show Gitea and Go version information in the footer.
|
||||
- `SHOW_FOOTER_TEMPLATE_LOAD_TIME`: **true**: Show time of template execution in the footer.
|
||||
- `ENABLE_SITEMAP`: **true**: Generate sitemap.
|
||||
|
|
|
@ -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,
|
||||
|
||||
```go
|
||||
// servcies/repository/repo.go
|
||||
func CreateXXXX() error {\
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
// do something, if return err, it will rollback automatically when `committer.Close()` is invoked.
|
||||
if err := issues.UpdateIssue(ctx, repoID); err != nil {
|
||||
// ...
|
||||
}
|
||||
|
||||
// ......
|
||||
|
||||
return committer.Commit()
|
||||
// services/repository/repository.go
|
||||
func CreateXXXX() error {
|
||||
return db.WithTx(func(ctx context.Context) error {
|
||||
e := db.GetEngine(ctx)
|
||||
// do something, if err is returned, it will rollback automatically
|
||||
if err := issues.UpdateIssue(ctx, repoID); err != nil {
|
||||
// ...
|
||||
return err
|
||||
}
|
||||
// ...
|
||||
return nil
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -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 {
|
||||
e := db.GetEngine(ctx)
|
||||
|
||||
// ......
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Package Name
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ menu:
|
|||
|
||||
## 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).
|
||||
|
||||
|
@ -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.
|
||||
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[]{}`
|
||||
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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
### 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.
|
|
@ -19,6 +19,12 @@ menu:
|
|||
|
||||
{{< toc >}}
|
||||
|
||||
## Quickstart
|
||||
|
||||
To get a quick working development environment you could use Gitpod.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/go-gitea/gitea)
|
||||
|
||||
## Installing 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
|
||||
|
||||
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:
|
||||
|
||||
|
|
|
@ -44,6 +44,12 @@ To use the Authorization Code Grant as a third party application it is required
|
|||
|
||||
Currently Gitea does not support scopes (see [#4300](https://github.com/go-gitea/gitea/issues/4300)) and all third party applications will be granted access to all resources of the user and their organizations.
|
||||
|
||||
## Client types
|
||||
|
||||
Gitea supports both confidential and public client types, [as defined by RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1).
|
||||
|
||||
For public clients, a redirect URI of a loopback IP address such as `http://127.0.0.1/` allows any port. Avoid using `localhost`, [as recommended by RFC 8252](https://datatracker.ietf.org/doc/html/rfc8252#section-8.3).
|
||||
|
||||
## Example
|
||||
|
||||
**Note:** This example does not use PKCE.
|
||||
|
|
|
@ -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.
|
||||
|
||||
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:_
|
||||
|
||||
|
@ -33,103 +33,111 @@ _Symbols used in table:_
|
|||
|
||||
## General Features
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ----------------------------------- | ---------------------------------------------------| ---- | --------- | --------- | --------- | -------------- | ------------ |
|
||||
| Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
||||
| Low resource usage (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| Multiple database support | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
||||
| Multiple OS support | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ |
|
||||
| Easy upgrade process | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Orgmode support | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? |
|
||||
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
||||
| Static Git-powered pages | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
||||
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Built-in Package/Container Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||
| Built-in CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Subgroups: groups within groups | [✘](https://github.com/go-gitea/gitea/issues/1872) | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| Mermaid diagrams in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Math syntax in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ------------------------------------------------ | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
||||
| Low RAM/ CPU usage | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| Multiple database support | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
||||
| Multiple OS support | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ |
|
||||
| Easy upgrades | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| Telemetry | **✘** | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
||||
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||
| Extensive API | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Built-in Package/Container Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Sync commits to an external repo (push mirror) | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| Sync commits from an external repo (pull mirror) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ? |
|
||||
| Light and Dark Theme | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ? |
|
||||
| Custom Theme Support | ✓ | ✓ | ✘ | ✘ | ✘ | ✓ | ✘ |
|
||||
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||
| 'GitHub / GitLab pages' | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Repo-specific wiki (as a repo itself) | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 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
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| -------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Verified Committer | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SSH Signed Commits | ✓ | ✘ | ✘ | ✘ | ✘ | ? | ? |
|
||||
| Reject unsigned commits | [✓](https://github.com/go-gitea/gitea/pull/9708) | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Web code editor | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Commit graph | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Template Repositories | [✓](https://github.com/go-gitea/gitea/pull/8768) | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ------------------------------------------- | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Group Milestones | [✘](https://github.com/go-gitea/gitea/issues/14622) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Granular user roles (Code, Issues, Wiki, …) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Verified Committer | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SSH Signed Commits | ✓ | ✘ | ✓ | ✘ | ✘ | ? | ? |
|
||||
| Reject unsigned commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Migrating repos from other services | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Web code editor | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Commit graph | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Template Repositories | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
||||
| Git Blame | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Visual comparison of image changes | ✓ | ✘ | ✓ | ? | ? | ? | ? |
|
||||
|
||||
## Issue Tracker
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ------------------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | ----------------------------------------------------------------------- | --------- | -------------- | ------------ |
|
||||
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
||||
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Multiple assignees for issues | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
|
||||
| Related issues | ✘ | ✘ | ⁄ | [✓](https://docs.gitlab.com/ce/user/project/issues/related_issues.html) | ✓ | ✘ | ✘ |
|
||||
| Confidential issues | [✘](https://github.com/go-gitea/gitea/issues/3217) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Lock Discussion | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue Boards (Kanban) | [✓](https://github.com/go-gitea/gitea/pull/8346) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Create new branches from issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Global issue search | [✘](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| Create issue via email | [✘](https://github.com/go-gitea/gitea/issues/6226) | [✘](https://github.com/gogs/gogs/issues/2602) | ✘ | ✘ | ✓ | ✓ | ✘ |
|
||||
| Service Desk | [✘](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | [✓](https://gitlab.com/groups/gitlab-org/-/epics/3103) | ✓ | ✘ | ✘ |
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ----------------------------- | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Multiple assignees for issues | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
|
||||
| Related issues | ✘ | ✘ | ⁄ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Confidential issues | [✘](https://github.com/go-gitea/gitea/issues/3217) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Lock Discussion | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue Boards (Kanban) | [/](https://github.com/go-gitea/gitea/issues/14710) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Create branch from issue | [✘](https://github.com/go-gitea/gitea/issues/20226) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Convert comment to new issue | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Global issue search | [/](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| 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
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ----------------------------------------------- | -------------------------------------------------- | ---- | --------- | --------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------ | ------------ |
|
||||
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Squash merging | ✓ | ✘ | ✓ | [✓](https://docs.gitlab.com/ce/user/project/merge_requests/squash_and_merge.html) | ✓ | ✓ | ✓ |
|
||||
| Rebase merging | ✓ | ✓ | ✓ | ✘ | ⁄ | ✘ | ✓ |
|
||||
| Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Pull/Merge request approval | ✓ | ✘ | ⁄ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Merge conflict resolution | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | ⁄ | ✓ | ✓ | ✓ |
|
||||
| Revert specific commits or a merge request | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Cherry-picking changes | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | [/](https://jira.atlassian.com/plugins/servlet/mobile#issue/BCLOUD-8323) | ✘ |
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ----------------------------------------------- | -------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Squash merging | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Rebase merging | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Pull/Merge request approval | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Merge conflict resolution | [✘](https://github.com/go-gitea/gitea/issues/9014) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Revert specific commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Cherry-picking changes | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
|
||||
## 3rd-party integrations
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ---------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Webhook support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Custom Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||
| LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | [✘](https://github.com/gogs/gogs/issues/1221) | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| OpenId Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
|
||||
| OAuth 2.0 integration (external authorization) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ |
|
||||
| Act as OAuth 2.0 provider | [✓](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Mattermost/Slack integration | ✓ | ✓ | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
||||
| Discord integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Microsoft Teams integration | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| External CI/CD status display | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ---------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Webhooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||
| LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| OpenID Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
|
||||
| OAuth 2.0 integration (external authorization) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ |
|
||||
| Act as OAuth 2.0 provider | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Integration with the most common services | ✓ | / | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
||||
| Incorporate external CI/CD | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
|
|
|
@ -97,12 +97,12 @@ chown root:git /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:
|
||||
|
||||
```sh
|
||||
chmod 750 /etc/gitea
|
||||
chmod 640 /etc/gitea/app.ini
|
||||
```
|
||||
> **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
|
||||
> chmod 750 /etc/gitea
|
||||
> 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:
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ choco install gitea
|
|||
macOS 平台下当前我们仅支持通过 `brew` 来安装。如果你没有安装 [Homebrew](http://brew.sh/),你也可以查看 [从二进制安装]({{< relref "from-binary.zh-cn.md" >}})。在你安装了 `brew` 之后, 你可以执行以下命令:
|
||||
|
||||
```
|
||||
brew tap go-gitea/gitea
|
||||
brew tap gitea/tap https://gitea.com/gitea/homebrew-gitea
|
||||
brew install gitea
|
||||
```
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ menu:
|
|||
|
||||
# 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**
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
---
|
||||
date: "2021-09-02T16:00:00+08:00"
|
||||
title: "Upgrade from an old Gitea"
|
||||
aliases:
|
||||
- /en-us/upgrade/
|
||||
slug: "upgrade-from-gitea"
|
||||
weight: 10
|
||||
toc: false
|
||||
|
|
|
@ -13,6 +13,12 @@ menu:
|
|||
identifier: "reverse-proxies"
|
||||
---
|
||||
|
||||
# 反向代理
|
||||
|
||||
**目录**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## 使用 Nginx 作为反向代理服务
|
||||
|
||||
如果您想使用 Nginx 作为 Gitea 的反向代理服务,您可以参照以下 `nginx.conf` 配置中 `server` 的 `http` 部分:
|
||||
|
@ -24,6 +30,10 @@ server {
|
|||
|
||||
location / {
|
||||
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/ {
|
||||
# 注意: 反向代理后端 URL 的最后需要有一个路径符号
|
||||
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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -287,7 +287,7 @@ You can try it out using [the online demo](https://try.gitea.io/).
|
|||
- UI frameworks:
|
||||
- [jQuery](https://jquery.com)
|
||||
- [Fomantic UI](https://fomantic-ui.com)
|
||||
- [Vue2](https://vuejs.org)
|
||||
- [Vue3](https://vuejs.org)
|
||||
- and various components (see package.json)
|
||||
- Editors:
|
||||
- [CodeMirror](https://codemirror.net)
|
||||
|
|
|
@ -258,7 +258,7 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide
|
|||
- Interface graphique :
|
||||
- [jQuery](https://jquery.com)
|
||||
- [Fomantic UI](https://fomantic-ui.com)
|
||||
- [Vue2](https://vuejs.org)
|
||||
- [Vue3](https://vuejs.org)
|
||||
- [CodeMirror](https://codemirror.net)
|
||||
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
||||
- [Monaco Editor](https://microsoft.github.io/monaco-editor)
|
||||
|
|
|
@ -52,7 +52,7 @@ Gitea的首要目标是创建一个极易安装,运行非常快速,安装和
|
|||
- UI 框架:
|
||||
- [jQuery](https://jquery.com)
|
||||
- [Fomantic UI](https://fomantic-ui.com)
|
||||
- [Vue2](https://vuejs.org)
|
||||
- [Vue3](https://vuejs.org)
|
||||
- 更多组件参见 package.json
|
||||
- 编辑器:
|
||||
- [CodeMirror](https://codemirror.net)
|
||||
|
|
|
@ -271,7 +271,7 @@ Gitea 是從 [Gogs](http://gogs.io) Fork 出來的,請閱讀部落格文章 [G
|
|||
- UI 元件:
|
||||
- [jQuery](https://jquery.com)
|
||||
- [Fomantic UI](https://fomantic-ui.com)
|
||||
- [Vue2](https://vuejs.org)
|
||||
- [Vue3](https://vuejs.org)
|
||||
- [CodeMirror](https://codemirror.net)
|
||||
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
||||
- [Monaco Editor](https://microsoft.github.io/monaco-editor)
|
||||
|
|
4
docs/static/_redirects
vendored
4
docs/static/_redirects
vendored
|
@ -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/third-party-tools/ /en-us/integrations/ 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
23
docs/static/open-in-gitpod.svg
vendored
Normal 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 |
80
go.mod
80
go.mod
|
@ -6,7 +6,7 @@ require (
|
|||
code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b
|
||||
code.gitea.io/sdk/gitea v0.15.1
|
||||
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
|
||||
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb
|
||||
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681
|
||||
gitea.com/go-chi/cache v0.2.0
|
||||
gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
|
||||
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8
|
||||
|
@ -16,9 +16,9 @@ require (
|
|||
github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/PuerkitoBio/goquery v1.8.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/caddyserver/certmagic v0.17.0
|
||||
github.com/caddyserver/certmagic v0.17.2
|
||||
github.com/chi-middleware/proxy v1.1.1
|
||||
github.com/denisenkom/go-mssqldb v0.12.2
|
||||
github.com/djherbis/buffer v1.2.0
|
||||
|
@ -31,46 +31,46 @@ require (
|
|||
github.com/felixge/fgprof v0.9.3
|
||||
github.com/fsnotify/fsnotify v1.5.4
|
||||
github.com/gliderlabs/ssh v0.3.5
|
||||
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535
|
||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d
|
||||
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0
|
||||
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778
|
||||
github.com/go-chi/chi/v5 v5.0.7
|
||||
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-git/go-billy/v5 v5.3.1
|
||||
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-redis/redis/v8 v8.11.5
|
||||
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/gobwas/glob v0.2.3
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
|
||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||
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/uuid v1.3.0
|
||||
github.com/gorilla/feeds v1.1.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/huandu/xstrings v1.3.2
|
||||
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
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/lib/pq v1.10.6
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/markbates/goth v1.73.0
|
||||
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/microcosm-cc/bluemonday v1.0.20
|
||||
github.com/minio/minio-go/v7 v7.0.35
|
||||
github.com/msteinert/pam v1.0.0
|
||||
github.com/minio/minio-go/v7 v7.0.39
|
||||
github.com/msteinert/pam v1.1.0
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/niklasfasching/go-org v1.6.5
|
||||
github.com/oliamb/cutter v0.2.2
|
||||
|
@ -79,26 +79,26 @@ require (
|
|||
github.com/pquerna/otp v1.3.0
|
||||
github.com/prometheus/client_golang v1.13.0
|
||||
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/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tstranex/u2f v1.0.0
|
||||
github.com/unrolled/render v1.5.0
|
||||
github.com/urfave/cli v1.22.9
|
||||
github.com/urfave/cli v1.22.10
|
||||
github.com/xanzy/go-gitlab v0.73.1
|
||||
github.com/yohcop/openid-go v1.0.0
|
||||
github.com/yuin/goldmark v1.4.15
|
||||
github.com/yuin/goldmark v1.5.2
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87
|
||||
github.com/yuin/goldmark-meta v1.1.0
|
||||
go.jolheiser.com/hcaptcha v0.0.4
|
||||
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-20220927171203-f486391704dc
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
|
||||
golang.org/x/text v0.3.7
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
|
||||
golang.org/x/text v0.3.8
|
||||
golang.org/x/tools v0.1.12
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
|
@ -117,9 +117,9 @@ require (
|
|||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 // indirect
|
||||
github.com/RoaringBitmap/roaring v0.9.4 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad // indirect
|
||||
github.com/RoaringBitmap/roaring v1.2.1 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
|
@ -128,21 +128,22 @@ require (
|
|||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.2.2 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.3.3 // 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/gtreap v0.1.1 // indirect
|
||||
github.com/blevesearch/mmap-go v1.0.3 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.0 // indirect
|
||||
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.2 // indirect
|
||||
github.com/blevesearch/segment 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/vellum v1.0.7 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.3.3 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.3.3 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.3.3 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.3.3 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.3.3 // indirect
|
||||
github.com/blevesearch/vellum v1.0.8 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.3.5 // indirect
|
||||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||
|
@ -167,7 +168,7 @@ require (
|
|||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
|
||||
github.com/fullstorydev/grpcurl v1.8.1 // 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-enry/go-oniguruma v1.2.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
|
@ -186,6 +187,7 @@ require (
|
|||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // 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/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
|
@ -219,7 +221,7 @@ require (
|
|||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // 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/mholt/acmez v1.0.4 // indirect
|
||||
github.com/miekg/dns v1.1.50 // indirect
|
||||
|
@ -237,12 +239,12 @@ require (
|
|||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // 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/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.37.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/rs/xid v1.4.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/zap v1.23.0 // 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/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
|
||||
google.golang.org/grpc v1.47.0 // indirect
|
||||
|
|
157
go.sum
157
go.sum
|
@ -81,8 +81,8 @@ contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcig
|
|||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
|
||||
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb h1:Yy0Bxzc8R2wxiwXoG/rECGplJUSpXqCsog9PuJFgiHs=
|
||||
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc=
|
||||
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681 h1:MMSPgnVULVwV9kEBgvyEUhC9v/uviZ55hPJEMjpbNR4=
|
||||
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc=
|
||||
gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0=
|
||||
gitea.com/go-chi/cache v0.2.0 h1:E0npuTfDW6CT1yD8NMDVc1SK6IeRjfmRL2zlEsCEd7w=
|
||||
gitea.com/go-chi/cache v0.2.0/go.mod h1:iQlVK2aKTZ/rE9UcHyz9pQWGvdP9i1eI2spOpzgCrtE=
|
||||
|
@ -134,22 +134,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/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.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
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/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
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-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY=
|
||||
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/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||
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/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.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo=
|
||||
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/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=
|
||||
|
@ -218,28 +220,31 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
|
|||
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.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.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bits-and-blooms/bitset v1.3.3 h1:R1XWiopGiXf66xygsiLpzLo67xEYvMkHw3w+rCOSAwg=
|
||||
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/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.3.2 h1:BJUnMhi2nrkl+vboHmKfW+9l+tJSj39HeWa5c3BN3/Y=
|
||||
github.com/blevesearch/bleve/v2 v2.3.2/go.mod h1:96+xE5pZUOsr3Y4vHzV1cBC837xZCpwLlX0hrrxnvIg=
|
||||
github.com/blevesearch/bleve/v2 v2.3.4 h1:SSb7/cwGzo85LWX1jchIsXM8ZiNNMX3shT5lROM63ew=
|
||||
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.1 h1:nx9++0hnyiGOHJwQQYfsUGzpRdEVE5LsylmmngQvaFk=
|
||||
github.com/blevesearch/bleve_index_api v1.0.1/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
|
||||
github.com/blevesearch/bleve_index_api v1.0.3 h1:DDSWaPXOZZJ2BB73ZTWjKxydAugjwywcqU+91AAqcAg=
|
||||
github.com/blevesearch/bleve_index_api v1.0.3/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
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/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||
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/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
||||
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.3/go.mod h1:pYvKl/grLQrBxuaRYgoTssa4rVujYYeenDp++2E+yvs=
|
||||
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
||||
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.1.0 h1:NFwteOpZEvJk5Vg0H6gD0hxupsG3JYocE4DBvsA2GZI=
|
||||
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 h1:TAte9VZLWda5WAVlZTTZ+GCzEHqGJb4iB2aiZSA6Iv8=
|
||||
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/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
||||
github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg=
|
||||
|
@ -249,23 +254,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/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.7 h1:+vn8rfyCRHxKVRgDLeR0FAXej2+6mEb5Q15aQE/XESQ=
|
||||
github.com/blevesearch/vellum v1.0.7/go.mod h1:doBZpmRhwTsASB4QdUZANlJvqVAUdUyX0ZK7QJCTeBE=
|
||||
github.com/blevesearch/vellum v1.0.8 h1:iMGh4lfxza4BnWO/UJTMPlI3HsK9YawjPv+TteVa9ck=
|
||||
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.3.3 h1:8vQMO5hdA2qPCmicIMuKS+qcvUAEh6Vcb0uve4Nh8e4=
|
||||
github.com/blevesearch/zapx/v11 v11.3.3/go.mod h1:YzTfUm4kS3e8OmTXDHVV8OzC5MWPO/VPJZQgPNVb4Lc=
|
||||
github.com/blevesearch/zapx/v11 v11.3.5 h1:eBQWQ7huA+mzm0sAGnZDwgGGli7S45EO+N+ObFWssbI=
|
||||
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.3.3 h1:MQO5YNI8MqdPz12ALCoXiJw5cl9QQamYZSp285Z/+Mo=
|
||||
github.com/blevesearch/zapx/v12 v12.3.3/go.mod h1:RMl6lOZqF+sTxKvhQDJ5yK2LT3Mu7E2p/jGdjAaiRxs=
|
||||
github.com/blevesearch/zapx/v12 v12.3.5 h1:5pX2hU+R1aZihT7ac1dNWh1n4wqkIM9pZzWp0ANED9s=
|
||||
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.3.3 h1:TS4xpMK1ARPYHq+1WwuEOKMOiwvKpTK3RuWOkKlI7BE=
|
||||
github.com/blevesearch/zapx/v13 v13.3.3/go.mod h1:eppobNM35U4C22yDvTuxV9xPqo10pwfP/jugL4INWG4=
|
||||
github.com/blevesearch/zapx/v13 v13.3.5 h1:eJ3gbD+Nu8p36/O6lhfdvWQ4pxsGYSuTOBrLLPVWJ74=
|
||||
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.3.3 h1:dqqAzGphKl0yehHKKntDHKlEMhi9B/tJrD4OsWpY7YE=
|
||||
github.com/blevesearch/zapx/v14 v14.3.3/go.mod h1:zXNcVzukh0AvG57oUtT1T0ndi09H0kELNaNmekEy0jw=
|
||||
github.com/blevesearch/zapx/v14 v14.3.5 h1:hEvVjZaagFCvOUJrlFQ6/Z6Jjy0opM3g7TMEo58TwP4=
|
||||
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.3.3 h1:60oE+qsJkveLenJmbc0eaH59GWYCbJJsPDV6Z5hEoYY=
|
||||
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 h1:NVD0qq8vRk66ImJn1KloXT5ckqPDUZT7VbVJs9jKlac=
|
||||
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 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
|
@ -277,8 +282,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.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
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.0/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM=
|
||||
github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE=
|
||||
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/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=
|
||||
|
@ -466,12 +471,12 @@ 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/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/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535 h1:vzEChLhjI35zDlXG9KZnOMCHa9MRVaagS5IHJcagVRI=
|
||||
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535/go.mod h1:y3eWqPv2lYZ0YbAvEk4CGyFUJzbNsoLmkon8S7ZyX6I=
|
||||
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1 h1:PkPVIQGt76HHFWSeUINXCfYpEnzlSS+AQyuXi7oJ/gM=
|
||||
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1/go.mod h1:KHkKFKZvc05lr79+RGoq/zG8YjWi3+FK60Bxd+mpCew=
|
||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d h1:Z/oRXMlZHjvjIqDma1FrIGL3iE5YL7MUI0bwYEZ6qbA=
|
||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA=
|
||||
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0 h1:EUMB0x7u3de/ikGBtXiLxaJbmxgiqiAcM4yjW4whApM=
|
||||
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0/go.mod h1:OX9ajs2vU4UauC/DlghS/8M468Kn79r+y9kB6j7LuGM=
|
||||
github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18 h1:A48SbkWKEciiJMbbcPzaRj9aizPUABzXFvCM3LtGGf8=
|
||||
github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18/go.mod h1:dd3ZgjjloBsKPDpqA2kf2VWhF0A1eKUItOBh0/QcDWI=
|
||||
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778 h1:0tV3i8tE1NghMC4rXZXfD39KUbkKgIyLTsvOEmMOPCQ=
|
||||
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/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
|
@ -480,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/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||
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.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
||||
github.com/go-enry/go-enry/v2 v2.8.3 h1:BwvNrN58JqBJhyyVdZSl5QD3xoxEEGYUrRyPh31FGhw=
|
||||
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/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8=
|
||||
|
@ -559,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-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-swagger/go-swagger v0.30.0 h1:HakSyutD7Ek9ndkR8Fxy6WAoQtgu7UcAmZCTa6SzawA=
|
||||
github.com/go-swagger/go-swagger v0.30.0/go.mod h1:GhZVX/KIBM4VpGp4P7AJOIrlTuBeRVPS+j9kk6rFmfY=
|
||||
github.com/go-swagger/go-swagger v0.30.3 h1:HuzvdMRed/9Q8vmzVcfNBQByZVtT79DNZxZ18OprdoI=
|
||||
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-testfixtures/testfixtures/v3 v3.8.1 h1:uonwvepqRvSgddcrReZQhojTlWlmOlHkYAb9ZaOMWgU=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.8.1/go.mod h1:Kdu7YeMC0KRXVHdaQ91Vmx3pcjoTF63h4f1qTJDdXLA=
|
||||
|
@ -620,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/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
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-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
@ -687,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/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
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.0.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28=
|
||||
github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI=
|
||||
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-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
|
@ -696,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/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.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/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
|
@ -926,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/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/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.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
|
@ -961,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.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.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
|
||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
|
||||
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/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
|
@ -1001,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.10.1/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.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
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/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
|
@ -1052,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.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.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
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-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.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.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I=
|
||||
github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
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/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
|
@ -1078,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/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/minio-go/v7 v7.0.35 h1:JuPPxWLdxQmNLSaS8AWZnO5HBadeI1xg6FGrEELQEVU=
|
||||
github.com/minio/minio-go/v7 v7.0.35/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw=
|
||||
github.com/minio/minio-go/v7 v7.0.39 h1:upnbu1jCGOqEvrGSpRauSN9ZG7RCHK7VHxXS8Vmg2zk=
|
||||
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/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
|
@ -1119,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.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
||||
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.0.0/go.mod h1:M4FPeAW8g2ITO68W8gACDz13NDJyOQM9IQsQhrR6TOI=
|
||||
github.com/msteinert/pam v1.1.0 h1:VhLun/0n0kQYxiRBJJvVpC2jR6d21SWJFjpvUVj20Kc=
|
||||
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-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
|
||||
|
@ -1200,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 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.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
|
||||
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/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
@ -1272,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/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.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
|
||||
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
|
||||
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/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=
|
||||
|
@ -1297,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/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/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.1 h1:HNLA3HtUIROrQwG1cuu5EYuqk3UEoJ61Dr/9xkd6sok=
|
||||
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/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=
|
||||
|
@ -1433,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.4/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.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
|
||||
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/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
|
||||
|
@ -1470,8 +1479,9 @@ 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.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.15 h1:CFa84T0goNn/UIXYS+dmjjVxMyTAvpOmzld40N/nfK0=
|
||||
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU=
|
||||
github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87 h1:Py16JEzkSdKAtEFJjiaYLYBOWGXc1r/xHj/Q/5lA37k=
|
||||
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=
|
||||
|
@ -1598,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-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-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
|
||||
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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -1737,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-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-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8=
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
|
||||
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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -1866,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-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-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||
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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -1881,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.5/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.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-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-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-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-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
|
||||
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-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -359,11 +359,11 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, error) {
|
|||
actions := make([]*Action, 0, opts.PageSize)
|
||||
|
||||
if err := sess.Desc("`action`.created_unix").Find(&actions); err != nil {
|
||||
return nil, fmt.Errorf("Find: %v", err)
|
||||
return nil, fmt.Errorf("Find: %w", err)
|
||||
}
|
||||
|
||||
if err := ActionList(actions).loadAttributes(ctx); err != nil {
|
||||
return nil, fmt.Errorf("LoadAttributes: %v", err)
|
||||
return nil, fmt.Errorf("LoadAttributes: %w", err)
|
||||
}
|
||||
|
||||
return actions, nil
|
||||
|
@ -415,7 +415,7 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
|
|||
env := organization.OrgFromUser(opts.RequestedUser).AccessibleTeamReposEnv(opts.RequestedTeam)
|
||||
teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetTeamRepositories: %v", err)
|
||||
return nil, fmt.Errorf("GetTeamRepositories: %w", err)
|
||||
}
|
||||
cond = cond.And(builder.In("repo_id", teamRepoIDs))
|
||||
}
|
||||
|
@ -477,14 +477,14 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error {
|
|||
// Add feeds for user self and all watchers.
|
||||
watchers, err = repo_model.GetWatchers(ctx, act.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get watchers: %v", err)
|
||||
return fmt.Errorf("get watchers: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Add feed for actioner.
|
||||
act.UserID = act.ActUserID
|
||||
if _, err = e.Insert(act); err != nil {
|
||||
return fmt.Errorf("insert new actioner: %v", err)
|
||||
return fmt.Errorf("insert new actioner: %w", err)
|
||||
}
|
||||
|
||||
if repoChanged {
|
||||
|
@ -493,7 +493,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error {
|
|||
|
||||
// check repo owner exist.
|
||||
if err := act.Repo.GetOwner(ctx); err != nil {
|
||||
return fmt.Errorf("can't get repo owner: %v", err)
|
||||
return fmt.Errorf("can't get repo owner: %w", err)
|
||||
}
|
||||
} else if act.Repo == nil {
|
||||
act.Repo = repo
|
||||
|
@ -504,7 +504,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error {
|
|||
act.ID = 0
|
||||
act.UserID = act.Repo.Owner.ID
|
||||
if err = db.Insert(ctx, act); err != nil {
|
||||
return fmt.Errorf("insert new actioner: %v", err)
|
||||
return fmt.Errorf("insert new actioner: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error {
|
|||
}
|
||||
|
||||
if err = db.Insert(ctx, act); err != nil {
|
||||
return fmt.Errorf("insert new action: %v", err)
|
||||
return fmt.Errorf("insert new action: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,11 @@ import (
|
|||
type ActionList []*Action
|
||||
|
||||
func (actions ActionList) getUserIDs() []int64 {
|
||||
userIDs := make(map[int64]struct{}, len(actions))
|
||||
userIDs := make(container.Set[int64], len(actions))
|
||||
for _, action := range actions {
|
||||
if _, ok := userIDs[action.ActUserID]; !ok {
|
||||
userIDs[action.ActUserID] = struct{}{}
|
||||
}
|
||||
userIDs.Add(action.ActUserID)
|
||||
}
|
||||
return container.KeysInt64(userIDs)
|
||||
return userIDs.Values()
|
||||
}
|
||||
|
||||
func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) {
|
||||
|
@ -38,7 +36,7 @@ func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.
|
|||
In("id", userIDs).
|
||||
Find(&userMaps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("find user: %v", err)
|
||||
return nil, fmt.Errorf("find user: %w", err)
|
||||
}
|
||||
|
||||
for _, action := range actions {
|
||||
|
@ -48,13 +46,11 @@ func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.
|
|||
}
|
||||
|
||||
func (actions ActionList) getRepoIDs() []int64 {
|
||||
repoIDs := make(map[int64]struct{}, len(actions))
|
||||
repoIDs := make(container.Set[int64], len(actions))
|
||||
for _, action := range actions {
|
||||
if _, ok := repoIDs[action.RepoID]; !ok {
|
||||
repoIDs[action.RepoID] = struct{}{}
|
||||
}
|
||||
repoIDs.Add(action.RepoID)
|
||||
}
|
||||
return container.KeysInt64(repoIDs)
|
||||
return repoIDs.Values()
|
||||
}
|
||||
|
||||
func (actions ActionList) loadRepositories(ctx context.Context) error {
|
||||
|
@ -66,7 +62,7 @@ func (actions ActionList) loadRepositories(ctx context.Context) error {
|
|||
repoMaps := make(map[int64]*repo_model.Repository, len(repoIDs))
|
||||
err := db.GetEngine(ctx).In("id", repoIDs).Find(&repoMaps)
|
||||
if err != nil {
|
||||
return fmt.Errorf("find repository: %v", err)
|
||||
return fmt.Errorf("find repository: %w", err)
|
||||
}
|
||||
|
||||
for _, action := range actions {
|
||||
|
|
|
@ -200,7 +200,7 @@ func CreateOrUpdateIssueNotifications(issueID, commentID, notificationAuthorID,
|
|||
|
||||
func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error {
|
||||
// init
|
||||
var toNotify map[int64]struct{}
|
||||
var toNotify container.Set[int64]
|
||||
notifications, err := getNotificationsByIssueID(ctx, issueID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -212,33 +212,27 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
|
|||
}
|
||||
|
||||
if receiverID > 0 {
|
||||
toNotify = make(map[int64]struct{}, 1)
|
||||
toNotify[receiverID] = struct{}{}
|
||||
toNotify = make(container.Set[int64], 1)
|
||||
toNotify.Add(receiverID)
|
||||
} else {
|
||||
toNotify = make(map[int64]struct{}, 32)
|
||||
toNotify = make(container.Set[int64], 32)
|
||||
issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, id := range issueWatches {
|
||||
toNotify[id] = struct{}{}
|
||||
}
|
||||
toNotify.AddMultiple(issueWatches...)
|
||||
if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) {
|
||||
repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, id := range repoWatches {
|
||||
toNotify[id] = struct{}{}
|
||||
}
|
||||
toNotify.AddMultiple(repoWatches...)
|
||||
}
|
||||
issueParticipants, err := issue.GetParticipantIDsByIssue(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, id := range issueParticipants {
|
||||
toNotify[id] = struct{}{}
|
||||
}
|
||||
toNotify.AddMultiple(issueParticipants...)
|
||||
|
||||
// dont notify user who cause notification
|
||||
delete(toNotify, notificationAuthorID)
|
||||
|
@ -248,7 +242,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
|
|||
return err
|
||||
}
|
||||
for _, id := range issueUnWatches {
|
||||
delete(toNotify, id)
|
||||
toNotify.Remove(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,7 +403,7 @@ func (n *Notification) loadRepo(ctx context.Context) (err error) {
|
|||
if n.Repository == nil {
|
||||
n.Repository, err = repo_model.GetRepositoryByIDCtx(ctx, n.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoryByID [%d]: %v", n.RepoID, err)
|
||||
return fmt.Errorf("getRepositoryByID [%d]: %w", n.RepoID, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -419,7 +413,7 @@ func (n *Notification) loadIssue(ctx context.Context) (err error) {
|
|||
if n.Issue == nil && n.IssueID != 0 {
|
||||
n.Issue, err = issues_model.GetIssueByID(ctx, n.IssueID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getIssueByID [%d]: %v", n.IssueID, err)
|
||||
return fmt.Errorf("getIssueByID [%d]: %w", n.IssueID, err)
|
||||
}
|
||||
return n.Issue.LoadAttributes(ctx)
|
||||
}
|
||||
|
@ -446,7 +440,7 @@ func (n *Notification) loadUser(ctx context.Context) (err error) {
|
|||
if n.User == nil {
|
||||
n.User, err = user_model.GetUserByIDCtx(ctx, n.UserID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getUserByID [%d]: %v", n.UserID, err)
|
||||
return fmt.Errorf("getUserByID [%d]: %w", n.UserID, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -499,16 +493,14 @@ func (nl NotificationList) LoadAttributes() error {
|
|||
}
|
||||
|
||||
func (nl NotificationList) getPendingRepoIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(nl))
|
||||
ids := make(container.Set[int64], len(nl))
|
||||
for _, notification := range nl {
|
||||
if notification.Repository != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[notification.RepoID]; !ok {
|
||||
ids[notification.RepoID] = struct{}{}
|
||||
}
|
||||
ids.Add(notification.RepoID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
// LoadRepos loads repositories from database
|
||||
|
@ -575,16 +567,14 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error)
|
|||
}
|
||||
|
||||
func (nl NotificationList) getPendingIssueIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(nl))
|
||||
ids := make(container.Set[int64], len(nl))
|
||||
for _, notification := range nl {
|
||||
if notification.Issue != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[notification.IssueID]; !ok {
|
||||
ids[notification.IssueID] = struct{}{}
|
||||
}
|
||||
ids.Add(notification.IssueID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
// LoadIssues loads issues from database
|
||||
|
@ -661,16 +651,14 @@ func (nl NotificationList) Without(failures []int) NotificationList {
|
|||
}
|
||||
|
||||
func (nl NotificationList) getPendingCommentIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(nl))
|
||||
ids := make(container.Set[int64], len(nl))
|
||||
for _, notification := range nl {
|
||||
if notification.CommentID == 0 || notification.Comment != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[notification.CommentID]; !ok {
|
||||
ids[notification.CommentID] = struct{}{}
|
||||
}
|
||||
ids.Add(notification.CommentID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
// LoadComments loads comments from database
|
||||
|
@ -818,7 +806,7 @@ func getNotificationByID(ctx context.Context, notificationID int64) (*Notificati
|
|||
}
|
||||
|
||||
if !ok {
|
||||
return nil, db.ErrNotExist{ID: notificationID}
|
||||
return nil, db.ErrNotExist{Resource: "notification", ID: notificationID}
|
||||
}
|
||||
|
||||
return notification, nil
|
||||
|
|
|
@ -49,32 +49,32 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
|
|||
stats := &ActivityStats{Code: &git.CodeActivityStats{}}
|
||||
if releases {
|
||||
if err := stats.FillReleases(repo.ID, timeFrom); err != nil {
|
||||
return nil, fmt.Errorf("FillReleases: %v", err)
|
||||
return nil, fmt.Errorf("FillReleases: %w", err)
|
||||
}
|
||||
}
|
||||
if prs {
|
||||
if err := stats.FillPullRequests(repo.ID, timeFrom); err != nil {
|
||||
return nil, fmt.Errorf("FillPullRequests: %v", err)
|
||||
return nil, fmt.Errorf("FillPullRequests: %w", err)
|
||||
}
|
||||
}
|
||||
if issues {
|
||||
if err := stats.FillIssues(repo.ID, timeFrom); err != nil {
|
||||
return nil, fmt.Errorf("FillIssues: %v", err)
|
||||
return nil, fmt.Errorf("FillIssues: %w", err)
|
||||
}
|
||||
}
|
||||
if err := stats.FillUnresolvedIssues(repo.ID, timeFrom, issues, prs); err != nil {
|
||||
return nil, fmt.Errorf("FillUnresolvedIssues: %v", err)
|
||||
return nil, fmt.Errorf("FillUnresolvedIssues: %w", err)
|
||||
}
|
||||
if code {
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||
return nil, fmt.Errorf("OpenRepository: %w", err)
|
||||
}
|
||||
defer closer.Close()
|
||||
|
||||
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("FillFromGit: %v", err)
|
||||
return nil, fmt.Errorf("FillFromGit: %w", err)
|
||||
}
|
||||
stats.Code = code
|
||||
}
|
||||
|
@ -85,13 +85,13 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
|
|||
func GetActivityStatsTopAuthors(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||
return nil, fmt.Errorf("OpenRepository: %w", err)
|
||||
}
|
||||
defer closer.Close()
|
||||
|
||||
code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("FillFromGit: %v", err)
|
||||
return nil, fmt.Errorf("FillFromGit: %w", err)
|
||||
}
|
||||
if code.Authors == nil {
|
||||
return nil, nil
|
||||
|
|
|
@ -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})
|
||||
}
|
|
@ -167,6 +167,10 @@ func (err ErrTaskDoesNotExist) Error() string {
|
|||
err.ID, err.RepoID, err.Type)
|
||||
}
|
||||
|
||||
func (err ErrTaskDoesNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// GetMigratingTask returns the migrating task by repo's id
|
||||
func GetMigratingTask(repoID int64) (*Task, error) {
|
||||
task := Task{
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
|
||||
package asymkey
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
|
||||
type ErrKeyUnableVerify struct {
|
||||
|
@ -36,6 +40,10 @@ func (err ErrKeyNotExist) Error() string {
|
|||
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.
|
||||
type ErrKeyAlreadyExist struct {
|
||||
OwnerID int64
|
||||
|
@ -54,6 +62,10 @@ func (err ErrKeyAlreadyExist) Error() string {
|
|||
err.OwnerID, err.Fingerprint, err.Content)
|
||||
}
|
||||
|
||||
func (err ErrKeyAlreadyExist) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
|
||||
type ErrKeyNameAlreadyUsed struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrKeyNameAlreadyUsed) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
|
||||
type ErrGPGNoEmailFound struct {
|
||||
FailedEmails []string
|
||||
|
@ -132,6 +148,10 @@ func (err ErrGPGKeyNotExist) Error() string {
|
|||
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.
|
||||
type ErrGPGKeyImportNotExist struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrGPGKeyImportNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error.
|
||||
type ErrGPGKeyIDAlreadyUsed struct {
|
||||
KeyID string
|
||||
|
@ -162,6 +186,10 @@ func (err ErrGPGKeyIDAlreadyUsed) Error() string {
|
|||
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.
|
||||
type ErrGPGKeyAccessDenied struct {
|
||||
UserID int64
|
||||
|
@ -180,6 +208,10 @@ func (err ErrGPGKeyAccessDenied) Error() string {
|
|||
err.UserID, err.KeyID)
|
||||
}
|
||||
|
||||
func (err ErrGPGKeyAccessDenied) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
|
||||
type ErrKeyAccessDenied struct {
|
||||
UserID int64
|
||||
|
@ -198,6 +230,10 @@ func (err ErrKeyAccessDenied) Error() string {
|
|||
err.UserID, err.KeyID, err.Note)
|
||||
}
|
||||
|
||||
func (err ErrKeyAccessDenied) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
|
||||
type ErrDeployKeyNotExist struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrDeployKeyNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
|
||||
type ErrDeployKeyAlreadyExist struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrDeployKeyAlreadyExist) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
|
||||
type ErrDeployKeyNameAlreadyUsed struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrDeployKeyNameAlreadyUsed) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrSSHInvalidTokenSignature represents a "ErrSSHInvalidTokenSignature" kind of error.
|
||||
type ErrSSHInvalidTokenSignature struct {
|
||||
Wrapped error
|
||||
|
@ -262,3 +310,7 @@ func IsErrSSHInvalidTokenSignature(err error) bool {
|
|||
func (err ErrSSHInvalidTokenSignature) Error() string {
|
||||
return "the provided signature does not sign the token with the provided key"
|
||||
}
|
||||
|
||||
func (err ErrSSHInvalidTokenSignature) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ func DeleteGPGKey(doer *user_model.User, id int64) (err error) {
|
|||
if IsErrGPGKeyNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("GetPublicKeyByID: %v", err)
|
||||
return fmt.Errorf("GetPublicKeyByID: %w", err)
|
||||
}
|
||||
|
||||
// Check if user has access to delete this key.
|
||||
|
|
|
@ -130,7 +130,7 @@ func AddPublicKey(ownerID int64, name, content string, authSourceID int64) (*Pub
|
|||
LoginSourceID: authSourceID,
|
||||
}
|
||||
if err = addKey(ctx, key); err != nil {
|
||||
return nil, fmt.Errorf("addKey: %v", err)
|
||||
return nil, fmt.Errorf("addKey: %w", err)
|
||||
}
|
||||
|
||||
return key, committer.Commit()
|
||||
|
|
|
@ -151,7 +151,7 @@ func AddDeployKey(repoID int64, name, content string, readOnly bool) (*DeployKey
|
|||
pkey.Content = content
|
||||
pkey.Name = name
|
||||
if err = addKey(ctx, pkey); err != nil {
|
||||
return nil, fmt.Errorf("addKey: %v", err)
|
||||
return nil, fmt.Errorf("addKey: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ func CalcFingerprint(publicKeyContent string) (string, error) {
|
|||
log.Info("%s", publicKeyContent)
|
||||
return "", err
|
||||
}
|
||||
return "", fmt.Errorf("%s: %v", fnName, err)
|
||||
return "", fmt.Errorf("%s: %w", fnName, err)
|
||||
}
|
||||
return fp, nil
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ const ssh2keyStart = "---- BEGIN SSH2 PUBLIC KEY ----"
|
|||
func extractTypeFromBase64Key(key string) (string, error) {
|
||||
b, err := base64.StdEncoding.DecodeString(key)
|
||||
if err != nil || len(b) < 4 {
|
||||
return "", fmt.Errorf("invalid key format: %v", err)
|
||||
return "", fmt.Errorf("invalid key format: %w", err)
|
||||
}
|
||||
|
||||
keyLength := int(binary.BigEndian.Uint32(b))
|
||||
|
@ -85,7 +85,7 @@ func parseKeyString(content string) (string, error) {
|
|||
|
||||
t, err := extractTypeFromBase64Key(keyContent)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("extractTypeFromBase64Key: %v", err)
|
||||
return "", fmt.Errorf("extractTypeFromBase64Key: %w", err)
|
||||
}
|
||||
keyType = t
|
||||
} else {
|
||||
|
@ -104,14 +104,14 @@ func parseKeyString(content string) (string, error) {
|
|||
var pk rsa.PublicKey
|
||||
_, err2 := asn1.Unmarshal(block.Bytes, &pk)
|
||||
if err2 != nil {
|
||||
return "", fmt.Errorf("failed to parse DER encoded public key as either PKIX or PEM RSA Key: %v %v", err, err2)
|
||||
return "", fmt.Errorf("failed to parse DER encoded public key as either PKIX or PEM RSA Key: %v %w", err, err2)
|
||||
}
|
||||
pub = &pk
|
||||
}
|
||||
|
||||
sshKey, err := ssh.NewPublicKey(pub)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to convert to ssh public key: %v", err)
|
||||
return "", fmt.Errorf("unable to convert to ssh public key: %w", err)
|
||||
}
|
||||
content = string(ssh.MarshalAuthorizedKey(sshKey))
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ func parseKeyString(content string) (string, error) {
|
|||
// If keyType is not given, extract it from content. If given, validate it.
|
||||
t, err := extractTypeFromBase64Key(keyContent)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("extractTypeFromBase64Key: %v", err)
|
||||
return "", fmt.Errorf("extractTypeFromBase64Key: %w", err)
|
||||
}
|
||||
if len(keyType) == 0 {
|
||||
keyType = t
|
||||
|
@ -149,7 +149,7 @@ func parseKeyString(content string) (string, error) {
|
|||
// Finally we need to check whether we can actually read the proposed key:
|
||||
_, _, _, _, err := ssh.ParseAuthorizedKey([]byte(keyType + " " + keyContent + " " + keyComment))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid ssh public key: %v", err)
|
||||
return "", fmt.Errorf("invalid ssh public key: %w", err)
|
||||
}
|
||||
return keyType + " " + keyContent + " " + keyComment, nil
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ func CheckPublicKeyString(content string) (_ string, err error) {
|
|||
keyType, length, err = SSHKeyGenParsePublicKey(content)
|
||||
}
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%s: %v", fnName, err)
|
||||
return "", fmt.Errorf("%s: %w", fnName, err)
|
||||
}
|
||||
log.Trace("Key info [native: %v]: %s-%d", setting.SSH.StartBuiltinServer, keyType, length)
|
||||
|
||||
|
@ -220,7 +220,7 @@ func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
|
|||
if strings.Contains(err.Error(), "ssh: unknown key algorithm") {
|
||||
return "", 0, ErrKeyUnableVerify{err.Error()}
|
||||
}
|
||||
return "", 0, fmt.Errorf("ParsePublicKey: %v", err)
|
||||
return "", 0, fmt.Errorf("ParsePublicKey: %w", err)
|
||||
}
|
||||
|
||||
// The ssh library can parse the key, so next we find out what key exactly we have.
|
||||
|
@ -267,12 +267,12 @@ func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
|
|||
func writeTmpKeyFile(content string) (string, error) {
|
||||
tmpFile, err := os.CreateTemp(setting.SSH.KeyTestPath, "gitea_keytest")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("TempFile: %v", err)
|
||||
return "", fmt.Errorf("TempFile: %w", err)
|
||||
}
|
||||
defer tmpFile.Close()
|
||||
|
||||
if _, err = tmpFile.WriteString(content); err != nil {
|
||||
return "", fmt.Errorf("WriteString: %v", err)
|
||||
return "", fmt.Errorf("WriteString: %w", err)
|
||||
}
|
||||
return tmpFile.Name(), nil
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ func writeTmpKeyFile(content string) (string, error) {
|
|||
func SSHKeyGenParsePublicKey(key string) (string, int, error) {
|
||||
tmpName, err := writeTmpKeyFile(key)
|
||||
if err != nil {
|
||||
return "", 0, fmt.Errorf("writeTmpKeyFile: %v", err)
|
||||
return "", 0, fmt.Errorf("writeTmpKeyFile: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := util.Remove(tmpName); err != nil {
|
||||
|
|
|
@ -51,7 +51,7 @@ func AddPrincipalKey(ownerID int64, content string, authSourceID int64) (*Public
|
|||
LoginSourceID: authSourceID,
|
||||
}
|
||||
if err = db.Insert(ctx, key); err != nil {
|
||||
return nil, fmt.Errorf("addKey: %v", err)
|
||||
return nil, fmt.Errorf("addKey: %w", err)
|
||||
}
|
||||
|
||||
if err = committer.Commit(); err != nil {
|
||||
|
|
|
@ -31,9 +31,14 @@ type OAuth2Application struct {
|
|||
Name string
|
||||
ClientID string `xorm:"unique"`
|
||||
ClientSecret string
|
||||
RedirectURIs []string `xorm:"redirect_uris JSON TEXT"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
// OAuth defines both Confidential and Public client types
|
||||
// https://datatracker.ietf.org/doc/html/rfc6749#section-2.1
|
||||
// "Authorization servers MUST record the client type in the client registration details"
|
||||
// https://datatracker.ietf.org/doc/html/rfc8252#section-8.4
|
||||
ConfidentialClient bool `xorm:"NOT NULL DEFAULT TRUE"`
|
||||
RedirectURIs []string `xorm:"redirect_uris JSON TEXT"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -57,15 +62,17 @@ func (app *OAuth2Application) PrimaryRedirectURI() string {
|
|||
|
||||
// ContainsRedirectURI checks if redirectURI is allowed for app
|
||||
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
|
||||
if !app.ConfidentialClient {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,19 +168,21 @@ func GetOAuth2ApplicationsByUserID(ctx context.Context, userID int64) (apps []*O
|
|||
|
||||
// CreateOAuth2ApplicationOptions holds options to create an oauth2 application
|
||||
type CreateOAuth2ApplicationOptions struct {
|
||||
Name string
|
||||
UserID int64
|
||||
RedirectURIs []string
|
||||
Name string
|
||||
UserID int64
|
||||
ConfidentialClient bool
|
||||
RedirectURIs []string
|
||||
}
|
||||
|
||||
// CreateOAuth2Application inserts a new oauth2 application
|
||||
func CreateOAuth2Application(ctx context.Context, opts CreateOAuth2ApplicationOptions) (*OAuth2Application, error) {
|
||||
clientID := uuid.New().String()
|
||||
app := &OAuth2Application{
|
||||
UID: opts.UserID,
|
||||
Name: opts.Name,
|
||||
ClientID: clientID,
|
||||
RedirectURIs: opts.RedirectURIs,
|
||||
UID: opts.UserID,
|
||||
Name: opts.Name,
|
||||
ClientID: clientID,
|
||||
RedirectURIs: opts.RedirectURIs,
|
||||
ConfidentialClient: opts.ConfidentialClient,
|
||||
}
|
||||
if err := db.Insert(ctx, app); err != nil {
|
||||
return nil, err
|
||||
|
@ -183,10 +192,11 @@ func CreateOAuth2Application(ctx context.Context, opts CreateOAuth2ApplicationOp
|
|||
|
||||
// UpdateOAuth2ApplicationOptions holds options to update an oauth2 application
|
||||
type UpdateOAuth2ApplicationOptions struct {
|
||||
ID int64
|
||||
Name string
|
||||
UserID int64
|
||||
RedirectURIs []string
|
||||
ID int64
|
||||
Name string
|
||||
UserID int64
|
||||
ConfidentialClient bool
|
||||
RedirectURIs []string
|
||||
}
|
||||
|
||||
// UpdateOAuth2Application updates an oauth2 application
|
||||
|
@ -207,6 +217,7 @@ func UpdateOAuth2Application(opts UpdateOAuth2ApplicationOptions) (*OAuth2Applic
|
|||
|
||||
app.Name = opts.Name
|
||||
app.RedirectURIs = opts.RedirectURIs
|
||||
app.ConfidentialClient = opts.ConfidentialClient
|
||||
|
||||
if err = updateOAuth2Application(ctx, app); err != nil {
|
||||
return nil, err
|
||||
|
@ -217,7 +228,7 @@ func UpdateOAuth2Application(opts UpdateOAuth2ApplicationOptions) (*OAuth2Applic
|
|||
}
|
||||
|
||||
func updateOAuth2Application(ctx context.Context, app *OAuth2Application) error {
|
||||
if _, err := db.GetEngine(ctx).ID(app.ID).Update(app); err != nil {
|
||||
if _, err := db.GetEngine(ctx).ID(app.ID).UseBool("confidential_client").Update(app); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -225,7 +236,8 @@ func updateOAuth2Application(ctx context.Context, app *OAuth2Application) error
|
|||
|
||||
func deleteOAuth2Application(ctx context.Context, id, userid int64) error {
|
||||
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
|
||||
} else if deleted == 0 {
|
||||
return ErrOAuthApplicationNotFound{ID: id}
|
||||
|
@ -476,7 +488,7 @@ func GetOAuth2GrantsByUserID(ctx context.Context, uid int64) ([]*OAuth2Grant, er
|
|||
|
||||
// RevokeOAuth2Grant deletes the grant with grantID and userID
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -485,7 +497,7 @@ type ErrOAuthClientIDInvalid struct {
|
|||
ClientID string
|
||||
}
|
||||
|
||||
// IsErrOauthClientIDInvalid checks if an error is a ErrReviewNotExist.
|
||||
// IsErrOauthClientIDInvalid checks if an error is a ErrOAuthClientIDInvalid.
|
||||
func IsErrOauthClientIDInvalid(err error) bool {
|
||||
_, ok := err.(ErrOAuthClientIDInvalid)
|
||||
return ok
|
||||
|
@ -496,6 +508,11 @@ func (err ErrOAuthClientIDInvalid) Error() string {
|
|||
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
|
||||
type ErrOAuthApplicationNotFound struct {
|
||||
ID int64
|
||||
|
@ -512,6 +529,11 @@ func (err ErrOAuthApplicationNotFound) Error() string {
|
|||
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
|
||||
func GetActiveOAuth2ProviderSources() ([]*Source, error) {
|
||||
sources := make([]*Source, 0, 1)
|
||||
|
@ -548,7 +570,7 @@ func DeleteOAuth2RelictsByUserID(ctx context.Context, userID int64) error {
|
|||
&OAuth2Application{UID: userID},
|
||||
&OAuth2Grant{UserID: userID},
|
||||
); err != nil {
|
||||
return fmt.Errorf("DeleteBeans: %v", err)
|
||||
return fmt.Errorf("DeleteBeans: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -45,7 +45,8 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) {
|
|||
|
||||
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/"},
|
||||
RedirectURIs: []string{"http://127.0.0.1/", "http://::1/", "http://192.168.0.1/", "http://intranet/", "https://127.0.0.1/"},
|
||||
ConfidentialClient: false,
|
||||
}
|
||||
|
||||
// http loopback uris should ignore port
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/convert"
|
||||
|
@ -366,6 +367,11 @@ func (err ErrSourceNotExist) Error() string {
|
|||
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.
|
||||
type ErrSourceAlreadyExist struct {
|
||||
Name string
|
||||
|
@ -381,6 +387,11 @@ func (err ErrSourceAlreadyExist) Error() string {
|
|||
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.
|
||||
type ErrSourceInUse struct {
|
||||
ID int64
|
||||
|
|
|
@ -35,6 +35,10 @@ func (err ErrAccessTokenNotExist) Error() string {
|
|||
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.
|
||||
type ErrAccessTokenEmpty struct{}
|
||||
|
||||
|
@ -48,6 +52,10 @@ func (err ErrAccessTokenEmpty) Error() string {
|
|||
return "access token is empty"
|
||||
}
|
||||
|
||||
func (err ErrAccessTokenEmpty) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var successfulAccessTokenCache *lru.Cache
|
||||
|
||||
// AccessToken represents a personal access token.
|
||||
|
@ -79,7 +87,7 @@ func init() {
|
|||
var err error
|
||||
successfulAccessTokenCache, err = lru.New(setting.SuccessfulTokensCacheSize)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to allocate AccessToken cache: %v", err)
|
||||
return fmt.Errorf("unable to allocate AccessToken cache: %w", err)
|
||||
}
|
||||
} else {
|
||||
successfulAccessTokenCache = nil
|
||||
|
|
|
@ -41,6 +41,11 @@ func (err ErrTwoFactorNotEnrolled) Error() string {
|
|||
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.
|
||||
type TwoFactor struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
"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)
|
||||
}
|
||||
|
||||
// Unwrap unwraps this as a ErrNotExist err
|
||||
func (err ErrWebAuthnCredentialNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// IsErrWebAuthnCredentialNotExist checks if an error is a ErrWebAuthnCredentialNotExist.
|
||||
func IsErrWebAuthnCredentialNotExist(err error) bool {
|
||||
_, ok := err.(ErrWebAuthnCredentialNotExist)
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"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/cache"
|
||||
"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.
|
||||
// This function should only be called if a federated avatar service is enabled.
|
||||
func LibravatarURL(email string) (*url.URL, error) {
|
||||
urlStr, err := setting.LibravatarService.FromEmail(email)
|
||||
urlStr, err := system_model.LibravatarService.FromEmail(email)
|
||||
if err != nil {
|
||||
log.Error("LibravatarService.FromEmail(email=%s): error %v", email, err)
|
||||
return nil, err
|
||||
|
@ -149,8 +150,10 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
|
|||
return DefaultAvatarLink()
|
||||
}
|
||||
|
||||
enableFederatedAvatar, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar)
|
||||
|
||||
var err error
|
||||
if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
|
||||
if enableFederatedAvatar != nil && enableFederatedAvatar.GetValueBool() && system_model.LibravatarService != nil {
|
||||
emailHash := saveEmailHash(email)
|
||||
if final {
|
||||
// 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)
|
||||
}
|
||||
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.
|
||||
avatarURLCopy := *setting.GravatarSourceURL
|
||||
avatarURLCopy := *system_model.GravatarSourceURL
|
||||
avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email))
|
||||
return generateRecognizedAvatarURL(avatarURLCopy, size)
|
||||
}
|
||||
|
||||
return DefaultAvatarLink()
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package avatars
|
||||
package avatars_test
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
avatars_model "code.gitea.io/gitea/models/avatars"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -15,40 +16,43 @@ import (
|
|||
|
||||
const gravatarSource = "https://secure.gravatar.com/avatar/"
|
||||
|
||||
func disableGravatar() {
|
||||
setting.EnableFederatedAvatar = false
|
||||
setting.LibravatarService = nil
|
||||
setting.DisableGravatar = true
|
||||
func disableGravatar(t *testing.T) {
|
||||
err := system_model.SetSettingNoVersion(system_model.KeyPictureEnableFederatedAvatar, "false")
|
||||
assert.NoError(t, err)
|
||||
err = system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "true")
|
||||
assert.NoError(t, err)
|
||||
system_model.LibravatarService = nil
|
||||
}
|
||||
|
||||
func enableGravatar(t *testing.T) {
|
||||
setting.DisableGravatar = false
|
||||
var err error
|
||||
setting.GravatarSourceURL, err = url.Parse(gravatarSource)
|
||||
err := system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "false")
|
||||
assert.NoError(t, err)
|
||||
setting.GravatarSource = gravatarSource
|
||||
err = system_model.Init()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestHashEmail(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
"d41d8cd98f00b204e9800998ecf8427e",
|
||||
HashEmail(""),
|
||||
avatars_model.HashEmail(""),
|
||||
)
|
||||
assert.Equal(t,
|
||||
"353cbad9b58e69c96154ad99f92bedc7",
|
||||
HashEmail("gitea@example.com"),
|
||||
avatars_model.HashEmail("gitea@example.com"),
|
||||
)
|
||||
}
|
||||
|
||||
func TestSizedAvatarLink(t *testing.T) {
|
||||
setting.AppSubURL = "/testsuburl"
|
||||
|
||||
disableGravatar()
|
||||
disableGravatar(t)
|
||||
assert.Equal(t, "/testsuburl/assets/img/avatar_default.png",
|
||||
GenerateEmailAvatarFastLink("gitea@example.com", 100))
|
||||
avatars_model.GenerateEmailAvatarFastLink("gitea@example.com", 100))
|
||||
|
||||
enableGravatar(t)
|
||||
assert.Equal(t,
|
||||
"https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100",
|
||||
GenerateEmailAvatarFastLink("gitea@example.com", 100),
|
||||
avatars_model.GenerateEmailAvatarFastLink("gitea@example.com", 100),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package admin_test
|
||||
package avatars_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
|
@ -130,7 +130,7 @@ func SyncAllTables() error {
|
|||
func InitEngine(ctx context.Context) error {
|
||||
xormEngine, err := newXORMEngine()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to database: %v", err)
|
||||
return fmt.Errorf("failed to connect to database: %w", err)
|
||||
}
|
||||
|
||||
xormEngine.SetMapper(names.GonicMapper{})
|
||||
|
@ -189,16 +189,16 @@ func InitEngineWithMigration(ctx context.Context, migrateFunc func(*xorm.Engine)
|
|||
// However, we should think carefully about should we support re-install on an installed instance,
|
||||
// as there may be other problems due to secret reinitialization.
|
||||
if err = migrateFunc(x); err != nil {
|
||||
return fmt.Errorf("migrate: %v", err)
|
||||
return fmt.Errorf("migrate: %w", err)
|
||||
}
|
||||
|
||||
if err = SyncAllTables(); err != nil {
|
||||
return fmt.Errorf("sync database struct error: %v", err)
|
||||
return fmt.Errorf("sync database struct error: %w", err)
|
||||
}
|
||||
|
||||
for _, initFunc := range initFuncs {
|
||||
if err := initFunc(); err != nil {
|
||||
return fmt.Errorf("initFunc failed: %v", err)
|
||||
return fmt.Errorf("initFunc failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,7 @@ func NamesToBean(names ...string) ([]interface{}, error) {
|
|||
for _, name := range names {
|
||||
bean, ok := beanMap[strings.ToLower(strings.TrimSpace(name))]
|
||||
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] {
|
||||
beans = append(beans, bean)
|
||||
|
|
|
@ -6,6 +6,8 @@ package db
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// ErrCancelled represents an error due to context cancellation
|
||||
|
@ -45,7 +47,8 @@ func (err ErrSSHDisabled) Error() string {
|
|||
|
||||
// ErrNotExist represents a non-exist error.
|
||||
type ErrNotExist struct {
|
||||
ID int64
|
||||
Resource string
|
||||
ID int64
|
||||
}
|
||||
|
||||
// IsErrNotExist checks if an error is an ErrNotExist
|
||||
|
@ -55,5 +58,18 @@ func IsErrNotExist(err error) bool {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -8,45 +8,15 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
// 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 {
|
||||
GroupID int64 `xorm:"pk"`
|
||||
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 (
|
||||
// ErrResouceOutdated represents an error when request resource outdated
|
||||
ErrResouceOutdated = errors.New("resource outdated")
|
||||
|
@ -59,53 +29,85 @@ const (
|
|||
MaxDupIndexAttempts = 3
|
||||
)
|
||||
|
||||
// GetNextResourceIndex retried 3 times to generate a resource index
|
||||
func GetNextResourceIndex(tableName string, groupID int64) (int64, error) {
|
||||
for i := 0; i < MaxDupIndexAttempts; i++ {
|
||||
idx, err := getNextResourceIndex(tableName, groupID)
|
||||
if err == ErrResouceOutdated {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return idx, nil
|
||||
// SyncMaxResourceIndex sync the max index with the resource
|
||||
func SyncMaxResourceIndex(ctx context.Context, tableName string, groupID, maxIndex int64) (err error) {
|
||||
e := GetEngine(ctx)
|
||||
|
||||
// try to update the max_index and acquire the write-lock for the record
|
||||
res, err := e.Exec(fmt.Sprintf("UPDATE %s SET max_index=? WHERE group_id=? AND max_index<?", tableName), maxIndex, groupID, maxIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
func DeleteResouceIndex(ctx context.Context, tableName string, groupID int64) error {
|
||||
_, err := Exec(ctx, fmt.Sprintf("DELETE FROM %s WHERE group_id=?", tableName), groupID)
|
||||
return err
|
||||
}
|
||||
// GetNextResourceIndex generates a resource index, it must run in the same transaction where the resource is created
|
||||
func GetNextResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
|
||||
e := GetEngine(ctx)
|
||||
|
||||
// getNextResourceIndex return the next index
|
||||
func getNextResourceIndex(tableName string, groupID int64) (int64, error) {
|
||||
ctx, commiter, err := TxContext()
|
||||
// try to update the max_index to next value, and acquire the write-lock for the record
|
||||
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
|
||||
}
|
||||
defer commiter.Close()
|
||||
var preIdx int64
|
||||
if _, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&preIdx); err != nil {
|
||||
affected, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err := UpsertResourceIndex(ctx, tableName, groupID); err != nil {
|
||||
return 0, err
|
||||
if affected == 0 {
|
||||
// this slow path is only for the first time of creating a resource index
|
||||
_, 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
|
||||
has, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ? AND max_index=?", tableName), groupID, preIdx+1).Get(&curIdx)
|
||||
// now, the new index is in database (protected by the transaction and write-lock)
|
||||
var newIdx int64
|
||||
has, err := e.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id=?", tableName), groupID).Get(&newIdx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
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 0, err
|
||||
}
|
||||
return curIdx, nil
|
||||
return newIdx, 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
127
models/db/index_test.go
Normal 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
|
||||
}
|
|
@ -5,16 +5,17 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
var (
|
||||
// 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 = regexp.MustCompile(`[^\w-\.]`)
|
||||
|
@ -35,6 +36,11 @@ func (err ErrNameReserved) Error() string {
|
|||
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.
|
||||
type ErrNamePatternNotAllowed struct {
|
||||
Pattern string
|
||||
|
@ -50,6 +56,11 @@ func (err ErrNamePatternNotAllowed) Error() string {
|
|||
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.
|
||||
type ErrNameCharsNotAllowed struct {
|
||||
Name string
|
||||
|
@ -62,7 +73,12 @@ func IsErrNameCharsNotAllowed(err error) bool {
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
|
||||
|
@ -63,8 +64,8 @@ type ErrNoPendingRepoTransfer struct {
|
|||
RepoID int64
|
||||
}
|
||||
|
||||
func (e ErrNoPendingRepoTransfer) Error() string {
|
||||
return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", e.RepoID)
|
||||
func (err ErrNoPendingRepoTransfer) Error() string {
|
||||
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
|
||||
|
@ -74,6 +75,10 @@ func IsErrNoPendingTransfer(err error) bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
func (err ErrNoPendingRepoTransfer) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrRepoTransferInProgress represents the state of a repository that has an
|
||||
// ongoing transfer
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrRepoTransferInProgress) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
|
||||
type ErrInvalidCloneAddr struct {
|
||||
Host string
|
||||
|
@ -124,6 +133,10 @@ func (err *ErrInvalidCloneAddr) Error() string {
|
|||
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.
|
||||
type ErrUpdateTaskNotExist struct {
|
||||
UUID string
|
||||
|
@ -139,6 +152,10 @@ func (err ErrUpdateTaskNotExist) Error() string {
|
|||
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.
|
||||
type ErrInvalidTagName struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrInvalidTagName) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrProtectedTagName represents a "ProtectedTagName" kind of error.
|
||||
type ErrProtectedTagName struct {
|
||||
TagName string
|
||||
|
@ -169,6 +190,10 @@ func (err ErrProtectedTagName) Error() string {
|
|||
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.
|
||||
type ErrRepoFileAlreadyExists struct {
|
||||
Path string
|
||||
|
@ -184,6 +209,10 @@ func (err ErrRepoFileAlreadyExists) Error() string {
|
|||
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.
|
||||
type ErrRepoFileDoesNotExist struct {
|
||||
Path string
|
||||
|
@ -200,6 +229,10 @@ func (err ErrRepoFileDoesNotExist) Error() string {
|
|||
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.
|
||||
type ErrFilenameInvalid struct {
|
||||
Path string
|
||||
|
@ -215,6 +248,10 @@ func (err ErrFilenameInvalid) Error() string {
|
|||
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.
|
||||
type ErrUserCannotCommit struct {
|
||||
UserName string
|
||||
|
@ -230,6 +267,10 @@ func (err ErrUserCannotCommit) Error() string {
|
|||
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.
|
||||
type ErrFilePathInvalid struct {
|
||||
Message string
|
||||
|
@ -251,6 +292,10 @@ func (err ErrFilePathInvalid) Error() string {
|
|||
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.
|
||||
type ErrFilePathProtected struct {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrBranchDoesNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrBranchAlreadyExists represents an error that branch with such name already exists.
|
||||
type ErrBranchAlreadyExists struct {
|
||||
BranchName string
|
||||
|
@ -307,6 +360,10 @@ func (err ErrBranchAlreadyExists) Error() string {
|
|||
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.
|
||||
type ErrBranchNameConflict struct {
|
||||
BranchName string
|
||||
|
@ -322,6 +379,10 @@ func (err ErrBranchNameConflict) Error() string {
|
|||
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.
|
||||
type ErrBranchesEqual struct {
|
||||
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)
|
||||
}
|
||||
|
||||
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.
|
||||
type ErrDisallowedToMerge struct {
|
||||
Reason string
|
||||
|
@ -353,6 +418,10 @@ func (err ErrDisallowedToMerge) Error() string {
|
|||
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.
|
||||
type ErrTagAlreadyExists struct {
|
||||
TagName string
|
||||
|
@ -368,6 +437,10 @@ func (err ErrTagAlreadyExists) Error() string {
|
|||
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.
|
||||
type ErrSHADoesNotMatch struct {
|
||||
Path string
|
||||
|
@ -400,6 +473,10 @@ func (err ErrSHANotFound) Error() string {
|
|||
return fmt.Sprintf("sha not found [%s]", err.SHA)
|
||||
}
|
||||
|
||||
func (err ErrSHANotFound) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrCommitIDDoesNotMatch represents a "CommitIDDoesNotMatch" kind of error.
|
||||
type ErrCommitIDDoesNotMatch struct {
|
||||
GivenCommitID string
|
||||
|
@ -446,6 +523,10 @@ func (err ErrInvalidMergeStyle) Error() string {
|
|||
err.ID, err.Style)
|
||||
}
|
||||
|
||||
func (err ErrInvalidMergeStyle) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrMergeConflicts represents an error if merging fails with a conflict
|
||||
type ErrMergeConflicts struct {
|
||||
Style repo_model.MergeStyle
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
|
||||
repo_id: 1
|
||||
issue_id: 1
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -13,9 +16,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12
|
||||
repo_id: 2
|
||||
issue_id: 4
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach2
|
||||
download_count: 1
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -23,9 +29,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a13
|
||||
repo_id: 1
|
||||
issue_id: 2
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 1
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -33,9 +42,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14
|
||||
repo_id: 1
|
||||
issue_id: 3
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 1
|
||||
name: attach2
|
||||
download_count: 1
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -43,9 +55,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a15
|
||||
repo_id: 2
|
||||
issue_id: 4
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -53,9 +68,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a16
|
||||
repo_id: 1
|
||||
issue_id: 5
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 2
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -63,9 +81,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17
|
||||
repo_id: 1
|
||||
issue_id: 5
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 2
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -73,34 +94,49 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18
|
||||
repo_id: 3
|
||||
issue_id: 6
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
id: 9
|
||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a19
|
||||
repo_id: 1
|
||||
issue_id: 0
|
||||
release_id: 1
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
id: 10
|
||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a20
|
||||
repo_id: 0 # TestGetAttachment/NotLinked
|
||||
issue_id: 0
|
||||
release_id: 0
|
||||
uploader_id: 8
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
id: 11
|
||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a21
|
||||
repo_id: 40
|
||||
issue_id: 0
|
||||
release_id: 2
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
-
|
||||
id: 1
|
||||
repo_id: 1
|
||||
hook_id: 1
|
||||
uuid: uuid1
|
||||
is_delivered: true
|
||||
|
|
|
@ -3,208 +3,287 @@
|
|||
repo_id: 1
|
||||
index: 1
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: issue1
|
||||
content: content for the first issue
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 2
|
||||
created_unix: 946684800
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 2
|
||||
repo_id: 1
|
||||
index: 2
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: issue2
|
||||
content: content for the second issue
|
||||
milestone_id: 1
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 946684810
|
||||
updated_unix: 978307190
|
||||
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 3
|
||||
repo_id: 1
|
||||
index: 3
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: issue3
|
||||
content: content for the third issue
|
||||
milestone_id: 3
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 946684820
|
||||
updated_unix: 978307180
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 4
|
||||
repo_id: 2
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue4
|
||||
content: content for the fourth issue
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: true
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 946684830
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 5
|
||||
repo_id: 1
|
||||
index: 4
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue5
|
||||
content: content for the fifth issue
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: true
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 946684840
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 6
|
||||
repo_id: 3
|
||||
index: 1
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: issue6
|
||||
content: content6
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 946684850
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 7
|
||||
repo_id: 2
|
||||
index: 2
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue7
|
||||
content: content for the seventh issue
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 946684830
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 8
|
||||
repo_id: 10
|
||||
index: 1
|
||||
poster_id: 11
|
||||
original_author_id: 0
|
||||
name: pr2
|
||||
content: a pull request
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 946684820
|
||||
updated_unix: 978307180
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 9
|
||||
repo_id: 48
|
||||
index: 1
|
||||
poster_id: 11
|
||||
original_author_id: 0
|
||||
name: pr1
|
||||
content: a pull request
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 946684820
|
||||
updated_unix: 978307180
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 10
|
||||
repo_id: 42
|
||||
index: 1
|
||||
poster_id: 500
|
||||
original_author_id: 0
|
||||
name: issue from deleted account
|
||||
content: content from deleted account
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
deadline_unix: 1019307200
|
||||
created_unix: 946684830
|
||||
updated_unix: 999307200
|
||||
deadline_unix: 1019307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 11
|
||||
repo_id: 1
|
||||
index: 5
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: pull5
|
||||
content: content for the a pull request
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 1579194806
|
||||
updated_unix: 1579194806
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 12
|
||||
repo_id: 3
|
||||
index: 2
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: pull6
|
||||
content: content for the a pull request
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 13
|
||||
repo_id: 50
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue in active repo
|
||||
content: we'll be testing github issue 13171 with this.
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 14
|
||||
repo_id: 51
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue in archived repo
|
||||
content: we'll be testing github issue 13171 with this.
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 15
|
||||
repo_id: 5
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue in repo not linked to team1
|
||||
content: content
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 16
|
||||
repo_id: 32
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: just a normal issue
|
||||
content: content
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 17
|
||||
repo_id: 32
|
||||
index: 2
|
||||
poster_id: 15
|
||||
original_author_id: 0
|
||||
name: a issue with a assignment
|
||||
content: content
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
color: '#000000'
|
||||
num_issues: 1
|
||||
num_closed_issues: 1
|
||||
|
||||
-
|
||||
id: 3
|
||||
repo_id: 0
|
||||
org_id: 3
|
||||
org_id: 3
|
||||
name: orglabel3
|
||||
color: '#abcdef'
|
||||
num_issues: 0
|
||||
|
@ -32,7 +33,7 @@
|
|||
color: '#000000'
|
||||
num_issues: 1
|
||||
num_closed_issues: 0
|
||||
|
||||
|
||||
-
|
||||
id: 5
|
||||
repo_id: 10
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
is_closed: false
|
||||
num_issues: 1
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
||||
-
|
||||
|
@ -16,6 +17,7 @@
|
|||
is_closed: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
||||
-
|
||||
|
@ -26,6 +28,7 @@
|
|||
is_closed: true
|
||||
num_issues: 1
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
||||
-
|
||||
|
@ -36,14 +39,16 @@
|
|||
is_closed: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
||||
-
|
||||
-
|
||||
id: 5
|
||||
repo_id: 10
|
||||
name: milestone of repo 10
|
||||
name: milestone of repo 10
|
||||
content: for testing with PRs
|
||||
is_closed: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
|
|
@ -4,6 +4,17 @@
|
|||
name: "Test"
|
||||
client_id: "da7da3ba-9a13-4167-856f-3899de0b0138"
|
||||
client_secret: "$2a$10$UYRgUSgekzBp6hYe8pAdc.cgB4Gn06QRKsORUnIYTYQADs.YR/uvi" # bcrypt of "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=
|
||||
redirect_uris: '["a"]'
|
||||
redirect_uris: '["a", "https://example.com/xyzzy"]'
|
||||
created_unix: 1546869730
|
||||
updated_unix: 1546869730
|
||||
confidential_client: true
|
||||
-
|
||||
id: 2
|
||||
uid: 2
|
||||
name: "Test native app"
|
||||
client_id: "ce5a1322-42a7-11ed-b878-0242ac120002"
|
||||
client_secret: "$2a$10$UYRgUSgekzBp6hYe8pAdc.cgB4Gn06QRKsORUnIYTYQADs.YR/uvi" # bcrypt of "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=
|
||||
redirect_uris: '["http://127.0.0.1"]'
|
||||
created_unix: 1546869730
|
||||
updated_unix: 1546869730
|
||||
confidential_client: false
|
||||
|
|
|
@ -6,3 +6,10 @@
|
|||
redirect_uri: "a"
|
||||
valid_until: 3546869730
|
||||
|
||||
- id: 2
|
||||
grant_id: 4
|
||||
code: "authcodepublic"
|
||||
code_challenge: "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg" # Code Verifier: N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt
|
||||
code_challenge_method: "S256"
|
||||
redirect_uri: "http://127.0.0.1/"
|
||||
valid_until: 3546869730
|
||||
|
|
|
@ -20,4 +20,12 @@
|
|||
counter: 1
|
||||
scope: "openid profile email"
|
||||
created_unix: 1546869730
|
||||
updated_unix: 1546869730
|
||||
updated_unix: 1546869730
|
||||
|
||||
- id: 4
|
||||
user_id: 99
|
||||
application_id: 2
|
||||
counter: 1
|
||||
scope: "whatever"
|
||||
created_unix: 1546869730
|
||||
updated_unix: 1546869730
|
||||
|
|
File diff suppressed because it is too large
Load diff
15
models/fixtures/system_setting.yml
Normal file
15
models/fixtures/system_setting.yml
Normal 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
|
|
@ -6,6 +6,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 3
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -16,6 +17,7 @@
|
|||
authorize: 2 # write
|
||||
num_repos: 1
|
||||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -26,6 +28,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -36,6 +39,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -46,6 +50,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 2
|
||||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -56,6 +61,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 2
|
||||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -66,6 +72,7 @@
|
|||
authorize: 2 # write
|
||||
num_repos: 1
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -76,6 +83,7 @@
|
|||
authorize: 2 # write
|
||||
num_repos: 1
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -86,6 +94,7 @@
|
|||
authorize: 1 # read
|
||||
num_repos: 1
|
||||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -93,9 +102,10 @@
|
|||
org_id: 25
|
||||
lower_name: notowners
|
||||
name: NotOwners
|
||||
authorize: 1 # owner
|
||||
authorize: 1 # read
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -106,6 +116,7 @@
|
|||
authorize: 1 # read
|
||||
num_repos: 0
|
||||
num_members: 0
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -116,6 +127,7 @@
|
|||
authorize: 3 # admin
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -126,4 +138,5 @@
|
|||
authorize: 3 # admin
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
|
|
@ -8,18 +8,22 @@
|
|||
name: database
|
||||
repo_count: 1
|
||||
|
||||
- id: 3
|
||||
-
|
||||
id: 3
|
||||
name: SQL
|
||||
repo_count: 1
|
||||
|
||||
- id: 4
|
||||
-
|
||||
id: 4
|
||||
name: graphql
|
||||
repo_count: 1
|
||||
|
||||
- id: 5
|
||||
-
|
||||
id: 5
|
||||
name: topicname1
|
||||
repo_count: 1
|
||||
|
||||
- id: 6
|
||||
-
|
||||
id: 6
|
||||
name: topicname2
|
||||
repo_count: 2
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,6 @@
|
|||
- id: 1
|
||||
name: "WebAuthn credential"
|
||||
-
|
||||
id: 1
|
||||
name: WebAuthn credential
|
||||
user_id: 32
|
||||
attestation_type: none
|
||||
sign_count: 0
|
||||
|
|
|
@ -6,6 +6,8 @@ package foreignreference
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (err ErrLocalIndexNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrForeignIndexNotExist represents a "ForeignIndexNotExist" kind of error.
|
||||
type ErrForeignIndexNotExist struct {
|
||||
RepoID int64
|
||||
|
@ -41,3 +47,7 @@ func IsErrForeignIndexNotExist(err error) bool {
|
|||
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)
|
||||
}
|
||||
|
||||
func (err ErrForeignIndexNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ type WhitelistOptions struct {
|
|||
// to avoid unnecessary whitelist delete and regenerate.
|
||||
func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, protectBranch *ProtectedBranch, opts WhitelistOptions) (err error) {
|
||||
if err = repo.GetOwner(ctx); err != nil {
|
||||
return fmt.Errorf("GetOwner: %v", err)
|
||||
return fmt.Errorf("GetOwner: %w", err)
|
||||
}
|
||||
|
||||
whitelist, err := updateUserWhitelist(ctx, repo, protectBranch.WhitelistUserIDs, opts.UserIDs)
|
||||
|
@ -313,13 +313,13 @@ func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, prote
|
|||
// Make sure protectBranch.ID is not 0 for whitelists
|
||||
if protectBranch.ID == 0 {
|
||||
if _, err = db.GetEngine(ctx).Insert(protectBranch); err != nil {
|
||||
return fmt.Errorf("Insert: %v", err)
|
||||
return fmt.Errorf("Insert: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err = db.GetEngine(ctx).ID(protectBranch.ID).AllCols().Update(protectBranch); err != nil {
|
||||
return fmt.Errorf("Update: %v", err)
|
||||
return fmt.Errorf("Update: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -378,11 +378,11 @@ func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, curre
|
|||
for _, userID := range newWhitelist {
|
||||
user, err := user_model.GetUserByIDCtx(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserByID [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
|
||||
return nil, fmt.Errorf("GetUserByID [user_id: %d, repo_id: %d]: %w", userID, repo.ID, err)
|
||||
}
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, repo, user)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
|
||||
return nil, fmt.Errorf("GetUserRepoPermission [user_id: %d, repo_id: %d]: %w", userID, repo.ID, err)
|
||||
}
|
||||
|
||||
if !perm.CanWrite(unit.TypeCode) {
|
||||
|
@ -405,7 +405,7 @@ func updateTeamWhitelist(ctx context.Context, repo *repo_model.Repository, curre
|
|||
|
||||
teams, err := organization.GetTeamsWithAccessToRepo(ctx, repo.OwnerID, repo.ID, perm.AccessModeRead)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetTeamsWithAccessToRepo [org_id: %d, repo_id: %d]: %v", repo.OwnerID, repo.ID, err)
|
||||
return nil, fmt.Errorf("GetTeamsWithAccessToRepo [org_id: %d, repo_id: %d]: %w", repo.OwnerID, repo.ID, err)
|
||||
}
|
||||
|
||||
whitelist = make([]int64, 0, len(teams))
|
||||
|
|
|
@ -128,13 +128,13 @@ func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) {
|
|||
if status.Repo == nil {
|
||||
status.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, status.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoryByID [%d]: %v", status.RepoID, err)
|
||||
return fmt.Errorf("getRepositoryByID [%d]: %w", status.RepoID, err)
|
||||
}
|
||||
}
|
||||
if status.Creator == nil && status.CreatorID > 0 {
|
||||
status.Creator, err = user_model.GetUserByIDCtx(ctx, status.CreatorID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getUserByID [%d]: %v", status.CreatorID, err)
|
||||
return fmt.Errorf("getUserByID [%d]: %w", status.CreatorID, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -294,12 +294,12 @@ func NewCommitStatus(opts NewCommitStatusOptions) error {
|
|||
// Get the next Status Index
|
||||
idx, err := GetNextCommitStatusIndex(opts.Repo.ID, opts.SHA)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate commit status index failed: %v", err)
|
||||
return fmt.Errorf("generate commit status index failed: %w", err)
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", opts.Repo.ID, opts.Creator.ID, opts.SHA, err)
|
||||
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", opts.Repo.ID, opts.Creator.ID, opts.SHA, err)
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
|
@ -316,7 +316,7 @@ func NewCommitStatus(opts NewCommitStatusOptions) error {
|
|||
|
||||
// Insert new CommitStatus
|
||||
if _, err = db.GetEngine(ctx).Insert(opts.CommitStatus); err != nil {
|
||||
return fmt.Errorf("Insert CommitStatus[%s, %s]: %v", repoPath, opts.SHA, err)
|
||||
return fmt.Errorf("Insert CommitStatus[%s, %s]: %w", repoPath, opts.SHA, err)
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
|
|
|
@ -6,7 +6,6 @@ package git
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
@ -17,6 +16,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/lfs"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"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)
|
||||
}
|
||||
|
||||
func (err ErrLFSLockNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error.
|
||||
type ErrLFSUnauthorizedAction struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrLFSUnauthorizedAction) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error.
|
||||
type ErrLFSLockAlreadyExist struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrLFSLockAlreadyExist) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrLFSFileLocked represents a "LFSFileLocked" kind of error.
|
||||
type ErrLFSFileLocked struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrLFSFileLocked) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// LFSMetaObject stores metadata for LFS tracked files.
|
||||
type LFSMetaObject struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
|
@ -114,7 +130,7 @@ type LFSTokenResponse struct {
|
|||
|
||||
// ErrLFSObjectNotExist is returned from lfs models functions in order
|
||||
// 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
|
||||
// if it is not already present.
|
||||
|
@ -300,7 +316,7 @@ func CopyLFS(ctx context.Context, newRepo, oldRepo *repo_model.Repository) error
|
|||
func GetRepoLFSSize(ctx context.Context, repoID int64) (int64, error) {
|
||||
lfsSize, err := db.GetEngine(ctx).Where("repository_id = ?", repoID).SumInt(new(LFSMetaObject), "size")
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("updateSize: GetLFSMetaObjects: %v", err)
|
||||
return 0, fmt.Errorf("updateSize: GetLFSMetaObjects: %w", err)
|
||||
}
|
||||
return lfsSize, nil
|
||||
}
|
||||
|
|
|
@ -85,12 +85,12 @@ func ToggleIssueAssignee(issue *Issue, doer *user_model.User, assigneeID int64)
|
|||
func toggleIssueAssignee(ctx context.Context, issue *Issue, doer *user_model.User, assigneeID int64, isCreate bool) (removed bool, comment *Comment, err error) {
|
||||
removed, err = toggleUserAssignee(ctx, issue, assigneeID)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("UpdateIssueUserByAssignee: %v", err)
|
||||
return false, nil, fmt.Errorf("UpdateIssueUserByAssignee: %w", err)
|
||||
}
|
||||
|
||||
// Repo infos
|
||||
if err = issue.LoadRepo(ctx); err != nil {
|
||||
return false, nil, fmt.Errorf("loadRepo: %v", err)
|
||||
return false, nil, fmt.Errorf("loadRepo: %w", err)
|
||||
}
|
||||
|
||||
opts := &CreateCommentOptions{
|
||||
|
@ -104,7 +104,7 @@ func toggleIssueAssignee(ctx context.Context, issue *Issue, doer *user_model.Use
|
|||
// Comment
|
||||
comment, err = CreateCommentCtx(ctx, opts)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("createComment: %v", err)
|
||||
return false, nil, fmt.Errorf("createComment: %w", err)
|
||||
}
|
||||
|
||||
// if pull request is in the middle of creation - don't call webhook
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/references"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
"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)
|
||||
}
|
||||
|
||||
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.
|
||||
type CommentType int
|
||||
|
||||
|
@ -568,13 +573,13 @@ func (c *Comment) UpdateAttachments(uuids []string) error {
|
|||
|
||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err)
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", uuids, err)
|
||||
}
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
attachments[i].IssueID = c.IssueID
|
||||
attachments[i].CommentID = c.ID
|
||||
if err := repo_model.UpdateAttachment(ctx, attachments[i]); err != nil {
|
||||
return fmt.Errorf("update attachment [id: %d]: %v", attachments[i].ID, err)
|
||||
return fmt.Errorf("update attachment [id: %d]: %w", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
return committer.Commit()
|
||||
|
@ -869,7 +874,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
|
|||
// Check attachments
|
||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", opts.Attachments, err)
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", opts.Attachments, err)
|
||||
}
|
||||
|
||||
for i := range attachments {
|
||||
|
@ -877,11 +882,11 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
|
|||
attachments[i].CommentID = comment.ID
|
||||
// No assign value could be 0, so ignore AllCols().
|
||||
if _, err = db.GetEngine(ctx).ID(attachments[i].ID).Update(attachments[i]); err != nil {
|
||||
return fmt.Errorf("update attachment [%d]: %v", attachments[i].ID, err)
|
||||
return fmt.Errorf("update attachment [%d]: %w", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
case CommentTypeReopen, CommentTypeClose:
|
||||
if err = updateIssueClosedNum(ctx, opts.Issue); err != nil {
|
||||
if err = repo_model.UpdateRepoIssueNumbers(ctx, opts.Issue.RepoID, opts.Issue.IsPull, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -1029,7 +1034,7 @@ func CreateRefComment(doer *user_model.User, repo *repo_model.Repository, issue
|
|||
CommitSHA: commitSHA,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("check reference comment: %v", err)
|
||||
return fmt.Errorf("check reference comment: %w", err)
|
||||
} else if has {
|
||||
return nil
|
||||
}
|
||||
|
@ -1147,7 +1152,7 @@ func UpdateComment(c *Comment, doer *user_model.User) error {
|
|||
return err
|
||||
}
|
||||
if err := committer.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
return fmt.Errorf("Commit: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -17,13 +17,11 @@ import (
|
|||
type CommentList []*Comment
|
||||
|
||||
func (comments CommentList) getPosterIDs() []int64 {
|
||||
posterIDs := make(map[int64]struct{}, len(comments))
|
||||
posterIDs := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := posterIDs[comment.PosterID]; !ok {
|
||||
posterIDs[comment.PosterID] = struct{}{}
|
||||
}
|
||||
posterIDs.Add(comment.PosterID)
|
||||
}
|
||||
return container.KeysInt64(posterIDs)
|
||||
return posterIDs.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadPosters(ctx context.Context) error {
|
||||
|
@ -70,13 +68,11 @@ func (comments CommentList) getCommentIDs() []int64 {
|
|||
}
|
||||
|
||||
func (comments CommentList) getLabelIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.LabelID]; !ok {
|
||||
ids[comment.LabelID] = struct{}{}
|
||||
}
|
||||
ids.Add(comment.LabelID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
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 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.MilestoneID]; !ok {
|
||||
ids[comment.MilestoneID] = struct{}{}
|
||||
}
|
||||
ids.Add(comment.MilestoneID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
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 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.OldMilestoneID]; !ok {
|
||||
ids[comment.OldMilestoneID] = struct{}{}
|
||||
}
|
||||
ids.Add(comment.OldMilestoneID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
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 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.AssigneeID]; !ok {
|
||||
ids[comment.AssigneeID] = struct{}{}
|
||||
}
|
||||
ids.Add(comment.AssigneeID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
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
|
||||
func (comments CommentList) getIssueIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.Issue != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[comment.IssueID]; !ok {
|
||||
ids[comment.IssueID] = struct{}{}
|
||||
}
|
||||
ids.Add(comment.IssueID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
// Issues returns all the issues of comments
|
||||
|
@ -334,16 +322,14 @@ func (comments CommentList) loadIssues(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getDependentIssueIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.DependentIssue != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[comment.DependentIssueID]; !ok {
|
||||
ids[comment.DependentIssueID] = struct{}{}
|
||||
}
|
||||
ids.Add(comment.DependentIssueID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
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 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.ReviewID]; !ok {
|
||||
ids[comment.ReviewID] = struct{}{}
|
||||
}
|
||||
ids.Add(comment.ReviewID)
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadReviews(ctx context.Context) error { //nolint
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"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)
|
||||
}
|
||||
|
||||
func (err ErrIssueContentHistoryNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// GetIssueContentHistoryByID get issue content history
|
||||
func GetIssueContentHistoryByID(dbCtx context.Context, id int64) (*ContentHistory, error) {
|
||||
h := &ContentHistory{}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
func (err ErrDependencyExists) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error.
|
||||
type ErrDependencyNotExists struct {
|
||||
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)
|
||||
}
|
||||
|
||||
func (err ErrDependencyNotExists) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrCircularDependency represents a "DependencyCircular" kind of error.
|
||||
type ErrCircularDependency struct {
|
||||
IssueID int64
|
||||
|
@ -91,6 +100,10 @@ func (err ErrUnknownDependencyType) Error() string {
|
|||
return fmt.Sprintf("unknown dependency type [type: %d]", err.Type)
|
||||
}
|
||||
|
||||
func (err ErrUnknownDependencyType) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// IssueDependency represents an issue dependency
|
||||
type IssueDependency struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
admin_model "code.gitea.io/gitea/models/admin"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/foreignreference"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
|
@ -21,6 +20,7 @@ import (
|
|||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"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)
|
||||
}
|
||||
|
||||
func (err ErrIssueNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrIssueIsClosed represents a "IssueIsClosed" kind of error.
|
||||
type ErrIssueIsClosed struct {
|
||||
ID int64
|
||||
|
@ -192,7 +196,7 @@ func (issue *Issue) LoadRepo(ctx context.Context) (err error) {
|
|||
if issue.Repo == nil {
|
||||
issue.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, issue.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoryByID [%d]: %v", issue.RepoID, err)
|
||||
return fmt.Errorf("getRepositoryByID [%d]: %w", issue.RepoID, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -230,7 +234,7 @@ func (issue *Issue) LoadLabels(ctx context.Context) (err error) {
|
|||
if issue.Labels == nil {
|
||||
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getLabelsByIssueID [%d]: %v", issue.ID, err)
|
||||
return fmt.Errorf("getLabelsByIssueID [%d]: %w", issue.ID, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -248,7 +252,7 @@ func (issue *Issue) loadPoster(ctx context.Context) (err error) {
|
|||
issue.PosterID = -1
|
||||
issue.Poster = user_model.NewGhostUser()
|
||||
if !user_model.IsErrUserNotExist(err) {
|
||||
return fmt.Errorf("getUserByID.(poster) [%d]: %v", issue.PosterID, err)
|
||||
return fmt.Errorf("getUserByID.(poster) [%d]: %w", issue.PosterID, err)
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
|
@ -264,7 +268,7 @@ func (issue *Issue) loadPullRequest(ctx context.Context) (err error) {
|
|||
if IsErrPullRequestNotExist(err) {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("getPullRequestByIssueID [%d]: %v", issue.ID, err)
|
||||
return fmt.Errorf("getPullRequestByIssueID [%d]: %w", issue.ID, err)
|
||||
}
|
||||
issue.PullRequest.Issue = issue
|
||||
}
|
||||
|
@ -357,7 +361,7 @@ func (issue *Issue) loadMilestone(ctx context.Context) (err error) {
|
|||
if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
|
||||
issue.Milestone, err = GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID)
|
||||
if err != nil && !IsErrMilestoneNotExist(err) {
|
||||
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
|
||||
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %w", issue.RepoID, issue.MilestoneID, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -397,7 +401,7 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
|
|||
if issue.Attachments == nil {
|
||||
issue.Attachments, err = repo_model.GetAttachmentsByIssueID(ctx, issue.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByIssueID [%d]: %v", issue.ID, err)
|
||||
return fmt.Errorf("getAttachmentsByIssueID [%d]: %w", issue.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,19 +518,19 @@ func (issue *Issue) getLabels(ctx context.Context) (err error) {
|
|||
|
||||
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getLabelsByIssueID: %v", err)
|
||||
return fmt.Errorf("getLabelsByIssueID: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func clearIssueLabels(ctx context.Context, issue *Issue, doer *user_model.User) (err error) {
|
||||
if err = issue.getLabels(ctx); err != nil {
|
||||
return fmt.Errorf("getLabels: %v", err)
|
||||
return fmt.Errorf("getLabels: %w", err)
|
||||
}
|
||||
|
||||
for i := range issue.Labels {
|
||||
if err = deleteIssueLabel(ctx, issue, issue.Labels[i], doer); err != nil {
|
||||
return fmt.Errorf("removeLabel: %v", err)
|
||||
return fmt.Errorf("removeLabel: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,7 +565,7 @@ func ClearIssueLabels(issue *Issue, doer *user_model.User) (err error) {
|
|||
}
|
||||
|
||||
if err = committer.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
return fmt.Errorf("Commit: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -631,13 +635,13 @@ func ReplaceIssueLabels(issue *Issue, labels []*Label, doer *user_model.User) (e
|
|||
|
||||
if len(toAdd) > 0 {
|
||||
if err = newIssueLabels(ctx, issue, toAdd, doer); err != nil {
|
||||
return fmt.Errorf("addLabels: %v", err)
|
||||
return fmt.Errorf("addLabels: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, l := range toRemove {
|
||||
if err = deleteIssueLabel(ctx, issue, l, doer); err != nil {
|
||||
return fmt.Errorf("removeLabel: %v", err)
|
||||
return fmt.Errorf("removeLabel: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -721,7 +725,8 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use
|
|||
}
|
||||
}
|
||||
|
||||
if err := updateIssueClosedNum(ctx, issue); err != nil {
|
||||
// update repository's issue closed number
|
||||
if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -762,11 +767,11 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err
|
|||
defer committer.Close()
|
||||
|
||||
if err = UpdateIssueCols(ctx, issue, "name"); err != nil {
|
||||
return fmt.Errorf("updateIssueCols: %v", err)
|
||||
return fmt.Errorf("updateIssueCols: %w", err)
|
||||
}
|
||||
|
||||
if err = issue.LoadRepo(ctx); err != nil {
|
||||
return fmt.Errorf("loadRepo: %v", err)
|
||||
return fmt.Errorf("loadRepo: %w", err)
|
||||
}
|
||||
|
||||
opts := &CreateCommentOptions{
|
||||
|
@ -778,7 +783,7 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err
|
|||
NewTitle: issue.Title,
|
||||
}
|
||||
if _, err = CreateCommentCtx(ctx, opts); err != nil {
|
||||
return fmt.Errorf("createComment: %v", err)
|
||||
return fmt.Errorf("createComment: %w", err)
|
||||
}
|
||||
if err = issue.AddCrossReferences(ctx, doer, true); err != nil {
|
||||
return err
|
||||
|
@ -796,11 +801,11 @@ func ChangeIssueRef(issue *Issue, doer *user_model.User, oldRef string) (err err
|
|||
defer committer.Close()
|
||||
|
||||
if err = UpdateIssueCols(ctx, issue, "ref"); err != nil {
|
||||
return fmt.Errorf("updateIssueCols: %v", err)
|
||||
return fmt.Errorf("updateIssueCols: %w", err)
|
||||
}
|
||||
|
||||
if err = issue.LoadRepo(ctx); err != nil {
|
||||
return fmt.Errorf("loadRepo: %v", err)
|
||||
return fmt.Errorf("loadRepo: %w", err)
|
||||
}
|
||||
oldRefFriendly := strings.TrimPrefix(oldRef, git.BranchPrefix)
|
||||
newRefFriendly := strings.TrimPrefix(issue.Ref, git.BranchPrefix)
|
||||
|
@ -814,7 +819,7 @@ func ChangeIssueRef(issue *Issue, doer *user_model.User, oldRef string) (err err
|
|||
NewRef: newRefFriendly,
|
||||
}
|
||||
if _, err = CreateCommentCtx(ctx, opts); err != nil {
|
||||
return fmt.Errorf("createComment: %v", err)
|
||||
return fmt.Errorf("createComment: %w", err)
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
|
@ -846,12 +851,12 @@ func UpdateIssueAttachments(issueID int64, uuids []string) (err error) {
|
|||
defer committer.Close()
|
||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err)
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", uuids, err)
|
||||
}
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
attachments[i].IssueID = issueID
|
||||
if err := repo_model.UpdateAttachment(ctx, attachments[i]); err != nil {
|
||||
return fmt.Errorf("update attachment [id: %d]: %v", attachments[i].ID, err)
|
||||
return fmt.Errorf("update attachment [id: %d]: %w", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
return committer.Commit()
|
||||
|
@ -867,28 +872,28 @@ func ChangeIssueContent(issue *Issue, doer *user_model.User, content string) (er
|
|||
|
||||
hasContentHistory, err := HasIssueContentHistory(ctx, issue.ID, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("HasIssueContentHistory: %v", err)
|
||||
return fmt.Errorf("HasIssueContentHistory: %w", err)
|
||||
}
|
||||
if !hasContentHistory {
|
||||
if err = SaveIssueContentHistory(ctx, issue.PosterID, issue.ID, 0,
|
||||
issue.CreatedUnix, issue.Content, true); err != nil {
|
||||
return fmt.Errorf("SaveIssueContentHistory: %v", err)
|
||||
return fmt.Errorf("SaveIssueContentHistory: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
issue.Content = content
|
||||
|
||||
if err = UpdateIssueCols(ctx, issue, "content"); err != nil {
|
||||
return fmt.Errorf("UpdateIssueCols: %v", err)
|
||||
return fmt.Errorf("UpdateIssueCols: %w", err)
|
||||
}
|
||||
|
||||
if err = SaveIssueContentHistory(ctx, doer.ID, issue.ID, 0,
|
||||
timeutil.TimeStampNow(), issue.Content, false); err != nil {
|
||||
return fmt.Errorf("SaveIssueContentHistory: %v", err)
|
||||
return fmt.Errorf("SaveIssueContentHistory: %w", err)
|
||||
}
|
||||
|
||||
if err = issue.AddCrossReferences(ctx, doer, true); err != nil {
|
||||
return fmt.Errorf("addCrossReferences: %v", err)
|
||||
return fmt.Errorf("addCrossReferences: %w", err)
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
|
@ -965,7 +970,7 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
|
|||
if opts.Issue.MilestoneID > 0 {
|
||||
milestone, err := GetMilestoneByRepoID(ctx, opts.Issue.RepoID, opts.Issue.MilestoneID)
|
||||
if err != nil && !IsErrMilestoneNotExist(err) {
|
||||
return fmt.Errorf("getMilestoneByID: %v", err)
|
||||
return fmt.Errorf("getMilestoneByID: %w", err)
|
||||
}
|
||||
|
||||
// Assume milestone is invalid and drop silently.
|
||||
|
@ -1019,7 +1024,7 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
|
|||
// So we have to get all needed labels first.
|
||||
labels := make([]*Label, 0, len(opts.LabelIDs))
|
||||
if err = e.In("id", opts.LabelIDs).Find(&labels); err != nil {
|
||||
return fmt.Errorf("find all labels [label_ids: %v]: %v", opts.LabelIDs, err)
|
||||
return fmt.Errorf("find all labels [label_ids: %v]: %w", opts.LabelIDs, err)
|
||||
}
|
||||
|
||||
if err = opts.Issue.loadPoster(ctx); err != nil {
|
||||
|
@ -1033,7 +1038,7 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
|
|||
}
|
||||
|
||||
if err = newIssueLabel(ctx, opts.Issue, label, opts.Issue.Poster); err != nil {
|
||||
return fmt.Errorf("addLabel [id: %d]: %v", label.ID, err)
|
||||
return fmt.Errorf("addLabel [id: %d]: %w", label.ID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1045,13 +1050,13 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
|
|||
if len(opts.Attachments) > 0 {
|
||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", opts.Attachments, err)
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", opts.Attachments, err)
|
||||
}
|
||||
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
attachments[i].IssueID = opts.Issue.ID
|
||||
if _, err = e.ID(attachments[i].ID).Update(attachments[i]); err != nil {
|
||||
return fmt.Errorf("update attachment [id: %d]: %v", attachments[i].ID, err)
|
||||
return fmt.Errorf("update attachment [id: %d]: %w", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1064,19 +1069,19 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
|
|||
|
||||
// NewIssue creates new issue with labels for repository.
|
||||
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()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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{
|
||||
Repo: repo,
|
||||
Issue: issue,
|
||||
|
@ -1086,11 +1091,11 @@ func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids
|
|||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("newIssue: %v", err)
|
||||
return fmt.Errorf("newIssue: %w", err)
|
||||
}
|
||||
|
||||
if err = committer.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
return fmt.Errorf("Commit: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -1492,7 +1497,8 @@ func applySubscribedCondition(sess *xorm.Session, subscriberID int64) *xorm.Sess
|
|||
builder.In("issue.repo_id", builder.
|
||||
Select("id").
|
||||
From("watch").
|
||||
Where(builder.Eq{"user_id": subscriberID, "mode": true}),
|
||||
Where(builder.And(builder.Eq{"user_id": subscriberID},
|
||||
builder.In("mode", repo_model.WatchModeNormal, repo_model.WatchModeAuto))),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -1609,7 +1615,7 @@ func UpdateIssueMentions(ctx context.Context, issueID int64, mentions []*user_mo
|
|||
ids[i] = u.ID
|
||||
}
|
||||
if err := UpdateIssueUsersByMentions(ctx, issueID, ids); err != nil {
|
||||
return fmt.Errorf("UpdateIssueUsersByMentions: %v", err)
|
||||
return fmt.Errorf("UpdateIssueUsersByMentions: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -1987,7 +1993,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment
|
|||
defer committer.Close()
|
||||
|
||||
if err := issue.LoadRepo(ctx); err != nil {
|
||||
return nil, false, fmt.Errorf("loadRepo: %v", err)
|
||||
return nil, false, fmt.Errorf("loadRepo: %w", err)
|
||||
}
|
||||
|
||||
// Reload the issue
|
||||
|
@ -2015,7 +2021,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment
|
|||
}
|
||||
_, err := CreateCommentCtx(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("createComment: %v", err)
|
||||
return nil, false, fmt.Errorf("createComment: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2051,7 +2057,7 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *us
|
|||
|
||||
// Make the comment
|
||||
if _, err = createDeadlineComment(ctx, doer, issue, deadlineUnix); err != nil {
|
||||
return fmt.Errorf("createRemovedDueDateComment: %v", err)
|
||||
return fmt.Errorf("createRemovedDueDateComment: %w", err)
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
|
@ -2088,7 +2094,7 @@ func (issue *Issue) GetParticipantIDsByIssue(ctx context.Context) ([]int64, erro
|
|||
Join("INNER", "`user`", "`user`.id = `comment`.poster_id").
|
||||
Distinct("poster_id").
|
||||
Find(&userIDs); err != nil {
|
||||
return nil, fmt.Errorf("get poster IDs: %v", err)
|
||||
return nil, fmt.Errorf("get poster IDs: %w", err)
|
||||
}
|
||||
if !util.IsInt64InSlice(issue.PosterID, userIDs) {
|
||||
return append(userIDs, issue.PosterID), nil
|
||||
|
@ -2132,24 +2138,15 @@ func (issue *Issue) BlockingDependencies(ctx context.Context) (issueDeps []*Depe
|
|||
return issueDeps, err
|
||||
}
|
||||
|
||||
func updateIssueClosedNum(ctx context.Context, issue *Issue) (err error) {
|
||||
if issue.IsPull {
|
||||
err = repo_model.StatsCorrectNumClosed(ctx, issue.RepoID, true, "num_closed_pulls")
|
||||
} else {
|
||||
err = repo_model.StatsCorrectNumClosed(ctx, issue.RepoID, false, "num_closed_issues")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// FindAndUpdateIssueMentions finds users mentioned in the given content string, and saves them in the database.
|
||||
func FindAndUpdateIssueMentions(ctx context.Context, issue *Issue, doer *user_model.User, content string) (mentions []*user_model.User, err error) {
|
||||
rawMentions := references.FindAllMentionsMarkdown(content)
|
||||
mentions, err = ResolveIssueMentionsByVisibility(ctx, issue, doer, rawMentions)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("UpdateIssueMentions [%d]: %v", issue.ID, err)
|
||||
return nil, fmt.Errorf("UpdateIssueMentions [%d]: %w", issue.ID, err)
|
||||
}
|
||||
if err = UpdateIssueMentions(ctx, issue.ID, mentions); err != nil {
|
||||
return nil, fmt.Errorf("UpdateIssueMentions [%d]: %v", issue.ID, err)
|
||||
return nil, fmt.Errorf("UpdateIssueMentions [%d]: %w", issue.ID, err)
|
||||
}
|
||||
return mentions, err
|
||||
}
|
||||
|
@ -2201,7 +2198,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
|||
Where("team_repo.repo_id=?", issue.Repo.ID).
|
||||
In("team.lower_name", mentionTeams).
|
||||
Find(&teams); err != nil {
|
||||
return nil, fmt.Errorf("find mentioned teams: %v", err)
|
||||
return nil, fmt.Errorf("find mentioned teams: %w", err)
|
||||
}
|
||||
if len(teams) != 0 {
|
||||
checked := make([]int64, 0, len(teams))
|
||||
|
@ -2217,7 +2214,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
|||
}
|
||||
has, err := db.GetEngine(ctx).Get(&organization.TeamUnit{OrgID: issue.Repo.Owner.ID, TeamID: team.ID, Type: unittype})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get team units (%d): %v", team.ID, err)
|
||||
return nil, fmt.Errorf("get team units (%d): %w", team.ID, err)
|
||||
}
|
||||
if has {
|
||||
checked = append(checked, team.ID)
|
||||
|
@ -2232,7 +2229,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
|||
And("`user`.is_active = ?", true).
|
||||
And("`user`.prohibit_login = ?", false).
|
||||
Find(&teamusers); err != nil {
|
||||
return nil, fmt.Errorf("get teams users: %v", err)
|
||||
return nil, fmt.Errorf("get teams users: %w", err)
|
||||
}
|
||||
if len(teamusers) > 0 {
|
||||
users = make([]*user_model.User, 0, len(teamusers))
|
||||
|
@ -2268,7 +2265,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
|||
And("`user`.prohibit_login = ?", false).
|
||||
In("`user`.lower_name", mentionUsers).
|
||||
Find(&unchecked); err != nil {
|
||||
return nil, fmt.Errorf("find mentioned users: %v", err)
|
||||
return nil, fmt.Errorf("find mentioned users: %w", err)
|
||||
}
|
||||
for _, user := range unchecked {
|
||||
if already := resolved[user.LowerName]; already || user.IsOrganization() {
|
||||
|
@ -2277,7 +2274,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
|||
// Normal users must have read access to the referencing issue
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, user)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserRepoPermission [%d]: %v", user.ID, err)
|
||||
return nil, fmt.Errorf("GetUserRepoPermission [%d]: %w", user.ID, err)
|
||||
}
|
||||
if !perm.CanReadIssuesOrPulls(issue.IsPull) {
|
||||
continue
|
||||
|
@ -2470,7 +2467,7 @@ func DeleteOrphanedIssues() error {
|
|||
|
||||
// Remove issue attachment files.
|
||||
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
|
||||
}
|
||||
|
|
|
@ -15,16 +15,12 @@ func RecalculateIssueIndexForRepo(repoID int64) error {
|
|||
}
|
||||
defer committer.Close()
|
||||
|
||||
if err := db.UpsertResourceIndex(ctx, "issue_index", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue