Merge branch 'main' into lunny/glob_protected_branch_rule
This commit is contained in:
commit
80d2396b61
479 changed files with 14860 additions and 9489 deletions
28
.drone.yml
28
.drone.yml
|
@ -100,7 +100,7 @@ steps:
|
|||
- name: checks-backend
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- make checks-backend
|
||||
- make --always-make checks-backend # ensure the 'go-licenses' make target runs
|
||||
depends_on: [deps-backend]
|
||||
volumes:
|
||||
- name: deps
|
||||
|
@ -112,16 +112,11 @@ steps:
|
|||
- make test-frontend
|
||||
depends_on: [lint-frontend]
|
||||
|
||||
- name: generate-frontend
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- make generate-frontend
|
||||
|
||||
- name: build-frontend
|
||||
image: node:18
|
||||
commands:
|
||||
- make frontend
|
||||
depends_on: [deps-frontend, generate-frontend]
|
||||
depends_on: [deps-frontend]
|
||||
|
||||
- name: build-backend-no-gcc
|
||||
image: golang:1.18 # this step is kept as the lowest version of golang that we support
|
||||
|
@ -549,16 +544,11 @@ steps:
|
|||
commands:
|
||||
- make deps-frontend
|
||||
|
||||
- name: generate-frontend
|
||||
image: golang:1.18
|
||||
commands:
|
||||
- make generate-frontend
|
||||
|
||||
- name: build-frontend
|
||||
image: node:18
|
||||
commands:
|
||||
- make frontend
|
||||
depends_on: [deps-frontend, generate-frontend]
|
||||
depends_on: [deps-frontend]
|
||||
|
||||
- name: deps-backend
|
||||
image: golang:1.18
|
||||
|
@ -571,9 +561,9 @@ steps:
|
|||
|
||||
# TODO: We should probably build all dependencies into a test image
|
||||
- name: test-e2e
|
||||
image: mcr.microsoft.com/playwright:v1.24.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.27.0-focal
|
||||
commands:
|
||||
- curl -sLO https://go.dev/dl/go1.18.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz
|
||||
- curl -sLO https://go.dev/dl/go1.19.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
|
||||
- groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea
|
||||
- apt-get -qq update && apt-get -qqy install build-essential
|
||||
- export TEST_PGSQL_SCHEMA=''
|
||||
|
@ -636,6 +626,8 @@ steps:
|
|||
commit_message: "[skip ci] Updated translations via Crowdin"
|
||||
remote: "git@github.com:go-gitea/gitea.git"
|
||||
environment:
|
||||
DRONE_COMMIT_AUTHOR_EMAIL: "teabot@gitea.io"
|
||||
DRONE_COMMIT_AUTHOR: GiteaBot
|
||||
GIT_PUSH_SSH_KEY:
|
||||
from_secret: git_push_ssh_key
|
||||
|
||||
|
@ -680,12 +672,14 @@ steps:
|
|||
pull: always
|
||||
settings:
|
||||
author_email: "teabot@gitea.io"
|
||||
author_name: GiteaBot
|
||||
author_name: "GiteaBot"
|
||||
branch: main
|
||||
commit: true
|
||||
commit_message: "[skip ci] Updated licenses and gitignores "
|
||||
commit_message: "[skip ci] Updated licenses and gitignores"
|
||||
remote: "git@github.com:go-gitea/gitea.git"
|
||||
environment:
|
||||
DRONE_COMMIT_AUTHOR_EMAIL: "teabot@gitea.io"
|
||||
DRONE_COMMIT_AUTHOR: "GiteaBot"
|
||||
GIT_PUSH_SSH_KEY:
|
||||
from_secret: git_push_ssh_key
|
||||
|
||||
|
|
|
@ -185,6 +185,7 @@ rules:
|
|||
linebreak-style: [2, unix]
|
||||
lines-around-comment: [0]
|
||||
lines-between-class-members: [0]
|
||||
logical-assignment-operators: [0]
|
||||
max-classes-per-file: [0]
|
||||
max-depth: [0]
|
||||
max-len: [0]
|
||||
|
@ -245,7 +246,7 @@ rules:
|
|||
no-floating-decimal: [0]
|
||||
no-func-assign: [2]
|
||||
no-global-assign: [2]
|
||||
no-implicit-coercion: [0]
|
||||
no-implicit-coercion: [2]
|
||||
no-implicit-globals: [0]
|
||||
no-implied-eval: [2]
|
||||
no-import-assign: [2]
|
||||
|
@ -322,7 +323,7 @@ rules:
|
|||
no-unused-private-class-members: [2]
|
||||
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
|
||||
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
|
||||
no-useless-backreference: [0]
|
||||
no-useless-backreference: [2]
|
||||
no-useless-call: [2]
|
||||
no-useless-catch: [2]
|
||||
no-useless-computed-key: [2]
|
||||
|
@ -353,7 +354,7 @@ rules:
|
|||
prefer-named-capture-group: [0]
|
||||
prefer-numeric-literals: [2]
|
||||
prefer-object-has-own: [0]
|
||||
prefer-object-spread: [0]
|
||||
prefer-object-spread: [2]
|
||||
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
|
||||
prefer-regex-literals: [2]
|
||||
prefer-rest-params: [2]
|
||||
|
@ -455,6 +456,7 @@ rules:
|
|||
unicorn/no-static-only-class: [2]
|
||||
unicorn/no-thenable: [2]
|
||||
unicorn/no-this-assignment: [2]
|
||||
unicorn/no-unnecessary-await: [2]
|
||||
unicorn/no-unreadable-array-destructuring: [0]
|
||||
unicorn/no-unreadable-iife: [2]
|
||||
unicorn/no-unsafe-regex: [0]
|
||||
|
@ -519,6 +521,7 @@ rules:
|
|||
unicorn/require-number-to-fixed-digits-argument: [2]
|
||||
unicorn/require-post-message-target-origin: [0]
|
||||
unicorn/string-content: [0]
|
||||
unicorn/switch-case-braces: [0]
|
||||
unicorn/template-indent: [2]
|
||||
unicorn/text-encoding-identifier-case: [0]
|
||||
unicorn/throw-new-error: [2]
|
||||
|
|
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -1,5 +1,6 @@
|
|||
* text=auto eol=lf
|
||||
*.tmpl linguist-language=Handlebars
|
||||
/assets/*.json linguist-generated
|
||||
/public/vendor/** -text -eol linguist-vendored
|
||||
/vendor/** -text -eol linguist-vendored
|
||||
/web_src/fomantic/build/** linguist-generated
|
||||
|
|
40
.gitpod.yml
Normal file
40
.gitpod.yml
Normal file
|
@ -0,0 +1,40 @@
|
|||
tasks:
|
||||
- name: Setup
|
||||
init: |
|
||||
make deps
|
||||
make build
|
||||
command: |
|
||||
gp sync-done setup
|
||||
exit 0
|
||||
- name: Run frontend
|
||||
command: |
|
||||
gp sync-await setup
|
||||
make watch-frontend
|
||||
- name: Run backend
|
||||
command: |
|
||||
gp sync-await setup
|
||||
mkdir -p custom/conf/
|
||||
echo -e "[server]\nROOT_URL=$(gp url 3000)/" > custom/conf/app.ini
|
||||
echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini
|
||||
export TAGS="sqlite sqlite_unlock_notify"
|
||||
make watch-backend
|
||||
- name: Run docs
|
||||
before: sudo bash -c "$(grep 'https://github.com/gohugoio/hugo/releases/download' Makefile | tr -d '\')" # install hugo
|
||||
command: cd docs && make clean update && hugo server -D -F --baseUrl $(gp url 1313) --liveReloadPort=443 --appendPort=false --bind=0.0.0.0
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- editorconfig.editorconfig
|
||||
- dbaeumer.vscode-eslint
|
||||
- golang.go
|
||||
- stylelint.vscode-stylelint
|
||||
- DavidAnson.vscode-markdownlint
|
||||
- johnsoncodehk.volar
|
||||
- ms-azuretools.vscode-docker
|
||||
- zixuanchen.vitest-explorer
|
||||
|
||||
ports:
|
||||
- name: Gitea
|
||||
port: 3000
|
||||
- name: Docs
|
||||
port: 1313
|
|
@ -12,7 +12,6 @@ linters:
|
|||
- dupl
|
||||
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
|
||||
- gofmt
|
||||
- misspell
|
||||
- gocritic
|
||||
- bidichk
|
||||
- ineffassign
|
||||
|
@ -86,6 +85,8 @@ linters-settings:
|
|||
- github.com/unknwon/com: "use gitea's util and replacements"
|
||||
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
exclude-rules:
|
||||
# Exclude some linters from running on tests files.
|
||||
- path: _test\.go
|
||||
|
@ -146,9 +147,6 @@ issues:
|
|||
- path: models/issue_comment_list.go
|
||||
linters:
|
||||
- dupl
|
||||
- linters:
|
||||
- misspell
|
||||
text: '`Unknwon` is a misspelling of `Unknown`'
|
||||
- path: models/update.go
|
||||
linters:
|
||||
- unused
|
||||
|
|
80
CHANGELOG.md
80
CHANGELOG.md
|
@ -4,6 +4,86 @@ This changelog goes through all the changes that have been made in each release
|
|||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.17.3](https://github.com/go-gitea/gitea/releases/tag/v1.17.3) - 2022-10-15
|
||||
|
||||
* SECURITY
|
||||
* Sanitize and Escape refs in git backend (#21464) (#21463)
|
||||
* Bump `golang.org/x/text` (#21412) (#21413)
|
||||
* Update bluemonday (#21281) (#21287)
|
||||
* ENHANCEMENTS
|
||||
* Fix empty container layer history and UI (#21251) (#21278)
|
||||
* Use en-US as fallback when using other default language (#21200) (#21256)
|
||||
* Make the vscode clone link respect transport protocol (#20557) (#21128)
|
||||
* BUGFIXES
|
||||
* Do DB update after merge in hammer context (#21401) (#21416)
|
||||
* Add Num{Issues,Pulls} stats checks (#21404) (#21414)
|
||||
* Stop logging CheckPath returns error: context canceled (#21064) (#21405)
|
||||
* Parse OAuth Authorization header when request omits client secret (#21351) (#21374)
|
||||
* Ignore port for loopback redirect URIs (#21293) (#21373)
|
||||
* Set SemverCompatible to false for Conan packages (#21275) (#21366)
|
||||
* Tag list should include draft releases with existing tags (#21263) (#21365)
|
||||
* Fix linked account translation (#21331) (#21334)
|
||||
* Make NuGet service index publicly accessible (#21242) (#21277)
|
||||
* Foreign ID conflicts if ID is 0 for each item (#21271) (#21272)
|
||||
* Use absolute links in feeds (#21229) (#21265)
|
||||
* Prevent invalid behavior for file reviewing when loading more files (#21230) (#21234)
|
||||
* Respect `REQUIRE_SIGNIN_VIEW` for packages (#20873) (#21232)
|
||||
* Treat git object mode 40755 as directory (#21195) (#21218)
|
||||
* Allow uppercase ASCII alphabet in PyPI package names (#21095) (#21217)
|
||||
* Fix limited user cannot view himself's profile (#21212)
|
||||
* Fix template bug of admin monitor (#21209)
|
||||
* Fix reaction of issues (#21185) (#21196)
|
||||
* Fix CSV diff for added/deleted files (#21189) (#21193)
|
||||
* Fix pagination limit parameter problem (#21111)
|
||||
* TESTING
|
||||
* Fix missing m.Run() in TestMain (#21341)
|
||||
* BUILD
|
||||
* Use Go 1.19 fmt for Gitea 1.17, sync emoji data (#21239)
|
||||
|
||||
## [1.17.2](https://github.com/go-gitea/gitea/releases/tag/v1.17.2) - 2022-09-06
|
||||
|
||||
* SECURITY
|
||||
* Double check CloneURL is acceptable (#20869) (#20892)
|
||||
* Add more checks in migration code (#21011) (#21050)
|
||||
* ENHANCEMENTS
|
||||
* Fix hard-coded timeout and error panic in API archive download endpoint (#20925) (#21051)
|
||||
* Improve arc-green code theme (#21039) (#21042)
|
||||
* Enable contenthash in filename for dynamic assets (#20813) (#20932)
|
||||
* Don't open new page for ext wiki on same repository (#20725) (#20910)
|
||||
* Disable doctor logging on panic (#20847) (#20898)
|
||||
* Remove calls to load Mirrors in user.Dashboard (#20855) (#20897)
|
||||
* Update codemirror to 5.65.8 (#20875)
|
||||
* Rework repo buttons (#20602, #20718) (#20719)
|
||||
* BUGFIXES
|
||||
* Ensure delete user deletes all comments (#21067) (#21068)
|
||||
* Delete unreferenced packages when deleting a package version (#20977) (#21060)
|
||||
* Redirect if user does not exist on admin pages (#20981) (#21059)
|
||||
* Set uploadpack.allowFilter etc on gitea serv to enable partial clones with ssh (#20902) (#21058)
|
||||
* Fix 500 on time in timeline API (#21052) (#21057)
|
||||
* Fill the specified ref in webhook test payload (#20961) (#21055)
|
||||
* Add another index for Action table on postgres (#21033) (#21054)
|
||||
* Fix broken insecureskipverify handling in redis connection uris (#20967) (#21053)
|
||||
* Add Dev, Peer and Optional dependencies to npm PackageMetadataVersion (#21017) (#21044)
|
||||
* Do not add links to Posters or Assignees with ID < 0 (#20577) (#21037)
|
||||
* Fix modified due date message (#20388) (#21032)
|
||||
* Fix missed sort bug (#21006)
|
||||
* Fix input.value attr for RequiredClaimName/Value (#20946) (#21001)
|
||||
* Change review buttons to icons to make space for text (#20934) (#20978)
|
||||
* Fix download archiver of a commit (#20962) (#20971)
|
||||
* Return 404 NotFound if requested attachment does not exist (#20886) (#20941)
|
||||
* Set no-tags in git fetch on compare (#20893) (#20936)
|
||||
* Allow multiple metadata files for Maven packages (#20674) (#20916)
|
||||
* Increase Content field size of gpg_key and public_key to MEDIUMTEXT (#20896) (#20911)
|
||||
* Fix mirror address setting not working (#20850) (#20904)
|
||||
* Fix push mirror address backend get error Address cause setting page display error (#20593) (#20901)
|
||||
* Fix panic when an invalid oauth2 name is passed (#20820) (#20900)
|
||||
* In PushMirrorsIterate and MirrorsIterate if limit is negative do not set it (#20837) (#20899)
|
||||
* Ensure that graceful start-up is informed of unused SSH listener (#20877) (#20888)
|
||||
* Pad GPG Key ID with preceding zeroes (#20878) (#20885)
|
||||
* Fix SQL Query for `SearchTeam` (#20844) (#20872)
|
||||
* Fix the mode of custom dir to 0700 in docker-rootless (#20861) (#20867)
|
||||
* Fix UI mis-align for PR commit history (#20845) (#20859)
|
||||
|
||||
## [1.17.1](https://github.com/go-gitea/gitea/releases/tag/1.17.1) - 2022-08-17
|
||||
|
||||
* SECURITY
|
||||
|
|
|
@ -146,6 +146,16 @@ If your PR could cause a breaking change you must add a BREAKING section to this
|
|||
|
||||
To explain how this could affect users and how to mitigate these changes.
|
||||
|
||||
Once code review starts on your PR, do not rebase nor squash your branch as it makes it
|
||||
difficult to review the new changes. Only if there is a need, sync your branch by merging
|
||||
the base branch into yours. Don't worry about merge commits messing up your tree as
|
||||
the final merge process squashes all commits into one, with the visible commit message (first
|
||||
line) being the PR title + PR index and description being the PR's first comment.
|
||||
|
||||
Once your PR gets the `lgtm/done` label, don't worry about keeping it up-to-date or breaking
|
||||
builds (unless there's a merge conflict or a request is made by a maintainer to make
|
||||
modifications). It is the maintainer team's responsibility from this point to get it merged.
|
||||
|
||||
## Styleguide
|
||||
|
||||
For imports you should use the following format (*without* the comments)
|
||||
|
@ -170,17 +180,22 @@ import (
|
|||
|
||||
To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts:
|
||||
|
||||
- **integration:** Integration tests
|
||||
- **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
|
||||
- **models/fixtures:** Sample model data used in integration tests.
|
||||
- **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step.
|
||||
- **modules:** Different modules to handle specific functionality in Gitea.
|
||||
- **modules:** Different modules to handle specific functionality in Gitea. Shall only depend on other modules but not other packages (models, services).
|
||||
- **public:** Frontend files (javascript, images, css, etc.)
|
||||
- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers
|
||||
- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers.
|
||||
- **services:** Support functions for common routing operations. Uses models and modules to handle the request.
|
||||
- **templates:** Golang templates for generating the html output.
|
||||
- **tests/e2e:** End to end tests
|
||||
- **tests/integration:** Integration tests
|
||||
- **vendor:** External code that Gitea depends on.
|
||||
|
||||
## Documentation
|
||||
|
||||
If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated.
|
||||
|
||||
## API v1
|
||||
|
||||
The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [GitHub API v3](https://developer.github.com/v3/).
|
||||
|
@ -229,27 +244,6 @@ An endpoint which changes/edits an object expects all fields to be optional (exc
|
|||
- support pagination (`page` & `limit` options in query)
|
||||
- set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
|
||||
|
||||
## Large Character Comments
|
||||
|
||||
Throughout the codebase there are large-text comments for sections of code, e.g.:
|
||||
|
||||
```go
|
||||
// __________ .__
|
||||
// \______ \ _______ _|__| ______ _ __
|
||||
// | _// __ \ \/ / |/ __ \ \/ \/ /
|
||||
// | | \ ___/\ /| \ ___/\ /
|
||||
// |____|_ /\___ >\_/ |__|\___ >\/\_/
|
||||
// \/ \/ \/
|
||||
```
|
||||
|
||||
These were created using the `figlet` tool with the `graffiti` font.
|
||||
|
||||
A simple way of creating these is to use the following:
|
||||
|
||||
```bash
|
||||
figlet -f graffiti Review | sed -e's+^+// +' - | xclip -sel clip -in
|
||||
```
|
||||
|
||||
## Backports and Frontports
|
||||
|
||||
Occasionally backports of PRs are required.
|
||||
|
|
48
Makefile
48
Makefile
|
@ -130,6 +130,7 @@ TEST_TAGS ?= sqlite sqlite_unlock_notify
|
|||
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR)
|
||||
|
||||
GO_DIRS := cmd tests models modules routers build services tools
|
||||
WEB_DIRS := web_src/js web_src/less
|
||||
|
||||
GO_SOURCES := $(wildcard *.go)
|
||||
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go)
|
||||
|
@ -263,11 +264,24 @@ clean:
|
|||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
@MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
|
||||
GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
|
||||
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
|
||||
@# strip whitespace after '{{' and before `}}` unless there is only whitespace before it
|
||||
@$(SED_INPLACE) -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' $(TEMPLATES)
|
||||
|
||||
.PHONY: fmt-check
|
||||
fmt-check: fmt
|
||||
@diff=$$(git diff $(GO_SOURCES) templates $(WEB_DIRS)); \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "Please run 'make fmt' and commit the result:"; \
|
||||
echo "$${diff}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: misspell-check
|
||||
misspell-check:
|
||||
go run $(MISSPELL_PACKAGE) -error -i unknwon $(GO_DIRS) $(WEB_DIRS)
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
@echo "Running go vet..."
|
||||
|
@ -311,22 +325,6 @@ errcheck:
|
|||
@echo "Running errcheck..."
|
||||
$(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES)
|
||||
|
||||
.PHONY: fmt-check
|
||||
fmt-check:
|
||||
@# get all go files and run gitea-fmt (with gofmt) on them
|
||||
@diff=$$(MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -l '{file-list}'); \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "Please run 'make fmt' and commit the result:"; \
|
||||
echo "$${diff}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@diff2=$$(git diff templates); \
|
||||
if [ -n "$$diff2" ]; then \
|
||||
echo "Please run 'make fmt' and commit the result:"; \
|
||||
echo "$${diff2}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: checks
|
||||
checks: checks-frontend checks-backend
|
||||
|
||||
|
@ -334,14 +332,14 @@ checks: checks-frontend checks-backend
|
|||
checks-frontend: lockfile-check svg-check
|
||||
|
||||
.PHONY: checks-backend
|
||||
checks-backend: tidy-check swagger-check swagger-validate
|
||||
checks-backend: tidy-check swagger-check fmt-check misspell-check swagger-validate
|
||||
|
||||
.PHONY: lint
|
||||
lint: lint-frontend lint-backend
|
||||
|
||||
.PHONY: lint-frontend
|
||||
lint-frontend: node_modules
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e/*.test.e2e.js tests/e2e/utils_e2e.js
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e
|
||||
npx stylelint --color --max-warnings=0 web_src/less
|
||||
npx spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||
npx markdownlint docs *.md
|
||||
|
@ -372,7 +370,7 @@ test-backend:
|
|||
|
||||
.PHONY: test-frontend
|
||||
test-frontend: node_modules
|
||||
@NODE_OPTIONS="--experimental-vm-modules --no-warnings" npx jest --color
|
||||
npx vitest
|
||||
|
||||
.PHONY: test-check
|
||||
test-check:
|
||||
|
@ -406,6 +404,7 @@ unit-test-coverage:
|
|||
tidy:
|
||||
$(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2))
|
||||
$(GO) mod tidy -compat=$(MIN_GO_VERSION)
|
||||
@$(MAKE) --no-print-directory $(GO_LICENSE_FILE)
|
||||
|
||||
vendor: go.mod go.sum
|
||||
$(GO) mod vendor
|
||||
|
@ -413,7 +412,7 @@ vendor: go.mod go.sum
|
|||
|
||||
.PHONY: tidy-check
|
||||
tidy-check: tidy
|
||||
@diff=$$(git diff go.mod go.sum); \
|
||||
@diff=$$(git diff go.mod go.sum $(GO_LICENSE_FILE)); \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "Please run 'make tidy' and commit the result:"; \
|
||||
echo "$${diff}"; \
|
||||
|
@ -709,17 +708,14 @@ install: $(wildcard *.go)
|
|||
build: frontend backend
|
||||
|
||||
.PHONY: frontend
|
||||
frontend: generate-frontend $(WEBPACK_DEST)
|
||||
frontend: $(WEBPACK_DEST)
|
||||
|
||||
.PHONY: backend
|
||||
backend: go-check generate-backend $(EXECUTABLE)
|
||||
|
||||
# We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend
|
||||
.PHONY: generate
|
||||
generate: generate-backend generate-frontend
|
||||
|
||||
.PHONY: generate-frontend
|
||||
generate-frontend: $(GO_LICENSE_FILE)
|
||||
generate: generate-backend
|
||||
|
||||
.PHONY: generate-backend
|
||||
generate-backend: $(TAGS_PREREQ) generate-go
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||
</a>
|
||||
<a href="https://gitpod.io/#https://github.com/go-gitea/gitea">
|
||||
<img
|
||||
src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod"
|
||||
alt="Contribute with Gitpod"
|
||||
/>
|
||||
</a>
|
||||
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||
</a>
|
||||
|
@ -145,6 +151,7 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
|
|||
<a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://cynkra.com/" target="_blank"><img src="https://images.opencollective.com/cynkra/logo/square/64/192.png"></a>
|
||||
|
||||
## FAQ
|
||||
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||
</a>
|
||||
<a href="https://gitpod.io/#https://github.com/go-gitea/gitea">
|
||||
<img
|
||||
src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod"
|
||||
alt="Contribute with Gitpod"
|
||||
/>
|
||||
</a>
|
||||
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||
</a>
|
||||
|
|
23
assets/go-licenses.json
generated
23
assets/go-licenses.json
generated
File diff suppressed because one or more lines are too long
|
@ -20,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
// Windows has a limitation for command line arguments, the size can not exceed 32KB.
|
||||
// So we have to feed the files to some tools (like gofmt/misspell) batch by batch
|
||||
// So we have to feed the files to some tools (like gofmt) batch by batch
|
||||
|
||||
// We also introduce a `gitea-fmt` command, it does better import formatting than gofmt/goimports. `gitea-fmt` calls `gofmt` internally.
|
||||
|
||||
|
@ -195,7 +195,6 @@ Options:
|
|||
|
||||
Commands:
|
||||
%[1]s gofmt ...
|
||||
%[1]s misspell ...
|
||||
|
||||
Arguments:
|
||||
{file-list} the file list
|
||||
|
@ -206,6 +205,17 @@ Example:
|
|||
`, "file-batch-exec")
|
||||
}
|
||||
|
||||
func getGoVersion() string {
|
||||
goModFile, err := os.ReadFile("go.mod")
|
||||
if err != nil {
|
||||
log.Fatalf(`Faild to read "go.mod": %v`, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
goModVersionRegex := regexp.MustCompile(`go \d+\.\d+`)
|
||||
goModVersionLine := goModVersionRegex.Find(goModFile)
|
||||
return string(goModVersionLine[3:])
|
||||
}
|
||||
|
||||
func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) {
|
||||
fileFilter := mainOptions["file-filter"]
|
||||
if fileFilter == "" {
|
||||
|
@ -228,9 +238,9 @@ func containsString(a []string, s string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func giteaFormatGoImports(files []string, hasChangedFiles, doWriteFile bool) error {
|
||||
func giteaFormatGoImports(files []string, doWriteFile bool) error {
|
||||
for _, file := range files {
|
||||
if err := codeformat.FormatGoImports(file, hasChangedFiles, doWriteFile); err != nil {
|
||||
if err := codeformat.FormatGoImports(file, doWriteFile); err != nil {
|
||||
log.Printf("failed to format go imports: %s, err=%v", file, err)
|
||||
return err
|
||||
}
|
||||
|
@ -269,10 +279,8 @@ func main() {
|
|||
if containsString(subArgs, "-d") {
|
||||
log.Print("the -d option is not supported by gitea-fmt")
|
||||
}
|
||||
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-l"), containsString(subArgs, "-w")))
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", "1.17"}, substArgs...)))
|
||||
case "misspell":
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("MISSPELL_PACKAGE")}, substArgs...)))
|
||||
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-w")))
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", getGoVersion()}, substArgs...)))
|
||||
default:
|
||||
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ package codeformat
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
|
@ -159,7 +158,7 @@ func formatGoImports(contentBytes []byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
// FormatGoImports format the imports by our rules (see unit tests)
|
||||
func FormatGoImports(file string, doChangedFiles, doWriteFile bool) error {
|
||||
func FormatGoImports(file string, doWriteFile bool) error {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -183,10 +182,6 @@ func FormatGoImports(file string, doChangedFiles, doWriteFile bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if doChangedFiles {
|
||||
fmt.Println(file)
|
||||
}
|
||||
|
||||
if doWriteFile {
|
||||
f, err = os.OpenFile(file, os.O_TRUNC|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
|
|
|
@ -43,7 +43,7 @@ const (
|
|||
var CmdServ = cli.Command{
|
||||
Name: "serv",
|
||||
Usage: "This command should only be called by SSH shell",
|
||||
Description: `Serv provide access auth for repositories`,
|
||||
Description: "Serv provides access auth for repositories",
|
||||
Action: runServ,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
|
|
|
@ -203,7 +203,7 @@ func setPort(port string) error {
|
|||
defaultLocalURL += ":" + setting.HTTPPort + "/"
|
||||
|
||||
// Save LOCAL_ROOT_URL if port changed
|
||||
setting.CreateOrAppendToCustomConf(func(cfg *ini.File) {
|
||||
setting.CreateOrAppendToCustomConf("server.LOCAL_ROOT_URL", func(cfg *ini.File) {
|
||||
cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,14 +2,43 @@
|
|||
|
||||
DIR=/var/lib/gitea
|
||||
USER=git
|
||||
HOME=/home/${USER}
|
||||
GITEA_WORK_DIR=${DIR}
|
||||
EXECUTABLE=/usr/local/bin/gitea
|
||||
|
||||
export USER
|
||||
export HOME
|
||||
export GITEA_WORK_DIR
|
||||
|
||||
name=$RC_SVCNAME
|
||||
cfgfile="/etc/$RC_SVCNAME/app.ini"
|
||||
command="${EXECUTABLE}"
|
||||
command_user="${USER}"
|
||||
command_args="web -c /etc/$RC_SVCNAME/app.ini"
|
||||
command_background="yes"
|
||||
pidfile="/run/$RC_SVCNAME/$RC_SVCNAME.pid"
|
||||
start_stop_daemon_args="--user ${USER} --chdir ${DIR}"
|
||||
command="/usr/local/bin/gitea"
|
||||
command_args="web -c /etc/gitea/app.ini"
|
||||
command_background=yes
|
||||
pidfile=/run/gitea.pid
|
||||
|
||||
depend()
|
||||
{
|
||||
need net
|
||||
###
|
||||
# Don't forget to add the database service requirements
|
||||
###
|
||||
#after postgresql
|
||||
#after mysql
|
||||
#after mariadb
|
||||
#after memcached
|
||||
#after redis
|
||||
}
|
||||
|
||||
start_pre()
|
||||
{
|
||||
checkpath --directory --owner $command_user:$command_user --mode 0750 \
|
||||
/run/$RC_SVCNAME /var/log/$RC_SVCNAME
|
||||
##
|
||||
# If you want to bind Gitea to a port below 1024, uncomment
|
||||
# the value below
|
||||
##
|
||||
#setcap cap_net_bind_service=+ep "${EXECUTABLE}"
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
|
@ -62,11 +61,7 @@ func runPR() {
|
|||
}
|
||||
setting.AppWorkPath = curDir
|
||||
setting.StaticRootPath = curDir
|
||||
setting.GravatarSourceURL, err = url.Parse("https://secure.gravatar.com/avatar/")
|
||||
if err != nil {
|
||||
log.Fatalf("url.Parse: %v\n", err)
|
||||
}
|
||||
|
||||
setting.GravatarSource = "https://secure.gravatar.com/avatar/"
|
||||
setting.AppURL = "http://localhost:8080/"
|
||||
setting.HTTPPort = "8080"
|
||||
setting.SSH.Domain = "localhost"
|
||||
|
|
|
@ -49,12 +49,8 @@ After=network.target
|
|||
###
|
||||
|
||||
[Service]
|
||||
# Modify these two values and uncomment them if you have
|
||||
# repos with lots of files and get an HTTP error 500 because
|
||||
# of that
|
||||
###
|
||||
#LimitMEMLOCK=infinity
|
||||
#LimitNOFILE=65535
|
||||
# Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that
|
||||
# LimitNOFILE=524288:524288
|
||||
RestartSec=2s
|
||||
Type=simple
|
||||
User=git
|
||||
|
|
|
@ -379,14 +379,19 @@ LOG_SQL = false ; if unset defaults to true
|
|||
;; Whether the installer is disabled (set to true to disable the installer)
|
||||
INSTALL_LOCK = false
|
||||
;;
|
||||
;; Global secret key that will be used - if blank will be regenerated.
|
||||
;; Global secret key that will be used
|
||||
;; This key is VERY IMPORTANT. If you lose it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
|
||||
SECRET_KEY =
|
||||
;;
|
||||
;; Alternative location to specify secret key, instead of this file; you cannot specify both this and SECRET_KEY, and must pick one
|
||||
;; This key is VERY IMPORTANT. If you lose it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
|
||||
;SECRET_KEY_URI = file:/etc/gitea/secret_key
|
||||
;;
|
||||
;; Secret used to validate communication within Gitea binary.
|
||||
INTERNAL_TOKEN=
|
||||
;;
|
||||
;; Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: file:/etc/gitea/internal_token)
|
||||
;INTERNAL_TOKEN_URI = ;e.g. /etc/gitea/internal_token
|
||||
;; Alternative location to specify internal token, instead of this file; you cannot specify both this and INTERNAL_TOKEN, and must pick one
|
||||
;INTERNAL_TOKEN_URI = file:/etc/gitea/internal_token
|
||||
;;
|
||||
;; How long to remember that a user is logged in before requiring relogin (in days)
|
||||
;LOGIN_REMEMBER_DAYS = 7
|
||||
|
@ -882,7 +887,7 @@ ROUTER = console
|
|||
;USE_COMPAT_SSH_URI = false
|
||||
;;
|
||||
;; Close issues as long as a commit on any branch marks it as fixed
|
||||
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki
|
||||
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects
|
||||
;DISABLED_REPO_UNITS =
|
||||
;;
|
||||
;; Comma separated list of default repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects.
|
||||
|
@ -1262,6 +1267,9 @@ ROUTER = console
|
|||
;; List of file extensions that should be rendered/edited as Markdown
|
||||
;; Separate the extensions with a comma. To render files without any extension as markdown, just put a comma
|
||||
;FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
|
||||
;;
|
||||
;; Enables math inline and block detection
|
||||
;ENABLE_MATH = true
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -2150,7 +2158,7 @@ ROUTER = console
|
|||
;[api]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Enables Swagger. True or false; default is true.
|
||||
;; Enables the API documentation endpoints (/api/swagger, /api/v1/swagger, …). True or false.
|
||||
;ENABLE_SWAGGER = true
|
||||
;; Max number of items in a page
|
||||
;MAX_RESPONSE_ITEMS = 50
|
||||
|
@ -2158,7 +2166,7 @@ ROUTER = console
|
|||
;DEFAULT_PAGING_NUM = 30
|
||||
;; Default and maximum number of items per page for git trees api
|
||||
;DEFAULT_GIT_TREES_PER_PAGE = 1000
|
||||
;; Default size of a blob returned by the blobs API (default is 10MiB)
|
||||
;; Default max size of a blob returned by the blobs API (default is 10MiB)
|
||||
;DEFAULT_MAX_BLOB_SIZE = 10485760
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -18,7 +18,7 @@ params:
|
|||
description: Git with a cup of tea
|
||||
author: The Gitea Authors
|
||||
website: https://docs.gitea.io
|
||||
version: 1.17.1
|
||||
version: 1.17.3
|
||||
minGoVersion: 1.18
|
||||
goVersion: 1.19
|
||||
minNodeVersion: 14
|
||||
|
|
|
@ -236,6 +236,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
|||
- `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional
|
||||
URL hyperlinks to be rendered in Markdown. URLs beginning in http and https are
|
||||
always displayed
|
||||
- `ENABLE_MATH`: **true**: Enables detection of `\(...\)`, `\[...\]`, `$...$` and `$$...$$` blocks as math blocks.
|
||||
|
||||
## Server (`server`)
|
||||
|
||||
|
@ -493,7 +494,8 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
|
|||
## Security (`security`)
|
||||
|
||||
- `INSTALL_LOCK`: **false**: Controls access to the installation page. When set to "true", the installation page is not accessible.
|
||||
- `SECRET_KEY`: **\<random at every install\>**: Global secret key. This should be changed.
|
||||
- `SECRET_KEY`: **\<random at every install\>**: Global secret key. This key is VERY IMPORTANT, if you lost it, the data encrypted by it (like 2FA secret) can't be decrypted anymore.
|
||||
- `SECRET_KEY_URI`: **<empty>**: Instead of defining SECRET_KEY, this option can be used to use the key stored in a file (example value: `file:/etc/gitea/secret_key`). It shouldn't be lost like SECRET_KEY.
|
||||
- `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days.
|
||||
- `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username.
|
||||
- `COOKIE_REMEMBER_NAME`: **gitea\_incredible**: Name of cookie used to store authentication
|
||||
|
@ -519,7 +521,7 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
|
|||
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to Gitea repositories you should set the environment appropriately.
|
||||
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
|
||||
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
|
||||
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
||||
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining INTERNAL_TOKEN in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
||||
- `PASSWORD_HASH_ALGO`: **pbkdf2**: The hash algorithm to use \[argon2, pbkdf2, scrypt, bcrypt\], argon2 will spend more memory than others.
|
||||
- `CSRF_COOKIE_HTTP_ONLY`: **true**: Set false to allow JavaScript to read CSRF cookie.
|
||||
- `MIN_PASSWORD_LENGTH`: **6**: Minimum password length for new users.
|
||||
|
@ -535,9 +537,9 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
|
|||
## Camo (`camo`)
|
||||
|
||||
- `ENABLED`: **false**: Enable media proxy, we support images only at the moment.
|
||||
- `SERVER_URL`: **<empty>**: url of camo server, it **is required** if camo is enabled.
|
||||
- `HMAC_KEY`: **<empty>**: Provide the HMAC key for encoding urls, it **is required** if camo is enabled.
|
||||
- `ALLWAYS`: **false**: Set to true to use camo for https too lese only non https urls are proxyed
|
||||
- `SERVER_URL`: **<empty>**: URL of camo server, it **is required** if camo is enabled.
|
||||
- `HMAC_KEY`: **<empty>**: Provide the HMAC key for encoding URLs, it **is required** if camo is enabled.
|
||||
- `ALLWAYS`: **false**: Set to true to use camo for both HTTP and HTTPS content, otherwise only non-HTTPS URLs are proxied
|
||||
|
||||
## OpenID (`openid`)
|
||||
|
||||
|
@ -851,7 +853,7 @@ Default templates for project boards:
|
|||
- `SCHEDULE` accept formats
|
||||
- Full crontab specs, e.g. `* * * * * ?`
|
||||
- Descriptors, e.g. `@midnight`, `@every 1h30m` ...
|
||||
- See more: [cron decument](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14)
|
||||
- See more: [cron documentation](https://pkg.go.dev/github.com/gogs/cron@v0.0.0-20171120032916-9f6c956d3e14)
|
||||
|
||||
### Basic cron tasks - enabled by default
|
||||
|
||||
|
@ -1014,11 +1016,11 @@ Default templates for project boards:
|
|||
|
||||
## API (`api`)
|
||||
|
||||
- `ENABLE_SWAGGER`: **true**: Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true.
|
||||
- `ENABLE_SWAGGER`: **true**: Enables the API documentation endpoints (`/api/swagger`, `/api/v1/swagger`, …). True or false.
|
||||
- `MAX_RESPONSE_ITEMS`: **50**: Max number of items in a page.
|
||||
- `DEFAULT_PAGING_NUM`: **30**: Default paging number of API.
|
||||
- `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: Default and maximum number of items per page for Git trees API.
|
||||
- `DEFAULT_MAX_BLOB_SIZE`: **10485760**: Default max size of a blob that can be return by the blobs API.
|
||||
- `DEFAULT_MAX_BLOB_SIZE`: **10485760** (10MiB): Default max size of a blob that can be returned by the blobs API.
|
||||
|
||||
## OAuth2 (`oauth2`)
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ test01.xls: application/vnd.ms-excel; charset=binary
|
|||
|
||||
## API (`api`)
|
||||
|
||||
- `ENABLE_SWAGGER`: **true**: 是否启用swagger路由 /api/swagger, /api/v1/swagger etc. endpoints. True 或 false; 默认是 true.
|
||||
- `ENABLE_SWAGGER`: **true**: 是否启用swagger路由 /api/swagger, /api/v1/swagger etc. endpoints. True 或 false.
|
||||
- `MAX_RESPONSE_ITEMS`: **50**: 一个页面最大的项目数。
|
||||
- `DEFAULT_PAGING_NUM`: **30**: API中默认分页条数。
|
||||
- `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: GIT TREES API每页的默认最大项数.
|
||||
|
|
|
@ -74,12 +74,13 @@ RENDER_COMMAND = "timeout 30s pandoc +RTS -M512M -RTS -f rst"
|
|||
IS_INPUT_FILE = false
|
||||
```
|
||||
|
||||
If your external markup relies on additional classes and attributes on the generated HTML elements, you might need to enable custom sanitizer policies. Gitea uses the [`bluemonday`](https://godoc.org/github.com/microcosm-cc/bluemonday) package as our HTML sanitizier. The example below will support [KaTeX](https://katex.org/) output from [`pandoc`](https://pandoc.org/).
|
||||
If your external markup relies on additional classes and attributes on the generated HTML elements, you might need to enable custom sanitizer policies. Gitea uses the [`bluemonday`](https://godoc.org/github.com/microcosm-cc/bluemonday) package as our HTML sanitizer. The example below could be used to support server-side [KaTeX](https://katex.org/) rendering output from [`pandoc`](https://pandoc.org/).
|
||||
|
||||
```ini
|
||||
[markup.sanitizer.TeX]
|
||||
; Pandoc renders TeX segments as <span>s with the "math" class, optionally
|
||||
; with "inline" or "display" classes depending on context.
|
||||
; - note this is different from the built-in math support in our markdown parser which uses <code>
|
||||
ELEMENT = span
|
||||
ALLOW_ATTR = class
|
||||
REGEXP = ^\s*((math(\s+|$)|inline(\s+|$)|display(\s+|$)))+
|
||||
|
|
|
@ -67,22 +67,18 @@ Some actions should allow for rollback when database record insertion/update/del
|
|||
So services must be allowed to create a database transaction. Here is some example,
|
||||
|
||||
```go
|
||||
// servcies/repository/repo.go
|
||||
func CreateXXXX() error {\
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
// do something, if return err, it will rollback automatically when `committer.Close()` is invoked.
|
||||
// services/repository/repository.go
|
||||
func CreateXXXX() error {
|
||||
return db.WithTx(func(ctx context.Context) error {
|
||||
e := db.GetEngine(ctx)
|
||||
// do something, if err is returned, it will rollback automatically
|
||||
if err := issues.UpdateIssue(ctx, repoID); err != nil {
|
||||
// ...
|
||||
return err
|
||||
}
|
||||
|
||||
// ......
|
||||
|
||||
return committer.Commit()
|
||||
// ...
|
||||
return nil
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -94,14 +90,14 @@ If the function will be used in the transaction, just let `context.Context` as t
|
|||
func UpdateIssue(ctx context.Context, repoID int64) error {
|
||||
e := db.GetEngine(ctx)
|
||||
|
||||
// ......
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Package Name
|
||||
|
||||
For the top level package, use a plural as package name, i.e. `services`, `models`, for sub packages, use singular,
|
||||
i.e. `servcies/user`, `models/repository`.
|
||||
i.e. `services/user`, `models/repository`.
|
||||
|
||||
### Import Alias
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ menu:
|
|||
|
||||
## Background
|
||||
|
||||
Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue2](https://vuejs.org/v2/guide/) for its frontend.
|
||||
Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue3](https://vuejs.org/) for its frontend.
|
||||
|
||||
The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template).
|
||||
|
||||
|
@ -44,7 +44,7 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h
|
|||
4. jQuery events across different features could use their own namespaces if there are potential conflicts.
|
||||
5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names with 2-3 feature related keywords to overwrite framework styles.
|
||||
6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}`
|
||||
7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future).
|
||||
7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue3.
|
||||
|
||||
### Framework Usage
|
||||
|
||||
|
@ -97,6 +97,6 @@ However, there are still some special cases, so the current guideline is:
|
|||
|
||||
A lot of legacy code already existed before this document's written. It's recommended to refactor legacy code to follow the guidelines.
|
||||
|
||||
### Vue2/Vue3 and JSX
|
||||
### Vue3 and JSX
|
||||
|
||||
Gitea is using Vue2 now, we plan to upgrade to Vue3. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.
|
||||
Gitea is using Vue3 now. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.
|
|
@ -19,6 +19,12 @@ menu:
|
|||
|
||||
{{< toc >}}
|
||||
|
||||
## Quickstart
|
||||
|
||||
To get a quick working development environment you could use Gitpod.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/go-gitea/gitea)
|
||||
|
||||
## Installing go
|
||||
|
||||
You should [install go](https://golang.org/doc/install) and set up your go
|
||||
|
@ -171,7 +177,7 @@ server as mentioned above.
|
|||
|
||||
### Working on JS and CSS
|
||||
|
||||
Frontend development should follow [Guidelines for Frontend Development](./guidelines-frontend.md)
|
||||
Frontend development should follow [Guidelines for Frontend Development]({{< relref "doc/developers/guidelines-frontend.en-us.md" >}})
|
||||
|
||||
To build with frontend resources, either use the `watch-frontend` target mentioned above or just build once:
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ menu:
|
|||
|
||||
To help decide if Gitea is suited for your needs, here is how it compares to other Git self hosted options.
|
||||
|
||||
Be warned that we don't regularly check for feature changes in other products, so this list may be outdated. If you find anything that needs to be updated in the table below, please report it in an [issue on GitHub](https://github.com/go-gitea/gitea/issues).
|
||||
Be warned that we don't regularly check for feature changes in other products, so this list may be outdated. If you find anything that needs to be updated in the table below, please [open an issue](https://github.com/go-gitea/gitea/issues/new/choose).
|
||||
|
||||
_Symbols used in table:_
|
||||
|
||||
|
@ -34,100 +34,110 @@ _Symbols used in table:_
|
|||
## General Features
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ----------------------------------- | ---------------------------------------------------| ---- | --------- | --------- | --------- | -------------- | ------------ |
|
||||
| ------------------------------------------------ | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Open source and free | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
||||
| Low resource usage (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| Low RAM/ CPU usage | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| Multiple database support | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
||||
| Multiple OS support | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ |
|
||||
| Easy upgrade process | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Orgmode support | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? |
|
||||
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||
| Easy upgrades | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| Telemetry | **✘** | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||
| Third-party render tool support | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
||||
| Static Git-powered pages | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
||||
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||
| Extensive API | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Built-in Package/Container Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Sync commits to an external repo (push mirror) | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| Sync commits from an external repo (pull mirror) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ? |
|
||||
| Light and Dark Theme | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ? |
|
||||
| Custom Theme Support | ✓ | ✓ | ✘ | ✘ | ✘ | ✓ | ✘ |
|
||||
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||
| 'GitHub / GitLab pages' | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Repo-specific wiki (as a repo itself) | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Built-in Package/Container Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||
| Built-in CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| RSS Feeds | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ✘ |
|
||||
| Built-in CI/CD | [✘](https://github.com/go-gitea/gitea/issues/13539) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Subgroups: groups within groups | [✘](https://github.com/go-gitea/gitea/issues/1872) | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| Interaction with other instances | [/](https://github.com/go-gitea/gitea/issues/18240) | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| Mermaid diagrams in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Math syntax in Markdown | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
|
||||
## Code management
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| -------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| ------------------------------------------- | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Global code search | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Group Milestones | [✘](https://github.com/go-gitea/gitea/issues/14622) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Granular user roles (Code, Issues, Wiki, …) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Verified Committer | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SSH Signed Commits | ✓ | ✘ | ✘ | ✘ | ✘ | ? | ? |
|
||||
| Reject unsigned commits | [✓](https://github.com/go-gitea/gitea/pull/9708) | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SSH Signed Commits | ✓ | ✘ | ✓ | ✘ | ✘ | ? | ? |
|
||||
| Reject unsigned commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Migrating repos from other services | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Web code editor | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Commit graph | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Template Repositories | [✓](https://github.com/go-gitea/gitea/pull/8768) | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
||||
| Template Repositories | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
||||
| Git Blame | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Visual comparison of image changes | ✓ | ✘ | ✓ | ? | ? | ? | ? |
|
||||
|
||||
## Issue Tracker
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ------------------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | ----------------------------------------------------------------------- | --------- | -------------- | ------------ |
|
||||
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
||||
| ----------------------------- | --------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 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) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Lock Discussion | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue Boards (Kanban) | [✓](https://github.com/go-gitea/gitea/pull/8346) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Create new branches from issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue Boards (Kanban) | [/](https://github.com/go-gitea/gitea/issues/14710) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Create branch from issue | [✘](https://github.com/go-gitea/gitea/issues/20226) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Convert comment to new issue | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Global issue search | [✘](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Global issue search | [/](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Issue dependency | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| Create issue via email | [✘](https://github.com/go-gitea/gitea/issues/6226) | [✘](https://github.com/gogs/gogs/issues/2602) | ✘ | ✘ | ✓ | ✓ | ✘ |
|
||||
| Service Desk | [✘](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | [✓](https://gitlab.com/groups/gitlab-org/-/epics/3103) | ✓ | ✘ | ✘ |
|
||||
| Create issue via email | [✘](https://github.com/go-gitea/gitea/issues/6226) | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ |
|
||||
| Service Desk | [✘](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
|
||||
## Pull/Merge requests
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ----------------------------------------------- | -------------------------------------------------- | ---- | --------- | --------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------ | ------------ |
|
||||
| ----------------------------------------------- | -------------------------------------------------- | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Squash merging | ✓ | ✘ | ✓ | [✓](https://docs.gitlab.com/ce/user/project/merge_requests/squash_and_merge.html) | ✓ | ✓ | ✓ |
|
||||
| Rebase merging | ✓ | ✓ | ✓ | ✘ | ⁄ | ✘ | ✓ |
|
||||
| Squash merging | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Rebase merging | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Pull/Merge request inline comments | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Pull/Merge request approval | ✓ | ✘ | ⁄ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Merge conflict resolution | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | ⁄ | ✓ | ✓ | ✓ |
|
||||
| Revert specific commits or a merge request | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Pull/Merge request approval | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Merge conflict resolution | [✘](https://github.com/go-gitea/gitea/issues/9014) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Revert specific commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Cherry-picking changes | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | [/](https://jira.atlassian.com/plugins/servlet/mobile#issue/BCLOUD-8323) | ✘ |
|
||||
| Cherry-picking changes | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Download Patch | ✓ | ✘ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
|
||||
## 3rd-party integrations
|
||||
|
||||
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
| ---------------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| Webhook support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Custom Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Webhooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||
| LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | [✘](https://github.com/gogs/gogs/issues/1221) | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| OpenId Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
|
||||
| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| OpenID Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
|
||||
| OAuth 2.0 integration (external authorization) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ |
|
||||
| Act as OAuth 2.0 provider | [✓](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Act as OAuth 2.0 provider | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Mattermost/Slack integration | ✓ | ✓ | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
||||
| Discord integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Microsoft Teams integration | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| External CI/CD status display | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Integration with the most common services | ✓ | / | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
||||
| Incorporate external CI/CD | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
|
|
|
@ -32,7 +32,7 @@ _表格中的符号含义:_
|
|||
#### 主要特性
|
||||
|
||||
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
|-----------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||
| --------------------- | -------------------------------------------------- | ---- | --------- | --------- | --------- | -------------- | ------------ |
|
||||
| 开源免费 | ✓ | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ |
|
||||
| 低资源开销 (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| 支持多种数据库 | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
||||
|
@ -42,79 +42,79 @@ _表格中的符号含义:_
|
|||
| 支持 Orgmode | ✓ | ✘ | ✓ | ✘ | ✘ | ✘ | ? |
|
||||
| 支持 CSV | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ? |
|
||||
| 支持第三方渲染工具 | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ | ? |
|
||||
| Git 驱动的静态 pages | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Git 驱动的集成化 wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Git 驱动的静态 pages | [✘](https://github.com/go-gitea/gitea/issues/302) | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Git 驱动的集成化 wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
||||
| 部署令牌 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 仓库写权限令牌 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||
| 内置容器 Registry | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 仓库写权限令牌 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 内置容器 Registry | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 外部 Git 镜像 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||
| 内置 CI/CD | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 子组织:组织内的组织 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
| 内置 CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 子组织:组织内的组织 | [✘](https://github.com/go-gitea/gitea/issues/1872) | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||
|
||||
#### 代码管理
|
||||
|
||||
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
|------------------------------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||
| ---------------------------------------- | ------------------------------------------------ | ---- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| 仓库主题描述 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 仓库内代码搜索 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 全局代码搜索 | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ |
|
||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 组织里程碑 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 细粒度用户角色 (例如 Code, Issues, Wiki) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 提交人的身份验证 | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||
| GPG 签名的提交 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SSH 签名的提交 | ✓ | ✘ | ✘ | ✘ | ✘ | ? | ? |
|
||||
| 拒绝未用通过验证的提交 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||
| 拒绝未用通过验证的提交 | [✓](https://github.com/go-gitea/gitea/pull/9708) | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 仓库活跃度页面 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 分支管理 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 建立新分支 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 在线代码编辑 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 提交的统计图表 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 模板仓库 | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
||||
| 模板仓库 | [✓](https://github.com/go-gitea/gitea/pull/8768) | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
||||
|
||||
#### Issue 管理
|
||||
#### 工单管理
|
||||
|
||||
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
|----------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||
| 跟踪 Issue | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Issue 模板 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| ------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | ----------------------------------------------------------------------- | --------- | -------------- | ------------ |
|
||||
| 工单跟踪 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (cloud only) | ✘ |
|
||||
| 工单模板 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 标签 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 跟踪时间 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue 可有多个负责人 | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
|
||||
| 关联的 issues | ✘ | ✘ | ⁄ | ✘ | ✓ | ✘ | ✘ |
|
||||
| 私密 issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 时间跟踪 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 支持多个负责人 | ✓ | ✘ | ✓ | ✘ | ✓ | ✘ | ✘ |
|
||||
| 关联的工单 | ✘ | ✘ | ⁄ | [✓](https://docs.gitlab.com/ce/user/project/issues/related_issues.html) | ✓ | ✘ | ✘ |
|
||||
| 私密工单 | [✘](https://github.com/go-gitea/gitea/issues/3217) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 评论反馈 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 锁定讨论 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue 批量处理 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue 看板 | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 从 issues 创建分支 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue 搜索 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 全局 Issue 搜索 | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Issue 依赖 | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| 工单批处理 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 工单看板 | [✓](https://github.com/go-gitea/gitea/pull/8346) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 从工单创建分支 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 工单搜索 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 工单全局搜索 | [✘](https://github.com/go-gitea/gitea/issues/2434) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 工单依赖关系 | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||
| 通过 Email 创建工单 | [✘](https://github.com/go-gitea/gitea/issues/6226) | [✘](https://github.com/gogs/gogs/issues/2602) | ✘ | ✘ | ✓ | ✓ | ✘ |
|
||||
| Service Desk | [✘](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | ✘ | ✓ | ✘ | ✘ |
|
||||
| 服务台 | [✘](https://github.com/go-gitea/gitea/issues/6219) | ✘ | ✘ | [✓](https://gitlab.com/groups/gitlab-org/-/epics/3103) | ✓ | ✘ | ✘ |
|
||||
|
||||
#### Pull/Merge requests
|
||||
|
||||
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
|--------------------------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||
| ------------------------------------ | -------------------------------------------------- | ---- | --------- | --------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------ | ------------ |
|
||||
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Squash merging | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
||||
| Squash merging | ✓ | ✘ | ✓ | [✓](https://docs.gitlab.com/ce/user/project/merge_requests/squash_and_merge.html) | ✓ | ✓ | ✓ |
|
||||
| Rebase merging | ✓ | ✓ | ✓ | ✘ | ⁄ | ✘ | ✓ |
|
||||
| 评论 Pull/Merge request 中的某行代码 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 指定 Pull/Merge request 的审核人 | ✓ | ✘ | ⁄ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 解决 Merge 冲突 | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 解决 Merge 冲突 | [✘](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 限制某些用户的 push 和 merge 权限 | ✓ | ✘ | ✓ | ⁄ | ✓ | ✓ | ✓ |
|
||||
| 回退某些 commits 或 merge request | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 回退某些 commits 或 merge request | [✓](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Pull/Merge requests 模板 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 查看 Cherry-picking 的更改 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 下载 Patch | ✓ | ✘ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
| 查看 Cherry-picking 的更改 | [✓](https://github.com/go-gitea/gitea/issues/5158) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 下载 Patch | ✓ | ✘ | ✓ | ✓ | ✓ | [/](https://jira.atlassian.com/plugins/servlet/mobile#issue/BCLOUD-8323) | ✘ |
|
||||
|
||||
#### 第三方集成
|
||||
|
||||
| 特性 | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||
|----------------------------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||
| -------------------------- | -------------------------------------------------- | --------------------------------------------- | --------- | --------- | --------- | --------- | ------------ |
|
||||
| 支持 Webhook | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 自定义 Git 钩子 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 集成 AD / LDAP | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
|
|
|
@ -126,13 +126,13 @@ A "login prohibited" user is a user that is not allowed to log in to Gitea anymo
|
|||
|
||||
## What is Swagger?
|
||||
|
||||
[Swagger](https://swagger.io/) is what Gitea uses for its API.
|
||||
[Swagger](https://swagger.io/) is what Gitea uses for its API documentation.
|
||||
|
||||
All Gitea instances have the built-in API, though it can be disabled by setting `ENABLE_SWAGGER` to `false` in the `api` section of your `app.ini`
|
||||
All Gitea instances have the built-in API and there is no way to disable it completely.
|
||||
You can, however, disable showing its documentation by setting `ENABLE_SWAGGER` to `false` in the `api` section of your `app.ini`.
|
||||
For more information, refer to Gitea's [API docs]({{< relref "doc/developers/api-usage.en-us.md" >}}).
|
||||
|
||||
For more information, refer to Gitea's [API docs]({{< relref "doc/developers/api-usage.en-us.md" >}})
|
||||
|
||||
[Swagger Example](https://try.gitea.io/api/swagger)
|
||||
You can see the latest API (for example) on <https://try.gitea.io/api/swagger>.
|
||||
|
||||
## Adjusting your server for public/private use
|
||||
|
||||
|
@ -214,13 +214,13 @@ Our translations are currently crowd-sourced on our [Crowdin project](https://cr
|
|||
|
||||
Whether you want to change a translation or add a new one, it will need to be there as all translations are overwritten in our CI via the Crowdin integration.
|
||||
|
||||
## Hooks aren't running
|
||||
## Push Hook / Webhook aren't running
|
||||
|
||||
If Gitea is not running hooks, a common cause is incorrect setup of SSH keys.
|
||||
If you can push but can't see push activities on the home dashboard, or the push doesn't trigger webhook, there are a few possibilities:
|
||||
|
||||
See [SSH Issues](#ssh-issues) for more information.
|
||||
|
||||
You can also try logging into the administration panel and running the `Resynchronize pre-receive, update and post-receive hooks of all repositories.` option.
|
||||
1. The git hooks are out of sync: run "Resynchronize pre-receive, update and post-receive hooks of all repositories" on the site admin panel
|
||||
2. The git repositories (and hooks) are stored on some filesystems (ex: mounted by NAS) which don't support script execution, make sure the filesystem supports `chmod a+x any-script`
|
||||
3. If you are using docker, make sure Docker Server (not the client) >= 20.10.6
|
||||
|
||||
## SSH issues
|
||||
|
||||
|
|
|
@ -97,12 +97,12 @@ chown root:git /etc/gitea
|
|||
chmod 770 /etc/gitea
|
||||
```
|
||||
|
||||
**NOTE:** `/etc/gitea` is temporarily set with write permissions for user `git` so that the web installer can write the configuration file. After the installation is finished, it is recommended to set permissions to read-only using:
|
||||
|
||||
```sh
|
||||
chmod 750 /etc/gitea
|
||||
chmod 640 /etc/gitea/app.ini
|
||||
```
|
||||
> **NOTE:** `/etc/gitea` is temporarily set with write permissions for user `git` so that the web installer can write the configuration file. After the installation is finished, it is recommended to set permissions to read-only using:
|
||||
>
|
||||
> ```sh
|
||||
> chmod 750 /etc/gitea
|
||||
> chmod 640 /etc/gitea/app.ini
|
||||
> ```
|
||||
|
||||
If you don't want the web installer to be able to write to the config file, it is possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`) however you will need to edit your config file manually to:
|
||||
|
||||
|
|
|
@ -127,6 +127,10 @@ npm dist-tag add test_package@1.0.2 release
|
|||
|
||||
The tag name must not be a valid version. All tag names which are parsable as a version are rejected.
|
||||
|
||||
## Search packages
|
||||
|
||||
The registry supports [searching](https://docs.npmjs.com/cli/v7/commands/npm-search/) but does not support special search qualifiers like `author:gitea`.
|
||||
|
||||
## Supported commands
|
||||
|
||||
```
|
||||
|
@ -136,4 +140,5 @@ npm publish
|
|||
npm unpublish
|
||||
npm dist-tag
|
||||
npm view
|
||||
npm search
|
||||
```
|
||||
|
|
|
@ -14,7 +14,7 @@ menu:
|
|||
|
||||
# NuGet Packages Repository
|
||||
|
||||
Publish [NuGet](https://www.nuget.org/) packages for your user or organization. The package registry supports [NuGet Symbol Packages](https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg) too.
|
||||
Publish [NuGet](https://www.nuget.org/) packages for your user or organization. The package registry supports the V2 and V3 API protocol and you can work with [NuGet Symbol Packages](https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg) too.
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
---
|
||||
date: "2021-09-02T16:00:00+08:00"
|
||||
title: "Upgrade from an old Gitea"
|
||||
aliases:
|
||||
- /en-us/upgrade/
|
||||
slug: "upgrade-from-gitea"
|
||||
weight: 10
|
||||
toc: false
|
||||
|
|
|
@ -13,6 +13,12 @@ menu:
|
|||
identifier: "reverse-proxies"
|
||||
---
|
||||
|
||||
# 反向代理
|
||||
|
||||
**目录**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## 使用 Nginx 作为反向代理服务
|
||||
|
||||
如果您想使用 Nginx 作为 Gitea 的反向代理服务,您可以参照以下 `nginx.conf` 配置中 `server` 的 `http` 部分:
|
||||
|
@ -24,6 +30,10 @@ server {
|
|||
|
||||
location / {
|
||||
proxy_pass http://localhost:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -41,6 +51,10 @@ server {
|
|||
location /git/ {
|
||||
# 注意: 反向代理后端 URL 的最后需要有一个路径符号
|
||||
proxy_pass http://localhost:3000/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -131,7 +131,8 @@ You can try it out using [the online demo](https://try.gitea.io/).
|
|||
- Environment variables
|
||||
- Command line options
|
||||
- Multi-language support ([21 languages](https://github.com/go-gitea/gitea/tree/main/options/locale))
|
||||
- [Mermaid](https://mermaidjs.github.io/) Diagram support
|
||||
- [Mermaid](https://mermaidjs.github.io/) diagrams in Markdown
|
||||
- Math syntax in Markdown
|
||||
- Mail service
|
||||
- Notifications
|
||||
- Registration confirmation
|
||||
|
@ -286,7 +287,7 @@ You can try it out using [the online demo](https://try.gitea.io/).
|
|||
- UI frameworks:
|
||||
- [jQuery](https://jquery.com)
|
||||
- [Fomantic UI](https://fomantic-ui.com)
|
||||
- [Vue2](https://vuejs.org)
|
||||
- [Vue3](https://vuejs.org)
|
||||
- and various components (see package.json)
|
||||
- Editors:
|
||||
- [CodeMirror](https://codemirror.net)
|
||||
|
|
|
@ -258,7 +258,7 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide
|
|||
- Interface graphique :
|
||||
- [jQuery](https://jquery.com)
|
||||
- [Fomantic UI](https://fomantic-ui.com)
|
||||
- [Vue2](https://vuejs.org)
|
||||
- [Vue3](https://vuejs.org)
|
||||
- [CodeMirror](https://codemirror.net)
|
||||
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
||||
- [Monaco Editor](https://microsoft.github.io/monaco-editor)
|
||||
|
|
|
@ -52,7 +52,7 @@ Gitea的首要目标是创建一个极易安装,运行非常快速,安装和
|
|||
- UI 框架:
|
||||
- [jQuery](https://jquery.com)
|
||||
- [Fomantic UI](https://fomantic-ui.com)
|
||||
- [Vue2](https://vuejs.org)
|
||||
- [Vue3](https://vuejs.org)
|
||||
- 更多组件参见 package.json
|
||||
- 编辑器:
|
||||
- [CodeMirror](https://codemirror.net)
|
||||
|
|
|
@ -271,7 +271,7 @@ Gitea 是從 [Gogs](http://gogs.io) Fork 出來的,請閱讀部落格文章 [G
|
|||
- UI 元件:
|
||||
- [jQuery](https://jquery.com)
|
||||
- [Fomantic UI](https://fomantic-ui.com)
|
||||
- [Vue2](https://vuejs.org)
|
||||
- [Vue3](https://vuejs.org)
|
||||
- [CodeMirror](https://codemirror.net)
|
||||
- [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
||||
- [Monaco Editor](https://microsoft.github.io/monaco-editor)
|
||||
|
|
4
docs/static/_redirects
vendored
4
docs/static/_redirects
vendored
|
@ -10,3 +10,7 @@ https://gitea-docs.netlify.com/* https://docs.gitea.io/:splat 302!
|
|||
/en-us/ci-cd/ /en-us/integrations/ 302!
|
||||
/en-us/third-party-tools/ /en-us/integrations/ 302!
|
||||
/en-us/make/ /en-us/hacking-on-gitea/ 302!
|
||||
/en-us/upgrade/ /en-us/upgrade-from-gitea/ 302!
|
||||
/fr-fr/upgrade/ /fr-fr/upgrade-from-gitea/ 302!
|
||||
/zh-cn/upgrade/ /zh-cn/upgrade-from-gitea/ 302!
|
||||
/zh-tw/upgrade/ /zh-tw/upgrade-from-gitea/ 302!
|
||||
|
|
23
docs/static/open-in-gitpod.svg
vendored
Normal file
23
docs/static/open-in-gitpod.svg
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<svg width="160" height="45" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d)">
|
||||
<rect x="2" y="2" width="156" height="40" rx="16" fill="#F9F9F9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.425 11.174c.604 1.114.233 2.53-.83 3.164l-6.986 4.166a.378.378 0 00-.18.325v6.748c0 .134.069.258.18.325l5.714 3.407c.11.066.244.066.354 0l5.714-3.407a.378.378 0 00.18-.325V21.29l-4.986 2.936c-1.067.628-2.416.231-3.015-.886-.6-1.118-.22-2.532.846-3.16l7.008-4.127c2.048-1.206 4.576.345 4.576 2.806v6.718c0 1.803-.924 3.467-2.42 4.36l-5.713 3.407a4.596 4.596 0 01-4.734 0l-5.714-3.408C18.924 29.044 18 27.38 18 25.576V18.83c0-1.803.924-3.467 2.42-4.36l6.985-4.165c1.063-.634 2.415-.245 3.02.87z" fill="url(#paint0_linear)"/>
|
||||
<path fill="#F9F9F9" d="M47 12.5h95v-1H47z"/>
|
||||
<path d="M52.538 27.752c2.744 0 4.844-1.876 4.844-5.152 0-3.108-2.1-5.152-4.844-5.152s-4.802 2.002-4.802 5.152c0 3.29 2.058 5.152 4.802 5.152zm0-1.554c-1.736 0-2.912-1.316-2.912-3.598 0-2.226 1.162-3.598 2.912-3.598s2.954 1.4 2.954 3.598c0 2.31-1.218 3.598-2.954 3.598zm7.89 4.158V27.22c0-.196-.013-.378-.055-.658.434.7 1.022 1.19 2.17 1.19 1.736 0 3.066-1.414 3.066-3.626 0-2.17-1.19-3.682-2.996-3.682-1.078 0-1.806.476-2.24 1.204.042-.28.056-.462.056-.672v-.308H58.72v9.688h1.708zm1.695-3.948c-1.036 0-1.764-.938-1.764-2.31 0-1.414.742-2.296 1.764-2.296 1.092 0 1.75.952 1.75 2.296 0 1.372-.7 2.31-1.75 2.31zm7.866 1.344c1.848 0 3.052-1.078 3.192-2.478h-1.736c-.112.714-.714 1.134-1.456 1.134-1.036 0-1.722-.826-1.736-1.904h4.97v-.378c0-2.226-1.204-3.682-3.29-3.682-1.988 0-3.43 1.47-3.43 3.626 0 2.366 1.442 3.682 3.486 3.682zm-1.75-4.48c.098-.896.756-1.554 1.68-1.554.924 0 1.526.63 1.554 1.554H68.24zm8.006 4.228v-4.004c0-.952.616-1.694 1.456-1.694.798 0 1.288.63 1.288 1.638v4.06h1.708v-4.312c0-1.68-.896-2.744-2.408-2.744-1.078 0-1.722.518-2.1 1.204.042-.266.056-.476.056-.672v-.308h-1.708V27.5h1.708zm8.911-7.868h1.792V17.84h-1.792v1.792zm.042 1.036V27.5h1.708v-6.832h-1.708zm5.097 6.832v-4.004c0-.952.616-1.694 1.456-1.694.798 0 1.288.63 1.288 1.638v4.06h1.708v-4.312c0-1.68-.896-2.744-2.408-2.744-1.078 0-1.722.518-2.1 1.204.042-.266.056-.476.056-.672v-.308h-1.708V27.5h1.708zm13.238.252c1.526 0 2.52-.658 2.982-1.54-.07.322-.098.644-.098.98v.308h1.68v-5.222h-4.34v1.554h2.66v.07c0 1.4-1.134 2.296-2.59 2.296-1.792 0-3.024-1.372-3.024-3.598s1.26-3.598 3.066-3.598c1.302 0 2.17.756 2.296 1.736h1.89c-.182-1.904-1.764-3.29-4.214-3.29-2.954 0-4.928 2.128-4.928 5.152 0 3.136 1.848 5.152 4.62 5.152zm6.063-8.12h1.792V17.84h-1.792v1.792zm.042 1.036V27.5h1.708v-6.832h-1.708zm6.413 6.958c.434 0 .84-.07 1.008-.126v-1.288c-.168.028-.35.042-.518.042-.728 0-1.008-.42-1.008-1.134v-3.094h1.68v-1.358h-1.68v-2.464h-1.708v2.464h-1.554v1.358h1.554v3.346c0 1.526.77 2.254 2.226 2.254zm3.961 2.73V27.22c0-.196-.014-.378-.056-.658.434.7 1.022 1.19 2.17 1.19 1.736 0 3.066-1.414 3.066-3.626 0-2.17-1.19-3.682-2.996-3.682-1.078 0-1.806.476-2.24 1.204.042-.28.056-.462.056-.672v-.308h-1.708v9.688h1.708zm1.694-3.948c-1.036 0-1.764-.938-1.764-2.31 0-1.414.742-2.296 1.764-2.296 1.092 0 1.75.952 1.75 2.296 0 1.372-.7 2.31-1.75 2.31zm7.88 1.344c2.058 0 3.514-1.372 3.514-3.64 0-2.24-1.456-3.668-3.514-3.668-2.044 0-3.5 1.428-3.5 3.668 0 2.268 1.442 3.64 3.5 3.64zm0-1.344c-1.064 0-1.764-.84-1.764-2.296 0-1.484.728-2.31 1.764-2.31 1.05 0 1.778.826 1.778 2.31 0 1.456-.714 2.296-1.778 2.296zm7.551 1.344c1.26 0 1.876-.686 2.142-1.19-.056.238-.056.42-.056.658v.28h1.708v-9.8h-1.708v3.276c0 .21 0 .42.056.672-.392-.658-1.05-1.204-2.114-1.204-1.596 0-3.15 1.218-3.15 3.668 0 2.408 1.316 3.64 3.122 3.64zm.406-1.344c-1.022 0-1.792-.896-1.792-2.31 0-1.358.77-2.296 1.792-2.296s1.778.896 1.778 2.296c0 1.372-.756 2.31-1.778 2.31z" fill="#12100C"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="33.806" y1="13.629" x2="22.389" y2="30.86" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFB45B"/>
|
||||
<stop offset="1" stop-color="#FF8A00"/>
|
||||
</linearGradient>
|
||||
<filter id="filter0_d" x="0" y=".5" width="160" height="44" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy=".5"/>
|
||||
<feGaussianBlur stdDeviation="1"/>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
88
go.mod
88
go.mod
|
@ -15,10 +15,10 @@ require (
|
|||
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/PuerkitoBio/goquery v1.8.0
|
||||
github.com/alecthomas/chroma v0.10.0
|
||||
github.com/blevesearch/bleve/v2 v2.3.2
|
||||
github.com/alecthomas/chroma/v2 v2.3.0
|
||||
github.com/blevesearch/bleve/v2 v2.3.4
|
||||
github.com/buildkite/terminal-to-html/v3 v3.7.0
|
||||
github.com/caddyserver/certmagic v0.17.0
|
||||
github.com/caddyserver/certmagic v0.17.2
|
||||
github.com/chi-middleware/proxy v1.1.1
|
||||
github.com/denisenkom/go-mssqldb v0.12.2
|
||||
github.com/djherbis/buffer v1.2.0
|
||||
|
@ -31,46 +31,46 @@ require (
|
|||
github.com/felixge/fgprof v0.9.3
|
||||
github.com/fsnotify/fsnotify v1.5.4
|
||||
github.com/gliderlabs/ssh v0.3.5
|
||||
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535
|
||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d
|
||||
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0
|
||||
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778
|
||||
github.com/go-chi/chi/v5 v5.0.7
|
||||
github.com/go-chi/cors v1.2.1
|
||||
github.com/go-enry/go-enry/v2 v2.8.2
|
||||
github.com/go-enry/go-enry/v2 v2.8.3
|
||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
|
||||
github.com/go-git/go-billy/v5 v5.3.1
|
||||
github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf
|
||||
github.com/go-ldap/ldap/v3 v3.4.4
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/go-swagger/go-swagger v0.30.0
|
||||
github.com/go-swagger/go-swagger v0.30.3
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.8.1
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
|
||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2
|
||||
github.com/google/go-github/v45 v45.0.0
|
||||
github.com/google/go-github/v45 v45.2.0
|
||||
github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/feeds v1.1.1
|
||||
github.com/gorilla/sessions v1.2.1
|
||||
github.com/hashicorp/go-version v1.4.0
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/huandu/xstrings v1.3.2
|
||||
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
||||
github.com/klauspost/compress v1.15.9
|
||||
github.com/klauspost/compress v1.15.11
|
||||
github.com/klauspost/cpuid/v2 v2.1.1
|
||||
github.com/lib/pq v1.10.6
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/markbates/goth v1.73.0
|
||||
github.com/mattn/go-isatty v0.0.16
|
||||
github.com/mattn/go-sqlite3 v1.14.13
|
||||
github.com/mattn/go-sqlite3 v1.14.15
|
||||
github.com/mholt/archiver/v3 v3.5.1
|
||||
github.com/microcosm-cc/bluemonday v1.0.19
|
||||
github.com/minio/minio-go/v7 v7.0.35
|
||||
github.com/msteinert/pam v1.0.0
|
||||
github.com/microcosm-cc/bluemonday v1.0.20
|
||||
github.com/minio/minio-go/v7 v7.0.39
|
||||
github.com/msteinert/pam v1.1.0
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/niklasfasching/go-org v1.6.5
|
||||
github.com/oliamb/cutter v0.2.2
|
||||
|
@ -79,30 +79,31 @@ require (
|
|||
github.com/pquerna/otp v1.3.0
|
||||
github.com/prometheus/client_golang v1.13.0
|
||||
github.com/quasoft/websspi v1.1.2
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.1
|
||||
github.com/sergi/go-diff v1.2.0
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tstranex/u2f v1.0.0
|
||||
github.com/unrolled/render v1.5.0
|
||||
github.com/urfave/cli v1.22.9
|
||||
github.com/urfave/cli v1.22.10
|
||||
github.com/xanzy/go-gitlab v0.73.1
|
||||
github.com/yohcop/openid-go v1.0.0
|
||||
github.com/yuin/goldmark v1.4.13
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594
|
||||
github.com/yuin/goldmark v1.5.2
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87
|
||||
github.com/yuin/goldmark-meta v1.1.0
|
||||
go.jolheiser.com/hcaptcha v0.0.4
|
||||
go.jolheiser.com/pwn v0.0.3
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
|
||||
golang.org/x/text v0.3.7
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
|
||||
golang.org/x/text v0.3.8
|
||||
golang.org/x/tools v0.1.12
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
mvdan.cc/xurls/v2 v2.4.0
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
xorm.io/builder v0.3.11
|
||||
|
@ -116,9 +117,9 @@ require (
|
|||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 // indirect
|
||||
github.com/RoaringBitmap/roaring v0.9.4 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad // indirect
|
||||
github.com/RoaringBitmap/roaring v1.2.1 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
|
@ -127,21 +128,22 @@ require (
|
|||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.2.2 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.3.3 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.0.3 // indirect
|
||||
github.com/blevesearch/geo v0.1.14 // indirect
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||
github.com/blevesearch/gtreap v0.1.1 // indirect
|
||||
github.com/blevesearch/mmap-go v1.0.3 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.0 // indirect
|
||||
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.2 // indirect
|
||||
github.com/blevesearch/segment v0.9.0 // indirect
|
||||
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect
|
||||
github.com/blevesearch/vellum v1.0.7 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.3.3 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.3.3 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.3.3 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.3.3 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.3.3 // indirect
|
||||
github.com/blevesearch/vellum v1.0.8 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.3.5 // indirect
|
||||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||
|
@ -166,7 +168,7 @@ require (
|
|||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
|
||||
github.com/fullstorydev/grpcurl v1.8.1 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
|
||||
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1 // indirect
|
||||
github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-enry/go-oniguruma v1.2.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
|
@ -185,6 +187,7 @@ require (
|
|||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
|
@ -218,7 +221,7 @@ require (
|
|||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/markbates/going v1.0.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mholt/acmez v1.0.4 // indirect
|
||||
github.com/miekg/dns v1.1.50 // indirect
|
||||
|
@ -236,12 +239,12 @@ require (
|
|||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/rivo/uniseg v0.3.4 // indirect
|
||||
github.com/rivo/uniseg v0.4.2 // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
|
@ -282,7 +285,7 @@ require (
|
|||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.23.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
|
||||
google.golang.org/grpc v1.47.0 // indirect
|
||||
|
@ -290,7 +293,6 @@ require (
|
|||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
||||
|
||||
|
|
174
go.sum
174
go.sum
|
@ -134,22 +134,24 @@ github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuN
|
|||
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
|
||||
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
|
||||
github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo=
|
||||
github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
||||
github.com/RoaringBitmap/roaring v1.2.1 h1:58/LJlg/81wfEHd5L9qsHduznOIhyv4qb1yWcSvVq9A=
|
||||
github.com/RoaringBitmap/roaring v1.2.1/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
|
@ -158,9 +160,12 @@ github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ
|
|||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=
|
||||
github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
|
||||
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
|
||||
github.com/alecthomas/chroma/v2 v2.3.0 h1:83xfxrnjv8eK+Cf8qZDzNo3PPF9IbTWHs7z28GY6D0U=
|
||||
github.com/alecthomas/chroma/v2 v2.3.0/go.mod h1:mZxeWZlxP2Dy+/8cBob2PYd8O2DwNAzave5AY7A2eQw=
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
|
||||
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
|
@ -215,28 +220,31 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
|
|||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE=
|
||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk=
|
||||
github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bits-and-blooms/bitset v1.3.3 h1:R1XWiopGiXf66xygsiLpzLo67xEYvMkHw3w+rCOSAwg=
|
||||
github.com/bits-and-blooms/bitset v1.3.3/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
|
||||
github.com/blevesearch/bleve/v2 v2.3.2 h1:BJUnMhi2nrkl+vboHmKfW+9l+tJSj39HeWa5c3BN3/Y=
|
||||
github.com/blevesearch/bleve/v2 v2.3.2/go.mod h1:96+xE5pZUOsr3Y4vHzV1cBC837xZCpwLlX0hrrxnvIg=
|
||||
github.com/blevesearch/bleve/v2 v2.3.4 h1:SSb7/cwGzo85LWX1jchIsXM8ZiNNMX3shT5lROM63ew=
|
||||
github.com/blevesearch/bleve/v2 v2.3.4/go.mod h1:Ot0zYum8XQRfPcwhae8bZmNyYubynsoMjVvl1jPqL30=
|
||||
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/bleve_index_api v1.0.1 h1:nx9++0hnyiGOHJwQQYfsUGzpRdEVE5LsylmmngQvaFk=
|
||||
github.com/blevesearch/bleve_index_api v1.0.1/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
|
||||
github.com/blevesearch/bleve_index_api v1.0.3 h1:DDSWaPXOZZJ2BB73ZTWjKxydAugjwywcqU+91AAqcAg=
|
||||
github.com/blevesearch/bleve_index_api v1.0.3/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/geo v0.1.13/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
|
||||
github.com/blevesearch/geo v0.1.14 h1:TTDpJN6l9ck/cUYbXSn4aCElNls0Whe44rcQKsB7EfU=
|
||||
github.com/blevesearch/geo v0.1.14/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
|
||||
github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||
github.com/blevesearch/goleveldb v1.0.1/go.mod h1:WrU8ltZbIp0wAoig/MHbrPCXSOLpe79nz5lv5nqfYrQ=
|
||||
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
||||
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
||||
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
|
||||
github.com/blevesearch/mmap-go v1.0.3 h1:7QkALgFNooSq3a46AE+pWeKASAZc9SiNFJhDGF1NDx4=
|
||||
github.com/blevesearch/mmap-go v1.0.3/go.mod h1:pYvKl/grLQrBxuaRYgoTssa4rVujYYeenDp++2E+yvs=
|
||||
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
||||
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.0 h1:NFwteOpZEvJk5Vg0H6gD0hxupsG3JYocE4DBvsA2GZI=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.0/go.mod h1:uch7xyyO/Alxkuxa+CGs79vw0QY8BENSBjg6Mw5L5DE=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.2 h1:TAte9VZLWda5WAVlZTTZ+GCzEHqGJb4iB2aiZSA6Iv8=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.2/go.mod h1:rvoQXZGq8drq7vXbNeyiRzdEOwZkjkiYGf1822i6CRA=
|
||||
github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac=
|
||||
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
||||
github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg=
|
||||
|
@ -246,23 +254,23 @@ github.com/blevesearch/upsidedown_store_api v1.0.1 h1:1SYRwyoFLwG3sj0ed89RLtM15a
|
|||
github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
|
||||
github.com/blevesearch/vellum v1.0.3/go.mod h1:2u5ax02KeDuNWu4/C+hVQMD6uLN4txH1JbtpaDNLJRo=
|
||||
github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRvNBlNMrEVgY=
|
||||
github.com/blevesearch/vellum v1.0.7 h1:+vn8rfyCRHxKVRgDLeR0FAXej2+6mEb5Q15aQE/XESQ=
|
||||
github.com/blevesearch/vellum v1.0.7/go.mod h1:doBZpmRhwTsASB4QdUZANlJvqVAUdUyX0ZK7QJCTeBE=
|
||||
github.com/blevesearch/vellum v1.0.8 h1:iMGh4lfxza4BnWO/UJTMPlI3HsK9YawjPv+TteVa9ck=
|
||||
github.com/blevesearch/vellum v1.0.8/go.mod h1:+cpRi/tqq49xUYSQN2P7A5zNSNrS+MscLeeaZ3J46UA=
|
||||
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
|
||||
github.com/blevesearch/zapx/v11 v11.3.3 h1:8vQMO5hdA2qPCmicIMuKS+qcvUAEh6Vcb0uve4Nh8e4=
|
||||
github.com/blevesearch/zapx/v11 v11.3.3/go.mod h1:YzTfUm4kS3e8OmTXDHVV8OzC5MWPO/VPJZQgPNVb4Lc=
|
||||
github.com/blevesearch/zapx/v11 v11.3.5 h1:eBQWQ7huA+mzm0sAGnZDwgGGli7S45EO+N+ObFWssbI=
|
||||
github.com/blevesearch/zapx/v11 v11.3.5/go.mod h1:5UdIa/HRMdeRCiLQOyFESsnqBGiip7vQmYReA9toevU=
|
||||
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
|
||||
github.com/blevesearch/zapx/v12 v12.3.3 h1:MQO5YNI8MqdPz12ALCoXiJw5cl9QQamYZSp285Z/+Mo=
|
||||
github.com/blevesearch/zapx/v12 v12.3.3/go.mod h1:RMl6lOZqF+sTxKvhQDJ5yK2LT3Mu7E2p/jGdjAaiRxs=
|
||||
github.com/blevesearch/zapx/v12 v12.3.5 h1:5pX2hU+R1aZihT7ac1dNWh1n4wqkIM9pZzWp0ANED9s=
|
||||
github.com/blevesearch/zapx/v12 v12.3.5/go.mod h1:ANcthYRZQycpbRut/6ArF5gP5HxQyJqiFcuJCBju/ss=
|
||||
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
|
||||
github.com/blevesearch/zapx/v13 v13.3.3 h1:TS4xpMK1ARPYHq+1WwuEOKMOiwvKpTK3RuWOkKlI7BE=
|
||||
github.com/blevesearch/zapx/v13 v13.3.3/go.mod h1:eppobNM35U4C22yDvTuxV9xPqo10pwfP/jugL4INWG4=
|
||||
github.com/blevesearch/zapx/v13 v13.3.5 h1:eJ3gbD+Nu8p36/O6lhfdvWQ4pxsGYSuTOBrLLPVWJ74=
|
||||
github.com/blevesearch/zapx/v13 v13.3.5/go.mod h1:FV+dRnScFgKnRDIp08RQL4JhVXt1x2HE3AOzqYa6fjo=
|
||||
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
|
||||
github.com/blevesearch/zapx/v14 v14.3.3 h1:dqqAzGphKl0yehHKKntDHKlEMhi9B/tJrD4OsWpY7YE=
|
||||
github.com/blevesearch/zapx/v14 v14.3.3/go.mod h1:zXNcVzukh0AvG57oUtT1T0ndi09H0kELNaNmekEy0jw=
|
||||
github.com/blevesearch/zapx/v14 v14.3.5 h1:hEvVjZaagFCvOUJrlFQ6/Z6Jjy0opM3g7TMEo58TwP4=
|
||||
github.com/blevesearch/zapx/v14 v14.3.5/go.mod h1:954A/eKFb+pg/ncIYWLWCKY+mIjReM9FGTGIO2Wu1cU=
|
||||
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
|
||||
github.com/blevesearch/zapx/v15 v15.3.3 h1:60oE+qsJkveLenJmbc0eaH59GWYCbJJsPDV6Z5hEoYY=
|
||||
github.com/blevesearch/zapx/v15 v15.3.3/go.mod h1:C+f/97ZzTzK6vt/7sVlZdzZxKu+5+j4SrGCvr9dJzaY=
|
||||
github.com/blevesearch/zapx/v15 v15.3.5 h1:NVD0qq8vRk66ImJn1KloXT5ckqPDUZT7VbVJs9jKlac=
|
||||
github.com/blevesearch/zapx/v15 v15.3.5/go.mod h1:QMUh2hXCaYIWFKPYGavq/Iga2zbHWZ9DZAa9uFbWyvg=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
|
@ -274,8 +282,8 @@ github.com/buildkite/terminal-to-html/v3 v3.7.0/go.mod h1:g0ME1XqbkBSgXR9YmlIHcJ
|
|||
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw=
|
||||
github.com/caddyserver/certmagic v0.17.0 h1:AHHvvmv6SNcq0vK5BgCevQqYMV8GNprVk6FWZzx8d+Q=
|
||||
github.com/caddyserver/certmagic v0.17.0/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM=
|
||||
github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE=
|
||||
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
|
||||
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A=
|
||||
|
@ -463,12 +471,12 @@ github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
|||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535 h1:vzEChLhjI35zDlXG9KZnOMCHa9MRVaagS5IHJcagVRI=
|
||||
github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535/go.mod h1:y3eWqPv2lYZ0YbAvEk4CGyFUJzbNsoLmkon8S7ZyX6I=
|
||||
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1 h1:PkPVIQGt76HHFWSeUINXCfYpEnzlSS+AQyuXi7oJ/gM=
|
||||
github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1/go.mod h1:KHkKFKZvc05lr79+RGoq/zG8YjWi3+FK60Bxd+mpCew=
|
||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d h1:Z/oRXMlZHjvjIqDma1FrIGL3iE5YL7MUI0bwYEZ6qbA=
|
||||
github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA=
|
||||
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0 h1:EUMB0x7u3de/ikGBtXiLxaJbmxgiqiAcM4yjW4whApM=
|
||||
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0/go.mod h1:OX9ajs2vU4UauC/DlghS/8M468Kn79r+y9kB6j7LuGM=
|
||||
github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18 h1:A48SbkWKEciiJMbbcPzaRj9aizPUABzXFvCM3LtGGf8=
|
||||
github.com/go-ap/errors v0.0.0-20220917143055-4283ea5dae18/go.mod h1:dd3ZgjjloBsKPDpqA2kf2VWhF0A1eKUItOBh0/QcDWI=
|
||||
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778 h1:0tV3i8tE1NghMC4rXZXfD39KUbkKgIyLTsvOEmMOPCQ=
|
||||
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
|
@ -477,8 +485,8 @@ github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
|
|||
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-enry/go-enry/v2 v2.8.2 h1:uiGmC+3K8sVd/6DOe2AOJEOihJdqda83nPyJNtMR8RI=
|
||||
github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
||||
github.com/go-enry/go-enry/v2 v2.8.3 h1:BwvNrN58JqBJhyyVdZSl5QD3xoxEEGYUrRyPh31FGhw=
|
||||
github.com/go-enry/go-enry/v2 v2.8.3/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
||||
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
||||
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8=
|
||||
|
@ -556,8 +564,8 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC
|
|||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
|
||||
github.com/go-swagger/go-swagger v0.30.0 h1:HakSyutD7Ek9ndkR8Fxy6WAoQtgu7UcAmZCTa6SzawA=
|
||||
github.com/go-swagger/go-swagger v0.30.0/go.mod h1:GhZVX/KIBM4VpGp4P7AJOIrlTuBeRVPS+j9kk6rFmfY=
|
||||
github.com/go-swagger/go-swagger v0.30.3 h1:HuzvdMRed/9Q8vmzVcfNBQByZVtT79DNZxZ18OprdoI=
|
||||
github.com/go-swagger/go-swagger v0.30.3/go.mod h1:neDPes8r8PCz2JPvHRDj8BTULLh4VJUt7n6MpQqxhHM=
|
||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.8.1 h1:uonwvepqRvSgddcrReZQhojTlWlmOlHkYAb9ZaOMWgU=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.8.1/go.mod h1:Kdu7YeMC0KRXVHdaQ91Vmx3pcjoTF63h4f1qTJDdXLA=
|
||||
|
@ -617,6 +625,8 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt
|
|||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
@ -684,8 +694,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
|
|||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
|
||||
github.com/google/go-github/v45 v45.0.0 h1:LU0WBjYidxIVyx7PZeWb+FP4JZJ3Wh3FQgdumnGqiLs=
|
||||
github.com/google/go-github/v45 v45.0.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28=
|
||||
github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI=
|
||||
github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28=
|
||||
github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
|
@ -693,6 +703,7 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
|
|||
github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
|
||||
github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/licenseclassifier v0.0.0-20210325184830-bb04aff29e72/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
|
@ -923,6 +934,7 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
|
|||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
|
@ -958,8 +970,8 @@ github.com/kisom/goutils v1.4.3/go.mod h1:Lp5qrquG7yhYnWzZCI/68Pa/GpFynw//od6EkG
|
|||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
|
||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
|
||||
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
|
@ -998,8 +1010,8 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
|
||||
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
||||
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
|
@ -1049,15 +1061,15 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
|
|||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I=
|
||||
github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
|
@ -1066,8 +1078,8 @@ github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80=
|
|||
github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY=
|
||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c=
|
||||
github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y=
|
||||
github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
|
@ -1075,8 +1087,8 @@ github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT
|
|||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.35 h1:JuPPxWLdxQmNLSaS8AWZnO5HBadeI1xg6FGrEELQEVU=
|
||||
github.com/minio/minio-go/v7 v7.0.35/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw=
|
||||
github.com/minio/minio-go/v7 v7.0.39 h1:upnbu1jCGOqEvrGSpRauSN9ZG7RCHK7VHxXS8Vmg2zk=
|
||||
github.com/minio/minio-go/v7 v7.0.39/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw=
|
||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
|
@ -1116,8 +1128,8 @@ github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450/go.mod h1:skjdDftzkF
|
|||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
||||
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
||||
github.com/msteinert/pam v1.0.0 h1:4XoXKtMCH3+e6GIkW41uxm6B37eYqci/DH3gzSq7ocg=
|
||||
github.com/msteinert/pam v1.0.0/go.mod h1:M4FPeAW8g2ITO68W8gACDz13NDJyOQM9IQsQhrR6TOI=
|
||||
github.com/msteinert/pam v1.1.0 h1:VhLun/0n0kQYxiRBJJvVpC2jR6d21SWJFjpvUVj20Kc=
|
||||
github.com/msteinert/pam v1.1.0/go.mod h1:M4FPeAW8g2ITO68W8gACDz13NDJyOQM9IQsQhrR6TOI=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
|
||||
|
@ -1197,8 +1209,8 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG
|
|||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
|
||||
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
@ -1269,8 +1281,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
|
|||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
|
||||
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
|
||||
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
|
@ -1294,8 +1306,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
|||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.1 h1:HNLA3HtUIROrQwG1cuu5EYuqk3UEoJ61Dr/9xkd6sok=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.1/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
||||
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
|
@ -1430,8 +1442,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
|||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw=
|
||||
github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
|
||||
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
|
||||
|
@ -1467,11 +1479,11 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.5/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
|
||||
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594 h1:yHfZyN55+5dp1wG7wDKv8HQ044moxkyGq12KFFMFDxg=
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594/go.mod h1:U9ihbh+1ZN7fR5Se3daSPoz1CGF9IYtSvWwVQtnzGHU=
|
||||
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU=
|
||||
github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87 h1:Py16JEzkSdKAtEFJjiaYLYBOWGXc1r/xHj/Q/5lA37k=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
|
||||
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
|
||||
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
|
@ -1596,8 +1608,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0
|
|||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -1708,8 +1720,9 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
|||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -1734,8 +1747,8 @@ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j
|
|||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8=
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -1863,8 +1876,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -1878,16 +1891,17 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
export default {
|
||||
rootDir: 'web_src',
|
||||
setupFilesAfterEnv: ['jest-extended/all'],
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
testMatch: ['<rootDir>/**/*.test.js'],
|
||||
testTimeout: 20000,
|
||||
transform: {
|
||||
'\\.svg$': '<rootDir>/js/testUtils/jestRawLoader.js',
|
||||
},
|
||||
verbose: false,
|
||||
};
|
||||
|
|
@ -218,6 +218,11 @@ func (a *Action) GetRepoLink() string {
|
|||
return path.Join(setting.AppSubURL, "/", url.PathEscape(a.GetRepoUserName()), url.PathEscape(a.GetRepoName()))
|
||||
}
|
||||
|
||||
// GetRepoAbsoluteLink returns the absolute link to action repository.
|
||||
func (a *Action) GetRepoAbsoluteLink() string {
|
||||
return setting.AppURL + url.PathEscape(a.GetRepoUserName()) + "/" + url.PathEscape(a.GetRepoName())
|
||||
}
|
||||
|
||||
// GetCommentLink returns link to action comment.
|
||||
func (a *Action) GetCommentLink() string {
|
||||
return a.getCommentLink(db.DefaultContext)
|
||||
|
|
|
@ -18,13 +18,11 @@ import (
|
|||
type ActionList []*Action
|
||||
|
||||
func (actions ActionList) getUserIDs() []int64 {
|
||||
userIDs := make(map[int64]struct{}, len(actions))
|
||||
userIDs := make(container.Set[int64], len(actions))
|
||||
for _, action := range actions {
|
||||
if _, ok := userIDs[action.ActUserID]; !ok {
|
||||
userIDs[action.ActUserID] = struct{}{}
|
||||
userIDs.Add(action.ActUserID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(userIDs)
|
||||
return userIDs.Values()
|
||||
}
|
||||
|
||||
func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) {
|
||||
|
@ -48,13 +46,11 @@ func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.
|
|||
}
|
||||
|
||||
func (actions ActionList) getRepoIDs() []int64 {
|
||||
repoIDs := make(map[int64]struct{}, len(actions))
|
||||
repoIDs := make(container.Set[int64], len(actions))
|
||||
for _, action := range actions {
|
||||
if _, ok := repoIDs[action.RepoID]; !ok {
|
||||
repoIDs[action.RepoID] = struct{}{}
|
||||
repoIDs.Add(action.RepoID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(repoIDs)
|
||||
return repoIDs.Values()
|
||||
}
|
||||
|
||||
func (actions ActionList) loadRepositories(ctx context.Context) error {
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
activities_model "code.gitea.io/gitea/models/activities"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issue_model "code.gitea.io/gitea/models/issues"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
@ -20,7 +21,7 @@ import (
|
|||
|
||||
func TestAction_GetRepoPath(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{})
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||
action := &activities_model.Action{RepoID: repo.ID}
|
||||
assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath())
|
||||
|
@ -28,12 +29,15 @@ func TestAction_GetRepoPath(t *testing.T) {
|
|||
|
||||
func TestAction_GetRepoLink(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{})
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||
action := &activities_model.Action{RepoID: repo.ID}
|
||||
comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{ID: 2})
|
||||
action := &activities_model.Action{RepoID: repo.ID, CommentID: comment.ID}
|
||||
setting.AppSubURL = "/suburl"
|
||||
expected := path.Join(setting.AppSubURL, owner.Name, repo.Name)
|
||||
assert.Equal(t, expected, action.GetRepoLink())
|
||||
assert.Equal(t, repo.HTMLURL(), action.GetRepoAbsoluteLink())
|
||||
assert.Equal(t, comment.HTMLURL(), action.GetCommentLink())
|
||||
}
|
||||
|
||||
func TestGetFeeds(t *testing.T) {
|
||||
|
|
|
@ -200,7 +200,7 @@ func CreateOrUpdateIssueNotifications(issueID, commentID, notificationAuthorID,
|
|||
|
||||
func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error {
|
||||
// init
|
||||
var toNotify map[int64]struct{}
|
||||
var toNotify container.Set[int64]
|
||||
notifications, err := getNotificationsByIssueID(ctx, issueID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -212,33 +212,27 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
|
|||
}
|
||||
|
||||
if receiverID > 0 {
|
||||
toNotify = make(map[int64]struct{}, 1)
|
||||
toNotify[receiverID] = struct{}{}
|
||||
toNotify = make(container.Set[int64], 1)
|
||||
toNotify.Add(receiverID)
|
||||
} else {
|
||||
toNotify = make(map[int64]struct{}, 32)
|
||||
toNotify = make(container.Set[int64], 32)
|
||||
issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, id := range issueWatches {
|
||||
toNotify[id] = struct{}{}
|
||||
}
|
||||
toNotify.AddMultiple(issueWatches...)
|
||||
if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) {
|
||||
repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, id := range repoWatches {
|
||||
toNotify[id] = struct{}{}
|
||||
}
|
||||
toNotify.AddMultiple(repoWatches...)
|
||||
}
|
||||
issueParticipants, err := issue.GetParticipantIDsByIssue(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, id := range issueParticipants {
|
||||
toNotify[id] = struct{}{}
|
||||
}
|
||||
toNotify.AddMultiple(issueParticipants...)
|
||||
|
||||
// dont notify user who cause notification
|
||||
delete(toNotify, notificationAuthorID)
|
||||
|
@ -248,7 +242,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
|
|||
return err
|
||||
}
|
||||
for _, id := range issueUnWatches {
|
||||
delete(toNotify, id)
|
||||
toNotify.Remove(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,16 +493,14 @@ func (nl NotificationList) LoadAttributes() error {
|
|||
}
|
||||
|
||||
func (nl NotificationList) getPendingRepoIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(nl))
|
||||
ids := make(container.Set[int64], len(nl))
|
||||
for _, notification := range nl {
|
||||
if notification.Repository != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[notification.RepoID]; !ok {
|
||||
ids[notification.RepoID] = struct{}{}
|
||||
ids.Add(notification.RepoID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
// LoadRepos loads repositories from database
|
||||
|
@ -575,16 +567,14 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error)
|
|||
}
|
||||
|
||||
func (nl NotificationList) getPendingIssueIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(nl))
|
||||
ids := make(container.Set[int64], len(nl))
|
||||
for _, notification := range nl {
|
||||
if notification.Issue != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[notification.IssueID]; !ok {
|
||||
ids[notification.IssueID] = struct{}{}
|
||||
ids.Add(notification.IssueID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
// LoadIssues loads issues from database
|
||||
|
@ -661,16 +651,14 @@ func (nl NotificationList) Without(failures []int) NotificationList {
|
|||
}
|
||||
|
||||
func (nl NotificationList) getPendingCommentIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(nl))
|
||||
ids := make(container.Set[int64], len(nl))
|
||||
for _, notification := range nl {
|
||||
if notification.CommentID == 0 || notification.Comment != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[notification.CommentID]; !ok {
|
||||
ids[notification.CommentID] = struct{}{}
|
||||
ids.Add(notification.CommentID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
// LoadComments loads comments from database
|
||||
|
|
|
@ -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})
|
||||
}
|
|
@ -10,6 +10,7 @@ import (
|
|||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
|
@ -56,6 +57,18 @@ func (app *OAuth2Application) PrimaryRedirectURI() string {
|
|||
|
||||
// ContainsRedirectURI checks if redirectURI is allowed for app
|
||||
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
|
||||
uri, err := url.Parse(redirectURI)
|
||||
// ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
|
||||
if err == nil && uri.Scheme == "http" && uri.Port() != "" {
|
||||
ip := net.ParseIP(uri.Hostname())
|
||||
if ip != nil && ip.IsLoopback() {
|
||||
// strip port
|
||||
uri.Host = uri.Hostname()
|
||||
if util.IsStringInSlice(uri.String(), app.RedirectURIs, true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return util.IsStringInSlice(redirectURI, app.RedirectURIs, true)
|
||||
}
|
||||
|
||||
|
@ -212,7 +225,8 @@ func updateOAuth2Application(ctx context.Context, app *OAuth2Application) error
|
|||
|
||||
func deleteOAuth2Application(ctx context.Context, id, userid int64) error {
|
||||
sess := db.GetEngine(ctx)
|
||||
if deleted, err := sess.Delete(&OAuth2Application{ID: id, UID: userid}); err != nil {
|
||||
// the userid could be 0 if the app is instance-wide
|
||||
if deleted, err := sess.Where(builder.Eq{"id": id, "uid": userid}).Delete(&OAuth2Application{}); err != nil {
|
||||
return err
|
||||
} else if deleted == 0 {
|
||||
return ErrOAuthApplicationNotFound{ID: id}
|
||||
|
@ -463,7 +477,7 @@ func GetOAuth2GrantsByUserID(ctx context.Context, uid int64) ([]*OAuth2Grant, er
|
|||
|
||||
// RevokeOAuth2Grant deletes the grant with grantID and userID
|
||||
func RevokeOAuth2Grant(ctx context.Context, grantID, userID int64) error {
|
||||
_, err := db.DeleteByBean(ctx, &OAuth2Grant{ID: grantID, UserID: userID})
|
||||
_, err := db.GetEngine(ctx).Where(builder.Eq{"id": grantID, "user_id": userID}).Delete(&OAuth2Grant{})
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,26 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) {
|
|||
assert.False(t, app.ContainsRedirectURI("d"))
|
||||
}
|
||||
|
||||
func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
|
||||
app := &auth_model.OAuth2Application{
|
||||
RedirectURIs: []string{"http://127.0.0.1/", "http://::1/", "http://192.168.0.1/", "http://intranet/", "https://127.0.0.1/"},
|
||||
}
|
||||
|
||||
// http loopback uris should ignore port
|
||||
// https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
|
||||
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1:3456/"))
|
||||
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
|
||||
assert.True(t, app.ContainsRedirectURI("http://[::1]:3456/"))
|
||||
|
||||
// not http
|
||||
assert.False(t, app.ContainsRedirectURI("https://127.0.0.1:3456/"))
|
||||
// not loopback
|
||||
assert.False(t, app.ContainsRedirectURI("http://192.168.0.1:9954/"))
|
||||
assert.False(t, app.ContainsRedirectURI("http://intranet:3456/"))
|
||||
// unparseable
|
||||
assert.False(t, app.ContainsRedirectURI(":"))
|
||||
}
|
||||
|
||||
func TestOAuth2Application_ValidateClientSecret(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
@ -72,7 +73,7 @@ func GetEmailForHash(md5Sum string) (string, error) {
|
|||
// LibravatarURL returns the URL for the given email. Slow due to the DNS lookup.
|
||||
// This function should only be called if a federated avatar service is enabled.
|
||||
func LibravatarURL(email string) (*url.URL, error) {
|
||||
urlStr, err := setting.LibravatarService.FromEmail(email)
|
||||
urlStr, err := system_model.LibravatarService.FromEmail(email)
|
||||
if err != nil {
|
||||
log.Error("LibravatarService.FromEmail(email=%s): error %v", email, err)
|
||||
return nil, err
|
||||
|
@ -149,8 +150,10 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
|
|||
return DefaultAvatarLink()
|
||||
}
|
||||
|
||||
enableFederatedAvatar, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar)
|
||||
|
||||
var err error
|
||||
if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
|
||||
if enableFederatedAvatar != nil && enableFederatedAvatar.GetValueBool() && system_model.LibravatarService != nil {
|
||||
emailHash := saveEmailHash(email)
|
||||
if final {
|
||||
// for final link, we can spend more time on slow external query
|
||||
|
@ -166,12 +169,16 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
|
|||
urlStr += "?size=" + strconv.Itoa(size)
|
||||
}
|
||||
return urlStr
|
||||
} else if !setting.DisableGravatar {
|
||||
}
|
||||
|
||||
disableGravatar, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar)
|
||||
if disableGravatar != nil && !disableGravatar.GetValueBool() {
|
||||
// copy GravatarSourceURL, because we will modify its Path.
|
||||
avatarURLCopy := *setting.GravatarSourceURL
|
||||
avatarURLCopy := *system_model.GravatarSourceURL
|
||||
avatarURLCopy.Path = path.Join(avatarURLCopy.Path, HashEmail(email))
|
||||
return generateRecognizedAvatarURL(avatarURLCopy, size)
|
||||
}
|
||||
|
||||
return DefaultAvatarLink()
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package avatars
|
||||
package avatars_test
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
avatars_model "code.gitea.io/gitea/models/avatars"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -15,40 +16,43 @@ import (
|
|||
|
||||
const gravatarSource = "https://secure.gravatar.com/avatar/"
|
||||
|
||||
func disableGravatar() {
|
||||
setting.EnableFederatedAvatar = false
|
||||
setting.LibravatarService = nil
|
||||
setting.DisableGravatar = true
|
||||
func disableGravatar(t *testing.T) {
|
||||
err := system_model.SetSettingNoVersion(system_model.KeyPictureEnableFederatedAvatar, "false")
|
||||
assert.NoError(t, err)
|
||||
err = system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "true")
|
||||
assert.NoError(t, err)
|
||||
system_model.LibravatarService = nil
|
||||
}
|
||||
|
||||
func enableGravatar(t *testing.T) {
|
||||
setting.DisableGravatar = false
|
||||
var err error
|
||||
setting.GravatarSourceURL, err = url.Parse(gravatarSource)
|
||||
err := system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "false")
|
||||
assert.NoError(t, err)
|
||||
setting.GravatarSource = gravatarSource
|
||||
err = system_model.Init()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestHashEmail(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
"d41d8cd98f00b204e9800998ecf8427e",
|
||||
HashEmail(""),
|
||||
avatars_model.HashEmail(""),
|
||||
)
|
||||
assert.Equal(t,
|
||||
"353cbad9b58e69c96154ad99f92bedc7",
|
||||
HashEmail("gitea@example.com"),
|
||||
avatars_model.HashEmail("gitea@example.com"),
|
||||
)
|
||||
}
|
||||
|
||||
func TestSizedAvatarLink(t *testing.T) {
|
||||
setting.AppSubURL = "/testsuburl"
|
||||
|
||||
disableGravatar()
|
||||
disableGravatar(t)
|
||||
assert.Equal(t, "/testsuburl/assets/img/avatar_default.png",
|
||||
GenerateEmailAvatarFastLink("gitea@example.com", 100))
|
||||
avatars_model.GenerateEmailAvatarFastLink("gitea@example.com", 100))
|
||||
|
||||
enableGravatar(t)
|
||||
assert.Equal(t,
|
||||
"https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100",
|
||||
GenerateEmailAvatarFastLink("gitea@example.com", 100),
|
||||
avatars_model.GenerateEmailAvatarFastLink("gitea@example.com", 100),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package admin_test
|
||||
package avatars_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
|
@ -8,45 +8,15 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
// ResourceIndex represents a resource index which could be used as issue/release and others
|
||||
// We can create different tables i.e. issue_index, release_index and etc.
|
||||
// We can create different tables i.e. issue_index, release_index, etc.
|
||||
type ResourceIndex struct {
|
||||
GroupID int64 `xorm:"pk"`
|
||||
MaxIndex int64 `xorm:"index"`
|
||||
}
|
||||
|
||||
// UpsertResourceIndex the function will not return until it acquires the lock or receives an error.
|
||||
func UpsertResourceIndex(ctx context.Context, tableName string, groupID int64) (err error) {
|
||||
// An atomic UPSERT operation (INSERT/UPDATE) is the only operation
|
||||
// that ensures that the key is actually locked.
|
||||
switch {
|
||||
case setting.Database.UseSQLite3 || setting.Database.UsePostgreSQL:
|
||||
_, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+
|
||||
"VALUES (?,1) ON CONFLICT (group_id) DO UPDATE SET max_index = %s.max_index+1",
|
||||
tableName, tableName), groupID)
|
||||
case setting.Database.UseMySQL:
|
||||
_, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+
|
||||
"VALUES (?,1) ON DUPLICATE KEY UPDATE max_index = max_index+1", tableName),
|
||||
groupID)
|
||||
case setting.Database.UseMSSQL:
|
||||
// https://weblogs.sqlteam.com/dang/2009/01/31/upsert-race-condition-with-merge/
|
||||
_, err = Exec(ctx, fmt.Sprintf("MERGE %s WITH (HOLDLOCK) as target "+
|
||||
"USING (SELECT ? AS group_id) AS src "+
|
||||
"ON src.group_id = target.group_id "+
|
||||
"WHEN MATCHED THEN UPDATE SET target.max_index = target.max_index+1 "+
|
||||
"WHEN NOT MATCHED THEN INSERT (group_id, max_index) "+
|
||||
"VALUES (src.group_id, 1);", tableName),
|
||||
groupID)
|
||||
default:
|
||||
return fmt.Errorf("database type not supported")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrResouceOutdated represents an error when request resource outdated
|
||||
ErrResouceOutdated = errors.New("resource outdated")
|
||||
|
@ -59,53 +29,85 @@ const (
|
|||
MaxDupIndexAttempts = 3
|
||||
)
|
||||
|
||||
// GetNextResourceIndex retried 3 times to generate a resource index
|
||||
func GetNextResourceIndex(tableName string, groupID int64) (int64, error) {
|
||||
for i := 0; i < MaxDupIndexAttempts; i++ {
|
||||
idx, err := getNextResourceIndex(tableName, groupID)
|
||||
if err == ErrResouceOutdated {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return idx, nil
|
||||
}
|
||||
return 0, ErrGetResourceIndexFailed
|
||||
}
|
||||
// SyncMaxResourceIndex sync the max index with the resource
|
||||
func SyncMaxResourceIndex(ctx context.Context, tableName string, groupID, maxIndex int64) (err error) {
|
||||
e := GetEngine(ctx)
|
||||
|
||||
// DeleteResouceIndex delete resource index
|
||||
func DeleteResouceIndex(ctx context.Context, tableName string, groupID int64) error {
|
||||
_, err := Exec(ctx, fmt.Sprintf("DELETE FROM %s WHERE group_id=?", tableName), groupID)
|
||||
// try to update the max_index and acquire the write-lock for the record
|
||||
res, err := e.Exec(fmt.Sprintf("UPDATE %s SET max_index=? WHERE group_id=? AND max_index<?", tableName), maxIndex, groupID, maxIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// getNextResourceIndex return the next index
|
||||
func getNextResourceIndex(tableName string, groupID int64) (int64, error) {
|
||||
ctx, commiter, err := TxContext()
|
||||
// GetNextResourceIndex generates a resource index, it must run in the same transaction where the resource is created
|
||||
func GetNextResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
|
||||
e := GetEngine(ctx)
|
||||
|
||||
// try to update the max_index to next value, and acquire the write-lock for the record
|
||||
res, err := e.Exec(fmt.Sprintf("UPDATE %s SET max_index=max_index+1 WHERE group_id=?", tableName), groupID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer commiter.Close()
|
||||
var preIdx int64
|
||||
if _, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&preIdx); err != nil {
|
||||
affected, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err := UpsertResourceIndex(ctx, tableName, groupID); err != nil {
|
||||
if affected == 0 {
|
||||
// this slow path is only for the first time of creating a resource index
|
||||
_, errIns := e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) VALUES (?, 0)", tableName), groupID)
|
||||
res, err = e.Exec(fmt.Sprintf("UPDATE %s SET max_index=max_index+1 WHERE group_id=?", tableName), groupID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
affected, err = res.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// if the update still can not update any records, the record must not exist and there must be some errors (insert error)
|
||||
if affected == 0 {
|
||||
if errIns == nil {
|
||||
return 0, errors.New("impossible error when GetNextResourceIndex, insert and update both succeeded but no record is updated")
|
||||
}
|
||||
return 0, errIns
|
||||
}
|
||||
}
|
||||
|
||||
var curIdx int64
|
||||
has, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ? AND max_index=?", tableName), groupID, preIdx+1).Get(&curIdx)
|
||||
// now, the new index is in database (protected by the transaction and write-lock)
|
||||
var newIdx int64
|
||||
has, err := e.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id=?", tableName), groupID).Get(&newIdx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !has {
|
||||
return 0, ErrResouceOutdated
|
||||
return 0, errors.New("impossible error when GetNextResourceIndex, upsert succeeded but no record can be selected")
|
||||
}
|
||||
if err := commiter.Commit(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return curIdx, nil
|
||||
return newIdx, nil
|
||||
}
|
||||
|
||||
// DeleteResourceIndex delete resource index
|
||||
func DeleteResourceIndex(ctx context.Context, tableName string, groupID int64) error {
|
||||
_, err := Exec(ctx, fmt.Sprintf("DELETE FROM %s WHERE group_id=?", tableName), groupID)
|
||||
return err
|
||||
}
|
||||
|
|
127
models/db/index_test.go
Normal file
127
models/db/index_test.go
Normal file
|
@ -0,0 +1,127 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package db_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TestIndex db.ResourceIndex
|
||||
|
||||
func getCurrentResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
|
||||
e := db.GetEngine(ctx)
|
||||
var idx int64
|
||||
has, err := e.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id=?", tableName), groupID).Get(&idx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !has {
|
||||
return 0, errors.New("no record")
|
||||
}
|
||||
return idx, nil
|
||||
}
|
||||
|
||||
func TestSyncMaxResourceIndex(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
xe := unittest.GetXORMEngine()
|
||||
assert.NoError(t, xe.Sync(&TestIndex{}))
|
||||
|
||||
err := db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 51)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// sync new max index
|
||||
maxIndex, err := getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 51, maxIndex)
|
||||
|
||||
// smaller index doesn't change
|
||||
err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 30)
|
||||
assert.NoError(t, err)
|
||||
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 51, maxIndex)
|
||||
|
||||
// larger index changes
|
||||
err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 62)
|
||||
assert.NoError(t, err)
|
||||
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 62, maxIndex)
|
||||
|
||||
// commit transaction
|
||||
err = db.WithTx(func(ctx context.Context) error {
|
||||
err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 73)
|
||||
assert.NoError(t, err)
|
||||
maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 73, maxIndex)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 73, maxIndex)
|
||||
|
||||
// rollback transaction
|
||||
err = db.WithTx(func(ctx context.Context) error {
|
||||
err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 84)
|
||||
maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 84, maxIndex)
|
||||
return errors.New("test rollback")
|
||||
})
|
||||
assert.Error(t, err)
|
||||
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 73, maxIndex) // the max index doesn't change because the transaction was rolled back
|
||||
}
|
||||
|
||||
func TestGetNextResourceIndex(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
xe := unittest.GetXORMEngine()
|
||||
assert.NoError(t, xe.Sync(&TestIndex{}))
|
||||
|
||||
// create a new record
|
||||
maxIndex, err := db.GetNextResourceIndex(db.DefaultContext, "test_index", 20)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, maxIndex)
|
||||
|
||||
// increase the existing record
|
||||
maxIndex, err = db.GetNextResourceIndex(db.DefaultContext, "test_index", 20)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 2, maxIndex)
|
||||
|
||||
// commit transaction
|
||||
err = db.WithTx(func(ctx context.Context) error {
|
||||
maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 3, maxIndex)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 3, maxIndex)
|
||||
|
||||
// rollback transaction
|
||||
err = db.WithTx(func(ctx context.Context) error {
|
||||
maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 4, maxIndex)
|
||||
return errors.New("test rollback")
|
||||
})
|
||||
assert.Error(t, err)
|
||||
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 3, maxIndex) // the max index doesn't change because the transaction was rolled back
|
||||
}
|
|
@ -124,3 +124,15 @@
|
|||
repo_id: 24
|
||||
mode: 1
|
||||
|
||||
-
|
||||
id: 22
|
||||
user_id: 31
|
||||
repo_id: 27
|
||||
mode: 4
|
||||
|
||||
-
|
||||
id: 23
|
||||
user_id: 31
|
||||
repo_id: 28
|
||||
mode: 4
|
||||
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
|
||||
repo_id: 1
|
||||
issue_id: 1
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -13,9 +16,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12
|
||||
repo_id: 2
|
||||
issue_id: 4
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach2
|
||||
download_count: 1
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -23,9 +29,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a13
|
||||
repo_id: 1
|
||||
issue_id: 2
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 1
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -33,9 +42,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14
|
||||
repo_id: 1
|
||||
issue_id: 3
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 1
|
||||
name: attach2
|
||||
download_count: 1
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -43,9 +55,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a15
|
||||
repo_id: 2
|
||||
issue_id: 4
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -53,9 +68,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a16
|
||||
repo_id: 1
|
||||
issue_id: 5
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 2
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -63,9 +81,12 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17
|
||||
repo_id: 1
|
||||
issue_id: 5
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 2
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
|
@ -73,34 +94,49 @@
|
|||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18
|
||||
repo_id: 3
|
||||
issue_id: 6
|
||||
release_id: 0
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
id: 9
|
||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a19
|
||||
repo_id: 1
|
||||
issue_id: 0
|
||||
release_id: 1
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
id: 10
|
||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a20
|
||||
repo_id: 0 # TestGetAttachment/NotLinked
|
||||
issue_id: 0
|
||||
release_id: 0
|
||||
uploader_id: 8
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
||||
-
|
||||
id: 11
|
||||
uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a21
|
||||
repo_id: 40
|
||||
issue_id: 0
|
||||
release_id: 2
|
||||
uploader_id: 0
|
||||
comment_id: 0
|
||||
name: attach1
|
||||
download_count: 0
|
||||
size: 0
|
||||
created_unix: 946684800
|
||||
|
|
|
@ -12,3 +12,8 @@
|
|||
id: 3
|
||||
user_id: 2
|
||||
follow_id: 8
|
||||
|
||||
-
|
||||
id: 4
|
||||
user_id: 31
|
||||
follow_id: 33
|
||||
|
|
|
@ -3,208 +3,287 @@
|
|||
repo_id: 1
|
||||
index: 1
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: issue1
|
||||
content: content for the first issue
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 2
|
||||
created_unix: 946684800
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 2
|
||||
repo_id: 1
|
||||
index: 2
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: issue2
|
||||
content: content for the second issue
|
||||
milestone_id: 1
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 946684810
|
||||
updated_unix: 978307190
|
||||
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 3
|
||||
repo_id: 1
|
||||
index: 3
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: issue3
|
||||
content: content for the third issue
|
||||
milestone_id: 3
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 946684820
|
||||
updated_unix: 978307180
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 4
|
||||
repo_id: 2
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue4
|
||||
content: content for the fourth issue
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: true
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 946684830
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 5
|
||||
repo_id: 1
|
||||
index: 4
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue5
|
||||
content: content for the fifth issue
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: true
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 946684840
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 6
|
||||
repo_id: 3
|
||||
index: 1
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: issue6
|
||||
content: content6
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 946684850
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 7
|
||||
repo_id: 2
|
||||
index: 2
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue7
|
||||
content: content for the seventh issue
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 946684830
|
||||
updated_unix: 978307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 8
|
||||
repo_id: 10
|
||||
index: 1
|
||||
poster_id: 11
|
||||
original_author_id: 0
|
||||
name: pr2
|
||||
content: a pull request
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 946684820
|
||||
updated_unix: 978307180
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 9
|
||||
repo_id: 48
|
||||
index: 1
|
||||
poster_id: 11
|
||||
original_author_id: 0
|
||||
name: pr1
|
||||
content: a pull request
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 946684820
|
||||
updated_unix: 978307180
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 10
|
||||
repo_id: 42
|
||||
index: 1
|
||||
poster_id: 500
|
||||
original_author_id: 0
|
||||
name: issue from deleted account
|
||||
content: content from deleted account
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
deadline_unix: 1019307200
|
||||
created_unix: 946684830
|
||||
updated_unix: 999307200
|
||||
deadline_unix: 1019307200
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 11
|
||||
repo_id: 1
|
||||
index: 5
|
||||
poster_id: 1
|
||||
original_author_id: 0
|
||||
name: pull5
|
||||
content: content for the a pull request
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 1579194806
|
||||
updated_unix: 1579194806
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 12
|
||||
repo_id: 3
|
||||
index: 2
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: pull6
|
||||
content: content for the a pull request
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: true
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 13
|
||||
repo_id: 50
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue in active repo
|
||||
content: we'll be testing github issue 13171 with this.
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 14
|
||||
repo_id: 51
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue in archived repo
|
||||
content: we'll be testing github issue 13171 with this.
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 15
|
||||
repo_id: 5
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: issue in repo not linked to team1
|
||||
content: content
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 16
|
||||
repo_id: 32
|
||||
index: 1
|
||||
poster_id: 2
|
||||
original_author_id: 0
|
||||
name: just a normal issue
|
||||
content: content
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
||||
-
|
||||
id: 17
|
||||
repo_id: 32
|
||||
index: 2
|
||||
poster_id: 15
|
||||
original_author_id: 0
|
||||
name: a issue with a assignment
|
||||
content: content
|
||||
milestone_id: 0
|
||||
priority: 0
|
||||
is_closed: false
|
||||
is_pull: false
|
||||
num_comments: 0
|
||||
created_unix: 1602935696
|
||||
updated_unix: 1602935696
|
||||
is_locked: false
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
color: '#000000'
|
||||
num_issues: 1
|
||||
num_closed_issues: 1
|
||||
|
||||
-
|
||||
id: 3
|
||||
repo_id: 0
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
is_closed: false
|
||||
num_issues: 1
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
||||
-
|
||||
|
@ -16,6 +17,7 @@
|
|||
is_closed: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
||||
-
|
||||
|
@ -26,6 +28,7 @@
|
|||
is_closed: true
|
||||
num_issues: 1
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
||||
-
|
||||
|
@ -36,6 +39,7 @@
|
|||
is_closed: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
||||
-
|
||||
|
@ -46,4 +50,5 @@
|
|||
is_closed: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
completeness: 0
|
||||
deadline_unix: 253370764800
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
name: "Test"
|
||||
client_id: "da7da3ba-9a13-4167-856f-3899de0b0138"
|
||||
client_secret: "$2a$10$UYRgUSgekzBp6hYe8pAdc.cgB4Gn06QRKsORUnIYTYQADs.YR/uvi" # bcrypt of "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=
|
||||
redirect_uris: '["a"]'
|
||||
redirect_uris: '["a", "https://example.com/xyzzy"]'
|
||||
created_unix: 1546869730
|
||||
updated_unix: 1546869730
|
||||
|
|
|
@ -69,3 +69,9 @@
|
|||
uid: 2
|
||||
org_id: 17
|
||||
is_public: true
|
||||
|
||||
-
|
||||
id: 13
|
||||
uid: 31
|
||||
org_id: 19
|
||||
is_public: true
|
||||
|
|
|
@ -60,8 +60,8 @@
|
|||
head_repo_id: 1
|
||||
base_repo_id: 1
|
||||
head_branch: pr-to-update
|
||||
base_branch: branch1
|
||||
merge_base: 1234567890abcdef
|
||||
base_branch: branch2
|
||||
merge_base: 985f0301dba5e7b34be866819cd15ad3d8f508ee
|
||||
has_merged: false
|
||||
|
||||
-
|
||||
|
|
File diff suppressed because it is too large
Load diff
15
models/fixtures/system_setting.yml
Normal file
15
models/fixtures/system_setting.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
-
|
||||
id: 1
|
||||
setting_key: 'disable_gravatar'
|
||||
setting_value: 'false'
|
||||
version: 1
|
||||
created: 1653533198
|
||||
updated: 1653533198
|
||||
|
||||
-
|
||||
id: 2
|
||||
setting_key: 'enable_federated_avatar'
|
||||
setting_value: 'false'
|
||||
version: 1
|
||||
created: 1653533198
|
||||
updated: 1653533198
|
|
@ -6,6 +6,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 3
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -16,6 +17,7 @@
|
|||
authorize: 2 # write
|
||||
num_repos: 1
|
||||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -26,6 +28,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -36,6 +39,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -46,6 +50,7 @@
|
|||
authorize: 4 # owner
|
||||
num_repos: 2
|
||||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -55,7 +60,8 @@
|
|||
name: Owners
|
||||
authorize: 4 # owner
|
||||
num_repos: 2
|
||||
num_members: 1
|
||||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -66,6 +72,7 @@
|
|||
authorize: 2 # write
|
||||
num_repos: 1
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -76,6 +83,7 @@
|
|||
authorize: 2 # write
|
||||
num_repos: 1
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -86,6 +94,7 @@
|
|||
authorize: 1 # read
|
||||
num_repos: 1
|
||||
num_members: 2
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -93,9 +102,10 @@
|
|||
org_id: 25
|
||||
lower_name: notowners
|
||||
name: NotOwners
|
||||
authorize: 1 # owner
|
||||
authorize: 1 # read
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -106,6 +116,7 @@
|
|||
authorize: 1 # read
|
||||
num_repos: 0
|
||||
num_members: 0
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
||||
-
|
||||
|
@ -116,6 +127,7 @@
|
|||
authorize: 3 # admin
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: true
|
||||
|
||||
-
|
||||
|
@ -126,4 +138,5 @@
|
|||
authorize: 3 # admin
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
includes_all_repositories: false
|
||||
can_create_org_repo: false
|
||||
|
|
|
@ -87,3 +87,9 @@
|
|||
org_id: 17
|
||||
team_id: 9
|
||||
uid: 29
|
||||
|
||||
-
|
||||
id: 16
|
||||
org_id: 19
|
||||
team_id: 6
|
||||
uid: 31
|
||||
|
|
|
@ -8,18 +8,22 @@
|
|||
name: database
|
||||
repo_count: 1
|
||||
|
||||
- id: 3
|
||||
-
|
||||
id: 3
|
||||
name: SQL
|
||||
repo_count: 1
|
||||
|
||||
- id: 4
|
||||
-
|
||||
id: 4
|
||||
name: graphql
|
||||
repo_count: 1
|
||||
|
||||
- id: 5
|
||||
-
|
||||
id: 5
|
||||
name: topicname1
|
||||
repo_count: 1
|
||||
|
||||
- id: 6
|
||||
-
|
||||
id: 6
|
||||
name: topicname2
|
||||
repo_count: 2
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,6 @@
|
|||
- id: 1
|
||||
name: "WebAuthn credential"
|
||||
-
|
||||
id: 1
|
||||
name: WebAuthn credential
|
||||
user_id: 32
|
||||
attestation_type: none
|
||||
sign_count: 0
|
||||
|
|
|
@ -17,13 +17,11 @@ import (
|
|||
type CommentList []*Comment
|
||||
|
||||
func (comments CommentList) getPosterIDs() []int64 {
|
||||
posterIDs := make(map[int64]struct{}, len(comments))
|
||||
posterIDs := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := posterIDs[comment.PosterID]; !ok {
|
||||
posterIDs[comment.PosterID] = struct{}{}
|
||||
posterIDs.Add(comment.PosterID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(posterIDs)
|
||||
return posterIDs.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadPosters(ctx context.Context) error {
|
||||
|
@ -70,13 +68,11 @@ func (comments CommentList) getCommentIDs() []int64 {
|
|||
}
|
||||
|
||||
func (comments CommentList) getLabelIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.LabelID]; !ok {
|
||||
ids[comment.LabelID] = struct{}{}
|
||||
ids.Add(comment.LabelID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
|
||||
|
@ -120,13 +116,11 @@ func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
|
|||
}
|
||||
|
||||
func (comments CommentList) getMilestoneIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.MilestoneID]; !ok {
|
||||
ids[comment.MilestoneID] = struct{}{}
|
||||
ids.Add(comment.MilestoneID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadMilestones(ctx context.Context) error {
|
||||
|
@ -163,13 +157,11 @@ func (comments CommentList) loadMilestones(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getOldMilestoneIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.OldMilestoneID]; !ok {
|
||||
ids[comment.OldMilestoneID] = struct{}{}
|
||||
ids.Add(comment.OldMilestoneID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadOldMilestones(ctx context.Context) error {
|
||||
|
@ -206,13 +198,11 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getAssigneeIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.AssigneeID]; !ok {
|
||||
ids[comment.AssigneeID] = struct{}{}
|
||||
ids.Add(comment.AssigneeID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadAssignees(ctx context.Context) error {
|
||||
|
@ -259,16 +249,14 @@ func (comments CommentList) loadAssignees(ctx context.Context) error {
|
|||
|
||||
// getIssueIDs returns all the issue ids on this comment list which issue hasn't been loaded
|
||||
func (comments CommentList) getIssueIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.Issue != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[comment.IssueID]; !ok {
|
||||
ids[comment.IssueID] = struct{}{}
|
||||
ids.Add(comment.IssueID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
// Issues returns all the issues of comments
|
||||
|
@ -334,16 +322,14 @@ func (comments CommentList) loadIssues(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (comments CommentList) getDependentIssueIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if comment.DependentIssue != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := ids[comment.DependentIssueID]; !ok {
|
||||
ids[comment.DependentIssueID] = struct{}{}
|
||||
ids.Add(comment.DependentIssueID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadDependentIssues(ctx context.Context) error {
|
||||
|
@ -439,13 +425,11 @@ func (comments CommentList) loadAttachments(ctx context.Context) (err error) {
|
|||
}
|
||||
|
||||
func (comments CommentList) getReviewIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(comments))
|
||||
ids := make(container.Set[int64], len(comments))
|
||||
for _, comment := range comments {
|
||||
if _, ok := ids[comment.ReviewID]; !ok {
|
||||
ids[comment.ReviewID] = struct{}{}
|
||||
ids.Add(comment.ReviewID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (comments CommentList) loadReviews(ctx context.Context) error { //nolint
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
admin_model "code.gitea.io/gitea/models/admin"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/foreignreference"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
|
@ -21,6 +20,7 @@ import (
|
|||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
|
@ -1064,19 +1064,19 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
|
|||
|
||||
// NewIssue creates new issue with labels for repository.
|
||||
func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
|
||||
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate issue index failed: %v", err)
|
||||
}
|
||||
|
||||
issue.Index = idx
|
||||
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate issue index failed: %w", err)
|
||||
}
|
||||
|
||||
issue.Index = idx
|
||||
|
||||
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
|
||||
Repo: repo,
|
||||
Issue: issue,
|
||||
|
@ -1186,6 +1186,7 @@ type IssuesOptions struct { //nolint
|
|||
PosterID int64
|
||||
MentionedID int64
|
||||
ReviewRequestedID int64
|
||||
SubscriberID int64
|
||||
MilestoneIDs []int64
|
||||
ProjectID int64
|
||||
ProjectBoardID int64
|
||||
|
@ -1299,6 +1300,10 @@ func (opts *IssuesOptions) setupSessionNoLimit(sess *xorm.Session) {
|
|||
applyReviewRequestedCondition(sess, opts.ReviewRequestedID)
|
||||
}
|
||||
|
||||
if opts.SubscriberID > 0 {
|
||||
applySubscribedCondition(sess, opts.SubscriberID)
|
||||
}
|
||||
|
||||
if len(opts.MilestoneIDs) > 0 {
|
||||
sess.In("issue.milestone_id", opts.MilestoneIDs)
|
||||
}
|
||||
|
@ -1463,6 +1468,36 @@ func applyReviewRequestedCondition(sess *xorm.Session, reviewRequestedID int64)
|
|||
reviewRequestedID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, reviewRequestedID)
|
||||
}
|
||||
|
||||
func applySubscribedCondition(sess *xorm.Session, subscriberID int64) *xorm.Session {
|
||||
return sess.And(
|
||||
builder.
|
||||
NotIn("issue.id",
|
||||
builder.Select("issue_id").
|
||||
From("issue_watch").
|
||||
Where(builder.Eq{"is_watching": false, "user_id": subscriberID}),
|
||||
),
|
||||
).And(
|
||||
builder.Or(
|
||||
builder.In("issue.id", builder.
|
||||
Select("issue_id").
|
||||
From("issue_watch").
|
||||
Where(builder.Eq{"is_watching": true, "user_id": subscriberID}),
|
||||
),
|
||||
builder.In("issue.id", builder.
|
||||
Select("issue_id").
|
||||
From("comment").
|
||||
Where(builder.Eq{"poster_id": subscriberID}),
|
||||
),
|
||||
builder.Eq{"issue.poster_id": subscriberID},
|
||||
builder.In("issue.repo_id", builder.
|
||||
Select("id").
|
||||
From("watch").
|
||||
Where(builder.Eq{"user_id": subscriberID, "mode": true}),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// CountIssuesByRepo map from repoID to number of issues matching the options
|
||||
func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) {
|
||||
e := db.GetEngine(db.DefaultContext)
|
||||
|
@ -2435,7 +2470,7 @@ func DeleteOrphanedIssues() error {
|
|||
|
||||
// Remove issue attachment files.
|
||||
for i := range attachmentPaths {
|
||||
admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i])
|
||||
system_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -15,16 +15,12 @@ func RecalculateIssueIndexForRepo(repoID int64) error {
|
|||
}
|
||||
defer committer.Close()
|
||||
|
||||
if err := db.UpsertResourceIndex(ctx, "issue_index", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var max int64
|
||||
if _, err := db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil {
|
||||
if _, err = db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := db.GetEngine(ctx).Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil {
|
||||
if err = db.SyncMaxResourceIndex(ctx, "issue_index", repoID, max); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -22,16 +22,16 @@ type IssueList []*Issue
|
|||
|
||||
// get the repo IDs to be loaded later, these IDs are for issue.Repo and issue.PullRequest.HeadRepo
|
||||
func (issues IssueList) getRepoIDs() []int64 {
|
||||
repoIDs := make(map[int64]struct{}, len(issues))
|
||||
repoIDs := make(container.Set[int64], len(issues))
|
||||
for _, issue := range issues {
|
||||
if issue.Repo == nil {
|
||||
repoIDs[issue.RepoID] = struct{}{}
|
||||
repoIDs.Add(issue.RepoID)
|
||||
}
|
||||
if issue.PullRequest != nil && issue.PullRequest.HeadRepo == nil {
|
||||
repoIDs[issue.PullRequest.HeadRepoID] = struct{}{}
|
||||
repoIDs.Add(issue.PullRequest.HeadRepoID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(repoIDs)
|
||||
return repoIDs.Values()
|
||||
}
|
||||
|
||||
func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Repository, error) {
|
||||
|
@ -79,13 +79,11 @@ func (issues IssueList) LoadRepositories() ([]*repo_model.Repository, error) {
|
|||
}
|
||||
|
||||
func (issues IssueList) getPosterIDs() []int64 {
|
||||
posterIDs := make(map[int64]struct{}, len(issues))
|
||||
posterIDs := make(container.Set[int64], len(issues))
|
||||
for _, issue := range issues {
|
||||
if _, ok := posterIDs[issue.PosterID]; !ok {
|
||||
posterIDs[issue.PosterID] = struct{}{}
|
||||
posterIDs.Add(issue.PosterID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(posterIDs)
|
||||
return posterIDs.Values()
|
||||
}
|
||||
|
||||
func (issues IssueList) loadPosters(ctx context.Context) error {
|
||||
|
@ -185,13 +183,11 @@ func (issues IssueList) loadLabels(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (issues IssueList) getMilestoneIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(issues))
|
||||
ids := make(container.Set[int64], len(issues))
|
||||
for _, issue := range issues {
|
||||
if _, ok := ids[issue.MilestoneID]; !ok {
|
||||
ids[issue.MilestoneID] = struct{}{}
|
||||
ids.Add(issue.MilestoneID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (issues IssueList) loadMilestones(ctx context.Context) error {
|
||||
|
@ -224,14 +220,11 @@ func (issues IssueList) loadMilestones(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (issues IssueList) getProjectIDs() []int64 {
|
||||
ids := make(map[int64]struct{}, len(issues))
|
||||
ids := make(container.Set[int64], len(issues))
|
||||
for _, issue := range issues {
|
||||
projectID := issue.ProjectID()
|
||||
if _, ok := ids[projectID]; !ok {
|
||||
ids[projectID] = struct{}{}
|
||||
ids.Add(issue.ProjectID())
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(ids)
|
||||
return ids.Values()
|
||||
}
|
||||
|
||||
func (issues IssueList) loadProjects(ctx context.Context) error {
|
||||
|
|
|
@ -131,7 +131,11 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu
|
|||
r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo})
|
||||
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
|
||||
|
||||
idx, err := db.GetNextResourceIndex("issue_index", r.ID)
|
||||
ctx, committer, err := db.TxContext()
|
||||
assert.NoError(t, err)
|
||||
defer committer.Close()
|
||||
|
||||
idx, err := db.GetNextResourceIndex(ctx, "issue_index", r.ID)
|
||||
assert.NoError(t, err)
|
||||
i := &issues_model.Issue{
|
||||
RepoID: r.ID,
|
||||
|
@ -143,9 +147,6 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu
|
|||
Index: idx,
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext()
|
||||
assert.NoError(t, err)
|
||||
defer committer.Close()
|
||||
err = issues_model.NewIssueWithIndex(ctx, d, issues_model.NewIssueOptions{
|
||||
Repo: r,
|
||||
Issue: i,
|
||||
|
|
|
@ -467,13 +467,6 @@ func (pr *PullRequest) SetMerged(ctx context.Context) (bool, error) {
|
|||
|
||||
// NewPullRequest creates new pull request with labels for repository.
|
||||
func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
|
||||
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate pull request index failed: %v", err)
|
||||
}
|
||||
|
||||
issue.Index = idx
|
||||
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -481,6 +474,13 @@ func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue
|
|||
defer committer.Close()
|
||||
ctx.WithContext(outerCtx)
|
||||
|
||||
idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate pull request index failed: %v", err)
|
||||
}
|
||||
|
||||
issue.Index = idx
|
||||
|
||||
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
|
||||
Repo: repo,
|
||||
Issue: issue,
|
||||
|
|
|
@ -181,6 +181,10 @@ func createReaction(ctx context.Context, opts *ReactionOptions) (*Reaction, erro
|
|||
Reaction: opts.Type,
|
||||
UserID: opts.DoerID,
|
||||
}
|
||||
if findOpts.CommentID == 0 {
|
||||
// explicit search of Issue Reactions where CommentID = 0
|
||||
findOpts.CommentID = -1
|
||||
}
|
||||
|
||||
existingR, _, err := FindReactions(ctx, findOpts)
|
||||
if err != nil {
|
||||
|
@ -207,7 +211,7 @@ type ReactionOptions struct {
|
|||
|
||||
// CreateReaction creates reaction for issue or comment.
|
||||
func CreateReaction(opts *ReactionOptions) (*Reaction, error) {
|
||||
if !setting.UI.ReactionsMap[opts.Type] {
|
||||
if !setting.UI.ReactionsLookup.Contains(opts.Type) {
|
||||
return nil, ErrForbiddenIssueReaction{opts.Type}
|
||||
}
|
||||
|
||||
|
@ -256,7 +260,13 @@ func DeleteReaction(ctx context.Context, opts *ReactionOptions) error {
|
|||
CommentID: opts.CommentID,
|
||||
}
|
||||
|
||||
_, err := db.GetEngine(ctx).Where("original_author_id = 0").Delete(reaction)
|
||||
sess := db.GetEngine(ctx).Where("original_author_id = 0")
|
||||
if opts.CommentID == -1 {
|
||||
reaction.CommentID = 0
|
||||
sess.MustCols("comment_id")
|
||||
}
|
||||
|
||||
_, err := sess.Delete(reaction)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -266,6 +276,7 @@ func DeleteIssueReaction(doerID, issueID int64, content string) error {
|
|||
Type: content,
|
||||
DoerID: doerID,
|
||||
IssueID: issueID,
|
||||
CommentID: -1,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -305,16 +316,14 @@ func (list ReactionList) GroupByType() map[string]ReactionList {
|
|||
}
|
||||
|
||||
func (list ReactionList) getUserIDs() []int64 {
|
||||
userIDs := make(map[int64]struct{}, len(list))
|
||||
userIDs := make(container.Set[int64], len(list))
|
||||
for _, reaction := range list {
|
||||
if reaction.OriginalAuthor != "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := userIDs[reaction.UserID]; !ok {
|
||||
userIDs[reaction.UserID] = struct{}{}
|
||||
userIDs.Add(reaction.UserID)
|
||||
}
|
||||
}
|
||||
return container.KeysInt64(userIDs)
|
||||
return userIDs.Values()
|
||||
}
|
||||
|
||||
func valuesUser(m map[int64]*user_model.User) []*user_model.User {
|
||||
|
|
|
@ -14,6 +14,8 @@ import (
|
|||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
_ "code.gitea.io/gitea/models/system"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
|
@ -99,9 +100,9 @@ func InsertIssueComments(comments []*issues_model.Comment) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
issueIDs := make(map[int64]bool)
|
||||
issueIDs := make(container.Set[int64])
|
||||
for _, comment := range comments {
|
||||
issueIDs[comment.IssueID] = true
|
||||
issueIDs.Add(comment.IssueID)
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext()
|
||||
|
|
|
@ -413,6 +413,10 @@ var migrations = []Migration{
|
|||
NewMigration("Add badges to users", createUserBadgesTable),
|
||||
// v225 -> v226
|
||||
NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", alterPublicGPGKeyContentFieldsToMediumText),
|
||||
// v226 -> v227
|
||||
NewMigration("Conan and generic packages do not need to be semantically versioned", fixPackageSemverField),
|
||||
// v227 -> v228
|
||||
NewMigration("Create key/value table for system settings", createSystemSettingsTable),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
@ -39,7 +40,7 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
|
|||
}
|
||||
log.Info("%d User Avatar(s) to migrate ...", count)
|
||||
|
||||
deleteList := make(map[string]struct{})
|
||||
deleteList := make(container.Set[string])
|
||||
start := 0
|
||||
migrated := 0
|
||||
for {
|
||||
|
@ -86,7 +87,7 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
|
|||
return fmt.Errorf("[user: %s] user table update: %v", user.LowerName, err)
|
||||
}
|
||||
|
||||
deleteList[filepath.Join(setting.Avatar.Path, oldAvatar)] = struct{}{}
|
||||
deleteList.Add(filepath.Join(setting.Avatar.Path, oldAvatar))
|
||||
migrated++
|
||||
select {
|
||||
case <-ticker.C:
|
||||
|
|
15
models/migrations/v226.go
Normal file
15
models/migrations/v226.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func fixPackageSemverField(x *xorm.Engine) error {
|
||||
_, err := x.Exec(builder.Update(builder.Eq{"semver_compatible": false}).From("`package`").Where(builder.In("`type`", "conan", "generic")))
|
||||
return err
|
||||
}
|
64
models/migrations/v227.go
Normal file
64
models/migrations/v227.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type SystemSetting struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
SettingKey string `xorm:"varchar(255) unique"` // ensure key is always lowercase
|
||||
SettingValue string `xorm:"text"`
|
||||
Version int `xorm:"version"` // prevent to override
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
func insertSettingsIfNotExist(x *xorm.Engine, sysSettings []*SystemSetting) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, setting := range sysSettings {
|
||||
exist, err := sess.Table("system_setting").Where("setting_key=?", setting.SettingKey).Exist()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
if _, err := sess.Insert(setting); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func createSystemSettingsTable(x *xorm.Engine) error {
|
||||
if err := x.Sync2(new(SystemSetting)); err != nil {
|
||||
return fmt.Errorf("sync2: %v", err)
|
||||
}
|
||||
|
||||
// migrate xx to database
|
||||
sysSettings := []*SystemSetting{
|
||||
{
|
||||
SettingKey: "picture.disable_gravatar",
|
||||
SettingValue: strconv.FormatBool(setting.DisableGravatar),
|
||||
},
|
||||
{
|
||||
SettingKey: "picture.enable_federated_avatar",
|
||||
SettingValue: strconv.FormatBool(setting.EnableFederatedAvatar),
|
||||
},
|
||||
}
|
||||
|
||||
return insertSettingsIfNotExist(x, sysSettings)
|
||||
}
|
|
@ -129,29 +129,11 @@ func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) {
|
|||
if opts.UserID > 0 {
|
||||
sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id")
|
||||
}
|
||||
|
||||
count, err := sess.
|
||||
Where(cond).
|
||||
Count(new(Team))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if opts.UserID > 0 {
|
||||
sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id")
|
||||
}
|
||||
|
||||
if opts.PageSize == -1 {
|
||||
opts.PageSize = int(count)
|
||||
} else {
|
||||
sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
|
||||
}
|
||||
sess = db.SetSessionPagination(sess, opts)
|
||||
|
||||
teams := make([]*Team, 0, opts.PageSize)
|
||||
if err = sess.
|
||||
Where(cond).
|
||||
OrderBy("lower_name").
|
||||
Find(&teams); err != nil {
|
||||
count, err := sess.Where(cond).OrderBy("lower_name").FindAndCount(&teams)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/packages"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
conan_module "code.gitea.io/gitea/modules/packages/conan"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
@ -88,7 +89,7 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er
|
|||
return nil, err
|
||||
}
|
||||
|
||||
unique := make(map[string]bool)
|
||||
unique := make(container.Set[string])
|
||||
for _, info := range results {
|
||||
recipe := fmt.Sprintf("%s/%s", info.Name, info.Version)
|
||||
|
||||
|
@ -111,7 +112,7 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er
|
|||
}
|
||||
}
|
||||
|
||||
unique[recipe] = true
|
||||
unique.Add(recipe)
|
||||
}
|
||||
|
||||
recipes := make([]string, 0, len(unique))
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/models/webhook"
|
||||
|
@ -32,9 +33,13 @@ import (
|
|||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// NewRepoContext creates a new repository context
|
||||
func NewRepoContext() {
|
||||
// ItemsPerPage maximum items per page in forks, watchers and stars of a repo
|
||||
var ItemsPerPage = 40
|
||||
|
||||
// Init initialize model
|
||||
func Init() error {
|
||||
unit.LoadUnitConfig()
|
||||
return system_model.Init()
|
||||
}
|
||||
|
||||
// DeleteRepository deletes a repository for a user or organization.
|
||||
|
@ -163,7 +168,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
|||
}
|
||||
|
||||
// Delete issue index
|
||||
if err := db.DeleteResouceIndex(ctx, "issue_index", repoID); err != nil {
|
||||
if err := db.DeleteResourceIndex(ctx, "issue_index", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -267,36 +272,36 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
|||
|
||||
// Remove repository files.
|
||||
repoPath := repo.RepoPath()
|
||||
admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete repository files", repoPath)
|
||||
system_model.RemoveAllWithNotice(db.DefaultContext, "Delete repository files", repoPath)
|
||||
|
||||
// Remove wiki files
|
||||
if repo.HasWiki() {
|
||||
admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete repository wiki", repo.WikiPath())
|
||||
system_model.RemoveAllWithNotice(db.DefaultContext, "Delete repository wiki", repo.WikiPath())
|
||||
}
|
||||
|
||||
// Remove archives
|
||||
for _, archive := range archivePaths {
|
||||
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.RepoArchives, "Delete repo archive file", archive)
|
||||
system_model.RemoveStorageWithNotice(db.DefaultContext, storage.RepoArchives, "Delete repo archive file", archive)
|
||||
}
|
||||
|
||||
// Remove lfs objects
|
||||
for _, lfsObj := range lfsPaths {
|
||||
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.LFS, "Delete orphaned LFS file", lfsObj)
|
||||
system_model.RemoveStorageWithNotice(db.DefaultContext, storage.LFS, "Delete orphaned LFS file", lfsObj)
|
||||
}
|
||||
|
||||
// Remove issue attachment files.
|
||||
for _, attachment := range attachmentPaths {
|
||||
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", attachment)
|
||||
system_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", attachment)
|
||||
}
|
||||
|
||||
// Remove release attachment files.
|
||||
for _, releaseAttachment := range releaseAttachments {
|
||||
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete release attachment", releaseAttachment)
|
||||
system_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete release attachment", releaseAttachment)
|
||||
}
|
||||
|
||||
// Remove attachment with no issue_id and release_id.
|
||||
for _, newAttachment := range newAttachmentPaths {
|
||||
admin_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", newAttachment)
|
||||
system_model.RemoveStorageWithNotice(db.DefaultContext, storage.Attachments, "Delete issue attachment", newAttachment)
|
||||
}
|
||||
|
||||
if len(repo.Avatar) > 0 {
|
||||
|
@ -438,15 +443,27 @@ func CheckRepoStats(ctx context.Context) error {
|
|||
repoStatsCorrectNumStars,
|
||||
"repository count 'num_stars'",
|
||||
},
|
||||
// Repository.NumIssues
|
||||
{
|
||||
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", false, false),
|
||||
repoStatsCorrectNumIssues,
|
||||
"repository count 'num_issues'",
|
||||
},
|
||||
// Repository.NumClosedIssues
|
||||
{
|
||||
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, false),
|
||||
repoStatsCorrectNumClosedIssues,
|
||||
"repository count 'num_closed_issues'",
|
||||
},
|
||||
// Repository.NumPulls
|
||||
{
|
||||
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", false, true),
|
||||
repoStatsCorrectNumPulls,
|
||||
"repository count 'num_pulls'",
|
||||
},
|
||||
// Repository.NumClosedPulls
|
||||
{
|
||||
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true),
|
||||
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true),
|
||||
repoStatsCorrectNumClosedPulls,
|
||||
"repository count 'num_closed_pulls'",
|
||||
},
|
||||
|
|
|
@ -200,6 +200,7 @@ type FindReleasesOptions struct {
|
|||
IsPreRelease util.OptionalBool
|
||||
IsDraft util.OptionalBool
|
||||
TagNames []string
|
||||
HasSha1 util.OptionalBool // useful to find draft releases which are created with existing tags
|
||||
}
|
||||
|
||||
func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
|
||||
|
@ -221,6 +222,13 @@ func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
|
|||
if !opts.IsDraft.IsNone() {
|
||||
cond = cond.And(builder.Eq{"is_draft": opts.IsDraft.IsTrue()})
|
||||
}
|
||||
if !opts.HasSha1.IsNone() {
|
||||
if opts.HasSha1.IsTrue() {
|
||||
cond = cond.And(builder.Neq{"sha1": ""})
|
||||
} else {
|
||||
cond = cond.And(builder.Eq{"sha1": ""})
|
||||
}
|
||||
}
|
||||
return cond
|
||||
}
|
||||
|
||||
|
|
|
@ -68,10 +68,10 @@ func (repos RepositoryList) loadAttributes(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
set := make(map[int64]struct{})
|
||||
set := make(container.Set[int64])
|
||||
repoIDs := make([]int64, len(repos))
|
||||
for i := range repos {
|
||||
set[repos[i].OwnerID] = struct{}{}
|
||||
set.Add(repos[i].OwnerID)
|
||||
repoIDs[i] = repos[i].ID
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ func (repos RepositoryList) loadAttributes(ctx context.Context) error {
|
|||
users := make(map[int64]*user_model.User, len(set))
|
||||
if err := db.GetEngine(ctx).
|
||||
Where("id > 0").
|
||||
In("id", container.KeysInt64(set)).
|
||||
In("id", set.Values()).
|
||||
Find(&users); err != nil {
|
||||
return fmt.Errorf("find users: %v", err)
|
||||
}
|
||||
|
@ -593,6 +593,16 @@ func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, c
|
|||
return sess, count, nil
|
||||
}
|
||||
|
||||
// SearchRepositoryIDsByCondition search repository IDs by given condition.
|
||||
func SearchRepositoryIDsByCondition(ctx context.Context, cond builder.Cond) ([]int64, error) {
|
||||
repoIDs := make([]int64, 0, 10)
|
||||
return repoIDs, db.GetEngine(ctx).
|
||||
Table("repository").
|
||||
Cols("id").
|
||||
Where(cond).
|
||||
Find(&repoIDs)
|
||||
}
|
||||
|
||||
// AccessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible
|
||||
func AccessibleRepositoryCondition(user *user_model.User, unitType unit.Type) builder.Cond {
|
||||
cond := builder.NewCond()
|
||||
|
@ -680,16 +690,16 @@ func AccessibleRepoIDsQuery(user *user_model.User) *builder.Builder {
|
|||
}
|
||||
|
||||
// FindUserCodeAccessibleRepoIDs finds all at Code level accessible repositories' ID by the user's id
|
||||
func FindUserCodeAccessibleRepoIDs(user *user_model.User) ([]int64, error) {
|
||||
repoIDs := make([]int64, 0, 10)
|
||||
if err := db.GetEngine(db.DefaultContext).
|
||||
Table("repository").
|
||||
Cols("id").
|
||||
Where(AccessibleRepositoryCondition(user, unit.TypeCode)).
|
||||
Find(&repoIDs); err != nil {
|
||||
return nil, fmt.Errorf("FindUserCodeAccesibleRepoIDs: %v", err)
|
||||
}
|
||||
return repoIDs, nil
|
||||
func FindUserCodeAccessibleRepoIDs(ctx context.Context, user *user_model.User) ([]int64, error) {
|
||||
return SearchRepositoryIDsByCondition(ctx, AccessibleRepositoryCondition(user, unit.TypeCode))
|
||||
}
|
||||
|
||||
// FindUserCodeAccessibleOwnerRepoIDs finds all repository IDs for the given owner whose code the user can see.
|
||||
func FindUserCodeAccessibleOwnerRepoIDs(ctx context.Context, ownerID int64, user *user_model.User) ([]int64, error) {
|
||||
return SearchRepositoryIDsByCondition(ctx, builder.NewCond().And(
|
||||
builder.Eq{"owner_id": ownerID},
|
||||
AccessibleRepositoryCondition(user, unit.TypeCode),
|
||||
))
|
||||
}
|
||||
|
||||
// GetUserRepositories returns a list of repositories of given user.
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
@ -62,7 +63,7 @@ func ValidateTopic(topic string) bool {
|
|||
// SanitizeAndValidateTopics sanitizes and checks an array or topics
|
||||
func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []string) {
|
||||
validTopics = make([]string, 0)
|
||||
mValidTopics := make(map[string]struct{})
|
||||
mValidTopics := make(container.Set[string])
|
||||
invalidTopics = make([]string, 0)
|
||||
|
||||
for _, topic := range topics {
|
||||
|
@ -72,12 +73,12 @@ func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []st
|
|||
continue
|
||||
}
|
||||
// ignore same topic twice
|
||||
if _, ok := mValidTopics[topic]; ok {
|
||||
if mValidTopics.Contains(topic) {
|
||||
continue
|
||||
}
|
||||
if ValidateTopic(topic) {
|
||||
validTopics = append(validTopics, topic)
|
||||
mValidTopics[topic] = struct{}{}
|
||||
mValidTopics.Add(topic)
|
||||
} else {
|
||||
invalidTopics = append(invalidTopics, topic)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
@ -83,37 +84,19 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
|
|||
return nil, err
|
||||
}
|
||||
|
||||
uidMap := map[int64]bool{}
|
||||
i := 0
|
||||
for _, uid := range userIDs {
|
||||
if uidMap[uid] {
|
||||
continue
|
||||
}
|
||||
uidMap[uid] = true
|
||||
userIDs[i] = uid
|
||||
i++
|
||||
}
|
||||
userIDs = userIDs[:i]
|
||||
userIDs = append(userIDs, additionalUserIDs...)
|
||||
|
||||
for _, uid := range additionalUserIDs {
|
||||
if uidMap[uid] {
|
||||
continue
|
||||
}
|
||||
userIDs[i] = uid
|
||||
i++
|
||||
}
|
||||
userIDs = userIDs[:i]
|
||||
uniqueUserIDs := make(container.Set[int64])
|
||||
uniqueUserIDs.AddMultiple(userIDs...)
|
||||
uniqueUserIDs.AddMultiple(additionalUserIDs...)
|
||||
|
||||
// Leave a seat for owner itself to append later, but if owner is an organization
|
||||
// and just waste 1 unit is cheaper than re-allocate memory once.
|
||||
users := make([]*user_model.User, 0, len(userIDs)+1)
|
||||
users := make([]*user_model.User, 0, len(uniqueUserIDs)+1)
|
||||
if len(userIDs) > 0 {
|
||||
if err = e.In("id", userIDs).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil {
|
||||
if err = e.In("id", uniqueUserIDs.Values()).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if !repo.Owner.IsOrganization() && !uidMap[repo.OwnerID] {
|
||||
if !repo.Owner.IsOrganization() && !uniqueUserIDs.Contains(repo.OwnerID) {
|
||||
users = append(users, repo.Owner)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package appstate
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
21
models/system/main_test.go
Normal file
21
models/system/main_test.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package system_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
_ "code.gitea.io/gitea/models" // register models
|
||||
_ "code.gitea.io/gitea/models/system" // register models of system
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", ".."),
|
||||
})
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package admin
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
117
models/system/notice_test.go
Normal file
117
models/system/notice_test.go
Normal file
|
@ -0,0 +1,117 @@
|
|||
// 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 system_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNotice_TrStr(t *testing.T) {
|
||||
notice := &system.Notice{
|
||||
Type: system.NoticeRepository,
|
||||
Description: "test description",
|
||||
}
|
||||
assert.Equal(t, "admin.notices.type_1", notice.TrStr())
|
||||
}
|
||||
|
||||
func TestCreateNotice(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
noticeBean := &system.Notice{
|
||||
Type: system.NoticeRepository,
|
||||
Description: "test description",
|
||||
}
|
||||
unittest.AssertNotExistsBean(t, noticeBean)
|
||||
assert.NoError(t, system.CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description))
|
||||
unittest.AssertExistsAndLoadBean(t, noticeBean)
|
||||
}
|
||||
|
||||
func TestCreateRepositoryNotice(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
noticeBean := &system.Notice{
|
||||
Type: system.NoticeRepository,
|
||||
Description: "test description",
|
||||
}
|
||||
unittest.AssertNotExistsBean(t, noticeBean)
|
||||
assert.NoError(t, system.CreateRepositoryNotice(noticeBean.Description))
|
||||
unittest.AssertExistsAndLoadBean(t, noticeBean)
|
||||
}
|
||||
|
||||
// TODO TestRemoveAllWithNotice
|
||||
|
||||
func TestCountNotices(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
assert.Equal(t, int64(3), system.CountNotices())
|
||||
}
|
||||
|
||||
func TestNotices(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
notices, err := system.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 = system.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, &system.Notice{ID: 3})
|
||||
assert.NoError(t, system.DeleteNotice(3))
|
||||
unittest.AssertNotExistsBean(t, &system.Notice{ID: 3})
|
||||
}
|
||||
|
||||
func TestDeleteNotices(t *testing.T) {
|
||||
// delete a non-empty range
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
|
||||
assert.NoError(t, system.DeleteNotices(1, 2))
|
||||
unittest.AssertNotExistsBean(t, &system.Notice{ID: 1})
|
||||
unittest.AssertNotExistsBean(t, &system.Notice{ID: 2})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
|
||||
}
|
||||
|
||||
func TestDeleteNotices2(t *testing.T) {
|
||||
// delete an empty range
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
|
||||
assert.NoError(t, system.DeleteNotices(3, 2))
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
|
||||
}
|
||||
|
||||
func TestDeleteNoticesByIDs(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
|
||||
assert.NoError(t, system.DeleteNoticesByIDs([]int64{1, 3}))
|
||||
unittest.AssertNotExistsBean(t, &system.Notice{ID: 1})
|
||||
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
|
||||
unittest.AssertNotExistsBean(t, &system.Notice{ID: 3})
|
||||
}
|
261
models/system/setting.go
Normal file
261
models/system/setting.go
Normal file
|
@ -0,0 +1,261 @@
|
|||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"strk.kbt.io/projects/go/libravatar"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// Setting is a key value store of user settings
|
||||
type Setting struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
SettingKey string `xorm:"varchar(255) unique"` // ensure key is always lowercase
|
||||
SettingValue string `xorm:"text"`
|
||||
Version int `xorm:"version"` // prevent to override
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
// TableName sets the table name for the settings struct
|
||||
func (s *Setting) TableName() string {
|
||||
return "system_setting"
|
||||
}
|
||||
|
||||
func (s *Setting) GetValueBool() bool {
|
||||
b, _ := strconv.ParseBool(s.SettingValue)
|
||||
return b
|
||||
}
|
||||
|
||||
func init() {
|
||||
db.RegisterModel(new(Setting))
|
||||
}
|
||||
|
||||
// ErrSettingIsNotExist represents an error that a setting is not exist with special key
|
||||
type ErrSettingIsNotExist struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
// Error implements error
|
||||
func (err ErrSettingIsNotExist) Error() string {
|
||||
return fmt.Sprintf("System setting[%s] is not exist", err.Key)
|
||||
}
|
||||
|
||||
// IsErrSettingIsNotExist return true if err is ErrSettingIsNotExist
|
||||
func IsErrSettingIsNotExist(err error) bool {
|
||||
_, ok := err.(ErrSettingIsNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrDataExpired represents an error that update a record which has been updated by another thread
|
||||
type ErrDataExpired struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
// Error implements error
|
||||
func (err ErrDataExpired) Error() string {
|
||||
return fmt.Sprintf("System setting[%s] has been updated by another thread", err.Key)
|
||||
}
|
||||
|
||||
// IsErrDataExpired return true if err is ErrDataExpired
|
||||
func IsErrDataExpired(err error) bool {
|
||||
_, ok := err.(ErrDataExpired)
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetSetting returns specific setting
|
||||
func GetSetting(key string) (*Setting, error) {
|
||||
v, err := GetSettings([]string{key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(v) == 0 {
|
||||
return nil, ErrSettingIsNotExist{key}
|
||||
}
|
||||
return v[key], nil
|
||||
}
|
||||
|
||||
// GetSettings returns specific settings
|
||||
func GetSettings(keys []string) (map[string]*Setting, error) {
|
||||
for i := 0; i < len(keys); i++ {
|
||||
keys[i] = strings.ToLower(keys[i])
|
||||
}
|
||||
settings := make([]*Setting, 0, len(keys))
|
||||
if err := db.GetEngine(db.DefaultContext).
|
||||
Where(builder.In("setting_key", keys)).
|
||||
Find(&settings); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
settingsMap := make(map[string]*Setting)
|
||||
for _, s := range settings {
|
||||
settingsMap[s.SettingKey] = s
|
||||
}
|
||||
return settingsMap, nil
|
||||
}
|
||||
|
||||
type AllSettings map[string]*Setting
|
||||
|
||||
func (settings AllSettings) Get(key string) Setting {
|
||||
if v, ok := settings[key]; ok {
|
||||
return *v
|
||||
}
|
||||
return Setting{}
|
||||
}
|
||||
|
||||
func (settings AllSettings) GetBool(key string) bool {
|
||||
b, _ := strconv.ParseBool(settings.Get(key).SettingValue)
|
||||
return b
|
||||
}
|
||||
|
||||
func (settings AllSettings) GetVersion(key string) int {
|
||||
return settings.Get(key).Version
|
||||
}
|
||||
|
||||
// GetAllSettings returns all settings from user
|
||||
func GetAllSettings() (AllSettings, error) {
|
||||
settings := make([]*Setting, 0, 5)
|
||||
if err := db.GetEngine(db.DefaultContext).
|
||||
Find(&settings); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
settingsMap := make(map[string]*Setting)
|
||||
for _, s := range settings {
|
||||
settingsMap[s.SettingKey] = s
|
||||
}
|
||||
return settingsMap, nil
|
||||
}
|
||||
|
||||
// DeleteSetting deletes a specific setting for a user
|
||||
func DeleteSetting(setting *Setting) error {
|
||||
_, err := db.GetEngine(db.DefaultContext).Delete(setting)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetSettingNoVersion(key, value string) error {
|
||||
s, err := GetSetting(key)
|
||||
if IsErrSettingIsNotExist(err) {
|
||||
return SetSetting(&Setting{
|
||||
SettingKey: key,
|
||||
SettingValue: value,
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.SettingValue = value
|
||||
return SetSetting(s)
|
||||
}
|
||||
|
||||
// SetSetting updates a users' setting for a specific key
|
||||
func SetSetting(setting *Setting) error {
|
||||
if err := upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version); err != nil {
|
||||
return err
|
||||
}
|
||||
setting.Version++
|
||||
return nil
|
||||
}
|
||||
|
||||
func upsertSettingValue(key, value string, version int) error {
|
||||
return db.WithTx(func(ctx context.Context) error {
|
||||
e := db.GetEngine(ctx)
|
||||
|
||||
// here we use a general method to do a safe upsert for different databases (and most transaction levels)
|
||||
// 1. try to UPDATE the record and acquire the transaction write lock
|
||||
// if UPDATE returns non-zero rows are changed, OK, the setting is saved correctly
|
||||
// if UPDATE returns "0 rows changed", two possibilities: (a) record doesn't exist (b) value is not changed
|
||||
// 2. do a SELECT to check if the row exists or not (we already have the transaction lock)
|
||||
// 3. if the row doesn't exist, do an INSERT (we are still protected by the transaction lock, so it's safe)
|
||||
//
|
||||
// to optimize the SELECT in step 2, we can use an extra column like `revision=revision+1`
|
||||
// to make sure the UPDATE always returns a non-zero value for existing (unchanged) records.
|
||||
|
||||
res, err := e.Exec("UPDATE system_setting SET setting_value=?, version = version+1 WHERE setting_key=? AND version=?", value, key, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, _ := res.RowsAffected()
|
||||
if rows > 0 {
|
||||
// the existing row is updated, so we can return
|
||||
return nil
|
||||
}
|
||||
|
||||
// in case the value isn't changed, update would return 0 rows changed, so we need this check
|
||||
has, err := e.Exist(&Setting{SettingKey: key})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if has {
|
||||
return ErrDataExpired{Key: key}
|
||||
}
|
||||
|
||||
// if no existing row, insert a new row
|
||||
_, err = e.Insert(&Setting{SettingKey: key, SettingValue: value})
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
var (
|
||||
GravatarSourceURL *url.URL
|
||||
LibravatarService *libravatar.Libravatar
|
||||
)
|
||||
|
||||
func Init() error {
|
||||
var disableGravatar bool
|
||||
disableGravatarSetting, err := GetSetting(KeyPictureDisableGravatar)
|
||||
if IsErrSettingIsNotExist(err) {
|
||||
disableGravatar = setting.GetDefaultDisableGravatar()
|
||||
disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)}
|
||||
} else if err != nil {
|
||||
return err
|
||||
} else {
|
||||
disableGravatar = disableGravatarSetting.GetValueBool()
|
||||
}
|
||||
|
||||
var enableFederatedAvatar bool
|
||||
enableFederatedAvatarSetting, err := GetSetting(KeyPictureEnableFederatedAvatar)
|
||||
if IsErrSettingIsNotExist(err) {
|
||||
enableFederatedAvatar = setting.GetDefaultEnableFederatedAvatar(disableGravatar)
|
||||
enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)}
|
||||
} else if err != nil {
|
||||
return err
|
||||
} else {
|
||||
enableFederatedAvatar = disableGravatarSetting.GetValueBool()
|
||||
}
|
||||
|
||||
if setting.OfflineMode {
|
||||
disableGravatar = true
|
||||
enableFederatedAvatar = false
|
||||
}
|
||||
|
||||
if disableGravatar || !enableFederatedAvatar {
|
||||
var err error
|
||||
GravatarSourceURL, err = url.Parse(setting.GravatarSource)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to parse Gravatar URL(%s): %v", setting.GravatarSource, err)
|
||||
}
|
||||
}
|
||||
|
||||
if enableFederatedAvatarSetting.GetValueBool() {
|
||||
LibravatarService = libravatar.New()
|
||||
if GravatarSourceURL.Scheme == "https" {
|
||||
LibravatarService.SetUseHTTPS(true)
|
||||
LibravatarService.SetSecureFallbackHost(GravatarSourceURL.Host)
|
||||
} else {
|
||||
LibravatarService.SetUseHTTPS(false)
|
||||
LibravatarService.SetFallbackHost(GravatarSourceURL.Host)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
11
models/system/setting_key.go
Normal file
11
models/system/setting_key.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
// 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 system
|
||||
|
||||
// enumerate all system setting keys
|
||||
const (
|
||||
KeyPictureDisableGravatar = "picture.disable_gravatar"
|
||||
KeyPictureEnableFederatedAvatar = "picture.enable_federated_avatar"
|
||||
)
|
53
models/system/setting_test.go
Normal file
53
models/system/setting_test.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package system_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSettings(t *testing.T) {
|
||||
keyName := "server.LFS_LOCKS_PAGING_NUM"
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
newSetting := &system.Setting{SettingKey: keyName, SettingValue: "50"}
|
||||
|
||||
// create setting
|
||||
err := system.SetSetting(newSetting)
|
||||
assert.NoError(t, err)
|
||||
// test about saving unchanged values
|
||||
err = system.SetSetting(newSetting)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// get specific setting
|
||||
settings, err := system.GetSettings([]string{keyName})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, settings, 1)
|
||||
assert.EqualValues(t, newSetting.SettingValue, settings[strings.ToLower(keyName)].SettingValue)
|
||||
|
||||
// updated setting
|
||||
updatedSetting := &system.Setting{SettingKey: keyName, SettingValue: "100", Version: newSetting.Version}
|
||||
err = system.SetSetting(updatedSetting)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// get all settings
|
||||
settings, err = system.GetAllSettings()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, settings, 3)
|
||||
assert.EqualValues(t, updatedSetting.SettingValue, settings[strings.ToLower(updatedSetting.SettingKey)].SettingValue)
|
||||
|
||||
// delete setting
|
||||
err = system.DeleteSetting(&system.Setting{SettingKey: strings.ToLower(keyName)})
|
||||
assert.NoError(t, err)
|
||||
settings, err = system.GetAllSettings()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, settings, 2)
|
||||
}
|
|
@ -7,12 +7,12 @@ package unittest
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"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/git"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -91,10 +91,8 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
|||
setting.AppDataPath = appDataPath
|
||||
setting.AppWorkPath = testOpts.GiteaRootPath
|
||||
setting.StaticRootPath = testOpts.GiteaRootPath
|
||||
setting.GravatarSourceURL, err = url.Parse("https://secure.gravatar.com/avatar/")
|
||||
if err != nil {
|
||||
fatalTestError("url.Parse: %v\n", err)
|
||||
}
|
||||
setting.GravatarSource = "https://secure.gravatar.com/avatar/"
|
||||
|
||||
setting.Attachment.Storage.Path = filepath.Join(setting.AppDataPath, "attachments")
|
||||
|
||||
setting.LFS.Storage.Path = filepath.Join(setting.AppDataPath, "lfs")
|
||||
|
@ -112,6 +110,9 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
|||
if err = storage.Init(); err != nil {
|
||||
fatalTestError("storage.Init: %v\n", err)
|
||||
}
|
||||
if err = system_model.Init(); err != nil {
|
||||
fatalTestError("models.Init: %v\n", err)
|
||||
}
|
||||
|
||||
if err = util.RemoveAll(repoRootPath); err != nil {
|
||||
fatalTestError("util.RemoveAll: %v\n", err)
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/models/avatars"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/modules/avatar"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -67,10 +68,16 @@ func (u *User) AvatarLinkWithSize(size int) string {
|
|||
useLocalAvatar := false
|
||||
autoGenerateAvatar := false
|
||||
|
||||
var disableGravatar bool
|
||||
disableGravatarSetting, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar)
|
||||
if disableGravatarSetting != nil {
|
||||
disableGravatar = disableGravatarSetting.GetValueBool()
|
||||
}
|
||||
|
||||
switch {
|
||||
case u.UseCustomAvatar:
|
||||
useLocalAvatar = true
|
||||
case setting.DisableGravatar, setting.OfflineMode:
|
||||
case disableGravatar, setting.OfflineMode:
|
||||
useLocalAvatar = true
|
||||
autoGenerateAvatar = true
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue