mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-05 18:32:41 +09:00
Compare commits
14 Commits
v1.16.0-rc
...
v1.16.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a044ec8b53 | ||
|
|
f93d72c09b | ||
|
|
2f22337125 | ||
|
|
781ad8a79e | ||
|
|
cada7202aa | ||
|
|
0b331e2213 | ||
|
|
0734ca0132 | ||
|
|
0b83cc21be | ||
|
|
b68e605d56 | ||
|
|
42991dc89a | ||
|
|
160de9fbda | ||
|
|
d644289fcb | ||
|
|
fd9ff7cd6f | ||
|
|
b7c6457648 |
27
CHANGELOG.md
27
CHANGELOG.md
@@ -4,13 +4,15 @@ 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.16.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.16.0-rc1) - 2022-01-19
|
## [1.16.0](https://github.com/go-gitea/gitea/releases/tag/v1.16.0) - 2022-01-30
|
||||||
|
|
||||||
* BREAKING
|
* BREAKING
|
||||||
* Remove golang vendored directory (#18277)
|
* Remove golang vendored directory (#18277)
|
||||||
* Paginate releases page & set default page size to 10 (#16857)
|
* Paginate releases page & set default page size to 10 (#16857)
|
||||||
* Only allow webhook to send requests to allowed hosts (#17482)
|
* Only allow webhook to send requests to allowed hosts (#17482)
|
||||||
* SECURITY
|
* SECURITY
|
||||||
|
* Disable content sniffing on `PlainTextBytes` (#18359) (#18365)
|
||||||
|
* Only view milestones from current repo (#18414) (#18417)
|
||||||
* Sanitize user-input on file name (#17666)
|
* Sanitize user-input on file name (#17666)
|
||||||
* Use `hostmatcher` to replace `matchlist` to improve blocking of bad hosts in Webhooks (#17605)
|
* Use `hostmatcher` to replace `matchlist` to improve blocking of bad hosts in Webhooks (#17605)
|
||||||
* FEATURES
|
* FEATURES
|
||||||
@@ -228,6 +230,16 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* Add left padding for chunk header of split diff view (#13397)
|
* Add left padding for chunk header of split diff view (#13397)
|
||||||
* Allow U2F 2FA without TOTP (#11573)
|
* Allow U2F 2FA without TOTP (#11573)
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
* GitLab reviews may not have the updated_at field set (#18450) (#18461)
|
||||||
|
* Fix detection of no commits when the default branch is not master (#18422) (#18423)
|
||||||
|
* Fix broken oauth2 authentication source edit page (#18412) (#18419)
|
||||||
|
* Place inline diff comment dialogs on split diff in 4th and 8th columns (#18403) (#18404)
|
||||||
|
* Fix restore without topic failure (#18387) (#18400)
|
||||||
|
* Fix commit's time (#18375) (#18392)
|
||||||
|
* Fix partial cloning a repo (#18373) (#18377)
|
||||||
|
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
|
||||||
|
* Prevent showing webauthn error for every time visiting `/user/settings/security` (#18386)
|
||||||
|
* Fix mime-type detection for HTTP server (#18370) (#18371)
|
||||||
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
|
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
|
||||||
* Restore propagation of ErrDependenciesLeft (#18325)
|
* Restore propagation of ErrDependenciesLeft (#18325)
|
||||||
* Fix PR comments UI (#18323)
|
* Fix PR comments UI (#18323)
|
||||||
@@ -299,6 +311,19 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* MISC
|
* MISC
|
||||||
* Update JS dependencies (#17611)
|
* Update JS dependencies (#17611)
|
||||||
|
|
||||||
|
## [1.15.11](https://github.com/go-gitea/gitea/releases/tag/v1.15.11) - 2022-01-29
|
||||||
|
|
||||||
|
* SECURITY
|
||||||
|
* Only view milestones from current repo (#18414) (#18418)
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix broken when no commits and default branch is not master (#18422) (#18424)
|
||||||
|
* Fix commit's time (#18375) (#18409)
|
||||||
|
* Fix restore without topic failure (#18387) (#18401)
|
||||||
|
* Fix mermaid import in 1.15 (it uses ESModule now) (#18382)
|
||||||
|
* Update to go/text 0.3.7 (#18336)
|
||||||
|
* MISC
|
||||||
|
* Upgrade EasyMDE to 2.16.1 (#18278) (#18279)
|
||||||
|
|
||||||
## [1.15.10](https://github.com/go-gitea/gitea/releases/tag/v1.15.10) - 2022-01-14
|
## [1.15.10](https://github.com/go-gitea/gitea/releases/tag/v1.15.10) - 2022-01-14
|
||||||
|
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ params:
|
|||||||
description: Git with a cup of tea
|
description: Git with a cup of tea
|
||||||
author: The Gitea Authors
|
author: The Gitea Authors
|
||||||
website: https://docs.gitea.io
|
website: https://docs.gitea.io
|
||||||
version: 1.15.10
|
version: 1.16.0
|
||||||
minGoVersion: 1.16
|
minGoVersion: 1.16
|
||||||
goVersion: 1.17
|
goVersion: 1.17
|
||||||
minNodeVersion: 12.17
|
minNodeVersion: 12.17
|
||||||
|
|||||||
6
go.mod
6
go.mod
@@ -30,7 +30,7 @@ require (
|
|||||||
github.com/denisenkom/go-mssqldb v0.10.0
|
github.com/denisenkom/go-mssqldb v0.10.0
|
||||||
github.com/djherbis/buffer v1.2.0
|
github.com/djherbis/buffer v1.2.0
|
||||||
github.com/djherbis/nio/v3 v3.0.1
|
github.com/djherbis/nio/v3 v3.0.1
|
||||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b
|
github.com/duo-labs/webauthn v0.0.0-20220122034320-81aea484c951
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2
|
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2
|
||||||
github.com/emirpasic/gods v1.12.0
|
github.com/emirpasic/gods v1.12.0
|
||||||
@@ -54,7 +54,7 @@ require (
|
|||||||
github.com/golang-jwt/jwt/v4 v4.2.0
|
github.com/golang-jwt/jwt/v4 v4.2.0
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/go-github/v39 v39.2.0
|
github.com/google/go-github/v39 v39.2.0
|
||||||
github.com/google/uuid v1.2.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/gorilla/feeds v1.1.1
|
github.com/gorilla/feeds v1.1.1
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/gorilla/sessions v1.2.1
|
github.com/gorilla/sessions v1.2.1
|
||||||
@@ -145,8 +145,6 @@ replace github.com/markbates/goth v1.68.0 => github.com/zeripath/goth v1.68.1-0.
|
|||||||
|
|
||||||
replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0
|
replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0
|
||||||
|
|
||||||
replace github.com/duo-labs/webauthn => github.com/authelia/webauthn v0.0.0-20211225121951-80d1f2a572e4
|
|
||||||
|
|
||||||
replace github.com/satori/go.uuid v1.2.0 => github.com/gofrs/uuid v4.2.0+incompatible
|
replace github.com/satori/go.uuid v1.2.0 => github.com/gofrs/uuid v4.2.0+incompatible
|
||||||
|
|
||||||
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
||||||
|
|||||||
9
go.sum
9
go.sum
@@ -131,8 +131,6 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:o
|
|||||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/authelia/webauthn v0.0.0-20211225121951-80d1f2a572e4 h1:u3eFvgr4A8IjlAokbFt6XY6VdurX7DEYnQMQ4K2yobc=
|
|
||||||
github.com/authelia/webauthn v0.0.0-20211225121951-80d1f2a572e4/go.mod h1:EYSpSkwoEcryMmQGfhol2IiB3IMN9IIIaNd/wcAQMGQ=
|
|
||||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||||
@@ -276,6 +274,8 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
|
|||||||
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
|
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
|
||||||
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
|
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
|
||||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||||
|
github.com/duo-labs/webauthn v0.0.0-20220122034320-81aea484c951 h1:17esZ09oW+29rklBtCVphIguql2u3NxYH2OasFPPZoo=
|
||||||
|
github.com/duo-labs/webauthn v0.0.0-20220122034320-81aea484c951/go.mod h1:nHy3JdztZWcsjenDeBuE8gn171OAwg12LBN027UP5AE=
|
||||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
@@ -491,7 +491,6 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
|||||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||||
github.com/goccy/go-json v0.7.4 h1:B44qRUFwz/vxPKPISQ1KhvzRi9kZ28RAf6YtjriBZ5k=
|
github.com/goccy/go-json v0.7.4 h1:B44qRUFwz/vxPKPISQ1KhvzRi9kZ28RAf6YtjriBZ5k=
|
||||||
github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
|
|
||||||
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
@@ -585,8 +584,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
|||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
|||||||
@@ -123,6 +123,17 @@ func doGitClone(dstLocalPath string, u *url.URL) func(*testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func doPartialGitClone(dstLocalPath string, u *url.URL) func(*testing.T) {
|
||||||
|
return func(t *testing.T) {
|
||||||
|
assert.NoError(t, git.CloneWithArgs(context.Background(), u.String(), dstLocalPath, allowLFSFilters(), git.CloneRepoOptions{
|
||||||
|
Filter: "blob:none",
|
||||||
|
}))
|
||||||
|
exist, err := util.IsExist(filepath.Join(dstLocalPath, "README.md"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, exist)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func doGitCloneFail(u *url.URL) func(*testing.T) {
|
func doGitCloneFail(u *url.URL) func(*testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
tmpDir, err := os.MkdirTemp("", "doGitCloneFail")
|
tmpDir, err := os.MkdirTemp("", "doGitCloneFail")
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
|
|
||||||
t.Run("Clone", doGitClone(dstPath, u))
|
t.Run("Clone", doGitClone(dstPath, u))
|
||||||
|
|
||||||
|
dstPath2, err := os.MkdirTemp("", httpContext.Reponame)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer util.RemoveAll(dstPath2)
|
||||||
|
|
||||||
|
t.Run("Partial Clone", doPartialGitClone(dstPath2, u))
|
||||||
|
|
||||||
little, big := standardCommitAndPushTest(t, dstPath)
|
little, big := standardCommitAndPushTest(t, dstPath)
|
||||||
littleLFS, bigLFS := lfsCommitAndPushTest(t, dstPath)
|
littleLFS, bigLFS := lfsCommitAndPushTest(t, dstPath)
|
||||||
rawTest(t, &httpContext, little, big, littleLFS, bigLFS)
|
rawTest(t, &httpContext, little, big, littleLFS, bigLFS)
|
||||||
|
|||||||
@@ -134,22 +134,6 @@ func GetMilestoneByRepoIDANDName(repoID int64, name string) (*Milestone, error)
|
|||||||
return &mile, nil
|
return &mile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMilestoneByID returns the milestone via id .
|
|
||||||
func GetMilestoneByID(id int64) (*Milestone, error) {
|
|
||||||
return getMilestoneByID(db.GetEngine(db.DefaultContext), id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMilestoneByID(e db.Engine, id int64) (*Milestone, error) {
|
|
||||||
var m Milestone
|
|
||||||
has, err := e.ID(id).Get(&m)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if !has {
|
|
||||||
return nil, ErrMilestoneNotExist{ID: id, RepoID: 0}
|
|
||||||
}
|
|
||||||
return &m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMilestone updates information of given milestone.
|
// UpdateMilestone updates information of given milestone.
|
||||||
func UpdateMilestone(m *Milestone, oldIsClosed bool) error {
|
func UpdateMilestone(m *Milestone, oldIsClosed bool) error {
|
||||||
ctx, committer, err := db.TxContext()
|
ctx, committer, err := db.TxContext()
|
||||||
|
|||||||
@@ -291,6 +291,7 @@ func (ctx *Context) PlainTextBytes(status int, bs []byte) {
|
|||||||
}
|
}
|
||||||
ctx.Resp.WriteHeader(status)
|
ctx.Resp.WriteHeader(status)
|
||||||
ctx.Resp.Header().Set("Content-Type", "text/plain;charset=utf-8")
|
ctx.Resp.Header().Set("Content-Type", "text/plain;charset=utf-8")
|
||||||
|
ctx.Resp.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
if _, err := ctx.Resp.Write(bs); err != nil {
|
if _, err := ctx.Resp.Write(bs); err != nil {
|
||||||
log.Error("Write bytes failed: %v", err)
|
log.Error("Write bytes failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,27 +59,28 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff
|
|||||||
ctx, _, finished := process.GetManager().AddContext(repo.Ctx, fmt.Sprintf("GetRawDiffForFile: [repo_path: %s]", repo.Path))
|
ctx, _, finished := process.GetManager().AddContext(repo.Ctx, fmt.Sprintf("GetRawDiffForFile: [repo_path: %s]", repo.Path))
|
||||||
defer finished()
|
defer finished()
|
||||||
|
|
||||||
var cmd *exec.Cmd
|
cmd := exec.CommandContext(ctx, GitExecutable, GlobalCommandArgs...)
|
||||||
|
|
||||||
switch diffType {
|
switch diffType {
|
||||||
case RawDiffNormal:
|
case RawDiffNormal:
|
||||||
if len(startCommit) != 0 {
|
if len(startCommit) != 0 {
|
||||||
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...)
|
cmd.Args = append(cmd.Args, append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...)
|
||||||
} else if commit.ParentCount() == 0 {
|
} else if commit.ParentCount() == 0 {
|
||||||
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"show", endCommit}, fileArgs...)...)
|
cmd.Args = append(cmd.Args, append([]string{"show", endCommit}, fileArgs...)...)
|
||||||
} else {
|
} else {
|
||||||
c, _ := commit.Parent(0)
|
c, _ := commit.Parent(0)
|
||||||
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...)
|
cmd.Args = append(cmd.Args, append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...)
|
||||||
}
|
}
|
||||||
case RawDiffPatch:
|
case RawDiffPatch:
|
||||||
if len(startCommit) != 0 {
|
if len(startCommit) != 0 {
|
||||||
query := fmt.Sprintf("%s...%s", endCommit, startCommit)
|
query := fmt.Sprintf("%s...%s", endCommit, startCommit)
|
||||||
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...)
|
cmd.Args = append(cmd.Args, append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...)
|
||||||
} else if commit.ParentCount() == 0 {
|
} else if commit.ParentCount() == 0 {
|
||||||
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...)
|
cmd.Args = append(cmd.Args, append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...)
|
||||||
} else {
|
} else {
|
||||||
c, _ := commit.Parent(0)
|
c, _ := commit.Parent(0)
|
||||||
query := fmt.Sprintf("%s...%s", endCommit, c.ID.String())
|
query := fmt.Sprintf("%s...%s", endCommit, c.ID.String())
|
||||||
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...)
|
cmd.Args = append(cmd.Args, append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid diffType: %s", diffType)
|
return fmt.Errorf("invalid diffType: %s", diffType)
|
||||||
|
|||||||
@@ -79,16 +79,21 @@ func InitRepository(repoPath string, bare bool) error {
|
|||||||
|
|
||||||
// IsEmpty Check if repository is empty.
|
// IsEmpty Check if repository is empty.
|
||||||
func (repo *Repository) IsEmpty() (bool, error) {
|
func (repo *Repository) IsEmpty() (bool, error) {
|
||||||
var errbuf strings.Builder
|
var errbuf, output strings.Builder
|
||||||
if err := NewCommand("log", "-1").RunInDirPipeline(repo.Path, nil, &errbuf); err != nil {
|
if err := NewCommandContext(repo.Ctx, "rev-list", "--all", "--count", "--max-count=1").RunWithContext(&RunContext{
|
||||||
if strings.Contains(errbuf.String(), "fatal: bad default revision 'HEAD'") ||
|
Timeout: -1,
|
||||||
strings.Contains(errbuf.String(), "fatal: your current branch 'master' does not have any commits yet") {
|
Dir: repo.Path,
|
||||||
return true, nil
|
Stdout: &output,
|
||||||
}
|
Stderr: &errbuf,
|
||||||
|
}); err != nil {
|
||||||
return true, fmt.Errorf("check empty: %v - %s", err, errbuf.String())
|
return true, fmt.Errorf("check empty: %v - %s", err, errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, nil
|
c, err := strconv.Atoi(strings.TrimSpace(output.String()))
|
||||||
|
if err != nil {
|
||||||
|
return true, fmt.Errorf("check empty: convert %s to count failed: %v", output.String(), err)
|
||||||
|
}
|
||||||
|
return c == 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloneRepoOptions options when clone a repository
|
// CloneRepoOptions options when clone a repository
|
||||||
@@ -101,6 +106,7 @@ type CloneRepoOptions struct {
|
|||||||
Shared bool
|
Shared bool
|
||||||
NoCheckout bool
|
NoCheckout bool
|
||||||
Depth int
|
Depth int
|
||||||
|
Filter string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone clones original repository to target path.
|
// Clone clones original repository to target path.
|
||||||
@@ -141,7 +147,9 @@ func CloneWithArgs(ctx context.Context, from, to string, args []string, opts Clo
|
|||||||
if opts.Depth > 0 {
|
if opts.Depth > 0 {
|
||||||
cmd.AddArguments("--depth", strconv.Itoa(opts.Depth))
|
cmd.AddArguments("--depth", strconv.Itoa(opts.Depth))
|
||||||
}
|
}
|
||||||
|
if opts.Filter != "" {
|
||||||
|
cmd.AddArguments("--filter", opts.Filter)
|
||||||
|
}
|
||||||
if len(opts.Branch) > 0 {
|
if len(opts.Branch) > 0 {
|
||||||
cmd.AddArguments("-b", opts.Branch)
|
cmd.AddArguments("-b", opts.Branch)
|
||||||
}
|
}
|
||||||
|
|||||||
41
modules/public/mime_types.go
Normal file
41
modules/public/mime_types.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package public
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// wellKnownMimeTypesLower comes from Golang's builtin mime package: `builtinTypesLower`, see the comment of detectWellKnownMimeType
|
||||||
|
var wellKnownMimeTypesLower = map[string]string{
|
||||||
|
".avif": "image/avif",
|
||||||
|
".css": "text/css; charset=utf-8",
|
||||||
|
".gif": "image/gif",
|
||||||
|
".htm": "text/html; charset=utf-8",
|
||||||
|
".html": "text/html; charset=utf-8",
|
||||||
|
".jpeg": "image/jpeg",
|
||||||
|
".jpg": "image/jpeg",
|
||||||
|
".js": "text/javascript; charset=utf-8",
|
||||||
|
".json": "application/json",
|
||||||
|
".mjs": "text/javascript; charset=utf-8",
|
||||||
|
".pdf": "application/pdf",
|
||||||
|
".png": "image/png",
|
||||||
|
".svg": "image/svg+xml",
|
||||||
|
".wasm": "application/wasm",
|
||||||
|
".webp": "image/webp",
|
||||||
|
".xml": "text/xml; charset=utf-8",
|
||||||
|
|
||||||
|
// well, there are some types missing from the builtin list
|
||||||
|
".txt": "text/plain; charset=utf-8",
|
||||||
|
}
|
||||||
|
|
||||||
|
// detectWellKnownMimeType will return the mime-type for a well-known file ext name
|
||||||
|
// The purpose of this function is to bypass the unstable behavior of Golang's mime.TypeByExtension
|
||||||
|
// mime.TypeByExtension would use OS's mime-type config to overwrite the well-known types (see its document).
|
||||||
|
// If the user's OS has incorrect mime-type config, it would make Gitea can not respond a correct Content-Type to browsers.
|
||||||
|
// For example, if Gitea returns `text/plain` for a `.js` file, the browser couldn't run the JS due to security reasons.
|
||||||
|
// detectWellKnownMimeType makes the Content-Type for well-known files stable.
|
||||||
|
func detectWellKnownMimeType(ext string) string {
|
||||||
|
ext = strings.ToLower(ext)
|
||||||
|
return wellKnownMimeTypesLower[ext]
|
||||||
|
}
|
||||||
@@ -95,6 +95,15 @@ func parseAcceptEncoding(val string) map[string]bool {
|
|||||||
return types
|
return types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setWellKnownContentType will set the Content-Type if the file is a well-known type.
|
||||||
|
// See the comments of detectWellKnownMimeType
|
||||||
|
func setWellKnownContentType(w http.ResponseWriter, file string) {
|
||||||
|
mimeType := detectWellKnownMimeType(filepath.Ext(file))
|
||||||
|
if mimeType != "" {
|
||||||
|
w.Header().Set("Content-Type", mimeType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (opts *Options) handle(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) bool {
|
func (opts *Options) handle(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) bool {
|
||||||
// use clean to keep the file is a valid path with no . or ..
|
// use clean to keep the file is a valid path with no . or ..
|
||||||
f, err := fs.Open(path.Clean(file))
|
f, err := fs.Open(path.Clean(file))
|
||||||
@@ -125,6 +134,8 @@ func (opts *Options) handle(w http.ResponseWriter, req *http.Request, fs http.Fi
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setWellKnownContentType(w, file)
|
||||||
|
|
||||||
serveContent(w, req, fi, fi.ModTime(), f)
|
serveContent(w, req, fi, fi.ModTime(), f)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,12 @@ package public
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -66,24 +63,16 @@ func serveContent(w http.ResponseWriter, req *http.Request, fi os.FileInfo, modt
|
|||||||
encodings := parseAcceptEncoding(req.Header.Get("Accept-Encoding"))
|
encodings := parseAcceptEncoding(req.Header.Get("Accept-Encoding"))
|
||||||
if encodings["gzip"] {
|
if encodings["gzip"] {
|
||||||
if cf, ok := fi.(*vfsgen۰CompressedFileInfo); ok {
|
if cf, ok := fi.(*vfsgen۰CompressedFileInfo); ok {
|
||||||
rd := bytes.NewReader(cf.GzipBytes())
|
rdGzip := bytes.NewReader(cf.GzipBytes())
|
||||||
w.Header().Set("Content-Encoding", "gzip")
|
// all static files are managed by Gitea, so we can make sure every file has the correct ext name
|
||||||
ctype := mime.TypeByExtension(filepath.Ext(fi.Name()))
|
// then we can get the correct Content-Type, we do not need to do http.DetectContentType on the decompressed data
|
||||||
if ctype == "" {
|
mimeType := detectWellKnownMimeType(filepath.Ext(fi.Name()))
|
||||||
// read a chunk to decide between utf-8 text and binary
|
if mimeType == "" {
|
||||||
var buf [512]byte
|
mimeType = "application/octet-stream"
|
||||||
grd, _ := gzip.NewReader(rd)
|
|
||||||
n, _ := io.ReadFull(grd, buf[:])
|
|
||||||
ctype = http.DetectContentType(buf[:n])
|
|
||||||
_, err := rd.Seek(0, io.SeekStart) // rewind to output whole file
|
|
||||||
if err != nil {
|
|
||||||
log.Error("rd.Seek error: %v", err)
|
|
||||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", ctype)
|
w.Header().Set("Content-Type", mimeType)
|
||||||
http.ServeContent(w, req, fi.Name(), modtime, rd)
|
w.Header().Set("Content-Encoding", "gzip")
|
||||||
|
http.ServeContent(w, req, fi.Name(), modtime, rdGzip)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -392,18 +392,18 @@ Content=අන්තර්ගතය
|
|||||||
SSPISeparatorReplacement=වෙන්කර
|
SSPISeparatorReplacement=වෙන්කර
|
||||||
SSPIDefaultLanguage=පෙරනිමි භාෂාව
|
SSPIDefaultLanguage=පෙරනිමි භාෂාව
|
||||||
|
|
||||||
require_error=හිස් විය නොහැක. `
|
require_error=` හිස් විය නොහැක.`
|
||||||
alpha_dash_error='අක්ෂරාංක, ඉරක් ('-') සහ යටි ඉරි ('_') අක්ෂර පමණක් අඩංගු විය යුතුය. `
|
alpha_dash_error=` අක්ෂරාංක, ඉරක් ('-') සහ යටි ඉරි ('_') අක්ෂර පමණක් අඩංගු විය යුතුය.`
|
||||||
alpha_dash_dot_error='අක්ෂරාංක, ඉරක් ('-'), යටි ඉරි ('_') සහ තිතක් ('.') අක්ෂර පමණක් අඩංගු විය යුතුය. `
|
alpha_dash_dot_error=` අක්ෂරාංක, ඉරක් ('-'), යටි ඉරි ('_') සහ තිතක් ('.') අක්ෂර පමණක් අඩංගු විය යුතුය.`
|
||||||
git_ref_name_error='හොඳින් සාදන ලද Git යොමු නාමයක් විය යුතුය. `
|
git_ref_name_error=` හොඳින් සාදන ලද Git යොමු නාමයක් විය යුතුය.`
|
||||||
size_error=%sප්රමාණය විය යුතුය. `
|
size_error=`%sප්රමාණය විය යුතුය. `
|
||||||
min_size_error=අවම වශයෙන් අක්ෂර %s ක් වත් අඩංගු විය යුතුය. `
|
min_size_error=` අවම වශයෙන් අක්ෂර %s ක් වත් අඩංගු විය යුතුය.`
|
||||||
max_size_error=Ost බොහෝ අක්ෂර %s හි අඩංගු විය යුතුය. `
|
max_size_error=` Ost බොහෝ අක්ෂර %s හි අඩංගු විය යුතුය.`
|
||||||
email_error=A වලංගු විද්යුත් තැපැල් ලිපිනයක් නොවේ. `
|
email_error=` A වලංගු විද්යුත් තැපැල් ලිපිනයක් නොවේ.`
|
||||||
url_error=A වලංගු URL එකක් නොවේ. `
|
url_error=` A වලංගු URL එකක් නොවේ.`
|
||||||
include_error='උප නූල් '%s' අඩංගු විය යුතුය . `
|
include_error=` උප නූල් '%s' අඩංගු විය යුතුය.`
|
||||||
glob_pattern_error='ලෝක ගෝලය රටාව අවලංගුයි: %s. `
|
glob_pattern_error=` ලෝක ගෝලය රටාව අවලංගුයි: %s.`
|
||||||
regex_pattern_error=Regex රටාව අවලංගුයි: %s. `
|
regex_pattern_error=` regex රටාව අවලංගුයි: %s.`
|
||||||
unknown_error=නොදන්නා දෝෂය:
|
unknown_error=නොදන්නා දෝෂය:
|
||||||
captcha_incorrect=CAPTCHA කේතය වැරදිය.
|
captcha_incorrect=CAPTCHA කේතය වැරදිය.
|
||||||
password_not_match=මුරපද නොගැලපේ.
|
password_not_match=මුරපද නොගැලපේ.
|
||||||
@@ -575,7 +575,7 @@ ssh_helper=<strong>උදව් අවශ්යද?</strong> GitHub හි ම
|
|||||||
gpg_helper=<strong>උදව් අවශ්යද?</strong> GPG</a>ගැන GitHub හි මාර්ගෝපදේශය <a href="%s">දෙස බලන්න.
|
gpg_helper=<strong>උදව් අවශ්යද?</strong> GPG</a>ගැන GitHub හි මාර්ගෝපදේශය <a href="%s">දෙස බලන්න.
|
||||||
add_new_key=SSH යතුර එක්කරන්න
|
add_new_key=SSH යතුර එක්කරන්න
|
||||||
add_new_gpg_key=ජීපීජී යතුර එක්කරන්න
|
add_new_gpg_key=ජීපීජී යතුර එක්කරන්න
|
||||||
key_content_ssh_placeholder=ආරම්භ වන්නේ 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', හෝ 'sk-ssh-ed25519@openssh.com
|
key_content_ssh_placeholder=ආරම්භ වන්නේ 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', හෝ 'sk-ssh-ed25519@openssh.com'
|
||||||
key_content_gpg_placeholder=ආරම්භ වන්නේ '-ආරම්භ කරන්න PGP පොදු ප්රධාන බ්ලොක්—'
|
key_content_gpg_placeholder=ආරම්භ වන්නේ '-ආරම්භ කරන්න PGP පොදු ප්රධාන බ්ලොක්—'
|
||||||
add_new_principal=විදුහල්පති එකතු කරන්න
|
add_new_principal=විදුහල්පති එකතු කරන්න
|
||||||
ssh_key_been_used=මෙම SSH යතුර දැනටමත් සේවාදායකයට එකතු කර ඇත.
|
ssh_key_been_used=මෙම SSH යතුර දැනටමත් සේවාදායකයට එකතු කර ඇත.
|
||||||
@@ -810,44 +810,8 @@ delete_preexisting_success=%sදී සම්මත නොකළ ගොනු
|
|||||||
blame_prior=මෙම වෙනසට පෙර දොස් බලන්න
|
blame_prior=මෙම වෙනසට පෙර දොස් බලන්න
|
||||||
|
|
||||||
transfer.accept=මාරු කිරීම පිළිගන්න
|
transfer.accept=මාරු කිරීම පිළිගන්න
|
||||||
transfer.accept_desc="%s\" වෙත මාරු කරන්න
|
transfer.accept_desc="%s" වෙත මාරු කරන්න
|
||||||
transfer.reject=මාරු කිරීම ප්රතික්ෂේප කරන්න
|
transfer.reject_desc="%s" වෙත මාරු කිරීම අවලංගු කරන්න
|
||||||
transfer.reject_desc=“%s” වෙත මාරු කිරීම අවලංගු කරන්න
|
|
||||||
transfer.no_permission_to_accept=ඔබට පිළිගැනීමට අවසර නැත
|
|
||||||
transfer.no_permission_to_reject=ප්රතික්ෂේප කිරීමට ඔබට අවසර නැත
|
|
||||||
|
|
||||||
desc.private=පෞද්ගලික
|
|
||||||
desc.public=පොදු
|
|
||||||
desc.private_template=පෞද්ගලික අච්චුව
|
|
||||||
desc.public_template=සැකිල්ල
|
|
||||||
desc.internal=අභ්යන්තර
|
|
||||||
desc.internal_template=අභ්යන්තර සැකිල්ල
|
|
||||||
desc.archived=සංරක්ෂිත
|
|
||||||
|
|
||||||
template.items=සැකිලි අයිතම
|
|
||||||
template.git_content=Git අන්තර්ගතය (පෙරනිමි ශාඛාව)
|
|
||||||
template.git_hooks=ගොතන ලද කොකු
|
|
||||||
template.git_hooks_tooltip=එකතු කළ පසු git කොකු වෙනස් කිරීමට හෝ ඉවත් කිරීමට ඔබට දැනට නොහැකි වේ. ඔබ සැකිලි ගබඩාව විශ්වාස කරන්නේ නම් පමණක් මෙය තෝරන්න.
|
|
||||||
template.webhooks=වෙබ්කොකු
|
|
||||||
template.topics=මාතෘකා
|
|
||||||
template.avatar=අවතාර්
|
|
||||||
template.issue_labels=නිකුත් ලේබල
|
|
||||||
template.one_item=අවම වශයෙන් එක් සැකිලි අයිතමයක් තෝරා ගත යුතුය
|
|
||||||
template.invalid=සැකිලි ගබඩාවක් තෝරා ගත යුතුය
|
|
||||||
|
|
||||||
archive.title=මෙම රෙපෝව සංරක්ෂණය කර ඇත. ඔබ ගොනු බැලීම හා පරිගණක ක්රිඩාවට සමාන කළ හැකි, නමුත් ගැටළු/අදින්න-ඉල්ලීම් තල්ලු හෝ විවෘත කළ නොහැක.
|
|
||||||
archive.issue.nocomment=මෙම රෙපෝව සංරක්ෂණය කර ඇත. ඔබට ගැටළු පිළිබඳව අදහස් දැක්විය නොහැක.
|
|
||||||
archive.pull.nocomment=මෙම රෙපෝව සංරක්ෂණය කර ඇත. ඔබට අදින්න ඉල්ලීම් මත අදහස් දැක්විය නොහැක.
|
|
||||||
|
|
||||||
form.reach_limit_of_creation_1=ඔබ දැනටමත් ඔබගේ %d ගබඩාවේ සීමාවට පැමිණ ඇත.
|
|
||||||
form.reach_limit_of_creation_n=ඔබ දැනටමත් ඔබගේ ගබඩාවේ %d සීමාවට පැමිණ ඇත.
|
|
||||||
form.name_reserved=නිධි නාමය '%s' වෙන් කර ඇත.
|
|
||||||
form.name_pattern_not_allowed='%s' රටාව ගබඩාවක නාමයකින් අවසර නැත.
|
|
||||||
|
|
||||||
need_auth=බලය පැවරීම
|
|
||||||
migrate_options=සංක්රමණ විකල්ප
|
|
||||||
migrate_service=සංක්රමණ සේවා
|
|
||||||
migrate_options_mirror_helper="
|
|
||||||
|
|
||||||
desc.private=පෞද්ගලික
|
desc.private=පෞද්ගලික
|
||||||
desc.public=ප්රසිද්ධ
|
desc.public=ප්රසිද්ධ
|
||||||
@@ -1236,7 +1200,7 @@ issues.label.filter_sort.reverse_alphabetically=අකාරාදී ප්ර
|
|||||||
issues.label.filter_sort.by_size=කුඩාම ප්රමාණය
|
issues.label.filter_sort.by_size=කුඩාම ප්රමාණය
|
||||||
issues.label.filter_sort.reverse_by_size=විශාලම ප්රමාණය
|
issues.label.filter_sort.reverse_by_size=විශාලම ප්රමාණය
|
||||||
issues.num_participants=සහභාගිවන්නන් %d
|
issues.num_participants=සහභාගිවන්නන් %d
|
||||||
issues.attachment.open_tab='නව වගුවක "%s" බැලීමට ක්ලික් කරන්න
|
issues.attachment.open_tab=`නව වගුවක "%s" බැලීමට ක්ලික් කරන්න`
|
||||||
issues.attachment.download=`"%s“ බාගැනීමට ඔබන්න`
|
issues.attachment.download=`"%s“ බාගැනීමට ඔබන්න`
|
||||||
issues.subscribe=දායක වන්න
|
issues.subscribe=දායක වන්න
|
||||||
issues.unsubscribe=දායක වන්න
|
issues.unsubscribe=දායක වන්න
|
||||||
@@ -1373,11 +1337,11 @@ pulls.filter_branch=ශාඛාව පෙරන්න
|
|||||||
pulls.no_results=ප්රතිඵල සොයාගත නොහැකි විය.
|
pulls.no_results=ප්රතිඵල සොයාගත නොහැකි විය.
|
||||||
pulls.nothing_to_compare=මෙම ශාඛා සමාන වේ. අදින්න ඉල්ලීමක් නිර්මාණය කිරීමට අවශ්ය නැත.
|
pulls.nothing_to_compare=මෙම ශාඛා සමාන වේ. අදින්න ඉල්ලීමක් නිර්මාණය කිරීමට අවශ්ය නැත.
|
||||||
pulls.nothing_to_compare_and_allow_empty_pr=මෙම ශාඛා සමාන වේ. මෙම මහජන සම්බන්ධතා හිස් වනු ඇත.
|
pulls.nothing_to_compare_and_allow_empty_pr=මෙම ශාඛා සමාන වේ. මෙම මහජන සම්බන්ධතා හිස් වනු ඇත.
|
||||||
pulls.has_pull_request='මෙම ශාඛා අතර අදින්න ඉල්ලීම දැනටමත් පවතී: <a href="%[1]s">%[2]s #%[3]d</a>`
|
pulls.has_pull_request=`මෙම ශාඛා අතර අදින්න ඉල්ලීම දැනටමත් පවතී: <a href="%[1]s">%[2]s #%[3]d</a>`
|
||||||
pulls.create=අදින්න ඉල්ලීම නිර්මාණය
|
pulls.create=අදින්න ඉල්ලීම නිර්මාණය
|
||||||
pulls.title_desc=%[1]d සිට <code>%[2]s</code> දක්වා <code id="branch_target">%[3]s</code>
|
pulls.title_desc=%[1]d සිට <code>%[2]s</code> දක්වා <code id="branch_target">%[3]s</code>
|
||||||
pulls.merged_title_desc=මර්ජ්%[1]d සිට <code>%[2]s</code> දක්වා <code>%[3]s</code> %[4]s
|
pulls.merged_title_desc=මර්ජ්%[1]d සිට <code>%[2]s</code> දක්වා <code>%[3]s</code> %[4]s
|
||||||
pulls.change_target_branch_at='ඉලක්කගත ශාඛාව <b>%s</b> සිට <b>%s</b> %sදක්වා වෙනස් කර ඇත
|
pulls.change_target_branch_at=`ඉලක්කගත ශාඛාව <b>%s</b> සිට <b>%s</b> %sදක්වා වෙනස් කර ඇත`
|
||||||
pulls.tab_conversation=සංවාදය
|
pulls.tab_conversation=සංවාදය
|
||||||
pulls.tab_commits=විවරයන්
|
pulls.tab_commits=විවරයන්
|
||||||
pulls.tab_files=වෙනස් වූ ගොනු
|
pulls.tab_files=වෙනස් වූ ගොනු
|
||||||
@@ -2715,7 +2679,7 @@ create_pull_request=`නිර්මාණය අදින්න ඉල්ලී
|
|||||||
close_pull_request=`closed අදින්න ඉල්ලීම <a href="%[1]s">%[3]s #%[2]s</a>`
|
close_pull_request=`closed අදින්න ඉල්ලීම <a href="%[1]s">%[3]s #%[2]s</a>`
|
||||||
reopen_pull_request=`නැවත විවෘත කරන ලද අදින්න ඉල්ලීම <a href="%[1]s">%[3]s #%[2]s</a>`
|
reopen_pull_request=`නැවත විවෘත කරන ලද අදින්න ඉල්ලීම <a href="%[1]s">%[3]s #%[2]s</a>`
|
||||||
comment_issue=`නිකුතුව පිළිබඳ අදහස් <a href="%[1]s">%[3]s #%[2]s</a>`
|
comment_issue=`නිකුතුව පිළිබඳ අදහස් <a href="%[1]s">%[3]s #%[2]s</a>`
|
||||||
comment_pull='අදින්න ඉල්ලීම මත අදහස් <a href="%[1]s">%[3]s #%[2]s</a>`
|
comment_pull=`අදින්න ඉල්ලීම මත අදහස් <a href="%[1]s">%[3]s #%[2]s</a>`
|
||||||
merge_pull_request=`ඒකාබද්ධ අදින්න ඉල්ලීම <a href="%[1]s">%[3]s #%[2]s</a>`
|
merge_pull_request=`ඒකාබද්ධ අදින්න ඉල්ලීම <a href="%[1]s">%[3]s #%[2]s</a>`
|
||||||
transfer_repo=මාරු කරන ලද ගබඩාව <code>%s</code> සිට <a href="%s">%s</a>
|
transfer_repo=මාරු කරන ලද ගබඩාව <code>%s</code> සිට <a href="%s">%s</a>
|
||||||
push_tag=තල්ලු ටැගය <a href="%[2]s">%[3]ගේ</a> <a href="%[1]s">%[4]ගේ</a>
|
push_tag=තල්ලු ටැගය <a href="%[2]s">%[3]ගේ</a> <a href="%[1]s">%[4]ගේ</a>
|
||||||
@@ -2729,7 +2693,7 @@ mirror_sync_create=සමමුහුර්ත නව යොමු <a href="%[2]
|
|||||||
mirror_sync_delete=සමමුහුර්ත සහ මකාදැමූ යොමු <code>%[2]s</code> හි <a href="%[1]s">%[3]s</a> කැඩපතෙන්
|
mirror_sync_delete=සමමුහුර්ත සහ මකාදැමූ යොමු <code>%[2]s</code> හි <a href="%[1]s">%[3]s</a> කැඩපතෙන්
|
||||||
approve_pull_request=`අනුමත <a href="%[1]s">%[3]s #%[2]ගේ</a>`
|
approve_pull_request=`අනුමත <a href="%[1]s">%[3]s #%[2]ගේ</a>`
|
||||||
reject_pull_request=<a href="%[1]s">%[3]s #%[2]s</a>සඳහා යෝජිත වෙනස්කම්
|
reject_pull_request=<a href="%[1]s">%[3]s #%[2]s</a>සඳහා යෝජිත වෙනස්කම්
|
||||||
publish_release=`නිදහස් <a href="%[2]s"> “%[4]s” </a> හි <a href="%[1]s">%[3]s</a>
|
publish_release=`නිදහස් <a href="%[2]s"> "%[4]s" </a> හි <a href="%[1]s">%[3]s</a>`
|
||||||
review_dismissed_reason=හේතුව:
|
review_dismissed_reason=හේතුව:
|
||||||
create_branch=නිර්මාණය කරන ලද ශාඛාව <a href="%[2]s">%[3]s</a> <a href="%[1]s">%[4]s</a>
|
create_branch=නිර්මාණය කරන ලද ශාඛාව <a href="%[2]s">%[3]s</a> <a href="%[1]s">%[4]s</a>
|
||||||
watched_repo=<a href="%[1]s">%[2]s</a>නැරඹීමට පටන් ගත්තා
|
watched_repo=<a href="%[1]s">%[2]s</a>නැරඹීමට පටන් ගත්තා
|
||||||
|
|||||||
@@ -491,7 +491,10 @@ func serviceRPC(h serviceHandler, service string) {
|
|||||||
defer finished()
|
defer finished()
|
||||||
|
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
cmd := exec.CommandContext(ctx, git.GitExecutable, service, "--stateless-rpc", h.dir)
|
args := make([]string, len(git.GlobalCommandArgs))
|
||||||
|
copy(args, git.GlobalCommandArgs)
|
||||||
|
args = append(args, []string{service, "--stateless-rpc", h.dir}...)
|
||||||
|
cmd := exec.CommandContext(ctx, git.GitExecutable, args...)
|
||||||
cmd.Dir = h.dir
|
cmd.Dir = h.dir
|
||||||
cmd.Env = append(os.Environ(), h.environ...)
|
cmd.Env = append(os.Environ(), h.environ...)
|
||||||
cmd.Stdout = h.w
|
cmd.Stdout = h.w
|
||||||
|
|||||||
@@ -802,7 +802,7 @@ func NewIssue(ctx *context.Context) {
|
|||||||
|
|
||||||
milestoneID := ctx.FormInt64("milestone")
|
milestoneID := ctx.FormInt64("milestone")
|
||||||
if milestoneID > 0 {
|
if milestoneID > 0 {
|
||||||
milestone, err := models.GetMilestoneByID(milestoneID)
|
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, milestoneID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetMilestoneByID: %d: %v", milestoneID, err)
|
log.Error("GetMilestoneByID: %d: %v", milestoneID, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -889,7 +889,7 @@ func ValidateRepoMetas(ctx *context.Context, form forms.CreateIssueForm, isPull
|
|||||||
// Check milestone.
|
// Check milestone.
|
||||||
milestoneID := form.MilestoneID
|
milestoneID := form.MilestoneID
|
||||||
if milestoneID > 0 {
|
if milestoneID > 0 {
|
||||||
milestone, err := models.GetMilestoneByID(milestoneID)
|
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, milestoneID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetMilestoneByID", err)
|
ctx.ServerError("GetMilestoneByID", err)
|
||||||
return nil, nil, 0, 0
|
return nil, nil, 0, 0
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ func DeleteMilestone(ctx *context.Context) {
|
|||||||
// MilestoneIssuesAndPulls lists all the issues and pull requests of the milestone
|
// MilestoneIssuesAndPulls lists all the issues and pull requests of the milestone
|
||||||
func MilestoneIssuesAndPulls(ctx *context.Context) {
|
func MilestoneIssuesAndPulls(ctx *context.Context) {
|
||||||
milestoneID := ctx.ParamsInt64(":id")
|
milestoneID := ctx.ParamsInt64(":id")
|
||||||
milestone, err := models.GetMilestoneByID(milestoneID)
|
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, milestoneID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrMilestoneNotExist(err) {
|
if models.IsErrMilestoneNotExist(err) {
|
||||||
ctx.NotFound("GetMilestoneByID", err)
|
ctx.NotFound("GetMilestoneByID", err)
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GitlabDownloaderFactory defines a gitlab downloader factory
|
// GitlabDownloaderFactory defines a gitlab downloader factory
|
||||||
type GitlabDownloaderFactory struct {
|
type GitlabDownloaderFactory struct{}
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a Downloader related to this factory according MigrateOptions
|
// New returns a Downloader related to this factory according MigrateOptions
|
||||||
func (f *GitlabDownloaderFactory) New(ctx context.Context, opts base.MigrateOptions) (base.Downloader, error) {
|
func (f *GitlabDownloaderFactory) New(ctx context.Context, opts base.MigrateOptions) (base.Downloader, error) {
|
||||||
@@ -184,16 +183,17 @@ func (g *GitlabDownloader) GetTopics() ([]string, error) {
|
|||||||
|
|
||||||
// GetMilestones returns milestones
|
// GetMilestones returns milestones
|
||||||
func (g *GitlabDownloader) GetMilestones() ([]*base.Milestone, error) {
|
func (g *GitlabDownloader) GetMilestones() ([]*base.Milestone, error) {
|
||||||
var perPage = g.maxPerPage
|
perPage := g.maxPerPage
|
||||||
var state = "all"
|
state := "all"
|
||||||
var milestones = make([]*base.Milestone, 0, perPage)
|
milestones := make([]*base.Milestone, 0, perPage)
|
||||||
for i := 1; ; i++ {
|
for i := 1; ; i++ {
|
||||||
ms, _, err := g.client.Milestones.ListMilestones(g.repoID, &gitlab.ListMilestonesOptions{
|
ms, _, err := g.client.Milestones.ListMilestones(g.repoID, &gitlab.ListMilestonesOptions{
|
||||||
State: &state,
|
State: &state,
|
||||||
ListOptions: gitlab.ListOptions{
|
ListOptions: gitlab.ListOptions{
|
||||||
Page: i,
|
Page: i,
|
||||||
PerPage: perPage,
|
PerPage: perPage,
|
||||||
}}, nil, gitlab.WithContext(g.ctx))
|
},
|
||||||
|
}, nil, gitlab.WithContext(g.ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -203,7 +203,7 @@ func (g *GitlabDownloader) GetMilestones() ([]*base.Milestone, error) {
|
|||||||
if m.Description != "" {
|
if m.Description != "" {
|
||||||
desc = m.Description
|
desc = m.Description
|
||||||
}
|
}
|
||||||
var state = "open"
|
state := "open"
|
||||||
var closedAt *time.Time
|
var closedAt *time.Time
|
||||||
if m.State != "" {
|
if m.State != "" {
|
||||||
state = m.State
|
state = m.State
|
||||||
@@ -255,8 +255,8 @@ func (g *GitlabDownloader) normalizeColor(val string) string {
|
|||||||
|
|
||||||
// GetLabels returns labels
|
// GetLabels returns labels
|
||||||
func (g *GitlabDownloader) GetLabels() ([]*base.Label, error) {
|
func (g *GitlabDownloader) GetLabels() ([]*base.Label, error) {
|
||||||
var perPage = g.maxPerPage
|
perPage := g.maxPerPage
|
||||||
var labels = make([]*base.Label, 0, perPage)
|
labels := make([]*base.Label, 0, perPage)
|
||||||
for i := 1; ; i++ {
|
for i := 1; ; i++ {
|
||||||
ls, _, err := g.client.Labels.ListLabels(g.repoID, &gitlab.ListLabelsOptions{ListOptions: gitlab.ListOptions{
|
ls, _, err := g.client.Labels.ListLabels(g.repoID, &gitlab.ListLabelsOptions{ListOptions: gitlab.ListOptions{
|
||||||
Page: i,
|
Page: i,
|
||||||
@@ -327,8 +327,8 @@ func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Relea
|
|||||||
|
|
||||||
// GetReleases returns releases
|
// GetReleases returns releases
|
||||||
func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) {
|
func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) {
|
||||||
var perPage = g.maxPerPage
|
perPage := g.maxPerPage
|
||||||
var releases = make([]*base.Release, 0, perPage)
|
releases := make([]*base.Release, 0, perPage)
|
||||||
for i := 1; ; i++ {
|
for i := 1; ; i++ {
|
||||||
ls, _, err := g.client.Releases.ListReleases(g.repoID, &gitlab.ListReleasesOptions{
|
ls, _, err := g.client.Releases.ListReleases(g.repoID, &gitlab.ListReleasesOptions{
|
||||||
Page: i,
|
Page: i,
|
||||||
@@ -381,7 +381,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var allIssues = make([]*base.Issue, 0, perPage)
|
allIssues := make([]*base.Issue, 0, perPage)
|
||||||
|
|
||||||
issues, _, err := g.client.Issues.ListProjectIssues(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
|
issues, _, err := g.client.Issues.ListProjectIssues(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -389,7 +389,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
|
|||||||
}
|
}
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
|
|
||||||
var labels = make([]*base.Label, 0, len(issue.Labels))
|
labels := make([]*base.Label, 0, len(issue.Labels))
|
||||||
for _, l := range issue.Labels {
|
for _, l := range issue.Labels {
|
||||||
labels = append(labels, &base.Label{
|
labels = append(labels, &base.Label{
|
||||||
Name: l,
|
Name: l,
|
||||||
@@ -402,7 +402,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
var reactions []*base.Reaction
|
var reactions []*base.Reaction
|
||||||
var awardPage = 1
|
awardPage := 1
|
||||||
for {
|
for {
|
||||||
awards, _, err := g.client.AwardEmoji.ListIssueAwardEmoji(g.repoID, issue.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx))
|
awards, _, err := g.client.AwardEmoji.ListIssueAwardEmoji(g.repoID, issue.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -456,9 +456,9 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
|
|||||||
return nil, false, fmt.Errorf("unexpected context: %+v", opts.Context)
|
return nil, false, fmt.Errorf("unexpected context: %+v", opts.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
var allComments = make([]*base.Comment, 0, g.maxPerPage)
|
allComments := make([]*base.Comment, 0, g.maxPerPage)
|
||||||
|
|
||||||
var page = 1
|
page := 1
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var comments []*gitlab.Discussion
|
var comments []*gitlab.Discussion
|
||||||
@@ -503,7 +503,6 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
|
|||||||
Created: *c.CreatedAt,
|
Created: *c.CreatedAt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if resp.NextPage == 0 {
|
if resp.NextPage == 0 {
|
||||||
break
|
break
|
||||||
@@ -526,7 +525,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var allPRs = make([]*base.PullRequest, 0, perPage)
|
allPRs := make([]*base.PullRequest, 0, perPage)
|
||||||
|
|
||||||
prs, _, err := g.client.MergeRequests.ListProjectMergeRequests(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
|
prs, _, err := g.client.MergeRequests.ListProjectMergeRequests(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -534,7 +533,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
|
|||||||
}
|
}
|
||||||
for _, pr := range prs {
|
for _, pr := range prs {
|
||||||
|
|
||||||
var labels = make([]*base.Label, 0, len(pr.Labels))
|
labels := make([]*base.Label, 0, len(pr.Labels))
|
||||||
for _, l := range pr.Labels {
|
for _, l := range pr.Labels {
|
||||||
labels = append(labels, &base.Label{
|
labels = append(labels, &base.Label{
|
||||||
Name: l,
|
Name: l,
|
||||||
@@ -547,12 +546,12 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
|
|||||||
pr.State = "closed"
|
pr.State = "closed"
|
||||||
}
|
}
|
||||||
|
|
||||||
var mergeTime = pr.MergedAt
|
mergeTime := pr.MergedAt
|
||||||
if merged && pr.MergedAt == nil {
|
if merged && pr.MergedAt == nil {
|
||||||
mergeTime = pr.UpdatedAt
|
mergeTime = pr.UpdatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
var closeTime = pr.ClosedAt
|
closeTime := pr.ClosedAt
|
||||||
if merged && pr.ClosedAt == nil {
|
if merged && pr.ClosedAt == nil {
|
||||||
closeTime = pr.UpdatedAt
|
closeTime = pr.UpdatedAt
|
||||||
}
|
}
|
||||||
@@ -568,7 +567,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
|
|||||||
}
|
}
|
||||||
|
|
||||||
var reactions []*base.Reaction
|
var reactions []*base.Reaction
|
||||||
var awardPage = 1
|
awardPage := 1
|
||||||
for {
|
for {
|
||||||
awards, _, err := g.client.AwardEmoji.ListMergeRequestAwardEmoji(g.repoID, pr.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx))
|
awards, _, err := g.client.AwardEmoji.ListMergeRequestAwardEmoji(g.repoID, pr.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -641,13 +640,22 @@ func (g *GitlabDownloader) GetReviews(context base.IssueContext) ([]*base.Review
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var reviews = make([]*base.Review, 0, len(approvals.ApprovedBy))
|
var createdAt time.Time
|
||||||
|
if approvals.CreatedAt != nil {
|
||||||
|
createdAt = *approvals.CreatedAt
|
||||||
|
} else if approvals.UpdatedAt != nil {
|
||||||
|
createdAt = *approvals.UpdatedAt
|
||||||
|
} else {
|
||||||
|
createdAt = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
reviews := make([]*base.Review, 0, len(approvals.ApprovedBy))
|
||||||
for _, user := range approvals.ApprovedBy {
|
for _, user := range approvals.ApprovedBy {
|
||||||
reviews = append(reviews, &base.Review{
|
reviews = append(reviews, &base.Review{
|
||||||
IssueIndex: context.LocalID(),
|
IssueIndex: context.LocalID(),
|
||||||
ReviewerID: int64(user.User.ID),
|
ReviewerID: int64(user.User.ID),
|
||||||
ReviewerName: user.User.Username,
|
ReviewerName: user.User.Username,
|
||||||
CreatedAt: *approvals.UpdatedAt,
|
CreatedAt: createdAt,
|
||||||
// All we get are approvals
|
// All we get are approvals
|
||||||
State: base.ReviewStateApproved,
|
State: base.ReviewStateApproved,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,13 +8,16 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
base "code.gitea.io/gitea/modules/migration"
|
base "code.gitea.io/gitea/modules/migration"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/xanzy/go-gitlab"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGitlabDownloadRepo(t *testing.T) {
|
func TestGitlabDownloadRepo(t *testing.T) {
|
||||||
@@ -310,12 +313,14 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assertReviewsEqual(t, []*base.Review{
|
assertReviewsEqual(t, []*base.Review{
|
||||||
{
|
{
|
||||||
|
IssueIndex: 1,
|
||||||
ReviewerID: 4102996,
|
ReviewerID: 4102996,
|
||||||
ReviewerName: "zeripath",
|
ReviewerName: "zeripath",
|
||||||
CreatedAt: time.Date(2019, 11, 28, 16, 2, 8, 377000000, time.UTC),
|
CreatedAt: time.Date(2019, 11, 28, 16, 2, 8, 377000000, time.UTC),
|
||||||
State: "APPROVED",
|
State: "APPROVED",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
IssueIndex: 1,
|
||||||
ReviewerID: 527793,
|
ReviewerID: 527793,
|
||||||
ReviewerName: "axifive",
|
ReviewerName: "axifive",
|
||||||
CreatedAt: time.Date(2019, 11, 28, 16, 2, 8, 377000000, time.UTC),
|
CreatedAt: time.Date(2019, 11, 28, 16, 2, 8, 377000000, time.UTC),
|
||||||
@@ -327,6 +332,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assertReviewsEqual(t, []*base.Review{
|
assertReviewsEqual(t, []*base.Review{
|
||||||
{
|
{
|
||||||
|
IssueIndex: 2,
|
||||||
ReviewerID: 4575606,
|
ReviewerID: 4575606,
|
||||||
ReviewerName: "real6543",
|
ReviewerName: "real6543",
|
||||||
CreatedAt: time.Date(2020, 4, 19, 19, 24, 21, 108000000, time.UTC),
|
CreatedAt: time.Date(2020, 4, 19, 19, 24, 21, 108000000, time.UTC),
|
||||||
@@ -334,3 +340,137 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}, rvs)
|
}, rvs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func gitlabClientMockSetup(t *testing.T) (*http.ServeMux, *httptest.Server, *gitlab.Client) {
|
||||||
|
// mux is the HTTP request multiplexer used with the test server.
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
|
// server is a test HTTP server used to provide mock API responses.
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
|
||||||
|
// client is the Gitlab client being tested.
|
||||||
|
client, err := gitlab.NewClient("", gitlab.WithBaseURL(server.URL))
|
||||||
|
if err != nil {
|
||||||
|
server.Close()
|
||||||
|
t.Fatalf("Failed to create client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mux, server, client
|
||||||
|
}
|
||||||
|
|
||||||
|
func gitlabClientMockTeardown(server *httptest.Server) {
|
||||||
|
server.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
type reviewTestCase struct {
|
||||||
|
repoID, prID, reviewerID int
|
||||||
|
reviewerName string
|
||||||
|
createdAt, updatedAt *time.Time
|
||||||
|
expectedCreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertTestCase(t reviewTestCase) (func(w http.ResponseWriter, r *http.Request), base.Review) {
|
||||||
|
var updatedAtField string
|
||||||
|
if t.updatedAt == nil {
|
||||||
|
updatedAtField = ""
|
||||||
|
} else {
|
||||||
|
updatedAtField = `"updated_at": "` + t.updatedAt.Format(time.RFC3339) + `",`
|
||||||
|
}
|
||||||
|
|
||||||
|
var createdAtField string
|
||||||
|
if t.createdAt == nil {
|
||||||
|
createdAtField = ""
|
||||||
|
} else {
|
||||||
|
createdAtField = `"created_at": "` + t.createdAt.Format(time.RFC3339) + `",`
|
||||||
|
}
|
||||||
|
|
||||||
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Fprint(w, `
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"iid": `+strconv.Itoa(t.prID)+`,
|
||||||
|
"project_id": `+strconv.Itoa(t.repoID)+`,
|
||||||
|
"title": "Approvals API",
|
||||||
|
"description": "Test",
|
||||||
|
"state": "opened",
|
||||||
|
`+createdAtField+`
|
||||||
|
`+updatedAtField+`
|
||||||
|
"merge_status": "cannot_be_merged",
|
||||||
|
"approvals_required": 2,
|
||||||
|
"approvals_left": 1,
|
||||||
|
"approved_by": [
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"name": "Administrator",
|
||||||
|
"username": "`+t.reviewerName+`",
|
||||||
|
"id": `+strconv.Itoa(t.reviewerID)+`,
|
||||||
|
"state": "active",
|
||||||
|
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",
|
||||||
|
"web_url": "http://localhost:3000/root"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`)
|
||||||
|
}
|
||||||
|
review := base.Review{
|
||||||
|
IssueIndex: int64(t.prID),
|
||||||
|
ReviewerID: int64(t.reviewerID),
|
||||||
|
ReviewerName: t.reviewerName,
|
||||||
|
CreatedAt: t.expectedCreatedAt,
|
||||||
|
State: "APPROVED",
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler, review
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitlabGetReviews(t *testing.T) {
|
||||||
|
mux, server, client := gitlabClientMockSetup(t)
|
||||||
|
defer gitlabClientMockTeardown(server)
|
||||||
|
|
||||||
|
repoID := 1324
|
||||||
|
|
||||||
|
downloader := &GitlabDownloader{
|
||||||
|
ctx: context.Background(),
|
||||||
|
client: client,
|
||||||
|
repoID: repoID,
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAt := time.Date(2020, 4, 19, 19, 24, 21, 0, time.UTC)
|
||||||
|
|
||||||
|
for _, testCase := range []reviewTestCase{
|
||||||
|
{
|
||||||
|
repoID: repoID,
|
||||||
|
prID: 1,
|
||||||
|
reviewerID: 801,
|
||||||
|
reviewerName: "someone1",
|
||||||
|
createdAt: nil,
|
||||||
|
updatedAt: &createdAt,
|
||||||
|
expectedCreatedAt: createdAt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
repoID: repoID,
|
||||||
|
prID: 2,
|
||||||
|
reviewerID: 802,
|
||||||
|
reviewerName: "someone2",
|
||||||
|
createdAt: &createdAt,
|
||||||
|
updatedAt: nil,
|
||||||
|
expectedCreatedAt: createdAt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
repoID: repoID,
|
||||||
|
prID: 3,
|
||||||
|
reviewerID: 803,
|
||||||
|
reviewerName: "someone3",
|
||||||
|
createdAt: nil,
|
||||||
|
updatedAt: nil,
|
||||||
|
expectedCreatedAt: time.Now(),
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
mock, review := convertTestCase(testCase)
|
||||||
|
mux.HandleFunc(fmt.Sprintf("/api/v4/projects/%d/merge_requests/%d/approvals", testCase.repoID, testCase.prID), mock)
|
||||||
|
|
||||||
|
rvs, err := downloader.GetReviews(base.BasicIssueContext(testCase.prID))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assertReviewsEqual(t, []*base.Review{&review}, rvs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -223,15 +223,15 @@ func assertRepositoryEqual(t *testing.T, expected, actual *base.Repository) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func assertReviewEqual(t *testing.T, expected, actual *base.Review) {
|
func assertReviewEqual(t *testing.T, expected, actual *base.Review) {
|
||||||
assert.Equal(t, expected.ID, actual.ID)
|
assert.Equal(t, expected.ID, actual.ID, "ID")
|
||||||
assert.Equal(t, expected.IssueIndex, actual.IssueIndex)
|
assert.Equal(t, expected.IssueIndex, actual.IssueIndex, "IsssueIndex")
|
||||||
assert.Equal(t, expected.ReviewerID, actual.ReviewerID)
|
assert.Equal(t, expected.ReviewerID, actual.ReviewerID, "ReviewerID")
|
||||||
assert.Equal(t, expected.ReviewerName, actual.ReviewerName)
|
assert.Equal(t, expected.ReviewerName, actual.ReviewerName, "ReviewerName")
|
||||||
assert.Equal(t, expected.Official, actual.Official)
|
assert.Equal(t, expected.Official, actual.Official, "Official")
|
||||||
assert.Equal(t, expected.CommitID, actual.CommitID)
|
assert.Equal(t, expected.CommitID, actual.CommitID, "CommitID")
|
||||||
assert.Equal(t, expected.Content, actual.Content)
|
assert.Equal(t, expected.Content, actual.Content, "Content")
|
||||||
assertTimeEqual(t, expected.CreatedAt, actual.CreatedAt)
|
assert.WithinDuration(t, expected.CreatedAt, actual.CreatedAt, 10*time.Second)
|
||||||
assert.Equal(t, expected.State, actual.State)
|
assert.Equal(t, expected.State, actual.State, "State")
|
||||||
assertReviewCommentsEqual(t, expected.Comments, actual.Comments)
|
assertReviewCommentsEqual(t, expected.Comments, actual.Comments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,9 @@ func (r *RepositoryRestorer) GetTopics() ([]string, error) {
|
|||||||
|
|
||||||
bs, err := os.ReadFile(p)
|
bs, err := os.ReadFile(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -286,6 +286,10 @@
|
|||||||
<input id="skip_local_two_fa" name="skip_local_two_fa" type="checkbox" {{if $cfg.SkipLocalTwoFA}}checked{{end}}>
|
<input id="skip_local_two_fa" name="skip_local_two_fa" type="checkbox" {{if $cfg.SkipLocalTwoFA}}checked{{end}}>
|
||||||
<p class="help">{{.i18n.Tr "admin.auths.skip_local_two_fa_helper"}}</p>
|
<p class="help">{{.i18n.Tr "admin.auths.skip_local_two_fa_helper"}}</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="oauth2_use_custom_url inline field">
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<label><strong>{{.i18n.Tr "admin.auths.oauth2_use_custom_url"}}</strong></label>
|
||||||
<input id="oauth2_use_custom_url" name="oauth2_use_custom_url" type="checkbox" {{if $cfg.CustomURLMapping}}checked{{end}}>
|
<input id="oauth2_use_custom_url" name="oauth2_use_custom_url" type="checkbox" {{if $cfg.CustomURLMapping}}checked{{end}}>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -75,7 +75,11 @@
|
|||||||
<pre class="commit-body" style="display: none;">{{RenderCommitBody .Message $commitRepoLink $.Repository.ComposeMetas}}</pre>
|
<pre class="commit-body" style="display: none;">{{RenderCommitBody .Message $commitRepoLink $.Repository.ComposeMetas}}</pre>
|
||||||
{{end}}
|
{{end}}
|
||||||
</td>
|
</td>
|
||||||
<td class="text right aligned">{{TimeSince .Author.When $.Lang}}</td>
|
{{if .Committer}}
|
||||||
|
<td class="text right aligned">{{TimeSince .Committer.When $.Lang}}</td>
|
||||||
|
{{else}}
|
||||||
|
<td class="text right aligned">{{TimeSince .Author.When $.Lang}}</td>
|
||||||
|
{{end}}
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</th>
|
</th>
|
||||||
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Author}}{{TimeSince .LatestCommit.Author.When $.Lang}}{{end}}{{end}}</th>
|
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Committer}}{{TimeSince .LatestCommit.Committer.When $.Lang}}{{end}}{{end}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -496,9 +496,11 @@ export function initRepoPullRequestReview() {
|
|||||||
<tr class="add-comment" data-line-type="${lineType}">
|
<tr class="add-comment" data-line-type="${lineType}">
|
||||||
${isSplit ? `
|
${isSplit ? `
|
||||||
<td class="lines-num"></td>
|
<td class="lines-num"></td>
|
||||||
|
<td class="lines-escape"></td>
|
||||||
<td class="lines-type-marker"></td>
|
<td class="lines-type-marker"></td>
|
||||||
<td class="add-comment-left"></td>
|
<td class="add-comment-left"></td>
|
||||||
<td class="lines-num"></td>
|
<td class="lines-num"></td>
|
||||||
|
<td class="lines-escape"></td>
|
||||||
<td class="lines-type-marker"></td>
|
<td class="lines-type-marker"></td>
|
||||||
<td class="add-comment-right"></td>
|
<td class="add-comment-right"></td>
|
||||||
` : `
|
` : `
|
||||||
|
|||||||
@@ -150,13 +150,12 @@ export function initUserAuthWebAuthnRegister() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!detectWebAuthnSupport()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#webauthn-error').modal({allowMultiple: false});
|
$('#webauthn-error').modal({allowMultiple: false});
|
||||||
$('#register-webauthn').on('click', (e) => {
|
$('#register-webauthn').on('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if (!detectWebAuthnSupport()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
webAuthnRegisterRequest();
|
webAuthnRegisterRequest();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user