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
|
- name: checks-backend
|
||||||
image: golang:1.19
|
image: golang:1.19
|
||||||
commands:
|
commands:
|
||||||
- make checks-backend
|
- make --always-make checks-backend # ensure the 'go-licenses' make target runs
|
||||||
depends_on: [deps-backend]
|
depends_on: [deps-backend]
|
||||||
volumes:
|
volumes:
|
||||||
- name: deps
|
- name: deps
|
||||||
|
@ -112,16 +112,11 @@ steps:
|
||||||
- make test-frontend
|
- make test-frontend
|
||||||
depends_on: [lint-frontend]
|
depends_on: [lint-frontend]
|
||||||
|
|
||||||
- name: generate-frontend
|
|
||||||
image: golang:1.19
|
|
||||||
commands:
|
|
||||||
- make generate-frontend
|
|
||||||
|
|
||||||
- name: build-frontend
|
- name: build-frontend
|
||||||
image: node:18
|
image: node:18
|
||||||
commands:
|
commands:
|
||||||
- make frontend
|
- make frontend
|
||||||
depends_on: [deps-frontend, generate-frontend]
|
depends_on: [deps-frontend]
|
||||||
|
|
||||||
- name: build-backend-no-gcc
|
- name: build-backend-no-gcc
|
||||||
image: golang:1.18 # this step is kept as the lowest version of golang that we support
|
image: golang:1.18 # this step is kept as the lowest version of golang that we support
|
||||||
|
@ -549,16 +544,11 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- make deps-frontend
|
- make deps-frontend
|
||||||
|
|
||||||
- name: generate-frontend
|
|
||||||
image: golang:1.18
|
|
||||||
commands:
|
|
||||||
- make generate-frontend
|
|
||||||
|
|
||||||
- name: build-frontend
|
- name: build-frontend
|
||||||
image: node:18
|
image: node:18
|
||||||
commands:
|
commands:
|
||||||
- make frontend
|
- make frontend
|
||||||
depends_on: [deps-frontend, generate-frontend]
|
depends_on: [deps-frontend]
|
||||||
|
|
||||||
- name: deps-backend
|
- name: deps-backend
|
||||||
image: golang:1.18
|
image: golang:1.18
|
||||||
|
@ -571,9 +561,9 @@ steps:
|
||||||
|
|
||||||
# TODO: We should probably build all dependencies into a test image
|
# TODO: We should probably build all dependencies into a test image
|
||||||
- name: test-e2e
|
- name: test-e2e
|
||||||
image: mcr.microsoft.com/playwright:v1.24.0-focal
|
image: mcr.microsoft.com/playwright:v1.27.1-focal
|
||||||
commands:
|
commands:
|
||||||
- curl -sLO https://go.dev/dl/go1.18.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz
|
- curl -sLO https://go.dev/dl/go1.19.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
|
||||||
- groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea
|
- groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea
|
||||||
- apt-get -qq update && apt-get -qqy install build-essential
|
- apt-get -qq update && apt-get -qqy install build-essential
|
||||||
- export TEST_PGSQL_SCHEMA=''
|
- export TEST_PGSQL_SCHEMA=''
|
||||||
|
@ -636,6 +626,8 @@ steps:
|
||||||
commit_message: "[skip ci] Updated translations via Crowdin"
|
commit_message: "[skip ci] Updated translations via Crowdin"
|
||||||
remote: "git@github.com:go-gitea/gitea.git"
|
remote: "git@github.com:go-gitea/gitea.git"
|
||||||
environment:
|
environment:
|
||||||
|
DRONE_COMMIT_AUTHOR_EMAIL: "teabot@gitea.io"
|
||||||
|
DRONE_COMMIT_AUTHOR: GiteaBot
|
||||||
GIT_PUSH_SSH_KEY:
|
GIT_PUSH_SSH_KEY:
|
||||||
from_secret: git_push_ssh_key
|
from_secret: git_push_ssh_key
|
||||||
|
|
||||||
|
@ -680,12 +672,14 @@ steps:
|
||||||
pull: always
|
pull: always
|
||||||
settings:
|
settings:
|
||||||
author_email: "teabot@gitea.io"
|
author_email: "teabot@gitea.io"
|
||||||
author_name: GiteaBot
|
author_name: "GiteaBot"
|
||||||
branch: main
|
branch: main
|
||||||
commit: true
|
commit: true
|
||||||
commit_message: "[skip ci] Updated licenses and gitignores "
|
commit_message: "[skip ci] Updated licenses and gitignores"
|
||||||
remote: "git@github.com:go-gitea/gitea.git"
|
remote: "git@github.com:go-gitea/gitea.git"
|
||||||
environment:
|
environment:
|
||||||
|
DRONE_COMMIT_AUTHOR_EMAIL: "teabot@gitea.io"
|
||||||
|
DRONE_COMMIT_AUTHOR: "GiteaBot"
|
||||||
GIT_PUSH_SSH_KEY:
|
GIT_PUSH_SSH_KEY:
|
||||||
from_secret: git_push_ssh_key
|
from_secret: git_push_ssh_key
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,6 @@ overrides:
|
||||||
rules:
|
rules:
|
||||||
import/no-unresolved: [0]
|
import/no-unresolved: [0]
|
||||||
import/no-extraneous-dependencies: [0]
|
import/no-extraneous-dependencies: [0]
|
||||||
- files: ["*.test.js"]
|
|
||||||
env:
|
|
||||||
jest: true
|
|
||||||
- files: ["*.config.js"]
|
- files: ["*.config.js"]
|
||||||
rules:
|
rules:
|
||||||
import/no-unused-modules: [0]
|
import/no-unused-modules: [0]
|
||||||
|
@ -185,6 +182,7 @@ rules:
|
||||||
linebreak-style: [2, unix]
|
linebreak-style: [2, unix]
|
||||||
lines-around-comment: [0]
|
lines-around-comment: [0]
|
||||||
lines-between-class-members: [0]
|
lines-between-class-members: [0]
|
||||||
|
logical-assignment-operators: [0]
|
||||||
max-classes-per-file: [0]
|
max-classes-per-file: [0]
|
||||||
max-depth: [0]
|
max-depth: [0]
|
||||||
max-len: [0]
|
max-len: [0]
|
||||||
|
@ -245,7 +243,7 @@ rules:
|
||||||
no-floating-decimal: [0]
|
no-floating-decimal: [0]
|
||||||
no-func-assign: [2]
|
no-func-assign: [2]
|
||||||
no-global-assign: [2]
|
no-global-assign: [2]
|
||||||
no-implicit-coercion: [0]
|
no-implicit-coercion: [2]
|
||||||
no-implicit-globals: [0]
|
no-implicit-globals: [0]
|
||||||
no-implied-eval: [2]
|
no-implied-eval: [2]
|
||||||
no-import-assign: [2]
|
no-import-assign: [2]
|
||||||
|
@ -256,7 +254,7 @@ rules:
|
||||||
no-irregular-whitespace: [2]
|
no-irregular-whitespace: [2]
|
||||||
no-iterator: [2]
|
no-iterator: [2]
|
||||||
no-label-var: [2]
|
no-label-var: [2]
|
||||||
no-labels: [2]
|
no-labels: [0]
|
||||||
no-lone-blocks: [2]
|
no-lone-blocks: [2]
|
||||||
no-lonely-if: [0]
|
no-lonely-if: [0]
|
||||||
no-loop-func: [0]
|
no-loop-func: [0]
|
||||||
|
@ -322,7 +320,7 @@ rules:
|
||||||
no-unused-private-class-members: [2]
|
no-unused-private-class-members: [2]
|
||||||
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
|
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
|
||||||
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
|
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
|
||||||
no-useless-backreference: [0]
|
no-useless-backreference: [2]
|
||||||
no-useless-call: [2]
|
no-useless-call: [2]
|
||||||
no-useless-catch: [2]
|
no-useless-catch: [2]
|
||||||
no-useless-computed-key: [2]
|
no-useless-computed-key: [2]
|
||||||
|
@ -335,7 +333,7 @@ rules:
|
||||||
no-void: [2]
|
no-void: [2]
|
||||||
no-warning-comments: [0]
|
no-warning-comments: [0]
|
||||||
no-whitespace-before-property: [2]
|
no-whitespace-before-property: [2]
|
||||||
no-with: [2]
|
no-with: [0]
|
||||||
nonblock-statement-body-position: [2]
|
nonblock-statement-body-position: [2]
|
||||||
object-curly-newline: [0]
|
object-curly-newline: [0]
|
||||||
object-curly-spacing: [2, never]
|
object-curly-spacing: [2, never]
|
||||||
|
@ -353,7 +351,7 @@ rules:
|
||||||
prefer-named-capture-group: [0]
|
prefer-named-capture-group: [0]
|
||||||
prefer-numeric-literals: [2]
|
prefer-numeric-literals: [2]
|
||||||
prefer-object-has-own: [0]
|
prefer-object-has-own: [0]
|
||||||
prefer-object-spread: [0]
|
prefer-object-spread: [2]
|
||||||
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
|
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
|
||||||
prefer-regex-literals: [2]
|
prefer-regex-literals: [2]
|
||||||
prefer-rest-params: [2]
|
prefer-rest-params: [2]
|
||||||
|
@ -380,11 +378,11 @@ rules:
|
||||||
sonarjs/no-duplicated-branches: [0]
|
sonarjs/no-duplicated-branches: [0]
|
||||||
sonarjs/no-element-overwrite: [2]
|
sonarjs/no-element-overwrite: [2]
|
||||||
sonarjs/no-empty-collection: [2]
|
sonarjs/no-empty-collection: [2]
|
||||||
sonarjs/no-extra-arguments: [0]
|
sonarjs/no-extra-arguments: [2]
|
||||||
sonarjs/no-gratuitous-expressions: [2]
|
sonarjs/no-gratuitous-expressions: [2]
|
||||||
sonarjs/no-identical-conditions: [2]
|
sonarjs/no-identical-conditions: [2]
|
||||||
sonarjs/no-identical-expressions: [0]
|
sonarjs/no-identical-expressions: [2]
|
||||||
sonarjs/no-identical-functions: [0]
|
sonarjs/no-identical-functions: [2, 5]
|
||||||
sonarjs/no-ignored-return: [2]
|
sonarjs/no-ignored-return: [2]
|
||||||
sonarjs/no-inverted-boolean-check: [2]
|
sonarjs/no-inverted-boolean-check: [2]
|
||||||
sonarjs/no-nested-switch: [0]
|
sonarjs/no-nested-switch: [0]
|
||||||
|
@ -396,7 +394,7 @@ rules:
|
||||||
sonarjs/no-small-switch: [0]
|
sonarjs/no-small-switch: [0]
|
||||||
sonarjs/no-unused-collection: [2]
|
sonarjs/no-unused-collection: [2]
|
||||||
sonarjs/no-use-of-empty-return-value: [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/non-existent-operator: [2]
|
||||||
sonarjs/prefer-immediate-return: [0]
|
sonarjs/prefer-immediate-return: [0]
|
||||||
sonarjs/prefer-object-literal: [0]
|
sonarjs/prefer-object-literal: [0]
|
||||||
|
@ -455,6 +453,7 @@ rules:
|
||||||
unicorn/no-static-only-class: [2]
|
unicorn/no-static-only-class: [2]
|
||||||
unicorn/no-thenable: [2]
|
unicorn/no-thenable: [2]
|
||||||
unicorn/no-this-assignment: [2]
|
unicorn/no-this-assignment: [2]
|
||||||
|
unicorn/no-unnecessary-await: [2]
|
||||||
unicorn/no-unreadable-array-destructuring: [0]
|
unicorn/no-unreadable-array-destructuring: [0]
|
||||||
unicorn/no-unreadable-iife: [2]
|
unicorn/no-unreadable-iife: [2]
|
||||||
unicorn/no-unsafe-regex: [0]
|
unicorn/no-unsafe-regex: [0]
|
||||||
|
@ -519,6 +518,7 @@ rules:
|
||||||
unicorn/require-number-to-fixed-digits-argument: [2]
|
unicorn/require-number-to-fixed-digits-argument: [2]
|
||||||
unicorn/require-post-message-target-origin: [0]
|
unicorn/require-post-message-target-origin: [0]
|
||||||
unicorn/string-content: [0]
|
unicorn/string-content: [0]
|
||||||
|
unicorn/switch-case-braces: [0]
|
||||||
unicorn/template-indent: [2]
|
unicorn/template-indent: [2]
|
||||||
unicorn/text-encoding-identifier-case: [0]
|
unicorn/text-encoding-identifier-case: [0]
|
||||||
unicorn/throw-new-error: [2]
|
unicorn/throw-new-error: [2]
|
||||||
|
|
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -1,5 +1,6 @@
|
||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
*.tmpl linguist-language=Handlebars
|
*.tmpl linguist-language=Handlebars
|
||||||
|
/assets/*.json linguist-generated
|
||||||
/public/vendor/** -text -eol linguist-vendored
|
/public/vendor/** -text -eol linguist-vendored
|
||||||
/vendor/** -text -eol linguist-vendored
|
/vendor/** -text -eol linguist-vendored
|
||||||
/web_src/fomantic/build/** linguist-generated
|
/web_src/fomantic/build/** linguist-generated
|
||||||
|
|
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
|
- dupl
|
||||||
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
|
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
|
||||||
- gofmt
|
- gofmt
|
||||||
- misspell
|
|
||||||
- gocritic
|
- gocritic
|
||||||
- bidichk
|
- bidichk
|
||||||
- ineffassign
|
- ineffassign
|
||||||
|
@ -148,9 +147,6 @@ issues:
|
||||||
- path: models/issue_comment_list.go
|
- path: models/issue_comment_list.go
|
||||||
linters:
|
linters:
|
||||||
- dupl
|
- dupl
|
||||||
- linters:
|
|
||||||
- misspell
|
|
||||||
text: '`Unknwon` is a misspelling of `Unknown`'
|
|
||||||
- path: models/update.go
|
- path: models/update.go
|
||||||
linters:
|
linters:
|
||||||
- unused
|
- unused
|
||||||
|
|
|
@ -16,6 +16,7 @@ rules:
|
||||||
declaration-empty-line-before: null
|
declaration-empty-line-before: null
|
||||||
function-no-unknown: null
|
function-no-unknown: null
|
||||||
hue-degree-notation: null
|
hue-degree-notation: null
|
||||||
|
import-notation: string
|
||||||
indentation: 2
|
indentation: 2
|
||||||
max-line-length: null
|
max-line-length: null
|
||||||
no-descending-specificity: 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
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
|
## [1.17.3](https://github.com/go-gitea/gitea/releases/tag/v1.17.3) - 2022-10-15
|
||||||
|
|
||||||
|
* SECURITY
|
||||||
|
* Sanitize and Escape refs in git backend (#21464) (#21463)
|
||||||
|
* Bump `golang.org/x/text` (#21412) (#21413)
|
||||||
|
* Update bluemonday (#21281) (#21287)
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* Fix empty container layer history and UI (#21251) (#21278)
|
||||||
|
* Use en-US as fallback when using other default language (#21200) (#21256)
|
||||||
|
* Make the vscode clone link respect transport protocol (#20557) (#21128)
|
||||||
|
* BUGFIXES
|
||||||
|
* Do DB update after merge in hammer context (#21401) (#21416)
|
||||||
|
* Add Num{Issues,Pulls} stats checks (#21404) (#21414)
|
||||||
|
* Stop logging CheckPath returns error: context canceled (#21064) (#21405)
|
||||||
|
* Parse OAuth Authorization header when request omits client secret (#21351) (#21374)
|
||||||
|
* Ignore port for loopback redirect URIs (#21293) (#21373)
|
||||||
|
* Set SemverCompatible to false for Conan packages (#21275) (#21366)
|
||||||
|
* Tag list should include draft releases with existing tags (#21263) (#21365)
|
||||||
|
* Fix linked account translation (#21331) (#21334)
|
||||||
|
* Make NuGet service index publicly accessible (#21242) (#21277)
|
||||||
|
* Foreign ID conflicts if ID is 0 for each item (#21271) (#21272)
|
||||||
|
* Use absolute links in feeds (#21229) (#21265)
|
||||||
|
* Prevent invalid behavior for file reviewing when loading more files (#21230) (#21234)
|
||||||
|
* Respect `REQUIRE_SIGNIN_VIEW` for packages (#20873) (#21232)
|
||||||
|
* Treat git object mode 40755 as directory (#21195) (#21218)
|
||||||
|
* Allow uppercase ASCII alphabet in PyPI package names (#21095) (#21217)
|
||||||
|
* Fix limited user cannot view himself's profile (#21212)
|
||||||
|
* Fix template bug of admin monitor (#21209)
|
||||||
|
* Fix reaction of issues (#21185) (#21196)
|
||||||
|
* Fix CSV diff for added/deleted files (#21189) (#21193)
|
||||||
|
* Fix pagination limit parameter problem (#21111)
|
||||||
|
* TESTING
|
||||||
|
* Fix missing m.Run() in TestMain (#21341)
|
||||||
|
* BUILD
|
||||||
|
* Use Go 1.19 fmt for Gitea 1.17, sync emoji data (#21239)
|
||||||
|
|
||||||
|
## [1.17.2](https://github.com/go-gitea/gitea/releases/tag/v1.17.2) - 2022-09-06
|
||||||
|
|
||||||
|
* SECURITY
|
||||||
|
* Double check CloneURL is acceptable (#20869) (#20892)
|
||||||
|
* Add more checks in migration code (#21011) (#21050)
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* Fix hard-coded timeout and error panic in API archive download endpoint (#20925) (#21051)
|
||||||
|
* Improve arc-green code theme (#21039) (#21042)
|
||||||
|
* Enable contenthash in filename for dynamic assets (#20813) (#20932)
|
||||||
|
* Don't open new page for ext wiki on same repository (#20725) (#20910)
|
||||||
|
* Disable doctor logging on panic (#20847) (#20898)
|
||||||
|
* Remove calls to load Mirrors in user.Dashboard (#20855) (#20897)
|
||||||
|
* Update codemirror to 5.65.8 (#20875)
|
||||||
|
* Rework repo buttons (#20602, #20718) (#20719)
|
||||||
|
* BUGFIXES
|
||||||
|
* Ensure delete user deletes all comments (#21067) (#21068)
|
||||||
|
* Delete unreferenced packages when deleting a package version (#20977) (#21060)
|
||||||
|
* Redirect if user does not exist on admin pages (#20981) (#21059)
|
||||||
|
* Set uploadpack.allowFilter etc on gitea serv to enable partial clones with ssh (#20902) (#21058)
|
||||||
|
* Fix 500 on time in timeline API (#21052) (#21057)
|
||||||
|
* Fill the specified ref in webhook test payload (#20961) (#21055)
|
||||||
|
* Add another index for Action table on postgres (#21033) (#21054)
|
||||||
|
* Fix broken insecureskipverify handling in redis connection uris (#20967) (#21053)
|
||||||
|
* Add Dev, Peer and Optional dependencies to npm PackageMetadataVersion (#21017) (#21044)
|
||||||
|
* Do not add links to Posters or Assignees with ID < 0 (#20577) (#21037)
|
||||||
|
* Fix modified due date message (#20388) (#21032)
|
||||||
|
* Fix missed sort bug (#21006)
|
||||||
|
* Fix input.value attr for RequiredClaimName/Value (#20946) (#21001)
|
||||||
|
* Change review buttons to icons to make space for text (#20934) (#20978)
|
||||||
|
* Fix download archiver of a commit (#20962) (#20971)
|
||||||
|
* Return 404 NotFound if requested attachment does not exist (#20886) (#20941)
|
||||||
|
* Set no-tags in git fetch on compare (#20893) (#20936)
|
||||||
|
* Allow multiple metadata files for Maven packages (#20674) (#20916)
|
||||||
|
* Increase Content field size of gpg_key and public_key to MEDIUMTEXT (#20896) (#20911)
|
||||||
|
* Fix mirror address setting not working (#20850) (#20904)
|
||||||
|
* Fix push mirror address backend get error Address cause setting page display error (#20593) (#20901)
|
||||||
|
* Fix panic when an invalid oauth2 name is passed (#20820) (#20900)
|
||||||
|
* In PushMirrorsIterate and MirrorsIterate if limit is negative do not set it (#20837) (#20899)
|
||||||
|
* Ensure that graceful start-up is informed of unused SSH listener (#20877) (#20888)
|
||||||
|
* Pad GPG Key ID with preceding zeroes (#20878) (#20885)
|
||||||
|
* Fix SQL Query for `SearchTeam` (#20844) (#20872)
|
||||||
|
* Fix the mode of custom dir to 0700 in docker-rootless (#20861) (#20867)
|
||||||
|
* Fix UI mis-align for PR commit history (#20845) (#20859)
|
||||||
|
|
||||||
## [1.17.1](https://github.com/go-gitea/gitea/releases/tag/1.17.1) - 2022-08-17
|
## [1.17.1](https://github.com/go-gitea/gitea/releases/tag/1.17.1) - 2022-08-17
|
||||||
|
|
||||||
* SECURITY
|
* SECURITY
|
||||||
|
|
|
@ -146,6 +146,16 @@ If your PR could cause a breaking change you must add a BREAKING section to this
|
||||||
|
|
||||||
To explain how this could affect users and how to mitigate these changes.
|
To explain how this could affect users and how to mitigate these changes.
|
||||||
|
|
||||||
|
Once code review starts on your PR, do not rebase nor squash your branch as it makes it
|
||||||
|
difficult to review the new changes. Only if there is a need, sync your branch by merging
|
||||||
|
the base branch into yours. Don't worry about merge commits messing up your tree as
|
||||||
|
the final merge process squashes all commits into one, with the visible commit message (first
|
||||||
|
line) being the PR title + PR index and description being the PR's first comment.
|
||||||
|
|
||||||
|
Once your PR gets the `lgtm/done` label, don't worry about keeping it up-to-date or breaking
|
||||||
|
builds (unless there's a merge conflict or a request is made by a maintainer to make
|
||||||
|
modifications). It is the maintainer team's responsibility from this point to get it merged.
|
||||||
|
|
||||||
## Styleguide
|
## Styleguide
|
||||||
|
|
||||||
For imports you should use the following format (*without* the comments)
|
For imports you should use the following format (*without* the comments)
|
||||||
|
@ -170,17 +180,22 @@ import (
|
||||||
|
|
||||||
To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts:
|
To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts:
|
||||||
|
|
||||||
- **integration:** Integration tests
|
|
||||||
- **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
|
- **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
|
||||||
- **models/fixtures:** Sample model data used in integration tests.
|
- **models/fixtures:** Sample model data used in integration tests.
|
||||||
- **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step.
|
- **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step.
|
||||||
- **modules:** Different modules to handle specific functionality in Gitea.
|
- **modules:** Different modules to handle specific functionality in Gitea. Shall only depend on other modules but not other packages (models, services).
|
||||||
- **public:** Frontend files (javascript, images, css, etc.)
|
- **public:** Frontend files (javascript, images, css, etc.)
|
||||||
- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers
|
- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers.
|
||||||
- **services:** Support functions for common routing operations. Uses models and modules to handle the request.
|
- **services:** Support functions for common routing operations. Uses models and modules to handle the request.
|
||||||
- **templates:** Golang templates for generating the html output.
|
- **templates:** Golang templates for generating the html output.
|
||||||
|
- **tests/e2e:** End to end tests
|
||||||
|
- **tests/integration:** Integration tests
|
||||||
- **vendor:** External code that Gitea depends on.
|
- **vendor:** External code that Gitea depends on.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated.
|
||||||
|
|
||||||
## API v1
|
## API v1
|
||||||
|
|
||||||
The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [GitHub API v3](https://developer.github.com/v3/).
|
The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [GitHub API v3](https://developer.github.com/v3/).
|
||||||
|
@ -229,27 +244,6 @@ An endpoint which changes/edits an object expects all fields to be optional (exc
|
||||||
- support pagination (`page` & `limit` options in query)
|
- support pagination (`page` & `limit` options in query)
|
||||||
- set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
|
- set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
|
||||||
|
|
||||||
## Large Character Comments
|
|
||||||
|
|
||||||
Throughout the codebase there are large-text comments for sections of code, e.g.:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// __________ .__
|
|
||||||
// \______ \ _______ _|__| ______ _ __
|
|
||||||
// | _// __ \ \/ / |/ __ \ \/ \/ /
|
|
||||||
// | | \ ___/\ /| \ ___/\ /
|
|
||||||
// |____|_ /\___ >\_/ |__|\___ >\/\_/
|
|
||||||
// \/ \/ \/
|
|
||||||
```
|
|
||||||
|
|
||||||
These were created using the `figlet` tool with the `graffiti` font.
|
|
||||||
|
|
||||||
A simple way of creating these is to use the following:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
figlet -f graffiti Review | sed -e's+^+// +' - | xclip -sel clip -in
|
|
||||||
```
|
|
||||||
|
|
||||||
## Backports and Frontports
|
## Backports and Frontports
|
||||||
|
|
||||||
Occasionally backports of PRs are required.
|
Occasionally backports of PRs are required.
|
||||||
|
|
|
@ -49,3 +49,4 @@ silentcode <silentcode@senga.org> (@silentcodeg)
|
||||||
Wim <wim@42.be> (@42wim)
|
Wim <wim@42.be> (@42wim)
|
||||||
xinyu <xinyu@nerv.org.cn> (@penlinux)
|
xinyu <xinyu@nerv.org.cn> (@penlinux)
|
||||||
Jason Song <i@wolfogre.com> (@wolfogre)
|
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)
|
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR)
|
||||||
|
|
||||||
GO_DIRS := cmd tests models modules routers build services tools
|
GO_DIRS := cmd tests models modules routers build services tools
|
||||||
|
WEB_DIRS := web_src/js web_src/less
|
||||||
|
|
||||||
GO_SOURCES := $(wildcard *.go)
|
GO_SOURCES := $(wildcard *.go)
|
||||||
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go)
|
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go)
|
||||||
|
@ -263,11 +264,24 @@ clean:
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
@MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
|
GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
|
||||||
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
|
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
|
||||||
@# strip whitespace after '{{' and before `}}` unless there is only whitespace before it
|
@# strip whitespace after '{{' and before `}}` unless there is only whitespace before it
|
||||||
@$(SED_INPLACE) -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' $(TEMPLATES)
|
@$(SED_INPLACE) -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' $(TEMPLATES)
|
||||||
|
|
||||||
|
.PHONY: fmt-check
|
||||||
|
fmt-check: fmt
|
||||||
|
@diff=$$(git diff $(GO_SOURCES) templates $(WEB_DIRS)); \
|
||||||
|
if [ -n "$$diff" ]; then \
|
||||||
|
echo "Please run 'make fmt' and commit the result:"; \
|
||||||
|
echo "$${diff}"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: misspell-check
|
||||||
|
misspell-check:
|
||||||
|
go run $(MISSPELL_PACKAGE) -error $(GO_DIRS) $(WEB_DIRS)
|
||||||
|
|
||||||
.PHONY: vet
|
.PHONY: vet
|
||||||
vet:
|
vet:
|
||||||
@echo "Running go vet..."
|
@echo "Running go vet..."
|
||||||
|
@ -311,22 +325,6 @@ errcheck:
|
||||||
@echo "Running errcheck..."
|
@echo "Running errcheck..."
|
||||||
$(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES)
|
$(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES)
|
||||||
|
|
||||||
.PHONY: fmt-check
|
|
||||||
fmt-check:
|
|
||||||
@# get all go files and run gitea-fmt (with gofmt) on them
|
|
||||||
@diff=$$(MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -l '{file-list}'); \
|
|
||||||
if [ -n "$$diff" ]; then \
|
|
||||||
echo "Please run 'make fmt' and commit the result:"; \
|
|
||||||
echo "$${diff}"; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
@diff2=$$(git diff templates); \
|
|
||||||
if [ -n "$$diff2" ]; then \
|
|
||||||
echo "Please run 'make fmt' and commit the result:"; \
|
|
||||||
echo "$${diff2}"; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
.PHONY: checks
|
.PHONY: checks
|
||||||
checks: checks-frontend checks-backend
|
checks: checks-frontend checks-backend
|
||||||
|
|
||||||
|
@ -334,14 +332,14 @@ checks: checks-frontend checks-backend
|
||||||
checks-frontend: lockfile-check svg-check
|
checks-frontend: lockfile-check svg-check
|
||||||
|
|
||||||
.PHONY: checks-backend
|
.PHONY: checks-backend
|
||||||
checks-backend: tidy-check swagger-check swagger-validate
|
checks-backend: tidy-check swagger-check fmt-check misspell-check swagger-validate
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint: lint-frontend lint-backend
|
lint: lint-frontend lint-backend
|
||||||
|
|
||||||
.PHONY: lint-frontend
|
.PHONY: lint-frontend
|
||||||
lint-frontend: node_modules
|
lint-frontend: node_modules
|
||||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e/*.test.e2e.js tests/e2e/utils_e2e.js
|
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e
|
||||||
npx stylelint --color --max-warnings=0 web_src/less
|
npx stylelint --color --max-warnings=0 web_src/less
|
||||||
npx spectral lint -q -F hint $(SWAGGER_SPEC)
|
npx spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||||
npx markdownlint docs *.md
|
npx markdownlint docs *.md
|
||||||
|
@ -372,7 +370,7 @@ test-backend:
|
||||||
|
|
||||||
.PHONY: test-frontend
|
.PHONY: test-frontend
|
||||||
test-frontend: node_modules
|
test-frontend: node_modules
|
||||||
@NODE_OPTIONS="--experimental-vm-modules --no-warnings" npx jest --color
|
npx vitest
|
||||||
|
|
||||||
.PHONY: test-check
|
.PHONY: test-check
|
||||||
test-check:
|
test-check:
|
||||||
|
@ -406,6 +404,7 @@ unit-test-coverage:
|
||||||
tidy:
|
tidy:
|
||||||
$(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2))
|
$(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2))
|
||||||
$(GO) mod tidy -compat=$(MIN_GO_VERSION)
|
$(GO) mod tidy -compat=$(MIN_GO_VERSION)
|
||||||
|
@$(MAKE) --no-print-directory $(GO_LICENSE_FILE)
|
||||||
|
|
||||||
vendor: go.mod go.sum
|
vendor: go.mod go.sum
|
||||||
$(GO) mod vendor
|
$(GO) mod vendor
|
||||||
|
@ -413,7 +412,7 @@ vendor: go.mod go.sum
|
||||||
|
|
||||||
.PHONY: tidy-check
|
.PHONY: tidy-check
|
||||||
tidy-check: tidy
|
tidy-check: tidy
|
||||||
@diff=$$(git diff go.mod go.sum); \
|
@diff=$$(git diff go.mod go.sum $(GO_LICENSE_FILE)); \
|
||||||
if [ -n "$$diff" ]; then \
|
if [ -n "$$diff" ]; then \
|
||||||
echo "Please run 'make tidy' and commit the result:"; \
|
echo "Please run 'make tidy' and commit the result:"; \
|
||||||
echo "$${diff}"; \
|
echo "$${diff}"; \
|
||||||
|
@ -709,17 +708,14 @@ install: $(wildcard *.go)
|
||||||
build: frontend backend
|
build: frontend backend
|
||||||
|
|
||||||
.PHONY: frontend
|
.PHONY: frontend
|
||||||
frontend: generate-frontend $(WEBPACK_DEST)
|
frontend: $(WEBPACK_DEST)
|
||||||
|
|
||||||
.PHONY: backend
|
.PHONY: backend
|
||||||
backend: go-check generate-backend $(EXECUTABLE)
|
backend: go-check generate-backend $(EXECUTABLE)
|
||||||
|
|
||||||
# We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend
|
# We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend
|
||||||
.PHONY: generate
|
.PHONY: generate
|
||||||
generate: generate-backend generate-frontend
|
generate: generate-backend
|
||||||
|
|
||||||
.PHONY: generate-frontend
|
|
||||||
generate-frontend: $(GO_LICENSE_FILE)
|
|
||||||
|
|
||||||
.PHONY: generate-backend
|
.PHONY: generate-backend
|
||||||
generate-backend: $(TAGS_PREREQ) generate-go
|
generate-backend: $(TAGS_PREREQ) generate-go
|
||||||
|
|
|
@ -33,6 +33,12 @@
|
||||||
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
||||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||||
</a>
|
</a>
|
||||||
|
<a href="https://gitpod.io/#https://github.com/go-gitea/gitea">
|
||||||
|
<img
|
||||||
|
src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod"
|
||||||
|
alt="Contribute with Gitpod"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
||||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||||
</a>
|
</a>
|
||||||
|
@ -145,6 +151,7 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
|
||||||
<a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a>
|
<a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a>
|
||||||
<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
|
<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
|
||||||
<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
|
<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
|
||||||
|
<a href="https://cynkra.com/" target="_blank"><img src="https://images.opencollective.com/cynkra/logo/square/64/192.png"></a>
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,12 @@
|
||||||
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
||||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||||
</a>
|
</a>
|
||||||
|
<a href="https://gitpod.io/#https://github.com/go-gitea/gitea">
|
||||||
|
<img
|
||||||
|
src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod"
|
||||||
|
alt="Contribute with Gitpod"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
||||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||||
</a>
|
</a>
|
||||||
|
|
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.
|
// Windows has a limitation for command line arguments, the size can not exceed 32KB.
|
||||||
// So we have to feed the files to some tools (like gofmt/misspell) batch by batch
|
// So we have to feed the files to some tools (like gofmt) batch by batch
|
||||||
|
|
||||||
// We also introduce a `gitea-fmt` command, it does better import formatting than gofmt/goimports. `gitea-fmt` calls `gofmt` internally.
|
// We also introduce a `gitea-fmt` command, it does better import formatting than gofmt/goimports. `gitea-fmt` calls `gofmt` internally.
|
||||||
|
|
||||||
|
@ -195,7 +195,6 @@ Options:
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
%[1]s gofmt ...
|
%[1]s gofmt ...
|
||||||
%[1]s misspell ...
|
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
{file-list} the file list
|
{file-list} the file list
|
||||||
|
@ -206,6 +205,17 @@ Example:
|
||||||
`, "file-batch-exec")
|
`, "file-batch-exec")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getGoVersion() string {
|
||||||
|
goModFile, err := os.ReadFile("go.mod")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf(`Faild to read "go.mod": %v`, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
goModVersionRegex := regexp.MustCompile(`go \d+\.\d+`)
|
||||||
|
goModVersionLine := goModVersionRegex.Find(goModFile)
|
||||||
|
return string(goModVersionLine[3:])
|
||||||
|
}
|
||||||
|
|
||||||
func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) {
|
func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) {
|
||||||
fileFilter := mainOptions["file-filter"]
|
fileFilter := mainOptions["file-filter"]
|
||||||
if fileFilter == "" {
|
if fileFilter == "" {
|
||||||
|
@ -228,9 +238,9 @@ func containsString(a []string, s string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func giteaFormatGoImports(files []string, hasChangedFiles, doWriteFile bool) error {
|
func giteaFormatGoImports(files []string, doWriteFile bool) error {
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
if err := codeformat.FormatGoImports(file, hasChangedFiles, doWriteFile); err != nil {
|
if err := codeformat.FormatGoImports(file, doWriteFile); err != nil {
|
||||||
log.Printf("failed to format go imports: %s, err=%v", file, err)
|
log.Printf("failed to format go imports: %s, err=%v", file, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -269,10 +279,8 @@ func main() {
|
||||||
if containsString(subArgs, "-d") {
|
if containsString(subArgs, "-d") {
|
||||||
log.Print("the -d option is not supported by gitea-fmt")
|
log.Print("the -d option is not supported by gitea-fmt")
|
||||||
}
|
}
|
||||||
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-l"), containsString(subArgs, "-w")))
|
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-w")))
|
||||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", "1.17"}, substArgs...)))
|
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", getGoVersion()}, substArgs...)))
|
||||||
case "misspell":
|
|
||||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("MISSPELL_PACKAGE")}, substArgs...)))
|
|
||||||
default:
|
default:
|
||||||
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
|
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ package codeformat
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -159,7 +158,7 @@ func formatGoImports(contentBytes []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormatGoImports format the imports by our rules (see unit tests)
|
// FormatGoImports format the imports by our rules (see unit tests)
|
||||||
func FormatGoImports(file string, doChangedFiles, doWriteFile bool) error {
|
func FormatGoImports(file string, doWriteFile bool) error {
|
||||||
f, err := os.Open(file)
|
f, err := os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -183,10 +182,6 @@ func FormatGoImports(file string, doChangedFiles, doWriteFile bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if doChangedFiles {
|
|
||||||
fmt.Println(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
if doWriteFile {
|
if doWriteFile {
|
||||||
f, err = os.OpenFile(file, os.O_TRUNC|os.O_WRONLY, 0o644)
|
f, err = os.OpenFile(file, os.O_TRUNC|os.O_WRONLY, 0o644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -588,7 +588,7 @@ func runCreateUser(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := user_model.CreateUser(u, overwriteDefault); err != nil {
|
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") {
|
if c.Bool("access-token") {
|
||||||
|
@ -735,7 +735,7 @@ func runRepoSyncReleases(_ *cli.Context) error {
|
||||||
Private: true,
|
Private: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("SearchRepositoryByName: %v", err)
|
return fmt.Errorf("SearchRepositoryByName: %w", err)
|
||||||
}
|
}
|
||||||
if len(repos) == 0 {
|
if len(repos) == 0 {
|
||||||
break
|
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 this is the intended configuration file complete the [database] section.`, setting.CustomConf)
|
||||||
}
|
}
|
||||||
if err := db.InitEngine(ctx); err != nil {
|
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
|
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",
|
Name: "skip-package-data",
|
||||||
Usage: "Skip package data",
|
Usage: "Skip package data",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "skip-index",
|
||||||
|
Usage: "Skip bleve index data",
|
||||||
|
},
|
||||||
cli.GenericFlag{
|
cli.GenericFlag{
|
||||||
Name: "type",
|
Name: "type",
|
||||||
Value: outputTypeEnum,
|
Value: outputTypeEnum,
|
||||||
|
@ -327,6 +331,11 @@ func runDump(ctx *cli.Context) error {
|
||||||
excludes = append(excludes, opts.ProviderConfig)
|
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.RepoRootPath)
|
||||||
excludes = append(excludes, setting.LFS.Path)
|
excludes = append(excludes, setting.LFS.Path)
|
||||||
excludes = append(excludes, setting.Attachment.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
|
// make sure the directory doesn't exist or is empty, prevent from deleting user files
|
||||||
repoDir := ctx.String("repo_dir")
|
repoDir := ctx.String("repo_dir")
|
||||||
if exists, err := util.IsExist(repoDir); err != nil {
|
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 {
|
} else if exists {
|
||||||
if isDir, _ := util.IsDir(repoDir); !isDir {
|
if isDir, _ := util.IsDir(repoDir); !isDir {
|
||||||
return fmt.Errorf("repo_dir %q already exists but it's not a directory", repoDir)
|
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)
|
data, err := assets[0].Section.Asset(assets[0].Name)
|
||||||
if err != nil {
|
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 {
|
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
|
return nil
|
||||||
|
@ -251,11 +251,11 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
||||||
|
|
||||||
data, err := a.Section.Asset(a.Name)
|
data, err := a.Section.Asset(a.Name)
|
||||||
if err != nil {
|
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 {
|
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
|
perms := os.ModePerm & 0o666
|
||||||
|
@ -263,7 +263,7 @@ func extractAsset(d string, a asset, overwrite, rename bool) error {
|
||||||
fi, err := os.Lstat(dest)
|
fi, err := os.Lstat(dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
return fmt.Errorf("%s: %v", dest, err)
|
return fmt.Errorf("%s: %w", dest, err)
|
||||||
}
|
}
|
||||||
} else if !overwrite && !rename {
|
} else if !overwrite && !rename {
|
||||||
fmt.Printf("%s already exists; skipped.\n", dest)
|
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)
|
return fmt.Errorf("%s already exists, but it's not a regular file", dest)
|
||||||
} else if rename {
|
} else if rename {
|
||||||
if err := util.Rename(dest, dest+".bak"); err != nil {
|
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)
|
// Attempt to respect file permissions mask (even if user:group will be set anew)
|
||||||
perms = fi.Mode()
|
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)
|
file, err := os.OpenFile(dest, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, perms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: %v", dest, err)
|
return fmt.Errorf("%s: %w", dest, err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
if _, err = file.Write(data); err != nil {
|
if _, err = file.Write(data); err != nil {
|
||||||
return fmt.Errorf("%s: %v", dest, err)
|
return fmt.Errorf("%s: %w", dest, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(dest)
|
fmt.Println(dest)
|
||||||
|
@ -325,7 +325,7 @@ func getPatterns(args []string) ([]glob.Glob, error) {
|
||||||
pat := make([]glob.Glob, len(args))
|
pat := make([]glob.Glob, len(args))
|
||||||
for i := range args {
|
for i := range args {
|
||||||
if g, err := glob.Compile(args[i], '/'); err != nil {
|
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 {
|
} else {
|
||||||
pat[i] = g
|
pat[i] = g
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,7 @@ func runHookPostReceive(c *cli.Context) error {
|
||||||
|
|
||||||
// First of all run update-server-info no matter what
|
// First of all run update-server-info no matter what
|
||||||
if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil {
|
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
|
// Now if we're an internal don't do anything else
|
||||||
|
|
|
@ -203,7 +203,7 @@ func setPort(port string) error {
|
||||||
defaultLocalURL += ":" + setting.HTTPPort + "/"
|
defaultLocalURL += ":" + setting.HTTPPort + "/"
|
||||||
|
|
||||||
// Save LOCAL_ROOT_URL if port changed
|
// Save LOCAL_ROOT_URL if port changed
|
||||||
setting.CreateOrAppendToCustomConf(func(cfg *ini.File) {
|
setting.CreateOrAppendToCustomConf("server.LOCAL_ROOT_URL", func(cfg *ini.File) {
|
||||||
cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
|
cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,43 @@
|
||||||
|
|
||||||
DIR=/var/lib/gitea
|
DIR=/var/lib/gitea
|
||||||
USER=git
|
USER=git
|
||||||
|
HOME=/home/${USER}
|
||||||
|
GITEA_WORK_DIR=${DIR}
|
||||||
|
EXECUTABLE=/usr/local/bin/gitea
|
||||||
|
|
||||||
|
export USER
|
||||||
|
export HOME
|
||||||
|
export GITEA_WORK_DIR
|
||||||
|
|
||||||
|
name=$RC_SVCNAME
|
||||||
|
cfgfile="/etc/$RC_SVCNAME/app.ini"
|
||||||
|
command="${EXECUTABLE}"
|
||||||
|
command_user="${USER}"
|
||||||
|
command_args="web -c /etc/$RC_SVCNAME/app.ini"
|
||||||
|
command_background="yes"
|
||||||
|
pidfile="/run/$RC_SVCNAME/$RC_SVCNAME.pid"
|
||||||
start_stop_daemon_args="--user ${USER} --chdir ${DIR}"
|
start_stop_daemon_args="--user ${USER} --chdir ${DIR}"
|
||||||
command="/usr/local/bin/gitea"
|
|
||||||
command_args="web -c /etc/gitea/app.ini"
|
|
||||||
command_background=yes
|
|
||||||
pidfile=/run/gitea.pid
|
|
||||||
|
|
||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
need net
|
need net
|
||||||
|
###
|
||||||
|
# Don't forget to add the database service requirements
|
||||||
|
###
|
||||||
|
#after postgresql
|
||||||
|
#after mysql
|
||||||
|
#after mariadb
|
||||||
|
#after memcached
|
||||||
|
#after redis
|
||||||
|
}
|
||||||
|
|
||||||
|
start_pre()
|
||||||
|
{
|
||||||
|
checkpath --directory --owner $command_user:$command_user --mode 0750 \
|
||||||
|
/run/$RC_SVCNAME /var/log/$RC_SVCNAME
|
||||||
|
##
|
||||||
|
# If you want to bind Gitea to a port below 1024, uncomment
|
||||||
|
# the value below
|
||||||
|
##
|
||||||
|
#setcap cap_net_bind_service=+ep "${EXECUTABLE}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/user"
|
"os/user"
|
||||||
|
@ -34,6 +33,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/routers"
|
"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"
|
||||||
"github.com/go-git/go-git/v5/config"
|
"github.com/go-git/go-git/v5/config"
|
||||||
|
@ -62,11 +62,7 @@ func runPR() {
|
||||||
}
|
}
|
||||||
setting.AppWorkPath = curDir
|
setting.AppWorkPath = curDir
|
||||||
setting.StaticRootPath = curDir
|
setting.StaticRootPath = curDir
|
||||||
setting.GravatarSourceURL, err = url.Parse("https://secure.gravatar.com/avatar/")
|
setting.GravatarSource = "https://secure.gravatar.com/avatar/"
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("url.Parse: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
setting.AppURL = "http://localhost:8080/"
|
setting.AppURL = "http://localhost:8080/"
|
||||||
setting.HTTPPort = "8080"
|
setting.HTTPPort = "8080"
|
||||||
setting.SSH.Domain = "localhost"
|
setting.SSH.Domain = "localhost"
|
||||||
|
@ -117,7 +113,7 @@ func runPR() {
|
||||||
log.Printf("[PR] Setting up router\n")
|
log.Printf("[PR] Setting up router\n")
|
||||||
// routers.GlobalInit()
|
// routers.GlobalInit()
|
||||||
external.RegisterRenderers()
|
external.RegisterRenderers()
|
||||||
markup.Init()
|
markup.Init(markup_service.ProcessorHelper())
|
||||||
c := routers.NormalRoutes(graceful.GetManager().HammerContext())
|
c := routers.NormalRoutes(graceful.GetManager().HammerContext())
|
||||||
|
|
||||||
log.Printf("[PR] Ready for testing !\n")
|
log.Printf("[PR] Ready for testing !\n")
|
||||||
|
|
|
@ -49,12 +49,8 @@ After=network.target
|
||||||
###
|
###
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
# Modify these two values and uncomment them if you have
|
# Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that
|
||||||
# repos with lots of files and get an HTTP error 500 because
|
# LimitNOFILE=524288:524288
|
||||||
# of that
|
|
||||||
###
|
|
||||||
#LimitMEMLOCK=infinity
|
|
||||||
#LimitNOFILE=65535
|
|
||||||
RestartSec=2s
|
RestartSec=2s
|
||||||
Type=simple
|
Type=simple
|
||||||
User=git
|
User=git
|
||||||
|
|
|
@ -379,14 +379,19 @@ LOG_SQL = false ; if unset defaults to true
|
||||||
;; Whether the installer is disabled (set to true to disable the installer)
|
;; Whether the installer is disabled (set to true to disable the installer)
|
||||||
INSTALL_LOCK = false
|
INSTALL_LOCK = false
|
||||||
;;
|
;;
|
||||||
;; Global secret key that will be used - if blank will be regenerated.
|
;; Global secret key that will be used
|
||||||
|
;; This key is VERY IMPORTANT. If you lose it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
|
||||||
SECRET_KEY =
|
SECRET_KEY =
|
||||||
;;
|
;;
|
||||||
|
;; Alternative location to specify secret key, instead of this file; you cannot specify both this and SECRET_KEY, and must pick one
|
||||||
|
;; This key is VERY IMPORTANT. If you lose it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
|
||||||
|
;SECRET_KEY_URI = file:/etc/gitea/secret_key
|
||||||
|
;;
|
||||||
;; Secret used to validate communication within Gitea binary.
|
;; Secret used to validate communication within Gitea binary.
|
||||||
INTERNAL_TOKEN=
|
INTERNAL_TOKEN=
|
||||||
;;
|
;;
|
||||||
;; Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: file:/etc/gitea/internal_token)
|
;; Alternative location to specify internal token, instead of this file; you cannot specify both this and INTERNAL_TOKEN, and must pick one
|
||||||
;INTERNAL_TOKEN_URI = ;e.g. /etc/gitea/internal_token
|
;INTERNAL_TOKEN_URI = file:/etc/gitea/internal_token
|
||||||
;;
|
;;
|
||||||
;; How long to remember that a user is logged in before requiring relogin (in days)
|
;; How long to remember that a user is logged in before requiring relogin (in days)
|
||||||
;LOGIN_REMEMBER_DAYS = 7
|
;LOGIN_REMEMBER_DAYS = 7
|
||||||
|
@ -882,7 +887,7 @@ ROUTER = console
|
||||||
;USE_COMPAT_SSH_URI = false
|
;USE_COMPAT_SSH_URI = false
|
||||||
;;
|
;;
|
||||||
;; Close issues as long as a commit on any branch marks it as fixed
|
;; Close issues as long as a commit on any branch marks it as fixed
|
||||||
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki
|
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects
|
||||||
;DISABLED_REPO_UNITS =
|
;DISABLED_REPO_UNITS =
|
||||||
;;
|
;;
|
||||||
;; Comma separated list of default repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects.
|
;; Comma separated list of default repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects.
|
||||||
|
@ -2191,7 +2196,8 @@ ROUTER = console
|
||||||
;SHOW_FOOTER_VERSION = true
|
;SHOW_FOOTER_VERSION = true
|
||||||
;; Show template execution time in the footer
|
;; Show template execution time in the footer
|
||||||
;SHOW_FOOTER_TEMPLATE_LOAD_TIME = true
|
;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
|
description: Git with a cup of tea
|
||||||
author: The Gitea Authors
|
author: The Gitea Authors
|
||||||
website: https://docs.gitea.io
|
website: https://docs.gitea.io
|
||||||
version: 1.17.1
|
version: 1.17.3
|
||||||
minGoVersion: 1.18
|
minGoVersion: 1.18
|
||||||
goVersion: 1.19
|
goVersion: 1.19
|
||||||
minNodeVersion: 14
|
minNodeVersion: 14
|
||||||
|
|
|
@ -494,7 +494,8 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
|
||||||
## Security (`security`)
|
## Security (`security`)
|
||||||
|
|
||||||
- `INSTALL_LOCK`: **false**: Controls access to the installation page. When set to "true", the installation page is not accessible.
|
- `INSTALL_LOCK`: **false**: Controls access to the installation page. When set to "true", the installation page is not accessible.
|
||||||
- `SECRET_KEY`: **\<random at every install\>**: Global secret key. This should be changed.
|
- `SECRET_KEY`: **\<random at every install\>**: Global secret key. This key is VERY IMPORTANT, if you lost it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
|
||||||
|
- `SECRET_KEY_URI`: **<empty>**: Instead of defining SECRET_KEY, this option can be used to use the key stored in a file (example value: `file:/etc/gitea/secret_key`). It shouldn't be lost like SECRET_KEY.
|
||||||
- `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days.
|
- `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days.
|
||||||
- `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username.
|
- `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username.
|
||||||
- `COOKIE_REMEMBER_NAME`: **gitea\_incredible**: Name of cookie used to store authentication
|
- `COOKIE_REMEMBER_NAME`: **gitea\_incredible**: Name of cookie used to store authentication
|
||||||
|
@ -520,7 +521,7 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
|
||||||
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to Gitea repositories you should set the environment appropriately.
|
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to Gitea repositories you should set the environment appropriately.
|
||||||
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
|
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
|
||||||
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
|
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
|
||||||
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining INTERNAL_TOKEN in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
||||||
- `PASSWORD_HASH_ALGO`: **pbkdf2**: The hash algorithm to use \[argon2, pbkdf2, scrypt, bcrypt\], argon2 will spend more memory than others.
|
- `PASSWORD_HASH_ALGO`: **pbkdf2**: The hash algorithm to use \[argon2, pbkdf2, scrypt, bcrypt\], argon2 will spend more memory than others.
|
||||||
- `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie.
|
- `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie.
|
||||||
- `MIN_PASSWORD_LENGTH`: **6**: Minimum password length for new users.
|
- `MIN_PASSWORD_LENGTH`: **6**: Minimum password length for new users.
|
||||||
|
@ -536,9 +537,9 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
|
||||||
## Camo (`camo`)
|
## Camo (`camo`)
|
||||||
|
|
||||||
- `ENABLED`: **false**: Enable media proxy, we support images only at the moment.
|
- `ENABLED`: **false**: Enable media proxy, we support images only at the moment.
|
||||||
- `SERVER_URL`: **<empty>**: url of camo server, it **is required** if camo is enabled.
|
- `SERVER_URL`: **<empty>**: URL of camo server, it **is required** if camo is enabled.
|
||||||
- `HMAC_KEY`: **<empty>**: Provide the HMAC key for encoding urls, it **is required** if camo is enabled.
|
- `HMAC_KEY`: **<empty>**: Provide the HMAC key for encoding URLs, it **is required** if camo is enabled.
|
||||||
- `ALLWAYS`: **false**: Set to true to use camo for https too lese only non https urls are proxyed
|
- `ALLWAYS`: **false**: Set to true to use camo for both HTTP and HTTPS content, otherwise only non-HTTPS URLs are proxied
|
||||||
|
|
||||||
## OpenID (`openid`)
|
## OpenID (`openid`)
|
||||||
|
|
||||||
|
@ -809,9 +810,9 @@ Default templates for project boards:
|
||||||
- `STACKTRACE_LEVEL`: **log.STACKTRACE_LEVEL**: Sets the log level at which to log stack traces.
|
- `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.
|
- `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.
|
- `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.
|
- `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`)
|
### 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_BRANDING`: **false**: Show Gitea branding in the footer.
|
||||||
- `SHOW_FOOTER_VERSION`: **true**: Show Gitea and Go version information 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.
|
- `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,
|
So services must be allowed to create a database transaction. Here is some example,
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// servcies/repository/repo.go
|
// services/repository/repository.go
|
||||||
func CreateXXXX() error {\
|
func CreateXXXX() error {
|
||||||
ctx, committer, err := db.TxContext()
|
return db.WithTx(func(ctx context.Context) error {
|
||||||
if err != nil {
|
e := db.GetEngine(ctx)
|
||||||
return err
|
// do something, if err is returned, it will rollback automatically
|
||||||
}
|
if err := issues.UpdateIssue(ctx, repoID); err != nil {
|
||||||
defer committer.Close()
|
// ...
|
||||||
|
return err
|
||||||
// do something, if return err, it will rollback automatically when `committer.Close()` is invoked.
|
}
|
||||||
if err := issues.UpdateIssue(ctx, repoID); err != nil {
|
// ...
|
||||||
// ...
|
return nil
|
||||||
}
|
})
|
||||||
|
|
||||||
// ......
|
|
||||||
|
|
||||||
return committer.Commit()
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -94,14 +90,14 @@ If the function will be used in the transaction, just let `context.Context` as t
|
||||||
func UpdateIssue(ctx context.Context, repoID int64) error {
|
func UpdateIssue(ctx context.Context, repoID int64) error {
|
||||||
e := db.GetEngine(ctx)
|
e := db.GetEngine(ctx)
|
||||||
|
|
||||||
// ......
|
// ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Package Name
|
### Package Name
|
||||||
|
|
||||||
For the top level package, use a plural as package name, i.e. `services`, `models`, for sub packages, use singular,
|
For the top level package, use a plural as package name, i.e. `services`, `models`, for sub packages, use singular,
|
||||||
i.e. `servcies/user`, `models/repository`.
|
i.e. `services/user`, `models/repository`.
|
||||||
|
|
||||||
### Import Alias
|
### Import Alias
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ menu:
|
||||||
|
|
||||||
## Background
|
## Background
|
||||||
|
|
||||||
Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue2](https://vuejs.org/v2/guide/) for its frontend.
|
Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue3](https://vuejs.org/) for its frontend.
|
||||||
|
|
||||||
The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template).
|
The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template).
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h
|
||||||
4. jQuery events across different features could use their own namespaces if there are potential conflicts.
|
4. jQuery events across different features could use their own namespaces if there are potential conflicts.
|
||||||
5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names with 2-3 feature related keywords to overwrite framework styles.
|
5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names with 2-3 feature related keywords to overwrite framework styles.
|
||||||
6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}`
|
6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}`
|
||||||
7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future).
|
7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue3.
|
||||||
|
|
||||||
### Framework Usage
|
### Framework Usage
|
||||||
|
|
||||||
|
@ -97,6 +97,6 @@ However, there are still some special cases, so the current guideline is:
|
||||||
|
|
||||||
A lot of legacy code already existed before this document's written. It's recommended to refactor legacy code to follow the guidelines.
|
A lot of legacy code already existed before this document's written. It's recommended to refactor legacy code to follow the guidelines.
|
||||||
|
|
||||||
### Vue2/Vue3 and JSX
|
### Vue3 and JSX
|
||||||
|
|
||||||
Gitea is using Vue2 now, we plan to upgrade to Vue3. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.
|
Gitea is using Vue3 now. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.
|
|
@ -19,6 +19,12 @@ menu:
|
||||||
|
|
||||||
{{< toc >}}
|
{{< toc >}}
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
To get a quick working development environment you could use Gitpod.
|
||||||
|
|
||||||
|
[](https://gitpod.io/#https://github.com/go-gitea/gitea)
|
||||||
|
|
||||||
## Installing go
|
## Installing go
|
||||||
|
|
||||||
You should [install go](https://golang.org/doc/install) and set up your go
|
You should [install go](https://golang.org/doc/install) and set up your go
|
||||||
|
@ -171,7 +177,7 @@ server as mentioned above.
|
||||||
|
|
||||||
### Working on JS and CSS
|
### Working on JS and CSS
|
||||||
|
|
||||||
Frontend development should follow [Guidelines for Frontend Development](./guidelines-frontend.md)
|
Frontend development should follow [Guidelines for Frontend Development]({{< relref "doc/developers/guidelines-frontend.en-us.md" >}})
|
||||||
|
|
||||||
To build with frontend resources, either use the `watch-frontend` target mentioned above or just build once:
|
To build with frontend resources, either use the `watch-frontend` target mentioned above or just build once:
|
||||||
|
|
||||||
|
|
|
@ -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.
|
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
|
## Example
|
||||||
|
|
||||||
**Note:** This example does not use PKCE.
|
**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.
|
To help decide if Gitea is suited for your needs, here is how it compares to other Git self hosted options.
|
||||||
|
|
||||||
Be warned that we don't regularly check for feature changes in other products, so this list may be outdated. If you find anything that needs to be updated in the table below, please report it in an [issue on GitHub](https://github.com/go-gitea/gitea/issues).
|
Be warned that we don't regularly check for feature changes in other products, so this list may be outdated. If you find anything that needs to be updated in the table below, please [open an issue](https://github.com/go-gitea/gitea/issues/new/choose).
|
||||||
|
|
||||||
_Symbols used in table:_
|
_Symbols used in table:_
|
||||||
|
|
||||||
|
@ -33,103 +33,111 @@ _Symbols used in table:_
|
||||||
|
|
||||||
## General Features
|
## General Features
|
||||||
|
|
||||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
| ----------------------------------- | ---------------------------------------------------| ---- | --------- | --------- | --------- | -------------- | ------------ |
|
| ------------------------------------------------ | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||||
| Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
| Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
||||||
| Low resource usage (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
| Low RAM/ CPU usage | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||||
| Multiple database support | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
| Multiple database support | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
||||||
| Multiple OS support | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ |
|
| Multiple OS support | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ |
|
||||||
| Easy upgrade process | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
| Easy upgrades | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||||
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Telemetry | **✘** | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||||
| Orgmode support | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? |
|
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
||||||
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||||
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
| Extensive API | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Static Git-powered pages | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Built-in Package/Container Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
| Sync commits to an external repo (push mirror) | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||||
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Sync commits from an external repo (pull mirror) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ? |
|
||||||
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Light and Dark Theme | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ? |
|
||||||
| Built-in Package/Container Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Custom Theme Support | ✓ | ✓ | ✘ | ✘ | ✘ | ✓ | ✘ |
|
||||||
| External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||||
| Built-in CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| 'GitHub / GitLab pages' | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Subgroups: groups within groups | [✘](https://github.com/go-gitea/gitea/issues/1872) | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
| Repo-specific wiki (as a repo itself) | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
|
||||||
| Mermaid diagrams in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Math syntax in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
| RSS Feeds | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ✘ |
|
||||||
|
| Built-in CI/CD | [✘](https://github.com/go-gitea/gitea/issues/13539) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
|
| Subgroups: groups within groups | [✘](https://github.com/go-gitea/gitea/issues/1872) | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||||
|
| Interaction with other instances | [/](https://github.com/go-gitea/gitea/issues/18240) | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||||
|
| Mermaid diagrams in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
|
| Math syntax in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
|
|
||||||
## Code management
|
## Code management
|
||||||
|
|
||||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
| -------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
| ------------------------------------------- | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||||
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
| Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
||||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Group Milestones | [✘](https://github.com/go-gitea/gitea/issues/14622) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Granular user roles (Code, Issues, Wiki, …) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Verified Committer | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
| Verified Committer | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||||
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| SSH Signed Commits | ✓ | ✘ | ✘ | ✘ | ✘ | ? | ? |
|
| SSH Signed Commits | ✓ | ✘ | ✓ | ✘ | ✘ | ? | ? |
|
||||||
| Reject unsigned commits | [✓](https://github.com/go-gitea/gitea/pull/9708) | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Reject unsigned commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Migrating repos from other services | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Web code editor | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Commit graph | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Web code editor | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Template Repositories | [✓](https://github.com/go-gitea/gitea/pull/8768) | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
| Commit graph | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
| Template Repositories | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
||||||
|
| Git Blame | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
|
| Visual comparison of image changes | ✓ | ✘ | ✓ | ? | ? | ? | ? |
|
||||||
|
|
||||||
## Issue Tracker
|
## Issue Tracker
|
||||||
|
|
||||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
| ------------------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | ----------------------------------------------------------------------- | --------- | -------------- | ------------ |
|
| ----------------------------- | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||||
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
|
||||||
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Multiple assignees for issues | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
|
| Multiple assignees for issues | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
|
||||||
| Related issues | ✘ | ✘ | ⁄ | [✓](https://docs.gitlab.com/ce/user/project/issues/related_issues.html) | ✓ | ✘ | ✘ |
|
| Related issues | ✘ | ✘ | ⁄ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Confidential issues | [✘](https://github.com/go-gitea/gitea/issues/3217) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Confidential issues | [✘](https://github.com/go-gitea/gitea/issues/3217) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Lock Discussion | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Lock Discussion | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Issue Boards (Kanban) | [✓](https://github.com/go-gitea/gitea/pull/8346) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Issue Boards (Kanban) | [/](https://github.com/go-gitea/gitea/issues/14710) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Create new branches from issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Create branch from issue | [✘](https://github.com/go-gitea/gitea/issues/20226) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
| Convert comment to new issue | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Global issue search | [✘](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
| Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
| Global issue search | [/](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| Create issue via email | [✘](https://github.com/go-gitea/gitea/issues/6226) | [✘](https://github.com/gogs/gogs/issues/2602) | ✘ | ✘ | ✓ | ✓ | ✘ |
|
| Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||||
| Service Desk | [✘](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | [✓](https://gitlab.com/groups/gitlab-org/-/epics/3103) | ✓ | ✘ | ✘ |
|
| Create issue via email | [✘](https://github.com/go-gitea/gitea/issues/6226) | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ |
|
||||||
|
| Service Desk | [✘](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
|
|
||||||
## Pull/Merge requests
|
## Pull/Merge requests
|
||||||
|
|
||||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
| ----------------------------------------------- | -------------------------------------------------- | ---- | --------- | --------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------ | ------------ |
|
| ----------------------------------------------- | -------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||||
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Squash merging | ✓ | ✘ | ✓ | [✓](https://docs.gitlab.com/ce/user/project/merge_requests/squash_and_merge.html) | ✓ | ✓ | ✓ |
|
| Squash merging | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Rebase merging | ✓ | ✓ | ✓ | ✘ | ⁄ | ✘ | ✓ |
|
| Rebase merging | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Pull/Merge request approval | ✓ | ✘ | ⁄ | ✓ | ✓ | ✓ | ✓ |
|
| Pull/Merge request approval | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Merge conflict resolution | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
| Merge conflict resolution | [✘](https://github.com/go-gitea/gitea/issues/9014) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | ⁄ | ✓ | ✓ | ✓ |
|
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Revert specific commits or a merge request | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
| Revert specific commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Cherry-picking changes | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
| Cherry-picking changes | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | [/](https://jira.atlassian.com/plugins/servlet/mobile#issue/BCLOUD-8323) | ✘ |
|
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | / | ✘ |
|
||||||
|
|
||||||
## 3rd-party integrations
|
## 3rd-party integrations
|
||||||
|
|
||||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
| ---------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
| ---------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||||
| Webhook support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Webhooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Custom Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
| Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||||
| LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | [✘](https://github.com/gogs/gogs/issues/1221) | ✓ | ✓ | ✓ | ✓ | ✘ |
|
| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| OpenId Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
|
| OpenID Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
|
||||||
| OAuth 2.0 integration (external authorization) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ |
|
| OAuth 2.0 integration (external authorization) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ |
|
||||||
| Act as OAuth 2.0 provider | [✓](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
| Act as OAuth 2.0 provider | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
| Mattermost/Slack integration | ✓ | ✓ | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
| Integration with the most common services | ✓ | / | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
||||||
| Discord integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
| Incorporate external CI/CD | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Microsoft Teams integration | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
|
||||||
| External CI/CD status display | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
||||||
|
|
|
@ -97,12 +97,12 @@ chown root:git /etc/gitea
|
||||||
chmod 770 /etc/gitea
|
chmod 770 /etc/gitea
|
||||||
```
|
```
|
||||||
|
|
||||||
**NOTE:** `/etc/gitea` is temporarily set with write permissions for user `git` so that the web installer can write the configuration file. After the installation is finished, it is recommended to set permissions to read-only using:
|
> **NOTE:** `/etc/gitea` is temporarily set with write permissions for user `git` so that the web installer can write the configuration file. After the installation is finished, it is recommended to set permissions to read-only using:
|
||||||
|
>
|
||||||
```sh
|
> ```sh
|
||||||
chmod 750 /etc/gitea
|
> chmod 750 /etc/gitea
|
||||||
chmod 640 /etc/gitea/app.ini
|
> chmod 640 /etc/gitea/app.ini
|
||||||
```
|
> ```
|
||||||
|
|
||||||
If you don't want the web installer to be able to write to the config file, it is possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`) however you will need to edit your config file manually to:
|
If you don't want the web installer to be able to write to the config file, it is possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`) however you will need to edit your config file manually to:
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ choco install gitea
|
||||||
macOS 平台下当前我们仅支持通过 `brew` 来安装。如果你没有安装 [Homebrew](http://brew.sh/),你也可以查看 [从二进制安装]({{< relref "from-binary.zh-cn.md" >}})。在你安装了 `brew` 之后, 你可以执行以下命令:
|
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
|
brew install gitea
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ menu:
|
||||||
|
|
||||||
# NuGet Packages Repository
|
# NuGet Packages Repository
|
||||||
|
|
||||||
Publish [NuGet](https://www.nuget.org/) packages for your user or organization. The package registry supports [NuGet Symbol Packages](https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg) too.
|
Publish [NuGet](https://www.nuget.org/) packages for your user or organization. The package registry supports the V2 and V3 API protocol and you can work with [NuGet Symbol Packages](https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg) too.
|
||||||
|
|
||||||
**Table of Contents**
|
**Table of Contents**
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
---
|
---
|
||||||
date: "2021-09-02T16:00:00+08:00"
|
date: "2021-09-02T16:00:00+08:00"
|
||||||
title: "Upgrade from an old Gitea"
|
title: "Upgrade from an old Gitea"
|
||||||
|
aliases:
|
||||||
|
- /en-us/upgrade/
|
||||||
slug: "upgrade-from-gitea"
|
slug: "upgrade-from-gitea"
|
||||||
weight: 10
|
weight: 10
|
||||||
toc: false
|
toc: false
|
||||||
|
|
|
@ -13,6 +13,12 @@ menu:
|
||||||
identifier: "reverse-proxies"
|
identifier: "reverse-proxies"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# 反向代理
|
||||||
|
|
||||||
|
**目录**
|
||||||
|
|
||||||
|
{{< toc >}}
|
||||||
|
|
||||||
## 使用 Nginx 作为反向代理服务
|
## 使用 Nginx 作为反向代理服务
|
||||||
|
|
||||||
如果您想使用 Nginx 作为 Gitea 的反向代理服务,您可以参照以下 `nginx.conf` 配置中 `server` 的 `http` 部分:
|
如果您想使用 Nginx 作为 Gitea 的反向代理服务,您可以参照以下 `nginx.conf` 配置中 `server` 的 `http` 部分:
|
||||||
|
@ -24,6 +30,10 @@ server {
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://localhost:3000;
|
proxy_pass http://localhost:3000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -41,6 +51,10 @@ server {
|
||||||
location /git/ {
|
location /git/ {
|
||||||
# 注意: 反向代理后端 URL 的最后需要有一个路径符号
|
# 注意: 反向代理后端 URL 的最后需要有一个路径符号
|
||||||
proxy_pass http://localhost:3000/;
|
proxy_pass http://localhost:3000/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -287,7 +287,7 @@ You can try it out using [the online demo](https://try.gitea.io/).
|
||||||
- UI frameworks:
|
- UI frameworks:
|
||||||
- [jQuery](https://jquery.com)
|
- [jQuery](https://jquery.com)
|
||||||
- [Fomantic UI](https://fomantic-ui.com)
|
- [Fomantic UI](https://fomantic-ui.com)
|
||||||
- [Vue2](https://vuejs.org)
|
- [Vue3](https://vuejs.org)
|
||||||
- and various components (see package.json)
|
- and various components (see package.json)
|
||||||
- Editors:
|
- Editors:
|
||||||
- [CodeMirror](https://codemirror.net)
|
- [CodeMirror](https://codemirror.net)
|
||||||
|
|
|
@ -258,7 +258,7 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide
|
||||||
- Interface graphique :
|
- Interface graphique :
|
||||||
- [jQuery](https://jquery.com)
|
- [jQuery](https://jquery.com)
|
||||||
- [Fomantic UI](https://fomantic-ui.com)
|
- [Fomantic UI](https://fomantic-ui.com)
|
||||||
- [Vue2](https://vuejs.org)
|
- [Vue3](https://vuejs.org)
|
||||||
- [CodeMirror](https://codemirror.net)
|
- [CodeMirror](https://codemirror.net)
|
||||||
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
||||||
- [Monaco Editor](https://microsoft.github.io/monaco-editor)
|
- [Monaco Editor](https://microsoft.github.io/monaco-editor)
|
||||||
|
|
|
@ -52,7 +52,7 @@ Gitea的首要目标是创建一个极易安装,运行非常快速,安装和
|
||||||
- UI 框架:
|
- UI 框架:
|
||||||
- [jQuery](https://jquery.com)
|
- [jQuery](https://jquery.com)
|
||||||
- [Fomantic UI](https://fomantic-ui.com)
|
- [Fomantic UI](https://fomantic-ui.com)
|
||||||
- [Vue2](https://vuejs.org)
|
- [Vue3](https://vuejs.org)
|
||||||
- 更多组件参见 package.json
|
- 更多组件参见 package.json
|
||||||
- 编辑器:
|
- 编辑器:
|
||||||
- [CodeMirror](https://codemirror.net)
|
- [CodeMirror](https://codemirror.net)
|
||||||
|
|
|
@ -271,7 +271,7 @@ Gitea 是從 [Gogs](http://gogs.io) Fork 出來的,請閱讀部落格文章 [G
|
||||||
- UI 元件:
|
- UI 元件:
|
||||||
- [jQuery](https://jquery.com)
|
- [jQuery](https://jquery.com)
|
||||||
- [Fomantic UI](https://fomantic-ui.com)
|
- [Fomantic UI](https://fomantic-ui.com)
|
||||||
- [Vue2](https://vuejs.org)
|
- [Vue3](https://vuejs.org)
|
||||||
- [CodeMirror](https://codemirror.net)
|
- [CodeMirror](https://codemirror.net)
|
||||||
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
||||||
- [Monaco Editor](https://microsoft.github.io/monaco-editor)
|
- [Monaco Editor](https://microsoft.github.io/monaco-editor)
|
||||||
|
|
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/ci-cd/ /en-us/integrations/ 302!
|
||||||
/en-us/third-party-tools/ /en-us/integrations/ 302!
|
/en-us/third-party-tools/ /en-us/integrations/ 302!
|
||||||
/en-us/make/ /en-us/hacking-on-gitea/ 302!
|
/en-us/make/ /en-us/hacking-on-gitea/ 302!
|
||||||
|
/en-us/upgrade/ /en-us/upgrade-from-gitea/ 302!
|
||||||
|
/fr-fr/upgrade/ /fr-fr/upgrade-from-gitea/ 302!
|
||||||
|
/zh-cn/upgrade/ /zh-cn/upgrade-from-gitea/ 302!
|
||||||
|
/zh-tw/upgrade/ /zh-tw/upgrade-from-gitea/ 302!
|
||||||
|
|
23
docs/static/open-in-gitpod.svg
vendored
Normal file
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/gitea-vet v0.2.2-0.20220122151748-48ebc902541b
|
||||||
code.gitea.io/sdk/gitea v0.15.1
|
code.gitea.io/sdk/gitea v0.15.1
|
||||||
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
|
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/cache v0.2.0
|
||||||
gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
|
gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
|
||||||
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8
|
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8
|
||||||
|
@ -16,9 +16,9 @@ require (
|
||||||
github.com/NYTimes/gziphandler v1.1.1
|
github.com/NYTimes/gziphandler v1.1.1
|
||||||
github.com/PuerkitoBio/goquery v1.8.0
|
github.com/PuerkitoBio/goquery v1.8.0
|
||||||
github.com/alecthomas/chroma/v2 v2.3.0
|
github.com/alecthomas/chroma/v2 v2.3.0
|
||||||
github.com/blevesearch/bleve/v2 v2.3.2
|
github.com/blevesearch/bleve/v2 v2.3.4
|
||||||
github.com/buildkite/terminal-to-html/v3 v3.7.0
|
github.com/buildkite/terminal-to-html/v3 v3.7.0
|
||||||
github.com/caddyserver/certmagic v0.17.0
|
github.com/caddyserver/certmagic v0.17.2
|
||||||
github.com/chi-middleware/proxy v1.1.1
|
github.com/chi-middleware/proxy v1.1.1
|
||||||
github.com/denisenkom/go-mssqldb v0.12.2
|
github.com/denisenkom/go-mssqldb v0.12.2
|
||||||
github.com/djherbis/buffer v1.2.0
|
github.com/djherbis/buffer v1.2.0
|
||||||
|
@ -31,46 +31,46 @@ require (
|
||||||
github.com/felixge/fgprof v0.9.3
|
github.com/felixge/fgprof v0.9.3
|
||||||
github.com/fsnotify/fsnotify v1.5.4
|
github.com/fsnotify/fsnotify v1.5.4
|
||||||
github.com/gliderlabs/ssh v0.3.5
|
github.com/gliderlabs/ssh v0.3.5
|
||||||
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535
|
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0
|
||||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d
|
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778
|
||||||
github.com/go-chi/chi/v5 v5.0.7
|
github.com/go-chi/chi/v5 v5.0.7
|
||||||
github.com/go-chi/cors v1.2.1
|
github.com/go-chi/cors v1.2.1
|
||||||
github.com/go-enry/go-enry/v2 v2.8.2
|
github.com/go-enry/go-enry/v2 v2.8.3
|
||||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
|
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
|
||||||
github.com/go-git/go-billy/v5 v5.3.1
|
github.com/go-git/go-billy/v5 v5.3.1
|
||||||
github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf
|
github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf
|
||||||
github.com/go-ldap/ldap/v3 v3.4.4
|
github.com/go-ldap/ldap/v3 v3.4.4
|
||||||
github.com/go-redis/redis/v8 v8.11.5
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
github.com/go-sql-driver/mysql v1.6.0
|
github.com/go-sql-driver/mysql v1.6.0
|
||||||
github.com/go-swagger/go-swagger v0.30.0
|
github.com/go-swagger/go-swagger v0.30.3
|
||||||
github.com/go-testfixtures/testfixtures/v3 v3.8.1
|
github.com/go-testfixtures/testfixtures/v3 v3.8.1
|
||||||
github.com/gobwas/glob v0.2.3
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
|
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
|
||||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.2
|
github.com/golang-jwt/jwt/v4 v4.4.2
|
||||||
github.com/google/go-github/v45 v45.0.0
|
github.com/google/go-github/v45 v45.2.0
|
||||||
github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40
|
github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/gorilla/feeds v1.1.1
|
github.com/gorilla/feeds v1.1.1
|
||||||
github.com/gorilla/sessions v1.2.1
|
github.com/gorilla/sessions v1.2.1
|
||||||
github.com/hashicorp/go-version v1.4.0
|
github.com/hashicorp/go-version v1.6.0
|
||||||
github.com/hashicorp/golang-lru v0.5.4
|
github.com/hashicorp/golang-lru v0.5.4
|
||||||
github.com/huandu/xstrings v1.3.2
|
github.com/huandu/xstrings v1.3.2
|
||||||
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba
|
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba
|
||||||
github.com/json-iterator/go v1.1.12
|
github.com/json-iterator/go v1.1.12
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
||||||
github.com/klauspost/compress v1.15.9
|
github.com/klauspost/compress v1.15.11
|
||||||
github.com/klauspost/cpuid/v2 v2.1.1
|
github.com/klauspost/cpuid/v2 v2.1.1
|
||||||
github.com/lib/pq v1.10.6
|
github.com/lib/pq v1.10.7
|
||||||
github.com/markbates/goth v1.73.0
|
github.com/markbates/goth v1.73.0
|
||||||
github.com/mattn/go-isatty v0.0.16
|
github.com/mattn/go-isatty v0.0.16
|
||||||
github.com/mattn/go-sqlite3 v1.14.13
|
github.com/mattn/go-sqlite3 v1.14.15
|
||||||
github.com/mholt/archiver/v3 v3.5.1
|
github.com/mholt/archiver/v3 v3.5.1
|
||||||
github.com/microcosm-cc/bluemonday v1.0.20
|
github.com/microcosm-cc/bluemonday v1.0.20
|
||||||
github.com/minio/minio-go/v7 v7.0.35
|
github.com/minio/minio-go/v7 v7.0.39
|
||||||
github.com/msteinert/pam v1.0.0
|
github.com/msteinert/pam v1.1.0
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/niklasfasching/go-org v1.6.5
|
github.com/niklasfasching/go-org v1.6.5
|
||||||
github.com/oliamb/cutter v0.2.2
|
github.com/oliamb/cutter v0.2.2
|
||||||
|
@ -79,26 +79,26 @@ require (
|
||||||
github.com/pquerna/otp v1.3.0
|
github.com/pquerna/otp v1.3.0
|
||||||
github.com/prometheus/client_golang v1.13.0
|
github.com/prometheus/client_golang v1.13.0
|
||||||
github.com/quasoft/websspi v1.1.2
|
github.com/quasoft/websspi v1.1.2
|
||||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0
|
github.com/santhosh-tekuri/jsonschema/v5 v5.0.1
|
||||||
github.com/sergi/go-diff v1.2.0
|
github.com/sergi/go-diff v1.2.0
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
github.com/syndtr/goleveldb v1.0.0
|
github.com/syndtr/goleveldb v1.0.0
|
||||||
github.com/tstranex/u2f v1.0.0
|
github.com/tstranex/u2f v1.0.0
|
||||||
github.com/unrolled/render v1.5.0
|
github.com/unrolled/render v1.5.0
|
||||||
github.com/urfave/cli v1.22.9
|
github.com/urfave/cli v1.22.10
|
||||||
github.com/xanzy/go-gitlab v0.73.1
|
github.com/xanzy/go-gitlab v0.73.1
|
||||||
github.com/yohcop/openid-go v1.0.0
|
github.com/yohcop/openid-go v1.0.0
|
||||||
github.com/yuin/goldmark v1.4.15
|
github.com/yuin/goldmark v1.5.2
|
||||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87
|
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87
|
||||||
github.com/yuin/goldmark-meta v1.1.0
|
github.com/yuin/goldmark-meta v1.1.0
|
||||||
go.jolheiser.com/hcaptcha v0.0.4
|
go.jolheiser.com/hcaptcha v0.0.4
|
||||||
go.jolheiser.com/pwn v0.0.3
|
go.jolheiser.com/pwn v0.0.3
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
|
||||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc
|
golang.org/x/net v0.0.0-20220927171203-f486391704dc
|
||||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
|
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
|
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
|
||||||
golang.org/x/text v0.3.7
|
golang.org/x/text v0.3.8
|
||||||
golang.org/x/tools v0.1.12
|
golang.org/x/tools v0.1.12
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/ini.v1 v1.67.0
|
gopkg.in/ini.v1 v1.67.0
|
||||||
|
@ -117,9 +117,9 @@ require (
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||||
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 // indirect
|
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad // indirect
|
||||||
github.com/RoaringBitmap/roaring v0.9.4 // indirect
|
github.com/RoaringBitmap/roaring v1.2.1 // indirect
|
||||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||||
|
@ -128,21 +128,22 @@ require (
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||||
github.com/bits-and-blooms/bitset v1.2.2 // indirect
|
github.com/bits-and-blooms/bitset v1.3.3 // indirect
|
||||||
github.com/blevesearch/bleve_index_api v1.0.1 // indirect
|
github.com/blevesearch/bleve_index_api v1.0.3 // indirect
|
||||||
|
github.com/blevesearch/geo v0.1.14 // indirect
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||||
github.com/blevesearch/gtreap v0.1.1 // indirect
|
github.com/blevesearch/gtreap v0.1.1 // indirect
|
||||||
github.com/blevesearch/mmap-go v1.0.3 // indirect
|
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.0 // indirect
|
github.com/blevesearch/scorch_segment_api/v2 v2.1.2 // indirect
|
||||||
github.com/blevesearch/segment v0.9.0 // indirect
|
github.com/blevesearch/segment v0.9.0 // indirect
|
||||||
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
||||||
github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect
|
github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect
|
||||||
github.com/blevesearch/vellum v1.0.7 // indirect
|
github.com/blevesearch/vellum v1.0.8 // indirect
|
||||||
github.com/blevesearch/zapx/v11 v11.3.3 // indirect
|
github.com/blevesearch/zapx/v11 v11.3.5 // indirect
|
||||||
github.com/blevesearch/zapx/v12 v12.3.3 // indirect
|
github.com/blevesearch/zapx/v12 v12.3.5 // indirect
|
||||||
github.com/blevesearch/zapx/v13 v13.3.3 // indirect
|
github.com/blevesearch/zapx/v13 v13.3.5 // indirect
|
||||||
github.com/blevesearch/zapx/v14 v14.3.3 // indirect
|
github.com/blevesearch/zapx/v14 v14.3.5 // indirect
|
||||||
github.com/blevesearch/zapx/v15 v15.3.3 // indirect
|
github.com/blevesearch/zapx/v15 v15.3.5 // indirect
|
||||||
github.com/boombuler/barcode v1.0.1 // indirect
|
github.com/boombuler/barcode v1.0.1 // indirect
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
|
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
|
||||||
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||||
|
@ -167,7 +168,7 @@ require (
|
||||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
|
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
|
||||||
github.com/fullstorydev/grpcurl v1.8.1 // indirect
|
github.com/fullstorydev/grpcurl v1.8.1 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
|
||||||
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1 // indirect
|
github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18 // indirect
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||||
github.com/go-enry/go-oniguruma v1.2.1 // indirect
|
github.com/go-enry/go-oniguruma v1.2.1 // indirect
|
||||||
github.com/go-git/gcfg v1.5.0 // indirect
|
github.com/go-git/gcfg v1.5.0 // indirect
|
||||||
|
@ -186,6 +187,7 @@ require (
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||||
|
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/mock v1.6.0 // indirect
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
@ -219,7 +221,7 @@ require (
|
||||||
github.com/magiconair/properties v1.8.6 // indirect
|
github.com/magiconair/properties v1.8.6 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/markbates/going v1.0.0 // indirect
|
github.com/markbates/going v1.0.0 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||||
github.com/mholt/acmez v1.0.4 // indirect
|
github.com/mholt/acmez v1.0.4 // indirect
|
||||||
github.com/miekg/dns v1.1.50 // indirect
|
github.com/miekg/dns v1.1.50 // indirect
|
||||||
|
@ -237,12 +239,12 @@ require (
|
||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_model v0.2.0 // indirect
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
github.com/prometheus/common v0.37.0 // indirect
|
github.com/prometheus/common v0.37.0 // indirect
|
||||||
github.com/prometheus/procfs v0.8.0 // indirect
|
github.com/prometheus/procfs v0.8.0 // indirect
|
||||||
github.com/rivo/uniseg v0.3.4 // indirect
|
github.com/rivo/uniseg v0.4.2 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||||
github.com/rs/xid v1.4.0 // indirect
|
github.com/rs/xid v1.4.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
|
@ -283,7 +285,7 @@ require (
|
||||||
go.uber.org/multierr v1.8.0 // indirect
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
go.uber.org/zap v1.23.0 // indirect
|
go.uber.org/zap v1.23.0 // indirect
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
|
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
|
||||||
google.golang.org/grpc v1.47.0 // indirect
|
google.golang.org/grpc v1.47.0 // indirect
|
||||||
|
|
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=
|
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 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
|
||||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
|
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-20221013104517-b29891619681 h1:MMSPgnVULVwV9kEBgvyEUhC9v/uviZ55hPJEMjpbNR4=
|
||||||
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/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.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 h1:E0npuTfDW6CT1yD8NMDVc1SK6IeRjfmRL2zlEsCEd7w=
|
||||||
gitea.com/go-chi/cache v0.2.0/go.mod h1:iQlVK2aKTZ/rE9UcHyz9pQWGvdP9i1eI2spOpzgCrtE=
|
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 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
|
||||||
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||||
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
|
||||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||||
|
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||||
|
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg=
|
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||||
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||||
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||||
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
|
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
|
||||||
github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo=
|
|
||||||
github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
||||||
|
github.com/RoaringBitmap/roaring v1.2.1 h1:58/LJlg/81wfEHd5L9qsHduznOIhyv4qb1yWcSvVq9A=
|
||||||
|
github.com/RoaringBitmap/roaring v1.2.1/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
|
@ -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/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE=
|
github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE=
|
||||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||||
github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk=
|
github.com/bits-and-blooms/bitset v1.3.3 h1:R1XWiopGiXf66xygsiLpzLo67xEYvMkHw3w+rCOSAwg=
|
||||||
github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
github.com/bits-and-blooms/bitset v1.3.3/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||||
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
|
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
|
||||||
github.com/blevesearch/bleve/v2 v2.3.2 h1:BJUnMhi2nrkl+vboHmKfW+9l+tJSj39HeWa5c3BN3/Y=
|
github.com/blevesearch/bleve/v2 v2.3.4 h1:SSb7/cwGzo85LWX1jchIsXM8ZiNNMX3shT5lROM63ew=
|
||||||
github.com/blevesearch/bleve/v2 v2.3.2/go.mod h1:96+xE5pZUOsr3Y4vHzV1cBC837xZCpwLlX0hrrxnvIg=
|
github.com/blevesearch/bleve/v2 v2.3.4/go.mod h1:Ot0zYum8XQRfPcwhae8bZmNyYubynsoMjVvl1jPqL30=
|
||||||
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||||
github.com/blevesearch/bleve_index_api v1.0.1 h1:nx9++0hnyiGOHJwQQYfsUGzpRdEVE5LsylmmngQvaFk=
|
github.com/blevesearch/bleve_index_api v1.0.3 h1:DDSWaPXOZZJ2BB73ZTWjKxydAugjwywcqU+91AAqcAg=
|
||||||
github.com/blevesearch/bleve_index_api v1.0.1/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
github.com/blevesearch/bleve_index_api v1.0.3/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||||
github.com/blevesearch/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
|
github.com/blevesearch/geo v0.1.13/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
|
||||||
|
github.com/blevesearch/geo v0.1.14 h1:TTDpJN6l9ck/cUYbXSn4aCElNls0Whe44rcQKsB7EfU=
|
||||||
|
github.com/blevesearch/geo v0.1.14/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
|
||||||
|
github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||||
github.com/blevesearch/goleveldb v1.0.1/go.mod h1:WrU8ltZbIp0wAoig/MHbrPCXSOLpe79nz5lv5nqfYrQ=
|
github.com/blevesearch/goleveldb v1.0.1/go.mod h1:WrU8ltZbIp0wAoig/MHbrPCXSOLpe79nz5lv5nqfYrQ=
|
||||||
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
||||||
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
||||||
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
|
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
|
||||||
github.com/blevesearch/mmap-go v1.0.3 h1:7QkALgFNooSq3a46AE+pWeKASAZc9SiNFJhDGF1NDx4=
|
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
||||||
github.com/blevesearch/mmap-go v1.0.3/go.mod h1:pYvKl/grLQrBxuaRYgoTssa4rVujYYeenDp++2E+yvs=
|
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
|
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.0 h1:NFwteOpZEvJk5Vg0H6gD0hxupsG3JYocE4DBvsA2GZI=
|
github.com/blevesearch/scorch_segment_api/v2 v2.1.2 h1:TAte9VZLWda5WAVlZTTZ+GCzEHqGJb4iB2aiZSA6Iv8=
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.0/go.mod h1:uch7xyyO/Alxkuxa+CGs79vw0QY8BENSBjg6Mw5L5DE=
|
github.com/blevesearch/scorch_segment_api/v2 v2.1.2/go.mod h1:rvoQXZGq8drq7vXbNeyiRzdEOwZkjkiYGf1822i6CRA=
|
||||||
github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac=
|
github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac=
|
||||||
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
||||||
github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg=
|
github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg=
|
||||||
|
@ -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/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
|
||||||
github.com/blevesearch/vellum v1.0.3/go.mod h1:2u5ax02KeDuNWu4/C+hVQMD6uLN4txH1JbtpaDNLJRo=
|
github.com/blevesearch/vellum v1.0.3/go.mod h1:2u5ax02KeDuNWu4/C+hVQMD6uLN4txH1JbtpaDNLJRo=
|
||||||
github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRvNBlNMrEVgY=
|
github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRvNBlNMrEVgY=
|
||||||
github.com/blevesearch/vellum v1.0.7 h1:+vn8rfyCRHxKVRgDLeR0FAXej2+6mEb5Q15aQE/XESQ=
|
github.com/blevesearch/vellum v1.0.8 h1:iMGh4lfxza4BnWO/UJTMPlI3HsK9YawjPv+TteVa9ck=
|
||||||
github.com/blevesearch/vellum v1.0.7/go.mod h1:doBZpmRhwTsASB4QdUZANlJvqVAUdUyX0ZK7QJCTeBE=
|
github.com/blevesearch/vellum v1.0.8/go.mod h1:+cpRi/tqq49xUYSQN2P7A5zNSNrS+MscLeeaZ3J46UA=
|
||||||
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
|
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
|
||||||
github.com/blevesearch/zapx/v11 v11.3.3 h1:8vQMO5hdA2qPCmicIMuKS+qcvUAEh6Vcb0uve4Nh8e4=
|
github.com/blevesearch/zapx/v11 v11.3.5 h1:eBQWQ7huA+mzm0sAGnZDwgGGli7S45EO+N+ObFWssbI=
|
||||||
github.com/blevesearch/zapx/v11 v11.3.3/go.mod h1:YzTfUm4kS3e8OmTXDHVV8OzC5MWPO/VPJZQgPNVb4Lc=
|
github.com/blevesearch/zapx/v11 v11.3.5/go.mod h1:5UdIa/HRMdeRCiLQOyFESsnqBGiip7vQmYReA9toevU=
|
||||||
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
|
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
|
||||||
github.com/blevesearch/zapx/v12 v12.3.3 h1:MQO5YNI8MqdPz12ALCoXiJw5cl9QQamYZSp285Z/+Mo=
|
github.com/blevesearch/zapx/v12 v12.3.5 h1:5pX2hU+R1aZihT7ac1dNWh1n4wqkIM9pZzWp0ANED9s=
|
||||||
github.com/blevesearch/zapx/v12 v12.3.3/go.mod h1:RMl6lOZqF+sTxKvhQDJ5yK2LT3Mu7E2p/jGdjAaiRxs=
|
github.com/blevesearch/zapx/v12 v12.3.5/go.mod h1:ANcthYRZQycpbRut/6ArF5gP5HxQyJqiFcuJCBju/ss=
|
||||||
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
|
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
|
||||||
github.com/blevesearch/zapx/v13 v13.3.3 h1:TS4xpMK1ARPYHq+1WwuEOKMOiwvKpTK3RuWOkKlI7BE=
|
github.com/blevesearch/zapx/v13 v13.3.5 h1:eJ3gbD+Nu8p36/O6lhfdvWQ4pxsGYSuTOBrLLPVWJ74=
|
||||||
github.com/blevesearch/zapx/v13 v13.3.3/go.mod h1:eppobNM35U4C22yDvTuxV9xPqo10pwfP/jugL4INWG4=
|
github.com/blevesearch/zapx/v13 v13.3.5/go.mod h1:FV+dRnScFgKnRDIp08RQL4JhVXt1x2HE3AOzqYa6fjo=
|
||||||
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
|
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
|
||||||
github.com/blevesearch/zapx/v14 v14.3.3 h1:dqqAzGphKl0yehHKKntDHKlEMhi9B/tJrD4OsWpY7YE=
|
github.com/blevesearch/zapx/v14 v14.3.5 h1:hEvVjZaagFCvOUJrlFQ6/Z6Jjy0opM3g7TMEo58TwP4=
|
||||||
github.com/blevesearch/zapx/v14 v14.3.3/go.mod h1:zXNcVzukh0AvG57oUtT1T0ndi09H0kELNaNmekEy0jw=
|
github.com/blevesearch/zapx/v14 v14.3.5/go.mod h1:954A/eKFb+pg/ncIYWLWCKY+mIjReM9FGTGIO2Wu1cU=
|
||||||
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
|
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
|
||||||
github.com/blevesearch/zapx/v15 v15.3.3 h1:60oE+qsJkveLenJmbc0eaH59GWYCbJJsPDV6Z5hEoYY=
|
github.com/blevesearch/zapx/v15 v15.3.5 h1:NVD0qq8vRk66ImJn1KloXT5ckqPDUZT7VbVJs9jKlac=
|
||||||
github.com/blevesearch/zapx/v15 v15.3.3/go.mod h1:C+f/97ZzTzK6vt/7sVlZdzZxKu+5+j4SrGCvr9dJzaY=
|
github.com/blevesearch/zapx/v15 v15.3.5/go.mod h1:QMUh2hXCaYIWFKPYGavq/Iga2zbHWZ9DZAa9uFbWyvg=
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||||
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
|
@ -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.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw=
|
github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw=
|
||||||
github.com/caddyserver/certmagic v0.17.0 h1:AHHvvmv6SNcq0vK5BgCevQqYMV8GNprVk6FWZzx8d+Q=
|
github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE=
|
||||||
github.com/caddyserver/certmagic v0.17.0/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM=
|
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
|
||||||
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo=
|
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo=
|
||||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A=
|
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A=
|
||||||
|
@ -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/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||||
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535 h1:vzEChLhjI35zDlXG9KZnOMCHa9MRVaagS5IHJcagVRI=
|
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0 h1:EUMB0x7u3de/ikGBtXiLxaJbmxgiqiAcM4yjW4whApM=
|
||||||
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535/go.mod h1:y3eWqPv2lYZ0YbAvEk4CGyFUJzbNsoLmkon8S7ZyX6I=
|
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-20220618122732-319f41ac54e1 h1:PkPVIQGt76HHFWSeUINXCfYpEnzlSS+AQyuXi7oJ/gM=
|
github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18 h1:A48SbkWKEciiJMbbcPzaRj9aizPUABzXFvCM3LtGGf8=
|
||||||
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1/go.mod h1:KHkKFKZvc05lr79+RGoq/zG8YjWi3+FK60Bxd+mpCew=
|
github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18/go.mod h1:dd3ZgjjloBsKPDpqA2kf2VWhF0A1eKUItOBh0/QcDWI=
|
||||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d h1:Z/oRXMlZHjvjIqDma1FrIGL3iE5YL7MUI0bwYEZ6qbA=
|
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778 h1:0tV3i8tE1NghMC4rXZXfD39KUbkKgIyLTsvOEmMOPCQ=
|
||||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA=
|
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA=
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||||
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
|
@ -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/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||||
github.com/go-enry/go-enry/v2 v2.8.2 h1:uiGmC+3K8sVd/6DOe2AOJEOihJdqda83nPyJNtMR8RI=
|
github.com/go-enry/go-enry/v2 v2.8.3 h1:BwvNrN58JqBJhyyVdZSl5QD3xoxEEGYUrRyPh31FGhw=
|
||||||
github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
github.com/go-enry/go-enry/v2 v2.8.3/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
||||||
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
||||||
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8=
|
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8=
|
||||||
|
@ -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-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
|
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
|
||||||
github.com/go-swagger/go-swagger v0.30.0 h1:HakSyutD7Ek9ndkR8Fxy6WAoQtgu7UcAmZCTa6SzawA=
|
github.com/go-swagger/go-swagger v0.30.3 h1:HuzvdMRed/9Q8vmzVcfNBQByZVtT79DNZxZ18OprdoI=
|
||||||
github.com/go-swagger/go-swagger v0.30.0/go.mod h1:GhZVX/KIBM4VpGp4P7AJOIrlTuBeRVPS+j9kk6rFmfY=
|
github.com/go-swagger/go-swagger v0.30.3/go.mod h1:neDPes8r8PCz2JPvHRDj8BTULLh4VJUt7n6MpQqxhHM=
|
||||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
|
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
|
||||||
github.com/go-testfixtures/testfixtures/v3 v3.8.1 h1:uonwvepqRvSgddcrReZQhojTlWlmOlHkYAb9ZaOMWgU=
|
github.com/go-testfixtures/testfixtures/v3 v3.8.1 h1:uonwvepqRvSgddcrReZQhojTlWlmOlHkYAb9ZaOMWgU=
|
||||||
github.com/go-testfixtures/testfixtures/v3 v3.8.1/go.mod h1:Kdu7YeMC0KRXVHdaQ91Vmx3pcjoTF63h4f1qTJDdXLA=
|
github.com/go-testfixtures/testfixtures/v3 v3.8.1/go.mod h1:Kdu7YeMC0KRXVHdaQ91Vmx3pcjoTF63h4f1qTJDdXLA=
|
||||||
|
@ -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/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||||
|
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
|
||||||
|
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
@ -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 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
|
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
|
||||||
github.com/google/go-github/v45 v45.0.0 h1:LU0WBjYidxIVyx7PZeWb+FP4JZJ3Wh3FQgdumnGqiLs=
|
github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI=
|
||||||
github.com/google/go-github/v45 v45.0.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28=
|
github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28=
|
||||||
github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M=
|
github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
|
@ -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/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
|
||||||
github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
|
github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M=
|
github.com/google/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
|
@ -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/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
|
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
|
github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
@ -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.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
|
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
|
||||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
@ -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.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
|
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||||
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
||||||
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||||
|
@ -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.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I=
|
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||||
github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
@ -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/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||||
github.com/minio/minio-go/v7 v7.0.35 h1:JuPPxWLdxQmNLSaS8AWZnO5HBadeI1xg6FGrEELQEVU=
|
github.com/minio/minio-go/v7 v7.0.39 h1:upnbu1jCGOqEvrGSpRauSN9ZG7RCHK7VHxXS8Vmg2zk=
|
||||||
github.com/minio/minio-go/v7 v7.0.35/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw=
|
github.com/minio/minio-go/v7 v7.0.39/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw=
|
||||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
|
@ -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.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||||
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
||||||
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
||||||
github.com/msteinert/pam v1.0.0 h1:4XoXKtMCH3+e6GIkW41uxm6B37eYqci/DH3gzSq7ocg=
|
github.com/msteinert/pam v1.1.0 h1:VhLun/0n0kQYxiRBJJvVpC2jR6d21SWJFjpvUVj20Kc=
|
||||||
github.com/msteinert/pam v1.0.0/go.mod h1:M4FPeAW8g2ITO68W8gACDz13NDJyOQM9IQsQhrR6TOI=
|
github.com/msteinert/pam v1.1.0/go.mod h1:M4FPeAW8g2ITO68W8gACDz13NDJyOQM9IQsQhrR6TOI=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
|
github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
|
||||||
|
@ -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 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
|
||||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
@ -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/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
|
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
|
||||||
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
|
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
|
@ -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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE=
|
github.com/santhosh-tekuri/jsonschema/v5 v5.0.1 h1:HNLA3HtUIROrQwG1cuu5EYuqk3UEoJ61Dr/9xkd6sok=
|
||||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
github.com/santhosh-tekuri/jsonschema/v5 v5.0.1/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
||||||
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I=
|
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
@ -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.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw=
|
github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
|
||||||
github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
|
github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
|
||||||
|
@ -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.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.15 h1:CFa84T0goNn/UIXYS+dmjjVxMyTAvpOmzld40N/nfK0=
|
|
||||||
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
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 h1:Py16JEzkSdKAtEFJjiaYLYBOWGXc1r/xHj/Q/5lA37k=
|
||||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
|
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
|
||||||
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
|
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
|
||||||
|
@ -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-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -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-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||||
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8=
|
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
|
||||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -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-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
@ -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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||||
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
|
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
|
||||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
|
|
@ -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)
|
actions := make([]*Action, 0, opts.PageSize)
|
||||||
|
|
||||||
if err := sess.Desc("`action`.created_unix").Find(&actions); err != nil {
|
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 {
|
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
|
return actions, nil
|
||||||
|
@ -415,7 +415,7 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
|
||||||
env := organization.OrgFromUser(opts.RequestedUser).AccessibleTeamReposEnv(opts.RequestedTeam)
|
env := organization.OrgFromUser(opts.RequestedUser).AccessibleTeamReposEnv(opts.RequestedTeam)
|
||||||
teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos)
|
teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos)
|
||||||
if err != nil {
|
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))
|
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.
|
// Add feeds for user self and all watchers.
|
||||||
watchers, err = repo_model.GetWatchers(ctx, act.RepoID)
|
watchers, err = repo_model.GetWatchers(ctx, act.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("get watchers: %v", err)
|
return fmt.Errorf("get watchers: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add feed for actioner.
|
// Add feed for actioner.
|
||||||
act.UserID = act.ActUserID
|
act.UserID = act.ActUserID
|
||||||
if _, err = e.Insert(act); err != nil {
|
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 {
|
if repoChanged {
|
||||||
|
@ -493,7 +493,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error {
|
||||||
|
|
||||||
// check repo owner exist.
|
// check repo owner exist.
|
||||||
if err := act.Repo.GetOwner(ctx); err != nil {
|
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 {
|
} else if act.Repo == nil {
|
||||||
act.Repo = repo
|
act.Repo = repo
|
||||||
|
@ -504,7 +504,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error {
|
||||||
act.ID = 0
|
act.ID = 0
|
||||||
act.UserID = act.Repo.Owner.ID
|
act.UserID = act.Repo.Owner.ID
|
||||||
if err = db.Insert(ctx, act); err != nil {
|
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 {
|
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
|
type ActionList []*Action
|
||||||
|
|
||||||
func (actions ActionList) getUserIDs() []int64 {
|
func (actions ActionList) getUserIDs() []int64 {
|
||||||
userIDs := make(map[int64]struct{}, len(actions))
|
userIDs := make(container.Set[int64], len(actions))
|
||||||
for _, action := range actions {
|
for _, action := range actions {
|
||||||
if _, ok := userIDs[action.ActUserID]; !ok {
|
userIDs.Add(action.ActUserID)
|
||||||
userIDs[action.ActUserID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(userIDs)
|
return userIDs.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) {
|
func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) {
|
||||||
|
@ -38,7 +36,7 @@ func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.
|
||||||
In("id", userIDs).
|
In("id", userIDs).
|
||||||
Find(&userMaps)
|
Find(&userMaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("find user: %v", err)
|
return nil, fmt.Errorf("find user: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, action := range actions {
|
for _, action := range actions {
|
||||||
|
@ -48,13 +46,11 @@ func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (actions ActionList) getRepoIDs() []int64 {
|
func (actions ActionList) getRepoIDs() []int64 {
|
||||||
repoIDs := make(map[int64]struct{}, len(actions))
|
repoIDs := make(container.Set[int64], len(actions))
|
||||||
for _, action := range actions {
|
for _, action := range actions {
|
||||||
if _, ok := repoIDs[action.RepoID]; !ok {
|
repoIDs.Add(action.RepoID)
|
||||||
repoIDs[action.RepoID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(repoIDs)
|
return repoIDs.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (actions ActionList) loadRepositories(ctx context.Context) error {
|
func (actions ActionList) loadRepositories(ctx context.Context) error {
|
||||||
|
@ -66,7 +62,7 @@ func (actions ActionList) loadRepositories(ctx context.Context) error {
|
||||||
repoMaps := make(map[int64]*repo_model.Repository, len(repoIDs))
|
repoMaps := make(map[int64]*repo_model.Repository, len(repoIDs))
|
||||||
err := db.GetEngine(ctx).In("id", repoIDs).Find(&repoMaps)
|
err := db.GetEngine(ctx).In("id", repoIDs).Find(&repoMaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("find repository: %v", err)
|
return fmt.Errorf("find repository: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, action := range actions {
|
for _, action := range actions {
|
||||||
|
|
|
@ -200,7 +200,7 @@ func CreateOrUpdateIssueNotifications(issueID, commentID, notificationAuthorID,
|
||||||
|
|
||||||
func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error {
|
func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error {
|
||||||
// init
|
// init
|
||||||
var toNotify map[int64]struct{}
|
var toNotify container.Set[int64]
|
||||||
notifications, err := getNotificationsByIssueID(ctx, issueID)
|
notifications, err := getNotificationsByIssueID(ctx, issueID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -212,33 +212,27 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
|
||||||
}
|
}
|
||||||
|
|
||||||
if receiverID > 0 {
|
if receiverID > 0 {
|
||||||
toNotify = make(map[int64]struct{}, 1)
|
toNotify = make(container.Set[int64], 1)
|
||||||
toNotify[receiverID] = struct{}{}
|
toNotify.Add(receiverID)
|
||||||
} else {
|
} else {
|
||||||
toNotify = make(map[int64]struct{}, 32)
|
toNotify = make(container.Set[int64], 32)
|
||||||
issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true)
|
issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, id := range issueWatches {
|
toNotify.AddMultiple(issueWatches...)
|
||||||
toNotify[id] = struct{}{}
|
|
||||||
}
|
|
||||||
if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) {
|
if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) {
|
||||||
repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID)
|
repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, id := range repoWatches {
|
toNotify.AddMultiple(repoWatches...)
|
||||||
toNotify[id] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
issueParticipants, err := issue.GetParticipantIDsByIssue(ctx)
|
issueParticipants, err := issue.GetParticipantIDsByIssue(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, id := range issueParticipants {
|
toNotify.AddMultiple(issueParticipants...)
|
||||||
toNotify[id] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dont notify user who cause notification
|
// dont notify user who cause notification
|
||||||
delete(toNotify, notificationAuthorID)
|
delete(toNotify, notificationAuthorID)
|
||||||
|
@ -248,7 +242,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, id := range issueUnWatches {
|
for _, id := range issueUnWatches {
|
||||||
delete(toNotify, id)
|
toNotify.Remove(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,7 +403,7 @@ func (n *Notification) loadRepo(ctx context.Context) (err error) {
|
||||||
if n.Repository == nil {
|
if n.Repository == nil {
|
||||||
n.Repository, err = repo_model.GetRepositoryByIDCtx(ctx, n.RepoID)
|
n.Repository, err = repo_model.GetRepositoryByIDCtx(ctx, n.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getRepositoryByID [%d]: %v", n.RepoID, err)
|
return fmt.Errorf("getRepositoryByID [%d]: %w", n.RepoID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -419,7 +413,7 @@ func (n *Notification) loadIssue(ctx context.Context) (err error) {
|
||||||
if n.Issue == nil && n.IssueID != 0 {
|
if n.Issue == nil && n.IssueID != 0 {
|
||||||
n.Issue, err = issues_model.GetIssueByID(ctx, n.IssueID)
|
n.Issue, err = issues_model.GetIssueByID(ctx, n.IssueID)
|
||||||
if err != nil {
|
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)
|
return n.Issue.LoadAttributes(ctx)
|
||||||
}
|
}
|
||||||
|
@ -446,7 +440,7 @@ func (n *Notification) loadUser(ctx context.Context) (err error) {
|
||||||
if n.User == nil {
|
if n.User == nil {
|
||||||
n.User, err = user_model.GetUserByIDCtx(ctx, n.UserID)
|
n.User, err = user_model.GetUserByIDCtx(ctx, n.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getUserByID [%d]: %v", n.UserID, err)
|
return fmt.Errorf("getUserByID [%d]: %w", n.UserID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -499,16 +493,14 @@ func (nl NotificationList) LoadAttributes() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nl NotificationList) getPendingRepoIDs() []int64 {
|
func (nl NotificationList) getPendingRepoIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(nl))
|
ids := make(container.Set[int64], len(nl))
|
||||||
for _, notification := range nl {
|
for _, notification := range nl {
|
||||||
if notification.Repository != nil {
|
if notification.Repository != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := ids[notification.RepoID]; !ok {
|
ids.Add(notification.RepoID)
|
||||||
ids[notification.RepoID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadRepos loads repositories from database
|
// LoadRepos loads repositories from database
|
||||||
|
@ -575,16 +567,14 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nl NotificationList) getPendingIssueIDs() []int64 {
|
func (nl NotificationList) getPendingIssueIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(nl))
|
ids := make(container.Set[int64], len(nl))
|
||||||
for _, notification := range nl {
|
for _, notification := range nl {
|
||||||
if notification.Issue != nil {
|
if notification.Issue != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := ids[notification.IssueID]; !ok {
|
ids.Add(notification.IssueID)
|
||||||
ids[notification.IssueID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadIssues loads issues from database
|
// LoadIssues loads issues from database
|
||||||
|
@ -661,16 +651,14 @@ func (nl NotificationList) Without(failures []int) NotificationList {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nl NotificationList) getPendingCommentIDs() []int64 {
|
func (nl NotificationList) getPendingCommentIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(nl))
|
ids := make(container.Set[int64], len(nl))
|
||||||
for _, notification := range nl {
|
for _, notification := range nl {
|
||||||
if notification.CommentID == 0 || notification.Comment != nil {
|
if notification.CommentID == 0 || notification.Comment != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := ids[notification.CommentID]; !ok {
|
ids.Add(notification.CommentID)
|
||||||
ids[notification.CommentID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadComments loads comments from database
|
// LoadComments loads comments from database
|
||||||
|
@ -818,7 +806,7 @@ func getNotificationByID(ctx context.Context, notificationID int64) (*Notificati
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, db.ErrNotExist{ID: notificationID}
|
return nil, db.ErrNotExist{Resource: "notification", ID: notificationID}
|
||||||
}
|
}
|
||||||
|
|
||||||
return notification, nil
|
return notification, nil
|
||||||
|
|
|
@ -49,32 +49,32 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
|
||||||
stats := &ActivityStats{Code: &git.CodeActivityStats{}}
|
stats := &ActivityStats{Code: &git.CodeActivityStats{}}
|
||||||
if releases {
|
if releases {
|
||||||
if err := stats.FillReleases(repo.ID, timeFrom); err != nil {
|
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 prs {
|
||||||
if err := stats.FillPullRequests(repo.ID, timeFrom); err != nil {
|
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 issues {
|
||||||
if err := stats.FillIssues(repo.ID, timeFrom); err != nil {
|
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 {
|
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 {
|
if code {
|
||||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
return nil, fmt.Errorf("OpenRepository: %w", err)
|
||||||
}
|
}
|
||||||
defer closer.Close()
|
defer closer.Close()
|
||||||
|
|
||||||
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
|
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("FillFromGit: %v", err)
|
return nil, fmt.Errorf("FillFromGit: %w", err)
|
||||||
}
|
}
|
||||||
stats.Code = code
|
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) {
|
func GetActivityStatsTopAuthors(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
|
||||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
return nil, fmt.Errorf("OpenRepository: %w", err)
|
||||||
}
|
}
|
||||||
defer closer.Close()
|
defer closer.Close()
|
||||||
|
|
||||||
code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
|
code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("FillFromGit: %v", err)
|
return nil, fmt.Errorf("FillFromGit: %w", err)
|
||||||
}
|
}
|
||||||
if code.Authors == nil {
|
if code.Authors == nil {
|
||||||
return nil, 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)
|
err.ID, err.RepoID, err.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrTaskDoesNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// GetMigratingTask returns the migrating task by repo's id
|
// GetMigratingTask returns the migrating task by repo's id
|
||||||
func GetMigratingTask(repoID int64) (*Task, error) {
|
func GetMigratingTask(repoID int64) (*Task, error) {
|
||||||
task := Task{
|
task := Task{
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
|
|
||||||
package asymkey
|
package asymkey
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
)
|
||||||
|
|
||||||
// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
|
// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
|
||||||
type ErrKeyUnableVerify struct {
|
type ErrKeyUnableVerify struct {
|
||||||
|
@ -36,6 +40,10 @@ func (err ErrKeyNotExist) Error() string {
|
||||||
return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
|
return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrKeyNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error.
|
// ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error.
|
||||||
type ErrKeyAlreadyExist struct {
|
type ErrKeyAlreadyExist struct {
|
||||||
OwnerID int64
|
OwnerID int64
|
||||||
|
@ -54,6 +62,10 @@ func (err ErrKeyAlreadyExist) Error() string {
|
||||||
err.OwnerID, err.Fingerprint, err.Content)
|
err.OwnerID, err.Fingerprint, err.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrKeyAlreadyExist) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
|
// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
|
||||||
type ErrKeyNameAlreadyUsed struct {
|
type ErrKeyNameAlreadyUsed struct {
|
||||||
OwnerID int64
|
OwnerID int64
|
||||||
|
@ -70,6 +82,10 @@ func (err ErrKeyNameAlreadyUsed) Error() string {
|
||||||
return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
|
return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrKeyNameAlreadyUsed) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
|
// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
|
||||||
type ErrGPGNoEmailFound struct {
|
type ErrGPGNoEmailFound struct {
|
||||||
FailedEmails []string
|
FailedEmails []string
|
||||||
|
@ -132,6 +148,10 @@ func (err ErrGPGKeyNotExist) Error() string {
|
||||||
return fmt.Sprintf("public gpg key does not exist [id: %d]", err.ID)
|
return fmt.Sprintf("public gpg key does not exist [id: %d]", err.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrGPGKeyNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrGPGKeyImportNotExist represents a "GPGKeyImportNotExist" kind of error.
|
// ErrGPGKeyImportNotExist represents a "GPGKeyImportNotExist" kind of error.
|
||||||
type ErrGPGKeyImportNotExist struct {
|
type ErrGPGKeyImportNotExist struct {
|
||||||
ID string
|
ID string
|
||||||
|
@ -147,6 +167,10 @@ func (err ErrGPGKeyImportNotExist) Error() string {
|
||||||
return fmt.Sprintf("public gpg key import does not exist [id: %s]", err.ID)
|
return fmt.Sprintf("public gpg key import does not exist [id: %s]", err.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrGPGKeyImportNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error.
|
// ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error.
|
||||||
type ErrGPGKeyIDAlreadyUsed struct {
|
type ErrGPGKeyIDAlreadyUsed struct {
|
||||||
KeyID string
|
KeyID string
|
||||||
|
@ -162,6 +186,10 @@ func (err ErrGPGKeyIDAlreadyUsed) Error() string {
|
||||||
return fmt.Sprintf("public key already exists [key_id: %s]", err.KeyID)
|
return fmt.Sprintf("public key already exists [key_id: %s]", err.KeyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrGPGKeyIDAlreadyUsed) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
|
// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
|
||||||
type ErrGPGKeyAccessDenied struct {
|
type ErrGPGKeyAccessDenied struct {
|
||||||
UserID int64
|
UserID int64
|
||||||
|
@ -180,6 +208,10 @@ func (err ErrGPGKeyAccessDenied) Error() string {
|
||||||
err.UserID, err.KeyID)
|
err.UserID, err.KeyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrGPGKeyAccessDenied) Unwrap() error {
|
||||||
|
return util.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
|
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
|
||||||
type ErrKeyAccessDenied struct {
|
type ErrKeyAccessDenied struct {
|
||||||
UserID int64
|
UserID int64
|
||||||
|
@ -198,6 +230,10 @@ func (err ErrKeyAccessDenied) Error() string {
|
||||||
err.UserID, err.KeyID, err.Note)
|
err.UserID, err.KeyID, err.Note)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrKeyAccessDenied) Unwrap() error {
|
||||||
|
return util.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
|
// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
|
||||||
type ErrDeployKeyNotExist struct {
|
type ErrDeployKeyNotExist struct {
|
||||||
ID int64
|
ID int64
|
||||||
|
@ -215,6 +251,10 @@ func (err ErrDeployKeyNotExist) Error() string {
|
||||||
return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
|
return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrDeployKeyNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
|
// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
|
||||||
type ErrDeployKeyAlreadyExist struct {
|
type ErrDeployKeyAlreadyExist struct {
|
||||||
KeyID int64
|
KeyID int64
|
||||||
|
@ -231,6 +271,10 @@ func (err ErrDeployKeyAlreadyExist) Error() string {
|
||||||
return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
|
return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrDeployKeyAlreadyExist) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
|
// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
|
||||||
type ErrDeployKeyNameAlreadyUsed struct {
|
type ErrDeployKeyNameAlreadyUsed struct {
|
||||||
RepoID int64
|
RepoID int64
|
||||||
|
@ -247,6 +291,10 @@ func (err ErrDeployKeyNameAlreadyUsed) Error() string {
|
||||||
return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
|
return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrDeployKeyNameAlreadyUsed) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrSSHInvalidTokenSignature represents a "ErrSSHInvalidTokenSignature" kind of error.
|
// ErrSSHInvalidTokenSignature represents a "ErrSSHInvalidTokenSignature" kind of error.
|
||||||
type ErrSSHInvalidTokenSignature struct {
|
type ErrSSHInvalidTokenSignature struct {
|
||||||
Wrapped error
|
Wrapped error
|
||||||
|
@ -262,3 +310,7 @@ func IsErrSSHInvalidTokenSignature(err error) bool {
|
||||||
func (err ErrSSHInvalidTokenSignature) Error() string {
|
func (err ErrSSHInvalidTokenSignature) Error() string {
|
||||||
return "the provided signature does not sign the token with the provided key"
|
return "the provided signature does not sign the token with the provided key"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrSSHInvalidTokenSignature) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
|
@ -226,7 +226,7 @@ func DeleteGPGKey(doer *user_model.User, id int64) (err error) {
|
||||||
if IsErrGPGKeyNotExist(err) {
|
if IsErrGPGKeyNotExist(err) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("GetPublicKeyByID: %v", err)
|
return fmt.Errorf("GetPublicKeyByID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if user has access to delete this key.
|
// 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,
|
LoginSourceID: authSourceID,
|
||||||
}
|
}
|
||||||
if err = addKey(ctx, key); err != nil {
|
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()
|
return key, committer.Commit()
|
||||||
|
|
|
@ -151,7 +151,7 @@ func AddDeployKey(repoID int64, name, content string, readOnly bool) (*DeployKey
|
||||||
pkey.Content = content
|
pkey.Content = content
|
||||||
pkey.Name = name
|
pkey.Name = name
|
||||||
if err = addKey(ctx, pkey); err != nil {
|
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)
|
log.Info("%s", publicKeyContent)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("%s: %v", fnName, err)
|
return "", fmt.Errorf("%s: %w", fnName, err)
|
||||||
}
|
}
|
||||||
return fp, nil
|
return fp, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ const ssh2keyStart = "---- BEGIN SSH2 PUBLIC KEY ----"
|
||||||
func extractTypeFromBase64Key(key string) (string, error) {
|
func extractTypeFromBase64Key(key string) (string, error) {
|
||||||
b, err := base64.StdEncoding.DecodeString(key)
|
b, err := base64.StdEncoding.DecodeString(key)
|
||||||
if err != nil || len(b) < 4 {
|
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))
|
keyLength := int(binary.BigEndian.Uint32(b))
|
||||||
|
@ -85,7 +85,7 @@ func parseKeyString(content string) (string, error) {
|
||||||
|
|
||||||
t, err := extractTypeFromBase64Key(keyContent)
|
t, err := extractTypeFromBase64Key(keyContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("extractTypeFromBase64Key: %v", err)
|
return "", fmt.Errorf("extractTypeFromBase64Key: %w", err)
|
||||||
}
|
}
|
||||||
keyType = t
|
keyType = t
|
||||||
} else {
|
} else {
|
||||||
|
@ -104,14 +104,14 @@ func parseKeyString(content string) (string, error) {
|
||||||
var pk rsa.PublicKey
|
var pk rsa.PublicKey
|
||||||
_, err2 := asn1.Unmarshal(block.Bytes, &pk)
|
_, err2 := asn1.Unmarshal(block.Bytes, &pk)
|
||||||
if err2 != nil {
|
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
|
pub = &pk
|
||||||
}
|
}
|
||||||
|
|
||||||
sshKey, err := ssh.NewPublicKey(pub)
|
sshKey, err := ssh.NewPublicKey(pub)
|
||||||
if err != nil {
|
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))
|
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.
|
// If keyType is not given, extract it from content. If given, validate it.
|
||||||
t, err := extractTypeFromBase64Key(keyContent)
|
t, err := extractTypeFromBase64Key(keyContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("extractTypeFromBase64Key: %v", err)
|
return "", fmt.Errorf("extractTypeFromBase64Key: %w", err)
|
||||||
}
|
}
|
||||||
if len(keyType) == 0 {
|
if len(keyType) == 0 {
|
||||||
keyType = t
|
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:
|
// Finally we need to check whether we can actually read the proposed key:
|
||||||
_, _, _, _, err := ssh.ParseAuthorizedKey([]byte(keyType + " " + keyContent + " " + keyComment))
|
_, _, _, _, err := ssh.ParseAuthorizedKey([]byte(keyType + " " + keyContent + " " + keyComment))
|
||||||
if err != nil {
|
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
|
return keyType + " " + keyContent + " " + keyComment, nil
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ func CheckPublicKeyString(content string) (_ string, err error) {
|
||||||
keyType, length, err = SSHKeyGenParsePublicKey(content)
|
keyType, length, err = SSHKeyGenParsePublicKey(content)
|
||||||
}
|
}
|
||||||
if err != nil {
|
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)
|
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") {
|
if strings.Contains(err.Error(), "ssh: unknown key algorithm") {
|
||||||
return "", 0, ErrKeyUnableVerify{err.Error()}
|
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.
|
// 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) {
|
func writeTmpKeyFile(content string) (string, error) {
|
||||||
tmpFile, err := os.CreateTemp(setting.SSH.KeyTestPath, "gitea_keytest")
|
tmpFile, err := os.CreateTemp(setting.SSH.KeyTestPath, "gitea_keytest")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("TempFile: %v", err)
|
return "", fmt.Errorf("TempFile: %w", err)
|
||||||
}
|
}
|
||||||
defer tmpFile.Close()
|
defer tmpFile.Close()
|
||||||
|
|
||||||
if _, err = tmpFile.WriteString(content); err != nil {
|
if _, err = tmpFile.WriteString(content); err != nil {
|
||||||
return "", fmt.Errorf("WriteString: %v", err)
|
return "", fmt.Errorf("WriteString: %w", err)
|
||||||
}
|
}
|
||||||
return tmpFile.Name(), nil
|
return tmpFile.Name(), nil
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ func writeTmpKeyFile(content string) (string, error) {
|
||||||
func SSHKeyGenParsePublicKey(key string) (string, int, error) {
|
func SSHKeyGenParsePublicKey(key string) (string, int, error) {
|
||||||
tmpName, err := writeTmpKeyFile(key)
|
tmpName, err := writeTmpKeyFile(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, fmt.Errorf("writeTmpKeyFile: %v", err)
|
return "", 0, fmt.Errorf("writeTmpKeyFile: %w", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := util.Remove(tmpName); err != nil {
|
if err := util.Remove(tmpName); err != nil {
|
||||||
|
|
|
@ -51,7 +51,7 @@ func AddPrincipalKey(ownerID int64, content string, authSourceID int64) (*Public
|
||||||
LoginSourceID: authSourceID,
|
LoginSourceID: authSourceID,
|
||||||
}
|
}
|
||||||
if err = db.Insert(ctx, key); err != nil {
|
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 {
|
if err = committer.Commit(); err != nil {
|
||||||
|
|
|
@ -31,9 +31,14 @@ type OAuth2Application struct {
|
||||||
Name string
|
Name string
|
||||||
ClientID string `xorm:"unique"`
|
ClientID string `xorm:"unique"`
|
||||||
ClientSecret string
|
ClientSecret string
|
||||||
RedirectURIs []string `xorm:"redirect_uris JSON TEXT"`
|
// OAuth defines both Confidential and Public client types
|
||||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
// https://datatracker.ietf.org/doc/html/rfc6749#section-2.1
|
||||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
// "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() {
|
func init() {
|
||||||
|
@ -57,15 +62,17 @@ func (app *OAuth2Application) PrimaryRedirectURI() string {
|
||||||
|
|
||||||
// ContainsRedirectURI checks if redirectURI is allowed for app
|
// ContainsRedirectURI checks if redirectURI is allowed for app
|
||||||
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
|
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
|
||||||
uri, err := url.Parse(redirectURI)
|
if !app.ConfidentialClient {
|
||||||
// ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
|
uri, err := url.Parse(redirectURI)
|
||||||
if err == nil && uri.Scheme == "http" && uri.Port() != "" {
|
// ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
|
||||||
ip := net.ParseIP(uri.Hostname())
|
if err == nil && uri.Scheme == "http" && uri.Port() != "" {
|
||||||
if ip != nil && ip.IsLoopback() {
|
ip := net.ParseIP(uri.Hostname())
|
||||||
// strip port
|
if ip != nil && ip.IsLoopback() {
|
||||||
uri.Host = uri.Hostname()
|
// strip port
|
||||||
if util.IsStringInSlice(uri.String(), app.RedirectURIs, true) {
|
uri.Host = uri.Hostname()
|
||||||
return true
|
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
|
// CreateOAuth2ApplicationOptions holds options to create an oauth2 application
|
||||||
type CreateOAuth2ApplicationOptions struct {
|
type CreateOAuth2ApplicationOptions struct {
|
||||||
Name string
|
Name string
|
||||||
UserID int64
|
UserID int64
|
||||||
RedirectURIs []string
|
ConfidentialClient bool
|
||||||
|
RedirectURIs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOAuth2Application inserts a new oauth2 application
|
// CreateOAuth2Application inserts a new oauth2 application
|
||||||
func CreateOAuth2Application(ctx context.Context, opts CreateOAuth2ApplicationOptions) (*OAuth2Application, error) {
|
func CreateOAuth2Application(ctx context.Context, opts CreateOAuth2ApplicationOptions) (*OAuth2Application, error) {
|
||||||
clientID := uuid.New().String()
|
clientID := uuid.New().String()
|
||||||
app := &OAuth2Application{
|
app := &OAuth2Application{
|
||||||
UID: opts.UserID,
|
UID: opts.UserID,
|
||||||
Name: opts.Name,
|
Name: opts.Name,
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
RedirectURIs: opts.RedirectURIs,
|
RedirectURIs: opts.RedirectURIs,
|
||||||
|
ConfidentialClient: opts.ConfidentialClient,
|
||||||
}
|
}
|
||||||
if err := db.Insert(ctx, app); err != nil {
|
if err := db.Insert(ctx, app); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -183,10 +192,11 @@ func CreateOAuth2Application(ctx context.Context, opts CreateOAuth2ApplicationOp
|
||||||
|
|
||||||
// UpdateOAuth2ApplicationOptions holds options to update an oauth2 application
|
// UpdateOAuth2ApplicationOptions holds options to update an oauth2 application
|
||||||
type UpdateOAuth2ApplicationOptions struct {
|
type UpdateOAuth2ApplicationOptions struct {
|
||||||
ID int64
|
ID int64
|
||||||
Name string
|
Name string
|
||||||
UserID int64
|
UserID int64
|
||||||
RedirectURIs []string
|
ConfidentialClient bool
|
||||||
|
RedirectURIs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOAuth2Application updates an oauth2 application
|
// UpdateOAuth2Application updates an oauth2 application
|
||||||
|
@ -207,6 +217,7 @@ func UpdateOAuth2Application(opts UpdateOAuth2ApplicationOptions) (*OAuth2Applic
|
||||||
|
|
||||||
app.Name = opts.Name
|
app.Name = opts.Name
|
||||||
app.RedirectURIs = opts.RedirectURIs
|
app.RedirectURIs = opts.RedirectURIs
|
||||||
|
app.ConfidentialClient = opts.ConfidentialClient
|
||||||
|
|
||||||
if err = updateOAuth2Application(ctx, app); err != nil {
|
if err = updateOAuth2Application(ctx, app); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -217,7 +228,7 @@ func UpdateOAuth2Application(opts UpdateOAuth2ApplicationOptions) (*OAuth2Applic
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateOAuth2Application(ctx context.Context, app *OAuth2Application) error {
|
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 err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -225,7 +236,8 @@ func updateOAuth2Application(ctx context.Context, app *OAuth2Application) error
|
||||||
|
|
||||||
func deleteOAuth2Application(ctx context.Context, id, userid int64) error {
|
func deleteOAuth2Application(ctx context.Context, id, userid int64) error {
|
||||||
sess := db.GetEngine(ctx)
|
sess := db.GetEngine(ctx)
|
||||||
if deleted, err := sess.Delete(&OAuth2Application{ID: id, UID: userid}); err != nil {
|
// the userid could be 0 if the app is instance-wide
|
||||||
|
if deleted, err := sess.Where(builder.Eq{"id": id, "uid": userid}).Delete(&OAuth2Application{}); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if deleted == 0 {
|
} else if deleted == 0 {
|
||||||
return ErrOAuthApplicationNotFound{ID: id}
|
return ErrOAuthApplicationNotFound{ID: id}
|
||||||
|
@ -476,7 +488,7 @@ func GetOAuth2GrantsByUserID(ctx context.Context, uid int64) ([]*OAuth2Grant, er
|
||||||
|
|
||||||
// RevokeOAuth2Grant deletes the grant with grantID and userID
|
// RevokeOAuth2Grant deletes the grant with grantID and userID
|
||||||
func RevokeOAuth2Grant(ctx context.Context, grantID, userID int64) error {
|
func RevokeOAuth2Grant(ctx context.Context, grantID, userID int64) error {
|
||||||
_, err := db.DeleteByBean(ctx, &OAuth2Grant{ID: grantID, UserID: userID})
|
_, err := db.GetEngine(ctx).Where(builder.Eq{"id": grantID, "user_id": userID}).Delete(&OAuth2Grant{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,7 +497,7 @@ type ErrOAuthClientIDInvalid struct {
|
||||||
ClientID string
|
ClientID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrOauthClientIDInvalid checks if an error is a ErrReviewNotExist.
|
// IsErrOauthClientIDInvalid checks if an error is a ErrOAuthClientIDInvalid.
|
||||||
func IsErrOauthClientIDInvalid(err error) bool {
|
func IsErrOauthClientIDInvalid(err error) bool {
|
||||||
_, ok := err.(ErrOAuthClientIDInvalid)
|
_, ok := err.(ErrOAuthClientIDInvalid)
|
||||||
return ok
|
return ok
|
||||||
|
@ -496,6 +508,11 @@ func (err ErrOAuthClientIDInvalid) Error() string {
|
||||||
return fmt.Sprintf("Client ID invalid [Client ID: %s]", err.ClientID)
|
return fmt.Sprintf("Client ID invalid [Client ID: %s]", err.ClientID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrNotExist err
|
||||||
|
func (err ErrOAuthClientIDInvalid) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrOAuthApplicationNotFound will be thrown if id cannot be found
|
// ErrOAuthApplicationNotFound will be thrown if id cannot be found
|
||||||
type ErrOAuthApplicationNotFound struct {
|
type ErrOAuthApplicationNotFound struct {
|
||||||
ID int64
|
ID int64
|
||||||
|
@ -512,6 +529,11 @@ func (err ErrOAuthApplicationNotFound) Error() string {
|
||||||
return fmt.Sprintf("OAuth application not found [ID: %d]", err.ID)
|
return fmt.Sprintf("OAuth application not found [ID: %d]", err.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrNotExist err
|
||||||
|
func (err ErrOAuthApplicationNotFound) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// GetActiveOAuth2ProviderSources returns all actived LoginOAuth2 sources
|
// GetActiveOAuth2ProviderSources returns all actived LoginOAuth2 sources
|
||||||
func GetActiveOAuth2ProviderSources() ([]*Source, error) {
|
func GetActiveOAuth2ProviderSources() ([]*Source, error) {
|
||||||
sources := make([]*Source, 0, 1)
|
sources := make([]*Source, 0, 1)
|
||||||
|
@ -548,7 +570,7 @@ func DeleteOAuth2RelictsByUserID(ctx context.Context, userID int64) error {
|
||||||
&OAuth2Application{UID: userID},
|
&OAuth2Application{UID: userID},
|
||||||
&OAuth2Grant{UserID: userID},
|
&OAuth2Grant{UserID: userID},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return fmt.Errorf("DeleteBeans: %v", err)
|
return fmt.Errorf("DeleteBeans: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -45,7 +45,8 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) {
|
||||||
|
|
||||||
func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
|
func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
|
||||||
app := &auth_model.OAuth2Application{
|
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
|
// http loopback uris should ignore port
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
"xorm.io/xorm/convert"
|
"xorm.io/xorm/convert"
|
||||||
|
@ -366,6 +367,11 @@ func (err ErrSourceNotExist) Error() string {
|
||||||
return fmt.Sprintf("login source does not exist [id: %d]", err.ID)
|
return fmt.Sprintf("login source does not exist [id: %d]", err.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrNotExist err
|
||||||
|
func (err ErrSourceNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrSourceAlreadyExist represents a "SourceAlreadyExist" kind of error.
|
// ErrSourceAlreadyExist represents a "SourceAlreadyExist" kind of error.
|
||||||
type ErrSourceAlreadyExist struct {
|
type ErrSourceAlreadyExist struct {
|
||||||
Name string
|
Name string
|
||||||
|
@ -381,6 +387,11 @@ func (err ErrSourceAlreadyExist) Error() string {
|
||||||
return fmt.Sprintf("login source already exists [name: %s]", err.Name)
|
return fmt.Sprintf("login source already exists [name: %s]", err.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrExist err
|
||||||
|
func (err ErrSourceAlreadyExist) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrSourceInUse represents a "SourceInUse" kind of error.
|
// ErrSourceInUse represents a "SourceInUse" kind of error.
|
||||||
type ErrSourceInUse struct {
|
type ErrSourceInUse struct {
|
||||||
ID int64
|
ID int64
|
||||||
|
|
|
@ -35,6 +35,10 @@ func (err ErrAccessTokenNotExist) Error() string {
|
||||||
return fmt.Sprintf("access token does not exist [sha: %s]", err.Token)
|
return fmt.Sprintf("access token does not exist [sha: %s]", err.Token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrAccessTokenNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error.
|
// ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error.
|
||||||
type ErrAccessTokenEmpty struct{}
|
type ErrAccessTokenEmpty struct{}
|
||||||
|
|
||||||
|
@ -48,6 +52,10 @@ func (err ErrAccessTokenEmpty) Error() string {
|
||||||
return "access token is empty"
|
return "access token is empty"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrAccessTokenEmpty) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
var successfulAccessTokenCache *lru.Cache
|
var successfulAccessTokenCache *lru.Cache
|
||||||
|
|
||||||
// AccessToken represents a personal access token.
|
// AccessToken represents a personal access token.
|
||||||
|
@ -79,7 +87,7 @@ func init() {
|
||||||
var err error
|
var err error
|
||||||
successfulAccessTokenCache, err = lru.New(setting.SuccessfulTokensCacheSize)
|
successfulAccessTokenCache, err = lru.New(setting.SuccessfulTokensCacheSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to allocate AccessToken cache: %v", err)
|
return fmt.Errorf("unable to allocate AccessToken cache: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
successfulAccessTokenCache = nil
|
successfulAccessTokenCache = nil
|
||||||
|
|
|
@ -41,6 +41,11 @@ func (err ErrTwoFactorNotEnrolled) Error() string {
|
||||||
return fmt.Sprintf("user not enrolled in 2FA [uid: %d]", err.UID)
|
return fmt.Sprintf("user not enrolled in 2FA [uid: %d]", err.UID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrNotExist err
|
||||||
|
func (err ErrTwoFactorNotEnrolled) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// TwoFactor represents a two-factor authentication token.
|
// TwoFactor represents a two-factor authentication token.
|
||||||
type TwoFactor struct {
|
type TwoFactor struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/duo-labs/webauthn/webauthn"
|
"github.com/duo-labs/webauthn/webauthn"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
|
@ -29,6 +30,11 @@ func (err ErrWebAuthnCredentialNotExist) Error() string {
|
||||||
return fmt.Sprintf("WebAuthn credential does not exist [credential_id: %x]", err.CredentialID)
|
return fmt.Sprintf("WebAuthn credential does not exist [credential_id: %x]", err.CredentialID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrNotExist err
|
||||||
|
func (err ErrWebAuthnCredentialNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// IsErrWebAuthnCredentialNotExist checks if an error is a ErrWebAuthnCredentialNotExist.
|
// IsErrWebAuthnCredentialNotExist checks if an error is a ErrWebAuthnCredentialNotExist.
|
||||||
func IsErrWebAuthnCredentialNotExist(err error) bool {
|
func IsErrWebAuthnCredentialNotExist(err error) bool {
|
||||||
_, ok := err.(ErrWebAuthnCredentialNotExist)
|
_, ok := err.(ErrWebAuthnCredentialNotExist)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
|
system_model "code.gitea.io/gitea/models/system"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/cache"
|
"code.gitea.io/gitea/modules/cache"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
@ -72,7 +73,7 @@ func GetEmailForHash(md5Sum string) (string, error) {
|
||||||
// LibravatarURL returns the URL for the given email. Slow due to the DNS lookup.
|
// LibravatarURL returns the URL for the given email. Slow due to the DNS lookup.
|
||||||
// This function should only be called if a federated avatar service is enabled.
|
// This function should only be called if a federated avatar service is enabled.
|
||||||
func LibravatarURL(email string) (*url.URL, error) {
|
func LibravatarURL(email string) (*url.URL, error) {
|
||||||
urlStr, err := setting.LibravatarService.FromEmail(email)
|
urlStr, err := system_model.LibravatarService.FromEmail(email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("LibravatarService.FromEmail(email=%s): error %v", email, err)
|
log.Error("LibravatarService.FromEmail(email=%s): error %v", email, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -149,8 +150,10 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
|
||||||
return DefaultAvatarLink()
|
return DefaultAvatarLink()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableFederatedAvatar, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
|
if enableFederatedAvatar != nil && enableFederatedAvatar.GetValueBool() && system_model.LibravatarService != nil {
|
||||||
emailHash := saveEmailHash(email)
|
emailHash := saveEmailHash(email)
|
||||||
if final {
|
if final {
|
||||||
// for final link, we can spend more time on slow external query
|
// for final link, we can spend more time on slow external query
|
||||||
|
@ -166,12 +169,16 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
|
||||||
urlStr += "?size=" + strconv.Itoa(size)
|
urlStr += "?size=" + strconv.Itoa(size)
|
||||||
}
|
}
|
||||||
return urlStr
|
return urlStr
|
||||||
} else if !setting.DisableGravatar {
|
}
|
||||||
|
|
||||||
|
disableGravatar, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar)
|
||||||
|
if disableGravatar != nil && !disableGravatar.GetValueBool() {
|
||||||
// copy GravatarSourceURL, because we will modify its Path.
|
// copy GravatarSourceURL, because we will modify its Path.
|
||||||
avatarURLCopy := *setting.GravatarSourceURL
|
avatarURLCopy := *system_model.GravatarSourceURL
|
||||||
avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email))
|
avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email))
|
||||||
return generateRecognizedAvatarURL(avatarURLCopy, size)
|
return generateRecognizedAvatarURL(avatarURLCopy, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefaultAvatarLink()
|
return DefaultAvatarLink()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package avatars
|
package avatars_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
avatars_model "code.gitea.io/gitea/models/avatars"
|
||||||
|
system_model "code.gitea.io/gitea/models/system"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -15,40 +16,43 @@ import (
|
||||||
|
|
||||||
const gravatarSource = "https://secure.gravatar.com/avatar/"
|
const gravatarSource = "https://secure.gravatar.com/avatar/"
|
||||||
|
|
||||||
func disableGravatar() {
|
func disableGravatar(t *testing.T) {
|
||||||
setting.EnableFederatedAvatar = false
|
err := system_model.SetSettingNoVersion(system_model.KeyPictureEnableFederatedAvatar, "false")
|
||||||
setting.LibravatarService = nil
|
assert.NoError(t, err)
|
||||||
setting.DisableGravatar = true
|
err = system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "true")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
system_model.LibravatarService = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func enableGravatar(t *testing.T) {
|
func enableGravatar(t *testing.T) {
|
||||||
setting.DisableGravatar = false
|
err := system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "false")
|
||||||
var err error
|
assert.NoError(t, err)
|
||||||
setting.GravatarSourceURL, err = url.Parse(gravatarSource)
|
setting.GravatarSource = gravatarSource
|
||||||
|
err = system_model.Init()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHashEmail(t *testing.T) {
|
func TestHashEmail(t *testing.T) {
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
"d41d8cd98f00b204e9800998ecf8427e",
|
"d41d8cd98f00b204e9800998ecf8427e",
|
||||||
HashEmail(""),
|
avatars_model.HashEmail(""),
|
||||||
)
|
)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
"353cbad9b58e69c96154ad99f92bedc7",
|
"353cbad9b58e69c96154ad99f92bedc7",
|
||||||
HashEmail("gitea@example.com"),
|
avatars_model.HashEmail("gitea@example.com"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSizedAvatarLink(t *testing.T) {
|
func TestSizedAvatarLink(t *testing.T) {
|
||||||
setting.AppSubURL = "/testsuburl"
|
setting.AppSubURL = "/testsuburl"
|
||||||
|
|
||||||
disableGravatar()
|
disableGravatar(t)
|
||||||
assert.Equal(t, "/testsuburl/assets/img/avatar_default.png",
|
assert.Equal(t, "/testsuburl/assets/img/avatar_default.png",
|
||||||
GenerateEmailAvatarFastLink("gitea@example.com", 100))
|
avatars_model.GenerateEmailAvatarFastLink("gitea@example.com", 100))
|
||||||
|
|
||||||
enableGravatar(t)
|
enableGravatar(t)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
"https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100",
|
"https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100",
|
||||||
GenerateEmailAvatarFastLink("gitea@example.com", 100),
|
avatars_model.GenerateEmailAvatarFastLink("gitea@example.com", 100),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package admin_test
|
package avatars_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
|
@ -130,7 +130,7 @@ func SyncAllTables() error {
|
||||||
func InitEngine(ctx context.Context) error {
|
func InitEngine(ctx context.Context) error {
|
||||||
xormEngine, err := newXORMEngine()
|
xormEngine, err := newXORMEngine()
|
||||||
if err != nil {
|
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{})
|
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,
|
// 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.
|
// as there may be other problems due to secret reinitialization.
|
||||||
if err = migrateFunc(x); err != nil {
|
if err = migrateFunc(x); err != nil {
|
||||||
return fmt.Errorf("migrate: %v", err)
|
return fmt.Errorf("migrate: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = SyncAllTables(); err != nil {
|
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 {
|
for _, initFunc := range initFuncs {
|
||||||
if err := initFunc(); err != nil {
|
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 {
|
for _, name := range names {
|
||||||
bean, ok := beanMap[strings.ToLower(strings.TrimSpace(name))]
|
bean, ok := beanMap[strings.ToLower(strings.TrimSpace(name))]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("No table found that matches: %s", name)
|
return nil, fmt.Errorf("no table found that matches: %s", name)
|
||||||
}
|
}
|
||||||
if !gotBean[bean] {
|
if !gotBean[bean] {
|
||||||
beans = append(beans, bean)
|
beans = append(beans, bean)
|
||||||
|
|
|
@ -6,6 +6,8 @@ package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrCancelled represents an error due to context cancellation
|
// ErrCancelled represents an error due to context cancellation
|
||||||
|
@ -45,7 +47,8 @@ func (err ErrSSHDisabled) Error() string {
|
||||||
|
|
||||||
// ErrNotExist represents a non-exist error.
|
// ErrNotExist represents a non-exist error.
|
||||||
type ErrNotExist struct {
|
type ErrNotExist struct {
|
||||||
ID int64
|
Resource string
|
||||||
|
ID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrNotExist checks if an error is an ErrNotExist
|
// IsErrNotExist checks if an error is an ErrNotExist
|
||||||
|
@ -55,5 +58,18 @@ func IsErrNotExist(err error) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (err ErrNotExist) Error() string {
|
func (err ErrNotExist) Error() string {
|
||||||
return fmt.Sprintf("record does not exist [id: %d]", err.ID)
|
name := "record"
|
||||||
|
if err.Resource != "" {
|
||||||
|
name = err.Resource
|
||||||
|
}
|
||||||
|
|
||||||
|
if err.ID != 0 {
|
||||||
|
return fmt.Sprintf("%s does not exist [id: %d]", name, err.ID)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s does not exist", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrNotExist err
|
||||||
|
func (err ErrNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,45 +8,15 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResourceIndex represents a resource index which could be used as issue/release and others
|
// ResourceIndex represents a resource index which could be used as issue/release and others
|
||||||
// We can create different tables i.e. issue_index, release_index and etc.
|
// We can create different tables i.e. issue_index, release_index, etc.
|
||||||
type ResourceIndex struct {
|
type ResourceIndex struct {
|
||||||
GroupID int64 `xorm:"pk"`
|
GroupID int64 `xorm:"pk"`
|
||||||
MaxIndex int64 `xorm:"index"`
|
MaxIndex int64 `xorm:"index"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpsertResourceIndex the function will not return until it acquires the lock or receives an error.
|
|
||||||
func UpsertResourceIndex(ctx context.Context, tableName string, groupID int64) (err error) {
|
|
||||||
// An atomic UPSERT operation (INSERT/UPDATE) is the only operation
|
|
||||||
// that ensures that the key is actually locked.
|
|
||||||
switch {
|
|
||||||
case setting.Database.UseSQLite3 || setting.Database.UsePostgreSQL:
|
|
||||||
_, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+
|
|
||||||
"VALUES (?,1) ON CONFLICT (group_id) DO UPDATE SET max_index = %s.max_index+1",
|
|
||||||
tableName, tableName), groupID)
|
|
||||||
case setting.Database.UseMySQL:
|
|
||||||
_, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+
|
|
||||||
"VALUES (?,1) ON DUPLICATE KEY UPDATE max_index = max_index+1", tableName),
|
|
||||||
groupID)
|
|
||||||
case setting.Database.UseMSSQL:
|
|
||||||
// https://weblogs.sqlteam.com/dang/2009/01/31/upsert-race-condition-with-merge/
|
|
||||||
_, err = Exec(ctx, fmt.Sprintf("MERGE %s WITH (HOLDLOCK) as target "+
|
|
||||||
"USING (SELECT ? AS group_id) AS src "+
|
|
||||||
"ON src.group_id = target.group_id "+
|
|
||||||
"WHEN MATCHED THEN UPDATE SET target.max_index = target.max_index+1 "+
|
|
||||||
"WHEN NOT MATCHED THEN INSERT (group_id, max_index) "+
|
|
||||||
"VALUES (src.group_id, 1);", tableName),
|
|
||||||
groupID)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("database type not supported")
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrResouceOutdated represents an error when request resource outdated
|
// ErrResouceOutdated represents an error when request resource outdated
|
||||||
ErrResouceOutdated = errors.New("resource outdated")
|
ErrResouceOutdated = errors.New("resource outdated")
|
||||||
|
@ -59,53 +29,85 @@ const (
|
||||||
MaxDupIndexAttempts = 3
|
MaxDupIndexAttempts = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetNextResourceIndex retried 3 times to generate a resource index
|
// SyncMaxResourceIndex sync the max index with the resource
|
||||||
func GetNextResourceIndex(tableName string, groupID int64) (int64, error) {
|
func SyncMaxResourceIndex(ctx context.Context, tableName string, groupID, maxIndex int64) (err error) {
|
||||||
for i := 0; i < MaxDupIndexAttempts; i++ {
|
e := GetEngine(ctx)
|
||||||
idx, err := getNextResourceIndex(tableName, groupID)
|
|
||||||
if err == ErrResouceOutdated {
|
// try to update the max_index and acquire the write-lock for the record
|
||||||
continue
|
res, err := e.Exec(fmt.Sprintf("UPDATE %s SET max_index=? WHERE group_id=? AND max_index<?", tableName), maxIndex, groupID, maxIndex)
|
||||||
}
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return idx, nil
|
|
||||||
}
|
}
|
||||||
return 0, ErrGetResourceIndexFailed
|
affected, err := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if affected == 0 {
|
||||||
|
// if nothing is updated, the record might not exist or might be larger, it's safe to try to insert it again and then check whether the record exists
|
||||||
|
_, errIns := e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) VALUES (?, ?)", tableName), groupID, maxIndex)
|
||||||
|
var savedIdx int64
|
||||||
|
has, err := e.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id=?", tableName), groupID).Get(&savedIdx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// if the record still doesn't exist, there must be some errors (insert error)
|
||||||
|
if !has {
|
||||||
|
if errIns == nil {
|
||||||
|
return errors.New("impossible error when SyncMaxResourceIndex, insert succeeded but no record is saved")
|
||||||
|
}
|
||||||
|
return errIns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResouceIndex delete resource index
|
// GetNextResourceIndex generates a resource index, it must run in the same transaction where the resource is created
|
||||||
func DeleteResouceIndex(ctx context.Context, tableName string, groupID int64) error {
|
func GetNextResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
|
||||||
_, err := Exec(ctx, fmt.Sprintf("DELETE FROM %s WHERE group_id=?", tableName), groupID)
|
e := GetEngine(ctx)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// getNextResourceIndex return the next index
|
// try to update the max_index to next value, and acquire the write-lock for the record
|
||||||
func getNextResourceIndex(tableName string, groupID int64) (int64, error) {
|
res, err := e.Exec(fmt.Sprintf("UPDATE %s SET max_index=max_index+1 WHERE group_id=?", tableName), groupID)
|
||||||
ctx, commiter, err := TxContext()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
defer commiter.Close()
|
affected, err := res.RowsAffected()
|
||||||
var preIdx int64
|
if err != nil {
|
||||||
if _, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&preIdx); err != nil {
|
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
if affected == 0 {
|
||||||
if err := UpsertResourceIndex(ctx, tableName, groupID); err != nil {
|
// this slow path is only for the first time of creating a resource index
|
||||||
return 0, err
|
_, errIns := e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) VALUES (?, 0)", tableName), groupID)
|
||||||
|
res, err = e.Exec(fmt.Sprintf("UPDATE %s SET max_index=max_index+1 WHERE group_id=?", tableName), groupID)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
affected, err = res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// if the update still can not update any records, the record must not exist and there must be some errors (insert error)
|
||||||
|
if affected == 0 {
|
||||||
|
if errIns == nil {
|
||||||
|
return 0, errors.New("impossible error when GetNextResourceIndex, insert and update both succeeded but no record is updated")
|
||||||
|
}
|
||||||
|
return 0, errIns
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var curIdx int64
|
// now, the new index is in database (protected by the transaction and write-lock)
|
||||||
has, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ? AND max_index=?", tableName), groupID, preIdx+1).Get(&curIdx)
|
var newIdx int64
|
||||||
|
has, err := e.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id=?", tableName), groupID).Get(&newIdx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if !has {
|
if !has {
|
||||||
return 0, ErrResouceOutdated
|
return 0, errors.New("impossible error when GetNextResourceIndex, upsert succeeded but no record can be selected")
|
||||||
}
|
}
|
||||||
if err := commiter.Commit(); err != nil {
|
return newIdx, nil
|
||||||
return 0, err
|
}
|
||||||
}
|
|
||||||
return curIdx, nil
|
// DeleteResourceIndex delete resource index
|
||||||
|
func DeleteResourceIndex(ctx context.Context, tableName string, groupID int64) error {
|
||||||
|
_, err := Exec(ctx, fmt.Sprintf("DELETE FROM %s WHERE group_id=?", tableName), groupID)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
127
models/db/index_test.go
Normal file
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
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrNameEmpty name is empty error
|
// ErrNameEmpty name is empty error
|
||||||
ErrNameEmpty = errors.New("Name is empty")
|
ErrNameEmpty = util.SilentWrap{Message: "name is empty", Err: util.ErrInvalidArgument}
|
||||||
|
|
||||||
// AlphaDashDotPattern characters prohibited in a user name (anything except A-Za-z0-9_.-)
|
// AlphaDashDotPattern characters prohibited in a user name (anything except A-Za-z0-9_.-)
|
||||||
AlphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
|
AlphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
|
||||||
|
@ -35,6 +36,11 @@ func (err ErrNameReserved) Error() string {
|
||||||
return fmt.Sprintf("name is reserved [name: %s]", err.Name)
|
return fmt.Sprintf("name is reserved [name: %s]", err.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrInvalid err
|
||||||
|
func (err ErrNameReserved) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// ErrNamePatternNotAllowed represents a "pattern not allowed" error.
|
// ErrNamePatternNotAllowed represents a "pattern not allowed" error.
|
||||||
type ErrNamePatternNotAllowed struct {
|
type ErrNamePatternNotAllowed struct {
|
||||||
Pattern string
|
Pattern string
|
||||||
|
@ -50,6 +56,11 @@ func (err ErrNamePatternNotAllowed) Error() string {
|
||||||
return fmt.Sprintf("name pattern is not allowed [pattern: %s]", err.Pattern)
|
return fmt.Sprintf("name pattern is not allowed [pattern: %s]", err.Pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrInvalid err
|
||||||
|
func (err ErrNamePatternNotAllowed) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// ErrNameCharsNotAllowed represents a "character not allowed in name" error.
|
// ErrNameCharsNotAllowed represents a "character not allowed in name" error.
|
||||||
type ErrNameCharsNotAllowed struct {
|
type ErrNameCharsNotAllowed struct {
|
||||||
Name string
|
Name string
|
||||||
|
@ -62,7 +73,12 @@ func IsErrNameCharsNotAllowed(err error) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (err ErrNameCharsNotAllowed) Error() string {
|
func (err ErrNameCharsNotAllowed) Error() string {
|
||||||
return fmt.Sprintf("User name is invalid [%s]: must be valid alpha or numeric or dash(-_) or dot characters", err.Name)
|
return fmt.Sprintf("name is invalid [%s]: must be valid alpha or numeric or dash(-_) or dot characters", err.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps this as a ErrInvalid err
|
||||||
|
func (err ErrNameCharsNotAllowed) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUsableName checks if name is reserved or pattern of name is not allowed
|
// IsUsableName checks if name is reserved or pattern of name is not allowed
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
|
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
|
||||||
|
@ -63,8 +64,8 @@ type ErrNoPendingRepoTransfer struct {
|
||||||
RepoID int64
|
RepoID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e ErrNoPendingRepoTransfer) Error() string {
|
func (err ErrNoPendingRepoTransfer) Error() string {
|
||||||
return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", e.RepoID)
|
return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", err.RepoID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrNoPendingTransfer is an error type when a repository has no pending
|
// IsErrNoPendingTransfer is an error type when a repository has no pending
|
||||||
|
@ -74,6 +75,10 @@ func IsErrNoPendingTransfer(err error) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrNoPendingRepoTransfer) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrRepoTransferInProgress represents the state of a repository that has an
|
// ErrRepoTransferInProgress represents the state of a repository that has an
|
||||||
// ongoing transfer
|
// ongoing transfer
|
||||||
type ErrRepoTransferInProgress struct {
|
type ErrRepoTransferInProgress struct {
|
||||||
|
@ -91,6 +96,10 @@ func (err ErrRepoTransferInProgress) Error() string {
|
||||||
return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name)
|
return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrRepoTransferInProgress) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
|
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
|
||||||
type ErrInvalidCloneAddr struct {
|
type ErrInvalidCloneAddr struct {
|
||||||
Host string
|
Host string
|
||||||
|
@ -124,6 +133,10 @@ func (err *ErrInvalidCloneAddr) Error() string {
|
||||||
return fmt.Sprintf("migration/cloning from '%s' is not allowed", err.Host)
|
return fmt.Sprintf("migration/cloning from '%s' is not allowed", err.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err *ErrInvalidCloneAddr) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// ErrUpdateTaskNotExist represents a "UpdateTaskNotExist" kind of error.
|
// ErrUpdateTaskNotExist represents a "UpdateTaskNotExist" kind of error.
|
||||||
type ErrUpdateTaskNotExist struct {
|
type ErrUpdateTaskNotExist struct {
|
||||||
UUID string
|
UUID string
|
||||||
|
@ -139,6 +152,10 @@ func (err ErrUpdateTaskNotExist) Error() string {
|
||||||
return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID)
|
return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrUpdateTaskNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrInvalidTagName represents a "InvalidTagName" kind of error.
|
// ErrInvalidTagName represents a "InvalidTagName" kind of error.
|
||||||
type ErrInvalidTagName struct {
|
type ErrInvalidTagName struct {
|
||||||
TagName string
|
TagName string
|
||||||
|
@ -154,6 +171,10 @@ func (err ErrInvalidTagName) Error() string {
|
||||||
return fmt.Sprintf("release tag name is not valid [tag_name: %s]", err.TagName)
|
return fmt.Sprintf("release tag name is not valid [tag_name: %s]", err.TagName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrInvalidTagName) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// ErrProtectedTagName represents a "ProtectedTagName" kind of error.
|
// ErrProtectedTagName represents a "ProtectedTagName" kind of error.
|
||||||
type ErrProtectedTagName struct {
|
type ErrProtectedTagName struct {
|
||||||
TagName string
|
TagName string
|
||||||
|
@ -169,6 +190,10 @@ func (err ErrProtectedTagName) Error() string {
|
||||||
return fmt.Sprintf("release tag name is protected [tag_name: %s]", err.TagName)
|
return fmt.Sprintf("release tag name is protected [tag_name: %s]", err.TagName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrProtectedTagName) Unwrap() error {
|
||||||
|
return util.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// ErrRepoFileAlreadyExists represents a "RepoFileAlreadyExist" kind of error.
|
// ErrRepoFileAlreadyExists represents a "RepoFileAlreadyExist" kind of error.
|
||||||
type ErrRepoFileAlreadyExists struct {
|
type ErrRepoFileAlreadyExists struct {
|
||||||
Path string
|
Path string
|
||||||
|
@ -184,6 +209,10 @@ func (err ErrRepoFileAlreadyExists) Error() string {
|
||||||
return fmt.Sprintf("repository file already exists [path: %s]", err.Path)
|
return fmt.Sprintf("repository file already exists [path: %s]", err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrRepoFileAlreadyExists) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrRepoFileDoesNotExist represents a "RepoFileDoesNotExist" kind of error.
|
// ErrRepoFileDoesNotExist represents a "RepoFileDoesNotExist" kind of error.
|
||||||
type ErrRepoFileDoesNotExist struct {
|
type ErrRepoFileDoesNotExist struct {
|
||||||
Path string
|
Path string
|
||||||
|
@ -200,6 +229,10 @@ func (err ErrRepoFileDoesNotExist) Error() string {
|
||||||
return fmt.Sprintf("repository file does not exist [path: %s]", err.Path)
|
return fmt.Sprintf("repository file does not exist [path: %s]", err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrRepoFileDoesNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrFilenameInvalid represents a "FilenameInvalid" kind of error.
|
// ErrFilenameInvalid represents a "FilenameInvalid" kind of error.
|
||||||
type ErrFilenameInvalid struct {
|
type ErrFilenameInvalid struct {
|
||||||
Path string
|
Path string
|
||||||
|
@ -215,6 +248,10 @@ func (err ErrFilenameInvalid) Error() string {
|
||||||
return fmt.Sprintf("path contains a malformed path component [path: %s]", err.Path)
|
return fmt.Sprintf("path contains a malformed path component [path: %s]", err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrFilenameInvalid) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// ErrUserCannotCommit represents "UserCannotCommit" kind of error.
|
// ErrUserCannotCommit represents "UserCannotCommit" kind of error.
|
||||||
type ErrUserCannotCommit struct {
|
type ErrUserCannotCommit struct {
|
||||||
UserName string
|
UserName string
|
||||||
|
@ -230,6 +267,10 @@ func (err ErrUserCannotCommit) Error() string {
|
||||||
return fmt.Sprintf("user cannot commit to repo [user: %s]", err.UserName)
|
return fmt.Sprintf("user cannot commit to repo [user: %s]", err.UserName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrUserCannotCommit) Unwrap() error {
|
||||||
|
return util.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// ErrFilePathInvalid represents a "FilePathInvalid" kind of error.
|
// ErrFilePathInvalid represents a "FilePathInvalid" kind of error.
|
||||||
type ErrFilePathInvalid struct {
|
type ErrFilePathInvalid struct {
|
||||||
Message string
|
Message string
|
||||||
|
@ -251,6 +292,10 @@ func (err ErrFilePathInvalid) Error() string {
|
||||||
return fmt.Sprintf("path is invalid [path: %s]", err.Path)
|
return fmt.Sprintf("path is invalid [path: %s]", err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrFilePathInvalid) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// ErrFilePathProtected represents a "FilePathProtected" kind of error.
|
// ErrFilePathProtected represents a "FilePathProtected" kind of error.
|
||||||
type ErrFilePathProtected struct {
|
type ErrFilePathProtected struct {
|
||||||
Message string
|
Message string
|
||||||
|
@ -270,6 +315,10 @@ func (err ErrFilePathProtected) Error() string {
|
||||||
return fmt.Sprintf("path is protected and can not be changed [path: %s]", err.Path)
|
return fmt.Sprintf("path is protected and can not be changed [path: %s]", err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrFilePathProtected) Unwrap() error {
|
||||||
|
return util.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// __________ .__
|
// __________ .__
|
||||||
// \______ \____________ ____ ____ | |__
|
// \______ \____________ ____ ____ | |__
|
||||||
// | | _/\_ __ \__ \ / \_/ ___\| | \
|
// | | _/\_ __ \__ \ / \_/ ___\| | \
|
||||||
|
@ -292,6 +341,10 @@ func (err ErrBranchDoesNotExist) Error() string {
|
||||||
return fmt.Sprintf("branch does not exist [name: %s]", err.BranchName)
|
return fmt.Sprintf("branch does not exist [name: %s]", err.BranchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrBranchDoesNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrBranchAlreadyExists represents an error that branch with such name already exists.
|
// ErrBranchAlreadyExists represents an error that branch with such name already exists.
|
||||||
type ErrBranchAlreadyExists struct {
|
type ErrBranchAlreadyExists struct {
|
||||||
BranchName string
|
BranchName string
|
||||||
|
@ -307,6 +360,10 @@ func (err ErrBranchAlreadyExists) Error() string {
|
||||||
return fmt.Sprintf("branch already exists [name: %s]", err.BranchName)
|
return fmt.Sprintf("branch already exists [name: %s]", err.BranchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrBranchAlreadyExists) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrBranchNameConflict represents an error that branch name conflicts with other branch.
|
// ErrBranchNameConflict represents an error that branch name conflicts with other branch.
|
||||||
type ErrBranchNameConflict struct {
|
type ErrBranchNameConflict struct {
|
||||||
BranchName string
|
BranchName string
|
||||||
|
@ -322,6 +379,10 @@ func (err ErrBranchNameConflict) Error() string {
|
||||||
return fmt.Sprintf("branch conflicts with existing branch [name: %s]", err.BranchName)
|
return fmt.Sprintf("branch conflicts with existing branch [name: %s]", err.BranchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrBranchNameConflict) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrBranchesEqual represents an error that branch name conflicts with other branch.
|
// ErrBranchesEqual represents an error that branch name conflicts with other branch.
|
||||||
type ErrBranchesEqual struct {
|
type ErrBranchesEqual struct {
|
||||||
BaseBranchName string
|
BaseBranchName string
|
||||||
|
@ -338,6 +399,10 @@ func (err ErrBranchesEqual) Error() string {
|
||||||
return fmt.Sprintf("branches are equal [head: %sm base: %s]", err.HeadBranchName, err.BaseBranchName)
|
return fmt.Sprintf("branches are equal [head: %sm base: %s]", err.HeadBranchName, err.BaseBranchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrBranchesEqual) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// ErrDisallowedToMerge represents an error that a branch is protected and the current user is not allowed to modify it.
|
// ErrDisallowedToMerge represents an error that a branch is protected and the current user is not allowed to modify it.
|
||||||
type ErrDisallowedToMerge struct {
|
type ErrDisallowedToMerge struct {
|
||||||
Reason string
|
Reason string
|
||||||
|
@ -353,6 +418,10 @@ func (err ErrDisallowedToMerge) Error() string {
|
||||||
return fmt.Sprintf("not allowed to merge [reason: %s]", err.Reason)
|
return fmt.Sprintf("not allowed to merge [reason: %s]", err.Reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrDisallowedToMerge) Unwrap() error {
|
||||||
|
return util.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// ErrTagAlreadyExists represents an error that tag with such name already exists.
|
// ErrTagAlreadyExists represents an error that tag with such name already exists.
|
||||||
type ErrTagAlreadyExists struct {
|
type ErrTagAlreadyExists struct {
|
||||||
TagName string
|
TagName string
|
||||||
|
@ -368,6 +437,10 @@ func (err ErrTagAlreadyExists) Error() string {
|
||||||
return fmt.Sprintf("tag already exists [name: %s]", err.TagName)
|
return fmt.Sprintf("tag already exists [name: %s]", err.TagName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrTagAlreadyExists) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrSHADoesNotMatch represents a "SHADoesNotMatch" kind of error.
|
// ErrSHADoesNotMatch represents a "SHADoesNotMatch" kind of error.
|
||||||
type ErrSHADoesNotMatch struct {
|
type ErrSHADoesNotMatch struct {
|
||||||
Path string
|
Path string
|
||||||
|
@ -400,6 +473,10 @@ func (err ErrSHANotFound) Error() string {
|
||||||
return fmt.Sprintf("sha not found [%s]", err.SHA)
|
return fmt.Sprintf("sha not found [%s]", err.SHA)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrSHANotFound) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrCommitIDDoesNotMatch represents a "CommitIDDoesNotMatch" kind of error.
|
// ErrCommitIDDoesNotMatch represents a "CommitIDDoesNotMatch" kind of error.
|
||||||
type ErrCommitIDDoesNotMatch struct {
|
type ErrCommitIDDoesNotMatch struct {
|
||||||
GivenCommitID string
|
GivenCommitID string
|
||||||
|
@ -446,6 +523,10 @@ func (err ErrInvalidMergeStyle) Error() string {
|
||||||
err.ID, err.Style)
|
err.ID, err.Style)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrInvalidMergeStyle) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// ErrMergeConflicts represents an error if merging fails with a conflict
|
// ErrMergeConflicts represents an error if merging fails with a conflict
|
||||||
type ErrMergeConflicts struct {
|
type ErrMergeConflicts struct {
|
||||||
Style repo_model.MergeStyle
|
Style repo_model.MergeStyle
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
issue_id: 1
|
issue_id: 1
|
||||||
|
release_id: 0
|
||||||
|
uploader_id: 0
|
||||||
comment_id: 0
|
comment_id: 0
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -13,9 +16,12 @@
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12
|
||||||
repo_id: 2
|
repo_id: 2
|
||||||
issue_id: 4
|
issue_id: 4
|
||||||
|
release_id: 0
|
||||||
|
uploader_id: 0
|
||||||
comment_id: 0
|
comment_id: 0
|
||||||
name: attach2
|
name: attach2
|
||||||
download_count: 1
|
download_count: 1
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -23,9 +29,12 @@
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a13
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a13
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
issue_id: 2
|
issue_id: 2
|
||||||
|
release_id: 0
|
||||||
|
uploader_id: 0
|
||||||
comment_id: 1
|
comment_id: 1
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -33,9 +42,12 @@
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
issue_id: 3
|
issue_id: 3
|
||||||
|
release_id: 0
|
||||||
|
uploader_id: 0
|
||||||
comment_id: 1
|
comment_id: 1
|
||||||
name: attach2
|
name: attach2
|
||||||
download_count: 1
|
download_count: 1
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -43,9 +55,12 @@
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a15
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a15
|
||||||
repo_id: 2
|
repo_id: 2
|
||||||
issue_id: 4
|
issue_id: 4
|
||||||
|
release_id: 0
|
||||||
|
uploader_id: 0
|
||||||
comment_id: 0
|
comment_id: 0
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -53,9 +68,12 @@
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a16
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a16
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
issue_id: 5
|
issue_id: 5
|
||||||
|
release_id: 0
|
||||||
|
uploader_id: 0
|
||||||
comment_id: 2
|
comment_id: 2
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -63,9 +81,12 @@
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
issue_id: 5
|
issue_id: 5
|
||||||
|
release_id: 0
|
||||||
|
uploader_id: 0
|
||||||
comment_id: 2
|
comment_id: 2
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -73,34 +94,49 @@
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18
|
||||||
repo_id: 3
|
repo_id: 3
|
||||||
issue_id: 6
|
issue_id: 6
|
||||||
|
release_id: 0
|
||||||
|
uploader_id: 0
|
||||||
comment_id: 0
|
comment_id: 0
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 9
|
id: 9
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a19
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a19
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
|
issue_id: 0
|
||||||
release_id: 1
|
release_id: 1
|
||||||
|
uploader_id: 0
|
||||||
|
comment_id: 0
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 10
|
id: 10
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a20
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a20
|
||||||
repo_id: 0 # TestGetAttachment/NotLinked
|
repo_id: 0 # TestGetAttachment/NotLinked
|
||||||
|
issue_id: 0
|
||||||
|
release_id: 0
|
||||||
uploader_id: 8
|
uploader_id: 8
|
||||||
|
comment_id: 0
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 11
|
id: 11
|
||||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a21
|
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a21
|
||||||
repo_id: 40
|
repo_id: 40
|
||||||
|
issue_id: 0
|
||||||
release_id: 2
|
release_id: 2
|
||||||
|
uploader_id: 0
|
||||||
|
comment_id: 0
|
||||||
name: attach1
|
name: attach1
|
||||||
download_count: 0
|
download_count: 0
|
||||||
|
size: 0
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
-
|
-
|
||||||
id: 1
|
id: 1
|
||||||
repo_id: 1
|
|
||||||
hook_id: 1
|
hook_id: 1
|
||||||
uuid: uuid1
|
uuid: uuid1
|
||||||
is_delivered: true
|
is_delivered: true
|
||||||
|
|
|
@ -3,208 +3,287 @@
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 1
|
poster_id: 1
|
||||||
|
original_author_id: 0
|
||||||
name: issue1
|
name: issue1
|
||||||
content: content for the first issue
|
content: content for the first issue
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
num_comments: 2
|
num_comments: 2
|
||||||
created_unix: 946684800
|
created_unix: 946684800
|
||||||
updated_unix: 978307200
|
updated_unix: 978307200
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 2
|
id: 2
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
index: 2
|
index: 2
|
||||||
poster_id: 1
|
poster_id: 1
|
||||||
|
original_author_id: 0
|
||||||
name: issue2
|
name: issue2
|
||||||
content: content for the second issue
|
content: content for the second issue
|
||||||
milestone_id: 1
|
milestone_id: 1
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: true
|
is_pull: true
|
||||||
|
num_comments: 0
|
||||||
created_unix: 946684810
|
created_unix: 946684810
|
||||||
updated_unix: 978307190
|
updated_unix: 978307190
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 3
|
id: 3
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
index: 3
|
index: 3
|
||||||
poster_id: 1
|
poster_id: 1
|
||||||
|
original_author_id: 0
|
||||||
name: issue3
|
name: issue3
|
||||||
content: content for the third issue
|
content: content for the third issue
|
||||||
milestone_id: 3
|
milestone_id: 3
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: true
|
is_pull: true
|
||||||
|
num_comments: 0
|
||||||
created_unix: 946684820
|
created_unix: 946684820
|
||||||
updated_unix: 978307180
|
updated_unix: 978307180
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 4
|
id: 4
|
||||||
repo_id: 2
|
repo_id: 2
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 2
|
poster_id: 2
|
||||||
|
original_author_id: 0
|
||||||
name: issue4
|
name: issue4
|
||||||
content: content for the fourth issue
|
content: content for the fourth issue
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: true
|
is_closed: true
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
created_unix: 946684830
|
created_unix: 946684830
|
||||||
updated_unix: 978307200
|
updated_unix: 978307200
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 5
|
id: 5
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
index: 4
|
index: 4
|
||||||
poster_id: 2
|
poster_id: 2
|
||||||
|
original_author_id: 0
|
||||||
name: issue5
|
name: issue5
|
||||||
content: content for the fifth issue
|
content: content for the fifth issue
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: true
|
is_closed: true
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
created_unix: 946684840
|
created_unix: 946684840
|
||||||
updated_unix: 978307200
|
updated_unix: 978307200
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 6
|
id: 6
|
||||||
repo_id: 3
|
repo_id: 3
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 1
|
poster_id: 1
|
||||||
|
original_author_id: 0
|
||||||
name: issue6
|
name: issue6
|
||||||
content: content6
|
content: content6
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
num_comments: 0
|
num_comments: 0
|
||||||
created_unix: 946684850
|
created_unix: 946684850
|
||||||
updated_unix: 978307200
|
updated_unix: 978307200
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 7
|
id: 7
|
||||||
repo_id: 2
|
repo_id: 2
|
||||||
index: 2
|
index: 2
|
||||||
poster_id: 2
|
poster_id: 2
|
||||||
|
original_author_id: 0
|
||||||
name: issue7
|
name: issue7
|
||||||
content: content for the seventh issue
|
content: content for the seventh issue
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
created_unix: 946684830
|
created_unix: 946684830
|
||||||
updated_unix: 978307200
|
updated_unix: 978307200
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 8
|
id: 8
|
||||||
repo_id: 10
|
repo_id: 10
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 11
|
poster_id: 11
|
||||||
|
original_author_id: 0
|
||||||
name: pr2
|
name: pr2
|
||||||
content: a pull request
|
content: a pull request
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: true
|
is_pull: true
|
||||||
|
num_comments: 0
|
||||||
created_unix: 946684820
|
created_unix: 946684820
|
||||||
updated_unix: 978307180
|
updated_unix: 978307180
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 9
|
id: 9
|
||||||
repo_id: 48
|
repo_id: 48
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 11
|
poster_id: 11
|
||||||
|
original_author_id: 0
|
||||||
name: pr1
|
name: pr1
|
||||||
content: a pull request
|
content: a pull request
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: true
|
is_pull: true
|
||||||
|
num_comments: 0
|
||||||
created_unix: 946684820
|
created_unix: 946684820
|
||||||
updated_unix: 978307180
|
updated_unix: 978307180
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 10
|
id: 10
|
||||||
repo_id: 42
|
repo_id: 42
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 500
|
poster_id: 500
|
||||||
|
original_author_id: 0
|
||||||
name: issue from deleted account
|
name: issue from deleted account
|
||||||
content: content from deleted account
|
content: content from deleted account
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
|
deadline_unix: 1019307200
|
||||||
created_unix: 946684830
|
created_unix: 946684830
|
||||||
updated_unix: 999307200
|
updated_unix: 999307200
|
||||||
deadline_unix: 1019307200
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 11
|
id: 11
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
index: 5
|
index: 5
|
||||||
poster_id: 1
|
poster_id: 1
|
||||||
|
original_author_id: 0
|
||||||
name: pull5
|
name: pull5
|
||||||
content: content for the a pull request
|
content: content for the a pull request
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: true
|
is_pull: true
|
||||||
|
num_comments: 0
|
||||||
created_unix: 1579194806
|
created_unix: 1579194806
|
||||||
updated_unix: 1579194806
|
updated_unix: 1579194806
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 12
|
id: 12
|
||||||
repo_id: 3
|
repo_id: 3
|
||||||
index: 2
|
index: 2
|
||||||
poster_id: 2
|
poster_id: 2
|
||||||
|
original_author_id: 0
|
||||||
name: pull6
|
name: pull6
|
||||||
content: content for the a pull request
|
content: content for the a pull request
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: true
|
is_pull: true
|
||||||
|
num_comments: 0
|
||||||
created_unix: 1602935696
|
created_unix: 1602935696
|
||||||
updated_unix: 1602935696
|
updated_unix: 1602935696
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 13
|
id: 13
|
||||||
repo_id: 50
|
repo_id: 50
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 2
|
poster_id: 2
|
||||||
|
original_author_id: 0
|
||||||
name: issue in active repo
|
name: issue in active repo
|
||||||
content: we'll be testing github issue 13171 with this.
|
content: we'll be testing github issue 13171 with this.
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
created_unix: 1602935696
|
created_unix: 1602935696
|
||||||
updated_unix: 1602935696
|
updated_unix: 1602935696
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 14
|
id: 14
|
||||||
repo_id: 51
|
repo_id: 51
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 2
|
poster_id: 2
|
||||||
|
original_author_id: 0
|
||||||
name: issue in archived repo
|
name: issue in archived repo
|
||||||
content: we'll be testing github issue 13171 with this.
|
content: we'll be testing github issue 13171 with this.
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
created_unix: 1602935696
|
created_unix: 1602935696
|
||||||
updated_unix: 1602935696
|
updated_unix: 1602935696
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 15
|
id: 15
|
||||||
repo_id: 5
|
repo_id: 5
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 2
|
poster_id: 2
|
||||||
|
original_author_id: 0
|
||||||
name: issue in repo not linked to team1
|
name: issue in repo not linked to team1
|
||||||
content: content
|
content: content
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
created_unix: 1602935696
|
created_unix: 1602935696
|
||||||
updated_unix: 1602935696
|
updated_unix: 1602935696
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 16
|
id: 16
|
||||||
repo_id: 32
|
repo_id: 32
|
||||||
index: 1
|
index: 1
|
||||||
poster_id: 2
|
poster_id: 2
|
||||||
|
original_author_id: 0
|
||||||
name: just a normal issue
|
name: just a normal issue
|
||||||
content: content
|
content: content
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
created_unix: 1602935696
|
created_unix: 1602935696
|
||||||
updated_unix: 1602935696
|
updated_unix: 1602935696
|
||||||
|
is_locked: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 17
|
id: 17
|
||||||
repo_id: 32
|
repo_id: 32
|
||||||
index: 2
|
index: 2
|
||||||
poster_id: 15
|
poster_id: 15
|
||||||
|
original_author_id: 0
|
||||||
name: a issue with a assignment
|
name: a issue with a assignment
|
||||||
content: content
|
content: content
|
||||||
|
milestone_id: 0
|
||||||
|
priority: 0
|
||||||
is_closed: false
|
is_closed: false
|
||||||
is_pull: false
|
is_pull: false
|
||||||
|
num_comments: 0
|
||||||
created_unix: 1602935696
|
created_unix: 1602935696
|
||||||
updated_unix: 1602935696
|
updated_unix: 1602935696
|
||||||
|
is_locked: false
|
||||||
|
|
|
@ -15,10 +15,11 @@
|
||||||
color: '#000000'
|
color: '#000000'
|
||||||
num_issues: 1
|
num_issues: 1
|
||||||
num_closed_issues: 1
|
num_closed_issues: 1
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 3
|
id: 3
|
||||||
repo_id: 0
|
repo_id: 0
|
||||||
org_id: 3
|
org_id: 3
|
||||||
name: orglabel3
|
name: orglabel3
|
||||||
color: '#abcdef'
|
color: '#abcdef'
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
|
@ -32,7 +33,7 @@
|
||||||
color: '#000000'
|
color: '#000000'
|
||||||
num_issues: 1
|
num_issues: 1
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 5
|
id: 5
|
||||||
repo_id: 10
|
repo_id: 10
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
is_closed: false
|
is_closed: false
|
||||||
num_issues: 1
|
num_issues: 1
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
completeness: 0
|
||||||
deadline_unix: 253370764800
|
deadline_unix: 253370764800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
is_closed: false
|
is_closed: false
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
completeness: 0
|
||||||
deadline_unix: 253370764800
|
deadline_unix: 253370764800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -26,6 +28,7 @@
|
||||||
is_closed: true
|
is_closed: true
|
||||||
num_issues: 1
|
num_issues: 1
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
completeness: 0
|
||||||
deadline_unix: 253370764800
|
deadline_unix: 253370764800
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -36,14 +39,16 @@
|
||||||
is_closed: false
|
is_closed: false
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
completeness: 0
|
||||||
deadline_unix: 253370764800
|
deadline_unix: 253370764800
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 5
|
id: 5
|
||||||
repo_id: 10
|
repo_id: 10
|
||||||
name: milestone of repo 10
|
name: milestone of repo 10
|
||||||
content: for testing with PRs
|
content: for testing with PRs
|
||||||
is_closed: false
|
is_closed: false
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
completeness: 0
|
||||||
deadline_unix: 253370764800
|
deadline_unix: 253370764800
|
||||||
|
|
|
@ -4,6 +4,17 @@
|
||||||
name: "Test"
|
name: "Test"
|
||||||
client_id: "da7da3ba-9a13-4167-856f-3899de0b0138"
|
client_id: "da7da3ba-9a13-4167-856f-3899de0b0138"
|
||||||
client_secret: "$2a$10$UYRgUSgekzBp6hYe8pAdc.cgB4Gn06QRKsORUnIYTYQADs.YR/uvi" # bcrypt of "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=
|
client_secret: "$2a$10$UYRgUSgekzBp6hYe8pAdc.cgB4Gn06QRKsORUnIYTYQADs.YR/uvi" # bcrypt of "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=
|
||||||
redirect_uris: '["a"]'
|
redirect_uris: '["a", "https://example.com/xyzzy"]'
|
||||||
created_unix: 1546869730
|
created_unix: 1546869730
|
||||||
updated_unix: 1546869730
|
updated_unix: 1546869730
|
||||||
|
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"
|
redirect_uri: "a"
|
||||||
valid_until: 3546869730
|
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
|
counter: 1
|
||||||
scope: "openid profile email"
|
scope: "openid profile email"
|
||||||
created_unix: 1546869730
|
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
|
authorize: 4 # owner
|
||||||
num_repos: 3
|
num_repos: 3
|
||||||
num_members: 1
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: true
|
can_create_org_repo: true
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
authorize: 2 # write
|
authorize: 2 # write
|
||||||
num_repos: 1
|
num_repos: 1
|
||||||
num_members: 2
|
num_members: 2
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: false
|
can_create_org_repo: false
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -26,6 +28,7 @@
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 0
|
num_repos: 0
|
||||||
num_members: 1
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: true
|
can_create_org_repo: true
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -36,6 +39,7 @@
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 0
|
num_repos: 0
|
||||||
num_members: 1
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: true
|
can_create_org_repo: true
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -46,6 +50,7 @@
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 2
|
num_repos: 2
|
||||||
num_members: 2
|
num_members: 2
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: true
|
can_create_org_repo: true
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -56,6 +61,7 @@
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 2
|
num_repos: 2
|
||||||
num_members: 2
|
num_members: 2
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: true
|
can_create_org_repo: true
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -66,6 +72,7 @@
|
||||||
authorize: 2 # write
|
authorize: 2 # write
|
||||||
num_repos: 1
|
num_repos: 1
|
||||||
num_members: 1
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: false
|
can_create_org_repo: false
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -76,6 +83,7 @@
|
||||||
authorize: 2 # write
|
authorize: 2 # write
|
||||||
num_repos: 1
|
num_repos: 1
|
||||||
num_members: 1
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: false
|
can_create_org_repo: false
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -86,6 +94,7 @@
|
||||||
authorize: 1 # read
|
authorize: 1 # read
|
||||||
num_repos: 1
|
num_repos: 1
|
||||||
num_members: 2
|
num_members: 2
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: false
|
can_create_org_repo: false
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -93,9 +102,10 @@
|
||||||
org_id: 25
|
org_id: 25
|
||||||
lower_name: notowners
|
lower_name: notowners
|
||||||
name: NotOwners
|
name: NotOwners
|
||||||
authorize: 1 # owner
|
authorize: 1 # read
|
||||||
num_repos: 0
|
num_repos: 0
|
||||||
num_members: 1
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: false
|
can_create_org_repo: false
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -106,6 +116,7 @@
|
||||||
authorize: 1 # read
|
authorize: 1 # read
|
||||||
num_repos: 0
|
num_repos: 0
|
||||||
num_members: 0
|
num_members: 0
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: false
|
can_create_org_repo: false
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -116,6 +127,7 @@
|
||||||
authorize: 3 # admin
|
authorize: 3 # admin
|
||||||
num_repos: 0
|
num_repos: 0
|
||||||
num_members: 1
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: true
|
can_create_org_repo: true
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -126,4 +138,5 @@
|
||||||
authorize: 3 # admin
|
authorize: 3 # admin
|
||||||
num_repos: 0
|
num_repos: 0
|
||||||
num_members: 1
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
can_create_org_repo: false
|
can_create_org_repo: false
|
||||||
|
|
|
@ -8,18 +8,22 @@
|
||||||
name: database
|
name: database
|
||||||
repo_count: 1
|
repo_count: 1
|
||||||
|
|
||||||
- id: 3
|
-
|
||||||
|
id: 3
|
||||||
name: SQL
|
name: SQL
|
||||||
repo_count: 1
|
repo_count: 1
|
||||||
|
|
||||||
- id: 4
|
-
|
||||||
|
id: 4
|
||||||
name: graphql
|
name: graphql
|
||||||
repo_count: 1
|
repo_count: 1
|
||||||
|
|
||||||
- id: 5
|
-
|
||||||
|
id: 5
|
||||||
name: topicname1
|
name: topicname1
|
||||||
repo_count: 1
|
repo_count: 1
|
||||||
|
|
||||||
- id: 6
|
-
|
||||||
|
id: 6
|
||||||
name: topicname2
|
name: topicname2
|
||||||
repo_count: 2
|
repo_count: 2
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,6 @@
|
||||||
- id: 1
|
-
|
||||||
name: "WebAuthn credential"
|
id: 1
|
||||||
|
name: WebAuthn credential
|
||||||
user_id: 32
|
user_id: 32
|
||||||
attestation_type: none
|
attestation_type: none
|
||||||
sign_count: 0
|
sign_count: 0
|
||||||
|
|
|
@ -6,6 +6,8 @@ package foreignreference
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrLocalIndexNotExist represents a "LocalIndexNotExist" kind of error.
|
// ErrLocalIndexNotExist represents a "LocalIndexNotExist" kind of error.
|
||||||
|
@ -25,6 +27,10 @@ func (err ErrLocalIndexNotExist) Error() string {
|
||||||
return fmt.Sprintf("repository %d has no LocalIndex for ForeignIndex %d of type %s", err.RepoID, err.ForeignIndex, err.Type)
|
return fmt.Sprintf("repository %d has no LocalIndex for ForeignIndex %d of type %s", err.RepoID, err.ForeignIndex, err.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrLocalIndexNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrForeignIndexNotExist represents a "ForeignIndexNotExist" kind of error.
|
// ErrForeignIndexNotExist represents a "ForeignIndexNotExist" kind of error.
|
||||||
type ErrForeignIndexNotExist struct {
|
type ErrForeignIndexNotExist struct {
|
||||||
RepoID int64
|
RepoID int64
|
||||||
|
@ -41,3 +47,7 @@ func IsErrForeignIndexNotExist(err error) bool {
|
||||||
func (err ErrForeignIndexNotExist) Error() string {
|
func (err ErrForeignIndexNotExist) Error() string {
|
||||||
return fmt.Sprintf("repository %d has no ForeignIndex for LocalIndex %d of type %s", err.RepoID, err.LocalIndex, err.Type)
|
return fmt.Sprintf("repository %d has no ForeignIndex for LocalIndex %d of type %s", err.RepoID, err.LocalIndex, err.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrForeignIndexNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
|
@ -270,7 +270,7 @@ type WhitelistOptions struct {
|
||||||
// to avoid unnecessary whitelist delete and regenerate.
|
// to avoid unnecessary whitelist delete and regenerate.
|
||||||
func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, protectBranch *ProtectedBranch, opts WhitelistOptions) (err error) {
|
func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, protectBranch *ProtectedBranch, opts WhitelistOptions) (err error) {
|
||||||
if err = repo.GetOwner(ctx); err != nil {
|
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)
|
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
|
// Make sure protectBranch.ID is not 0 for whitelists
|
||||||
if protectBranch.ID == 0 {
|
if protectBranch.ID == 0 {
|
||||||
if _, err = db.GetEngine(ctx).Insert(protectBranch); err != nil {
|
if _, err = db.GetEngine(ctx).Insert(protectBranch); err != nil {
|
||||||
return fmt.Errorf("Insert: %v", err)
|
return fmt.Errorf("Insert: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = db.GetEngine(ctx).ID(protectBranch.ID).AllCols().Update(protectBranch); err != 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
|
return nil
|
||||||
|
@ -378,11 +378,11 @@ func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, curre
|
||||||
for _, userID := range newWhitelist {
|
for _, userID := range newWhitelist {
|
||||||
user, err := user_model.GetUserByIDCtx(ctx, userID)
|
user, err := user_model.GetUserByIDCtx(ctx, userID)
|
||||||
if err != nil {
|
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)
|
perm, err := access_model.GetUserRepoPermission(ctx, repo, user)
|
||||||
if err != nil {
|
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) {
|
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)
|
teams, err := organization.GetTeamsWithAccessToRepo(ctx, repo.OwnerID, repo.ID, perm.AccessModeRead)
|
||||||
if err != nil {
|
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))
|
whitelist = make([]int64, 0, len(teams))
|
||||||
|
|
|
@ -128,13 +128,13 @@ func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) {
|
||||||
if status.Repo == nil {
|
if status.Repo == nil {
|
||||||
status.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, status.RepoID)
|
status.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, status.RepoID)
|
||||||
if err != nil {
|
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 {
|
if status.Creator == nil && status.CreatorID > 0 {
|
||||||
status.Creator, err = user_model.GetUserByIDCtx(ctx, status.CreatorID)
|
status.Creator, err = user_model.GetUserByIDCtx(ctx, status.CreatorID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getUserByID [%d]: %v", status.CreatorID, err)
|
return fmt.Errorf("getUserByID [%d]: %w", status.CreatorID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -294,12 +294,12 @@ func NewCommitStatus(opts NewCommitStatusOptions) error {
|
||||||
// Get the next Status Index
|
// Get the next Status Index
|
||||||
idx, err := GetNextCommitStatusIndex(opts.Repo.ID, opts.SHA)
|
idx, err := GetNextCommitStatusIndex(opts.Repo.ID, opts.SHA)
|
||||||
if err != nil {
|
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()
|
ctx, committer, err := db.TxContext()
|
||||||
if err != nil {
|
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()
|
defer committer.Close()
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ func NewCommitStatus(opts NewCommitStatusOptions) error {
|
||||||
|
|
||||||
// Insert new CommitStatus
|
// Insert new CommitStatus
|
||||||
if _, err = db.GetEngine(ctx).Insert(opts.CommitStatus); err != nil {
|
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()
|
return committer.Commit()
|
||||||
|
|
|
@ -6,7 +6,6 @@ package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
|
@ -17,6 +16,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/lfs"
|
"code.gitea.io/gitea/modules/lfs"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
@ -38,6 +38,10 @@ func (err ErrLFSLockNotExist) Error() string {
|
||||||
return fmt.Sprintf("lfs lock does not exist [id: %d, rid: %d, path: %s]", err.ID, err.RepoID, err.Path)
|
return fmt.Sprintf("lfs lock does not exist [id: %d, rid: %d, path: %s]", err.ID, err.RepoID, err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrLFSLockNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error.
|
// ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error.
|
||||||
type ErrLFSUnauthorizedAction struct {
|
type ErrLFSUnauthorizedAction struct {
|
||||||
RepoID int64
|
RepoID int64
|
||||||
|
@ -58,6 +62,10 @@ func (err ErrLFSUnauthorizedAction) Error() string {
|
||||||
return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID)
|
return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrLFSUnauthorizedAction) Unwrap() error {
|
||||||
|
return util.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error.
|
// ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error.
|
||||||
type ErrLFSLockAlreadyExist struct {
|
type ErrLFSLockAlreadyExist struct {
|
||||||
RepoID int64
|
RepoID int64
|
||||||
|
@ -74,6 +82,10 @@ func (err ErrLFSLockAlreadyExist) Error() string {
|
||||||
return fmt.Sprintf("lfs lock already exists [rid: %d, path: %s]", err.RepoID, err.Path)
|
return fmt.Sprintf("lfs lock already exists [rid: %d, path: %s]", err.RepoID, err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrLFSLockAlreadyExist) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrLFSFileLocked represents a "LFSFileLocked" kind of error.
|
// ErrLFSFileLocked represents a "LFSFileLocked" kind of error.
|
||||||
type ErrLFSFileLocked struct {
|
type ErrLFSFileLocked struct {
|
||||||
RepoID int64
|
RepoID int64
|
||||||
|
@ -91,6 +103,10 @@ func (err ErrLFSFileLocked) Error() string {
|
||||||
return fmt.Sprintf("File is lfs locked [repo: %d, locked by: %s, path: %s]", err.RepoID, err.UserName, err.Path)
|
return fmt.Sprintf("File is lfs locked [repo: %d, locked by: %s, path: %s]", err.RepoID, err.UserName, err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrLFSFileLocked) Unwrap() error {
|
||||||
|
return util.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// LFSMetaObject stores metadata for LFS tracked files.
|
// LFSMetaObject stores metadata for LFS tracked files.
|
||||||
type LFSMetaObject struct {
|
type LFSMetaObject struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
@ -114,7 +130,7 @@ type LFSTokenResponse struct {
|
||||||
|
|
||||||
// ErrLFSObjectNotExist is returned from lfs models functions in order
|
// ErrLFSObjectNotExist is returned from lfs models functions in order
|
||||||
// to differentiate between database and missing object errors.
|
// to differentiate between database and missing object errors.
|
||||||
var ErrLFSObjectNotExist = errors.New("LFS Meta object does not exist")
|
var ErrLFSObjectNotExist = db.ErrNotExist{Resource: "LFS Meta object"}
|
||||||
|
|
||||||
// NewLFSMetaObject stores a given populated LFSMetaObject structure in the database
|
// NewLFSMetaObject stores a given populated LFSMetaObject structure in the database
|
||||||
// if it is not already present.
|
// if it is not already present.
|
||||||
|
@ -300,7 +316,7 @@ func CopyLFS(ctx context.Context, newRepo, oldRepo *repo_model.Repository) error
|
||||||
func GetRepoLFSSize(ctx context.Context, repoID int64) (int64, error) {
|
func GetRepoLFSSize(ctx context.Context, repoID int64) (int64, error) {
|
||||||
lfsSize, err := db.GetEngine(ctx).Where("repository_id = ?", repoID).SumInt(new(LFSMetaObject), "size")
|
lfsSize, err := db.GetEngine(ctx).Where("repository_id = ?", repoID).SumInt(new(LFSMetaObject), "size")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("updateSize: GetLFSMetaObjects: %v", err)
|
return 0, fmt.Errorf("updateSize: GetLFSMetaObjects: %w", err)
|
||||||
}
|
}
|
||||||
return lfsSize, nil
|
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) {
|
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)
|
removed, err = toggleUserAssignee(ctx, issue, assigneeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, fmt.Errorf("UpdateIssueUserByAssignee: %v", err)
|
return false, nil, fmt.Errorf("UpdateIssueUserByAssignee: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repo infos
|
// Repo infos
|
||||||
if err = issue.LoadRepo(ctx); err != nil {
|
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{
|
opts := &CreateCommentOptions{
|
||||||
|
@ -104,7 +104,7 @@ func toggleIssueAssignee(ctx context.Context, issue *Issue, doer *user_model.Use
|
||||||
// Comment
|
// Comment
|
||||||
comment, err = CreateCommentCtx(ctx, opts)
|
comment, err = CreateCommentCtx(ctx, opts)
|
||||||
if err != nil {
|
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
|
// 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/references"
|
||||||
"code.gitea.io/gitea/modules/structs"
|
"code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
|
@ -49,6 +50,10 @@ func (err ErrCommentNotExist) Error() string {
|
||||||
return fmt.Sprintf("comment does not exist [id: %d, issue_id: %d]", err.ID, err.IssueID)
|
return fmt.Sprintf("comment does not exist [id: %d, issue_id: %d]", err.ID, err.IssueID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrCommentNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
|
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
|
||||||
type CommentType int
|
type CommentType int
|
||||||
|
|
||||||
|
@ -568,13 +573,13 @@ func (c *Comment) UpdateAttachments(uuids []string) error {
|
||||||
|
|
||||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids)
|
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids)
|
||||||
if err != nil {
|
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++ {
|
for i := 0; i < len(attachments); i++ {
|
||||||
attachments[i].IssueID = c.IssueID
|
attachments[i].IssueID = c.IssueID
|
||||||
attachments[i].CommentID = c.ID
|
attachments[i].CommentID = c.ID
|
||||||
if err := repo_model.UpdateAttachment(ctx, attachments[i]); err != nil {
|
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()
|
return committer.Commit()
|
||||||
|
@ -869,7 +874,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
|
||||||
// Check attachments
|
// Check attachments
|
||||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
|
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
|
||||||
if err != nil {
|
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 {
|
for i := range attachments {
|
||||||
|
@ -877,11 +882,11 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
|
||||||
attachments[i].CommentID = comment.ID
|
attachments[i].CommentID = comment.ID
|
||||||
// No assign value could be 0, so ignore AllCols().
|
// No assign value could be 0, so ignore AllCols().
|
||||||
if _, err = db.GetEngine(ctx).ID(attachments[i].ID).Update(attachments[i]); err != nil {
|
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:
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1029,7 +1034,7 @@ func CreateRefComment(doer *user_model.User, repo *repo_model.Repository, issue
|
||||||
CommitSHA: commitSHA,
|
CommitSHA: commitSHA,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("check reference comment: %v", err)
|
return fmt.Errorf("check reference comment: %w", err)
|
||||||
} else if has {
|
} else if has {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1147,7 +1152,7 @@ func UpdateComment(c *Comment, doer *user_model.User) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := committer.Commit(); err != nil {
|
if err := committer.Commit(); err != nil {
|
||||||
return fmt.Errorf("Commit: %v", err)
|
return fmt.Errorf("Commit: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -17,13 +17,11 @@ import (
|
||||||
type CommentList []*Comment
|
type CommentList []*Comment
|
||||||
|
|
||||||
func (comments CommentList) getPosterIDs() []int64 {
|
func (comments CommentList) getPosterIDs() []int64 {
|
||||||
posterIDs := make(map[int64]struct{}, len(comments))
|
posterIDs := make(container.Set[int64], len(comments))
|
||||||
for _, comment := range comments {
|
for _, comment := range comments {
|
||||||
if _, ok := posterIDs[comment.PosterID]; !ok {
|
posterIDs.Add(comment.PosterID)
|
||||||
posterIDs[comment.PosterID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(posterIDs)
|
return posterIDs.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) loadPosters(ctx context.Context) error {
|
func (comments CommentList) loadPosters(ctx context.Context) error {
|
||||||
|
@ -70,13 +68,11 @@ func (comments CommentList) getCommentIDs() []int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) getLabelIDs() []int64 {
|
func (comments CommentList) getLabelIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(comments))
|
ids := make(container.Set[int64], len(comments))
|
||||||
for _, comment := range comments {
|
for _, comment := range comments {
|
||||||
if _, ok := ids[comment.LabelID]; !ok {
|
ids.Add(comment.LabelID)
|
||||||
ids[comment.LabelID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
|
func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
|
||||||
|
@ -120,13 +116,11 @@ func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) getMilestoneIDs() []int64 {
|
func (comments CommentList) getMilestoneIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(comments))
|
ids := make(container.Set[int64], len(comments))
|
||||||
for _, comment := range comments {
|
for _, comment := range comments {
|
||||||
if _, ok := ids[comment.MilestoneID]; !ok {
|
ids.Add(comment.MilestoneID)
|
||||||
ids[comment.MilestoneID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) loadMilestones(ctx context.Context) error {
|
func (comments CommentList) loadMilestones(ctx context.Context) error {
|
||||||
|
@ -163,13 +157,11 @@ func (comments CommentList) loadMilestones(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) getOldMilestoneIDs() []int64 {
|
func (comments CommentList) getOldMilestoneIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(comments))
|
ids := make(container.Set[int64], len(comments))
|
||||||
for _, comment := range comments {
|
for _, comment := range comments {
|
||||||
if _, ok := ids[comment.OldMilestoneID]; !ok {
|
ids.Add(comment.OldMilestoneID)
|
||||||
ids[comment.OldMilestoneID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) loadOldMilestones(ctx context.Context) error {
|
func (comments CommentList) loadOldMilestones(ctx context.Context) error {
|
||||||
|
@ -206,13 +198,11 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) getAssigneeIDs() []int64 {
|
func (comments CommentList) getAssigneeIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(comments))
|
ids := make(container.Set[int64], len(comments))
|
||||||
for _, comment := range comments {
|
for _, comment := range comments {
|
||||||
if _, ok := ids[comment.AssigneeID]; !ok {
|
ids.Add(comment.AssigneeID)
|
||||||
ids[comment.AssigneeID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) loadAssignees(ctx context.Context) error {
|
func (comments CommentList) loadAssignees(ctx context.Context) error {
|
||||||
|
@ -259,16 +249,14 @@ func (comments CommentList) loadAssignees(ctx context.Context) error {
|
||||||
|
|
||||||
// getIssueIDs returns all the issue ids on this comment list which issue hasn't been loaded
|
// getIssueIDs returns all the issue ids on this comment list which issue hasn't been loaded
|
||||||
func (comments CommentList) getIssueIDs() []int64 {
|
func (comments CommentList) getIssueIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(comments))
|
ids := make(container.Set[int64], len(comments))
|
||||||
for _, comment := range comments {
|
for _, comment := range comments {
|
||||||
if comment.Issue != nil {
|
if comment.Issue != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := ids[comment.IssueID]; !ok {
|
ids.Add(comment.IssueID)
|
||||||
ids[comment.IssueID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issues returns all the issues of comments
|
// Issues returns all the issues of comments
|
||||||
|
@ -334,16 +322,14 @@ func (comments CommentList) loadIssues(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) getDependentIssueIDs() []int64 {
|
func (comments CommentList) getDependentIssueIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(comments))
|
ids := make(container.Set[int64], len(comments))
|
||||||
for _, comment := range comments {
|
for _, comment := range comments {
|
||||||
if comment.DependentIssue != nil {
|
if comment.DependentIssue != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := ids[comment.DependentIssueID]; !ok {
|
ids.Add(comment.DependentIssueID)
|
||||||
ids[comment.DependentIssueID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) loadDependentIssues(ctx context.Context) error {
|
func (comments CommentList) loadDependentIssues(ctx context.Context) error {
|
||||||
|
@ -439,13 +425,11 @@ func (comments CommentList) loadAttachments(ctx context.Context) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) getReviewIDs() []int64 {
|
func (comments CommentList) getReviewIDs() []int64 {
|
||||||
ids := make(map[int64]struct{}, len(comments))
|
ids := make(container.Set[int64], len(comments))
|
||||||
for _, comment := range comments {
|
for _, comment := range comments {
|
||||||
if _, ok := ids[comment.ReviewID]; !ok {
|
ids.Add(comment.ReviewID)
|
||||||
ids[comment.ReviewID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.KeysInt64(ids)
|
return ids.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (comments CommentList) loadReviews(ctx context.Context) error { //nolint
|
func (comments CommentList) loadReviews(ctx context.Context) error { //nolint
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
@ -201,6 +202,10 @@ func (err ErrIssueContentHistoryNotExist) Error() string {
|
||||||
return fmt.Sprintf("issue content history does not exist [id: %d]", err.ID)
|
return fmt.Sprintf("issue content history does not exist [id: %d]", err.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrIssueContentHistoryNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// GetIssueContentHistoryByID get issue content history
|
// GetIssueContentHistoryByID get issue content history
|
||||||
func GetIssueContentHistoryByID(dbCtx context.Context, id int64) (*ContentHistory, error) {
|
func GetIssueContentHistoryByID(dbCtx context.Context, id int64) (*ContentHistory, error) {
|
||||||
h := &ContentHistory{}
|
h := &ContentHistory{}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrDependencyExists represents a "DependencyAlreadyExists" kind of error.
|
// ErrDependencyExists represents a "DependencyAlreadyExists" kind of error.
|
||||||
|
@ -29,6 +30,10 @@ func (err ErrDependencyExists) Error() string {
|
||||||
return fmt.Sprintf("issue dependency does already exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID)
|
return fmt.Sprintf("issue dependency does already exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrDependencyExists) Unwrap() error {
|
||||||
|
return util.ErrAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error.
|
// ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error.
|
||||||
type ErrDependencyNotExists struct {
|
type ErrDependencyNotExists struct {
|
||||||
IssueID int64
|
IssueID int64
|
||||||
|
@ -45,6 +50,10 @@ func (err ErrDependencyNotExists) Error() string {
|
||||||
return fmt.Sprintf("issue dependency does not exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID)
|
return fmt.Sprintf("issue dependency does not exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrDependencyNotExists) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrCircularDependency represents a "DependencyCircular" kind of error.
|
// ErrCircularDependency represents a "DependencyCircular" kind of error.
|
||||||
type ErrCircularDependency struct {
|
type ErrCircularDependency struct {
|
||||||
IssueID int64
|
IssueID int64
|
||||||
|
@ -91,6 +100,10 @@ func (err ErrUnknownDependencyType) Error() string {
|
||||||
return fmt.Sprintf("unknown dependency type [type: %d]", err.Type)
|
return fmt.Sprintf("unknown dependency type [type: %d]", err.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrUnknownDependencyType) Unwrap() error {
|
||||||
|
return util.ErrInvalidArgument
|
||||||
|
}
|
||||||
|
|
||||||
// IssueDependency represents an issue dependency
|
// IssueDependency represents an issue dependency
|
||||||
type IssueDependency struct {
|
type IssueDependency struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
admin_model "code.gitea.io/gitea/models/admin"
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/models/foreignreference"
|
"code.gitea.io/gitea/models/foreignreference"
|
||||||
"code.gitea.io/gitea/models/organization"
|
"code.gitea.io/gitea/models/organization"
|
||||||
|
@ -21,6 +20,7 @@ import (
|
||||||
access_model "code.gitea.io/gitea/models/perm/access"
|
access_model "code.gitea.io/gitea/models/perm/access"
|
||||||
project_model "code.gitea.io/gitea/models/project"
|
project_model "code.gitea.io/gitea/models/project"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
system_model "code.gitea.io/gitea/models/system"
|
||||||
"code.gitea.io/gitea/models/unit"
|
"code.gitea.io/gitea/models/unit"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
|
@ -52,6 +52,10 @@ func (err ErrIssueNotExist) Error() string {
|
||||||
return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index)
|
return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err ErrIssueNotExist) Unwrap() error {
|
||||||
|
return util.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// ErrIssueIsClosed represents a "IssueIsClosed" kind of error.
|
// ErrIssueIsClosed represents a "IssueIsClosed" kind of error.
|
||||||
type ErrIssueIsClosed struct {
|
type ErrIssueIsClosed struct {
|
||||||
ID int64
|
ID int64
|
||||||
|
@ -192,7 +196,7 @@ func (issue *Issue) LoadRepo(ctx context.Context) (err error) {
|
||||||
if issue.Repo == nil {
|
if issue.Repo == nil {
|
||||||
issue.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, issue.RepoID)
|
issue.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, issue.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getRepositoryByID [%d]: %v", issue.RepoID, err)
|
return fmt.Errorf("getRepositoryByID [%d]: %w", issue.RepoID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -230,7 +234,7 @@ func (issue *Issue) LoadLabels(ctx context.Context) (err error) {
|
||||||
if issue.Labels == nil {
|
if issue.Labels == nil {
|
||||||
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
|
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getLabelsByIssueID [%d]: %v", issue.ID, err)
|
return fmt.Errorf("getLabelsByIssueID [%d]: %w", issue.ID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -248,7 +252,7 @@ func (issue *Issue) loadPoster(ctx context.Context) (err error) {
|
||||||
issue.PosterID = -1
|
issue.PosterID = -1
|
||||||
issue.Poster = user_model.NewGhostUser()
|
issue.Poster = user_model.NewGhostUser()
|
||||||
if !user_model.IsErrUserNotExist(err) {
|
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
|
err = nil
|
||||||
return
|
return
|
||||||
|
@ -264,7 +268,7 @@ func (issue *Issue) loadPullRequest(ctx context.Context) (err error) {
|
||||||
if IsErrPullRequestNotExist(err) {
|
if IsErrPullRequestNotExist(err) {
|
||||||
return 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
|
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 {
|
if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
|
||||||
issue.Milestone, err = GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID)
|
issue.Milestone, err = GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID)
|
||||||
if err != nil && !IsErrMilestoneNotExist(err) {
|
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
|
return nil
|
||||||
|
@ -397,7 +401,7 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
|
||||||
if issue.Attachments == nil {
|
if issue.Attachments == nil {
|
||||||
issue.Attachments, err = repo_model.GetAttachmentsByIssueID(ctx, issue.ID)
|
issue.Attachments, err = repo_model.GetAttachmentsByIssueID(ctx, issue.ID)
|
||||||
if err != nil {
|
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)
|
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getLabelsByIssueID: %v", err)
|
return fmt.Errorf("getLabelsByIssueID: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearIssueLabels(ctx context.Context, issue *Issue, doer *user_model.User) (err error) {
|
func clearIssueLabels(ctx context.Context, issue *Issue, doer *user_model.User) (err error) {
|
||||||
if err = issue.getLabels(ctx); err != nil {
|
if err = issue.getLabels(ctx); err != nil {
|
||||||
return fmt.Errorf("getLabels: %v", err)
|
return fmt.Errorf("getLabels: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range issue.Labels {
|
for i := range issue.Labels {
|
||||||
if err = deleteIssueLabel(ctx, issue, issue.Labels[i], doer); err != nil {
|
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 {
|
if err = committer.Commit(); err != nil {
|
||||||
return fmt.Errorf("Commit: %v", err)
|
return fmt.Errorf("Commit: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -631,13 +635,13 @@ func ReplaceIssueLabels(issue *Issue, labels []*Label, doer *user_model.User) (e
|
||||||
|
|
||||||
if len(toAdd) > 0 {
|
if len(toAdd) > 0 {
|
||||||
if err = newIssueLabels(ctx, issue, toAdd, doer); err != nil {
|
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 {
|
for _, l := range toRemove {
|
||||||
if err = deleteIssueLabel(ctx, issue, l, doer); err != nil {
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,11 +767,11 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
if err = UpdateIssueCols(ctx, issue, "name"); err != nil {
|
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 {
|
if err = issue.LoadRepo(ctx); err != nil {
|
||||||
return fmt.Errorf("loadRepo: %v", err)
|
return fmt.Errorf("loadRepo: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := &CreateCommentOptions{
|
opts := &CreateCommentOptions{
|
||||||
|
@ -778,7 +783,7 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err
|
||||||
NewTitle: issue.Title,
|
NewTitle: issue.Title,
|
||||||
}
|
}
|
||||||
if _, err = CreateCommentCtx(ctx, opts); err != nil {
|
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 {
|
if err = issue.AddCrossReferences(ctx, doer, true); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -796,11 +801,11 @@ func ChangeIssueRef(issue *Issue, doer *user_model.User, oldRef string) (err err
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
if err = UpdateIssueCols(ctx, issue, "ref"); err != nil {
|
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 {
|
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)
|
oldRefFriendly := strings.TrimPrefix(oldRef, git.BranchPrefix)
|
||||||
newRefFriendly := strings.TrimPrefix(issue.Ref, 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,
|
NewRef: newRefFriendly,
|
||||||
}
|
}
|
||||||
if _, err = CreateCommentCtx(ctx, opts); err != nil {
|
if _, err = CreateCommentCtx(ctx, opts); err != nil {
|
||||||
return fmt.Errorf("createComment: %v", err)
|
return fmt.Errorf("createComment: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return committer.Commit()
|
return committer.Commit()
|
||||||
|
@ -846,12 +851,12 @@ func UpdateIssueAttachments(issueID int64, uuids []string) (err error) {
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids)
|
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids)
|
||||||
if err != nil {
|
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++ {
|
for i := 0; i < len(attachments); i++ {
|
||||||
attachments[i].IssueID = issueID
|
attachments[i].IssueID = issueID
|
||||||
if err := repo_model.UpdateAttachment(ctx, attachments[i]); err != nil {
|
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()
|
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)
|
hasContentHistory, err := HasIssueContentHistory(ctx, issue.ID, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("HasIssueContentHistory: %v", err)
|
return fmt.Errorf("HasIssueContentHistory: %w", err)
|
||||||
}
|
}
|
||||||
if !hasContentHistory {
|
if !hasContentHistory {
|
||||||
if err = SaveIssueContentHistory(ctx, issue.PosterID, issue.ID, 0,
|
if err = SaveIssueContentHistory(ctx, issue.PosterID, issue.ID, 0,
|
||||||
issue.CreatedUnix, issue.Content, true); err != nil {
|
issue.CreatedUnix, issue.Content, true); err != nil {
|
||||||
return fmt.Errorf("SaveIssueContentHistory: %v", err)
|
return fmt.Errorf("SaveIssueContentHistory: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue.Content = content
|
issue.Content = content
|
||||||
|
|
||||||
if err = UpdateIssueCols(ctx, issue, "content"); err != nil {
|
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,
|
if err = SaveIssueContentHistory(ctx, doer.ID, issue.ID, 0,
|
||||||
timeutil.TimeStampNow(), issue.Content, false); err != nil {
|
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 {
|
if err = issue.AddCrossReferences(ctx, doer, true); err != nil {
|
||||||
return fmt.Errorf("addCrossReferences: %v", err)
|
return fmt.Errorf("addCrossReferences: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return committer.Commit()
|
return committer.Commit()
|
||||||
|
@ -965,7 +970,7 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
|
||||||
if opts.Issue.MilestoneID > 0 {
|
if opts.Issue.MilestoneID > 0 {
|
||||||
milestone, err := GetMilestoneByRepoID(ctx, opts.Issue.RepoID, opts.Issue.MilestoneID)
|
milestone, err := GetMilestoneByRepoID(ctx, opts.Issue.RepoID, opts.Issue.MilestoneID)
|
||||||
if err != nil && !IsErrMilestoneNotExist(err) {
|
if err != nil && !IsErrMilestoneNotExist(err) {
|
||||||
return fmt.Errorf("getMilestoneByID: %v", err)
|
return fmt.Errorf("getMilestoneByID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume milestone is invalid and drop silently.
|
// 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.
|
// So we have to get all needed labels first.
|
||||||
labels := make([]*Label, 0, len(opts.LabelIDs))
|
labels := make([]*Label, 0, len(opts.LabelIDs))
|
||||||
if err = e.In("id", opts.LabelIDs).Find(&labels); err != nil {
|
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 {
|
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 {
|
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 {
|
if len(opts.Attachments) > 0 {
|
||||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
|
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
|
||||||
if err != nil {
|
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++ {
|
for i := 0; i < len(attachments); i++ {
|
||||||
attachments[i].IssueID = opts.Issue.ID
|
attachments[i].IssueID = opts.Issue.ID
|
||||||
if _, err = e.ID(attachments[i].ID).Update(attachments[i]); err != nil {
|
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.
|
// NewIssue creates new issue with labels for repository.
|
||||||
func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
|
func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
|
||||||
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("generate issue index failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
issue.Index = idx
|
|
||||||
|
|
||||||
ctx, committer, err := db.TxContext()
|
ctx, committer, err := db.TxContext()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
|
idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("generate issue index failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
issue.Index = idx
|
||||||
|
|
||||||
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
|
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
Issue: issue,
|
Issue: issue,
|
||||||
|
@ -1086,11 +1091,11 @@ func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids
|
||||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
|
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return fmt.Errorf("newIssue: %v", err)
|
return fmt.Errorf("newIssue: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = committer.Commit(); err != nil {
|
if err = committer.Commit(); err != nil {
|
||||||
return fmt.Errorf("Commit: %v", err)
|
return fmt.Errorf("Commit: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -1492,7 +1497,8 @@ func applySubscribedCondition(sess *xorm.Session, subscriberID int64) *xorm.Sess
|
||||||
builder.In("issue.repo_id", builder.
|
builder.In("issue.repo_id", builder.
|
||||||
Select("id").
|
Select("id").
|
||||||
From("watch").
|
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
|
ids[i] = u.ID
|
||||||
}
|
}
|
||||||
if err := UpdateIssueUsersByMentions(ctx, issueID, ids); err != nil {
|
if err := UpdateIssueUsersByMentions(ctx, issueID, ids); err != nil {
|
||||||
return fmt.Errorf("UpdateIssueUsersByMentions: %v", err)
|
return fmt.Errorf("UpdateIssueUsersByMentions: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1987,7 +1993,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
if err := issue.LoadRepo(ctx); err != nil {
|
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
|
// Reload the issue
|
||||||
|
@ -2015,7 +2021,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment
|
||||||
}
|
}
|
||||||
_, err := CreateCommentCtx(ctx, opts)
|
_, err := CreateCommentCtx(ctx, opts)
|
||||||
if err != nil {
|
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
|
// Make the comment
|
||||||
if _, err = createDeadlineComment(ctx, doer, issue, deadlineUnix); err != nil {
|
if _, err = createDeadlineComment(ctx, doer, issue, deadlineUnix); err != nil {
|
||||||
return fmt.Errorf("createRemovedDueDateComment: %v", err)
|
return fmt.Errorf("createRemovedDueDateComment: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return committer.Commit()
|
return committer.Commit()
|
||||||
|
@ -2088,7 +2094,7 @@ func (issue *Issue) GetParticipantIDsByIssue(ctx context.Context) ([]int64, erro
|
||||||
Join("INNER", "`user`", "`user`.id = `comment`.poster_id").
|
Join("INNER", "`user`", "`user`.id = `comment`.poster_id").
|
||||||
Distinct("poster_id").
|
Distinct("poster_id").
|
||||||
Find(&userIDs); err != nil {
|
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) {
|
if !util.IsInt64InSlice(issue.PosterID, userIDs) {
|
||||||
return append(userIDs, issue.PosterID), nil
|
return append(userIDs, issue.PosterID), nil
|
||||||
|
@ -2132,24 +2138,15 @@ func (issue *Issue) BlockingDependencies(ctx context.Context) (issueDeps []*Depe
|
||||||
return issueDeps, err
|
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.
|
// 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) {
|
func FindAndUpdateIssueMentions(ctx context.Context, issue *Issue, doer *user_model.User, content string) (mentions []*user_model.User, err error) {
|
||||||
rawMentions := references.FindAllMentionsMarkdown(content)
|
rawMentions := references.FindAllMentionsMarkdown(content)
|
||||||
mentions, err = ResolveIssueMentionsByVisibility(ctx, issue, doer, rawMentions)
|
mentions, err = ResolveIssueMentionsByVisibility(ctx, issue, doer, rawMentions)
|
||||||
if err != nil {
|
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 {
|
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
|
return mentions, err
|
||||||
}
|
}
|
||||||
|
@ -2201,7 +2198,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
||||||
Where("team_repo.repo_id=?", issue.Repo.ID).
|
Where("team_repo.repo_id=?", issue.Repo.ID).
|
||||||
In("team.lower_name", mentionTeams).
|
In("team.lower_name", mentionTeams).
|
||||||
Find(&teams); err != nil {
|
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 {
|
if len(teams) != 0 {
|
||||||
checked := make([]int64, 0, len(teams))
|
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})
|
has, err := db.GetEngine(ctx).Get(&organization.TeamUnit{OrgID: issue.Repo.Owner.ID, TeamID: team.ID, Type: unittype})
|
||||||
if err != nil {
|
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 {
|
if has {
|
||||||
checked = append(checked, team.ID)
|
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`.is_active = ?", true).
|
||||||
And("`user`.prohibit_login = ?", false).
|
And("`user`.prohibit_login = ?", false).
|
||||||
Find(&teamusers); err != nil {
|
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 {
|
if len(teamusers) > 0 {
|
||||||
users = make([]*user_model.User, 0, len(teamusers))
|
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).
|
And("`user`.prohibit_login = ?", false).
|
||||||
In("`user`.lower_name", mentionUsers).
|
In("`user`.lower_name", mentionUsers).
|
||||||
Find(&unchecked); err != nil {
|
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 {
|
for _, user := range unchecked {
|
||||||
if already := resolved[user.LowerName]; already || user.IsOrganization() {
|
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
|
// Normal users must have read access to the referencing issue
|
||||||
perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, user)
|
perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, user)
|
||||||
if err != nil {
|
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) {
|
if !perm.CanReadIssuesOrPulls(issue.IsPull) {
|
||||||
continue
|
continue
|
||||||
|
@ -2470,7 +2467,7 @@ func DeleteOrphanedIssues() error {
|
||||||
|
|
||||||
// Remove issue attachment files.
|
// Remove issue attachment files.
|
||||||
for i := range attachmentPaths {
|
for i := range attachmentPaths {
|
||||||
admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i])
|
system_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,12 @@ func RecalculateIssueIndexForRepo(repoID int64) error {
|
||||||
}
|
}
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
if err := db.UpsertResourceIndex(ctx, "issue_index", repoID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var max int64
|
var max int64
|
||||||
if _, err := db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil {
|
if _, err = db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := db.GetEngine(ctx).Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil {
|
if err = db.SyncMaxResourceIndex(ctx, "issue_index", repoID, max); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue