mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-20 09:32:43 +09:00
Compare commits
74 Commits
v1.12.0-rc
...
v1.12.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a51c48eb6 | ||
|
|
0fa538e552 | ||
|
|
69e4b6910b | ||
|
|
0e9dcc9500 | ||
|
|
87f02d90cf | ||
|
|
21cd7ab812 | ||
|
|
981216c9fe | ||
|
|
cfbfb73c56 | ||
|
|
4a548a0332 | ||
|
|
8bf2ee1e02 | ||
|
|
a687980412 | ||
|
|
1f85815a3b | ||
|
|
ee5e5a5093 | ||
|
|
03ba12aabf | ||
|
|
24ed1b5feb | ||
|
|
8282697734 | ||
|
|
ec48618d40 | ||
|
|
f0dd07129a | ||
|
|
6d3b8141df | ||
|
|
13c4c7a132 | ||
|
|
6015d30dd6 | ||
|
|
b1cfb0d7a2 | ||
|
|
48a423a8a8 | ||
|
|
cc8a7c9345 | ||
|
|
77af0a23c4 | ||
|
|
87bfe02b5b | ||
|
|
9bac656b7d | ||
|
|
ad68c9ccb2 | ||
|
|
8d1cd4d252 | ||
|
|
64eaa2a942 | ||
|
|
489e9162fc | ||
|
|
5e62137fe3 | ||
|
|
6a081f95c0 | ||
|
|
c3c246cffc | ||
|
|
85be939c2a | ||
|
|
a680c911e4 | ||
|
|
d9c18cbba0 | ||
|
|
3daedb3877 | ||
|
|
2bf987229a | ||
|
|
f984a7e6c6 | ||
|
|
c96da610c2 | ||
|
|
e46dbec294 | ||
|
|
8f64017058 | ||
|
|
d737eaa63a | ||
|
|
058ee52333 | ||
|
|
47b1fc5149 | ||
|
|
20c2bdf86b | ||
|
|
df13fc8818 | ||
|
|
445992d929 | ||
|
|
d059156c3a | ||
|
|
12f51ec7dd | ||
|
|
82b843a5ab | ||
|
|
dcbbf37082 | ||
|
|
3e8618a543 | ||
|
|
3a2679db2e | ||
|
|
6839010bd6 | ||
|
|
80da796025 | ||
|
|
113c99512b | ||
|
|
82343f4943 | ||
|
|
d534007bc4 | ||
|
|
6466053b4d | ||
|
|
7dc8db9ea8 | ||
|
|
ecad970a26 | ||
|
|
47a5c8e1f7 | ||
|
|
6abb8d751c | ||
|
|
fdc6287973 | ||
|
|
320031fce6 | ||
|
|
ef2f18964e | ||
|
|
f2bde40804 | ||
|
|
6b1e5f7f88 | ||
|
|
56660c3fd0 | ||
|
|
87a82138c6 | ||
|
|
d06f98d9a2 | ||
|
|
c52f81eecc |
@@ -25,7 +25,7 @@ globals:
|
|||||||
Tribute: false
|
Tribute: false
|
||||||
|
|
||||||
overrides:
|
overrides:
|
||||||
- files: ["web_src/**/*.worker.js", "web_src/js/serviceworker.js"]
|
- files: ["web_src/**/*worker.js"]
|
||||||
env:
|
env:
|
||||||
worker: true
|
worker: true
|
||||||
rules:
|
rules:
|
||||||
|
|||||||
196
CHANGELOG.md
196
CHANGELOG.md
@@ -4,61 +4,79 @@ This changelog goes through all the changes that have been made in each release
|
|||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
## [1.12.0-rc2](https://github.com/go-gitea/gitea/releases/tag/v1.12.0-rc2) - 2020-06-08
|
## [1.12.4](https://github.com/go-gitea/gitea/releases/tag/v1.12.4) - 2020-09-02
|
||||||
|
|
||||||
|
* SECURITY
|
||||||
|
* Escape provider name in oauth2 provider redirect (#12648) (#12650)
|
||||||
|
* Escape Email on password reset page (#12610) (#12612)
|
||||||
|
* When reading expired sessions - expire them (#12686) (#12690)
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* StaticRootPath configurable at compile time (#12371) (#12652)
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix to show an issue that is related to a deleted issue (#12651) (#12692)
|
||||||
|
* Expire time acknowledged for cache (#12605) (#12611)
|
||||||
|
* Fix diff path unquoting (#12554) (#12575)
|
||||||
|
* Improve HTML escaping helper (#12562)
|
||||||
|
* models: break out of loop (#12386) (#12561)
|
||||||
|
* Default empty merger list to those with write permissions (#12535) (#12560)
|
||||||
|
* Skip SSPI authentication attempts for /api/internal (#12556) (#12559)
|
||||||
|
* Prevent NPE on commenting on lines with invalidated comments (#12549) (#12550)
|
||||||
|
* Remove hardcoded ES indexername (#12521) (#12526)
|
||||||
|
* Fix bug preventing transfer to private organization (#12497) (#12501)
|
||||||
|
* Keys should not verify revoked email addresses (#12486) (#12495)
|
||||||
|
* Do not add prefix on http/https submodule links (#12477) (#12479)
|
||||||
|
* Fix ignored login on compare (#12476) (#12478)
|
||||||
|
* Fix incorrect error logging in Stats indexer and OAuth2 (#12387) (#12422)
|
||||||
|
* Upgrade google/go-github to v32.1.0 (#12361) (#12390)
|
||||||
|
* Render emoji's of Commit message on feed-page (#12373)
|
||||||
|
* Fix handling of diff on unrelated branches when Git 2.28 used (#12370)
|
||||||
|
|
||||||
|
## [1.12.3](https://github.com/go-gitea/gitea/releases/tag/v1.12.3) - 2020-07-28
|
||||||
|
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
* In File Create/Update API return 404 if Branch does not exist (#11791) (#11795)
|
* Don't change creation date when updating Release (#12343) (#12351)
|
||||||
* Fix doer of rename repo (#11789) (#11794)
|
* Show 404 page when release not found (#12328) (#12332)
|
||||||
* Initialize SimpleMDE when making a code comment (#11749) (#11785)
|
* Fix emoji detection in certain cases (#12320) (#12327)
|
||||||
* Fix timezone on issue deadline (#11697) (#11784)
|
* Reduce emoji size (#12317) (#12327)
|
||||||
* Fix to allow comment poster to edit or delete his own comments (#11671) (#11774)
|
* Fix double-indirection bug in logging IDs (#12294) (#12308)
|
||||||
* Show full 500 error in API when Gitea in dev mode (#11641) (#11753)
|
* Link to pull list page on sidebar when view pr (#12256) (#12263)
|
||||||
* Add missing templates for Matrix system webhooks (#11729) (#11748)
|
* Extend Notifications API and return pinned notifications by default (#12164) (#12232)
|
||||||
* Fix verification of subkeys of default gpg key (#11713) (#11747)
|
|
||||||
* Fix styling for commiter on diff view (#11715) (#11744)
|
|
||||||
* Properly truncate system notices (#11714) (#11742)
|
|
||||||
* Handle expected errors in FileCreate & FileUpdate API (#11643) (#11718)
|
|
||||||
* Fix missing authorization check on pull for public repos of private/limited org (#11656) (#11682)
|
|
||||||
* Update emoji regex (#11584) (#11679)
|
|
||||||
* Doctor check & fix db consistency (#11111) (#11676)
|
|
||||||
* Default MSSQL port 0 to allow automatic detection by default (#11642) (#11673)
|
|
||||||
* Exclude generated files from language statistics (#11653) (#11670)
|
|
||||||
* Use -1 to disable key algorithm type in ssh.minimum_key_sizes (#11635) (#11662)
|
|
||||||
* Return json on 500 error from API (#11574) (#11659)
|
|
||||||
* When must change password only show Signout (#11600) (#11637)
|
|
||||||
* Backport various styling fixes (#11619)
|
|
||||||
* Fix wrong milestone in webhook message (#11596) (#11611)
|
|
||||||
* Fix serviceworker output file and misc improvements (#11562) (#11610)
|
|
||||||
* When initialising repositories ensure that the user doing the creation is the initializer (#11601) (#11608)
|
|
||||||
* Prevent empty query parameter being set on dashboard (#11561) (#11604)
|
|
||||||
* Fix images in wiki edit preview (#11546) (#11602)
|
|
||||||
* Allow different HardBreaks settings for documents and comments (#11515) (#11599)
|
|
||||||
* Prevent (caught) panic on login (#11590) (#11597)
|
|
||||||
* Prevent transferring repos to invisible orgs (#11517) (#11549)
|
|
||||||
* Move serviceworker to workbox and fix SSE interference (#11538) (#11547)
|
|
||||||
* API PullReviewComment HTMLPullURL should return the HTMLURL (#11501) (#11533)
|
|
||||||
* Fix repo-list private and total count bugs (#11500) (#11532)
|
|
||||||
* Fix form action template substitutions on admin pages (backport #11519) (#11531)
|
|
||||||
* Fix a bug where the reaction emoji doesn't disappear. (#11489) (#11530)
|
|
||||||
* TrimSpace when reading InternalToken from a file (#11502) (#11524)
|
|
||||||
* Fix selected line color in arc-green (#11492) (#11520)
|
|
||||||
* Make localstorage read ssh or https correctly (#11483) (#11490)
|
|
||||||
* ENHANCEMENTS
|
|
||||||
* Make tabular menu styling consistent for arc-green (#11570) (#11798)
|
|
||||||
* Add option to API to update PullRequest base branch (#11666) (#11796)
|
|
||||||
* Increase maximum SQLite variables count to 32766 (#11696) (#11783)
|
|
||||||
* Update emoji dataset with skin tone variants (#11678) (#11763)
|
|
||||||
* Add logging to long migrations (#11647) (#11691)
|
|
||||||
* Change language statistics to save size instead of percentage (#11681) (#11690)
|
|
||||||
* Fix alignment for commits on dashboard (#11595) (#11680)
|
|
||||||
* Handle expected errors in AddGPGkey API (#11644) (#11661)
|
|
||||||
* Close EventSource before unloading the page (#11539) (#11557)
|
|
||||||
* Ensure emoji render with regular font-weight (#11541) (#11545)
|
|
||||||
* Fix webpack chunk loading with STATIC_URL_PREFIX (#11526) (#11542)
|
|
||||||
* Tweak reaction buttons (#11516)
|
|
||||||
* Use more toned colors for selected line (#11493) (#11511)
|
|
||||||
|
|
||||||
## [1.12.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.12.0-rc1) - 2020-05-18
|
## [1.12.2](https://github.com/go-gitea/gitea/releases/tag/v1.12.2) - 2020-07-11
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* When deleting repository decrese user repository count in cache (#11954) (#12188)
|
||||||
|
* Return full commit message instead of summary in commits API (#12186) (#12187)
|
||||||
|
* Properly set HEAD when a repo is created with a default branch that is not named 'master' (#12135) (#12182)
|
||||||
|
* Ensure GPG Subkeys are verified (#12155) (#12168)
|
||||||
|
* Fix failing to cache last commit with key being to long (#12151) (#12161)
|
||||||
|
* Multiple small admin dashboard fixes (#12153) (#12156)
|
||||||
|
* Remove spurious logging of " Delete all repository archives" at startup (#12139) (#12148)
|
||||||
|
* Fix repository setup instructions when default branch is not named 'master' (#12122) (#12147)
|
||||||
|
* Move EventSource to SharedWorker (#12095) (#12130)
|
||||||
|
* Fix ui bug in wiki commit page (#12089) (#12125)
|
||||||
|
* Fix gitgraph branch continues after merge (#12044) (#12105)
|
||||||
|
* Set the base url when migrating from Gitlab using access token or username without password (#11852) (#12104)
|
||||||
|
* Ensure BlameReaders close at end of request (#12102) (#12103)
|
||||||
|
* Fix panic when adding review comment (#12058)
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* Disable dropzone's timeout for file uploads (#12024) (#12032)
|
||||||
|
|
||||||
|
## [1.12.1](https://github.com/go-gitea/gitea/releases/tag/v1.12.1) - 2020-06-21
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* Handle multiple merges in gitgraph.js (#11996) (#12000)
|
||||||
|
* Add serviceworker.js to KnownPublicEntries (#11992) (#11994)
|
||||||
|
* For language detection do not try to analyze big files by content (#11971) (#11975)
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* Fix scrollable header on dropdowns (#11893) (#11965)
|
||||||
|
|
||||||
|
## [1.11.8](https://github.com/go-gitea/gitea/releases/tag/v1.11.8) - 2020-06-21
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* Really fix __webpack_public_path__ for 1.11 (#11961)
|
||||||
|
|
||||||
|
## [1.12.0](https://github.com/go-gitea/gitea/releases/tag/v1.12.0) - 2020-06-17
|
||||||
|
|
||||||
* BREAKING
|
* BREAKING
|
||||||
* When using API CreateRelease set created_unix to the tag commit time (#11218)
|
* When using API CreateRelease set created_unix to the tag commit time (#11218)
|
||||||
@@ -68,6 +86,8 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* Return 404 from Contents API when items don't exist (#10323)
|
* Return 404 from Contents API when items don't exist (#10323)
|
||||||
* Notification API should always return a JSON object with the current count of notifications (#10059)
|
* Notification API should always return a JSON object with the current count of notifications (#10059)
|
||||||
* Remove migration support from versions earlier than 1.6.0 (#10026)
|
* Remove migration support from versions earlier than 1.6.0 (#10026)
|
||||||
|
* SECURITY
|
||||||
|
* Use -1 to disable key algorithm type in ssh.minimum_key_sizes (#11635) (#11662)
|
||||||
* FEATURES
|
* FEATURES
|
||||||
* Improve config logging when WrappedQueue times out (#11174)
|
* Improve config logging when WrappedQueue times out (#11174)
|
||||||
* Add branch delete to API (#11112)
|
* Add branch delete to API (#11112)
|
||||||
@@ -109,6 +129,53 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* Language statistics bar for repositories (#8037)
|
* Language statistics bar for repositories (#8037)
|
||||||
* Restricted users (#6274)
|
* Restricted users (#6274)
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
* Fix commenting on non-utf8 encoded files (#11916) (#11950)
|
||||||
|
* Use google/uuid to instead satori/go.uuid (#11943) (#11946)
|
||||||
|
* Align show/hide outdated button on code review block (#11932) (#11944)
|
||||||
|
* Update to go-git v5.1.0 (#11936) (#11941)
|
||||||
|
* Use ID or Where to instead directly use Get when load object from database (#11925) (#11934)
|
||||||
|
* Update CommitsAhead CommitsBehind on Pull BaseBranch Change too (#11912) (#11915)
|
||||||
|
* Invalidate comments when file is shortened (#11882) (#11884)
|
||||||
|
* Rework api/user/repos for pagination (#11827) (#11877)
|
||||||
|
* Handle more pathological branch and tag names (#11843) (#11863)
|
||||||
|
* Add doctor check to set IsArchived false if it is null (partial #11853) (#11859)
|
||||||
|
* Prevent panic on empty HOST for mysql (#11850) (#11856)
|
||||||
|
* Use DEFAULT_PAGING_NUM instead of MAX_RESPONSE_ITEMS in ListOptions (#11831) (#11836)
|
||||||
|
* Fix reply octicon (#11821) (#11822)
|
||||||
|
* Honor DEFAULT_PAGING_NUM for API (#11805) (#11813)
|
||||||
|
* Ensure rejected push to refs/pull/index/head fails nicely (#11724) (#11809)
|
||||||
|
* In File Create/Update API return 404 if Branch does not exist (#11791) (#11795)
|
||||||
|
* Fix doer of rename repo (#11789) (#11794)
|
||||||
|
* Initialize SimpleMDE when making a code comment (#11749) (#11785)
|
||||||
|
* Fix timezone on issue deadline (#11697) (#11784)
|
||||||
|
* Fix to allow comment poster to edit or delete his own comments (#11671) (#11774)
|
||||||
|
* Show full 500 error in API when Gitea in dev mode (#11641) (#11753)
|
||||||
|
* Add missing templates for Matrix system webhooks (#11729) (#11748)
|
||||||
|
* Fix verification of subkeys of default gpg key (#11713) (#11747)
|
||||||
|
* Fix styling for commiter on diff view (#11715) (#11744)
|
||||||
|
* Properly truncate system notices (#11714) (#11742)
|
||||||
|
* Handle expected errors in FileCreate & FileUpdate API (#11643) (#11718)
|
||||||
|
* Fix missing authorization check on pull for public repos of private/limited org (#11656) (#11682)
|
||||||
|
* Doctor check & fix db consistency (#11111) (#11676)
|
||||||
|
* Exclude generated files from language statistics (#11653) (#11670)
|
||||||
|
* Return json on 500 error from API (#11574) (#11659)
|
||||||
|
* When must change password only show Signout (#11600) (#11637)
|
||||||
|
* Backport various styling fixes (#11619)
|
||||||
|
* Fix wrong milestone in webhook message (#11596) (#11611)
|
||||||
|
* Fix serviceworker output file and misc improvements (#11562) (#11610)
|
||||||
|
* When initialising repositories ensure that the user doing the creation is the initializer (#11601) (#11608)
|
||||||
|
* Prevent empty query parameter being set on dashboard (#11561) (#11604)
|
||||||
|
* Fix images in wiki edit preview (#11546) (#11602)
|
||||||
|
* Prevent (caught) panic on login (#11590) (#11597)
|
||||||
|
* Prevent transferring repos to invisible orgs (#11517) (#11549)
|
||||||
|
* Move serviceworker to workbox and fix SSE interference (#11538) (#11547)
|
||||||
|
* API PullReviewComment HTMLPullURL should return the HTMLURL (#11501) (#11533)
|
||||||
|
* Fix repo-list private and total count bugs (#11500) (#11532)
|
||||||
|
* Fix form action template substitutions on admin pages (backport #11519) (#11531)
|
||||||
|
* Fix a bug where the reaction emoji doesn't disappear. (#11489) (#11530)
|
||||||
|
* TrimSpace when reading InternalToken from a file (#11502) (#11524)
|
||||||
|
* Fix selected line color in arc-green (#11492) (#11520)
|
||||||
|
* Make localstorage read ssh or https correctly (#11483) (#11490)
|
||||||
* Check branch protection on IsUserAllowedToUpdate (#11448)
|
* Check branch protection on IsUserAllowedToUpdate (#11448)
|
||||||
* Fix margin on attached segment headers when they are separated by other element (#11425)
|
* Fix margin on attached segment headers when they are separated by other element (#11425)
|
||||||
* Fix webhook template when validation errors occur (#11421)
|
* Fix webhook template when validation errors occur (#11421)
|
||||||
@@ -176,6 +243,22 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* Fix wrong original git service type on a migrated repository (#9693)
|
* Fix wrong original git service type on a migrated repository (#9693)
|
||||||
* Fix ref links in issue overviews for tags (#8742)
|
* Fix ref links in issue overviews for tags (#8742)
|
||||||
* ENHANCEMENTS
|
* ENHANCEMENTS
|
||||||
|
* Fix search form button overlap (#11840) (#11864)
|
||||||
|
* Make tabular menu styling consistent for arc-green (#11570) (#11798)
|
||||||
|
* Add option to API to update PullRequest base branch (#11666) (#11796)
|
||||||
|
* Increase maximum SQLite variables count to 32766 (#11696) (#11783)
|
||||||
|
* Update emoji dataset with skin tone variants (#11678) (#11763)
|
||||||
|
* Add logging to long migrations (#11647) (#11691)
|
||||||
|
* Change language statistics to save size instead of percentage (#11681) (#11690)
|
||||||
|
* Allow different HardBreaks settings for documents and comments (#11515) (#11599)
|
||||||
|
* Fix alignment for commits on dashboard (#11595) (#11680)
|
||||||
|
* Default MSSQL port 0 to allow automatic detection by default (#11642) (#11673)
|
||||||
|
* Handle expected errors in AddGPGkey API (#11644) (#11661)
|
||||||
|
* Close EventSource before unloading the page (#11539) (#11557)
|
||||||
|
* Ensure emoji render with regular font-weight (#11541) (#11545)
|
||||||
|
* Fix webpack chunk loading with STATIC_URL_PREFIX (#11526) (#11542)
|
||||||
|
* Tweak reaction buttons (#11516)
|
||||||
|
* Use more toned colors for selected line (#11493) (#11511)
|
||||||
* Increase width for authors on commit view (#11441)
|
* Increase width for authors on commit view (#11441)
|
||||||
* Hide archived repos by default in repo-list (#11440)
|
* Hide archived repos by default in repo-list (#11440)
|
||||||
* Better styling for code review comment textarea (#11428)
|
* Better styling for code review comment textarea (#11428)
|
||||||
@@ -338,6 +421,15 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* Fix queue log param (#10733)
|
* Fix queue log param (#10733)
|
||||||
* Add warning when using relative path to app.ini (#10104)
|
* Add warning when using relative path to app.ini (#10104)
|
||||||
|
|
||||||
|
## [1.11.7](https://github.com/go-gitea/gitea/releases/tag/v1.11.7) - 2020-06-18
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* Use ID or Where to instead directly use Get when load object from database (#11925) (#11935)
|
||||||
|
* Fix __webpack_public_path__ for 1.11 (#11907)
|
||||||
|
* Fix verification of subkeys of default gpg key (#11713) (#11902)
|
||||||
|
* Remove unnecessary parentheses in wiki/view template (#11781)
|
||||||
|
* Doctor fix xorm.Count nil on sqlite error (#11741)
|
||||||
|
|
||||||
## [1.11.6](https://github.com/go-gitea/gitea/releases/tag/v1.11.6) - 2020-05-30
|
## [1.11.6](https://github.com/go-gitea/gitea/releases/tag/v1.11.6) - 2020-05-30
|
||||||
|
|
||||||
* SECURITY
|
* SECURITY
|
||||||
|
|||||||
17
Makefile
17
Makefile
@@ -40,8 +40,10 @@ endif
|
|||||||
|
|
||||||
|
|
||||||
ifeq ($(OS), Windows_NT)
|
ifeq ($(OS), Windows_NT)
|
||||||
|
GOFLAGS := -v -buildmode=exe
|
||||||
EXECUTABLE ?= gitea.exe
|
EXECUTABLE ?= gitea.exe
|
||||||
else
|
else
|
||||||
|
GOFLAGS := -v
|
||||||
EXECUTABLE ?= gitea
|
EXECUTABLE ?= gitea
|
||||||
UNAME_S := $(shell uname -s)
|
UNAME_S := $(shell uname -s)
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
@@ -54,7 +56,6 @@ endif
|
|||||||
|
|
||||||
GOFMT ?= gofmt -s
|
GOFMT ?= gofmt -s
|
||||||
|
|
||||||
GOFLAGS := -v
|
|
||||||
EXTRA_GOFLAGS ?=
|
EXTRA_GOFLAGS ?=
|
||||||
|
|
||||||
MAKE_VERSION := $(shell $(MAKE) -v | head -n 1)
|
MAKE_VERSION := $(shell $(MAKE) -v | head -n 1)
|
||||||
@@ -253,7 +254,7 @@ swagger-validate:
|
|||||||
.PHONY: errcheck
|
.PHONY: errcheck
|
||||||
errcheck:
|
errcheck:
|
||||||
@hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/kisielk/errcheck; \
|
GO111MODULE=off $(GO) get -u github.com/kisielk/errcheck; \
|
||||||
fi
|
fi
|
||||||
errcheck $(GO_PACKAGES)
|
errcheck $(GO_PACKAGES)
|
||||||
|
|
||||||
@@ -264,14 +265,14 @@ revive:
|
|||||||
.PHONY: misspell-check
|
.PHONY: misspell-check
|
||||||
misspell-check:
|
misspell-check:
|
||||||
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
||||||
fi
|
fi
|
||||||
misspell -error -i unknwon,destory $(GO_SOURCES_OWN)
|
misspell -error -i unknwon,destory $(GO_SOURCES_OWN)
|
||||||
|
|
||||||
.PHONY: misspell
|
.PHONY: misspell
|
||||||
misspell:
|
misspell:
|
||||||
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
||||||
fi
|
fi
|
||||||
misspell -w -i unknwon $(GO_SOURCES_OWN)
|
misspell -w -i unknwon $(GO_SOURCES_OWN)
|
||||||
|
|
||||||
@@ -529,9 +530,9 @@ $(DIST_DIRS):
|
|||||||
.PHONY: release-windows
|
.PHONY: release-windows
|
||||||
release-windows: | $(DIST_DIRS)
|
release-windows: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
cp /build/* $(DIST)/binaries
|
cp /build/* $(DIST)/binaries
|
||||||
endif
|
endif
|
||||||
@@ -539,7 +540,7 @@ endif
|
|||||||
.PHONY: release-linux
|
.PHONY: release-linux
|
||||||
release-linux: | $(DIST_DIRS)
|
release-linux: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/mips64le,linux/mips,linux/mipsle' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/mips64le,linux/mips,linux/mipsle' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
@@ -549,7 +550,7 @@ endif
|
|||||||
.PHONY: release-darwin
|
.PHONY: release-darwin
|
||||||
release-darwin: | $(DIST_DIRS)
|
release-darwin: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
|
|||||||
@@ -120,6 +120,12 @@ var checklist = []check{
|
|||||||
isDefault: false,
|
isDefault: false,
|
||||||
f: runDoctorPRMergeBase,
|
f: runDoctorPRMergeBase,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Recalculate Stars number for all user",
|
||||||
|
name: "recalculate_stars_number",
|
||||||
|
isDefault: false,
|
||||||
|
f: runDoctorUserStarNum,
|
||||||
|
},
|
||||||
// more checks please append here
|
// more checks please append here
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,6 +500,10 @@ func runDoctorPRMergeBase(ctx *cli.Context) ([]string, error) {
|
|||||||
return results, err
|
return results, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runDoctorUserStarNum(ctx *cli.Context) ([]string, error) {
|
||||||
|
return nil, models.DoctorUserStarNum()
|
||||||
|
}
|
||||||
|
|
||||||
func runDoctorScriptType(ctx *cli.Context) ([]string, error) {
|
func runDoctorScriptType(ctx *cli.Context) ([]string, error) {
|
||||||
path, err := exec.LookPath(setting.ScriptType)
|
path, err := exec.LookPath(setting.ScriptType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -574,6 +584,22 @@ func runDoctorCheckDBConsistency(ctx *cli.Context) ([]string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count, err = models.CountNullArchivedRepository()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
if ctx.Bool("fix") {
|
||||||
|
updatedCount, err := models.FixNullArchivedRepository()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("%d repositories with null is_archived updated", updatedCount))
|
||||||
|
} else {
|
||||||
|
results = append(results, fmt.Sprintf("%d repositories with null is_archived", count))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//ToDo: function to recalc all counters
|
//ToDo: function to recalc all counters
|
||||||
|
|
||||||
return results, nil
|
return results, nil
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ DISABLED_REPO_UNITS =
|
|||||||
DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki
|
DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki
|
||||||
; Prefix archive files by placing them in a directory named after the repository
|
; Prefix archive files by placing them in a directory named after the repository
|
||||||
PREFIX_ARCHIVE_FILES = true
|
PREFIX_ARCHIVE_FILES = true
|
||||||
|
; The default branch name of new repositories
|
||||||
|
DEFAULT_BRANCH=master
|
||||||
|
|
||||||
[repository.editor]
|
[repository.editor]
|
||||||
; List of file extensions for which lines should be wrapped in the Monaco editor
|
; List of file extensions for which lines should be wrapped in the Monaco editor
|
||||||
@@ -209,7 +211,7 @@ MIN_TIMEOUT = 10s
|
|||||||
MAX_TIMEOUT = 60s
|
MAX_TIMEOUT = 60s
|
||||||
TIMEOUT_STEP = 10s
|
TIMEOUT_STEP = 10s
|
||||||
; This setting determines how often the db is queried to get the latest notification counts.
|
; This setting determines how often the db is queried to get the latest notification counts.
|
||||||
; If the browser client supports EventSource, it will be used in preference to polling notification.
|
; If the browser client supports EventSource and SharedWorker, a SharedWorker will be used in preference to polling notification. Set to -1 to disable the EventSource
|
||||||
EVENT_SOURCE_UPDATE_TIME = 10s
|
EVENT_SOURCE_UPDATE_TIME = 10s
|
||||||
|
|
||||||
[markdown]
|
[markdown]
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
|||||||
- `ENABLE_PUSH_CREATE_USER`: **false**: Allow users to push local repositories to Gitea and have them automatically created for a user.
|
- `ENABLE_PUSH_CREATE_USER`: **false**: Allow users to push local repositories to Gitea and have them automatically created for a user.
|
||||||
- `ENABLE_PUSH_CREATE_ORG`: **false**: Allow users to push local repositories to Gitea and have them automatically created for an org.
|
- `ENABLE_PUSH_CREATE_ORG`: **false**: Allow users to push local repositories to Gitea and have them automatically created for an org.
|
||||||
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
||||||
|
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
|
||||||
|
|
||||||
### Repository - Pull Request (`repository.pull-request`)
|
### Repository - Pull Request (`repository.pull-request`)
|
||||||
|
|
||||||
@@ -147,8 +148,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
|||||||
- `MIN_TIMEOUT`: **10s**: These options control how often notification endpoint is polled to update the notification count. On page load the notification count will be checked after `MIN_TIMEOUT`. The timeout will increase to `MAX_TIMEOUT` by `TIMEOUT_STEP` if the notification count is unchanged. Set MIN_TIMEOUT to 0 to turn off.
|
- `MIN_TIMEOUT`: **10s**: These options control how often notification endpoint is polled to update the notification count. On page load the notification count will be checked after `MIN_TIMEOUT`. The timeout will increase to `MAX_TIMEOUT` by `TIMEOUT_STEP` if the notification count is unchanged. Set MIN_TIMEOUT to 0 to turn off.
|
||||||
- `MAX_TIMEOUT`: **60s**.
|
- `MAX_TIMEOUT`: **60s**.
|
||||||
- `TIMEOUT_STEP`: **10s**.
|
- `TIMEOUT_STEP`: **10s**.
|
||||||
- `EVENT_SOURCE_UPDATE_TIME`: **10s**: This setting determines how often the database is queried to update notification counts. If the browser client supports `EventSource`, it will be used in preference to polling notification endpoint.
|
- `EVENT_SOURCE_UPDATE_TIME`: **10s**: This setting determines how often the database is queried to update notification counts. If the browser client supports `EventSource` and `SharedWorker`, a `SharedWorker` will be used in preference to polling notification endpoint. Set to **-1** to disable the `EventSource`.
|
||||||
|
|
||||||
|
|
||||||
## Markdown (`markdown`)
|
## Markdown (`markdown`)
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ Gitea will search for a number of things from the `CustomPath`. By default this
|
|||||||
the `custom/` directory in the current working directory when running Gitea. It will also
|
the `custom/` directory in the current working directory when running Gitea. It will also
|
||||||
look for its configuration file `CustomConf` in `$CustomPath/conf/app.ini`, and will use the
|
look for its configuration file `CustomConf` in `$CustomPath/conf/app.ini`, and will use the
|
||||||
current working directory as the relative base path `AppWorkPath` for a number configurable
|
current working directory as the relative base path `AppWorkPath` for a number configurable
|
||||||
values.
|
values. Finally the static files will be served from `StaticRootPath` which defaults to the `AppWorkPath`.
|
||||||
|
|
||||||
These values, although useful when developing, may conflict with downstream users preferences.
|
These values, although useful when developing, may conflict with downstream users preferences.
|
||||||
|
|
||||||
@@ -152,6 +152,7 @@ using the `LDFLAGS` environment variable for `make`. The appropriate settings ar
|
|||||||
* To set the `CustomPath` use `LDFLAGS="-X \"code.gitea.io/gitea/modules/setting.CustomPath=custom-path\""`
|
* To set the `CustomPath` use `LDFLAGS="-X \"code.gitea.io/gitea/modules/setting.CustomPath=custom-path\""`
|
||||||
* For `CustomConf` you should use `-X \"code.gitea.io/gitea/modules/setting.CustomConf=conf.ini\"`
|
* For `CustomConf` you should use `-X \"code.gitea.io/gitea/modules/setting.CustomConf=conf.ini\"`
|
||||||
* For `AppWorkPath` you should use `-X \"code.gitea.io/gitea/modules/setting.AppWorkPath=working-path\"`
|
* For `AppWorkPath` you should use `-X \"code.gitea.io/gitea/modules/setting.AppWorkPath=working-path\"`
|
||||||
|
* For `StaticRootPath` you should use `-X \"code.gitea.io/gitea/modules/setting.StaticRootPath=static-root-path\"`
|
||||||
|
|
||||||
Add as many of the strings with their preceding `-X` to the `LDFLAGS` variable and run `make build`
|
Add as many of the strings with their preceding `-X` to the `LDFLAGS` variable and run `make build`
|
||||||
with the appropriate `TAGS` as above.
|
with the appropriate `TAGS` as above.
|
||||||
|
|||||||
14
go.mod
14
go.mod
@@ -15,7 +15,7 @@ require (
|
|||||||
gitea.com/macaron/i18n v0.0.0-20190822004228-474e714e2223
|
gitea.com/macaron/i18n v0.0.0-20190822004228-474e714e2223
|
||||||
gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a
|
gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a
|
||||||
gitea.com/macaron/macaron v1.4.0
|
gitea.com/macaron/macaron v1.4.0
|
||||||
gitea.com/macaron/session v0.0.0-20191207215012-613cebf0674d
|
gitea.com/macaron/session v0.0.0-20200902202411-e3a87877db6e
|
||||||
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7
|
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/PuerkitoBio/goquery v1.5.0
|
github.com/PuerkitoBio/goquery v1.5.0
|
||||||
@@ -39,7 +39,7 @@ require (
|
|||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a // indirect
|
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a // indirect
|
||||||
github.com/go-enry/go-enry/v2 v2.5.2
|
github.com/go-enry/go-enry/v2 v2.5.2
|
||||||
github.com/go-git/go-billy/v5 v5.0.0
|
github.com/go-git/go-billy/v5 v5.0.0
|
||||||
github.com/go-git/go-git/v5 v5.0.0
|
github.com/go-git/go-git/v5 v5.1.0
|
||||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
||||||
github.com/go-redis/redis v6.15.2+incompatible
|
github.com/go-redis/redis v6.15.2+incompatible
|
||||||
github.com/go-sql-driver/mysql v1.4.1
|
github.com/go-sql-driver/mysql v1.4.1
|
||||||
@@ -48,7 +48,8 @@ require (
|
|||||||
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
|
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
|
||||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||||
github.com/golang/protobuf v1.4.1 // indirect
|
github.com/golang/protobuf v1.4.1 // indirect
|
||||||
github.com/google/go-github/v24 v24.0.1
|
github.com/google/go-github/v32 v32.1.0
|
||||||
|
github.com/google/uuid v1.1.1
|
||||||
github.com/gorilla/context v1.1.1
|
github.com/gorilla/context v1.1.1
|
||||||
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
|
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
|
||||||
github.com/huandu/xstrings v1.3.0
|
github.com/huandu/xstrings v1.3.0
|
||||||
@@ -85,7 +86,6 @@ require (
|
|||||||
github.com/prometheus/procfs v0.0.4 // indirect
|
github.com/prometheus/procfs v0.0.4 // indirect
|
||||||
github.com/quasoft/websspi v1.0.0
|
github.com/quasoft/websspi v1.0.0
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
|
||||||
github.com/satori/go.uuid v1.2.0
|
|
||||||
github.com/sergi/go-diff v1.1.0
|
github.com/sergi/go-diff v1.1.0
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect
|
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||||
@@ -102,10 +102,10 @@ require (
|
|||||||
github.com/yohcop/openid-go v1.0.0
|
github.com/yohcop/openid-go v1.0.0
|
||||||
github.com/yuin/goldmark v1.1.25
|
github.com/yuin/goldmark v1.1.25
|
||||||
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60
|
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60
|
||||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1
|
||||||
golang.org/x/text v0.3.2
|
golang.org/x/text v0.3.2
|
||||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
|
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
|
||||||
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224
|
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224
|
||||||
|
|||||||
32
go.sum
32
go.sum
@@ -37,8 +37,8 @@ gitea.com/macaron/macaron v1.4.0 h1:FY1QDGqyuUzs21K6ChkbYbRUfwL7v2aUrhNEJ0IgsAw=
|
|||||||
gitea.com/macaron/macaron v1.4.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY=
|
gitea.com/macaron/macaron v1.4.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY=
|
||||||
gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705 h1:mvkQGAlON1Z6Y8pqa/+FpYIskk54mazuECUfZK5oTg0=
|
gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705 h1:mvkQGAlON1Z6Y8pqa/+FpYIskk54mazuECUfZK5oTg0=
|
||||||
gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705/go.mod h1:1ujH0jD6Ca4iK9NL0Q2a7fG2chvXx5hVa7hBfABwpkA=
|
gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705/go.mod h1:1ujH0jD6Ca4iK9NL0Q2a7fG2chvXx5hVa7hBfABwpkA=
|
||||||
gitea.com/macaron/session v0.0.0-20191207215012-613cebf0674d h1:XLww3CvnFZkXVwauN67fniDaIpIqsE+9KVcxlZKlvLU=
|
gitea.com/macaron/session v0.0.0-20200902202411-e3a87877db6e h1:BHoJ/xWNt6FrVsL54JennM9HPIQlnbmRvmaC5DO65pU=
|
||||||
gitea.com/macaron/session v0.0.0-20191207215012-613cebf0674d/go.mod h1:FanKy3WjWb5iw/iZBPk4ggoQT9FcM6bkBPvmDmsH6tY=
|
gitea.com/macaron/session v0.0.0-20200902202411-e3a87877db6e/go.mod h1:FanKy3WjWb5iw/iZBPk4ggoQT9FcM6bkBPvmDmsH6tY=
|
||||||
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 h1:N9QFoeNsUXLhl14mefLzGluqV7w2mGU3u+iZU+jCeWk=
|
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 h1:N9QFoeNsUXLhl14mefLzGluqV7w2mGU3u+iZU+jCeWk=
|
||||||
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7/go.mod h1:kgsbFPPS4P+acDYDOPDa3N4IWWOuDJt5/INKRUz7aks=
|
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7/go.mod h1:kgsbFPPS4P+acDYDOPDa3N4IWWOuDJt5/INKRUz7aks=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
@@ -203,8 +203,8 @@ github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agR
|
|||||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
|
github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||||
github.com/go-git/go-git/v5 v5.0.0 h1:k5RWPm4iJwYtfWoxIJy4wJX9ON7ihPeZZYC1fLYDnpg=
|
github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk=
|
||||||
github.com/go-git/go-git/v5 v5.0.0/go.mod h1:oYD8y9kWsGINPFJoLdaScGCN6dlKg23blmClfZwtUVA=
|
github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
@@ -315,10 +315,8 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
|||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||||
github.com/google/go-github/v24 v24.0.1 h1:KCt1LjMJEey1qvPXxa9SjaWxwTsCWSq6p2Ju57UR4Q4=
|
|
||||||
github.com/google/go-github/v24 v24.0.1/go.mod h1:CRqaW1Uns1TCkP0wqTpxYyRxRjxwvKU/XSS44u6X74M=
|
|
||||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
@@ -371,6 +369,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
|||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/huandu/xstrings v1.3.0 h1:gvV6jG9dTgFEncxo+AF7PH6MZXi/vZl25owA/8Dg8Wo=
|
github.com/huandu/xstrings v1.3.0 h1:gvV6jG9dTgFEncxo+AF7PH6MZXi/vZl25owA/8Dg8Wo=
|
||||||
github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
|
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||||
|
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
||||||
github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=
|
github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=
|
||||||
@@ -556,8 +556,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qq
|
|||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
|
||||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
||||||
@@ -664,7 +662,6 @@ go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
|||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
@@ -681,8 +678,8 @@ golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
||||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
@@ -721,8 +718,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y=
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
@@ -737,7 +734,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -769,8 +765,8 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0
|
|||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f h1:mOhmO9WsBaJCNmaZHPtHs9wOcdqdKCjF6OPJlmDM3KI=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func TestAPINotification(t *testing.T) {
|
|||||||
assert.EqualValues(t, false, apiNL[2].Pinned)
|
assert.EqualValues(t, false, apiNL[2].Pinned)
|
||||||
|
|
||||||
// -- GET /repos/{owner}/{repo}/notifications --
|
// -- GET /repos/{owner}/{repo}/notifications --
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?token=%s", user2.Name, repo1.Name, token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread&token=%s", user2.Name, repo1.Name, token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ func TestAPINotification(t *testing.T) {
|
|||||||
assert.True(t, new.New > 0)
|
assert.True(t, new.New > 0)
|
||||||
|
|
||||||
// -- mark notifications as read --
|
// -- mark notifications as read --
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
assert.Len(t, apiNL, 2)
|
assert.Len(t, apiNL, 2)
|
||||||
@@ -101,7 +101,7 @@ func TestAPINotification(t *testing.T) {
|
|||||||
req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token))
|
req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusResetContent)
|
resp = session.MakeRequest(t, req, http.StatusResetContent)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
assert.Len(t, apiNL, 1)
|
assert.Len(t, apiNL, 1)
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ func TestAPIPullReview(t *testing.T) {
|
|||||||
Body: "first old line",
|
Body: "first old line",
|
||||||
OldLineNum: 1,
|
OldLineNum: 1,
|
||||||
NewLineNum: 0,
|
NewLineNum: 0,
|
||||||
|
}, {
|
||||||
|
Path: "iso-8859-1.txt",
|
||||||
|
Body: "this line contains a non-utf-8 character",
|
||||||
|
OldLineNum: 0,
|
||||||
|
NewLineNum: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -93,7 +98,7 @@ func TestAPIPullReview(t *testing.T) {
|
|||||||
DecodeJSON(t, resp, &review)
|
DecodeJSON(t, resp, &review)
|
||||||
assert.EqualValues(t, 6, review.ID)
|
assert.EqualValues(t, 6, review.ID)
|
||||||
assert.EqualValues(t, "PENDING", review.State)
|
assert.EqualValues(t, "PENDING", review.State)
|
||||||
assert.EqualValues(t, 2, review.CodeCommentsCount)
|
assert.EqualValues(t, 3, review.CodeCommentsCount)
|
||||||
|
|
||||||
// test SubmitPullReview
|
// test SubmitPullReview
|
||||||
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, review.ID, token), &api.SubmitPullReviewOptions{
|
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, review.ID, token), &api.SubmitPullReviewOptions{
|
||||||
@@ -104,7 +109,7 @@ func TestAPIPullReview(t *testing.T) {
|
|||||||
DecodeJSON(t, resp, &review)
|
DecodeJSON(t, resp, &review)
|
||||||
assert.EqualValues(t, 6, review.ID)
|
assert.EqualValues(t, 6, review.ID)
|
||||||
assert.EqualValues(t, "APPROVED", review.State)
|
assert.EqualValues(t, "APPROVED", review.State)
|
||||||
assert.EqualValues(t, 2, review.CodeCommentsCount)
|
assert.EqualValues(t, 3, review.CodeCommentsCount)
|
||||||
|
|
||||||
// test DeletePullReview
|
// test DeletePullReview
|
||||||
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{
|
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -57,6 +58,12 @@ func TestAPISearchRepo(t *testing.T) {
|
|||||||
user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 20}).(*models.User)
|
user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 20}).(*models.User)
|
||||||
orgUser := models.AssertExistsAndLoadBean(t, &models.User{ID: 17}).(*models.User)
|
orgUser := models.AssertExistsAndLoadBean(t, &models.User{ID: 17}).(*models.User)
|
||||||
|
|
||||||
|
oldAPIDefaultNum := setting.API.DefaultPagingNum
|
||||||
|
defer func() {
|
||||||
|
setting.API.DefaultPagingNum = oldAPIDefaultNum
|
||||||
|
}()
|
||||||
|
setting.API.DefaultPagingNum = 10
|
||||||
|
|
||||||
// Map of expected results, where key is user for login
|
// Map of expected results, where key is user for login
|
||||||
type expectedResults map[*models.User]struct {
|
type expectedResults map[*models.User]struct {
|
||||||
count int
|
count int
|
||||||
@@ -79,7 +86,7 @@ func TestAPISearchRepo(t *testing.T) {
|
|||||||
user: {count: 10},
|
user: {count: 10},
|
||||||
user2: {count: 10}},
|
user2: {count: 10}},
|
||||||
},
|
},
|
||||||
{name: "RepositoriesDefaultMax10", requestURL: "/api/v1/repos/search?default&private=false", expectedResults: expectedResults{
|
{name: "RepositoriesDefault", requestURL: "/api/v1/repos/search?default&private=false", expectedResults: expectedResults{
|
||||||
nil: {count: 10},
|
nil: {count: 10},
|
||||||
user: {count: 10},
|
user: {count: 10},
|
||||||
user2: {count: 10}},
|
user2: {count: 10}},
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ func TestDeleteBranch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUndoDeleteBranch(t *testing.T) {
|
func TestUndoDeleteBranch(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
deleteBranch(t)
|
||||||
deleteBranch(t)
|
htmlDoc, name := branchAction(t, ".undo-button")
|
||||||
htmlDoc, name := branchAction(t, ".undo-button")
|
assert.Contains(t,
|
||||||
assert.Contains(t,
|
htmlDoc.doc.Find(".ui.positive.message").Text(),
|
||||||
htmlDoc.doc.Find(".ui.positive.message").Text(),
|
i18n.Tr("en", "repo.branch.restore_success", name),
|
||||||
i18n.Tr("en", "repo.branch.restore_success", name),
|
)
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteBranch(t *testing.T) {
|
func deleteBranch(t *testing.T) {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func TestEventSourceManagerRun(t *testing.T) {
|
|||||||
var apiNL []api.NotificationThread
|
var apiNL []api.NotificationThread
|
||||||
|
|
||||||
// -- mark notifications as read --
|
// -- mark notifications as read --
|
||||||
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token))
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
@@ -69,7 +69,7 @@ func TestEventSourceManagerRun(t *testing.T) {
|
|||||||
req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token))
|
req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusResetContent)
|
resp = session.MakeRequest(t, req, http.StatusResetContent)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s&status-types=unread", token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
assert.Len(t, apiNL, 1)
|
assert.Len(t, apiNL, 1)
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
|||||||
|
xe<><65>N<EFBFBD>0D<>#<23><1F><03>4
|
||||||
|
J<EFBFBD>A<05>5<EFBFBD><35><EFBFBD><EFBFBD>,<2C>x<EFBFBD>zsV<73><56><EFBFBD>5<08>D<EFBFBD><44>ػ<EFBFBD>7<EFBFBD>,=<3D><>o.<13>E卢<45>q5J=<3D><><EFBFBD><EFBFBD><EFBFBD> r<>=>4<1B><1D>
|
||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
4a357436d925b5c974181ff12a994538ddc5a269
|
5f22f7d0d95d614d25a5b68592adb345a4b5c7fd
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/test"
|
"code.gitea.io/gitea/modules/test"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -106,6 +107,12 @@ func TestCreateReleaseDraft(t *testing.T) {
|
|||||||
func TestCreateReleasePaging(t *testing.T) {
|
func TestCreateReleasePaging(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
defer prepareTestEnv(t)()
|
||||||
|
|
||||||
|
oldAPIDefaultNum := setting.API.DefaultPagingNum
|
||||||
|
defer func() {
|
||||||
|
setting.API.DefaultPagingNum = oldAPIDefaultNum
|
||||||
|
}()
|
||||||
|
setting.API.DefaultPagingNum = 10
|
||||||
|
|
||||||
session := loginUser(t, "user2")
|
session := loginUser(t, "user2")
|
||||||
// Create enaugh releases to have paging
|
// Create enaugh releases to have paging
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
gouuid "github.com/satori/go.uuid"
|
gouuid "github.com/google/uuid"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ func (a *Attachment) LinkedRepository() (*Repository, UnitType, error) {
|
|||||||
|
|
||||||
// NewAttachment creates a new attachment object.
|
// NewAttachment creates a new attachment object.
|
||||||
func NewAttachment(attach *Attachment, buf []byte, file io.Reader) (_ *Attachment, err error) {
|
func NewAttachment(attach *Attachment, buf []byte, file io.Reader) (_ *Attachment, err error) {
|
||||||
attach.UUID = gouuid.NewV4().String()
|
attach.UUID = gouuid.New().String()
|
||||||
|
|
||||||
localPath := attach.LocalPath()
|
localPath := attach.LocalPath()
|
||||||
if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
|
if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
|
||||||
@@ -136,9 +136,8 @@ func GetAttachmentByID(id int64) (*Attachment, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAttachmentByID(e Engine, id int64) (*Attachment, error) {
|
func getAttachmentByID(e Engine, id int64) (*Attachment, error) {
|
||||||
attach := &Attachment{ID: id}
|
attach := &Attachment{}
|
||||||
|
if has, err := e.ID(id).Get(attach); err != nil {
|
||||||
if has, err := e.Get(attach); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
return nil, ErrAttachmentNotExist{ID: id, UUID: ""}
|
return nil, ErrAttachmentNotExist{ID: id, UUID: ""}
|
||||||
@@ -147,8 +146,8 @@ func getAttachmentByID(e Engine, id int64) (*Attachment, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAttachmentByUUID(e Engine, uuid string) (*Attachment, error) {
|
func getAttachmentByUUID(e Engine, uuid string) (*Attachment, error) {
|
||||||
attach := &Attachment{UUID: uuid}
|
attach := &Attachment{}
|
||||||
has, err := e.Get(attach)
|
has, err := e.Where("uuid=?", uuid).Get(attach)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
|||||||
@@ -98,9 +98,10 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsUserMergeWhitelisted checks if some user is whitelisted to merge to this branch
|
// IsUserMergeWhitelisted checks if some user is whitelisted to merge to this branch
|
||||||
func (protectBranch *ProtectedBranch) IsUserMergeWhitelisted(userID int64) bool {
|
func (protectBranch *ProtectedBranch) IsUserMergeWhitelisted(userID int64, permissionInRepo Permission) bool {
|
||||||
if !protectBranch.EnableMergeWhitelist {
|
if !protectBranch.EnableMergeWhitelist {
|
||||||
return true
|
// Then we need to fall back on whether the user has write permission
|
||||||
|
return permissionInRepo.CanWrite(UnitTypeCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if base.Int64sContains(protectBranch.MergeWhitelistUserIDs, userID) {
|
if base.Int64sContains(protectBranch.MergeWhitelistUserIDs, userID) {
|
||||||
@@ -240,8 +241,8 @@ func getProtectedBranchBy(e Engine, repoID int64, branchName string) (*Protected
|
|||||||
|
|
||||||
// GetProtectedBranchByID getting protected branch by ID
|
// GetProtectedBranchByID getting protected branch by ID
|
||||||
func GetProtectedBranchByID(id int64) (*ProtectedBranch, error) {
|
func GetProtectedBranchByID(id int64) (*ProtectedBranch, error) {
|
||||||
rel := &ProtectedBranch{ID: id}
|
rel := &ProtectedBranch{}
|
||||||
has, err := x.Get(rel)
|
has, err := x.ID(id).Get(rel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -509,9 +510,9 @@ func (repo *Repository) GetDeletedBranches() ([]*DeletedBranch, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetDeletedBranchByID get a deleted branch by its ID
|
// GetDeletedBranchByID get a deleted branch by its ID
|
||||||
func (repo *Repository) GetDeletedBranchByID(ID int64) (*DeletedBranch, error) {
|
func (repo *Repository) GetDeletedBranchByID(id int64) (*DeletedBranch, error) {
|
||||||
deletedBranch := &DeletedBranch{ID: ID}
|
deletedBranch := &DeletedBranch{}
|
||||||
has, err := x.Get(deletedBranch)
|
has, err := x.ID(id).Get(deletedBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,3 +283,15 @@ func DeleteOrphanedObjects(subject, refobject, joinCond string) error {
|
|||||||
Delete("`" + subject + "`")
|
Delete("`" + subject + "`")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountNullArchivedRepository counts the number of repositories with is_archived is null
|
||||||
|
func CountNullArchivedRepository() (int64, error) {
|
||||||
|
return x.Where(builder.IsNull{"is_archived"}).Count(new(Repository))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FixNullArchivedRepository sets is_archived to false where it is null
|
||||||
|
func FixNullArchivedRepository() (int64, error) {
|
||||||
|
return x.Where(builder.IsNull{"is_archived"}).Cols("is_archived").Update(&Repository{
|
||||||
|
IsArchived: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -286,6 +286,9 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity) (*GPGKey, error) {
|
|||||||
|
|
||||||
emails := make([]*EmailAddress, 0, len(e.Identities))
|
emails := make([]*EmailAddress, 0, len(e.Identities))
|
||||||
for _, ident := range e.Identities {
|
for _, ident := range e.Identities {
|
||||||
|
if ident.Revocation != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
email := strings.ToLower(strings.TrimSpace(ident.UserId.Email))
|
email := strings.ToLower(strings.TrimSpace(ident.UserId.Email))
|
||||||
for _, e := range userEmails {
|
for _, e := range userEmails {
|
||||||
if e.Email == email {
|
if e.Email == email {
|
||||||
@@ -509,6 +512,18 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
|
var primaryKeys []*GPGKey
|
||||||
|
if key.PrimaryKeyID != "" {
|
||||||
|
primaryKeys, err = GetGPGKeysByKeyID(key.PrimaryKeyID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("GetGPGKeysByKeyID: %v", err)
|
||||||
|
return &CommitVerification{
|
||||||
|
CommittingUser: committer,
|
||||||
|
Verified: false,
|
||||||
|
Reason: "gpg.error.failed_retrieval_gpg_keys",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
activated := false
|
activated := false
|
||||||
if len(email) != 0 {
|
if len(email) != 0 {
|
||||||
for _, e := range key.Emails {
|
for _, e := range key.Emails {
|
||||||
@@ -518,6 +533,20 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !activated {
|
||||||
|
for _, pkey := range primaryKeys {
|
||||||
|
for _, e := range pkey.Emails {
|
||||||
|
if e.IsActivated && strings.EqualFold(e.Email, email) {
|
||||||
|
activated = true
|
||||||
|
email = e.Email
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if activated {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, e := range key.Emails {
|
for _, e := range key.Emails {
|
||||||
if e.IsActivated {
|
if e.IsActivated {
|
||||||
@@ -526,7 +555,22 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !activated {
|
||||||
|
for _, pkey := range primaryKeys {
|
||||||
|
for _, e := range pkey.Emails {
|
||||||
|
if e.IsActivated {
|
||||||
|
activated = true
|
||||||
|
email = e.Email
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if activated {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !activated {
|
if !activated {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -614,7 +658,6 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
|
|||||||
if keyID == "" && sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) > 0 {
|
if keyID == "" && sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) > 0 {
|
||||||
keyID = fmt.Sprintf("%X", sig.IssuerFingerprint[12:20])
|
keyID = fmt.Sprintf("%X", sig.IssuerFingerprint[12:20])
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultReason := NoKeyFound
|
defaultReason := NoKeyFound
|
||||||
|
|
||||||
// First check if the sig has a keyID and if so just look at that
|
// First check if the sig has a keyID and if so just look at that
|
||||||
|
|||||||
@@ -1953,6 +1953,11 @@ func deleteIssuesByRepoID(sess Engine, repoID int64) (attachmentPaths []string,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err = sess.In("dependent_issue_id", deleteCond).
|
||||||
|
Delete(&Comment{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var attachments []*Attachment
|
var attachments []*Attachment
|
||||||
if err = sess.In("issue_id", deleteCond).
|
if err = sess.In("issue_id", deleteCond).
|
||||||
Find(&attachments); err != nil {
|
Find(&attachments); err != nil {
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
@@ -138,7 +141,8 @@ type Comment struct {
|
|||||||
RenderedContent string `xorm:"-"`
|
RenderedContent string `xorm:"-"`
|
||||||
|
|
||||||
// Path represents the 4 lines of code cemented by this comment
|
// Path represents the 4 lines of code cemented by this comment
|
||||||
Patch string `xorm:"TEXT"`
|
Patch string `xorm:"-"`
|
||||||
|
PatchQuoted string `xorm:"TEXT patch"`
|
||||||
|
|
||||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||||
@@ -182,6 +186,33 @@ func (c *Comment) loadIssue(e Engine) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BeforeInsert will be invoked by XORM before inserting a record
|
||||||
|
func (c *Comment) BeforeInsert() {
|
||||||
|
c.PatchQuoted = c.Patch
|
||||||
|
if !utf8.ValidString(c.Patch) {
|
||||||
|
c.PatchQuoted = strconv.Quote(c.Patch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeforeUpdate will be invoked by XORM before updating a record
|
||||||
|
func (c *Comment) BeforeUpdate() {
|
||||||
|
c.PatchQuoted = c.Patch
|
||||||
|
if !utf8.ValidString(c.Patch) {
|
||||||
|
c.PatchQuoted = strconv.Quote(c.Patch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
|
||||||
|
func (c *Comment) AfterLoad(session *xorm.Session) {
|
||||||
|
c.Patch = c.PatchQuoted
|
||||||
|
if len(c.PatchQuoted) > 0 && c.PatchQuoted[0] == '"' {
|
||||||
|
unquoted, err := strconv.Unquote(c.PatchQuoted)
|
||||||
|
if err == nil {
|
||||||
|
c.Patch = unquoted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Comment) loadPoster(e Engine) (err error) {
|
func (c *Comment) loadPoster(e Engine) (err error) {
|
||||||
if c.PosterID <= 0 || c.Poster != nil {
|
if c.PosterID <= 0 || c.Poster != nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -489,10 +520,12 @@ func (c *Comment) LoadReview() error {
|
|||||||
return c.loadReview(x)
|
return c.loadReview(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var notEnoughLines = regexp.MustCompile(`fatal: file .* has only \d+ lines?`)
|
||||||
|
|
||||||
func (c *Comment) checkInvalidation(doer *User, repo *git.Repository, branch string) error {
|
func (c *Comment) checkInvalidation(doer *User, repo *git.Repository, branch string) error {
|
||||||
// FIXME differentiate between previous and proposed line
|
// FIXME differentiate between previous and proposed line
|
||||||
commit, err := repo.LineBlame(branch, repo.Path, c.TreePath, uint(c.UnsignedLine()))
|
commit, err := repo.LineBlame(branch, repo.Path, c.TreePath, uint(c.UnsignedLine()))
|
||||||
if err != nil && strings.Contains(err.Error(), "fatal: no such path") {
|
if err != nil && (strings.Contains(err.Error(), "fatal: no such path") || notEnoughLines.MatchString(err.Error())) {
|
||||||
c.Invalidated = true
|
c.Invalidated = true
|
||||||
return UpdateComment(c, doer)
|
return UpdateComment(c, doer)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,10 +295,8 @@ func getLabelByID(e Engine, labelID int64) (*Label, error) {
|
|||||||
return nil, ErrLabelNotExist{labelID}
|
return nil, ErrLabelNotExist{labelID}
|
||||||
}
|
}
|
||||||
|
|
||||||
l := &Label{
|
l := &Label{}
|
||||||
ID: labelID,
|
has, err := e.ID(labelID).Get(l)
|
||||||
}
|
|
||||||
has, err := e.Get(l)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ func (opts ListOptions) setEnginePagination(e Engine) Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (opts ListOptions) setDefaultValues() {
|
func (opts ListOptions) setDefaultValues() {
|
||||||
if opts.PageSize <= 0 || opts.PageSize > setting.API.MaxResponseItems {
|
if opts.PageSize <= 0 {
|
||||||
|
opts.PageSize = setting.API.DefaultPagingNum
|
||||||
|
}
|
||||||
|
if opts.PageSize > setting.API.MaxResponseItems {
|
||||||
opts.PageSize = setting.API.MaxResponseItems
|
opts.PageSize = setting.API.MaxResponseItems
|
||||||
}
|
}
|
||||||
if opts.Page <= 0 {
|
if opts.Page <= 0 {
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ func (source *LoginSource) SSPI() *SSPIConfig {
|
|||||||
// CreateLoginSource inserts a LoginSource in the DB if not already
|
// CreateLoginSource inserts a LoginSource in the DB if not already
|
||||||
// existing with the given name.
|
// existing with the given name.
|
||||||
func CreateLoginSource(source *LoginSource) error {
|
func CreateLoginSource(source *LoginSource) error {
|
||||||
has, err := x.Get(&LoginSource{Name: source.Name})
|
has, err := x.Where("name=?", source.Name).Exist(new(LoginSource))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if has {
|
} else if has {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ type FindNotificationOptions struct {
|
|||||||
UserID int64
|
UserID int64
|
||||||
RepoID int64
|
RepoID int64
|
||||||
IssueID int64
|
IssueID int64
|
||||||
Status NotificationStatus
|
Status []NotificationStatus
|
||||||
UpdatedAfterUnix int64
|
UpdatedAfterUnix int64
|
||||||
UpdatedBeforeUnix int64
|
UpdatedBeforeUnix int64
|
||||||
}
|
}
|
||||||
@@ -89,8 +89,8 @@ func (opts *FindNotificationOptions) ToCond() builder.Cond {
|
|||||||
if opts.IssueID != 0 {
|
if opts.IssueID != 0 {
|
||||||
cond = cond.And(builder.Eq{"notification.issue_id": opts.IssueID})
|
cond = cond.And(builder.Eq{"notification.issue_id": opts.IssueID})
|
||||||
}
|
}
|
||||||
if opts.Status != 0 {
|
if len(opts.Status) > 0 {
|
||||||
cond = cond.And(builder.Eq{"notification.status": opts.Status})
|
cond = cond.And(builder.In("notification.status", opts.Status))
|
||||||
}
|
}
|
||||||
if opts.UpdatedAfterUnix != 0 {
|
if opts.UpdatedAfterUnix != 0 {
|
||||||
cond = cond.And(builder.Gte{"notification.updated_unix": opts.UpdatedAfterUnix})
|
cond = cond.And(builder.Gte{"notification.updated_unix": opts.UpdatedAfterUnix})
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/google/uuid"
|
||||||
"github.com/unknwon/com"
|
"github.com/unknwon/com"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
@@ -174,7 +174,7 @@ func CreateOAuth2Application(opts CreateOAuth2ApplicationOptions) (*OAuth2Applic
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createOAuth2Application(e Engine, opts CreateOAuth2ApplicationOptions) (*OAuth2Application, error) {
|
func createOAuth2Application(e Engine, opts CreateOAuth2ApplicationOptions) (*OAuth2Application, error) {
|
||||||
clientID := uuid.NewV4().String()
|
clientID := uuid.New().String()
|
||||||
app := &OAuth2Application{
|
app := &OAuth2Application{
|
||||||
UID: opts.UserID,
|
UID: opts.UserID,
|
||||||
Name: opts.Name,
|
Name: opts.Name,
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ func hasOrgVisible(e Engine, org *User, user *User) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (org.Visibility == structs.VisibleTypePrivate || user.IsRestricted) && !org.isUserPartOfOrg(e, user.ID) {
|
if (org.Visibility == structs.VisibleTypePrivate || user.IsRestricted) && !org.hasMemberWithUserID(e, user.ID) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -27,12 +27,13 @@ func (pr *PullRequest) SignMerge(u *User, tmpBasePath, baseCommit, headCommit st
|
|||||||
var gitRepo *git.Repository
|
var gitRepo *git.Repository
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
Loop:
|
||||||
for _, rule := range rules {
|
for _, rule := range rules {
|
||||||
switch rule {
|
switch rule {
|
||||||
case never:
|
case never:
|
||||||
return false, "", &ErrWontSign{never}
|
return false, "", &ErrWontSign{never}
|
||||||
case always:
|
case always:
|
||||||
break
|
break Loop
|
||||||
case pubkey:
|
case pubkey:
|
||||||
keys, err := ListGPGKeys(u.ID, ListOptions{})
|
keys, err := ListGPGKeys(u.ID, ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
// Needed for jpeg support
|
// Needed for jpeg support
|
||||||
_ "image/jpeg"
|
_ "image/jpeg"
|
||||||
@@ -35,6 +36,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/unknwon/com"
|
"github.com/unknwon/com"
|
||||||
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -1383,11 +1385,11 @@ func GetRepositoriesByForkID(forkID int64) ([]*Repository, error) {
|
|||||||
func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) {
|
func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) {
|
||||||
repo.LowerName = strings.ToLower(repo.Name)
|
repo.LowerName = strings.ToLower(repo.Name)
|
||||||
|
|
||||||
if len(repo.Description) > 255 {
|
if utf8.RuneCountInString(repo.Description) > 255 {
|
||||||
repo.Description = repo.Description[:255]
|
repo.Description = string([]rune(repo.Description)[:255])
|
||||||
}
|
}
|
||||||
if len(repo.Website) > 255 {
|
if utf8.RuneCountInString(repo.Website) > 255 {
|
||||||
repo.Website = repo.Website[:255]
|
repo.Website = string([]rune(repo.Website)[:255])
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = e.ID(repo.ID).AllCols().Update(repo); err != nil {
|
if _, err = e.ID(repo.ID).AllCols().Update(repo); err != nil {
|
||||||
@@ -1565,6 +1567,10 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
|
|||||||
releaseAttachments = append(releaseAttachments, attachments[i].LocalPath())
|
releaseAttachments = append(releaseAttachments, attachments[i].LocalPath())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err = sess.Exec("UPDATE `user` SET num_stars=num_stars-1 WHERE id IN (SELECT `uid` FROM `star` WHERE repo_id = ?)", repo.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err = deleteBeans(sess,
|
if err = deleteBeans(sess,
|
||||||
&Access{RepoID: repo.ID},
|
&Access{RepoID: repo.ID},
|
||||||
&Action{RepoID: repo.ID},
|
&Action{RepoID: repo.ID},
|
||||||
@@ -1754,22 +1760,28 @@ func GetRepositoriesMapByIDs(ids []int64) (map[int64]*Repository, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetUserRepositories returns a list of repositories of given user.
|
// GetUserRepositories returns a list of repositories of given user.
|
||||||
func GetUserRepositories(opts *SearchRepoOptions) ([]*Repository, error) {
|
func GetUserRepositories(opts *SearchRepoOptions) ([]*Repository, int64, error) {
|
||||||
if len(opts.OrderBy) == 0 {
|
if len(opts.OrderBy) == 0 {
|
||||||
opts.OrderBy = "updated_unix DESC"
|
opts.OrderBy = "updated_unix DESC"
|
||||||
}
|
}
|
||||||
|
|
||||||
sess := x.
|
var cond = builder.NewCond()
|
||||||
Where("owner_id = ?", opts.Actor.ID).
|
cond = cond.And(builder.Eq{"owner_id": opts.Actor.ID})
|
||||||
OrderBy(opts.OrderBy.String())
|
|
||||||
if !opts.Private {
|
if !opts.Private {
|
||||||
sess.And("is_private=?", false)
|
cond = cond.And(builder.Eq{"is_private": false})
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = opts.setSessionPagination(sess)
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
|
||||||
|
count, err := sess.Where(cond).Count(new(Repository))
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, fmt.Errorf("Count: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sess.Where(cond).OrderBy(opts.OrderBy.String())
|
||||||
repos := make([]*Repository, 0, opts.PageSize)
|
repos := make([]*Repository, 0, opts.PageSize)
|
||||||
return repos, opts.setSessionPagination(sess).Find(&repos)
|
return repos, count, opts.setSessionPagination(sess).Find(&repos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserMirrorRepositories returns a list of mirror repositories of given user.
|
// GetUserMirrorRepositories returns a list of mirror repositories of given user.
|
||||||
@@ -2324,3 +2336,38 @@ func updateRepositoryCols(e Engine, repo *Repository, cols ...string) error {
|
|||||||
func UpdateRepositoryCols(repo *Repository, cols ...string) error {
|
func UpdateRepositoryCols(repo *Repository, cols ...string) error {
|
||||||
return updateRepositoryCols(x, repo, cols...)
|
return updateRepositoryCols(x, repo, cols...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DoctorUserStarNum recalculate Stars number for all user
|
||||||
|
func DoctorUserStarNum() (err error) {
|
||||||
|
const batchSize = 100
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
|
||||||
|
for start := 0; ; start += batchSize {
|
||||||
|
users := make([]User, 0, batchSize)
|
||||||
|
if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(users) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = sess.Begin(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, user := range users {
|
||||||
|
if _, err = sess.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = sess.Commit(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("recalculate Stars number for all user finished")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -187,3 +187,9 @@ func TestDeleteAvatar(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, "", repo.Avatar)
|
assert.Equal(t, "", repo.Avatar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDoctorUserStarNum(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
|
||||||
|
assert.NoError(t, DoctorUserStarNum())
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/generate"
|
"code.gitea.io/gitea/modules/generate"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
gouuid "github.com/satori/go.uuid"
|
gouuid "github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccessToken represents a personal access token.
|
// AccessToken represents a personal access token.
|
||||||
@@ -45,7 +45,7 @@ func NewAccessToken(t *AccessToken) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
t.TokenSalt = salt
|
t.TokenSalt = salt
|
||||||
t.Token = base.EncodeSha1(gouuid.NewV4().String())
|
t.Token = base.EncodeSha1(gouuid.New().String())
|
||||||
t.TokenHash = hashToken(t.Token, t.TokenSalt)
|
t.TokenHash = hashToken(t.Token, t.TokenSalt)
|
||||||
t.TokenLastEight = t.Token[len(t.Token)-8:]
|
t.TokenLastEight = t.Token[len(t.Token)-8:]
|
||||||
_, err = x.Insert(t)
|
_, err = x.Insert(t)
|
||||||
|
|||||||
@@ -142,8 +142,8 @@ func UpdateTwoFactor(t *TwoFactor) error {
|
|||||||
// GetTwoFactorByUID returns the two-factor authentication token associated with
|
// GetTwoFactorByUID returns the two-factor authentication token associated with
|
||||||
// the user, if any.
|
// the user, if any.
|
||||||
func GetTwoFactorByUID(uid int64) (*TwoFactor, error) {
|
func GetTwoFactorByUID(uid int64) (*TwoFactor, error) {
|
||||||
twofa := &TwoFactor{UID: uid}
|
twofa := &TwoFactor{}
|
||||||
has, err := x.Get(twofa)
|
has, err := x.Where("uid=?", uid).Get(twofa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
gouuid "github.com/satori/go.uuid"
|
gouuid "github.com/google/uuid"
|
||||||
"github.com/unknwon/com"
|
"github.com/unknwon/com"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func (upload *Upload) LocalPath() string {
|
|||||||
// NewUpload creates a new upload object.
|
// NewUpload creates a new upload object.
|
||||||
func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err error) {
|
func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err error) {
|
||||||
upload := &Upload{
|
upload := &Upload{
|
||||||
UUID: gouuid.NewV4().String(),
|
UUID: gouuid.New().String(),
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,8 +76,8 @@ func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err err
|
|||||||
|
|
||||||
// GetUploadByUUID returns the Upload by UUID
|
// GetUploadByUUID returns the Upload by UUID
|
||||||
func GetUploadByUUID(uuid string) (*Upload, error) {
|
func GetUploadByUUID(uuid string) (*Upload, error) {
|
||||||
upload := &Upload{UUID: uuid}
|
upload := &Upload{}
|
||||||
has, err := x.Get(upload)
|
has, err := x.Where("uuid=?", uuid).Get(upload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/generate"
|
"code.gitea.io/gitea/modules/generate"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/public"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/structs"
|
"code.gitea.io/gitea/modules/structs"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
@@ -608,12 +609,12 @@ func (u *User) IsUserOrgOwner(orgID int64) bool {
|
|||||||
return isOwner
|
return isOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUserPartOfOrg returns true if user with userID is part of the u organisation.
|
// HasMemberWithUserID returns true if user with userID is part of the u organisation.
|
||||||
func (u *User) IsUserPartOfOrg(userID int64) bool {
|
func (u *User) HasMemberWithUserID(userID int64) bool {
|
||||||
return u.isUserPartOfOrg(x, userID)
|
return u.hasMemberWithUserID(x, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) isUserPartOfOrg(e Engine, userID int64) bool {
|
func (u *User) hasMemberWithUserID(e Engine, userID int64) bool {
|
||||||
isMember, err := isOrganizationMember(e, u.ID, userID)
|
isMember, err := isOrganizationMember(e, u.ID, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("IsOrganizationMember: %v", err)
|
log.Error("IsOrganizationMember: %v", err)
|
||||||
@@ -645,7 +646,7 @@ func (u *User) GetOrganizationCount() (int64, error) {
|
|||||||
|
|
||||||
// GetRepositories returns repositories that user owns, including private repositories.
|
// GetRepositories returns repositories that user owns, including private repositories.
|
||||||
func (u *User) GetRepositories(listOpts ListOptions) (err error) {
|
func (u *User) GetRepositories(listOpts ListOptions) (err error) {
|
||||||
u.Repos, err = GetUserRepositories(&SearchRepoOptions{Actor: u, Private: true, ListOptions: listOpts})
|
u.Repos, _, err = GetUserRepositories(&SearchRepoOptions{Actor: u, Private: true, ListOptions: listOpts})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,7 +879,7 @@ func (u *User) IsGhost() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
reservedUsernames = []string{
|
reservedUsernames = append([]string{
|
||||||
".",
|
".",
|
||||||
"..",
|
"..",
|
||||||
".well-known",
|
".well-known",
|
||||||
@@ -888,17 +889,13 @@ var (
|
|||||||
"attachments",
|
"attachments",
|
||||||
"avatars",
|
"avatars",
|
||||||
"commits",
|
"commits",
|
||||||
"css",
|
|
||||||
"debug",
|
"debug",
|
||||||
"error",
|
"error",
|
||||||
"explore",
|
"explore",
|
||||||
"fomantic",
|
|
||||||
"ghost",
|
"ghost",
|
||||||
"help",
|
"help",
|
||||||
"img",
|
|
||||||
"install",
|
"install",
|
||||||
"issues",
|
"issues",
|
||||||
"js",
|
|
||||||
"less",
|
"less",
|
||||||
"login",
|
"login",
|
||||||
"manifest.json",
|
"manifest.json",
|
||||||
@@ -916,8 +913,8 @@ var (
|
|||||||
"stars",
|
"stars",
|
||||||
"template",
|
"template",
|
||||||
"user",
|
"user",
|
||||||
"vendor",
|
}, public.KnownPublicEntries...)
|
||||||
}
|
|
||||||
reservedUserPatterns = []string{"*.keys", "*.gpg"}
|
reservedUserPatterns = []string{"*.keys", "*.gpg"}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1558,8 +1555,8 @@ func GetUserByEmailContext(ctx DBContext, email string) (*User, error) {
|
|||||||
// Finally, if email address is the protected email address:
|
// Finally, if email address is the protected email address:
|
||||||
if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) {
|
if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) {
|
||||||
username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress))
|
username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress))
|
||||||
user := &User{LowerName: username}
|
user := &User{}
|
||||||
has, err := ctx.e.Get(user)
|
has, err := ctx.e.Where("lower_name=?", username).Get(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
|
|||||||
// GetEmailAddressByID gets a user's email address by ID
|
// GetEmailAddressByID gets a user's email address by ID
|
||||||
func GetEmailAddressByID(uid, id int64) (*EmailAddress, error) {
|
func GetEmailAddressByID(uid, id int64) (*EmailAddress, error) {
|
||||||
// User ID is required for security reasons
|
// User ID is required for security reasons
|
||||||
email := &EmailAddress{ID: id, UID: uid}
|
email := &EmailAddress{UID: uid}
|
||||||
if has, err := x.Get(email); err != nil {
|
if has, err := x.ID(id).Get(email); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -126,7 +126,7 @@ func isEmailUsed(e Engine, email string) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Get(&EmailAddress{Email: email})
|
return e.Where("email=?", email).Get(&EmailAddress{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmailUsed returns true if the email has been used.
|
// IsEmailUsed returns true if the email has been used.
|
||||||
@@ -251,8 +251,8 @@ func MakeEmailPrimary(email *EmailAddress) error {
|
|||||||
return ErrEmailNotActivated
|
return ErrEmailNotActivated
|
||||||
}
|
}
|
||||||
|
|
||||||
user := &User{ID: email.UID}
|
user := &User{}
|
||||||
has, err = x.Get(user)
|
has, err = x.ID(email.UID).Get(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
|||||||
@@ -111,8 +111,8 @@ func GetUserByOpenID(uri string) (*User, error) {
|
|||||||
log.Trace("Normalized OpenID URI: " + uri)
|
log.Trace("Normalized OpenID URI: " + uri)
|
||||||
|
|
||||||
// Otherwise, check in openid table
|
// Otherwise, check in openid table
|
||||||
oid := &UserOpenID{URI: uri}
|
oid := &UserOpenID{}
|
||||||
has, err := x.Get(oid)
|
has, err := x.Where("uri=?", uri).Get(oid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
gouuid "github.com/satori/go.uuid"
|
gouuid "github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HookContentType is the content type of a web hook
|
// HookContentType is the content type of a web hook
|
||||||
@@ -769,7 +769,7 @@ func createHookTask(e Engine, t *HookTask) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
t.UUID = gouuid.NewV4().String()
|
t.UUID = gouuid.New().String()
|
||||||
t.PayloadContent = string(data)
|
t.PayloadContent = string(data)
|
||||||
_, err = e.Insert(t)
|
_, err = e.Insert(t)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs binding.Errors)
|
|||||||
|
|
||||||
// AdminDashboardForm form for admin dashboard operations
|
// AdminDashboardForm form for admin dashboard operations
|
||||||
type AdminDashboardForm struct {
|
type AdminDashboardForm struct {
|
||||||
Op string `binding:"required"`
|
Op string `binding:"required"`
|
||||||
|
From string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates form fields
|
// Validate validates form fields
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ package oauth2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
|
uuid "github.com/google/uuid"
|
||||||
"github.com/lafriks/xormstore"
|
"github.com/lafriks/xormstore"
|
||||||
"github.com/markbates/goth"
|
"github.com/markbates/goth"
|
||||||
"github.com/markbates/goth/gothic"
|
"github.com/markbates/goth/gothic"
|
||||||
@@ -25,7 +27,6 @@ import (
|
|||||||
"github.com/markbates/goth/providers/openidConnect"
|
"github.com/markbates/goth/providers/openidConnect"
|
||||||
"github.com/markbates/goth/providers/twitter"
|
"github.com/markbates/goth/providers/twitter"
|
||||||
"github.com/markbates/goth/providers/yandex"
|
"github.com/markbates/goth/providers/yandex"
|
||||||
uuid "github.com/satori/go.uuid"
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ func Init(x *xorm.Engine) error {
|
|||||||
gothic.Store = store
|
gothic.Store = store
|
||||||
|
|
||||||
gothic.SetState = func(req *http.Request) string {
|
gothic.SetState = func(req *http.Request) string {
|
||||||
return uuid.NewV4().String()
|
return uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
gothic.GetProviderName = func(req *http.Request) (string, error) {
|
gothic.GetProviderName = func(req *http.Request) (string, error) {
|
||||||
@@ -119,7 +120,7 @@ func RemoveProvider(providerName string) {
|
|||||||
|
|
||||||
// used to create different types of goth providers
|
// used to create different types of goth providers
|
||||||
func createProvider(providerName, providerType, clientID, clientSecret, openIDConnectAutoDiscoveryURL string, customURLMapping *CustomURLMapping) (goth.Provider, error) {
|
func createProvider(providerName, providerType, clientID, clientSecret, openIDConnectAutoDiscoveryURL string, customURLMapping *CustomURLMapping) (goth.Provider, error) {
|
||||||
callbackURL := setting.AppURL + "user/oauth2/" + providerName + "/callback"
|
callbackURL := setting.AppURL + "user/oauth2/" + url.PathEscape(providerName) + "/callback"
|
||||||
|
|
||||||
var provider goth.Provider
|
var provider goth.Provider
|
||||||
var err error
|
var err error
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ func (o *OAuth2) userIDFromToken(ctx *macaron.Context) int64 {
|
|||||||
}
|
}
|
||||||
t, err := models.GetAccessTokenBySHA(tokenSHA)
|
t, err := models.GetAccessTokenBySHA(tokenSHA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) {
|
if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) {
|
||||||
log.Error("GetAccessTokenBySHA: %v", err)
|
log.Error("GetAccessTokenBySHA: %v", err)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
@@ -121,7 +121,7 @@ func (o *OAuth2) VerifyAuthData(ctx *macaron.Context, sess session.Store) *model
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isAPIPath(ctx) && !isAttachmentDownload(ctx) {
|
if isInternalPath(ctx) || !isAPIPath(ctx) && !isAttachmentDownload(ctx) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
"gitea.com/macaron/macaron"
|
"gitea.com/macaron/macaron"
|
||||||
"gitea.com/macaron/session"
|
"gitea.com/macaron/session"
|
||||||
gouuid "github.com/satori/go.uuid"
|
gouuid "github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure the struct implements the interface.
|
// Ensure the struct implements the interface.
|
||||||
@@ -92,7 +92,7 @@ func (r *ReverseProxy) newUser(ctx *macaron.Context) *models.User {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
email := gouuid.NewV4().String() + "@localhost"
|
email := gouuid.New().String() + "@localhost"
|
||||||
if setting.Service.EnableReverseProxyEmail {
|
if setting.Service.EnableReverseProxyEmail {
|
||||||
webAuthEmail := ctx.Req.Header.Get(setting.ReverseProxyAuthEmail)
|
webAuthEmail := ctx.Req.Header.Get(setting.ReverseProxyAuthEmail)
|
||||||
if len(webAuthEmail) > 0 {
|
if len(webAuthEmail) > 0 {
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ func isAPIPath(ctx *macaron.Context) bool {
|
|||||||
return strings.HasPrefix(ctx.Req.URL.Path, "/api/")
|
return strings.HasPrefix(ctx.Req.URL.Path, "/api/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isInternalPath returns true if the specified URL is an internal API path
|
||||||
|
func isInternalPath(ctx *macaron.Context) bool {
|
||||||
|
return strings.HasPrefix(ctx.Req.URL.Path, "/api/internal/")
|
||||||
|
}
|
||||||
|
|
||||||
// isAttachmentDownload check if request is a file download (GET) with URL to an attachment
|
// isAttachmentDownload check if request is a file download (GET) with URL to an attachment
|
||||||
func isAttachmentDownload(ctx *macaron.Context) bool {
|
func isAttachmentDownload(ctx *macaron.Context) bool {
|
||||||
return strings.HasPrefix(ctx.Req.URL.Path, "/attachments/") && ctx.Req.Method == "GET"
|
return strings.HasPrefix(ctx.Req.URL.Path, "/attachments/") && ctx.Req.Method == "GET"
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import (
|
|||||||
"gitea.com/macaron/macaron"
|
"gitea.com/macaron/macaron"
|
||||||
"gitea.com/macaron/session"
|
"gitea.com/macaron/session"
|
||||||
|
|
||||||
|
gouuid "github.com/google/uuid"
|
||||||
"github.com/quasoft/websspi"
|
"github.com/quasoft/websspi"
|
||||||
gouuid "github.com/satori/go.uuid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -148,6 +148,8 @@ func (s *SSPI) shouldAuthenticate(ctx *macaron.Context) (shouldAuth bool) {
|
|||||||
} else if ctx.Req.FormValue("auth_with_sspi") == "1" {
|
} else if ctx.Req.FormValue("auth_with_sspi") == "1" {
|
||||||
shouldAuth = true
|
shouldAuth = true
|
||||||
}
|
}
|
||||||
|
} else if isInternalPath(ctx) {
|
||||||
|
shouldAuth = false
|
||||||
} else if isAPIPath(ctx) || isAttachmentDownload(ctx) {
|
} else if isAPIPath(ctx) || isAttachmentDownload(ctx) {
|
||||||
shouldAuth = true
|
shouldAuth = true
|
||||||
}
|
}
|
||||||
@@ -157,12 +159,12 @@ func (s *SSPI) shouldAuthenticate(ctx *macaron.Context) (shouldAuth bool) {
|
|||||||
// newUser creates a new user object for the purpose of automatic registration
|
// newUser creates a new user object for the purpose of automatic registration
|
||||||
// and populates its name and email with the information present in request headers.
|
// and populates its name and email with the information present in request headers.
|
||||||
func (s *SSPI) newUser(ctx *macaron.Context, username string, cfg *models.SSPIConfig) (*models.User, error) {
|
func (s *SSPI) newUser(ctx *macaron.Context, username string, cfg *models.SSPIConfig) (*models.User, error) {
|
||||||
email := gouuid.NewV4().String() + "@localhost.localdomain"
|
email := gouuid.New().String() + "@localhost.localdomain"
|
||||||
user := &models.User{
|
user := &models.User{
|
||||||
Name: username,
|
Name: username,
|
||||||
Email: email,
|
Email: email,
|
||||||
KeepEmailPrivate: true,
|
KeepEmailPrivate: true,
|
||||||
Passwd: gouuid.NewV4().String(),
|
Passwd: gouuid.New().String(),
|
||||||
IsActive: cfg.AutoActivateUsers,
|
IsActive: cfg.AutoActivateUsers,
|
||||||
Language: cfg.DefaultLanguage,
|
Language: cfg.DefaultLanguage,
|
||||||
UseCustomAvatar: true,
|
UseCustomAvatar: true,
|
||||||
|
|||||||
10
modules/cache/last_commit.go
vendored
10
modules/cache/last_commit.go
vendored
@@ -5,6 +5,7 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
@@ -34,9 +35,14 @@ func NewLastCommitCache(repoPath string, gitRepo *git.Repository, ttl int64) *La
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c LastCommitCache) getCacheKey(repoPath, ref, entryPath string) string {
|
||||||
|
hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%s:%s", repoPath, ref, entryPath)))
|
||||||
|
return fmt.Sprintf("last_commit:%x", hashBytes)
|
||||||
|
}
|
||||||
|
|
||||||
// Get get the last commit information by commit id and entry path
|
// Get get the last commit information by commit id and entry path
|
||||||
func (c LastCommitCache) Get(ref, entryPath string) (*object.Commit, error) {
|
func (c LastCommitCache) Get(ref, entryPath string) (*object.Commit, error) {
|
||||||
v := c.Cache.Get(fmt.Sprintf("last_commit:%s:%s:%s", c.repoPath, ref, entryPath))
|
v := c.Cache.Get(c.getCacheKey(c.repoPath, ref, entryPath))
|
||||||
if vs, ok := v.(string); ok {
|
if vs, ok := v.(string); ok {
|
||||||
log.Trace("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, vs)
|
log.Trace("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, vs)
|
||||||
if commit, ok := c.commitCache[vs]; ok {
|
if commit, ok := c.commitCache[vs]; ok {
|
||||||
@@ -60,5 +66,5 @@ func (c LastCommitCache) Get(ref, entryPath string) (*object.Commit, error) {
|
|||||||
// Put put the last commit id with commit and entry path
|
// Put put the last commit id with commit and entry path
|
||||||
func (c LastCommitCache) Put(ref, entryPath, commitID string) error {
|
func (c LastCommitCache) Put(ref, entryPath, commitID string) error {
|
||||||
log.Trace("LastCommitCache save: [%s:%s:%s]", ref, entryPath, commitID)
|
log.Trace("LastCommitCache save: [%s:%s:%s]", ref, entryPath, commitID)
|
||||||
return c.Cache.Put(fmt.Sprintf("last_commit:%s:%s:%s", c.repoPath, ref, entryPath), commitID, c.ttl)
|
return c.Cache.Put(c.getCacheKey(c.repoPath, ref, entryPath), commitID, c.ttl)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,8 +67,12 @@ func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.
|
|||||||
}
|
}
|
||||||
|
|
||||||
if user != nil {
|
if user != nil {
|
||||||
|
permission, err := models.GetUserRepoPermission(repo, user)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
branch.UserCanPush = bp.CanUserPush(user.ID)
|
branch.UserCanPush = bp.CanUserPush(user.ID)
|
||||||
branch.UserCanMerge = bp.IsUserMergeWhitelisted(user.ID)
|
branch.UserCanMerge = bp.IsUserMergeWhitelisted(user.ID, permission)
|
||||||
}
|
}
|
||||||
|
|
||||||
return branch, nil
|
return branch, nil
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
// ToCorrectPageSize makes sure page size is in allowed range.
|
// ToCorrectPageSize makes sure page size is in allowed range.
|
||||||
func ToCorrectPageSize(size int) int {
|
func ToCorrectPageSize(size int) int {
|
||||||
if size <= 0 {
|
if size <= 0 {
|
||||||
size = 10
|
size = setting.API.DefaultPagingNum
|
||||||
} else if size > setting.API.MaxResponseItems {
|
} else if size > setting.API.MaxResponseItems {
|
||||||
size = setting.API.MaxResponseItems
|
size = setting.API.MaxResponseItems
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ func ReplaceAliases(s string) string {
|
|||||||
// FindEmojiSubmatchIndex returns index pair of longest emoji in a string
|
// FindEmojiSubmatchIndex returns index pair of longest emoji in a string
|
||||||
func FindEmojiSubmatchIndex(s string) []int {
|
func FindEmojiSubmatchIndex(s string) []int {
|
||||||
loadMap()
|
loadMap()
|
||||||
|
found := make(map[int]int)
|
||||||
|
keys := make([]int, 0)
|
||||||
|
|
||||||
//see if there are any emoji in string before looking for position of specific ones
|
//see if there are any emoji in string before looking for position of specific ones
|
||||||
//no performance difference when there is a match but 10x faster when there are not
|
//no performance difference when there is a match but 10x faster when there are not
|
||||||
@@ -137,11 +139,26 @@ func FindEmojiSubmatchIndex(s string) []int {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get index of first emoji occurrence while also checking for longest combination
|
||||||
for j := range GemojiData {
|
for j := range GemojiData {
|
||||||
i := strings.Index(s, GemojiData[j].Emoji)
|
i := strings.Index(s, GemojiData[j].Emoji)
|
||||||
if i != -1 {
|
if i != -1 {
|
||||||
return []int{i, i + len(GemojiData[j].Emoji)}
|
if _, ok := found[i]; !ok {
|
||||||
|
if len(keys) == 0 || i < keys[0] {
|
||||||
|
found[i] = j
|
||||||
|
keys = []int{i}
|
||||||
|
}
|
||||||
|
if i == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(keys) > 0 {
|
||||||
|
index := keys[0]
|
||||||
|
return []int{index, index + len(GemojiData[found[index]].Emoji)}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import (
|
|||||||
|
|
||||||
// Init starts this eventsource
|
// Init starts this eventsource
|
||||||
func (m *Manager) Init() {
|
func (m *Manager) Init() {
|
||||||
|
if setting.UI.Notification.EventSourceUpdateTime <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
go graceful.GetManager().RunWithShutdownContext(m.Run)
|
go graceful.GetManager().RunWithShutdownContext(m.Run)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,9 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
|
|||||||
// Close BlameReader - don't run NextPart after invoking that
|
// Close BlameReader - don't run NextPart after invoking that
|
||||||
func (r *BlameReader) Close() error {
|
func (r *BlameReader) Close() error {
|
||||||
defer process.GetManager().Remove(r.pid)
|
defer process.GetManager().Remove(r.pid)
|
||||||
defer r.cancel()
|
r.cancel()
|
||||||
|
|
||||||
|
_ = r.output.Close()
|
||||||
|
|
||||||
if err := r.cmd.Wait(); err != nil {
|
if err := r.cmd.Wait(); err != nil {
|
||||||
return fmt.Errorf("Wait: %v", err)
|
return fmt.Errorf("Wait: %v", err)
|
||||||
@@ -89,19 +91,19 @@ func (r *BlameReader) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateBlameReader creates reader for given repository, commit and file
|
// CreateBlameReader creates reader for given repository, commit and file
|
||||||
func CreateBlameReader(repoPath, commitID, file string) (*BlameReader, error) {
|
func CreateBlameReader(ctx context.Context, repoPath, commitID, file string) (*BlameReader, error) {
|
||||||
gitRepo, err := OpenRepository(repoPath)
|
gitRepo, err := OpenRepository(repoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
gitRepo.Close()
|
gitRepo.Close()
|
||||||
|
|
||||||
return createBlameReader(repoPath, GitExecutable, "blame", commitID, "--porcelain", "--", file)
|
return createBlameReader(ctx, repoPath, GitExecutable, "blame", commitID, "--porcelain", "--", file)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBlameReader(dir string, command ...string) (*BlameReader, error) {
|
func createBlameReader(ctx context.Context, dir string, command ...string) (*BlameReader, error) {
|
||||||
// FIXME: graceful: This should have a timeout
|
// Here we use the provided context - this should be tied to the request performing the blame so that it does not hang around.
|
||||||
ctx, cancel := context.WithCancel(DefaultContext)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
cmd := exec.CommandContext(ctx, command[0], command[1:]...)
|
cmd := exec.CommandContext(ctx, command[0], command[1:]...)
|
||||||
cmd.Dir = dir
|
cmd.Dir = dir
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -93,8 +94,10 @@ func TestReadingBlameOutput(t *testing.T) {
|
|||||||
if _, err = tempFile.WriteString(exampleBlame); err != nil {
|
if _, err = tempFile.WriteString(exampleBlame); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
blameReader, err := createBlameReader("", "cat", tempFile.Name())
|
blameReader, err := createBlameReader(ctx, "", "cat", tempFile.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -271,11 +271,12 @@ func AllCommitsCount(repoPath string) (int64, error) {
|
|||||||
return strconv.ParseInt(strings.TrimSpace(stdout), 10, 64)
|
return strconv.ParseInt(strings.TrimSpace(stdout), 10, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func commitsCount(repoPath, revision, relpath string) (int64, error) {
|
func commitsCount(repoPath string, revision, relpath []string) (int64, error) {
|
||||||
cmd := NewCommand("rev-list", "--count")
|
cmd := NewCommand("rev-list", "--count")
|
||||||
cmd.AddArguments(revision)
|
cmd.AddArguments(revision...)
|
||||||
if len(relpath) > 0 {
|
if len(relpath) > 0 {
|
||||||
cmd.AddArguments("--", relpath)
|
cmd.AddArguments("--")
|
||||||
|
cmd.AddArguments(relpath...)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, err := cmd.RunInDir(repoPath)
|
stdout, err := cmd.RunInDir(repoPath)
|
||||||
@@ -288,7 +289,7 @@ func commitsCount(repoPath, revision, relpath string) (int64, error) {
|
|||||||
|
|
||||||
// CommitsCount returns number of total commits of until given revision.
|
// CommitsCount returns number of total commits of until given revision.
|
||||||
func CommitsCount(repoPath, revision string) (int64, error) {
|
func CommitsCount(repoPath, revision string) (int64, error) {
|
||||||
return commitsCount(repoPath, revision, "")
|
return commitsCount(repoPath, []string{revision}, []string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitsCount returns number of total commits of until current revision.
|
// CommitsCount returns number of total commits of until current revision.
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func (repo *Repository) GetBranchCommitID(name string) (string, error) {
|
|||||||
|
|
||||||
// GetTagCommitID returns last commit ID string of given tag.
|
// GetTagCommitID returns last commit ID string of given tag.
|
||||||
func (repo *Repository) GetTagCommitID(name string) (string, error) {
|
func (repo *Repository) GetTagCommitID(name string) (string, error) {
|
||||||
stdout, err := NewCommand("rev-list", "-n", "1", name).RunInDir(repo.Path)
|
stdout, err := NewCommand("rev-list", "-n", "1", TagPrefix+name).RunInDir(repo.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "unknown revision or path") {
|
if strings.Contains(err.Error(), "unknown revision or path") {
|
||||||
return "", ErrNotExist{name, ""}
|
return "", ErrNotExist{name, ""}
|
||||||
@@ -293,7 +293,7 @@ func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bo
|
|||||||
|
|
||||||
// FileCommitsCount return the number of files at a revison
|
// FileCommitsCount return the number of files at a revison
|
||||||
func (repo *Repository) FileCommitsCount(revision, file string) (int64, error) {
|
func (repo *Repository) FileCommitsCount(revision, file string) (int64, error) {
|
||||||
return commitsCount(repo.Path, revision, file)
|
return commitsCount(repo.Path, []string{revision}, []string{file})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitsByFileAndRange return the commits according revison file and the page
|
// CommitsByFileAndRange return the commits according revison file and the page
|
||||||
@@ -319,6 +319,11 @@ func (repo *Repository) CommitsByFileAndRangeNoFollow(revision, file string, pag
|
|||||||
// FilesCountBetween return the number of files changed between two commits
|
// FilesCountBetween return the number of files changed between two commits
|
||||||
func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) {
|
func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) {
|
||||||
stdout, err := NewCommand("diff", "--name-only", startCommitID+"..."+endCommitID).RunInDir(repo.Path)
|
stdout, err := NewCommand("diff", "--name-only", startCommitID+"..."+endCommitID).RunInDir(repo.Path)
|
||||||
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
|
// git >= 2.28 now returns an error if startCommitID and endCommitID have become unrelated.
|
||||||
|
// previously it would return the results of git diff --name-only startCommitID endCommitID so let's try that...
|
||||||
|
stdout, err = NewCommand("diff", "--name-only", startCommitID, endCommitID).RunInDir(repo.Path)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -333,6 +338,11 @@ func (repo *Repository) CommitsBetween(last *Commit, before *Commit) (*list.List
|
|||||||
stdout, err = NewCommand("rev-list", last.ID.String()).RunInDirBytes(repo.Path)
|
stdout, err = NewCommand("rev-list", last.ID.String()).RunInDirBytes(repo.Path)
|
||||||
} else {
|
} else {
|
||||||
stdout, err = NewCommand("rev-list", before.ID.String()+"..."+last.ID.String()).RunInDirBytes(repo.Path)
|
stdout, err = NewCommand("rev-list", before.ID.String()+"..."+last.ID.String()).RunInDirBytes(repo.Path)
|
||||||
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
|
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
||||||
|
// previously it would return the results of git rev-list before last so let's try that...
|
||||||
|
stdout, err = NewCommand("rev-list", before.ID.String(), last.ID.String()).RunInDirBytes(repo.Path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -348,6 +358,11 @@ func (repo *Repository) CommitsBetweenLimit(last *Commit, before *Commit, limit,
|
|||||||
stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), last.ID.String()).RunInDirBytes(repo.Path)
|
stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), last.ID.String()).RunInDirBytes(repo.Path)
|
||||||
} else {
|
} else {
|
||||||
stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), before.ID.String()+"..."+last.ID.String()).RunInDirBytes(repo.Path)
|
stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), before.ID.String()+"..."+last.ID.String()).RunInDirBytes(repo.Path)
|
||||||
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
|
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
||||||
|
// previously it would return the results of git rev-list --max-count n before last so let's try that...
|
||||||
|
stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), before.ID.String(), last.ID.String()).RunInDirBytes(repo.Path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -373,7 +388,14 @@ func (repo *Repository) CommitsBetweenIDs(last, before string) (*list.List, erro
|
|||||||
|
|
||||||
// CommitsCountBetween return numbers of commits between two commits
|
// CommitsCountBetween return numbers of commits between two commits
|
||||||
func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) {
|
func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) {
|
||||||
return commitsCount(repo.Path, start+"..."+end, "")
|
count, err := commitsCount(repo.Path, []string{start + "..." + end}, []string{})
|
||||||
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
|
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
||||||
|
// previously it would return the results of git rev-list before last so let's try that...
|
||||||
|
return commitsCount(repo.Path, []string{start, end}, []string{})
|
||||||
|
}
|
||||||
|
|
||||||
|
return count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// commitsBefore the limit is depth, not total number of returned commits.
|
// commitsBefore the limit is depth, not total number of returned commits.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -66,7 +67,7 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string)
|
|||||||
compareInfo := new(CompareInfo)
|
compareInfo := new(CompareInfo)
|
||||||
compareInfo.MergeBase, remoteBranch, err = repo.GetMergeBase(tmpRemote, baseBranch, headBranch)
|
compareInfo.MergeBase, remoteBranch, err = repo.GetMergeBase(tmpRemote, baseBranch, headBranch)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// We have a common base
|
// We have a common base - therefore we know that ... should work
|
||||||
logs, err := NewCommand("log", compareInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path)
|
logs, err := NewCommand("log", compareInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -85,6 +86,11 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string)
|
|||||||
|
|
||||||
// Count number of changed files.
|
// Count number of changed files.
|
||||||
stdout, err := NewCommand("diff", "--name-only", remoteBranch+"..."+headBranch).RunInDir(repo.Path)
|
stdout, err := NewCommand("diff", "--name-only", remoteBranch+"..."+headBranch).RunInDir(repo.Path)
|
||||||
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
|
// git >= 2.28 now returns an error if base and head have become unrelated.
|
||||||
|
// previously it would return the results of git diff --name-only base head so let's try that...
|
||||||
|
stdout, err = NewCommand("diff", "--name-only", remoteBranch, headBranch).RunInDir(repo.Path)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -108,12 +114,24 @@ func (repo *Repository) GetDiff(base, head string, w io.Writer) error {
|
|||||||
|
|
||||||
// GetPatch generates and returns format-patch data between given revisions.
|
// GetPatch generates and returns format-patch data between given revisions.
|
||||||
func (repo *Repository) GetPatch(base, head string, w io.Writer) error {
|
func (repo *Repository) GetPatch(base, head string, w io.Writer) error {
|
||||||
return NewCommand("format-patch", "--binary", "--stdout", base+"..."+head).
|
stderr := new(bytes.Buffer)
|
||||||
RunInDirPipeline(repo.Path, w, nil)
|
err := NewCommand("format-patch", "--binary", "--stdout", base+"..."+head).
|
||||||
|
RunInDirPipeline(repo.Path, w, stderr)
|
||||||
|
if err != nil && bytes.Contains(stderr.Bytes(), []byte("no merge base")) {
|
||||||
|
return NewCommand("format-patch", "--binary", "--stdout", base, head).
|
||||||
|
RunInDirPipeline(repo.Path, w, nil)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDiffFromMergeBase generates and return patch data from merge base to head
|
// GetDiffFromMergeBase generates and return patch data from merge base to head
|
||||||
func (repo *Repository) GetDiffFromMergeBase(base, head string, w io.Writer) error {
|
func (repo *Repository) GetDiffFromMergeBase(base, head string, w io.Writer) error {
|
||||||
return NewCommand("diff", "-p", "--binary", base+"..."+head).
|
stderr := new(bytes.Buffer)
|
||||||
RunInDirPipeline(repo.Path, w, nil)
|
err := NewCommand("diff", "-p", "--binary", base+"..."+head).
|
||||||
|
RunInDirPipeline(repo.Path, w, stderr)
|
||||||
|
if err != nil && bytes.Contains(stderr.Bytes(), []byte("no merge base")) {
|
||||||
|
return NewCommand("diff", "-p", "--binary", base, head).
|
||||||
|
RunInDirPipeline(repo.Path, w, nil)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ import (
|
|||||||
"github.com/go-git/go-git/v5/plumbing/object"
|
"github.com/go-git/go-git/v5/plumbing/object"
|
||||||
)
|
)
|
||||||
|
|
||||||
const fileSizeLimit int64 = 16 * 1024 * 1024
|
const fileSizeLimit int64 = 16 * 1024 // 16 KiB
|
||||||
|
const bigFileSize int64 = 1024 * 1024 // 1 MiB
|
||||||
|
|
||||||
// specialLanguages defines list of languages that are excluded from the calculation
|
// specialLanguages defines list of languages that are excluded from the calculation
|
||||||
// unless they are the only language present in repository. Only languages which under
|
// unless they are the only language present in repository. Only languages which under
|
||||||
@@ -62,8 +63,11 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If content can not be read just do detection by filename
|
// If content can not be read or file is too big just do detection by filename
|
||||||
content, _ := readFile(f, fileSizeLimit)
|
var content []byte
|
||||||
|
if f.Size <= bigFileSize {
|
||||||
|
content, _ = readFile(f, fileSizeLimit)
|
||||||
|
}
|
||||||
if enry.IsGenerated(f.Name, content) {
|
if enry.IsGenerated(f.Name, content) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ func getRefURL(refURL, urlPrefix, repoFullName string) string {
|
|||||||
|
|
||||||
for _, scheme := range supportedSchemes {
|
for _, scheme := range supportedSchemes {
|
||||||
if ref.Scheme == scheme {
|
if ref.Scheme == scheme {
|
||||||
if urlPrefixHostname == refHostname {
|
if ref.Scheme == "http" || ref.Scheme == "https" {
|
||||||
return urlPrefix + path.Clean(path.Join("/", ref.Path))
|
|
||||||
} else if ref.Scheme == "http" || ref.Scheme == "https" {
|
|
||||||
if len(ref.User.Username()) > 0 {
|
if len(ref.User.Username()) > 0 {
|
||||||
return ref.Scheme + "://" + fmt.Sprintf("%v", ref.User) + "@" + ref.Host + ref.Path
|
return ref.Scheme + "://" + fmt.Sprintf("%v", ref.User) + "@" + ref.Host + ref.Path
|
||||||
}
|
}
|
||||||
return ref.Scheme + "://" + ref.Host + ref.Path
|
return ref.Scheme + "://" + ref.Host + ref.Path
|
||||||
|
} else if urlPrefixHostname == refHostname {
|
||||||
|
return urlPrefix + path.Clean(path.Join("/", ref.Path))
|
||||||
} else {
|
} else {
|
||||||
return "http://" + refHostname + ref.Path
|
return "http://" + refHostname + ref.Path
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ func TestGetRefURL(t *testing.T) {
|
|||||||
{"git://git@try.gitea.io:9999/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "https://try.gitea.io/go-gitea/gitea"},
|
{"git://git@try.gitea.io:9999/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "https://try.gitea.io/go-gitea/gitea"},
|
||||||
{"ssh://git@127.0.0.1:9999/go-gitea/gitea", "https://127.0.0.1:3000/", "go-gitea/sdk", "https://127.0.0.1:3000/go-gitea/gitea"},
|
{"ssh://git@127.0.0.1:9999/go-gitea/gitea", "https://127.0.0.1:3000/", "go-gitea/sdk", "https://127.0.0.1:3000/go-gitea/gitea"},
|
||||||
{"https://gitea.com:3000/user1/repo1.git", "https://127.0.0.1:3000/", "user/repo2", "https://gitea.com:3000/user1/repo1"},
|
{"https://gitea.com:3000/user1/repo1.git", "https://127.0.0.1:3000/", "user/repo2", "https://gitea.com:3000/user1/repo1"},
|
||||||
|
{"https://example.gitea.com/gitea/user1/repo1.git", "https://example.gitea.com/gitea/", "user/repo2", "https://example.gitea.com/gitea/user1/repo1"},
|
||||||
{"https://username:password@github.com/username/repository.git", "/", "username/repository2", "https://username:password@github.com/username/repository"},
|
{"https://username:password@github.com/username/repository.git", "/", "username/repository2", "https://username:password@github.com/username/repository"},
|
||||||
{"somethingbad", "https://127.0.0.1:3000/go-gitea/gitea", "/", ""},
|
{"somethingbad", "https://127.0.0.1:3000/go-gitea/gitea", "/", ""},
|
||||||
{"git@localhost:user/repo", "https://localhost/", "user2/repo1", "https://localhost/user/repo"},
|
{"git@localhost:user/repo", "https://localhost/", "user2/repo1", "https://localhost/user/repo"},
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ func InitIssueIndexer(syncReindex bool) {
|
|||||||
log.Debug("Created Bleve Indexer")
|
log.Debug("Created Bleve Indexer")
|
||||||
case "elasticsearch":
|
case "elasticsearch":
|
||||||
graceful.GetManager().RunWithShutdownFns(func(_, atTerminate func(context.Context, func())) {
|
graceful.GetManager().RunWithShutdownFns(func(_, atTerminate func(context.Context, func())) {
|
||||||
issueIndexer, err := NewElasticSearchIndexer(setting.Indexer.IssueConnStr, "gitea_issues")
|
issueIndexer, err := NewElasticSearchIndexer(setting.Indexer.IssueConnStr, setting.Indexer.IssueIndexerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Unable to initialize Elastic Search Issue Indexer at connection: %s Error: %v", setting.Indexer.IssueConnStr, err)
|
log.Fatal("Unable to initialize Elastic Search Issue Indexer at connection: %s Error: %v", setting.Indexer.IssueConnStr, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func handle(data ...queue.Data) {
|
|||||||
for _, datum := range data {
|
for _, datum := range data {
|
||||||
opts := datum.(int64)
|
opts := datum.(int64)
|
||||||
if err := indexer.Index(opts); err != nil {
|
if err := indexer.Index(opts); err != nil {
|
||||||
log.Error("stats queue idexer.Index(%d) failed: %v", opts, err)
|
log.Error("stats queue indexer.Index(%d) failed: %v", opts, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,5 +39,11 @@ func initStatsQueue() error {
|
|||||||
|
|
||||||
// UpdateRepoIndexer update a repository's entries in the indexer
|
// UpdateRepoIndexer update a repository's entries in the indexer
|
||||||
func UpdateRepoIndexer(repo *models.Repository) error {
|
func UpdateRepoIndexer(repo *models.Repository) error {
|
||||||
return statsQueue.Push(repo.ID)
|
if err := statsQueue.Push(repo.ID); err != nil {
|
||||||
|
if err != queue.ErrAlreadyInQueue {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debug("Repo ID: %d already queued", repo.ID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ func NewColoredValueBytes(value interface{}, colorBytes *[]byte) *ColoredValue {
|
|||||||
// The Value will be colored with FgCyan
|
// The Value will be colored with FgCyan
|
||||||
// If a ColoredValue is provided it is not changed
|
// If a ColoredValue is provided it is not changed
|
||||||
func NewColoredIDValue(value interface{}) *ColoredValue {
|
func NewColoredIDValue(value interface{}) *ColoredValue {
|
||||||
return NewColoredValueBytes(&value, &fgCyanBytes)
|
return NewColoredValueBytes(value, &fgCyanBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format will format the provided value and protect against ANSI color spoofing within the value
|
// Format will format the provided value and protect against ANSI color spoofing within the value
|
||||||
|
|||||||
@@ -266,6 +266,10 @@ func TestRender_emoji(t *testing.T) {
|
|||||||
test(
|
test(
|
||||||
"Some text with 😄😄 2 emoji next to each other",
|
"Some text with 😄😄 2 emoji next to each other",
|
||||||
`<p>Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span><span class="emoji" aria-label="grinning face with smiling eyes">😄</span> 2 emoji next to each other</p>`)
|
`<p>Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span><span class="emoji" aria-label="grinning face with smiling eyes">😄</span> 2 emoji next to each other</p>`)
|
||||||
|
test(
|
||||||
|
"😎🤪🔐🤑❓",
|
||||||
|
`<p><span class="emoji" aria-label="smiling face with sunglasses">😎</span><span class="emoji" aria-label="zany face">🤪</span><span class="emoji" aria-label="locked with key">🔐</span><span class="emoji" aria-label="money-mouth face">🤑</span><span class="emoji" aria-label="question mark">❓</span></p>`)
|
||||||
|
|
||||||
// should match nothing
|
// should match nothing
|
||||||
test(
|
test(
|
||||||
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ package migrations
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/google/go-github/v24/github"
|
"github.com/google/go-github/v32/github"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/structs"
|
"code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
gouuid "github.com/satori/go.uuid"
|
gouuid "github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -260,7 +260,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
|
|||||||
|
|
||||||
for _, asset := range release.Assets {
|
for _, asset := range release.Assets {
|
||||||
var attach = models.Attachment{
|
var attach = models.Attachment{
|
||||||
UUID: gouuid.NewV4().String(),
|
UUID: gouuid.New().String(),
|
||||||
Name: asset.Name,
|
Name: asset.Name,
|
||||||
DownloadCount: int64(*asset.DownloadCount),
|
DownloadCount: int64(*asset.DownloadCount),
|
||||||
Size: int64(*asset.Size),
|
Size: int64(*asset.Size),
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/structs"
|
"code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/google/go-github/v24/github"
|
"github.com/google/go-github/v32/github"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool,
|
|||||||
}
|
}
|
||||||
var labels = make([]*base.Label, 0, len(issue.Labels))
|
var labels = make([]*base.Label, 0, len(issue.Labels))
|
||||||
for _, l := range issue.Labels {
|
for _, l := range issue.Labels {
|
||||||
labels = append(labels, convertGithubLabel(&l))
|
labels = append(labels, convertGithubLabel(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
var email string
|
var email string
|
||||||
@@ -425,8 +425,8 @@ func (g *GithubDownloaderV3) GetComments(issueNumber int64) ([]*base.Comment, er
|
|||||||
asc = "asc"
|
asc = "asc"
|
||||||
)
|
)
|
||||||
opt := &github.IssueListCommentsOptions{
|
opt := &github.IssueListCommentsOptions{
|
||||||
Sort: created,
|
Sort: &created,
|
||||||
Direction: asc,
|
Direction: &asc,
|
||||||
ListOptions: github.ListOptions{
|
ListOptions: github.ListOptions{
|
||||||
PerPage: 100,
|
PerPage: 100,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func NewGitlabDownloader(baseURL, repoPath, username, password string) *GitlabDo
|
|||||||
var err error
|
var err error
|
||||||
if username != "" {
|
if username != "" {
|
||||||
if password == "" {
|
if password == "" {
|
||||||
gitlabClient, err = gitlab.NewClient(username)
|
gitlabClient, err = gitlab.NewClient(username, gitlab.WithBaseURL(baseURL))
|
||||||
} else {
|
} else {
|
||||||
gitlabClient, err = gitlab.NewBasicAuthClient(username, password, gitlab.WithBaseURL(baseURL))
|
gitlabClient, err = gitlab.NewBasicAuthClient(username, password, gitlab.WithBaseURL(baseURL))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,13 @@ type Options struct {
|
|||||||
Prefix string
|
Prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
// List of known entries inside the `public` directory
|
// KnownPublicEntries list all direct children in the `public` directory
|
||||||
var knownEntries = []string{
|
var KnownPublicEntries = []string{
|
||||||
"css",
|
"css",
|
||||||
"fomantic",
|
"fomantic",
|
||||||
"img",
|
"img",
|
||||||
"js",
|
"js",
|
||||||
|
"serviceworker.js",
|
||||||
"vendor",
|
"vendor",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +115,7 @@ func (opts *Options) handle(ctx *macaron.Context, log *log.Logger, opt *Options)
|
|||||||
if len(parts) < 2 {
|
if len(parts) < 2 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, entry := range knownEntries {
|
for _, entry := range KnownPublicEntries {
|
||||||
if entry == parts[1] {
|
if entry == parts[1] {
|
||||||
ctx.Resp.WriteHeader(404)
|
ctx.Resp.WriteHeader(404)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ func CreateQueue(name string, handle HandlerFunc, exemplar interface{}) Queue {
|
|||||||
MaxAttempts: q.MaxAttempts,
|
MaxAttempts: q.MaxAttempts,
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
QueueLength: q.Length,
|
QueueLength: q.Length,
|
||||||
|
Name: name,
|
||||||
}, exemplar)
|
}, exemplar)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetBranch returns a branch by its name
|
// GetBranch returns a branch by its name
|
||||||
@@ -74,39 +73,9 @@ func CreateNewBranch(doer *models.User, repo *models.Repository, oldBranchName,
|
|||||||
return fmt.Errorf("OldBranch: %s does not exist. Cannot create new branch from this", oldBranchName)
|
return fmt.Errorf("OldBranch: %s does not exist. Cannot create new branch from this", oldBranchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
basePath, err := models.CreateTemporaryPath("branch-maker")
|
if err := git.Push(repo.RepoPath(), git.PushOptions{
|
||||||
if err != nil {
|
Remote: repo.RepoPath(),
|
||||||
return err
|
Branch: fmt.Sprintf("%s:%s%s", oldBranchName, git.BranchPrefix, branchName),
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := models.RemoveTemporaryPath(basePath); err != nil {
|
|
||||||
log.Error("CreateNewBranch: RemoveTemporaryPath: %s", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err := git.Clone(repo.RepoPath(), basePath, git.CloneRepoOptions{
|
|
||||||
Bare: true,
|
|
||||||
Shared: true,
|
|
||||||
}); err != nil {
|
|
||||||
log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err)
|
|
||||||
return fmt.Errorf("Failed to clone repository: %s (%v)", repo.FullName(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
gitRepo, err := git.OpenRepository(basePath)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
|
||||||
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
|
||||||
}
|
|
||||||
defer gitRepo.Close()
|
|
||||||
|
|
||||||
if err = gitRepo.CreateBranch(branchName, oldBranchName); err != nil {
|
|
||||||
log.Error("Unable to create branch: %s from %s. (%v)", branchName, oldBranchName, err)
|
|
||||||
return fmt.Errorf("Unable to create branch: %s from %s. (%v)", branchName, oldBranchName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = git.Push(basePath, git.PushOptions{
|
|
||||||
Remote: "origin",
|
|
||||||
Branch: branchName,
|
|
||||||
Env: models.PushingEnvironment(doer, repo),
|
Env: models.PushingEnvironment(doer, repo),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
|
if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
|
||||||
@@ -124,39 +93,10 @@ func CreateNewBranchFromCommit(doer *models.User, repo *models.Repository, commi
|
|||||||
if err := checkBranchName(repo, branchName); err != nil {
|
if err := checkBranchName(repo, branchName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
basePath, err := models.CreateTemporaryPath("branch-maker")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := models.RemoveTemporaryPath(basePath); err != nil {
|
|
||||||
log.Error("CreateNewBranchFromCommit: RemoveTemporaryPath: %s", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err := git.Clone(repo.RepoPath(), basePath, git.CloneRepoOptions{
|
if err := git.Push(repo.RepoPath(), git.PushOptions{
|
||||||
Bare: true,
|
Remote: repo.RepoPath(),
|
||||||
Shared: true,
|
Branch: fmt.Sprintf("%s:%s%s", commit, git.BranchPrefix, branchName),
|
||||||
}); err != nil {
|
|
||||||
log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err)
|
|
||||||
return fmt.Errorf("Failed to clone repository: %s (%v)", repo.FullName(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
gitRepo, err := git.OpenRepository(basePath)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
|
||||||
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
|
||||||
}
|
|
||||||
defer gitRepo.Close()
|
|
||||||
|
|
||||||
if err = gitRepo.CreateBranch(branchName, commit); err != nil {
|
|
||||||
log.Error("Unable to create branch: %s from %s. (%v)", branchName, commit, err)
|
|
||||||
return fmt.Errorf("Unable to create branch: %s from %s. (%v)", branchName, commit, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = git.Push(basePath, git.PushOptions{
|
|
||||||
Remote: "origin",
|
|
||||||
Branch: branchName,
|
|
||||||
Env: models.PushingEnvironment(doer, repo),
|
Env: models.PushingEnvironment(doer, repo),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
|
if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"github.com/mcuadros/go-version"
|
"github.com/mcuadros/go-version"
|
||||||
"github.com/unknwon/com"
|
"github.com/unknwon/com"
|
||||||
@@ -147,7 +148,7 @@ func initRepoCommit(tmpPath string, repo *models.Repository, u *models.User, def
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(defaultBranch) == 0 {
|
if len(defaultBranch) == 0 {
|
||||||
defaultBranch = "master"
|
defaultBranch = setting.Repository.DefaultBranch
|
||||||
}
|
}
|
||||||
|
|
||||||
if stdout, err := git.NewCommand("push", "origin", "master:"+defaultBranch).
|
if stdout, err := git.NewCommand("push", "origin", "master:"+defaultBranch).
|
||||||
@@ -213,6 +214,13 @@ func initRepository(ctx models.DBContext, repoPath string, u *models.User, repo
|
|||||||
repo.DefaultBranch = "master"
|
repo.DefaultBranch = "master"
|
||||||
if len(opts.DefaultBranch) > 0 {
|
if len(opts.DefaultBranch) > 0 {
|
||||||
repo.DefaultBranch = opts.DefaultBranch
|
repo.DefaultBranch = opts.DefaultBranch
|
||||||
|
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("openRepository: %v", err)
|
||||||
|
}
|
||||||
|
if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
|
||||||
|
return fmt.Errorf("setDefaultBranch: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
|
if err = models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
|
||||||
|
|||||||
@@ -1,216 +0,0 @@
|
|||||||
// Copyright 2013 Beego Authors
|
|
||||||
// Copyright 2014 The Macaron Authors
|
|
||||||
// Copyright 2019 The Gitea Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
|
||||||
// not use this file except in compliance with the License. You may obtain
|
|
||||||
// a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
// License for the specific language governing permissions and limitations
|
|
||||||
// under the License.
|
|
||||||
|
|
||||||
package session
|
|
||||||
|
|
||||||
import (
|
|
||||||
"container/list"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"gitea.com/macaron/session"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MemStore represents a in-memory session store implementation.
|
|
||||||
type MemStore struct {
|
|
||||||
sid string
|
|
||||||
lock sync.RWMutex
|
|
||||||
data map[interface{}]interface{}
|
|
||||||
lastAccess time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMemStore creates and returns a memory session store.
|
|
||||||
func NewMemStore(sid string) *MemStore {
|
|
||||||
return &MemStore{
|
|
||||||
sid: sid,
|
|
||||||
data: make(map[interface{}]interface{}),
|
|
||||||
lastAccess: time.Now(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets value to given key in session.
|
|
||||||
func (s *MemStore) Set(key, val interface{}) error {
|
|
||||||
s.lock.Lock()
|
|
||||||
defer s.lock.Unlock()
|
|
||||||
|
|
||||||
s.data[key] = val
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get gets value by given key in session.
|
|
||||||
func (s *MemStore) Get(key interface{}) interface{} {
|
|
||||||
s.lock.RLock()
|
|
||||||
defer s.lock.RUnlock()
|
|
||||||
|
|
||||||
return s.data[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete deletes a key from session.
|
|
||||||
func (s *MemStore) Delete(key interface{}) error {
|
|
||||||
s.lock.Lock()
|
|
||||||
defer s.lock.Unlock()
|
|
||||||
|
|
||||||
delete(s.data, key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns current session ID.
|
|
||||||
func (s *MemStore) ID() string {
|
|
||||||
return s.sid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release releases resource and save data to provider.
|
|
||||||
func (*MemStore) Release() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush deletes all session data.
|
|
||||||
func (s *MemStore) Flush() error {
|
|
||||||
s.lock.Lock()
|
|
||||||
defer s.lock.Unlock()
|
|
||||||
|
|
||||||
s.data = make(map[interface{}]interface{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MemProvider represents a in-memory session provider implementation.
|
|
||||||
type MemProvider struct {
|
|
||||||
lock sync.RWMutex
|
|
||||||
maxLifetime int64
|
|
||||||
data map[string]*list.Element
|
|
||||||
// A priority list whose lastAccess newer gets higher priority.
|
|
||||||
list *list.List
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init initializes memory session provider.
|
|
||||||
func (p *MemProvider) Init(maxLifetime int64, _ string) error {
|
|
||||||
p.lock.Lock()
|
|
||||||
p.maxLifetime = maxLifetime
|
|
||||||
p.lock.Unlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// update expands time of session store by given ID.
|
|
||||||
func (p *MemProvider) update(sid string) error {
|
|
||||||
p.lock.Lock()
|
|
||||||
defer p.lock.Unlock()
|
|
||||||
|
|
||||||
if e, ok := p.data[sid]; ok {
|
|
||||||
e.Value.(*MemStore).lastAccess = time.Now()
|
|
||||||
p.list.MoveToFront(e)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read returns raw session store by session ID.
|
|
||||||
func (p *MemProvider) Read(sid string) (_ session.RawStore, err error) {
|
|
||||||
p.lock.RLock()
|
|
||||||
e, ok := p.data[sid]
|
|
||||||
p.lock.RUnlock()
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
if err = p.update(sid); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return e.Value.(*MemStore), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new session.
|
|
||||||
p.lock.Lock()
|
|
||||||
defer p.lock.Unlock()
|
|
||||||
|
|
||||||
s := NewMemStore(sid)
|
|
||||||
p.data[sid] = p.list.PushBack(s)
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exist returns true if session with given ID exists.
|
|
||||||
func (p *MemProvider) Exist(sid string) bool {
|
|
||||||
p.lock.RLock()
|
|
||||||
defer p.lock.RUnlock()
|
|
||||||
|
|
||||||
_, ok := p.data[sid]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy deletes a session by session ID.
|
|
||||||
func (p *MemProvider) Destroy(sid string) error {
|
|
||||||
p.lock.Lock()
|
|
||||||
defer p.lock.Unlock()
|
|
||||||
|
|
||||||
e, ok := p.data[sid]
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
p.list.Remove(e)
|
|
||||||
delete(p.data, sid)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regenerate regenerates a session store from old session ID to new one.
|
|
||||||
func (p *MemProvider) Regenerate(oldsid, sid string) (session.RawStore, error) {
|
|
||||||
if p.Exist(sid) {
|
|
||||||
return nil, fmt.Errorf("new sid '%s' already exists", sid)
|
|
||||||
}
|
|
||||||
|
|
||||||
s, err := p.Read(oldsid)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = p.Destroy(oldsid); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s.(*MemStore).sid = sid
|
|
||||||
|
|
||||||
p.lock.Lock()
|
|
||||||
defer p.lock.Unlock()
|
|
||||||
p.data[sid] = p.list.PushBack(s)
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count counts and returns number of sessions.
|
|
||||||
func (p *MemProvider) Count() int {
|
|
||||||
return p.list.Len()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GC calls GC to clean expired sessions.
|
|
||||||
func (p *MemProvider) GC() {
|
|
||||||
p.lock.RLock()
|
|
||||||
for {
|
|
||||||
// No session in the list.
|
|
||||||
e := p.list.Back()
|
|
||||||
if e == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.Value.(*MemStore).lastAccess.Unix() + p.maxLifetime) < time.Now().Unix() {
|
|
||||||
p.lock.RUnlock()
|
|
||||||
p.lock.Lock()
|
|
||||||
p.list.Remove(e)
|
|
||||||
delete(p.data, e.Value.(*MemStore).sid)
|
|
||||||
p.lock.Unlock()
|
|
||||||
p.lock.RLock()
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.lock.RUnlock()
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
package session
|
package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/list"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -37,7 +36,7 @@ func (o *VirtualSessionProvider) Init(gclifetime int64, config string) error {
|
|||||||
// This is only slightly more wrong than modules/setting/session.go:23
|
// This is only slightly more wrong than modules/setting/session.go:23
|
||||||
switch opts.Provider {
|
switch opts.Provider {
|
||||||
case "memory":
|
case "memory":
|
||||||
o.provider = &MemProvider{list: list.New(), data: make(map[string]*list.Element)}
|
o.provider = &session.MemProvider{}
|
||||||
case "file":
|
case "file":
|
||||||
o.provider = &session.FileProvider{}
|
o.provider = &session.FileProvider{}
|
||||||
case "redis":
|
case "redis":
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ type Cache struct {
|
|||||||
var (
|
var (
|
||||||
// CacheService the global cache
|
// CacheService the global cache
|
||||||
CacheService = struct {
|
CacheService = struct {
|
||||||
Cache
|
Cache `ini:"cache"`
|
||||||
|
|
||||||
LastCommit struct {
|
LastCommit struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ func DBConnStr() (string, error) {
|
|||||||
switch Database.Type {
|
switch Database.Type {
|
||||||
case "mysql":
|
case "mysql":
|
||||||
connType := "tcp"
|
connType := "tcp"
|
||||||
if Database.Host[0] == '/' { // looks like a unix socket
|
if len(Database.Host) > 0 && Database.Host[0] == '/' { // looks like a unix socket
|
||||||
connType = "unix"
|
connType = "unix"
|
||||||
}
|
}
|
||||||
tls := Database.SSLMode
|
tls := Database.SSLMode
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ var (
|
|||||||
DisabledRepoUnits []string
|
DisabledRepoUnits []string
|
||||||
DefaultRepoUnits []string
|
DefaultRepoUnits []string
|
||||||
PrefixArchiveFiles bool
|
PrefixArchiveFiles bool
|
||||||
|
DefaultBranch string
|
||||||
|
|
||||||
// Repository editor settings
|
// Repository editor settings
|
||||||
Editor struct {
|
Editor struct {
|
||||||
@@ -201,6 +202,7 @@ func newRepository() {
|
|||||||
Repository.DisableHTTPGit = sec.Key("DISABLE_HTTP_GIT").MustBool()
|
Repository.DisableHTTPGit = sec.Key("DISABLE_HTTP_GIT").MustBool()
|
||||||
Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool()
|
Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool()
|
||||||
Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1)
|
Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1)
|
||||||
|
Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString("master")
|
||||||
RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gitea-repositories"))
|
RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gitea-repositories"))
|
||||||
forcePathSeparator(RepoRootPath)
|
forcePathSeparator(RepoRootPath)
|
||||||
if !filepath.IsAbs(RepoRootPath) {
|
if !filepath.IsAbs(RepoRootPath) {
|
||||||
|
|||||||
@@ -666,7 +666,10 @@ func NewContext() {
|
|||||||
PortToRedirect = sec.Key("PORT_TO_REDIRECT").MustString("80")
|
PortToRedirect = sec.Key("PORT_TO_REDIRECT").MustString("80")
|
||||||
OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
|
OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
|
||||||
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
|
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
|
||||||
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(AppWorkPath)
|
if len(StaticRootPath) == 0 {
|
||||||
|
StaticRootPath = AppWorkPath
|
||||||
|
}
|
||||||
|
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(StaticRootPath)
|
||||||
StaticCacheTime = sec.Key("STATIC_CACHE_TIME").MustDuration(6 * time.Hour)
|
StaticCacheTime = sec.Key("STATIC_CACHE_TIME").MustDuration(6 * time.Hour)
|
||||||
AppDataPath = sec.Key("APP_DATA_PATH").MustString(path.Join(AppWorkPath, "data"))
|
AppDataPath = sec.Key("APP_DATA_PATH").MustString(path.Join(AppWorkPath, "data"))
|
||||||
EnableGzip = sec.Key("ENABLE_GZIP").MustBool()
|
EnableGzip = sec.Key("ENABLE_GZIP").MustBool()
|
||||||
|
|||||||
@@ -164,9 +164,16 @@ func NewFuncMap() []template.FuncMap {
|
|||||||
mimeType := mime.TypeByExtension(filepath.Ext(filename))
|
mimeType := mime.TypeByExtension(filepath.Ext(filename))
|
||||||
return strings.HasPrefix(mimeType, "image/")
|
return strings.HasPrefix(mimeType, "image/")
|
||||||
},
|
},
|
||||||
"TabSizeClass": func(ec *editorconfig.Editorconfig, filename string) string {
|
"TabSizeClass": func(ec interface{}, filename string) string {
|
||||||
|
var (
|
||||||
|
value *editorconfig.Editorconfig
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
if ec != nil {
|
if ec != nil {
|
||||||
def, err := ec.GetDefinitionForFilename(filename)
|
if value, ok = ec.(*editorconfig.Editorconfig); !ok || value == nil {
|
||||||
|
return "tab-size-8"
|
||||||
|
}
|
||||||
|
def, err := value.GetDefinitionForFilename(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("tab size class: getting definition for filename: %v", err)
|
log.Error("tab size class: getting definition for filename: %v", err)
|
||||||
return "tab-size-8"
|
return "tab-size-8"
|
||||||
@@ -282,8 +289,8 @@ func NewFuncMap() []template.FuncMap {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NotificationSettings": func() map[string]int {
|
"NotificationSettings": func() map[string]interface{} {
|
||||||
return map[string]int{
|
return map[string]interface{}{
|
||||||
"MinTimeout": int(setting.UI.Notification.MinTimeout / time.Millisecond),
|
"MinTimeout": int(setting.UI.Notification.MinTimeout / time.Millisecond),
|
||||||
"TimeoutStep": int(setting.UI.Notification.TimeoutStep / time.Millisecond),
|
"TimeoutStep": int(setting.UI.Notification.TimeoutStep / time.Millisecond),
|
||||||
"MaxTimeout": int(setting.UI.Notification.MaxTimeout / time.Millisecond),
|
"MaxTimeout": int(setting.UI.Notification.MaxTimeout / time.Millisecond),
|
||||||
|
|||||||
@@ -264,7 +264,11 @@ func GetDingtalkPayload(p api.Payloader, event models.HookEventType, meta string
|
|||||||
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
||||||
return getDingtalkIssuesPayload(p.(*api.IssuePayload))
|
return getDingtalkIssuesPayload(p.(*api.IssuePayload))
|
||||||
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
||||||
return getDingtalkIssueCommentPayload(p.(*api.IssueCommentPayload))
|
pl, ok := p.(*api.IssueCommentPayload)
|
||||||
|
if ok {
|
||||||
|
return getDingtalkIssueCommentPayload(pl)
|
||||||
|
}
|
||||||
|
return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload))
|
||||||
case models.HookEventPush:
|
case models.HookEventPush:
|
||||||
return getDingtalkPushPayload(p.(*api.PushPayload))
|
return getDingtalkPushPayload(p.(*api.PushPayload))
|
||||||
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
||||||
|
|||||||
@@ -408,7 +408,11 @@ func GetDiscordPayload(p api.Payloader, event models.HookEventType, meta string)
|
|||||||
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
||||||
return getDiscordIssuesPayload(p.(*api.IssuePayload), discord)
|
return getDiscordIssuesPayload(p.(*api.IssuePayload), discord)
|
||||||
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
||||||
return getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), discord)
|
pl, ok := p.(*api.IssueCommentPayload)
|
||||||
|
if ok {
|
||||||
|
return getDiscordIssueCommentPayload(pl, discord)
|
||||||
|
}
|
||||||
|
return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord)
|
||||||
case models.HookEventPush:
|
case models.HookEventPush:
|
||||||
return getDiscordPushPayload(p.(*api.PushPayload), discord)
|
return getDiscordPushPayload(p.(*api.PushPayload), discord)
|
||||||
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
||||||
|
|||||||
@@ -183,13 +183,17 @@ func GetFeishuPayload(p api.Payloader, event models.HookEventType, meta string)
|
|||||||
return getFeishuForkPayload(p.(*api.ForkPayload))
|
return getFeishuForkPayload(p.(*api.ForkPayload))
|
||||||
case models.HookEventIssues:
|
case models.HookEventIssues:
|
||||||
return getFeishuIssuesPayload(p.(*api.IssuePayload))
|
return getFeishuIssuesPayload(p.(*api.IssuePayload))
|
||||||
case models.HookEventIssueComment:
|
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
||||||
return getFeishuIssueCommentPayload(p.(*api.IssueCommentPayload))
|
pl, ok := p.(*api.IssueCommentPayload)
|
||||||
|
if ok {
|
||||||
|
return getFeishuIssueCommentPayload(pl)
|
||||||
|
}
|
||||||
|
return getFeishuPullRequestPayload(p.(*api.PullRequestPayload))
|
||||||
case models.HookEventPush:
|
case models.HookEventPush:
|
||||||
return getFeishuPushPayload(p.(*api.PushPayload))
|
return getFeishuPushPayload(p.(*api.PushPayload))
|
||||||
case models.HookEventPullRequest:
|
case models.HookEventPullRequest:
|
||||||
return getFeishuPullRequestPayload(p.(*api.PullRequestPayload))
|
return getFeishuPullRequestPayload(p.(*api.PullRequestPayload))
|
||||||
case models.HookEventPullRequestReviewApproved, models.HookEventPullRequestReviewRejected, models.HookEventPullRequestComment:
|
case models.HookEventPullRequestReviewApproved, models.HookEventPullRequestReviewRejected:
|
||||||
return getFeishuPullRequestApprovalPayload(p.(*api.PullRequestPayload), event)
|
return getFeishuPullRequestApprovalPayload(p.(*api.PullRequestPayload), event)
|
||||||
case models.HookEventRepository:
|
case models.HookEventRepository:
|
||||||
return getFeishuRepositoryPayload(p.(*api.RepositoryPayload))
|
return getFeishuRepositoryPayload(p.(*api.RepositoryPayload))
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ func getPullRequestPayloadInfo(p *api.PullRequestPayload, linkFormatter linkForm
|
|||||||
linkFormatter(mileStoneLink, p.PullRequest.Milestone.Title), titleLink)
|
linkFormatter(mileStoneLink, p.PullRequest.Milestone.Title), titleLink)
|
||||||
case api.HookIssueDemilestoned:
|
case api.HookIssueDemilestoned:
|
||||||
text = fmt.Sprintf("[%s] Pull request milestone cleared: %s", repoLink, titleLink)
|
text = fmt.Sprintf("[%s] Pull request milestone cleared: %s", repoLink, titleLink)
|
||||||
|
case api.HookIssueReviewed:
|
||||||
|
text = fmt.Sprintf("[%s] Pull request reviewed: %s", repoLink, titleLink)
|
||||||
}
|
}
|
||||||
if withSender {
|
if withSender {
|
||||||
text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName))
|
text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName))
|
||||||
|
|||||||
@@ -230,7 +230,11 @@ func GetMatrixPayload(p api.Payloader, event models.HookEventType, meta string)
|
|||||||
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
||||||
return getMatrixIssuesPayload(p.(*api.IssuePayload), matrix)
|
return getMatrixIssuesPayload(p.(*api.IssuePayload), matrix)
|
||||||
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
||||||
return getMatrixIssueCommentPayload(p.(*api.IssueCommentPayload), matrix)
|
pl, ok := p.(*api.IssueCommentPayload)
|
||||||
|
if ok {
|
||||||
|
return getMatrixIssueCommentPayload(pl, matrix)
|
||||||
|
}
|
||||||
|
return getMatrixPullRequestPayload(p.(*api.PullRequestPayload), matrix)
|
||||||
case models.HookEventPush:
|
case models.HookEventPush:
|
||||||
return getMatrixPushPayload(p.(*api.PushPayload), matrix)
|
return getMatrixPushPayload(p.(*api.PushPayload), matrix)
|
||||||
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
||||||
|
|||||||
@@ -558,7 +558,11 @@ func GetMSTeamsPayload(p api.Payloader, event models.HookEventType, meta string)
|
|||||||
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
||||||
return getMSTeamsIssuesPayload(p.(*api.IssuePayload))
|
return getMSTeamsIssuesPayload(p.(*api.IssuePayload))
|
||||||
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
||||||
return getMSTeamsIssueCommentPayload(p.(*api.IssueCommentPayload))
|
pl, ok := p.(*api.IssueCommentPayload)
|
||||||
|
if ok {
|
||||||
|
return getMSTeamsIssueCommentPayload(pl)
|
||||||
|
}
|
||||||
|
return getMSTeamsPullRequestPayload(p.(*api.PullRequestPayload))
|
||||||
case models.HookEventPush:
|
case models.HookEventPush:
|
||||||
return getMSTeamsPushPayload(p.(*api.PushPayload))
|
return getMSTeamsPushPayload(p.(*api.PushPayload))
|
||||||
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
||||||
|
|||||||
@@ -321,7 +321,11 @@ func GetSlackPayload(p api.Payloader, event models.HookEventType, meta string) (
|
|||||||
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
||||||
return getSlackIssuesPayload(p.(*api.IssuePayload), slack)
|
return getSlackIssuesPayload(p.(*api.IssuePayload), slack)
|
||||||
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
||||||
return getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack)
|
pl, ok := p.(*api.IssueCommentPayload)
|
||||||
|
if ok {
|
||||||
|
return getSlackIssueCommentPayload(pl, slack)
|
||||||
|
}
|
||||||
|
return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
|
||||||
case models.HookEventPush:
|
case models.HookEventPush:
|
||||||
return getSlackPushPayload(p.(*api.PushPayload), slack)
|
return getSlackPushPayload(p.(*api.PushPayload), slack)
|
||||||
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
||||||
|
|||||||
@@ -206,7 +206,11 @@ func GetTelegramPayload(p api.Payloader, event models.HookEventType, meta string
|
|||||||
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
|
||||||
return getTelegramIssuesPayload(p.(*api.IssuePayload))
|
return getTelegramIssuesPayload(p.(*api.IssuePayload))
|
||||||
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
case models.HookEventIssueComment, models.HookEventPullRequestComment:
|
||||||
return getTelegramIssueCommentPayload(p.(*api.IssueCommentPayload))
|
pl, ok := p.(*api.IssueCommentPayload)
|
||||||
|
if ok {
|
||||||
|
return getTelegramIssueCommentPayload(pl)
|
||||||
|
}
|
||||||
|
return getTelegramPullRequestPayload(p.(*api.PullRequestPayload))
|
||||||
case models.HookEventPush:
|
case models.HookEventPush:
|
||||||
return getTelegramPushPayload(p.(*api.PushPayload))
|
return getTelegramPushPayload(p.(*api.PushPayload))
|
||||||
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
|
||||||
|
|||||||
@@ -1843,12 +1843,12 @@ dashboard.operation_switch = Switch
|
|||||||
dashboard.operation_run = Run
|
dashboard.operation_run = Run
|
||||||
dashboard.clean_unbind_oauth = Clean unbound OAuth connections
|
dashboard.clean_unbind_oauth = Clean unbound OAuth connections
|
||||||
dashboard.clean_unbind_oauth_success = All unbound OAuth connections have been deleted.
|
dashboard.clean_unbind_oauth_success = All unbound OAuth connections have been deleted.
|
||||||
dashboard.task.started=Started Task: %s
|
dashboard.task.started=Started Task: %[1]s
|
||||||
dashboard.task.process=Task: %s
|
dashboard.task.process=Task: %[1]s
|
||||||
dashboard.task.cancelled=Task: %s cancelled: %[3]s
|
dashboard.task.cancelled=Task: %[1]s cancelled: %[3]s
|
||||||
dashboard.task.error=Error in Task: %s: %[3]s
|
dashboard.task.error=Error in Task: %[1]s: %[3]s
|
||||||
dashboard.task.finished=Task: %s started by %s has finished
|
dashboard.task.finished=Task: %[1]s started by %[2]s has finished
|
||||||
dashboard.task.unknown=Unknown task: %s
|
dashboard.task.unknown=Unknown task: %[1]s
|
||||||
dashboard.cron.started=Started Cron: %[1]s
|
dashboard.cron.started=Started Cron: %[1]s
|
||||||
dashboard.cron.process=Cron: %[1]s
|
dashboard.cron.process=Cron: %[1]s
|
||||||
dashboard.cron.cancelled=Cron: %s cancelled: %[3]s
|
dashboard.cron.cancelled=Cron: %s cancelled: %[3]s
|
||||||
|
|||||||
5
package-lock.json
generated
5
package-lock.json
generated
@@ -4007,6 +4007,11 @@
|
|||||||
"es6-symbol": "^3.1.1"
|
"es6-symbol": "^3.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"escape-goat": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw=="
|
||||||
|
},
|
||||||
"escape-string-regexp": {
|
"escape-string-regexp": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"cssnano": "4.1.10",
|
"cssnano": "4.1.10",
|
||||||
"domino": "2.1.5",
|
"domino": "2.1.5",
|
||||||
"dropzone": "5.7.0",
|
"dropzone": "5.7.0",
|
||||||
|
"escape-goat": "3.0.0",
|
||||||
"fast-glob": "3.2.2",
|
"fast-glob": "3.2.2",
|
||||||
"file-loader": "6.0.0",
|
"file-loader": "6.0.0",
|
||||||
"fomantic-ui": "2.8.4",
|
"fomantic-ui": "2.8.4",
|
||||||
|
|||||||
@@ -153,8 +153,11 @@ func DashboardPost(ctx *context.Context, form auth.AdminDashboardForm) {
|
|||||||
ctx.Flash.Error(ctx.Tr("admin.dashboard.task.unknown", form.Op))
|
ctx.Flash.Error(ctx.Tr("admin.dashboard.task.unknown", form.Op))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if form.From == "monitor" {
|
||||||
ctx.Redirect(setting.AppSubURL + "/admin")
|
ctx.Redirect(setting.AppSubURL + "/admin/monitor")
|
||||||
|
} else {
|
||||||
|
ctx.Redirect(setting.AppSubURL + "/admin")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendTestMail send test mail to confirm mail service is OK
|
// SendTestMail send test mail to confirm mail service is OK
|
||||||
@@ -331,7 +334,7 @@ func MonitorCancel(ctx *context.Context) {
|
|||||||
pid := ctx.ParamsInt64("pid")
|
pid := ctx.ParamsInt64("pid")
|
||||||
process.GetManager().Cancel(pid)
|
process.GetManager().Cancel(pid)
|
||||||
ctx.JSON(200, map[string]interface{}{
|
ctx.JSON(200, map[string]interface{}{
|
||||||
"redirect": ctx.Repo.RepoLink + "/admin/monitor",
|
"redirect": setting.AppSubURL + "/admin/monitor",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,37 @@ import (
|
|||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func statusStringToNotificationStatus(status string) models.NotificationStatus {
|
||||||
|
switch strings.ToLower(strings.TrimSpace(status)) {
|
||||||
|
case "unread":
|
||||||
|
return models.NotificationStatusUnread
|
||||||
|
case "read":
|
||||||
|
return models.NotificationStatusRead
|
||||||
|
case "pinned":
|
||||||
|
return models.NotificationStatusPinned
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func statusStringsToNotificationStatuses(statuses []string, defaultStatuses []string) []models.NotificationStatus {
|
||||||
|
if len(statuses) == 0 {
|
||||||
|
statuses = defaultStatuses
|
||||||
|
}
|
||||||
|
results := make([]models.NotificationStatus, 0, len(statuses))
|
||||||
|
for _, status := range statuses {
|
||||||
|
notificationStatus := statusStringToNotificationStatus(status)
|
||||||
|
if notificationStatus > 0 {
|
||||||
|
results = append(results, notificationStatus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
// ListRepoNotifications list users's notification threads on a specific repo
|
// ListRepoNotifications list users's notification threads on a specific repo
|
||||||
func ListRepoNotifications(ctx *context.APIContext) {
|
func ListRepoNotifications(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/notifications notification notifyGetRepoList
|
// swagger:operation GET /repos/{owner}/{repo}/notifications notification notifyGetRepoList
|
||||||
@@ -39,6 +67,14 @@ func ListRepoNotifications(ctx *context.APIContext) {
|
|||||||
// description: If true, show notifications marked as read. Default value is false
|
// description: If true, show notifications marked as read. Default value is false
|
||||||
// type: string
|
// type: string
|
||||||
// required: false
|
// required: false
|
||||||
|
// - name: status-types
|
||||||
|
// in: query
|
||||||
|
// description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned"
|
||||||
|
// type: array
|
||||||
|
// collectionFormat: multi
|
||||||
|
// items:
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
// - name: since
|
// - name: since
|
||||||
// in: query
|
// in: query
|
||||||
// description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format
|
// description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format
|
||||||
@@ -75,9 +111,10 @@ func ListRepoNotifications(ctx *context.APIContext) {
|
|||||||
UpdatedBeforeUnix: before,
|
UpdatedBeforeUnix: before,
|
||||||
UpdatedAfterUnix: since,
|
UpdatedAfterUnix: since,
|
||||||
}
|
}
|
||||||
qAll := strings.Trim(ctx.Query("all"), " ")
|
|
||||||
if qAll != "true" {
|
if !ctx.QueryBool("all") {
|
||||||
opts.Status = models.NotificationStatusUnread
|
statuses := ctx.QueryStrings("status-types")
|
||||||
|
opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread", "pinned"})
|
||||||
}
|
}
|
||||||
nl, err := models.GetNotifications(opts)
|
nl, err := models.GetNotifications(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -97,7 +134,7 @@ func ListRepoNotifications(ctx *context.APIContext) {
|
|||||||
func ReadRepoNotifications(ctx *context.APIContext) {
|
func ReadRepoNotifications(ctx *context.APIContext) {
|
||||||
// swagger:operation PUT /repos/{owner}/{repo}/notifications notification notifyReadRepoList
|
// swagger:operation PUT /repos/{owner}/{repo}/notifications notification notifyReadRepoList
|
||||||
// ---
|
// ---
|
||||||
// summary: Mark notification threads as read on a specific repo
|
// summary: Mark notification threads as read, pinned or unread on a specific repo
|
||||||
// consumes:
|
// consumes:
|
||||||
// - application/json
|
// - application/json
|
||||||
// produces:
|
// produces:
|
||||||
@@ -113,6 +150,24 @@ func ReadRepoNotifications(ctx *context.APIContext) {
|
|||||||
// description: name of the repo
|
// description: name of the repo
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
|
// - name: all
|
||||||
|
// in: query
|
||||||
|
// description: If true, mark all notifications on this repo. Default value is false
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
|
// - name: status-types
|
||||||
|
// in: query
|
||||||
|
// description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread."
|
||||||
|
// type: array
|
||||||
|
// collectionFormat: multi
|
||||||
|
// items:
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
|
// - name: to-status
|
||||||
|
// in: query
|
||||||
|
// description: Status to mark notifications as. Defaults to read.
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
// - name: last_read_at
|
// - name: last_read_at
|
||||||
// in: query
|
// in: query
|
||||||
// description: Describes the last point that notifications were checked. Anything updated since this time will not be updated.
|
// description: Describes the last point that notifications were checked. Anything updated since this time will not be updated.
|
||||||
@@ -135,11 +190,17 @@ func ReadRepoNotifications(ctx *context.APIContext) {
|
|||||||
lastRead = tmpLastRead.Unix()
|
lastRead = tmpLastRead.Unix()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := models.FindNotificationOptions{
|
opts := models.FindNotificationOptions{
|
||||||
UserID: ctx.User.ID,
|
UserID: ctx.User.ID,
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
RepoID: ctx.Repo.Repository.ID,
|
||||||
UpdatedBeforeUnix: lastRead,
|
UpdatedBeforeUnix: lastRead,
|
||||||
Status: models.NotificationStatusUnread,
|
}
|
||||||
|
|
||||||
|
if !ctx.QueryBool("all") {
|
||||||
|
statuses := ctx.QueryStrings("status-types")
|
||||||
|
opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"})
|
||||||
|
log.Error("%v", opts.Status)
|
||||||
}
|
}
|
||||||
nl, err := models.GetNotifications(opts)
|
nl, err := models.GetNotifications(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -147,8 +208,13 @@ func ReadRepoNotifications(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetStatus := statusStringToNotificationStatus(ctx.Query("to-status"))
|
||||||
|
if targetStatus == 0 {
|
||||||
|
targetStatus = models.NotificationStatusRead
|
||||||
|
}
|
||||||
|
|
||||||
for _, n := range nl {
|
for _, n := range nl {
|
||||||
err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead)
|
err := models.SetNotificationStatus(n.ID, ctx.User, targetStatus)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.InternalServerError(err)
|
ctx.InternalServerError(err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -62,6 +62,12 @@ func ReadThread(ctx *context.APIContext) {
|
|||||||
// description: id of notification thread
|
// description: id of notification thread
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
|
// - name: to-status
|
||||||
|
// in: query
|
||||||
|
// description: Status to mark notifications as
|
||||||
|
// type: string
|
||||||
|
// default: read
|
||||||
|
// required: false
|
||||||
// responses:
|
// responses:
|
||||||
// "205":
|
// "205":
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
@@ -75,7 +81,12 @@ func ReadThread(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead)
|
targetStatus := statusStringToNotificationStatus(ctx.Query("to-status"))
|
||||||
|
if targetStatus == 0 {
|
||||||
|
targetStatus = models.NotificationStatusRead
|
||||||
|
}
|
||||||
|
|
||||||
|
err := models.SetNotificationStatus(n.ID, ctx.User, targetStatus)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.InternalServerError(err)
|
ctx.InternalServerError(err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -29,6 +29,14 @@ func ListNotifications(ctx *context.APIContext) {
|
|||||||
// description: If true, show notifications marked as read. Default value is false
|
// description: If true, show notifications marked as read. Default value is false
|
||||||
// type: string
|
// type: string
|
||||||
// required: false
|
// required: false
|
||||||
|
// - name: status-types
|
||||||
|
// in: query
|
||||||
|
// description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned."
|
||||||
|
// type: array
|
||||||
|
// collectionFormat: multi
|
||||||
|
// items:
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
// - name: since
|
// - name: since
|
||||||
// in: query
|
// in: query
|
||||||
// description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format
|
// description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format
|
||||||
@@ -64,9 +72,9 @@ func ListNotifications(ctx *context.APIContext) {
|
|||||||
UpdatedBeforeUnix: before,
|
UpdatedBeforeUnix: before,
|
||||||
UpdatedAfterUnix: since,
|
UpdatedAfterUnix: since,
|
||||||
}
|
}
|
||||||
qAll := strings.Trim(ctx.Query("all"), " ")
|
if !ctx.QueryBool("all") {
|
||||||
if qAll != "true" {
|
statuses := ctx.QueryStrings("status-types")
|
||||||
opts.Status = models.NotificationStatusUnread
|
opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread", "pinned"})
|
||||||
}
|
}
|
||||||
nl, err := models.GetNotifications(opts)
|
nl, err := models.GetNotifications(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -82,11 +90,11 @@ func ListNotifications(ctx *context.APIContext) {
|
|||||||
ctx.JSON(http.StatusOK, nl.APIFormat())
|
ctx.JSON(http.StatusOK, nl.APIFormat())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadNotifications mark notification threads as read
|
// ReadNotifications mark notification threads as read, unread, or pinned
|
||||||
func ReadNotifications(ctx *context.APIContext) {
|
func ReadNotifications(ctx *context.APIContext) {
|
||||||
// swagger:operation PUT /notifications notification notifyReadList
|
// swagger:operation PUT /notifications notification notifyReadList
|
||||||
// ---
|
// ---
|
||||||
// summary: Mark notification threads as read
|
// summary: Mark notification threads as read, pinned or unread
|
||||||
// consumes:
|
// consumes:
|
||||||
// - application/json
|
// - application/json
|
||||||
// produces:
|
// produces:
|
||||||
@@ -98,6 +106,24 @@ func ReadNotifications(ctx *context.APIContext) {
|
|||||||
// type: string
|
// type: string
|
||||||
// format: date-time
|
// format: date-time
|
||||||
// required: false
|
// required: false
|
||||||
|
// - name: all
|
||||||
|
// in: query
|
||||||
|
// description: If true, mark all notifications on this repo. Default value is false
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
|
// - name: status-types
|
||||||
|
// in: query
|
||||||
|
// description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread."
|
||||||
|
// type: array
|
||||||
|
// collectionFormat: multi
|
||||||
|
// items:
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
|
// - name: to-status
|
||||||
|
// in: query
|
||||||
|
// description: Status to mark notifications as, Defaults to read.
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
// responses:
|
// responses:
|
||||||
// "205":
|
// "205":
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
@@ -117,7 +143,10 @@ func ReadNotifications(ctx *context.APIContext) {
|
|||||||
opts := models.FindNotificationOptions{
|
opts := models.FindNotificationOptions{
|
||||||
UserID: ctx.User.ID,
|
UserID: ctx.User.ID,
|
||||||
UpdatedBeforeUnix: lastRead,
|
UpdatedBeforeUnix: lastRead,
|
||||||
Status: models.NotificationStatusUnread,
|
}
|
||||||
|
if !ctx.QueryBool("all") {
|
||||||
|
statuses := ctx.QueryStrings("status-types")
|
||||||
|
opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"})
|
||||||
}
|
}
|
||||||
nl, err := models.GetNotifications(opts)
|
nl, err := models.GetNotifications(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -125,8 +154,13 @@ func ReadNotifications(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetStatus := statusStringToNotificationStatus(ctx.Query("to-status"))
|
||||||
|
if targetStatus == 0 {
|
||||||
|
targetStatus = models.NotificationStatusRead
|
||||||
|
}
|
||||||
|
|
||||||
for _, n := range nl {
|
for _, n := range nl {
|
||||||
err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead)
|
err := models.SetNotificationStatus(n.ID, ctx.User, targetStatus)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.InternalServerError(err)
|
ctx.InternalServerError(err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ func toCommit(ctx *context.APIContext, repo *models.Repository, commit *git.Comm
|
|||||||
},
|
},
|
||||||
Date: commit.Committer.When.Format(time.RFC3339),
|
Date: commit.Committer.When.Format(time.RFC3339),
|
||||||
},
|
},
|
||||||
Message: commit.Summary(),
|
Message: commit.Message(),
|
||||||
Tree: &api.CommitMeta{
|
Tree: &api.CommitMeta{
|
||||||
URL: repo.APIURL() + "/git/trees/" + commit.ID.String(),
|
URL: repo.APIURL() + "/git/trees/" + commit.ID.String(),
|
||||||
SHA: commit.ID.String(),
|
SHA: commit.ID.String(),
|
||||||
|
|||||||
@@ -275,12 +275,6 @@ func TopicSearch(ctx *context.APIContext) {
|
|||||||
kw := ctx.Query("q")
|
kw := ctx.Query("q")
|
||||||
|
|
||||||
listOptions := utils.GetListOptions(ctx)
|
listOptions := utils.GetListOptions(ctx)
|
||||||
if listOptions.Page < 1 {
|
|
||||||
listOptions.Page = 1
|
|
||||||
}
|
|
||||||
if listOptions.PageSize < 1 {
|
|
||||||
listOptions.PageSize = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
topics, err := models.FindTopics(&models.FindTopicOptions{
|
topics, err := models.FindTopics(&models.FindTopicOptions{
|
||||||
Keyword: kw,
|
Keyword: kw,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/convert"
|
"code.gitea.io/gitea/modules/convert"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/structs"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
repo_service "code.gitea.io/gitea/services/repository"
|
repo_service "code.gitea.io/gitea/services/repository"
|
||||||
)
|
)
|
||||||
@@ -53,13 +54,21 @@ func Transfer(ctx *context.APIContext, opts api.TransferRepoOption) {
|
|||||||
newOwner, err := models.GetUserByName(opts.NewOwner)
|
newOwner, err := models.GetUserByName(opts.NewOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrUserNotExist(err) {
|
if models.IsErrUserNotExist(err) {
|
||||||
ctx.Error(http.StatusNotFound, "GetUserByName", err)
|
ctx.Error(http.StatusNotFound, "", "The new owner does not exist or cannot be found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.InternalServerError(err)
|
ctx.InternalServerError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if newOwner.Type == models.UserTypeOrganization {
|
||||||
|
if !ctx.User.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !newOwner.HasMemberWithUserID(ctx.User.ID) {
|
||||||
|
// The user shouldn't know about this organization
|
||||||
|
ctx.Error(http.StatusNotFound, "", "The new owner does not exist or cannot be found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var teams []*models.Team
|
var teams []*models.Team
|
||||||
if opts.TeamIDs != nil {
|
if opts.TeamIDs != nil {
|
||||||
if !newOwner.IsOrganization() {
|
if !newOwner.IsOrganization() {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
@@ -15,10 +16,12 @@ import (
|
|||||||
|
|
||||||
// listUserRepos - List the repositories owned by the given user.
|
// listUserRepos - List the repositories owned by the given user.
|
||||||
func listUserRepos(ctx *context.APIContext, u *models.User, private bool) {
|
func listUserRepos(ctx *context.APIContext, u *models.User, private bool) {
|
||||||
repos, err := models.GetUserRepositories(&models.SearchRepoOptions{
|
opts := utils.GetListOptions(ctx)
|
||||||
|
|
||||||
|
repos, count, err := models.GetUserRepositories(&models.SearchRepoOptions{
|
||||||
Actor: u,
|
Actor: u,
|
||||||
Private: private,
|
Private: private,
|
||||||
ListOptions: utils.GetListOptions(ctx),
|
ListOptions: opts,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetUserRepositories", err)
|
ctx.Error(http.StatusInternalServerError, "GetUserRepositories", err)
|
||||||
@@ -36,6 +39,9 @@ func listUserRepos(ctx *context.APIContext, u *models.User, private bool) {
|
|||||||
apiRepos = append(apiRepos, repos[i].APIFormat(access))
|
apiRepos = append(apiRepos, repos[i].APIFormat(access))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.SetLinkHeader(int(count), opts.PageSize)
|
||||||
|
ctx.Header().Set("X-Total-Count", strconv.FormatInt(count, 10))
|
||||||
ctx.JSON(http.StatusOK, &apiRepos)
|
ctx.JSON(http.StatusOK, &apiRepos)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,31 +98,37 @@ func ListMyRepos(ctx *context.APIContext) {
|
|||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/RepositoryList"
|
// "$ref": "#/responses/RepositoryList"
|
||||||
|
|
||||||
ownRepos, err := models.GetUserRepositories(&models.SearchRepoOptions{
|
opts := &models.SearchRepoOptions{
|
||||||
Actor: ctx.User,
|
ListOptions: utils.GetListOptions(ctx),
|
||||||
Private: true,
|
Actor: ctx.User,
|
||||||
ListOptions: utils.GetListOptions(ctx),
|
OwnerID: ctx.User.ID,
|
||||||
})
|
Private: ctx.IsSigned,
|
||||||
if err != nil {
|
IncludeDescription: true,
|
||||||
ctx.Error(http.StatusInternalServerError, "GetUserRepositories", err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
accessibleReposMap, err := ctx.User.GetRepositoryAccesses()
|
|
||||||
|
var err error
|
||||||
|
repos, count, err := models.SearchRepository(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetRepositoryAccesses", err)
|
ctx.Error(http.StatusInternalServerError, "SearchRepository", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiRepos := make([]*api.Repository, len(ownRepos)+len(accessibleReposMap))
|
results := make([]*api.Repository, len(repos))
|
||||||
for i := range ownRepos {
|
for i, repo := range repos {
|
||||||
apiRepos[i] = ownRepos[i].APIFormat(models.AccessModeOwner)
|
if err = repo.GetOwner(); err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "GetOwner", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
accessMode, err := models.AccessLevel(ctx.User, repo)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
|
||||||
|
}
|
||||||
|
results[i] = repo.APIFormat(accessMode)
|
||||||
}
|
}
|
||||||
i := len(ownRepos)
|
|
||||||
for repo, access := range accessibleReposMap {
|
ctx.SetLinkHeader(int(count), opts.ListOptions.PageSize)
|
||||||
apiRepos[i] = repo.APIFormat(access)
|
ctx.Header().Set("X-Total-Count", strconv.FormatInt(count, 10))
|
||||||
i++
|
ctx.JSON(http.StatusOK, &results)
|
||||||
}
|
|
||||||
ctx.JSON(http.StatusOK, &apiRepos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListOrgRepos - list the repositories of an organization.
|
// ListOrgRepos - list the repositories of an organization.
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import (
|
|||||||
|
|
||||||
"gitea.com/macaron/i18n"
|
"gitea.com/macaron/i18n"
|
||||||
"gitea.com/macaron/macaron"
|
"gitea.com/macaron/macaron"
|
||||||
unknwoni18n "github.com/unknwon/i18n"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkRunMode() {
|
func checkRunMode() {
|
||||||
@@ -124,8 +123,6 @@ func GlobalInit(ctx context.Context) {
|
|||||||
// Setup i18n
|
// Setup i18n
|
||||||
InitLocales()
|
InitLocales()
|
||||||
|
|
||||||
log.Info("%s", unknwoni18n.Tr("en-US", "admin.dashboard.delete_repo_archives"))
|
|
||||||
|
|
||||||
NewServices()
|
NewServices()
|
||||||
|
|
||||||
if setting.InstallLock {
|
if setting.InstallLock {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []
|
|||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// This is safe as force pushes are already forbidden
|
||||||
err = git.NewCommand("rev-list", oldCommitID+"..."+newCommitID).
|
err = git.NewCommand("rev-list", oldCommitID+"..."+newCommitID).
|
||||||
RunInDirTimeoutEnvFullPipelineFunc(env, -1, repo.Path,
|
RunInDirTimeoutEnvFullPipelineFunc(env, -1, repo.Path,
|
||||||
stdoutWriter, nil, nil,
|
stdoutWriter, nil, nil,
|
||||||
@@ -70,6 +71,7 @@ func checkFileProtection(oldCommitID, newCommitID string, patterns []glob.Glob,
|
|||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// This use of ... is safe as force-pushes have already been ruled out.
|
||||||
err = git.NewCommand("diff", "--name-only", oldCommitID+"..."+newCommitID).
|
err = git.NewCommand("diff", "--name-only", oldCommitID+"..."+newCommitID).
|
||||||
RunInDirTimeoutEnvFullPipelineFunc(env, -1, repo.Path,
|
RunInDirTimeoutEnvFullPipelineFunc(env, -1, repo.Path,
|
||||||
stdoutWriter, nil, nil,
|
stdoutWriter, nil, nil,
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user