mirror of
https://github.com/go-gitea/gitea.git
synced 2025-08-09 03:51:46 +02:00
Compare commits
56 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
55e159ca5f | ||
|
87074ec860 | ||
|
1fe5fe419e | ||
|
67a12b8fac | ||
|
e861dcbbaf | ||
|
53c2136a9a | ||
|
24ebc7e517 | ||
|
b072907987 | ||
|
942b0360ad | ||
|
1ec4913add | ||
|
16e34025b4 | ||
|
456d63b6cf | ||
|
798ac3f85a | ||
|
460093b952 | ||
|
38d184d518 | ||
|
80b55263d8 | ||
|
32232db55f | ||
|
cf9b6c281f | ||
|
a8c6a4a70e | ||
|
e6050e80f7 | ||
|
3803b15d76 | ||
|
af73e1ee35 | ||
|
4bc8dfc6a3 | ||
|
33c4e246fe | ||
|
8ec7beb9f4 | ||
|
c6eb9b30ae | ||
|
f75a9b27b0 | ||
|
2705696d4d | ||
|
2b68f66e0e | ||
|
5c7d30cf52 | ||
|
e520dff4da | ||
|
2bc759518e | ||
|
92b2883058 | ||
|
0ebfc1405c | ||
|
fd5c67226e | ||
|
61308825a6 | ||
|
0cccad04f0 | ||
|
a0e5c49ac3 | ||
|
3558310c1f | ||
|
e99534cfd2 | ||
|
27acf6165e | ||
|
f286a28568 | ||
|
b5c4cb1bde | ||
|
26b98417ad | ||
|
8b0cf88c0c | ||
|
23db3375df | ||
|
14011d77c9 | ||
|
5519e26c2f | ||
|
6feb435867 | ||
|
61444ed8ca | ||
|
d770cc9886 | ||
|
fbaa01998a | ||
|
ac2ae66ae7 | ||
|
ed60fe0986 | ||
|
29e0d62790 | ||
|
7b464fa67b |
70
CHANGELOG.md
70
CHANGELOG.md
@@ -4,14 +4,16 @@ This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.14.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.14.0) - 2021-03-19
|
||||
## [1.14.0](https://github.com/go-gitea/gitea/releases/tag/v1.14.0) - 2021-04-11
|
||||
|
||||
* SECURITY
|
||||
* Respect approved email domain list for externally validated user registration (#15014)
|
||||
* Add reverse proxy configuration support for remote IP address detection (#14959)
|
||||
* Ensure validation occurs on clone addresses too (#14994)
|
||||
* Fix several render issues highlighted during fuzzing (#14986)
|
||||
* BREAKING
|
||||
* Fix double 'push tag' action feed (#15078) (#15083)
|
||||
* Remove possible resource leak (#15067) (#15082)
|
||||
* Handle unauthorized user events gracefully (#15071) (#15074)
|
||||
* Restore Access.log following migration to Chi framework (Stops access logging of /api/internal routes) (#14475)
|
||||
* Migrate from Macaron to Chi framework (#14293)
|
||||
* Deprecate building for mips (#14174)
|
||||
@@ -42,6 +44,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Dump github/gitlab/gitea repository data to a local directory and restore to gitea (#12244)
|
||||
* Create Rootless Docker image (#10154)
|
||||
* API
|
||||
* Speedup issue search (#15179) (#15192)
|
||||
* Get pull, return head branch sha, even if deleted (#14931)
|
||||
* Export LFS & TimeTracking function status (#14753)
|
||||
* Show Gitea version in swagger (#14654)
|
||||
@@ -66,6 +69,20 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Add more filters to issues search (#13514)
|
||||
* Add review request api (#11355)
|
||||
* BUGFIXES
|
||||
* Fix delete nonexist oauth application 500 and prevent deadlock (#15384) (#15396)
|
||||
* Always set the merge base used to merge the commit (#15352) (#15385)
|
||||
* Upgrade to bluemonday 1.0.7 (#15379) (#15380)
|
||||
* Turn RepoRef and RepoAssignment back into func(*Context) (#15372) (#15377)
|
||||
* Move FCGI req.URL.Path fix-up to the FCGI listener (#15292) (#15361)
|
||||
* Show diff on rename with diff changes (#15338) (#15339)
|
||||
* Fix handling of logout event (#15323) (#15337)
|
||||
* Fix CanCreateRepo check (#15311) (#15321)
|
||||
* Fix xorm log stack level (#15285) (#15316)
|
||||
* Fix bug in Wrap (#15302) (#15309)
|
||||
* Drop the event source if we are unauthorized (#15275) (#15280)
|
||||
* Backport Fix graph pagination (#15225) (#15249)
|
||||
* Prevent NPE in CommentMustAsDiff if no hunk header (#15199) (#15200)
|
||||
* should run RetrieveRepoMetas() for empty pr (#15187) (#15190)
|
||||
* Move setting to enable closing issue via commit in non default branch to repo settings (#14965)
|
||||
* Show correct issues for team dashboard (#14952)
|
||||
* Ensure that new pull request button works on forked forks owned by owner of the root and reduce ambiguity (#14932)
|
||||
@@ -122,6 +139,9 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Use GO variable in go-check target (#13146) (#13147)
|
||||
* ENHANCEMENTS
|
||||
* UI style improvements
|
||||
* Dropzone styling improvements (#15291) (#15374)
|
||||
* Add size to Save function (#15264) (#15270)
|
||||
* Monaco improvements (#15333) (#15345)
|
||||
* Support .mailmap in code activity stats (#15009)
|
||||
* Sort release attachments by name (#15008)
|
||||
* Add ui.explore settings to control view of explore pages (#14094)
|
||||
@@ -267,6 +287,52 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Reduce make verbosity (#13803)
|
||||
* Add git command error directory on log (#13194)
|
||||
|
||||
## [1.13.7](https://github.com/go-gitea/gitea/releases/tag/v1.13.7) - 2021-04-07
|
||||
|
||||
* SECURITY
|
||||
* Update to bluemonday-1.0.6 (#15294) (#15298)
|
||||
* Clusterfuzz found another way (#15160) (#15169)
|
||||
* API
|
||||
* Fix wrong user returned in API (#15139) (#15150)
|
||||
* BUGFIXES
|
||||
* Add 'fonts' into 'KnownPublicEntries' (#15188) (#15317)
|
||||
* Speed up `enry.IsVendor` (#15213) (#15246)
|
||||
* Response 404 for diff/patch of a commit that not exist (#15221) (#15238)
|
||||
* Prevent NPE in CommentMustAsDiff if no hunk header (#15199) (#15201)
|
||||
* MISC
|
||||
* Add size to Save function (#15264) (#15271)
|
||||
|
||||
## [1.13.6](https://github.com/go-gitea/gitea/releases/tag/v1.13.6) - 2021-03-23
|
||||
|
||||
* SECURITY
|
||||
* Fix bug on avatar middleware (#15124) (#15125)
|
||||
* Fix another clusterfuzz identified issue (#15096) (#15114)
|
||||
* API
|
||||
* Fix nil pointer exception in get pull reviews API (#15106)
|
||||
* BUGFIXES
|
||||
* Fix markdown rendering in milestone content (#15056) (#15092)
|
||||
|
||||
## [1.13.5](https://github.com/go-gitea/gitea/releases/tag/v1.13.5) - 2021-03-21
|
||||
|
||||
* SECURITY
|
||||
* Update to goldmark 1.3.3 (#15059) (#15061)
|
||||
* Another clusterfuzz spotted issue (#15032) (#15034)
|
||||
* API
|
||||
* Fix set milestone on PR creation (#14981) (#15001)
|
||||
* Prevent panic when editing forked repos by API (#14960) (#14963)
|
||||
* BUGFIXES
|
||||
* Fix bug when upload on web (#15042) (#15055)
|
||||
* Delete Labels & IssueLabels on Repo Delete too (#15039) (#15051)
|
||||
* Fix postgres ID sequences broken by recreate-table (#15015) (#15029)
|
||||
* Fix several render issues (#14986) (#15013)
|
||||
* Make sure sibling images get a link too (#14979) (#14995)
|
||||
* Fix Anchor jumping with escaped query components (#14969) (#14977)
|
||||
* Fix release mail html template (#14976)
|
||||
* Fix excluding more than two labels on issues list (#14962) (#14973)
|
||||
* Don't mark each comment poster as OP (#14971) (#14972)
|
||||
* Add "captcha" to list of reserved usernames (#14930)
|
||||
* Re-enable import local paths after reversion from #13610 (#14925) (#14927)
|
||||
|
||||
## [1.13.4](https://github.com/go-gitea/gitea/releases/tag/v1.13.4) - 2021-03-07
|
||||
|
||||
* SECURITY
|
||||
|
@@ -9,9 +9,11 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/fcgi"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
func runHTTP(network, listenAddr, name string, m http.Handler) error {
|
||||
@@ -48,7 +50,12 @@ func runFCGI(network, listenAddr, name string, m http.Handler) error {
|
||||
fcgiServer := graceful.NewServer(network, listenAddr, name)
|
||||
|
||||
err := fcgiServer.ListenAndServe(func(listener net.Listener) error {
|
||||
return fcgi.Serve(listener, m)
|
||||
return fcgi.Serve(listener, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
||||
if setting.AppSubURL != "" {
|
||||
req.URL.Path = strings.TrimPrefix(req.URL.Path, setting.AppSubURL)
|
||||
}
|
||||
m.ServeHTTP(resp, req)
|
||||
}))
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal("Failed to start FCGI main server: %v", err)
|
||||
|
12
go.mod
12
go.mod
@@ -5,7 +5,7 @@ go 1.14
|
||||
require (
|
||||
cloud.google.com/go v0.78.0 // indirect
|
||||
code.gitea.io/gitea-vet v0.2.1
|
||||
code.gitea.io/sdk/gitea v0.13.2
|
||||
code.gitea.io/sdk/gitea v0.14.0
|
||||
gitea.com/go-chi/binding v0.0.0-20210301195521-1fe1c9a555e7
|
||||
gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e
|
||||
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e
|
||||
@@ -86,7 +86,7 @@ require (
|
||||
github.com/mgechev/revive v1.0.3
|
||||
github.com/mholt/acmez v0.1.3 // indirect
|
||||
github.com/mholt/archiver/v3 v3.5.0
|
||||
github.com/microcosm-cc/bluemonday v1.0.4
|
||||
github.com/microcosm-cc/bluemonday v1.0.7
|
||||
github.com/miekg/dns v1.1.40 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.10
|
||||
@@ -128,7 +128,7 @@ require (
|
||||
github.com/xanzy/go-gitlab v0.44.0
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
github.com/yohcop/openid-go v1.0.0
|
||||
github.com/yuin/goldmark v1.3.2
|
||||
github.com/yuin/goldmark v1.3.3
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
|
||||
github.com/yuin/goldmark-meta v1.0.0
|
||||
go.jolheiser.com/hcaptcha v0.0.4
|
||||
@@ -136,9 +136,9 @@ require (
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.16.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93
|
||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44
|
||||
golang.org/x/text v0.3.5
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
golang.org/x/tools v0.1.0
|
||||
@@ -153,5 +153,3 @@ require (
|
||||
)
|
||||
|
||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.2.4
|
||||
|
||||
replace github.com/microcosm-cc/bluemonday => github.com/lunny/bluemonday v1.0.5-0.20201227154428-ca34796141e8
|
||||
|
23
go.sum
23
go.sum
@@ -38,8 +38,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
code.gitea.io/gitea-vet v0.2.1 h1:b30by7+3SkmiftK0RjuXqFvZg2q4p68uoPGuxhzBN0s=
|
||||
code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
|
||||
code.gitea.io/sdk/gitea v0.13.2 h1:wAnT/J7Z62q3fJXbgnecoaOBh8CM1Qq0/DakWxiv4yA=
|
||||
code.gitea.io/sdk/gitea v0.13.2/go.mod h1:lee2y8LeV3kQb2iK+hHlMqoadL4bp27QOkOV/hawLKg=
|
||||
code.gitea.io/sdk/gitea v0.14.0 h1:m4J352I3p9+bmJUfS+g0odeQzBY/5OXP91Gv6D4fnJ0=
|
||||
code.gitea.io/sdk/gitea v0.14.0/go.mod h1:89WiyOX1KEcvjP66sRHdu0RafojGo60bT9UqW17VbWs=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
gitea.com/go-chi/binding v0.0.0-20210301195521-1fe1c9a555e7 h1:xCVJPY823C8RWpgMabTw2kOglDrg0iS3GcQU6wdwHkU=
|
||||
gitea.com/go-chi/binding v0.0.0-20210301195521-1fe1c9a555e7/go.mod h1:AyfTrwtfYN54R/HmVvMYPnSTenH5bVoyh8x6tBluxEA=
|
||||
@@ -196,8 +196,6 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ=
|
||||
github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0=
|
||||
github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU=
|
||||
github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@@ -776,8 +774,6 @@ github.com/libdns/libdns v0.2.0 h1:ewg3ByWrdUrxrje8ChPVMBNcotg7H9LQYg+u5De2RzI=
|
||||
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lunny/bluemonday v1.0.5-0.20201227154428-ca34796141e8 h1:1omo92DLtxQu6VwVPSZAmduHaK5zssed6cvkHyl1XOg=
|
||||
github.com/lunny/bluemonday v1.0.5-0.20201227154428-ca34796141e8/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w=
|
||||
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY=
|
||||
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:mmIfjCSQlGYXmJ95jFN84AkQFnVABtKuJL8IrzwvUKQ=
|
||||
github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
|
||||
@@ -834,6 +830,8 @@ github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk=
|
||||
github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
|
||||
github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE=
|
||||
github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
|
||||
github.com/microcosm-cc/bluemonday v1.0.7 h1:6yAQfk4XT+PI/dk1ZeBp1gr3Q2Hd1DR0O3aEyPUJVTE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.7/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.40 h1:pyyPFfGMnciYUk/mXpKkVmeMQjfXqt3FAJ2hy7tPiLA=
|
||||
@@ -1145,8 +1143,8 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.2 h1:YjHC5TgyMmHpicTgEqDN0Q96Xo8K6tLXPnmNOHXCgs0=
|
||||
github.com/yuin/goldmark v1.3.2/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.3.3 h1:37BdQwPx8VOSic8eDSWee6QL9mRpZRm9VJp/QugNrW0=
|
||||
github.com/yuin/goldmark v1.3.3/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio=
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
|
||||
github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
|
||||
@@ -1321,8 +1319,9 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1418,8 +1417,8 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 h1:V066+OYJ66oTjnhm4Yrn7SXIwSCiDQJxpBxmvqb1N1c=
|
||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
|
@@ -239,6 +239,26 @@ func doAPICreatePullRequest(ctx APITestContext, owner, repo, baseBranch, headBra
|
||||
}
|
||||
}
|
||||
|
||||
func doAPIGetPullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) (api.PullRequest, error) {
|
||||
return func(t *testing.T) (api.PullRequest, error) {
|
||||
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d?token=%s",
|
||||
owner, repo, index, ctx.Token)
|
||||
req := NewRequest(t, http.MethodGet, urlStr)
|
||||
|
||||
expected := 200
|
||||
if ctx.ExpectedCode != 0 {
|
||||
expected = ctx.ExpectedCode
|
||||
}
|
||||
resp := ctx.Session.MakeRequest(t, req, expected)
|
||||
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
pr := api.PullRequest{}
|
||||
err := decoder.Decode(&pr)
|
||||
return pr, err
|
||||
}
|
||||
}
|
||||
|
||||
func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) {
|
||||
return func(t *testing.T) {
|
||||
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s",
|
||||
|
@@ -92,6 +92,10 @@ func testAPIDeleteOAuth2Application(t *testing.T) {
|
||||
session.MakeRequest(t, req, http.StatusNoContent)
|
||||
|
||||
models.AssertNotExistsBean(t, &models.OAuth2Application{UID: oldApp.UID, Name: oldApp.Name})
|
||||
|
||||
// Delete again will return not found
|
||||
req = NewRequest(t, "DELETE", urlStr)
|
||||
session.MakeRequest(t, req, http.StatusNotFound)
|
||||
}
|
||||
|
||||
func testAPIGetOAuth2Application(t *testing.T) {
|
||||
|
@@ -122,7 +122,7 @@ func TestGetAttachment(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
//Write empty file to be available for response
|
||||
if tc.createFile {
|
||||
_, err := storage.Attachments.Save(models.AttachmentRelativePath(tc.uuid), strings.NewReader("hello world"))
|
||||
_, err := storage.Attachments.Save(models.AttachmentRelativePath(tc.uuid), strings.NewReader("hello world"), -1)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
//Actual test
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package integrations
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
@@ -208,13 +209,13 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
|
||||
|
||||
// Request raw paths
|
||||
req := NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", little))
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
assert.Equal(t, littleSize, resp.Body.Len())
|
||||
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||
assert.Equal(t, littleSize, resp.Length)
|
||||
|
||||
setting.CheckLFSVersion()
|
||||
if setting.LFS.StartServer {
|
||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
assert.NotEqual(t, littleSize, resp.Body.Len())
|
||||
assert.LessOrEqual(t, resp.Body.Len(), 1024)
|
||||
if resp.Body.Len() != littleSize && resp.Body.Len() <= 1024 {
|
||||
@@ -224,12 +225,12 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
|
||||
|
||||
if !testing.Short() {
|
||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", big))
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
assert.Equal(t, bigSize, resp.Body.Len())
|
||||
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||
assert.Equal(t, bigSize, resp.Length)
|
||||
|
||||
if setting.LFS.StartServer {
|
||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", bigLFS))
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
assert.NotEqual(t, bigSize, resp.Body.Len())
|
||||
if resp.Body.Len() != bigSize && resp.Body.Len() <= 1024 {
|
||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||
@@ -450,27 +451,35 @@ func doMergeFork(ctx, baseCtx APITestContext, baseBranch, headBranch string) fun
|
||||
t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr))
|
||||
|
||||
// Then get the diff string
|
||||
var diffStr string
|
||||
var diffHash string
|
||||
var diffLength int
|
||||
t.Run("GetDiff", func(t *testing.T) {
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d.diff", url.PathEscape(baseCtx.Username), url.PathEscape(baseCtx.Reponame), pr.Index))
|
||||
resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
|
||||
diffStr = resp.Body.String()
|
||||
resp := ctx.Session.MakeRequestNilResponseHashSumRecorder(t, req, http.StatusOK)
|
||||
diffHash = string(resp.Hash.Sum(nil))
|
||||
diffLength = resp.Length
|
||||
})
|
||||
|
||||
// Now: Merge the PR & make sure that doesn't break the PR page or change its diff
|
||||
t.Run("MergePR", doAPIMergePullRequest(baseCtx, baseCtx.Username, baseCtx.Reponame, pr.Index))
|
||||
t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr))
|
||||
t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffStr))
|
||||
t.Run("CheckPR", func(t *testing.T) {
|
||||
oldMergeBase := pr.MergeBase
|
||||
pr2, err := doAPIGetPullRequest(baseCtx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, oldMergeBase, pr2.MergeBase)
|
||||
})
|
||||
t.Run("EnsurDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffHash, diffLength))
|
||||
|
||||
// Then: Delete the head branch & make sure that doesn't break the PR page or change its diff
|
||||
t.Run("DeleteHeadBranch", doBranchDelete(baseCtx, baseCtx.Username, baseCtx.Reponame, headBranch))
|
||||
t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr))
|
||||
t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffStr))
|
||||
t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffHash, diffLength))
|
||||
|
||||
// Delete the head repository & make sure that doesn't break the PR page or change its diff
|
||||
t.Run("DeleteHeadRepository", doAPIDeleteRepository(ctx))
|
||||
t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr))
|
||||
t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffStr))
|
||||
t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffHash, diffLength))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,20 +523,15 @@ func doEnsureCanSeePull(ctx APITestContext, pr api.PullRequest) func(t *testing.
|
||||
}
|
||||
}
|
||||
|
||||
func doEnsureDiffNoChange(ctx APITestContext, pr api.PullRequest, diffStr string) func(t *testing.T) {
|
||||
func doEnsureDiffNoChange(ctx APITestContext, pr api.PullRequest, diffHash string, diffLength int) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d.diff", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), pr.Index))
|
||||
resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
|
||||
expectedMaxLen := len(diffStr)
|
||||
if expectedMaxLen > 800 {
|
||||
expectedMaxLen = 800
|
||||
}
|
||||
actual := resp.Body.String()
|
||||
actualMaxLen := len(actual)
|
||||
if actualMaxLen > 800 {
|
||||
actualMaxLen = 800
|
||||
}
|
||||
assert.Equal(t, diffStr, actual, "Unexpected change in the diff string: expected: %s but was actually: %s", diffStr[:expectedMaxLen], actual[:actualMaxLen])
|
||||
resp := ctx.Session.MakeRequestNilResponseHashSumRecorder(t, req, http.StatusOK)
|
||||
actual := string(resp.Hash.Sum(nil))
|
||||
actualLength := resp.Length
|
||||
|
||||
equal := diffHash == actual
|
||||
assert.True(t, equal, "Unexpected change in the diff string: expected hash: %s size: %d but was actually: %s size: %d", hex.EncodeToString([]byte(diffHash)), diffLength, hex.EncodeToString([]byte(actual)), actualLength)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,8 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
@@ -58,6 +60,26 @@ func NewNilResponseRecorder() *NilResponseRecorder {
|
||||
}
|
||||
}
|
||||
|
||||
type NilResponseHashSumRecorder struct {
|
||||
httptest.ResponseRecorder
|
||||
Hash hash.Hash
|
||||
Length int
|
||||
}
|
||||
|
||||
func (n *NilResponseHashSumRecorder) Write(b []byte) (int, error) {
|
||||
_, _ = n.Hash.Write(b)
|
||||
n.Length += len(b)
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// NewRecorder returns an initialized ResponseRecorder.
|
||||
func NewNilResponseHashSumRecorder() *NilResponseHashSumRecorder {
|
||||
return &NilResponseHashSumRecorder{
|
||||
Hash: fnv.New32(),
|
||||
ResponseRecorder: *httptest.NewRecorder(),
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
defer log.Close()
|
||||
|
||||
@@ -284,6 +306,23 @@ func (s *TestSession) MakeRequestNilResponseRecorder(t testing.TB, req *http.Req
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *TestSession) MakeRequestNilResponseHashSumRecorder(t testing.TB, req *http.Request, expectedStatus int) *NilResponseHashSumRecorder {
|
||||
t.Helper()
|
||||
baseURL, err := url.Parse(setting.AppURL)
|
||||
assert.NoError(t, err)
|
||||
for _, c := range s.jar.Cookies(baseURL) {
|
||||
req.AddCookie(c)
|
||||
}
|
||||
resp := MakeRequestNilResponseHashSumRecorder(t, req, expectedStatus)
|
||||
|
||||
ch := http.Header{}
|
||||
ch.Add("Cookie", strings.Join(resp.Header()["Set-Cookie"], ";"))
|
||||
cr := http.Request{Header: ch}
|
||||
s.jar.SetCookies(baseURL, cr.Cookies())
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
const userPassword = "password"
|
||||
|
||||
var loginSessionCache = make(map[string]*TestSession, 10)
|
||||
@@ -429,6 +468,19 @@ func MakeRequestNilResponseRecorder(t testing.TB, req *http.Request, expectedSta
|
||||
return recorder
|
||||
}
|
||||
|
||||
func MakeRequestNilResponseHashSumRecorder(t testing.TB, req *http.Request, expectedStatus int) *NilResponseHashSumRecorder {
|
||||
t.Helper()
|
||||
recorder := NewNilResponseHashSumRecorder()
|
||||
c.ServeHTTP(recorder, req)
|
||||
if expectedStatus != NoExpectedStatus {
|
||||
if !assert.EqualValues(t, expectedStatus, recorder.Code,
|
||||
"Request: %s %s", req.Method, req.URL.String()) {
|
||||
logUnexpectedResponse(t, &recorder.ResponseRecorder)
|
||||
}
|
||||
}
|
||||
return recorder
|
||||
}
|
||||
|
||||
// logUnexpectedResponse logs the contents of an unexpected response.
|
||||
func logUnexpectedResponse(t testing.TB, recorder *httptest.ResponseRecorder) {
|
||||
t.Helper()
|
||||
|
@@ -382,7 +382,7 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
|
||||
}
|
||||
|
||||
if opts.Date != "" {
|
||||
dateLow, err := time.Parse("2006-01-02", opts.Date)
|
||||
dateLow, err := time.ParseInLocation("2006-01-02", opts.Date, setting.DefaultUILocation)
|
||||
if err != nil {
|
||||
log.Warn("Unable to parse %s, filter not applied: %v", opts.Date, err)
|
||||
} else {
|
||||
|
@@ -85,7 +85,7 @@ func (a *Attachment) LinkedRepository() (*Repository, UnitType, error) {
|
||||
func NewAttachment(attach *Attachment, buf []byte, file io.Reader) (_ *Attachment, err error) {
|
||||
attach.UUID = gouuid.New().String()
|
||||
|
||||
size, err := storage.Attachments.Save(attach.RelativePath(), io.MultiReader(bytes.NewReader(buf), file))
|
||||
size, err := storage.Attachments.Save(attach.RelativePath(), io.MultiReader(bytes.NewReader(buf), file), -1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Create: %v", err)
|
||||
}
|
||||
|
@@ -338,7 +338,7 @@ func FixCommentTypeLabelWithEmptyLabel() (int64, error) {
|
||||
|
||||
// CountCommentTypeLabelWithOutsideLabels count label comments with outside label
|
||||
func CountCommentTypeLabelWithOutsideLabels() (int64, error) {
|
||||
return x.Where("comment.type = ? AND (issue.repo_id != label.repo_id OR (label.repo_id = 0 AND repository.owner_id != label.org_id))", CommentTypeLabel).
|
||||
return x.Where("comment.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))", CommentTypeLabel).
|
||||
Table("comment").
|
||||
Join("inner", "label", "label.id = comment.label_id").
|
||||
Join("inner", "issue", "issue.id = comment.issue_id ").
|
||||
@@ -354,8 +354,9 @@ func FixCommentTypeLabelWithOutsideLabels() (int64, error) {
|
||||
FROM comment AS com
|
||||
INNER JOIN label ON com.label_id = label.id
|
||||
INNER JOIN issue on issue.id = com.issue_id
|
||||
INNER JOIN repository ON issue.repo_id = repository.id
|
||||
WHERE
|
||||
com.type = ? AND (issue.repo_id != label.repo_id OR (label.repo_id = 0 AND label.org_id != repo.owner_id))
|
||||
com.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))
|
||||
) AS il_too)`, CommentTypeLabel)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -366,9 +367,9 @@ func FixCommentTypeLabelWithOutsideLabels() (int64, error) {
|
||||
|
||||
// CountIssueLabelWithOutsideLabels count label comments with outside label
|
||||
func CountIssueLabelWithOutsideLabels() (int64, error) {
|
||||
return x.Where(builder.Expr("issue.repo_id != label.repo_id OR (label.repo_id = 0 AND repository.owner_id != label.org_id)")).
|
||||
return x.Where(builder.Expr("(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)")).
|
||||
Table("issue_label").
|
||||
Join("inner", "label", "issue_label.id = label.id ").
|
||||
Join("inner", "label", "issue_label.label_id = label.id ").
|
||||
Join("inner", "issue", "issue.id = issue_label.issue_id ").
|
||||
Join("inner", "repository", "issue.repo_id = repository.id").
|
||||
Count(new(IssueLabel))
|
||||
@@ -380,11 +381,11 @@ func FixIssueLabelWithOutsideLabels() (int64, error) {
|
||||
SELECT il_too.id FROM (
|
||||
SELECT il_too_too.id
|
||||
FROM issue_label AS il_too_too
|
||||
INNER JOIN label ON il_too_too.id = label.id
|
||||
INNER JOIN label ON il_too_too.label_id = label.id
|
||||
INNER JOIN issue on issue.id = il_too_too.issue_id
|
||||
INNER JOIN repository on repository.id = issue.repo_id
|
||||
WHERE
|
||||
issue.repo_id != label.repo_id OR (label.repo_id = 0 AND label.org_id != repository.owner_id)
|
||||
(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)
|
||||
) AS il_too )`)
|
||||
|
||||
if err != nil {
|
||||
|
@@ -26,6 +26,8 @@ func NewXORMLogger(showSQL bool) xormlog.Logger {
|
||||
}
|
||||
}
|
||||
|
||||
const stackLevel = 8
|
||||
|
||||
// Log a message with defined skip and at logging level
|
||||
func (l *XORMLogBridge) Log(skip int, level log.Level, format string, v ...interface{}) error {
|
||||
return l.logger.Log(skip+1, level, format, v...)
|
||||
@@ -33,42 +35,42 @@ func (l *XORMLogBridge) Log(skip int, level log.Level, format string, v ...inter
|
||||
|
||||
// Debug show debug log
|
||||
func (l *XORMLogBridge) Debug(v ...interface{}) {
|
||||
_ = l.Log(2, log.DEBUG, fmt.Sprint(v...))
|
||||
_ = l.Log(stackLevel, log.DEBUG, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Debugf show debug log
|
||||
func (l *XORMLogBridge) Debugf(format string, v ...interface{}) {
|
||||
_ = l.Log(2, log.DEBUG, format, v...)
|
||||
_ = l.Log(stackLevel, log.DEBUG, format, v...)
|
||||
}
|
||||
|
||||
// Error show error log
|
||||
func (l *XORMLogBridge) Error(v ...interface{}) {
|
||||
_ = l.Log(2, log.ERROR, fmt.Sprint(v...))
|
||||
_ = l.Log(stackLevel, log.ERROR, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Errorf show error log
|
||||
func (l *XORMLogBridge) Errorf(format string, v ...interface{}) {
|
||||
_ = l.Log(2, log.ERROR, format, v...)
|
||||
_ = l.Log(stackLevel, log.ERROR, format, v...)
|
||||
}
|
||||
|
||||
// Info show information level log
|
||||
func (l *XORMLogBridge) Info(v ...interface{}) {
|
||||
_ = l.Log(2, log.INFO, fmt.Sprint(v...))
|
||||
_ = l.Log(stackLevel, log.INFO, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Infof show information level log
|
||||
func (l *XORMLogBridge) Infof(format string, v ...interface{}) {
|
||||
_ = l.Log(2, log.INFO, format, v...)
|
||||
_ = l.Log(stackLevel, log.INFO, format, v...)
|
||||
}
|
||||
|
||||
// Warn show warning log
|
||||
func (l *XORMLogBridge) Warn(v ...interface{}) {
|
||||
_ = l.Log(2, log.WARN, fmt.Sprint(v...))
|
||||
_ = l.Log(stackLevel, log.WARN, fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Warnf show warnning log
|
||||
func (l *XORMLogBridge) Warnf(format string, v ...interface{}) {
|
||||
_ = l.Log(2, log.WARN, format, v...)
|
||||
_ = l.Log(stackLevel, log.WARN, format, v...)
|
||||
}
|
||||
|
||||
// Level get logger level
|
||||
|
@@ -39,6 +39,7 @@ func InsertMilestones(ms ...*Milestone) (err error) {
|
||||
// InsertIssues insert issues to database
|
||||
func InsertIssues(issues ...*Issue) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -194,6 +195,7 @@ func InsertPullRequests(prs ...*PullRequest) error {
|
||||
// InsertReleases migrates release
|
||||
func InsertReleases(rels ...*Release) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -48,11 +48,11 @@ func removeInvalidLabels(x *xorm.Engine) error {
|
||||
SELECT il_too.id FROM (
|
||||
SELECT il_too_too.id
|
||||
FROM issue_label AS il_too_too
|
||||
INNER JOIN label ON il_too_too.id = label.id
|
||||
INNER JOIN label ON il_too_too.label_id = label.id
|
||||
INNER JOIN issue on issue.id = il_too_too.issue_id
|
||||
INNER JOIN repository on repository.id = issue.repo_id
|
||||
WHERE
|
||||
issue.repo_id != label.repo_id OR (label.repo_id = 0 AND label.org_id != repository.owner_id)
|
||||
(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)
|
||||
) AS il_too )`); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -65,7 +65,7 @@ func removeInvalidLabels(x *xorm.Engine) error {
|
||||
INNER JOIN issue on issue.id = com.issue_id
|
||||
INNER JOIN repository on repository.id = issue.repo_id
|
||||
WHERE
|
||||
com.type = ? AND (issue.repo_id != label.repo_id OR (label.repo_id = 0 AND label.org_id != repository.owner_id))
|
||||
com.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))
|
||||
) AS il_too)`, 7); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -235,7 +235,7 @@ func deleteOAuth2Application(sess *xorm.Session, id, userid int64) error {
|
||||
if deleted, err := sess.Delete(&OAuth2Application{ID: id, UID: userid}); err != nil {
|
||||
return err
|
||||
} else if deleted == 0 {
|
||||
return fmt.Errorf("cannot find oauth2 application")
|
||||
return ErrOAuthApplicationNotFound{ID: id}
|
||||
}
|
||||
codes := make([]*OAuth2AuthorizationCode, 0)
|
||||
// delete correlating auth codes
|
||||
@@ -261,6 +261,7 @@ func deleteOAuth2Application(sess *xorm.Session, id, userid int64) error {
|
||||
// DeleteOAuth2Application deletes the application with the given id and the grants and auth codes related to it. It checks if the userid was the creator of the app.
|
||||
func DeleteOAuth2Application(id, userid int64) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -406,7 +406,8 @@ func (pr *PullRequest) SetMerged() (bool, error) {
|
||||
return false, fmt.Errorf("Issue.changeStatus: %v", err)
|
||||
}
|
||||
|
||||
if _, err := sess.Where("id = ?", pr.ID).Cols("has_merged, status, merged_commit_id, merger_id, merged_unix").Update(pr); err != nil {
|
||||
// We need to save all of the data used to compute this merge as it may have already been changed by TestPatch. FIXME: need to set some state to prevent TestPatch from running whilst we are merging.
|
||||
if _, err := sess.Where("id = ?", pr.ID).Cols("has_merged, status, merge_base, merged_commit_id, merger_id, merged_unix").Update(pr); err != nil {
|
||||
return false, fmt.Errorf("Failed to update pr[%d]: %v", pr.ID, err)
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// RepositoryListDefaultPageSize is the default number of repositories
|
||||
@@ -363,6 +364,35 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) {
|
||||
|
||||
// SearchRepositoryByCondition search repositories by condition
|
||||
func SearchRepositoryByCondition(opts *SearchRepoOptions, cond builder.Cond, loadAttributes bool) (RepositoryList, int64, error) {
|
||||
sess, count, err := searchRepositoryByCondition(opts, cond)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
defer sess.Close()
|
||||
|
||||
defaultSize := 50
|
||||
if opts.PageSize > 0 {
|
||||
defaultSize = opts.PageSize
|
||||
}
|
||||
repos := make(RepositoryList, 0, defaultSize)
|
||||
if err := sess.Find(&repos); err != nil {
|
||||
return nil, 0, fmt.Errorf("Repo: %v", err)
|
||||
}
|
||||
|
||||
if opts.PageSize <= 0 {
|
||||
count = int64(len(repos))
|
||||
}
|
||||
|
||||
if loadAttributes {
|
||||
if err := repos.loadAttributes(sess); err != nil {
|
||||
return nil, 0, fmt.Errorf("LoadAttributes: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return repos, count, nil
|
||||
}
|
||||
|
||||
func searchRepositoryByCondition(opts *SearchRepoOptions, cond builder.Cond) (*xorm.Session, int64, error) {
|
||||
if opts.Page <= 0 {
|
||||
opts.Page = 1
|
||||
}
|
||||
@@ -376,31 +406,24 @@ func SearchRepositoryByCondition(opts *SearchRepoOptions, cond builder.Cond, loa
|
||||
}
|
||||
|
||||
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)
|
||||
var count int64
|
||||
if opts.PageSize > 0 {
|
||||
var err error
|
||||
count, err = sess.
|
||||
Where(cond).
|
||||
Count(new(Repository))
|
||||
if err != nil {
|
||||
_ = sess.Close()
|
||||
return nil, 0, fmt.Errorf("Count: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
repos := make(RepositoryList, 0, opts.PageSize)
|
||||
sess.Where(cond).OrderBy(opts.OrderBy.String())
|
||||
if opts.PageSize > 0 {
|
||||
sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
|
||||
}
|
||||
if err = sess.Find(&repos); err != nil {
|
||||
return nil, 0, fmt.Errorf("Repo: %v", err)
|
||||
}
|
||||
|
||||
if loadAttributes {
|
||||
if err = repos.loadAttributes(sess); err != nil {
|
||||
return nil, 0, fmt.Errorf("LoadAttributes: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return repos, count, nil
|
||||
return sess, count, nil
|
||||
}
|
||||
|
||||
// accessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible
|
||||
@@ -456,6 +479,33 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err
|
||||
return SearchRepository(opts)
|
||||
}
|
||||
|
||||
// SearchRepositoryIDs takes keyword and part of repository name to search,
|
||||
// it returns results in given range and number of total results.
|
||||
func SearchRepositoryIDs(opts *SearchRepoOptions) ([]int64, int64, error) {
|
||||
opts.IncludeDescription = false
|
||||
|
||||
cond := SearchRepositoryCondition(opts)
|
||||
|
||||
sess, count, err := searchRepositoryByCondition(opts, cond)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
defer sess.Close()
|
||||
|
||||
defaultSize := 50
|
||||
if opts.PageSize > 0 {
|
||||
defaultSize = opts.PageSize
|
||||
}
|
||||
|
||||
ids := make([]int64, 0, defaultSize)
|
||||
err = sess.Select("id").Table("repository").Find(&ids)
|
||||
if opts.PageSize <= 0 {
|
||||
count = int64(len(ids))
|
||||
}
|
||||
|
||||
return ids, count, err
|
||||
}
|
||||
|
||||
// AccessibleRepoIDsQuery queries accessible repository ids. Usable as a subquery wherever repo ids need to be filtered.
|
||||
func AccessibleRepoIDsQuery(user *User) *builder.Builder {
|
||||
// NB: Please note this code needs to still work if user is nil
|
||||
|
@@ -330,10 +330,10 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) (err e
|
||||
SELECT il_too.id FROM (
|
||||
SELECT il_too_too.id
|
||||
FROM issue_label AS il_too_too
|
||||
INNER JOIN label ON il_too_too.id = label.id
|
||||
INNER JOIN label ON il_too_too.label_id = label.id
|
||||
INNER JOIN issue on issue.id = il_too_too.issue_id
|
||||
WHERE
|
||||
issue.repo_id = ? AND (issue.repo_id != label.repo_id OR (label.repo_id = 0 AND label.org_id != ?))
|
||||
issue.repo_id = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != ?))
|
||||
) AS il_too )`, repo.ID, newOwner.ID); err != nil {
|
||||
return fmt.Errorf("Unable to remove old org labels: %v", err)
|
||||
}
|
||||
@@ -343,9 +343,9 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) (err e
|
||||
SELECT com.id
|
||||
FROM comment AS com
|
||||
INNER JOIN label ON com.label_id = label.id
|
||||
INNER JOIN issue on issue.id = com.issue_id
|
||||
INNER JOIN issue ON issue.id = com.issue_id
|
||||
WHERE
|
||||
com.type = ? AND issue.repo_id = ? AND (issue.repo_id != label.repo_id OR (label.repo_id = 0 AND label.org_id != ?))
|
||||
com.type = ? AND issue.repo_id = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != ?))
|
||||
) AS il_too)`, CommentTypeLabel, repo.ID, newOwner.ID); err != nil {
|
||||
return fmt.Errorf("Unable to remove old org label comments: %v", err)
|
||||
}
|
||||
|
@@ -239,10 +239,10 @@ func (u *User) GetEmail() string {
|
||||
return u.Email
|
||||
}
|
||||
|
||||
// GetAllUsers returns a slice of all users found in DB.
|
||||
// GetAllUsers returns a slice of all individual users found in DB.
|
||||
func GetAllUsers() ([]*User, error) {
|
||||
users := make([]*User, 0)
|
||||
return users, x.OrderBy("id").Find(&users)
|
||||
return users, x.OrderBy("id").Where("type = ?", UserTypeIndividual).Find(&users)
|
||||
}
|
||||
|
||||
// IsLocal returns true if user login type is LoginPlain.
|
||||
|
70
modules/analyze/vendor.go
Normal file
70
modules/analyze/vendor.go
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package analyze
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-enry/go-enry/v2/data"
|
||||
)
|
||||
|
||||
var isVendorRegExp *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
matchers := data.VendorMatchers
|
||||
|
||||
caretStrings := make([]string, 0, 10)
|
||||
caretShareStrings := make([]string, 0, 10)
|
||||
|
||||
matcherStrings := make([]string, 0, len(matchers))
|
||||
for _, matcher := range matchers {
|
||||
str := matcher.String()
|
||||
if str[0] == '^' {
|
||||
caretStrings = append(caretStrings, str[1:])
|
||||
} else if str[0:5] == "(^|/)" {
|
||||
caretShareStrings = append(caretShareStrings, str[5:])
|
||||
} else {
|
||||
matcherStrings = append(matcherStrings, str)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(caretShareStrings)
|
||||
sort.Strings(caretStrings)
|
||||
sort.Strings(matcherStrings)
|
||||
|
||||
sb := &strings.Builder{}
|
||||
sb.WriteString("(?:^(?:")
|
||||
sb.WriteString(caretStrings[0])
|
||||
for _, matcher := range caretStrings[1:] {
|
||||
sb.WriteString(")|(?:")
|
||||
sb.WriteString(matcher)
|
||||
}
|
||||
sb.WriteString("))")
|
||||
sb.WriteString("|")
|
||||
sb.WriteString("(?:(?:^|/)(?:")
|
||||
sb.WriteString(caretShareStrings[0])
|
||||
for _, matcher := range caretShareStrings[1:] {
|
||||
sb.WriteString(")|(?:")
|
||||
sb.WriteString(matcher)
|
||||
}
|
||||
sb.WriteString("))")
|
||||
sb.WriteString("|")
|
||||
sb.WriteString("(?:")
|
||||
sb.WriteString(matcherStrings[0])
|
||||
for _, matcher := range matcherStrings[1:] {
|
||||
sb.WriteString(")|(?:")
|
||||
sb.WriteString(matcher)
|
||||
}
|
||||
sb.WriteString(")")
|
||||
combined := sb.String()
|
||||
isVendorRegExp = regexp.MustCompile(combined)
|
||||
}
|
||||
|
||||
// IsVendor returns whether or not path is a vendor path.
|
||||
func IsVendor(path string) bool {
|
||||
return isVendorRegExp.MatchString(path)
|
||||
}
|
42
modules/analyze/vendor_test.go
Normal file
42
modules/analyze/vendor_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package analyze
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestIsVendor(t *testing.T) {
|
||||
tests := []struct {
|
||||
path string
|
||||
want bool
|
||||
}{
|
||||
{"cache/", true},
|
||||
{"random/cache/", true},
|
||||
{"cache", false},
|
||||
{"dependencies/", true},
|
||||
{"Dependencies/", true},
|
||||
{"dependency/", false},
|
||||
{"dist/", true},
|
||||
{"dist", false},
|
||||
{"random/dist/", true},
|
||||
{"random/dist", false},
|
||||
{"deps/", true},
|
||||
{"configure", true},
|
||||
{"a/configure", true},
|
||||
{"config.guess", true},
|
||||
{"config.guess/", false},
|
||||
{".vscode/", true},
|
||||
{"doc/_build/", true},
|
||||
{"a/docs/_build/", true},
|
||||
{"a/dasdocs/_build-vsdoc.js", true},
|
||||
{"a/dasdocs/_build-vsdoc.j", false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.path, func(t *testing.T) {
|
||||
if got := IsVendor(tt.path); got != tt.want {
|
||||
t.Errorf("IsVendor() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@@ -8,7 +8,6 @@ package context
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
@@ -394,238 +393,231 @@ func RepoIDAssignment() func(ctx *Context) {
|
||||
}
|
||||
|
||||
// RepoAssignment returns a middleware to handle repository assignment
|
||||
func RepoAssignment() func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var (
|
||||
owner *models.User
|
||||
err error
|
||||
ctx = GetContext(req)
|
||||
)
|
||||
func RepoAssignment(ctx *Context) {
|
||||
var (
|
||||
owner *models.User
|
||||
err error
|
||||
)
|
||||
|
||||
userName := ctx.Params(":username")
|
||||
repoName := ctx.Params(":reponame")
|
||||
repoName = strings.TrimSuffix(repoName, ".git")
|
||||
userName := ctx.Params(":username")
|
||||
repoName := ctx.Params(":reponame")
|
||||
repoName = strings.TrimSuffix(repoName, ".git")
|
||||
|
||||
// Check if the user is the same as the repository owner
|
||||
if ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName) {
|
||||
owner = ctx.User
|
||||
// Check if the user is the same as the repository owner
|
||||
if ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName) {
|
||||
owner = ctx.User
|
||||
} else {
|
||||
owner, err = models.GetUserByName(userName)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
if ctx.Query("go-get") == "1" {
|
||||
EarlyResponseForGoGetMeta(ctx)
|
||||
return
|
||||
}
|
||||
ctx.NotFound("GetUserByName", nil)
|
||||
} else {
|
||||
owner, err = models.GetUserByName(userName)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
if ctx.Query("go-get") == "1" {
|
||||
EarlyResponseForGoGetMeta(ctx)
|
||||
return
|
||||
}
|
||||
ctx.NotFound("GetUserByName", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetUserByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.ServerError("GetUserByName", err)
|
||||
}
|
||||
ctx.Repo.Owner = owner
|
||||
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
||||
return
|
||||
}
|
||||
}
|
||||
ctx.Repo.Owner = owner
|
||||
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
||||
|
||||
// Get repository.
|
||||
repo, err := models.GetRepositoryByName(owner.ID, repoName)
|
||||
if err != nil {
|
||||
if models.IsErrRepoNotExist(err) {
|
||||
redirectRepoID, err := models.LookupRepoRedirect(owner.ID, repoName)
|
||||
if err == nil {
|
||||
RedirectToRepo(ctx, redirectRepoID)
|
||||
} else if models.IsErrRepoRedirectNotExist(err) {
|
||||
if ctx.Query("go-get") == "1" {
|
||||
EarlyResponseForGoGetMeta(ctx)
|
||||
return
|
||||
}
|
||||
ctx.NotFound("GetRepositoryByName", nil)
|
||||
} else {
|
||||
ctx.ServerError("LookupRepoRedirect", err)
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("GetRepositoryByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
repo.Owner = owner
|
||||
|
||||
repoAssignment(ctx, repo)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Repo.RepoLink = repo.Link()
|
||||
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
||||
ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
||||
|
||||
unit, err := ctx.Repo.Repository.GetUnit(models.UnitTypeExternalTracker)
|
||||
// Get repository.
|
||||
repo, err := models.GetRepositoryByName(owner.ID, repoName)
|
||||
if err != nil {
|
||||
if models.IsErrRepoNotExist(err) {
|
||||
redirectRepoID, err := models.LookupRepoRedirect(owner.ID, repoName)
|
||||
if err == nil {
|
||||
ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL
|
||||
}
|
||||
|
||||
ctx.Data["NumTags"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{
|
||||
IncludeTags: true,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetReleaseCountByRepoID", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["NumReleases"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetReleaseCountByRepoID", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = owner.Name + "/" + repo.Name
|
||||
ctx.Data["Repository"] = repo
|
||||
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
|
||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
||||
ctx.Data["RepoOwnerIsOrganization"] = repo.Owner.IsOrganization()
|
||||
ctx.Data["CanWriteCode"] = ctx.Repo.CanWrite(models.UnitTypeCode)
|
||||
ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(models.UnitTypeIssues)
|
||||
ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(models.UnitTypePullRequests)
|
||||
|
||||
if ctx.Data["CanSignedUserFork"], err = ctx.Repo.Repository.CanUserFork(ctx.User); err != nil {
|
||||
ctx.ServerError("CanUserFork", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
||||
ctx.Data["ExposeAnonSSH"] = setting.SSH.ExposeAnonymous
|
||||
ctx.Data["DisableHTTP"] = setting.Repository.DisableHTTPGit
|
||||
ctx.Data["RepoSearchEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
ctx.Data["CloneLink"] = repo.CloneLink()
|
||||
ctx.Data["WikiCloneLink"] = repo.WikiCloneLink()
|
||||
|
||||
if ctx.IsSigned {
|
||||
ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID)
|
||||
ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID)
|
||||
}
|
||||
|
||||
if repo.IsFork {
|
||||
RetrieveBaseRepo(ctx, repo)
|
||||
if ctx.Written() {
|
||||
RedirectToRepo(ctx, redirectRepoID)
|
||||
} else if models.IsErrRepoRedirectNotExist(err) {
|
||||
if ctx.Query("go-get") == "1" {
|
||||
EarlyResponseForGoGetMeta(ctx)
|
||||
return
|
||||
}
|
||||
ctx.NotFound("GetRepositoryByName", nil)
|
||||
} else {
|
||||
ctx.ServerError("LookupRepoRedirect", err)
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("GetRepositoryByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
repo.Owner = owner
|
||||
|
||||
if repo.IsGenerated() {
|
||||
RetrieveTemplateRepo(ctx, repo)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
}
|
||||
repoAssignment(ctx, repo)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
// Disable everything when the repo is being created
|
||||
if ctx.Repo.Repository.IsBeingCreated() {
|
||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
||||
return
|
||||
}
|
||||
ctx.Repo.RepoLink = repo.Link()
|
||||
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
||||
ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
||||
|
||||
gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName))
|
||||
if err != nil {
|
||||
ctx.ServerError("RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
unit, err := ctx.Repo.Repository.GetUnit(models.UnitTypeExternalTracker)
|
||||
if err == nil {
|
||||
ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL
|
||||
}
|
||||
|
||||
// We opened it, we should close it
|
||||
defer func() {
|
||||
// If it's been set to nil then assume someone else has closed it.
|
||||
if ctx.Repo.GitRepo != nil {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
}
|
||||
}()
|
||||
ctx.Data["NumTags"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{
|
||||
IncludeTags: true,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetReleaseCountByRepoID", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["NumReleases"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetReleaseCountByRepoID", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Stop at this point when the repo is empty.
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
||||
next.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
ctx.Data["Title"] = owner.Name + "/" + repo.Name
|
||||
ctx.Data["Repository"] = repo
|
||||
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
|
||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
||||
ctx.Data["RepoOwnerIsOrganization"] = repo.Owner.IsOrganization()
|
||||
ctx.Data["CanWriteCode"] = ctx.Repo.CanWrite(models.UnitTypeCode)
|
||||
ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(models.UnitTypeIssues)
|
||||
ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(models.UnitTypePullRequests)
|
||||
|
||||
tags, err := ctx.Repo.GitRepo.GetTags()
|
||||
if err != nil {
|
||||
ctx.ServerError("GetTags", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Tags"] = tags
|
||||
if ctx.Data["CanSignedUserFork"], err = ctx.Repo.Repository.CanUserFork(ctx.User); err != nil {
|
||||
ctx.ServerError("CanUserFork", err)
|
||||
return
|
||||
}
|
||||
|
||||
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBranches", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Branches"] = brs
|
||||
ctx.Data["BranchesCount"] = len(brs)
|
||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
||||
ctx.Data["ExposeAnonSSH"] = setting.SSH.ExposeAnonymous
|
||||
ctx.Data["DisableHTTP"] = setting.Repository.DisableHTTPGit
|
||||
ctx.Data["RepoSearchEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
ctx.Data["CloneLink"] = repo.CloneLink()
|
||||
ctx.Data["WikiCloneLink"] = repo.WikiCloneLink()
|
||||
|
||||
ctx.Data["TagName"] = ctx.Repo.TagName
|
||||
if ctx.IsSigned {
|
||||
ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID)
|
||||
ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID)
|
||||
}
|
||||
|
||||
// If not branch selected, try default one.
|
||||
// If default branch doesn't exists, fall back to some other branch.
|
||||
if len(ctx.Repo.BranchName) == 0 {
|
||||
if len(ctx.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
|
||||
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
|
||||
} else if len(brs) > 0 {
|
||||
ctx.Repo.BranchName = brs[0]
|
||||
}
|
||||
}
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||
if repo.IsFork {
|
||||
RetrieveBaseRepo(ctx, repo)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// People who have push access or have forked repository can propose a new pull request.
|
||||
canPush := ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID))
|
||||
canCompare := false
|
||||
if repo.IsGenerated() {
|
||||
RetrieveTemplateRepo(ctx, repo)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Pull request is allowed if this is a fork repository
|
||||
// and base repository accepts pull requests.
|
||||
if repo.BaseRepo != nil && repo.BaseRepo.AllowsPulls() {
|
||||
canCompare = true
|
||||
ctx.Data["BaseRepo"] = repo.BaseRepo
|
||||
ctx.Repo.PullRequest.BaseRepo = repo.BaseRepo
|
||||
ctx.Repo.PullRequest.Allowed = canPush
|
||||
ctx.Repo.PullRequest.HeadInfo = ctx.Repo.Owner.Name + ":" + ctx.Repo.BranchName
|
||||
} else if repo.AllowsPulls() {
|
||||
// Or, this is repository accepts pull requests between branches.
|
||||
canCompare = true
|
||||
ctx.Data["BaseRepo"] = repo
|
||||
ctx.Repo.PullRequest.BaseRepo = repo
|
||||
ctx.Repo.PullRequest.Allowed = canPush
|
||||
ctx.Repo.PullRequest.SameRepo = true
|
||||
ctx.Repo.PullRequest.HeadInfo = ctx.Repo.BranchName
|
||||
}
|
||||
ctx.Data["CanCompareOrPull"] = canCompare
|
||||
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
|
||||
// Disable everything when the repo is being created
|
||||
if ctx.Repo.Repository.IsBeingCreated() {
|
||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.Repo.Repository.Status == models.RepositoryPendingTransfer {
|
||||
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx.Repo.Repository)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPendingRepositoryTransfer", err)
|
||||
return
|
||||
}
|
||||
gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName))
|
||||
if err != nil {
|
||||
ctx.ServerError("RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
|
||||
if err := repoTransfer.LoadAttributes(); err != nil {
|
||||
ctx.ServerError("LoadRecipient", err)
|
||||
return
|
||||
}
|
||||
// We opened it, we should close it
|
||||
defer func() {
|
||||
// If it's been set to nil then assume someone else has closed it.
|
||||
if ctx.Repo.GitRepo != nil {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
ctx.Data["RepoTransfer"] = repoTransfer
|
||||
if ctx.User != nil {
|
||||
ctx.Data["CanUserAcceptTransfer"] = repoTransfer.CanUserAcceptTransfer(ctx.User)
|
||||
}
|
||||
}
|
||||
// Stop at this point when the repo is empty.
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.Query("go-get") == "1" {
|
||||
ctx.Data["GoGetImport"] = ComposeGoGetImport(owner.Name, repo.Name)
|
||||
prefix := setting.AppURL + path.Join(owner.Name, repo.Name, "src", "branch", ctx.Repo.BranchName)
|
||||
ctx.Data["GoDocDirectory"] = prefix + "{/dir}"
|
||||
ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}"
|
||||
}
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
tags, err := ctx.Repo.GitRepo.GetTags()
|
||||
if err != nil {
|
||||
ctx.ServerError("GetTags", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Tags"] = tags
|
||||
|
||||
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBranches", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Branches"] = brs
|
||||
ctx.Data["BranchesCount"] = len(brs)
|
||||
|
||||
ctx.Data["TagName"] = ctx.Repo.TagName
|
||||
|
||||
// If not branch selected, try default one.
|
||||
// If default branch doesn't exists, fall back to some other branch.
|
||||
if len(ctx.Repo.BranchName) == 0 {
|
||||
if len(ctx.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
|
||||
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
|
||||
} else if len(brs) > 0 {
|
||||
ctx.Repo.BranchName = brs[0]
|
||||
}
|
||||
}
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||
|
||||
// People who have push access or have forked repository can propose a new pull request.
|
||||
canPush := ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID))
|
||||
canCompare := false
|
||||
|
||||
// Pull request is allowed if this is a fork repository
|
||||
// and base repository accepts pull requests.
|
||||
if repo.BaseRepo != nil && repo.BaseRepo.AllowsPulls() {
|
||||
canCompare = true
|
||||
ctx.Data["BaseRepo"] = repo.BaseRepo
|
||||
ctx.Repo.PullRequest.BaseRepo = repo.BaseRepo
|
||||
ctx.Repo.PullRequest.Allowed = canPush
|
||||
ctx.Repo.PullRequest.HeadInfo = ctx.Repo.Owner.Name + ":" + ctx.Repo.BranchName
|
||||
} else if repo.AllowsPulls() {
|
||||
// Or, this is repository accepts pull requests between branches.
|
||||
canCompare = true
|
||||
ctx.Data["BaseRepo"] = repo
|
||||
ctx.Repo.PullRequest.BaseRepo = repo
|
||||
ctx.Repo.PullRequest.Allowed = canPush
|
||||
ctx.Repo.PullRequest.SameRepo = true
|
||||
ctx.Repo.PullRequest.HeadInfo = ctx.Repo.BranchName
|
||||
}
|
||||
ctx.Data["CanCompareOrPull"] = canCompare
|
||||
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
|
||||
|
||||
if ctx.Repo.Repository.Status == models.RepositoryPendingTransfer {
|
||||
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx.Repo.Repository)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPendingRepositoryTransfer", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := repoTransfer.LoadAttributes(); err != nil {
|
||||
ctx.ServerError("LoadRecipient", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["RepoTransfer"] = repoTransfer
|
||||
if ctx.User != nil {
|
||||
ctx.Data["CanUserAcceptTransfer"] = repoTransfer.CanUserAcceptTransfer(ctx.User)
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.Query("go-get") == "1" {
|
||||
ctx.Data["GoGetImport"] = ComposeGoGetImport(owner.Name, repo.Name)
|
||||
prefix := setting.AppURL + path.Join(owner.Name, repo.Name, "src", "branch", ctx.Repo.BranchName)
|
||||
ctx.Data["GoDocDirectory"] = prefix + "{/dir}"
|
||||
ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,7 +643,7 @@ const (
|
||||
|
||||
// RepoRef handles repository reference names when the ref name is not
|
||||
// explicitly given
|
||||
func RepoRef() func(http.Handler) http.Handler {
|
||||
func RepoRef() func(*Context) {
|
||||
// since no ref name is explicitly specified, ok to just use branch
|
||||
return RepoRefByType(RepoRefBranch)
|
||||
}
|
||||
@@ -730,130 +722,125 @@ func getRefName(ctx *Context, pathType RepoRefType) string {
|
||||
|
||||
// RepoRefByType handles repository reference name for a specific type
|
||||
// of repository reference
|
||||
func RepoRefByType(refType RepoRefType) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
ctx := GetContext(req)
|
||||
// Empty repository does not have reference information.
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
func RepoRefByType(refType RepoRefType) func(*Context) {
|
||||
return func(ctx *Context) {
|
||||
// Empty repository does not have reference information.
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
refName string
|
||||
err error
|
||||
)
|
||||
|
||||
if ctx.Repo.GitRepo == nil {
|
||||
repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
ctx.Repo.GitRepo, err = git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
ctx.ServerError("RepoRef Invalid repo "+repoPath, err)
|
||||
return
|
||||
}
|
||||
// We opened it, we should close it
|
||||
defer func() {
|
||||
// If it's been set to nil then assume someone else has closed it.
|
||||
if ctx.Repo.GitRepo != nil {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
var (
|
||||
refName string
|
||||
err error
|
||||
)
|
||||
|
||||
if ctx.Repo.GitRepo == nil {
|
||||
repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
ctx.Repo.GitRepo, err = git.OpenRepository(repoPath)
|
||||
// Get default branch.
|
||||
if len(ctx.Params("*")) == 0 {
|
||||
refName = ctx.Repo.Repository.DefaultBranch
|
||||
ctx.Repo.BranchName = refName
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
|
||||
if err != nil {
|
||||
ctx.ServerError("RepoRef Invalid repo "+repoPath, err)
|
||||
ctx.ServerError("GetBranches", err)
|
||||
return
|
||||
} else if len(brs) == 0 {
|
||||
err = fmt.Errorf("No branches in non-empty repository %s",
|
||||
ctx.Repo.GitRepo.Path)
|
||||
ctx.ServerError("GetBranches", err)
|
||||
return
|
||||
}
|
||||
// We opened it, we should close it
|
||||
defer func() {
|
||||
// If it's been set to nil then assume someone else has closed it.
|
||||
if ctx.Repo.GitRepo != nil {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
}
|
||||
}()
|
||||
refName = brs[0]
|
||||
}
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBranchCommit", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||
ctx.Repo.IsViewBranch = true
|
||||
|
||||
} else {
|
||||
refName = getRefName(ctx, refType)
|
||||
ctx.Repo.BranchName = refName
|
||||
if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||
ctx.Repo.IsViewBranch = true
|
||||
|
||||
// Get default branch.
|
||||
if len(ctx.Params("*")) == 0 {
|
||||
refName = ctx.Repo.Repository.DefaultBranch
|
||||
ctx.Repo.BranchName = refName
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBranches", err)
|
||||
return
|
||||
} else if len(brs) == 0 {
|
||||
err = fmt.Errorf("No branches in non-empty repository %s",
|
||||
ctx.Repo.GitRepo.Path)
|
||||
ctx.ServerError("GetBranches", err)
|
||||
return
|
||||
}
|
||||
refName = brs[0]
|
||||
}
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBranchCommit", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||
ctx.Repo.IsViewBranch = true
|
||||
|
||||
} else if refType.RefTypeIncludesTags() && ctx.Repo.GitRepo.IsTagExist(refName) {
|
||||
ctx.Repo.IsViewTag = true
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetTagCommit", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||
} else if len(refName) >= 7 && len(refName) <= 40 {
|
||||
ctx.Repo.IsViewCommit = true
|
||||
ctx.Repo.CommitID = refName
|
||||
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName)
|
||||
if err != nil {
|
||||
ctx.NotFound("GetCommit", err)
|
||||
return
|
||||
}
|
||||
// If short commit ID add canonical link header
|
||||
if len(refName) < 40 {
|
||||
ctx.Header().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"",
|
||||
util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), refName, ctx.Repo.Commit.ID.String(), 1))))
|
||||
}
|
||||
} else {
|
||||
refName = getRefName(ctx, refType)
|
||||
ctx.Repo.BranchName = refName
|
||||
if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||
ctx.Repo.IsViewBranch = true
|
||||
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBranchCommit", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||
|
||||
} else if refType.RefTypeIncludesTags() && ctx.Repo.GitRepo.IsTagExist(refName) {
|
||||
ctx.Repo.IsViewTag = true
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetTagCommit", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||
} else if len(refName) >= 7 && len(refName) <= 40 {
|
||||
ctx.Repo.IsViewCommit = true
|
||||
ctx.Repo.CommitID = refName
|
||||
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName)
|
||||
if err != nil {
|
||||
ctx.NotFound("GetCommit", err)
|
||||
return
|
||||
}
|
||||
// If short commit ID add canonical link header
|
||||
if len(refName) < 40 {
|
||||
ctx.Header().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"",
|
||||
util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), refName, ctx.Repo.Commit.ID.String(), 1))))
|
||||
}
|
||||
} else {
|
||||
ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName))
|
||||
return
|
||||
}
|
||||
|
||||
if refType == RepoRefLegacy {
|
||||
// redirect from old URL scheme to new URL scheme
|
||||
ctx.Redirect(path.Join(
|
||||
setting.AppSubURL,
|
||||
strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*")),
|
||||
ctx.Repo.BranchNameSubURL(),
|
||||
ctx.Repo.TreePath))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
|
||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
||||
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
|
||||
ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag
|
||||
ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit
|
||||
ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch()
|
||||
|
||||
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitsCount", err)
|
||||
ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName))
|
||||
return
|
||||
}
|
||||
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
|
||||
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
if refType == RepoRefLegacy {
|
||||
// redirect from old URL scheme to new URL scheme
|
||||
ctx.Redirect(path.Join(
|
||||
setting.AppSubURL,
|
||||
strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*")),
|
||||
ctx.Repo.BranchNameSubURL(),
|
||||
ctx.Repo.TreePath))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
|
||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
||||
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
|
||||
ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag
|
||||
ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit
|
||||
ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch()
|
||||
|
||||
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitsCount", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -85,18 +85,17 @@ func ToPullReviewCommentList(review *models.Review, doer *models.User) ([]*api.P
|
||||
|
||||
apiComments := make([]*api.PullReviewComment, 0, len(review.CodeComments))
|
||||
|
||||
auth := false
|
||||
if doer != nil {
|
||||
auth = doer.IsAdmin || doer.ID == review.ReviewerID
|
||||
}
|
||||
|
||||
for _, lines := range review.CodeComments {
|
||||
for _, comments := range lines {
|
||||
for _, comment := range comments {
|
||||
auth := false
|
||||
if doer != nil {
|
||||
auth = doer.IsAdmin || doer.ID == comment.Poster.ID
|
||||
}
|
||||
apiComment := &api.PullReviewComment{
|
||||
ID: comment.ID,
|
||||
Body: comment.Content,
|
||||
Reviewer: ToUser(review.Reviewer, doer != nil, auth),
|
||||
Reviewer: ToUser(comment.Poster, doer != nil, auth),
|
||||
ReviewID: review.ID,
|
||||
Created: comment.CreatedUnix.AsTime(),
|
||||
Updated: comment.UpdatedUnix.AsTime(),
|
||||
|
@@ -47,7 +47,7 @@ func GetRawDiffForFile(repoPath, startCommit, endCommit string, diffType RawDiff
|
||||
func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diffType RawDiffType, file string, writer io.Writer) error {
|
||||
commit, err := repo.GetCommit(endCommit)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetCommit: %v", err)
|
||||
return err
|
||||
}
|
||||
fileArgs := make([]string, 0)
|
||||
if len(file) > 0 {
|
||||
|
@@ -43,7 +43,7 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err
|
||||
|
||||
sizes := make(map[string]int64)
|
||||
err = tree.Files().ForEach(func(f *object.File) error {
|
||||
if f.Size == 0 || enry.IsVendor(f.Name) || enry.IsDotFile(f.Name) ||
|
||||
if f.Size == 0 || analyze.IsVendor(f.Name) || enry.IsDotFile(f.Name) ||
|
||||
enry.IsDocumentation(f.Name) || enry.IsConfiguration(f.Name) {
|
||||
return nil
|
||||
}
|
||||
|
@@ -67,7 +67,7 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err
|
||||
for _, f := range entries {
|
||||
contentBuf.Reset()
|
||||
content = contentBuf.Bytes()
|
||||
if f.Size() == 0 || enry.IsVendor(f.Name()) || enry.IsDotFile(f.Name()) ||
|
||||
if f.Size() == 0 || analyze.IsVendor(f.Name()) || enry.IsDotFile(f.Name()) ||
|
||||
enry.IsDocumentation(f.Name()) || enry.IsConfiguration(f.Name()) {
|
||||
continue
|
||||
}
|
||||
|
@@ -68,17 +68,19 @@ func (g *Manager) start() {
|
||||
// Set the running state
|
||||
g.setState(stateRunning)
|
||||
if skip, _ := strconv.ParseBool(os.Getenv("SKIP_MINWINSVC")); skip {
|
||||
log.Trace("Skipping SVC check as SKIP_MINWINSVC is set")
|
||||
return
|
||||
}
|
||||
|
||||
// Make SVC process
|
||||
run := svc.Run
|
||||
isInteractive, err := svc.IsWindowsService()
|
||||
isWindowsService, err := svc.IsWindowsService()
|
||||
if err != nil {
|
||||
log.Error("Unable to ascertain if running as an Interactive Session: %v", err)
|
||||
log.Error("Unable to ascertain if running as an Windows Service: %v", err)
|
||||
return
|
||||
}
|
||||
if isInteractive {
|
||||
if !isWindowsService {
|
||||
log.Trace("Not running a service ... using the debug SVC manager")
|
||||
run = debug.Run
|
||||
}
|
||||
go func() {
|
||||
@@ -94,38 +96,49 @@ func (g *Manager) Execute(args []string, changes <-chan svc.ChangeRequest, statu
|
||||
status <- svc.Status{State: svc.StartPending, WaitHint: uint32(setting.StartupTimeout / time.Millisecond)}
|
||||
}
|
||||
|
||||
log.Trace("Awaiting server start-up")
|
||||
// Now need to wait for everything to start...
|
||||
if !g.awaitServer(setting.StartupTimeout) {
|
||||
log.Trace("... start-up failed ... Stopped")
|
||||
return false, 1
|
||||
}
|
||||
|
||||
log.Trace("Sending Running state to SVC")
|
||||
|
||||
// We need to implement some way of svc.AcceptParamChange/svc.ParamChange
|
||||
status <- svc.Status{
|
||||
State: svc.Running,
|
||||
Accepts: svc.AcceptStop | svc.AcceptShutdown | acceptHammerCode,
|
||||
}
|
||||
|
||||
log.Trace("Started")
|
||||
|
||||
waitTime := 30 * time.Second
|
||||
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case <-g.ctx.Done():
|
||||
log.Trace("Shutting down")
|
||||
g.DoGracefulShutdown()
|
||||
waitTime += setting.GracefulHammerTime
|
||||
break loop
|
||||
case <-g.shutdownRequested:
|
||||
log.Trace("Shutting down")
|
||||
waitTime += setting.GracefulHammerTime
|
||||
break loop
|
||||
case change := <-changes:
|
||||
switch change.Cmd {
|
||||
case svc.Interrogate:
|
||||
log.Trace("SVC sent interrogate")
|
||||
status <- change.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown:
|
||||
log.Trace("SVC requested shutdown - shutting down")
|
||||
g.DoGracefulShutdown()
|
||||
waitTime += setting.GracefulHammerTime
|
||||
break loop
|
||||
case hammerCode:
|
||||
log.Trace("SVC requested hammer - shutting down and hammering immediately")
|
||||
g.DoGracefulShutdown()
|
||||
g.DoImmediateHammer()
|
||||
break loop
|
||||
@@ -134,6 +147,8 @@ loop:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Trace("Sending StopPending state to SVC")
|
||||
status <- svc.Status{
|
||||
State: svc.StopPending,
|
||||
WaitHint: uint32(waitTime / time.Millisecond),
|
||||
@@ -145,8 +160,10 @@ hammerLoop:
|
||||
case change := <-changes:
|
||||
switch change.Cmd {
|
||||
case svc.Interrogate:
|
||||
log.Trace("SVC sent interrogate")
|
||||
status <- change.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown, hammerCmd:
|
||||
log.Trace("SVC requested hammer - hammering immediately")
|
||||
g.DoImmediateHammer()
|
||||
break hammerLoop
|
||||
default:
|
||||
@@ -156,6 +173,8 @@ hammerLoop:
|
||||
break hammerLoop
|
||||
}
|
||||
}
|
||||
|
||||
log.Trace("Stopped")
|
||||
return false, 0
|
||||
}
|
||||
|
||||
|
@@ -178,7 +178,7 @@ func NewBleveIndexer(indexDir string) (*BleveIndexer, bool, error) {
|
||||
|
||||
func (b *BleveIndexer) addUpdate(batchWriter *io.PipeWriter, batchReader *bufio.Reader, commitSha string, update fileUpdate, repo *models.Repository, batch rupture.FlushingBatch) error {
|
||||
// Ignore vendored files in code search
|
||||
if setting.Indexer.ExcludeVendored && enry.IsVendor(update.Filename) {
|
||||
if setting.Indexer.ExcludeVendored && analyze.IsVendor(update.Filename) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -177,7 +177,7 @@ func (b *ElasticSearchIndexer) init() (bool, error) {
|
||||
|
||||
func (b *ElasticSearchIndexer) addUpdate(batchWriter *io.PipeWriter, batchReader *bufio.Reader, sha string, update fileUpdate, repo *models.Repository) ([]elastic.BulkableRequest, error) {
|
||||
// Ignore vendored files in code search
|
||||
if setting.Indexer.ExcludeVendored && enry.IsVendor(update.Filename) {
|
||||
if setting.Indexer.ExcludeVendored && analyze.IsVendor(update.Filename) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@@ -44,24 +44,13 @@ type ContentStore struct {
|
||||
}
|
||||
|
||||
// Get takes a Meta object and retrieves the content from the store, returning
|
||||
// it as an io.Reader. If fromByte > 0, the reader starts from that byte
|
||||
func (s *ContentStore) Get(meta *models.LFSMetaObject, fromByte int64) (io.ReadCloser, error) {
|
||||
// it as an io.ReadSeekCloser.
|
||||
func (s *ContentStore) Get(meta *models.LFSMetaObject) (storage.Object, error) {
|
||||
f, err := s.Open(meta.RelativePath())
|
||||
if err != nil {
|
||||
log.Error("Whilst trying to read LFS OID[%s]: Unable to open Error: %v", meta.Oid, err)
|
||||
return nil, err
|
||||
}
|
||||
if fromByte > 0 {
|
||||
if fromByte >= meta.Size {
|
||||
return nil, ErrRangeNotSatisfiable{
|
||||
FromByte: fromByte,
|
||||
}
|
||||
}
|
||||
_, err = f.Seek(fromByte, io.SeekStart)
|
||||
if err != nil {
|
||||
log.Error("Whilst trying to read LFS OID[%s]: Unable to seek to %d Error: %v", meta.Oid, fromByte, err)
|
||||
}
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
|
||||
@@ -74,7 +63,7 @@ func (s *ContentStore) Put(meta *models.LFSMetaObject, r io.Reader) error {
|
||||
|
||||
// now pass the wrapped reader to Save - if there is a size mismatch or hash mismatch then
|
||||
// the errors returned by the newHashingReader should percolate up to here
|
||||
written, err := s.Save(p, wrappedRd)
|
||||
written, err := s.Save(p, wrappedRd, meta.Size)
|
||||
if err != nil {
|
||||
log.Error("Whilst putting LFS OID[%s]: Failed to copy to tmpPath: %s Error: %v", meta.Oid, p, err)
|
||||
return err
|
||||
|
@@ -67,5 +67,5 @@ func IsPointerFile(buf *[]byte) *models.LFSMetaObject {
|
||||
// ReadMetaObject will read a models.LFSMetaObject and return a reader
|
||||
func ReadMetaObject(meta *models.LFSMetaObject) (io.ReadCloser, error) {
|
||||
contentStore := &ContentStore{ObjectStorage: storage.LFS}
|
||||
return contentStore.Get(meta, 0)
|
||||
return contentStore.Get(meta)
|
||||
}
|
||||
|
@@ -175,6 +175,11 @@ func getContentHandler(ctx *context.Context) {
|
||||
statusCode = 206
|
||||
fromByte, _ = strconv.ParseInt(match[1], 10, 32)
|
||||
|
||||
if fromByte >= meta.Size {
|
||||
writeStatus(ctx, http.StatusRequestedRangeNotSatisfiable)
|
||||
return
|
||||
}
|
||||
|
||||
if match[2] != "" {
|
||||
_toByte, _ := strconv.ParseInt(match[2], 10, 32)
|
||||
if _toByte >= fromByte && _toByte < toByte {
|
||||
@@ -188,18 +193,24 @@ func getContentHandler(ctx *context.Context) {
|
||||
}
|
||||
|
||||
contentStore := &ContentStore{ObjectStorage: storage.LFS}
|
||||
content, err := contentStore.Get(meta, fromByte)
|
||||
content, err := contentStore.Get(meta)
|
||||
if err != nil {
|
||||
if IsErrRangeNotSatisfiable(err) {
|
||||
writeStatus(ctx, http.StatusRequestedRangeNotSatisfiable)
|
||||
} else {
|
||||
// Errors are logged in contentStore.Get
|
||||
writeStatus(ctx, 404)
|
||||
}
|
||||
// Errors are logged in contentStore.Get
|
||||
writeStatus(ctx, http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
defer content.Close()
|
||||
|
||||
if fromByte > 0 {
|
||||
_, err = content.Seek(fromByte, io.SeekStart)
|
||||
if err != nil {
|
||||
log.Error("Whilst trying to read LFS OID[%s]: Unable to seek to %d Error: %v", meta.Oid, fromByte, err)
|
||||
|
||||
writeStatus(ctx, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
contentLength := toByte + 1 - fromByte
|
||||
ctx.Resp.Header().Set("Content-Length", strconv.FormatInt(contentLength, 10))
|
||||
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
|
||||
|
@@ -313,7 +313,7 @@ func RenderEmoji(
|
||||
return ctx.postProcess(rawHTML)
|
||||
}
|
||||
|
||||
var tagCleaner = regexp.MustCompile(`<((?:/?\w+/\w+)|(?:/[\w ]+/)|(/?[hH][tT][mM][lL][ />])|(/?[hH][eE][aA][dD][ />]))`)
|
||||
var tagCleaner = regexp.MustCompile(`<((?:/?\w+/\w+)|(?:/[\w ]+/)|(/?[hH][tT][mM][lL]\b)|(/?[hH][eE][aA][dD]\b))`)
|
||||
var nulCleaner = strings.NewReplacer("\000", "")
|
||||
|
||||
func (ctx *postProcessCtx) postProcess(rawHTML []byte) ([]byte, error) {
|
||||
@@ -327,7 +327,7 @@ func (ctx *postProcessCtx) postProcess(rawHTML []byte) ([]byte, error) {
|
||||
_, _ = res.WriteString("<html><body>")
|
||||
|
||||
// Strip out nuls - they're always invalid
|
||||
_, _ = nulCleaner.WriteString(res, string(tagCleaner.ReplaceAll(rawHTML, []byte("<$1"))))
|
||||
_, _ = res.Write(tagCleaner.ReplaceAll([]byte(nulCleaner.Replace(string(rawHTML))), []byte("<$1")))
|
||||
|
||||
// close the tags
|
||||
_, _ = res.WriteString("</body></html>")
|
||||
|
@@ -124,7 +124,7 @@ func TestRender_links(t *testing.T) {
|
||||
`<p><a href="http://www.example.com/wpstyle/?p=364" rel="nofollow">http://www.example.com/wpstyle/?p=364</a></p>`)
|
||||
test(
|
||||
"https://www.example.com/foo/?bar=baz&inga=42&quux",
|
||||
`<p><a href="https://www.example.com/foo/?bar=baz&inga=42&quux=" rel="nofollow">https://www.example.com/foo/?bar=baz&inga=42&quux</a></p>`)
|
||||
`<p><a href="https://www.example.com/foo/?bar=baz&inga=42&quux" rel="nofollow">https://www.example.com/foo/?bar=baz&inga=42&quux</a></p>`)
|
||||
test(
|
||||
"http://142.42.1.1/",
|
||||
`<p><a href="http://142.42.1.1/" rel="nofollow">http://142.42.1.1/</a></p>`)
|
||||
|
@@ -46,7 +46,9 @@ func ReplaceSanitizer() {
|
||||
sanitizer.policy.AllowAttrs("checked", "disabled").OnElements("input")
|
||||
|
||||
// Custom URL-Schemes
|
||||
sanitizer.policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...)
|
||||
if len(setting.Markdown.CustomURLSchemes) > 0 {
|
||||
sanitizer.policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...)
|
||||
}
|
||||
|
||||
// Allow keyword markup
|
||||
sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^` + keywordClass + `$`)).OnElements("span")
|
||||
|
@@ -6,6 +6,8 @@
|
||||
package markup
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -50,3 +52,13 @@ func Test_Sanitizer(t *testing.T) {
|
||||
assert.Equal(t, testCases[i+1], string(SanitizeBytes([]byte(testCases[i]))))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizeNonEscape(t *testing.T) {
|
||||
descStr := "<scrİpt><script>alert(document.domain)</script></scrİpt>"
|
||||
|
||||
output := template.HTML(Sanitize(string(descStr)))
|
||||
if strings.Contains(string(output), "<script>") {
|
||||
t.Errorf("un-escaped <script> in output: %q", output)
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -525,9 +525,6 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques
|
||||
headRepoName = pr.Head.Repository.Name
|
||||
headCloneURL = pr.Head.Repository.CloneURL
|
||||
}
|
||||
if err := fixPullHeadSha(g.client, pr); err != nil {
|
||||
return nil, false, fmt.Errorf("error while resolving head git ref: %s for pull #%d. Error: %v", pr.Head.Ref, pr.Index, err)
|
||||
}
|
||||
headSHA = pr.Head.Sha
|
||||
headRef = pr.Head.Ref
|
||||
}
|
||||
@@ -679,22 +676,3 @@ func (g *GiteaDownloader) GetReviews(index int64) ([]*base.Review, error) {
|
||||
}
|
||||
return allReviews, nil
|
||||
}
|
||||
|
||||
// fixPullHeadSha is a workaround for https://github.com/go-gitea/gitea/issues/12675
|
||||
// When no head sha is available, this is because the branch got deleted in the base repo.
|
||||
// pr.Head.Ref points in this case not to the head repo branch name, but the base repo ref,
|
||||
// which stays available to resolve the commit sha.
|
||||
func fixPullHeadSha(client *gitea_sdk.Client, pr *gitea_sdk.PullRequest) error {
|
||||
owner := pr.Base.Repository.Owner.UserName
|
||||
repo := pr.Base.Repository.Name
|
||||
if pr.Head != nil && pr.Head.Sha == "" {
|
||||
refs, _, err := client.GetRepoRefs(owner, repo, pr.Head.Ref)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(refs) == 0 {
|
||||
return fmt.Errorf("unable to resolve PR ref '%s'", pr.Head.Ref)
|
||||
}
|
||||
pr.Head.Sha = refs[0].Object.SHA
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -283,7 +283,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
|
||||
}
|
||||
}
|
||||
defer rc.Close()
|
||||
_, err = storage.Attachments.Save(attach.RelativePath(), rc)
|
||||
_, err = storage.Attachments.Save(attach.RelativePath(), rc, int64(*asset.Size))
|
||||
return err
|
||||
}()
|
||||
if err != nil {
|
||||
|
@@ -332,7 +332,8 @@ func (a *actionNotifier) NotifyPushCommits(pusher *models.User, repo *models.Rep
|
||||
func (a *actionNotifier) NotifyCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) {
|
||||
opType := models.ActionCommitRepo
|
||||
if refType == "tag" {
|
||||
opType = models.ActionPushTag
|
||||
// has sent same action in `NotifyPushCommits`, so skip it.
|
||||
return
|
||||
}
|
||||
if err := models.NotifyWatchers(&models.Action{
|
||||
ActUserID: doer.ID,
|
||||
@@ -350,7 +351,8 @@ func (a *actionNotifier) NotifyCreateRef(doer *models.User, repo *models.Reposit
|
||||
func (a *actionNotifier) NotifyDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) {
|
||||
opType := models.ActionDeleteBranch
|
||||
if refType == "tag" {
|
||||
opType = models.ActionDeleteTag
|
||||
// has sent same action in `NotifyPushCommits`, so skip it.
|
||||
return
|
||||
}
|
||||
if err := models.NotifyWatchers(&models.Action{
|
||||
ActUserID: doer.ID,
|
||||
|
@@ -27,6 +27,7 @@ type Options struct {
|
||||
// KnownPublicEntries list all direct children in the `public` directory
|
||||
var KnownPublicEntries = []string{
|
||||
"css",
|
||||
"fonts",
|
||||
"img",
|
||||
"js",
|
||||
"serviceworker.js",
|
||||
|
@@ -174,6 +174,7 @@ func (m *Manager) FlushAll(baseCtx context.Context, timeout time.Duration) error
|
||||
default:
|
||||
}
|
||||
mqs := m.ManagedQueues()
|
||||
log.Debug("Found %d Managed Queues", len(mqs))
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(len(mqs))
|
||||
allEmpty := true
|
||||
@@ -184,6 +185,7 @@ func (m *Manager) FlushAll(baseCtx context.Context, timeout time.Duration) error
|
||||
}
|
||||
allEmpty = false
|
||||
if flushable, ok := mq.Managed.(Flushable); ok {
|
||||
log.Debug("Flushing (flushable) queue: %s", mq.Name)
|
||||
go func(q *ManagedQueue) {
|
||||
localCtx, localCancel := context.WithCancel(ctx)
|
||||
pid := q.RegisterWorkers(1, start, hasTimeout, end, localCancel, true)
|
||||
@@ -196,7 +198,11 @@ func (m *Manager) FlushAll(baseCtx context.Context, timeout time.Duration) error
|
||||
wg.Done()
|
||||
}(mq)
|
||||
} else {
|
||||
wg.Done()
|
||||
log.Debug("Queue: %s is non-empty but is not flushable - adding 100 millisecond wait", mq.Name)
|
||||
go func() {
|
||||
<-time.After(100 * time.Millisecond)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -99,42 +99,10 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
||||
}
|
||||
|
||||
// Copy uploaded files into repository.
|
||||
for i, uploadInfo := range infos {
|
||||
file, err := os.Open(uploadInfo.upload.LocalPath())
|
||||
if err != nil {
|
||||
for i := range infos {
|
||||
if err := copyUploadedLFSFileIntoRepository(&infos[i], filename2attribute2info, t, opts.TreePath); err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var objectHash string
|
||||
if setting.LFS.StartServer && filename2attribute2info[uploadInfo.upload.Name] != nil && filename2attribute2info[uploadInfo.upload.Name]["filter"] == "lfs" {
|
||||
// Handle LFS
|
||||
// FIXME: Inefficient! this should probably happen in models.Upload
|
||||
oid, err := models.GenerateLFSOid(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uploadInfo.lfsMetaObject = &models.LFSMetaObject{Oid: oid, Size: fileInfo.Size(), RepositoryID: t.repo.ID}
|
||||
|
||||
if objectHash, err = t.HashObject(strings.NewReader(uploadInfo.lfsMetaObject.Pointer())); err != nil {
|
||||
return err
|
||||
}
|
||||
infos[i] = uploadInfo
|
||||
|
||||
} else if objectHash, err = t.HashObject(file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add the object to the index
|
||||
if err := t.AddObjectToIndex("100644", objectHash, path.Join(opts.TreePath, uploadInfo.upload.Name)); err != nil {
|
||||
return err
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Now write the tree
|
||||
@@ -154,11 +122,11 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
||||
}
|
||||
|
||||
// Now deal with LFS objects
|
||||
for _, uploadInfo := range infos {
|
||||
if uploadInfo.lfsMetaObject == nil {
|
||||
for i := range infos {
|
||||
if infos[i].lfsMetaObject == nil {
|
||||
continue
|
||||
}
|
||||
uploadInfo.lfsMetaObject, err = models.NewLFSMetaObject(uploadInfo.lfsMetaObject)
|
||||
infos[i].lfsMetaObject, err = models.NewLFSMetaObject(infos[i].lfsMetaObject)
|
||||
if err != nil {
|
||||
// OK Now we need to cleanup
|
||||
return cleanUpAfterFailure(&infos, t, err)
|
||||
@@ -170,28 +138,10 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
||||
// OK now we can insert the data into the store - there's no way to clean up the store
|
||||
// once it's in there, it's in there.
|
||||
contentStore := &lfs.ContentStore{ObjectStorage: storage.LFS}
|
||||
for _, uploadInfo := range infos {
|
||||
if uploadInfo.lfsMetaObject == nil {
|
||||
continue
|
||||
}
|
||||
exist, err := contentStore.Exists(uploadInfo.lfsMetaObject)
|
||||
if err != nil {
|
||||
for _, info := range infos {
|
||||
if err := uploadToLFSContentStore(info, contentStore); err != nil {
|
||||
return cleanUpAfterFailure(&infos, t, err)
|
||||
}
|
||||
if !exist {
|
||||
file, err := os.Open(uploadInfo.upload.LocalPath())
|
||||
if err != nil {
|
||||
return cleanUpAfterFailure(&infos, t, err)
|
||||
}
|
||||
defer file.Close()
|
||||
// FIXME: Put regenerates the hash and copies the file over.
|
||||
// I guess this strictly ensures the soundness of the store but this is inefficient.
|
||||
if err := contentStore.Put(uploadInfo.lfsMetaObject, file); err != nil {
|
||||
// OK Now we need to cleanup
|
||||
// Can't clean up the store, once uploaded there they're there.
|
||||
return cleanUpAfterFailure(&infos, t, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then push this tree to NewBranch
|
||||
@@ -201,3 +151,62 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
||||
|
||||
return models.DeleteUploads(uploads...)
|
||||
}
|
||||
|
||||
func copyUploadedLFSFileIntoRepository(info *uploadInfo, filename2attribute2info map[string]map[string]string, t *TemporaryUploadRepository, treePath string) error {
|
||||
file, err := os.Open(info.upload.LocalPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var objectHash string
|
||||
if setting.LFS.StartServer && filename2attribute2info[info.upload.Name] != nil && filename2attribute2info[info.upload.Name]["filter"] == "lfs" {
|
||||
// Handle LFS
|
||||
// FIXME: Inefficient! this should probably happen in models.Upload
|
||||
oid, err := models.GenerateLFSOid(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
info.lfsMetaObject = &models.LFSMetaObject{Oid: oid, Size: fileInfo.Size(), RepositoryID: t.repo.ID}
|
||||
|
||||
if objectHash, err = t.HashObject(strings.NewReader(info.lfsMetaObject.Pointer())); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if objectHash, err = t.HashObject(file); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add the object to the index
|
||||
return t.AddObjectToIndex("100644", objectHash, path.Join(treePath, info.upload.Name))
|
||||
}
|
||||
|
||||
func uploadToLFSContentStore(info uploadInfo, contentStore *lfs.ContentStore) error {
|
||||
if info.lfsMetaObject == nil {
|
||||
return nil
|
||||
}
|
||||
exist, err := contentStore.Exists(info.lfsMetaObject)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
file, err := os.Open(info.upload.LocalPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
// FIXME: Put regenerates the hash and copies the file over.
|
||||
// I guess this strictly ensures the soundness of the store but this is inefficient.
|
||||
if err := contentStore.Put(info.lfsMetaObject, file); err != nil {
|
||||
// OK Now we need to cleanup
|
||||
// Can't clean up the store, once uploaded there they're there.
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -66,7 +66,7 @@ func (l *LocalStorage) Open(path string) (Object, error) {
|
||||
}
|
||||
|
||||
// Save a file
|
||||
func (l *LocalStorage) Save(path string, r io.Reader) (int64, error) {
|
||||
func (l *LocalStorage) Save(path string, r io.Reader, size int64) (int64, error) {
|
||||
p := filepath.Join(l.dir, path)
|
||||
if err := os.MkdirAll(filepath.Dir(p), os.ModePerm); err != nil {
|
||||
return 0, err
|
||||
|
@@ -131,13 +131,13 @@ func (m *MinioStorage) Open(path string) (Object, error) {
|
||||
}
|
||||
|
||||
// Save save a file to minio
|
||||
func (m *MinioStorage) Save(path string, r io.Reader) (int64, error) {
|
||||
func (m *MinioStorage) Save(path string, r io.Reader, size int64) (int64, error) {
|
||||
uploadInfo, err := m.client.PutObject(
|
||||
m.ctx,
|
||||
m.bucket,
|
||||
m.buildMinioPath(path),
|
||||
r,
|
||||
-1,
|
||||
size,
|
||||
minio.PutObjectOptions{ContentType: "application/octet-stream"},
|
||||
)
|
||||
if err != nil {
|
||||
|
@@ -65,7 +65,8 @@ type Object interface {
|
||||
// ObjectStorage represents an object storage to handle a bucket and files
|
||||
type ObjectStorage interface {
|
||||
Open(path string) (Object, error)
|
||||
Save(path string, r io.Reader) (int64, error)
|
||||
// Save store a object, if size is unknown set -1
|
||||
Save(path string, r io.Reader, size int64) (int64, error)
|
||||
Stat(path string) (os.FileInfo, error)
|
||||
Delete(path string) error
|
||||
URL(path, name string) (*url.URL, error)
|
||||
@@ -80,7 +81,13 @@ func Copy(dstStorage ObjectStorage, dstPath string, srcStorage ObjectStorage, sr
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return dstStorage.Save(dstPath, f)
|
||||
size := int64(-1)
|
||||
fsinfo, err := f.Stat()
|
||||
if err == nil {
|
||||
size = fsinfo.Size()
|
||||
}
|
||||
|
||||
return dstStorage.Save(dstPath, f, size)
|
||||
}
|
||||
|
||||
// SaveFrom saves data to the ObjectStorage with path p from the callback
|
||||
@@ -94,7 +101,7 @@ func SaveFrom(objStorage ObjectStorage, p string, callback func(w io.Writer) err
|
||||
}
|
||||
}()
|
||||
|
||||
_, err := objStorage.Save(p, pr)
|
||||
_, err := objStorage.Save(p, pr, -1)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@@ -68,10 +68,11 @@ func Wrap(handlers ...interface{}) http.HandlerFunc {
|
||||
}
|
||||
case func(http.Handler) http.Handler:
|
||||
var next = http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})
|
||||
t(next).ServeHTTP(resp, req)
|
||||
if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 {
|
||||
return
|
||||
if len(handlers) > i+1 {
|
||||
next = Wrap(handlers[i+1:]...)
|
||||
}
|
||||
t(next).ServeHTTP(resp, req)
|
||||
return
|
||||
default:
|
||||
panic(fmt.Sprintf("Unsupported handler type: %#v", t))
|
||||
}
|
||||
|
@@ -16,7 +16,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
@@ -113,11 +112,7 @@ func SearchIssues(ctx *context.APIContext) {
|
||||
}
|
||||
|
||||
// find repos user can access (for issue search)
|
||||
repoIDs := make([]int64, 0)
|
||||
opts := &models.SearchRepoOptions{
|
||||
ListOptions: models.ListOptions{
|
||||
PageSize: 15,
|
||||
},
|
||||
Private: false,
|
||||
AllPublic: true,
|
||||
TopicOnly: false,
|
||||
@@ -132,21 +127,10 @@ func SearchIssues(ctx *context.APIContext) {
|
||||
opts.AllLimited = true
|
||||
}
|
||||
|
||||
for page := 1; ; page++ {
|
||||
opts.Page = page
|
||||
repos, count, err := models.SearchRepositoryByName(opts)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(repos) == 0 {
|
||||
break
|
||||
}
|
||||
log.Trace("Processing next %d repos of %d", len(repos), count)
|
||||
for _, repo := range repos {
|
||||
repoIDs = append(repoIDs, repo.ID)
|
||||
}
|
||||
repoIDs, _, err := models.SearchRepositoryIDs(opts)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err)
|
||||
return
|
||||
}
|
||||
|
||||
var issues []*models.Issue
|
||||
@@ -157,7 +141,6 @@ func SearchIssues(ctx *context.APIContext) {
|
||||
keyword = ""
|
||||
}
|
||||
var issueIDs []int64
|
||||
var labelIDs []int64
|
||||
if len(keyword) > 0 && len(repoIDs) > 0 {
|
||||
if issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "SearchIssuesByKeyword", err)
|
||||
@@ -192,7 +175,7 @@ func SearchIssues(ctx *context.APIContext) {
|
||||
|
||||
// Only fetch the issues if we either don't have a keyword or the search returned issues
|
||||
// This would otherwise return all issues if no issues were found by the search.
|
||||
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
|
||||
if len(keyword) == 0 || len(issueIDs) > 0 || len(includedLabelNames) > 0 {
|
||||
issuesOpt := &models.IssuesOptions{
|
||||
ListOptions: models.ListOptions{
|
||||
Page: ctx.QueryInt("page"),
|
||||
|
@@ -274,7 +274,11 @@ func DeleteOauth2Application(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/empty"
|
||||
appID := ctx.ParamsInt64(":id")
|
||||
if err := models.DeleteOAuth2Application(appID, ctx.User.ID); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteOauth2ApplicationByID", err)
|
||||
if models.IsErrOAuthApplicationNotFound(err) {
|
||||
ctx.NotFound()
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteOauth2ApplicationByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,17 @@ func Events(ctx *context.Context) {
|
||||
ctx.Resp.Header().Set("X-Accel-Buffering", "no")
|
||||
ctx.Resp.WriteHeader(http.StatusOK)
|
||||
|
||||
if !ctx.IsSigned {
|
||||
// Return unauthorized status event
|
||||
event := (&eventsource.Event{
|
||||
Name: "close",
|
||||
Data: "unauthorized",
|
||||
})
|
||||
_, _ = event.WriteTo(ctx)
|
||||
ctx.Resp.Flush()
|
||||
return
|
||||
}
|
||||
|
||||
// Listen to connection close and un-register messageChan
|
||||
notify := ctx.Req.Context().Done()
|
||||
ctx.Resp.Flush()
|
||||
|
@@ -6,6 +6,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
@@ -389,6 +390,11 @@ func RawDiff(ctx *context.Context) {
|
||||
git.RawDiffType(ctx.Params(":ext")),
|
||||
ctx.Resp,
|
||||
); err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound("GetRawDiff",
|
||||
errors.New("commit "+ctx.Params(":sha")+" does not exist."))
|
||||
return
|
||||
}
|
||||
ctx.ServerError("GetRawDiff", err)
|
||||
return
|
||||
}
|
||||
|
@@ -431,11 +431,15 @@ func PrepareCompareDiff(
|
||||
ctx.Data["IsNothingToCompare"] = true
|
||||
if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil {
|
||||
config := unit.PullRequestsConfig()
|
||||
|
||||
if !config.AutodetectManualMerge {
|
||||
ctx.Data["AllowEmptyPr"] = !(baseBranch == headBranch && ctx.Repo.Repository.Name == headRepo.Name)
|
||||
} else {
|
||||
ctx.Data["AllowEmptyPr"] = false
|
||||
allowEmptyPr := !(baseBranch == headBranch && ctx.Repo.Repository.Name == headRepo.Name)
|
||||
ctx.Data["AllowEmptyPr"] = allowEmptyPr
|
||||
|
||||
return !allowEmptyPr
|
||||
}
|
||||
|
||||
ctx.Data["AllowEmptyPr"] = false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@@ -192,6 +192,9 @@ func CreatePost(ctx *context.Context) {
|
||||
ctx.Data["Licenses"] = models.Licenses
|
||||
ctx.Data["Readmes"] = models.Readmes
|
||||
|
||||
ctx.Data["CanCreateRepo"] = ctx.User.CanCreateRepo()
|
||||
ctx.Data["MaxCreationLimit"] = ctx.User.MaxCreationLimit()
|
||||
|
||||
ctxUser := checkContextUser(ctx, form.UID)
|
||||
if ctx.Written() {
|
||||
return
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -87,13 +88,21 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(req.URL.RequestURI(), "/"+prefix) {
|
||||
prefix := strings.Trim(prefix, "/")
|
||||
|
||||
if !strings.HasPrefix(req.URL.EscapedPath(), "/"+prefix+"/") {
|
||||
next.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
rPath := strings.TrimPrefix(req.URL.RequestURI(), "/"+prefix)
|
||||
rPath := strings.TrimPrefix(req.URL.EscapedPath(), "/"+prefix+"/")
|
||||
rPath = strings.TrimPrefix(rPath, "/")
|
||||
if rPath == "" {
|
||||
http.Error(w, "file not found", 404)
|
||||
return
|
||||
}
|
||||
rPath = path.Clean("/" + filepath.ToSlash(rPath))
|
||||
rPath = rPath[1:]
|
||||
|
||||
fi, err := objStore.Stat(rPath)
|
||||
if err == nil && httpcache.HandleTimeCache(req, w, fi) {
|
||||
|
@@ -168,15 +168,6 @@ func WebRoutes() *web.Route {
|
||||
r.Use(h)
|
||||
}
|
||||
|
||||
if (setting.Protocol == setting.FCGI || setting.Protocol == setting.FCGIUnix) && setting.AppSubURL != "" {
|
||||
r.Use(func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
||||
req.URL.Path = strings.TrimPrefix(req.URL.Path, setting.AppSubURL)
|
||||
next.ServeHTTP(resp, req)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
mailer.InitMailRender(templates.Mailer())
|
||||
|
||||
if setting.Service.EnableCaptcha {
|
||||
@@ -400,7 +391,7 @@ func RegisterRoutes(m *web.Route) {
|
||||
})
|
||||
}, reqSignOut)
|
||||
|
||||
m.Any("/user/events", reqSignIn, events.Events)
|
||||
m.Any("/user/events", events.Events)
|
||||
|
||||
m.Group("/login/oauth", func() {
|
||||
m.Get("/authorize", bindIgnErr(auth.AuthorizationForm{}), user.AuthorizeOAuth)
|
||||
@@ -700,7 +691,7 @@ func RegisterRoutes(m *web.Route) {
|
||||
}, reqSignIn)
|
||||
|
||||
// ***** Release Attachment Download without Signin
|
||||
m.Get("/{username}/{reponame}/releases/download/{vTag}/{fileName}", ignSignIn, context.RepoAssignment(), repo.MustBeNotEmpty, repo.RedirectDownload)
|
||||
m.Get("/{username}/{reponame}/releases/download/{vTag}/{fileName}", ignSignIn, context.RepoAssignment, repo.MustBeNotEmpty, repo.RedirectDownload)
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/settings", func() {
|
||||
@@ -780,9 +771,9 @@ func RegisterRoutes(m *web.Route) {
|
||||
ctx.Data["PageIsSettings"] = true
|
||||
ctx.Data["LFSStartServer"] = setting.LFS.StartServer
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoAdmin, context.RepoRef())
|
||||
}, reqSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoAdmin, context.RepoRef())
|
||||
|
||||
m.Post("/{username}/{reponame}/action/{action}", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action)
|
||||
m.Post("/{username}/{reponame}/action/{action}", reqSignIn, context.RepoAssignment, context.UnitTypes(), repo.Action)
|
||||
|
||||
// Grouping for those endpoints not requiring authentication
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
@@ -792,7 +783,7 @@ func RegisterRoutes(m *web.Route) {
|
||||
m.Combo("/compare/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists).
|
||||
Get(ignSignIn, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff).
|
||||
Post(reqSignIn, context.RepoMustNotBeArchived(), reqRepoPullsReader, repo.MustAllowPulls, bindIgnErr(auth.CreateIssueForm{}), repo.SetWhitespaceBehavior, repo.CompareAndPullRequestPost)
|
||||
}, context.RepoAssignment(), context.UnitTypes())
|
||||
}, context.RepoAssignment, context.UnitTypes())
|
||||
|
||||
// Grouping for those endpoints that do require authentication
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
@@ -899,7 +890,7 @@ func RegisterRoutes(m *web.Route) {
|
||||
m.Post("/restore", repo.RestoreBranchPost)
|
||||
}, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty)
|
||||
|
||||
}, reqSignIn, context.RepoAssignment(), context.UnitTypes())
|
||||
}, reqSignIn, context.RepoAssignment, context.UnitTypes())
|
||||
|
||||
// Releases
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
@@ -937,11 +928,11 @@ func RegisterRoutes(m *web.Route) {
|
||||
}
|
||||
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
|
||||
})
|
||||
}, ignSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoReleaseReader)
|
||||
}, ignSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoReleaseReader)
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Post("/topics", repo.TopicsPost)
|
||||
}, context.RepoAssignment(), context.RepoMustNotBeArchived(), reqRepoAdmin)
|
||||
}, context.RepoAssignment, context.RepoMustNotBeArchived(), reqRepoAdmin)
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("", func() {
|
||||
@@ -1089,17 +1080,17 @@ func RegisterRoutes(m *web.Route) {
|
||||
}, context.RepoRef(), reqRepoCodeReader)
|
||||
m.Get("/commit/{sha:([a-f0-9]{7,40})}.{ext:patch|diff}",
|
||||
repo.MustBeNotEmpty, reqRepoCodeReader, repo.RawDiff)
|
||||
}, ignSignIn, context.RepoAssignment(), context.UnitTypes())
|
||||
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Get("/stars", repo.Stars)
|
||||
m.Get("/watchers", repo.Watchers)
|
||||
m.Get("/search", reqRepoCodeReader, repo.Search)
|
||||
}, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes())
|
||||
}, ignSignIn, context.RepoAssignment, context.RepoRef(), context.UnitTypes())
|
||||
|
||||
m.Group("/{username}", func() {
|
||||
m.Group("/{reponame}", func() {
|
||||
m.Get("", repo.SetEditorconfigIfExists, repo.Home)
|
||||
}, goGet, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes())
|
||||
}, goGet, ignSignIn, context.RepoAssignment, context.RepoRef(), context.UnitTypes())
|
||||
|
||||
m.Group("/{reponame}", func() {
|
||||
m.Group("/info/lfs", func() {
|
||||
|
@@ -1014,6 +1014,11 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
|
||||
}
|
||||
diffLine := &DiffLine{Type: DiffLineAdd, RightIdx: rightLine}
|
||||
rightLine++
|
||||
if curSection == nil {
|
||||
// Create a new section to represent this hunk
|
||||
curSection = &DiffSection{}
|
||||
curFile.Sections = append(curFile.Sections, curSection)
|
||||
}
|
||||
curSection.Lines = append(curSection.Lines, diffLine)
|
||||
case '-':
|
||||
curFileLinesCount++
|
||||
@@ -1026,6 +1031,11 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
|
||||
if leftLine > 0 {
|
||||
leftLine++
|
||||
}
|
||||
if curSection == nil {
|
||||
// Create a new section to represent this hunk
|
||||
curSection = &DiffSection{}
|
||||
curFile.Sections = append(curFile.Sections, curSection)
|
||||
}
|
||||
curSection.Lines = append(curSection.Lines, diffLine)
|
||||
case ' ':
|
||||
curFileLinesCount++
|
||||
@@ -1036,6 +1046,11 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
|
||||
diffLine := &DiffLine{Type: DiffLinePlain, LeftIdx: leftLine, RightIdx: rightLine}
|
||||
leftLine++
|
||||
rightLine++
|
||||
if curSection == nil {
|
||||
// Create a new section to represent this hunk
|
||||
curSection = &DiffSection{}
|
||||
curFile.Sections = append(curFile.Sections, curSection)
|
||||
}
|
||||
curSection.Lines = append(curSection.Lines, diffLine)
|
||||
default:
|
||||
// This is unexpected
|
||||
@@ -1288,6 +1303,14 @@ func CommentAsDiff(c *models.Comment) (*Diff, error) {
|
||||
|
||||
// CommentMustAsDiff executes AsDiff and logs the error instead of returning
|
||||
func CommentMustAsDiff(c *models.Comment) *Diff {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Error("PANIC whilst retrieving diff for comment[%d] Error: %v\nStack: %s", c.ID, err, log.Stack(2))
|
||||
}
|
||||
}()
|
||||
diff, err := CommentAsDiff(c)
|
||||
if err != nil {
|
||||
log.Warn("CommentMustAsDiff: %v", err)
|
||||
|
@@ -64,7 +64,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
||||
pr.Merger = doer
|
||||
pr.MergerID = doer.ID
|
||||
|
||||
if _, err = pr.SetMerged(); err != nil {
|
||||
if _, err := pr.SetMerged(); err != nil {
|
||||
log.Error("setMerged [%d]: %v", pr.ID, err)
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<div class="twelve wide field">
|
||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
|
||||
</div>
|
||||
<div class="two wide field">
|
||||
<div class="two wide field mx-2">
|
||||
<select name="t">
|
||||
<option value="">{{.i18n.Tr "explore.search.fuzzy"}}</option>
|
||||
<option value="match" {{if eq .queryType "match"}}selected{{end}}>{{.i18n.Tr "explore.search.match"}}</option>
|
||||
|
@@ -25,7 +25,7 @@
|
||||
</td>
|
||||
<td class="right aligned overflow-visible">
|
||||
<div class="ui basic jump dropdown icon button poping up" data-content="{{$.i18n.Tr "repo.branch.download" ($.DefaultBranch)}}" data-variation="tiny inverted" data-position="top right">
|
||||
<i class="download icon"></i>
|
||||
{{svg "octicon-download"}}
|
||||
<div class="menu">
|
||||
<a class="item archive-link" data-url="{{$.RepoLink}}/archive/{{EscapePound $.DefaultBranch}}.zip">{{svg "octicon-file-zip"}} ZIP</a>
|
||||
<a class="item archive-link" data-url="{{$.RepoLink}}/archive/{{EscapePound $.DefaultBranch}}.tar.gz">{{svg "octicon-file-zip"}} TAR.GZ</a>
|
||||
@@ -91,20 +91,20 @@
|
||||
</a>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<a href="{{.LatestPullRequest.Issue.HTMLURL}}">{{if not .LatestPullRequest.IsSameRepo}}{{.LatestPullRequest.BaseRepo.FullName}}{{end}}#{{.LatestPullRequest.Issue.Index}}</a>
|
||||
<a href="{{.LatestPullRequest.Issue.HTMLURL}}" class="vm">{{if not .LatestPullRequest.IsSameRepo}}{{.LatestPullRequest.BaseRepo.FullName}}{{end}}#{{.LatestPullRequest.Issue.Index}}</a>
|
||||
{{if .LatestPullRequest.HasMerged}}
|
||||
<a href="{{.LatestPullRequest.Issue.HTMLURL}}" class="ui text-label purple mini label">{{svg "octicon-git-merge"}} {{$.i18n.Tr "repo.pulls.merged"}}</a>
|
||||
<a href="{{.LatestPullRequest.Issue.HTMLURL}}" class="ui text-label purple large label vm">{{svg "octicon-git-merge" 16 "mr-2"}}{{$.i18n.Tr "repo.pulls.merged"}}</a>
|
||||
{{else if .LatestPullRequest.Issue.IsClosed}}
|
||||
<a href="{{.LatestPullRequest.Issue.HTMLURL}}" class="ui text-label red mini label">{{svg "octicon-git-pull-request"}} {{$.i18n.Tr "repo.issues.closed_title"}}</a>
|
||||
<a href="{{.LatestPullRequest.Issue.HTMLURL}}" class="ui text-label red large label vm">{{svg "octicon-git-pull-request" 16 "mr-2"}}{{$.i18n.Tr "repo.issues.closed_title"}}</a>
|
||||
{{else}}
|
||||
<a href="{{.LatestPullRequest.Issue.HTMLURL}}" class="ui text-label green mini label">{{svg "octicon-git-pull-request"}} {{$.i18n.Tr "repo.issues.open_title"}}</a>
|
||||
<a href="{{.LatestPullRequest.Issue.HTMLURL}}" class="ui text-label green large label vm">{{svg "octicon-git-pull-request" 16 "mr-2"}}{{$.i18n.Tr "repo.issues.open_title"}}</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="two wide right aligned overflow-visible">
|
||||
{{if (not .IsDeleted)}}
|
||||
<div class="ui basic jump dropdown icon button poping up" data-content="{{$.i18n.Tr "repo.branch.download" (.Name)}}" data-variation="tiny inverted" data-position="top right">
|
||||
<i class="download icon"></i>
|
||||
{{svg "octicon-download"}}
|
||||
<div class="menu">
|
||||
<a class="item archive-link" data-url="{{$.RepoLink}}/archive/{{EscapePound .Name}}.zip">{{svg "octicon-file-zip"}} ZIP</a>
|
||||
<a class="item archive-link" data-url="{{$.RepoLink}}/archive/{{EscapePound .Name}}.tar.gz">{{svg "octicon-file-zip"}} TAR.GZ</a>
|
||||
|
@@ -43,15 +43,13 @@
|
||||
</ol>
|
||||
{{range $i, $file := .Diff.Files}}
|
||||
{{if $file.IsIncomplete}}
|
||||
<div class="diff-file-box diff-box file-content">
|
||||
<div class="diff-file-box diff-box file-content mt-3">
|
||||
<h4 class="ui top attached normal header rounded">
|
||||
<a role="button" class="fold-file muted mr-2">
|
||||
{{svg "octicon-chevron-down" 18}}
|
||||
</a>
|
||||
<div class="bold ui left df ac">
|
||||
{{if not $file.IsRenamed}}
|
||||
{{template "repo/diff/stats" dict "file" . "root" $}}
|
||||
{{end}}
|
||||
{{template "repo/diff/stats" dict "file" . "root" $}}
|
||||
</div>
|
||||
<span class="file mono">{{$file.Name}}</span>
|
||||
<div class="diff-file-header-actions df ac">
|
||||
@@ -70,7 +68,7 @@
|
||||
</h4>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}}" id="diff-{{.Index}}">
|
||||
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} mt-3" id="diff-{{.Index}}">
|
||||
<h4 class="diff-file-header sticky-2nd-row ui top attached normal header df ac sb">
|
||||
<div class="df ac">
|
||||
{{$isImage := false}}
|
||||
@@ -85,7 +83,7 @@
|
||||
<div class="bold df ac">
|
||||
{{if $file.IsBin}}
|
||||
{{$.i18n.Tr "repo.diff.bin"}}
|
||||
{{else if not $file.IsRenamed}}
|
||||
{{else}}
|
||||
{{template "repo/diff/stats" dict "file" . "root" $}}
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -105,30 +103,28 @@
|
||||
</div>
|
||||
</h4>
|
||||
<div class="diff-file-body ui attached unstackable table segment">
|
||||
{{if ne $file.Type 4}}
|
||||
<div class="file-body file-code has-context-menu{{if not $isImage}} code-diff{{end}}{{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}{{if $isImage}} py-4{{end}}">
|
||||
<table class="chroma{{if $isImage}} w-100{{end}}">
|
||||
<tbody>
|
||||
{{if $isImage}}
|
||||
{{template "repo/diff/image_diff" dict "file" . "root" $}}
|
||||
<div class="file-body file-code has-context-menu{{if not $isImage}} code-diff{{end}}{{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}{{if $isImage}} py-4{{end}}">
|
||||
<table class="chroma{{if $isImage}} w-100{{end}}">
|
||||
<tbody>
|
||||
{{if $isImage}}
|
||||
{{template "repo/diff/image_diff" dict "file" . "root" $}}
|
||||
{{else}}
|
||||
{{if $.IsSplitStyle}}
|
||||
{{template "repo/diff/section_split" dict "file" . "root" $}}
|
||||
{{else}}
|
||||
{{if $.IsSplitStyle}}
|
||||
{{template "repo/diff/section_split" dict "file" . "root" $}}
|
||||
{{else}}
|
||||
{{template "repo/diff/section_unified" dict "file" . "root" $}}
|
||||
{{end}}
|
||||
{{template "repo/diff/section_unified" dict "file" . "root" $}}
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if .Diff.IsIncomplete}}
|
||||
<div class="diff-file-box diff-box file-content">
|
||||
<div class="diff-file-box diff-box file-content mt-3">
|
||||
<h4 class="ui top attached normal header">
|
||||
{{$.i18n.Tr "repo.diff.too_many_files"}}
|
||||
</h4>
|
||||
|
@@ -3,7 +3,7 @@
|
||||
{{ $createdStr:= TimeSinceUnix .CreatedUnix $.root.Lang }}
|
||||
<div class="comment" id="{{.HashTag}}">
|
||||
{{if .OriginalAuthor }}
|
||||
<span class="avatar"><img src="/img/avatar_default.png"></span>
|
||||
<span class="avatar"><img src="{{AppSubUrl}}/img/avatar_default.png"></span>
|
||||
{{else}}
|
||||
<a class="avatar" {{if gt .Poster.ID 0}}href="{{.Poster.HomeLink}}"{{end}}>
|
||||
{{avatar .Poster}}
|
||||
|
@@ -3,16 +3,20 @@
|
||||
{{$isNotPending := (not (eq (index .comments 0).Review.Type 0))}}
|
||||
<div class="conversation-holder" data-path="{{(index .comments 0).TreePath}}" data-side="{{if lt (index .comments 0).Line 0}}left{{else}}right{{end}}" data-idx="{{(index .comments 0).UnsignedLine}}">
|
||||
{{if $resolved}}
|
||||
<div class="ui attached header resolved-placeholder">
|
||||
<span class="ui grey text left"><b>{{$resolveDoer.Name}}</b> {{$.i18n.Tr "repo.issues.review.resolved_by"}}</span>
|
||||
<button id="show-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="ui tiny right labeled button show-outdated">
|
||||
{{svg "octicon-unfold"}}
|
||||
{{$.i18n.Tr "repo.issues.review.show_resolved"}}
|
||||
</button>
|
||||
<button id="hide-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="hide ui tiny right labeled button hide-outdated">
|
||||
{{svg "octicon-fold"}}
|
||||
{{$.i18n.Tr "repo.issues.review.hide_resolved"}}
|
||||
</button>
|
||||
<div class="ui attached header resolved-placeholder df ac sb">
|
||||
<div class="ui grey text">
|
||||
<b>{{$resolveDoer.Name}}</b> {{$.i18n.Tr "repo.issues.review.resolved_by"}}
|
||||
</div>
|
||||
<div>
|
||||
<button id="show-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="ui tiny right labeled button show-outdated df ac">
|
||||
{{svg "octicon-unfold" 16 "mr-3"}}
|
||||
{{$.i18n.Tr "repo.issues.review.show_resolved"}}
|
||||
</button>
|
||||
<button id="hide-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="hide ui tiny right labeled button hide-outdated df ac">
|
||||
{{svg "octicon-fold" 16 "mr-3"}}
|
||||
{{$.i18n.Tr "repo.issues.review.hide_resolved"}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div id="code-comments-{{(index .comments 0).ID}}" class="field comment-code-cloud {{if $resolved}}hide{{end}}">
|
||||
@@ -32,4 +36,4 @@
|
||||
</button>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<div id="rev-container">
|
||||
<ul id="rev-list">
|
||||
{{ range $commitI, $commit := .Graph.Commits }}
|
||||
<li id="commit-{{$commit.Rev}}" data-flow="{{$commit.Flow}}">
|
||||
<li {{if $commit.Rev}}id="commit-{{$commit.Rev}}"{{end}} data-flow="{{$commit.Flow}}">
|
||||
{{ if $commit.OnlyRelation }}
|
||||
<span />
|
||||
<span></span>
|
||||
{{ else }}
|
||||
<span class="sha" id="{{$commit.ShortRev}}">
|
||||
{{$class := "ui sha label"}}
|
||||
|
@@ -4,8 +4,8 @@
|
||||
<div class="ui container">
|
||||
<div class="ui three column stackable grid">
|
||||
<div class="column">
|
||||
<h3>{{.Milestone.Name}}</h3>
|
||||
<div class="content">
|
||||
<h1>{{.Milestone.Name}}</h1>
|
||||
<div class="markdown content">
|
||||
{{.Milestone.RenderedContent|Str2html}}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -43,7 +43,7 @@
|
||||
<div class="milestone list">
|
||||
{{range .Milestones}}
|
||||
<li class="item">
|
||||
{{svg "octicon-milestone"}} <a href="{{$.RepoLink}}/milestone/{{.ID}}">{{.Name}}</a>
|
||||
{{svg "octicon-milestone" 16 "mr-2"}} <a href="{{$.RepoLink}}/milestone/{{.ID}}">{{.Name}}</a>
|
||||
<div class="ui right green progress" data-percent="{{.Completeness}}">
|
||||
<div class="bar" {{if not .Completeness}}style="background-color: transparent"{{end}}>
|
||||
<div class="progress"></div>
|
||||
@@ -80,7 +80,7 @@
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .Content}}
|
||||
<div class="content">
|
||||
<div class="markdown content">
|
||||
{{.RenderedContent|Str2html}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@@ -13,7 +13,7 @@
|
||||
<ui class="ui timeline">
|
||||
<div id="{{.Issue.HashTag}}" class="timeline-item comment first">
|
||||
{{if .Issue.OriginalAuthor }}
|
||||
<span class="timeline-avatar"><img src="/img/avatar_default.png"></span>
|
||||
<span class="timeline-avatar"><img src="{{AppSubUrl}}/img/avatar_default.png"></span>
|
||||
{{else}}
|
||||
<a class="timeline-avatar" {{if gt .Issue.Poster.ID 0}}href="{{.Issue.Poster.HomeLink}}"{{end}}>
|
||||
{{avatar .Issue.Poster}}
|
||||
|
@@ -8,12 +8,12 @@
|
||||
18 = REMOVED_DEADLINE, 19 = ADD_DEPENDENCY, 20 = REMOVE_DEPENDENCY, 21 = CODE,
|
||||
22 = REVIEW, 23 = ISSUE_LOCKED, 24 = ISSUE_UNLOCKED, 25 = TARGET_BRANCH_CHANGED,
|
||||
26 = DELETE_TIME_MANUAL, 27 = REVIEW_REQUEST, 28 = MERGE_PULL_REQUEST,
|
||||
29 = PULL_PUSH_EVENT, 30 = PROJECT_CHANGED, 31 = PROJECT_BOARD_CHANGED
|
||||
29 = PULL_PUSH_EVENT, 30 = PROJECT_CHANGED, 31 = PROJECT_BOARD_CHANGED
|
||||
32 = DISMISSED_REVIEW -->
|
||||
{{if eq .Type 0}}
|
||||
<div class="timeline-item comment" id="{{.HashTag}}">
|
||||
{{if .OriginalAuthor }}
|
||||
<span class="timeline-avatar"><img src="/img/avatar_default.png"></span>
|
||||
<span class="timeline-avatar"><img src="{{AppSubUrl}}/img/avatar_default.png"></span>
|
||||
{{else}}
|
||||
<a class="timeline-avatar" {{if gt .Poster.ID 0}}href="{{.Poster.HomeLink}}"{{end}}>
|
||||
{{avatar .Poster}}
|
||||
@@ -459,35 +459,39 @@
|
||||
{{ range $filename, $lines := .Review.CodeComments}}
|
||||
{{range $line, $comms := $lines}}
|
||||
<div class="ui segments">
|
||||
<div class="ui segment py-3">
|
||||
<div class="ui segment py-3 df ac sb">
|
||||
{{$invalid := (index $comms 0).Invalidated}}
|
||||
{{$resolved := (index $comms 0).IsResolved}}
|
||||
{{$resolveDoer := (index $comms 0).ResolveDoer}}
|
||||
{{$isNotPending := (not (eq (index $comms 0).Review.Type 0))}}
|
||||
{{if or $invalid $resolved}}
|
||||
<button id="show-outdated-{{(index $comms 0).ID}}" data-comment="{{(index $comms 0).ID}}" class="{{if not $resolved}}hide {{end}}ui compact right labeled button show-outdated">
|
||||
{{svg "octicon-unfold"}}
|
||||
{{if $resolved}}
|
||||
{{$.i18n.Tr "repo.issues.review.show_resolved"}}
|
||||
{{else}}
|
||||
{{$.i18n.Tr "repo.issues.review.show_outdated"}}
|
||||
<div class="df ac">
|
||||
<a href="{{(index $comms 0).CodeCommentURL}}" class="file-comment ml-3">{{$filename}}</a>
|
||||
{{if $invalid }}
|
||||
<span class="ui label basic small ml-3">
|
||||
{{$.i18n.Tr "repo.issues.review.outdated"}}
|
||||
</span>
|
||||
{{end}}
|
||||
</button>
|
||||
<button id="hide-outdated-{{(index $comms 0).ID}}" data-comment="{{(index $comms 0).ID}}" class="{{if $resolved}}hide {{end}}ui compact right labeled button hide-outdated">
|
||||
{{svg "octicon-fold"}}
|
||||
{{if $resolved}}
|
||||
{{$.i18n.Tr "repo.issues.review.hide_resolved"}}
|
||||
{{else}}
|
||||
{{$.i18n.Tr "repo.issues.review.hide_outdated"}}
|
||||
</div>
|
||||
<div>
|
||||
{{if or $invalid $resolved}}
|
||||
<button id="show-outdated-{{(index $comms 0).ID}}" data-comment="{{(index $comms 0).ID}}" class="{{if not $resolved}}hide {{end}}ui compact right labeled button show-outdated df ac">
|
||||
{{svg "octicon-unfold" 16 "mr-3"}}
|
||||
{{if $resolved}}
|
||||
{{$.i18n.Tr "repo.issues.review.show_resolved"}}
|
||||
{{else}}
|
||||
{{$.i18n.Tr "repo.issues.review.show_outdated"}}
|
||||
{{end}}
|
||||
</button>
|
||||
<button id="hide-outdated-{{(index $comms 0).ID}}" data-comment="{{(index $comms 0).ID}}" class="{{if $resolved}}hide {{end}}ui compact right labeled button hide-outdated df ac">
|
||||
{{svg "octicon-fold" 16 "mr-3"}}
|
||||
{{if $resolved}}
|
||||
{{$.i18n.Tr "repo.issues.review.hide_resolved"}}
|
||||
{{else}}
|
||||
{{$.i18n.Tr "repo.issues.review.hide_outdated"}}
|
||||
{{end}}
|
||||
</button>
|
||||
{{end}}
|
||||
</button>
|
||||
{{end}}
|
||||
<a href="{{(index $comms 0).CodeCommentURL}}" class="file-comment">{{$filename}}</a>
|
||||
{{if $invalid }}
|
||||
<span class="ui label basic small yellow">
|
||||
{{$.i18n.Tr "repo.issues.review.outdated"}}
|
||||
</span>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{$diff := (CommentMustAsDiff (index $comms 0))}}
|
||||
{{if $diff}}
|
||||
|
@@ -578,8 +578,6 @@
|
||||
{{end}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="ui tiny modal" id="lock">
|
||||
<div class="header">
|
||||
{{ if .Issue.IsLocked }}
|
||||
@@ -588,62 +586,61 @@
|
||||
{{.i18n.Tr "repo.issues.lock.title"}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{ if .Issue.IsLocked }}
|
||||
{{.i18n.Tr "repo.issues.unlock.notice_1"}}<br>
|
||||
{{.i18n.Tr "repo.issues.unlock.notice_2"}}<br>
|
||||
{{else}}
|
||||
{{.i18n.Tr "repo.issues.lock.notice_1"}}<br>
|
||||
{{.i18n.Tr "repo.issues.lock.notice_2"}}<br>
|
||||
{{.i18n.Tr "repo.issues.lock.notice_3"}}<br>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{ if .Issue.IsLocked }}
|
||||
{{.i18n.Tr "repo.issues.unlock.notice_1"}}<br>
|
||||
{{.i18n.Tr "repo.issues.unlock.notice_2"}}<br>
|
||||
{{else}}
|
||||
{{.i18n.Tr "repo.issues.lock.notice_1"}}<br>
|
||||
{{.i18n.Tr "repo.issues.lock.notice_2"}}<br>
|
||||
{{.i18n.Tr "repo.issues.lock.notice_3"}}<br>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<form class="ui form" action="{{$.RepoLink}}/issues/{{.Issue.Index}}{{ if .Issue.IsLocked }}/unlock{{else}}/lock{{end}}"
|
||||
method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<form class="ui form" action="{{$.RepoLink}}/issues/{{.Issue.Index}}{{ if .Issue.IsLocked }}/unlock{{else}}/lock{{end}}"
|
||||
method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
|
||||
{{ if not .Issue.IsLocked }}
|
||||
<div class="field">
|
||||
<strong> {{ .i18n.Tr "repo.issues.lock.reason" }} </strong>
|
||||
</div>
|
||||
{{ if not .Issue.IsLocked }}
|
||||
<div class="field">
|
||||
<strong> {{ .i18n.Tr "repo.issues.lock.reason" }} </strong>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="ui fluid dropdown selection" tabindex="0">
|
||||
<div class="field">
|
||||
<div class="ui fluid dropdown selection" tabindex="0">
|
||||
|
||||
<select name="reason">
|
||||
<option value=""> </option>
|
||||
{{range .LockReasons}}
|
||||
<option value="{{.}}">{{.}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<select name="reason">
|
||||
<option value=""> </option>
|
||||
{{range .LockReasons}}
|
||||
<option value="{{.}}">{{.}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
|
||||
<div class="default text"> </div>
|
||||
<div class="default text"> </div>
|
||||
|
||||
<div class="menu transition hidden" tabindex="-1" style="display: block !important;">
|
||||
{{range .LockReasons}}
|
||||
<div class="item" data-value="{{.}}">{{.}}</div>
|
||||
{{end}}
|
||||
<div class="menu transition hidden" tabindex="-1" style="display: block !important;">
|
||||
{{range .LockReasons}}
|
||||
<div class="item" data-value="{{.}}">{{.}}</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">
|
||||
{{ if .Issue.IsLocked }}
|
||||
{{.i18n.Tr "repo.issues.unlock_confirm"}}
|
||||
{{else}}
|
||||
{{.i18n.Tr "repo.issues.lock_confirm"}}
|
||||
{{end}}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">
|
||||
{{ if .Issue.IsLocked }}
|
||||
{{.i18n.Tr "repo.issues.unlock_confirm"}}
|
||||
{{else}}
|
||||
{{.i18n.Tr "repo.issues.lock_confirm"}}
|
||||
{{end}}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
@@ -71,8 +71,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{if .ContextUser.IsOrganization}}
|
||||
<div class="right stackable menu">
|
||||
@@ -101,5 +101,6 @@
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
|
3
vendor/code.gitea.io/sdk/gitea/admin_cron.go
generated
vendored
3
vendor/code.gitea.io/sdk/gitea/admin_cron.go
generated
vendored
@@ -39,6 +39,9 @@ func (c *Client) RunCronTasks(task string) (*Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := escapeValidatePathSegments(&task); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("POST", fmt.Sprintf("/admin/cron/%s", task), jsonHeader, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
3
vendor/code.gitea.io/sdk/gitea/admin_org.go
generated
vendored
3
vendor/code.gitea.io/sdk/gitea/admin_org.go
generated
vendored
@@ -26,6 +26,9 @@ func (c *Client) AdminListOrgs(opt AdminListOrgsOptions) ([]*Organization, *Resp
|
||||
|
||||
// AdminCreateOrg create an organization
|
||||
func (c *Client) AdminCreateOrg(user string, opt CreateOrgOption) (*Organization, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
3
vendor/code.gitea.io/sdk/gitea/admin_repo.go
generated
vendored
3
vendor/code.gitea.io/sdk/gitea/admin_repo.go
generated
vendored
@@ -12,6 +12,9 @@ import (
|
||||
|
||||
// AdminCreateRepo create a repo
|
||||
func (c *Client) AdminCreateRepo(user string, opt CreateRepoOption) (*Repository, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
42
vendor/code.gitea.io/sdk/gitea/admin_user.go
generated
vendored
42
vendor/code.gitea.io/sdk/gitea/admin_user.go
generated
vendored
@@ -63,25 +63,28 @@ func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, *Response, error)
|
||||
|
||||
// EditUserOption edit user options
|
||||
type EditUserOption struct {
|
||||
SourceID int64 `json:"source_id"`
|
||||
LoginName string `json:"login_name"`
|
||||
FullName string `json:"full_name"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
MustChangePassword *bool `json:"must_change_password"`
|
||||
Website string `json:"website"`
|
||||
Location string `json:"location"`
|
||||
Active *bool `json:"active"`
|
||||
Admin *bool `json:"admin"`
|
||||
AllowGitHook *bool `json:"allow_git_hook"`
|
||||
AllowImportLocal *bool `json:"allow_import_local"`
|
||||
MaxRepoCreation *int `json:"max_repo_creation"`
|
||||
ProhibitLogin *bool `json:"prohibit_login"`
|
||||
AllowCreateOrganization *bool `json:"allow_create_organization"`
|
||||
SourceID int64 `json:"source_id"`
|
||||
LoginName string `json:"login_name"`
|
||||
Email *string `json:"email"`
|
||||
FullName *string `json:"full_name"`
|
||||
Password string `json:"password"`
|
||||
MustChangePassword *bool `json:"must_change_password"`
|
||||
Website *string `json:"website"`
|
||||
Location *string `json:"location"`
|
||||
Active *bool `json:"active"`
|
||||
Admin *bool `json:"admin"`
|
||||
AllowGitHook *bool `json:"allow_git_hook"`
|
||||
AllowImportLocal *bool `json:"allow_import_local"`
|
||||
MaxRepoCreation *int `json:"max_repo_creation"`
|
||||
ProhibitLogin *bool `json:"prohibit_login"`
|
||||
AllowCreateOrganization *bool `json:"allow_create_organization"`
|
||||
}
|
||||
|
||||
// AdminEditUser modify user informations
|
||||
func (c *Client) AdminEditUser(user string, opt EditUserOption) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -92,12 +95,18 @@ func (c *Client) AdminEditUser(user string, opt EditUserOption) (*Response, erro
|
||||
|
||||
// AdminDeleteUser delete one user according name
|
||||
func (c *Client) AdminDeleteUser(user string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s", user), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// AdminCreateUserPublicKey adds a public key for the user
|
||||
func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*PublicKey, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -109,6 +118,9 @@ func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*Pu
|
||||
|
||||
// AdminDeleteUserPublicKey deletes a user's public key
|
||||
func (c *Client) AdminDeleteUserPublicKey(user string, keyID int) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s/keys/%d", user, keyID), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
15
vendor/code.gitea.io/sdk/gitea/attachment.go
generated
vendored
15
vendor/code.gitea.io/sdk/gitea/attachment.go
generated
vendored
@@ -31,6 +31,9 @@ type ListReleaseAttachmentsOptions struct {
|
||||
|
||||
// ListReleaseAttachments list release's attachments
|
||||
func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt ListReleaseAttachmentsOptions) ([]*Attachment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
attachments := make([]*Attachment, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET",
|
||||
@@ -41,6 +44,9 @@ func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt Li
|
||||
|
||||
// GetReleaseAttachment returns the requested attachment
|
||||
func (c *Client) GetReleaseAttachment(user, repo string, release int64, id int64) (*Attachment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
a := new(Attachment)
|
||||
resp, err := c.getParsedResponse("GET",
|
||||
fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id),
|
||||
@@ -50,6 +56,9 @@ func (c *Client) GetReleaseAttachment(user, repo string, release int64, id int64
|
||||
|
||||
// CreateReleaseAttachment creates an attachment for the given release
|
||||
func (c *Client) CreateReleaseAttachment(user, repo string, release int64, file io.Reader, filename string) (*Attachment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Write file to body
|
||||
body := new(bytes.Buffer)
|
||||
writer := multipart.NewWriter(body)
|
||||
@@ -80,6 +89,9 @@ type EditAttachmentOptions struct {
|
||||
|
||||
// EditReleaseAttachment updates the given attachment with the given options
|
||||
func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachment int64, form EditAttachmentOptions) (*Attachment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&form)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -91,6 +103,9 @@ func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachm
|
||||
|
||||
// DeleteReleaseAttachment deletes the given attachment including the uploaded file
|
||||
func (c *Client) DeleteReleaseAttachment(user, repo string, release int64, id int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
176
vendor/code.gitea.io/sdk/gitea/client.go
generated
vendored
176
vendor/code.gitea.io/sdk/gitea/client.go
generated
vendored
@@ -13,6 +13,7 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -23,22 +24,23 @@ var jsonHeader = http.Header{"content-type": []string{"application/json"}}
|
||||
|
||||
// Version return the library version
|
||||
func Version() string {
|
||||
return "0.13.0"
|
||||
return "0.14.0"
|
||||
}
|
||||
|
||||
// Client represents a Gitea API client.
|
||||
// Client represents a thread-safe Gitea API client.
|
||||
type Client struct {
|
||||
url string
|
||||
accessToken string
|
||||
username string
|
||||
password string
|
||||
otp string
|
||||
sudo string
|
||||
debug bool
|
||||
client *http.Client
|
||||
ctx context.Context
|
||||
serverVersion *version.Version
|
||||
versionLock sync.RWMutex
|
||||
url string
|
||||
accessToken string
|
||||
username string
|
||||
password string
|
||||
otp string
|
||||
sudo string
|
||||
debug bool
|
||||
client *http.Client
|
||||
ctx context.Context
|
||||
mutex sync.RWMutex
|
||||
serverVersion *version.Version
|
||||
getVersionOnce sync.Once
|
||||
}
|
||||
|
||||
// Response represents the gitea response
|
||||
@@ -47,6 +49,7 @@ type Response struct {
|
||||
}
|
||||
|
||||
// NewClient initializes and returns a API client.
|
||||
// Usage of all gitea.Client methods is concurrency-safe.
|
||||
func NewClient(url string, options ...func(*Client)) (*Client, error) {
|
||||
client := &Client{
|
||||
url: strings.TrimSuffix(url, "/"),
|
||||
@@ -56,7 +59,7 @@ func NewClient(url string, options ...func(*Client)) (*Client, error) {
|
||||
for _, opt := range options {
|
||||
opt(client)
|
||||
}
|
||||
if err := client.checkServerVersionGreaterThanOrEqual(version1_10_0); err != nil {
|
||||
if err := client.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client, nil
|
||||
@@ -72,14 +75,23 @@ func NewClientWithHTTP(url string, httpClient *http.Client) *Client {
|
||||
// SetHTTPClient is an option for NewClient to set custom http client
|
||||
func SetHTTPClient(httpClient *http.Client) func(client *Client) {
|
||||
return func(client *Client) {
|
||||
client.client = httpClient
|
||||
client.SetHTTPClient(httpClient)
|
||||
}
|
||||
}
|
||||
|
||||
// SetHTTPClient replaces default http.Client with user given one.
|
||||
func (c *Client) SetHTTPClient(client *http.Client) {
|
||||
c.mutex.Lock()
|
||||
c.client = client
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetToken is an option for NewClient to set token
|
||||
func SetToken(token string) func(client *Client) {
|
||||
return func(client *Client) {
|
||||
client.mutex.Lock()
|
||||
client.accessToken = token
|
||||
client.mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +104,9 @@ func SetBasicAuth(username, password string) func(client *Client) {
|
||||
|
||||
// SetBasicAuth sets username and password
|
||||
func (c *Client) SetBasicAuth(username, password string) {
|
||||
c.mutex.Lock()
|
||||
c.username, c.password = username, password
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetOTP is an option for NewClient to set OTP for 2FA
|
||||
@@ -104,7 +118,9 @@ func SetOTP(otp string) func(client *Client) {
|
||||
|
||||
// SetOTP sets OTP for 2FA
|
||||
func (c *Client) SetOTP(otp string) {
|
||||
c.mutex.Lock()
|
||||
c.otp = otp
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetContext is an option for NewClient to set context
|
||||
@@ -116,12 +132,9 @@ func SetContext(ctx context.Context) func(client *Client) {
|
||||
|
||||
// SetContext set context witch is used for http requests
|
||||
func (c *Client) SetContext(ctx context.Context) {
|
||||
c.mutex.Lock()
|
||||
c.ctx = ctx
|
||||
}
|
||||
|
||||
// SetHTTPClient replaces default http.Client with user given one.
|
||||
func (c *Client) SetHTTPClient(client *http.Client) {
|
||||
c.client = client
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetSudo is an option for NewClient to set sudo header
|
||||
@@ -133,43 +146,57 @@ func SetSudo(sudo string) func(client *Client) {
|
||||
|
||||
// SetSudo sets username to impersonate.
|
||||
func (c *Client) SetSudo(sudo string) {
|
||||
c.mutex.Lock()
|
||||
c.sudo = sudo
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDebugMode is an option for NewClient to enable debug mode
|
||||
func SetDebugMode() func(client *Client) {
|
||||
return func(client *Client) {
|
||||
client.mutex.Lock()
|
||||
client.debug = true
|
||||
client.mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *Response, error) {
|
||||
if c.debug {
|
||||
c.mutex.RLock()
|
||||
debug := c.debug
|
||||
if debug {
|
||||
fmt.Printf("%s: %s\nBody: %v\n", method, c.url+path, body)
|
||||
}
|
||||
req, err := http.NewRequestWithContext(c.ctx, method, c.url+path, body)
|
||||
|
||||
client := c.client // client ref can change from this point on so safe it
|
||||
c.mutex.RUnlock()
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
resp, err := c.client.Do(req)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if c.debug {
|
||||
if debug {
|
||||
fmt.Printf("Response: %v\n\n", resp)
|
||||
}
|
||||
return data, &Response{resp}, nil
|
||||
}
|
||||
|
||||
func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*Response, error) {
|
||||
if c.debug {
|
||||
c.mutex.RLock()
|
||||
debug := c.debug
|
||||
if debug {
|
||||
fmt.Printf("%s: %s\nHeader: %v\nBody: %s\n", method, c.url+"/api/v1"+path, header, body)
|
||||
}
|
||||
req, err := http.NewRequestWithContext(c.ctx, method, c.url+"/api/v1"+path, body)
|
||||
if err != nil {
|
||||
c.mutex.RUnlock()
|
||||
return nil, err
|
||||
}
|
||||
if len(c.accessToken) != 0 {
|
||||
@@ -184,20 +211,66 @@ func (c *Client) doRequest(method, path string, header http.Header, body io.Read
|
||||
if len(c.sudo) != 0 {
|
||||
req.Header.Set("Sudo", c.sudo)
|
||||
}
|
||||
|
||||
client := c.client // client ref can change from this point on so safe it
|
||||
c.mutex.RUnlock()
|
||||
|
||||
for k, v := range header {
|
||||
req.Header[k] = v
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c.debug {
|
||||
if debug {
|
||||
fmt.Printf("Response: %v\n\n", resp)
|
||||
}
|
||||
return &Response{resp}, nil
|
||||
}
|
||||
|
||||
// Converts a response for a HTTP status code indicating an error condition
|
||||
// (non-2XX) to a well-known error value and response body. For non-problematic
|
||||
// (2XX) status codes nil will be returned. Note that on a non-2XX response, the
|
||||
// response body stream will have been read and, hence, is closed on return.
|
||||
func statusCodeToErr(resp *Response) (body []byte, err error) {
|
||||
// no error
|
||||
if resp.StatusCode/100 == 2 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
//
|
||||
// error: body will be read for details
|
||||
//
|
||||
defer resp.Body.Close()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("body read on HTTP error %d: %v", resp.StatusCode, err)
|
||||
}
|
||||
|
||||
switch resp.StatusCode {
|
||||
case 403:
|
||||
return data, errors.New("403 Forbidden")
|
||||
case 404:
|
||||
return data, errors.New("404 Not Found")
|
||||
case 409:
|
||||
return data, errors.New("409 Conflict")
|
||||
case 422:
|
||||
return data, fmt.Errorf("422 Unprocessable Entity: %s", string(data))
|
||||
}
|
||||
|
||||
path := resp.Request.URL.Path
|
||||
method := resp.Request.Method
|
||||
header := resp.Request.Header
|
||||
errMap := make(map[string]interface{})
|
||||
if err = json.Unmarshal(data, &errMap); err != nil {
|
||||
// when the JSON can't be parsed, data was probably empty or a
|
||||
// plain string, so we try to return a helpful error anyway
|
||||
return data, fmt.Errorf("Unknown API Error: %d\nRequest: '%s' with '%s' method '%s' header and '%s' body", resp.StatusCode, path, method, header, string(data))
|
||||
}
|
||||
return data, errors.New(errMap["message"].(string))
|
||||
}
|
||||
|
||||
func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, *Response, error) {
|
||||
resp, err := c.doRequest(method, path, header, body)
|
||||
if err != nil {
|
||||
@@ -205,32 +278,18 @@ func (c *Client) getResponse(method, path string, header http.Header, body io.Re
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
// check for errors
|
||||
data, err := statusCodeToErr(resp)
|
||||
if err != nil {
|
||||
return data, resp, err
|
||||
}
|
||||
|
||||
// success (2XX), read body
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
switch resp.StatusCode {
|
||||
case 403:
|
||||
return data, resp, errors.New("403 Forbidden")
|
||||
case 404:
|
||||
return data, resp, errors.New("404 Not Found")
|
||||
case 409:
|
||||
return data, resp, errors.New("409 Conflict")
|
||||
case 422:
|
||||
return data, resp, fmt.Errorf("422 Unprocessable Entity: %s", string(data))
|
||||
}
|
||||
|
||||
if resp.StatusCode/100 != 2 {
|
||||
errMap := make(map[string]interface{})
|
||||
if err = json.Unmarshal(data, &errMap); err != nil {
|
||||
// when the JSON can't be parsed, data was probably empty or a plain string,
|
||||
// so we try to return a helpful error anyway
|
||||
return data, resp, fmt.Errorf("Unknown API Error: %d\nRequest: '%s' with '%s' method '%s' header and '%s' body", resp.StatusCode, path, method, header, string(data))
|
||||
}
|
||||
return data, resp, errors.New(errMap["message"].(string))
|
||||
}
|
||||
|
||||
return data, resp, nil
|
||||
}
|
||||
|
||||
@@ -251,3 +310,24 @@ func (c *Client) getStatusCode(method, path string, header http.Header, body io.
|
||||
|
||||
return resp.StatusCode, resp, nil
|
||||
}
|
||||
|
||||
// pathEscapeSegments escapes segments of a path while not escaping forward slash
|
||||
func pathEscapeSegments(path string) string {
|
||||
slice := strings.Split(path, "/")
|
||||
for index := range slice {
|
||||
slice[index] = url.PathEscape(slice[index])
|
||||
}
|
||||
escapedPath := strings.Join(slice, "/")
|
||||
return escapedPath
|
||||
}
|
||||
|
||||
// escapeValidatePathSegments is a help function to validate and encode url path segments
|
||||
func escapeValidatePathSegments(seg ...*string) error {
|
||||
for i := range seg {
|
||||
if seg[i] == nil || len(*seg[i]) == 0 {
|
||||
return fmt.Errorf("path segment [%d] is empty", i)
|
||||
}
|
||||
*seg[i] = url.PathEscape(*seg[i])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
6
vendor/code.gitea.io/sdk/gitea/fork.go
generated
vendored
6
vendor/code.gitea.io/sdk/gitea/fork.go
generated
vendored
@@ -17,6 +17,9 @@ type ListForksOptions struct {
|
||||
|
||||
// ListForks list a repository's forks
|
||||
func (c *Client) ListForks(user string, repo string, opt ListForksOptions) ([]*Repository, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
forks := make([]*Repository, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET",
|
||||
@@ -33,6 +36,9 @@ type CreateForkOption struct {
|
||||
|
||||
// CreateFork create a fork of a repository
|
||||
func (c *Client) CreateFork(user, repo string, form CreateForkOption) (*Repository, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(form)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
3
vendor/code.gitea.io/sdk/gitea/git_blob.go
generated
vendored
3
vendor/code.gitea.io/sdk/gitea/git_blob.go
generated
vendored
@@ -19,6 +19,9 @@ type GitBlobResponse struct {
|
||||
|
||||
// GetBlob get the blob of a repository file
|
||||
func (c *Client) GetBlob(user, repo, sha string) (*GitBlobResponse, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo, &sha); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
blob := new(GitBlobResponse)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/blobs/%s", user, repo, sha), nil, nil, blob)
|
||||
return blob, resp, err
|
||||
|
12
vendor/code.gitea.io/sdk/gitea/git_hook.go
generated
vendored
12
vendor/code.gitea.io/sdk/gitea/git_hook.go
generated
vendored
@@ -24,6 +24,9 @@ type ListRepoGitHooksOptions struct {
|
||||
|
||||
// ListRepoGitHooks list all the Git hooks of one repository
|
||||
func (c *Client) ListRepoGitHooks(user, repo string, opt ListRepoGitHooksOptions) ([]*GitHook, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
hooks := make([]*GitHook, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks)
|
||||
@@ -32,6 +35,9 @@ func (c *Client) ListRepoGitHooks(user, repo string, opt ListRepoGitHooksOptions
|
||||
|
||||
// GetRepoGitHook get a Git hook of a repository
|
||||
func (c *Client) GetRepoGitHook(user, repo, id string) (*GitHook, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo, &id); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
h := new(GitHook)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil, h)
|
||||
return h, resp, err
|
||||
@@ -44,6 +50,9 @@ type EditGitHookOption struct {
|
||||
|
||||
// EditRepoGitHook modify one Git hook of a repository
|
||||
func (c *Client) EditRepoGitHook(user, repo, id string, opt EditGitHookOption) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo, &id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -54,6 +63,9 @@ func (c *Client) EditRepoGitHook(user, repo, id string, opt EditGitHookOption) (
|
||||
|
||||
// DeleteRepoGitHook delete one Git hook from a repository
|
||||
func (c *Client) DeleteRepoGitHook(user, repo, id string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo, &id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
2
vendor/code.gitea.io/sdk/gitea/go.mod
generated
vendored
2
vendor/code.gitea.io/sdk/gitea/go.mod
generated
vendored
@@ -1,6 +1,6 @@
|
||||
module code.gitea.io/sdk/gitea
|
||||
|
||||
go 1.12
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/hashicorp/go-version v1.2.1
|
||||
|
2
vendor/code.gitea.io/sdk/gitea/go.sum
generated
vendored
2
vendor/code.gitea.io/sdk/gitea/go.sum
generated
vendored
@@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
|
||||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
20
vendor/code.gitea.io/sdk/gitea/helper.go
generated
vendored
Normal file
20
vendor/code.gitea.io/sdk/gitea/helper.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gitea
|
||||
|
||||
// OptionalBool convert a bool to a bool reference
|
||||
func OptionalBool(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// OptionalString convert a string to a string reference
|
||||
func OptionalString(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// OptionalInt64 convert a int64 to a int64 reference
|
||||
func OptionalInt64(v int64) *int64 {
|
||||
return &v
|
||||
}
|
30
vendor/code.gitea.io/sdk/gitea/hook.go
generated
vendored
30
vendor/code.gitea.io/sdk/gitea/hook.go
generated
vendored
@@ -31,6 +31,9 @@ type ListHooksOptions struct {
|
||||
|
||||
// ListOrgHooks list all the hooks of one organization
|
||||
func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
hooks := make([]*Hook, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks?%s", org, opt.getURLQuery().Encode()), nil, nil, &hooks)
|
||||
@@ -39,6 +42,9 @@ func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, *Respo
|
||||
|
||||
// ListRepoHooks list all the hooks of one repository
|
||||
func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
hooks := make([]*Hook, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks)
|
||||
@@ -47,6 +53,9 @@ func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook
|
||||
|
||||
// GetOrgHook get a hook of an organization
|
||||
func (c *Client) GetOrgHook(org string, id int64) (*Hook, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
h := new(Hook)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil, h)
|
||||
return h, resp, err
|
||||
@@ -54,6 +63,9 @@ func (c *Client) GetOrgHook(org string, id int64) (*Hook, *Response, error) {
|
||||
|
||||
// GetRepoHook get a hook of a repository
|
||||
func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
h := new(Hook)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil, h)
|
||||
return h, resp, err
|
||||
@@ -78,6 +90,9 @@ func (opt CreateHookOption) Validate() error {
|
||||
|
||||
// CreateOrgHook create one hook for an organization, with options
|
||||
func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -92,6 +107,9 @@ func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, *Respon
|
||||
|
||||
// CreateRepoHook create one hook for a repository, with options
|
||||
func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -111,6 +129,9 @@ type EditHookOption struct {
|
||||
|
||||
// EditOrgHook modify one hook of an organization, with hook id and options
|
||||
func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -121,6 +142,9 @@ func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) (*Respons
|
||||
|
||||
// EditRepoHook modify one hook of a repository, with hook id and options
|
||||
func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -131,12 +155,18 @@ func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) (
|
||||
|
||||
// DeleteOrgHook delete one hook from an organization, with hook id
|
||||
func (c *Client) DeleteOrgHook(org string, id int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// DeleteRepoHook delete one hook from a repository, with hook id
|
||||
func (c *Client) DeleteRepoHook(user, repo string, id int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
59
vendor/code.gitea.io/sdk/gitea/issue.go
generated
vendored
59
vendor/code.gitea.io/sdk/gitea/issue.go
generated
vendored
@@ -32,16 +32,20 @@ type RepositoryMeta struct {
|
||||
type Issue struct {
|
||||
ID int64 `json:"id"`
|
||||
URL string `json:"url"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
Index int64 `json:"number"`
|
||||
Poster *User `json:"user"`
|
||||
OriginalAuthor string `json:"original_author"`
|
||||
OriginalAuthorID int64 `json:"original_author_id"`
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
Ref string `json:"ref"`
|
||||
Labels []*Label `json:"labels"`
|
||||
Milestone *Milestone `json:"milestone"`
|
||||
Assignee *User `json:"assignee"`
|
||||
Assignees []*User `json:"assignees"`
|
||||
// deprecated
|
||||
// TODO: rm on sdk 0.15.0
|
||||
Assignee *User `json:"assignee"`
|
||||
Assignees []*User `json:"assignees"`
|
||||
// Whether the issue is open or closed
|
||||
State StateType `json:"state"`
|
||||
IsLocked bool `json:"is_locked"`
|
||||
@@ -128,11 +132,17 @@ func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, *Response, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range issues {
|
||||
c.issueBackwardsCompatibility(issues[i])
|
||||
}
|
||||
return issues, resp, err
|
||||
}
|
||||
|
||||
// ListRepoIssues returns all issues for a given repository
|
||||
func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
issues := make([]*Issue, 0, opt.PageSize)
|
||||
|
||||
@@ -146,16 +156,23 @@ func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Iss
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range issues {
|
||||
c.issueBackwardsCompatibility(issues[i])
|
||||
}
|
||||
return issues, resp, err
|
||||
}
|
||||
|
||||
// GetIssue returns a single issue for a given repository
|
||||
func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
issue := new(Issue)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue)
|
||||
if e := c.checkServerVersionGreaterThanOrEqual(version1_12_0); e != nil && issue.Repository != nil {
|
||||
issue.Repository.Owner = strings.Split(issue.Repository.FullName, "/")[0]
|
||||
}
|
||||
c.issueBackwardsCompatibility(issue)
|
||||
return issue, resp, err
|
||||
}
|
||||
|
||||
@@ -163,7 +180,9 @@ func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, e
|
||||
type CreateIssueOption struct {
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
// username of assignee
|
||||
Ref string `json:"ref"`
|
||||
// deprecated
|
||||
// TODO: rm on sdk 0.15.0
|
||||
Assignee string `json:"assignee"`
|
||||
Assignees []string `json:"assignees"`
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
@@ -184,6 +203,9 @@ func (opt CreateIssueOption) Validate() error {
|
||||
|
||||
// CreateIssue create a new issue for a given repository
|
||||
func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -194,18 +216,23 @@ func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue,
|
||||
issue := new(Issue)
|
||||
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues", owner, repo),
|
||||
jsonHeader, bytes.NewReader(body), issue)
|
||||
c.issueBackwardsCompatibility(issue)
|
||||
return issue, resp, err
|
||||
}
|
||||
|
||||
// EditIssueOption options for editing an issue
|
||||
type EditIssueOption struct {
|
||||
Title string `json:"title"`
|
||||
Body *string `json:"body"`
|
||||
Assignee *string `json:"assignee"`
|
||||
Assignees []string `json:"assignees"`
|
||||
Milestone *int64 `json:"milestone"`
|
||||
State *StateType `json:"state"`
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
Title string `json:"title"`
|
||||
Body *string `json:"body"`
|
||||
Ref *string `json:"ref"`
|
||||
// deprecated
|
||||
// TODO: rm on sdk 0.15.0
|
||||
Assignee *string `json:"assignee"`
|
||||
Assignees []string `json:"assignees"`
|
||||
Milestone *int64 `json:"milestone"`
|
||||
State *StateType `json:"state"`
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
RemoveDeadline *bool `json:"unset_due_date"`
|
||||
}
|
||||
|
||||
// Validate the EditIssueOption struct
|
||||
@@ -218,6 +245,9 @@ func (opt EditIssueOption) Validate() error {
|
||||
|
||||
// EditIssue modify an existing issue for a given repository
|
||||
func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -229,5 +259,14 @@ func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption)
|
||||
resp, err := c.getParsedResponse("PATCH",
|
||||
fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index),
|
||||
jsonHeader, bytes.NewReader(body), issue)
|
||||
c.issueBackwardsCompatibility(issue)
|
||||
return issue, resp, err
|
||||
}
|
||||
|
||||
func (c *Client) issueBackwardsCompatibility(issue *Issue) {
|
||||
if c.checkServerVersionGreaterThanOrEqual(version1_12_0) != nil {
|
||||
c.mutex.RLock()
|
||||
issue.HTMLURL = fmt.Sprintf("%s/%s/issues/%d", c.url, issue.Repository.FullName, issue.Index)
|
||||
c.mutex.RUnlock()
|
||||
}
|
||||
}
|
||||
|
18
vendor/code.gitea.io/sdk/gitea/issue_comment.go
generated
vendored
18
vendor/code.gitea.io/sdk/gitea/issue_comment.go
generated
vendored
@@ -47,6 +47,9 @@ func (opt *ListIssueCommentOptions) QueryEncode() string {
|
||||
|
||||
// ListIssueComments list comments on an issue.
|
||||
func (c *Client) ListIssueComments(owner, repo string, index int64, opt ListIssueCommentOptions) ([]*Comment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index))
|
||||
link.RawQuery = opt.QueryEncode()
|
||||
@@ -57,6 +60,9 @@ func (c *Client) ListIssueComments(owner, repo string, index int64, opt ListIssu
|
||||
|
||||
// ListRepoIssueComments list comments for a given repo.
|
||||
func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentOptions) ([]*Comment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/comments", owner, repo))
|
||||
link.RawQuery = opt.QueryEncode()
|
||||
@@ -67,6 +73,9 @@ func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentO
|
||||
|
||||
// GetIssueComment get a comment for a given repo by id.
|
||||
func (c *Client) GetIssueComment(owner, repo string, id int64) (*Comment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
comment := new(Comment)
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return comment, nil, err
|
||||
@@ -90,6 +99,9 @@ func (opt CreateIssueCommentOption) Validate() error {
|
||||
|
||||
// CreateIssueComment create comment on an issue.
|
||||
func (c *Client) CreateIssueComment(owner, repo string, index int64, opt CreateIssueCommentOption) (*Comment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -117,6 +129,9 @@ func (opt EditIssueCommentOption) Validate() error {
|
||||
|
||||
// EditIssueComment edits an issue comment.
|
||||
func (c *Client) EditIssueComment(owner, repo string, commentID int64, opt EditIssueCommentOption) (*Comment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -131,6 +146,9 @@ func (c *Client) EditIssueComment(owner, repo string, commentID int64, opt EditI
|
||||
|
||||
// DeleteIssueComment deletes an issue comment.
|
||||
func (c *Client) DeleteIssueComment(owner, repo string, commentID int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, commentID), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
30
vendor/code.gitea.io/sdk/gitea/issue_label.go
generated
vendored
30
vendor/code.gitea.io/sdk/gitea/issue_label.go
generated
vendored
@@ -29,6 +29,9 @@ type ListLabelsOptions struct {
|
||||
|
||||
// ListRepoLabels list labels of one repository
|
||||
func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*Label, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
labels := make([]*Label, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels?%s", owner, repo, opt.getURLQuery().Encode()), nil, nil, &labels)
|
||||
@@ -37,6 +40,9 @@ func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*L
|
||||
|
||||
// GetRepoLabel get one label of repository by repo it
|
||||
func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
label := new(Label)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil, label)
|
||||
return label, resp, err
|
||||
@@ -67,6 +73,9 @@ func (opt CreateLabelOption) Validate() error {
|
||||
|
||||
// CreateLabel create one label of repository
|
||||
func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -114,6 +123,9 @@ func (opt EditLabelOption) Validate() error {
|
||||
|
||||
// EditLabel modify one label with options
|
||||
func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*Label, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -128,12 +140,18 @@ func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*
|
||||
|
||||
// DeleteLabel delete one label of repository by id
|
||||
func (c *Client) DeleteLabel(owner, repo string, id int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// GetIssueLabels get labels of one issue via issue id
|
||||
func (c *Client) GetIssueLabels(owner, repo string, index int64, opts ListLabelsOptions) ([]*Label, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
labels := make([]*Label, 0, 5)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels?%s", owner, repo, index, opts.getURLQuery().Encode()), nil, nil, &labels)
|
||||
return labels, resp, err
|
||||
@@ -147,6 +165,9 @@ type IssueLabelsOption struct {
|
||||
|
||||
// AddIssueLabels add one or more labels to one issue
|
||||
func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -158,6 +179,9 @@ func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabels
|
||||
|
||||
// ReplaceIssueLabels replace old labels of issue with new labels
|
||||
func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -170,12 +194,18 @@ func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLa
|
||||
// DeleteIssueLabel delete one label of one issue by issue id and label id
|
||||
// TODO: maybe we need delete by label name and issue id
|
||||
func (c *Client) DeleteIssueLabel(owner, repo string, index, label int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, label), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// ClearIssueLabels delete all the labels of one issue.
|
||||
func (c *Client) ClearIssueLabels(owner, repo string, index int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
24
vendor/code.gitea.io/sdk/gitea/issue_milestone.go
generated
vendored
24
vendor/code.gitea.io/sdk/gitea/issue_milestone.go
generated
vendored
@@ -49,6 +49,9 @@ func (opt *ListMilestoneOption) QueryEncode() string {
|
||||
|
||||
// ListRepoMilestones list all the milestones of one repository
|
||||
func (c *Client) ListRepoMilestones(owner, repo string, opt ListMilestoneOption) ([]*Milestone, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
milestones := make([]*Milestone, 0, opt.PageSize)
|
||||
|
||||
@@ -60,6 +63,9 @@ func (c *Client) ListRepoMilestones(owner, repo string, opt ListMilestoneOption)
|
||||
|
||||
// GetMilestone get one milestone by repo name and milestone id
|
||||
func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
milestone := new(Milestone)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil, milestone)
|
||||
return milestone, resp, err
|
||||
@@ -72,6 +78,9 @@ func (c *Client) GetMilestoneByName(owner, repo string, name string) (*Milestone
|
||||
m, resp, err := c.resolveMilestoneByName(owner, repo, name)
|
||||
return m, resp, err
|
||||
}
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
milestone := new(Milestone)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%s", owner, repo, name), nil, nil, milestone)
|
||||
return milestone, resp, err
|
||||
@@ -95,6 +104,9 @@ func (opt CreateMilestoneOption) Validate() error {
|
||||
|
||||
// CreateMilestone create one milestone with options
|
||||
func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption) (*Milestone, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -135,6 +147,9 @@ func (opt EditMilestoneOption) Validate() error {
|
||||
|
||||
// EditMilestone modify milestone with options
|
||||
func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOption) (*Milestone, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -157,6 +172,9 @@ func (c *Client) EditMilestoneByName(owner, repo string, name string, opt EditMi
|
||||
}
|
||||
return c.EditMilestone(owner, repo, m.ID, opt)
|
||||
}
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -171,6 +189,9 @@ func (c *Client) EditMilestoneByName(owner, repo string, name string, opt EditMi
|
||||
|
||||
// DeleteMilestone delete one milestone by id
|
||||
func (c *Client) DeleteMilestone(owner, repo string, id int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
@@ -185,6 +206,9 @@ func (c *Client) DeleteMilestoneByName(owner, repo string, name string) (*Respon
|
||||
}
|
||||
return c.DeleteMilestone(owner, repo, m.ID)
|
||||
}
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%s", owner, repo, name), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
12
vendor/code.gitea.io/sdk/gitea/issue_reaction.go
generated
vendored
12
vendor/code.gitea.io/sdk/gitea/issue_reaction.go
generated
vendored
@@ -20,7 +20,7 @@ type Reaction struct {
|
||||
|
||||
// GetIssueReactions get a list reactions of an issue
|
||||
func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
reactions := make([]*Reaction, 0, 10)
|
||||
@@ -30,7 +30,7 @@ func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction
|
||||
|
||||
// GetIssueCommentReactions get a list of reactions from a comment of an issue
|
||||
func (c *Client) GetIssueCommentReactions(owner, repo string, commentID int64) ([]*Reaction, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
reactions := make([]*Reaction, 0, 10)
|
||||
@@ -45,7 +45,7 @@ type editReactionOption struct {
|
||||
|
||||
// PostIssueReaction add a reaction to an issue
|
||||
func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction string) (*Reaction, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
reactionResponse := new(Reaction)
|
||||
@@ -61,7 +61,7 @@ func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction str
|
||||
|
||||
// DeleteIssueReaction remove a reaction from an issue
|
||||
func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction string) (*Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&editReactionOption{Reaction: reaction})
|
||||
@@ -74,7 +74,7 @@ func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction s
|
||||
|
||||
// PostIssueCommentReaction add a reaction to a comment of an issue
|
||||
func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Reaction, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
reactionResponse := new(Reaction)
|
||||
@@ -90,7 +90,7 @@ func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, r
|
||||
|
||||
// DeleteIssueCommentReaction remove a reaction from a comment of an issue
|
||||
func (c *Client) DeleteIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&editReactionOption{Reaction: reaction})
|
||||
|
18
vendor/code.gitea.io/sdk/gitea/issue_stopwatch.go
generated
vendored
18
vendor/code.gitea.io/sdk/gitea/issue_stopwatch.go
generated
vendored
@@ -11,8 +11,13 @@ import (
|
||||
|
||||
// StopWatch represents a running stopwatch of an issue / pr
|
||||
type StopWatch struct {
|
||||
Created time.Time `json:"created"`
|
||||
IssueIndex int64 `json:"issue_index"`
|
||||
Created time.Time `json:"created"`
|
||||
Seconds int64 `json:"seconds"`
|
||||
Duration string `json:"duration"`
|
||||
IssueIndex int64 `json:"issue_index"`
|
||||
IssueTitle string `json:"issue_title"`
|
||||
RepoOwnerName string `json:"repo_owner_name"`
|
||||
RepoName string `json:"repo_name"`
|
||||
}
|
||||
|
||||
// GetMyStopwatches list all stopwatches
|
||||
@@ -24,6 +29,9 @@ func (c *Client) GetMyStopwatches() ([]*StopWatch, *Response, error) {
|
||||
|
||||
// DeleteIssueStopwatch delete / cancel a specific stopwatch
|
||||
func (c *Client) DeleteIssueStopwatch(owner, repo string, index int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/delete", owner, repo, index), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
@@ -31,6 +39,9 @@ func (c *Client) DeleteIssueStopwatch(owner, repo string, index int64) (*Respons
|
||||
// StartIssueStopWatch starts a stopwatch for an existing issue for a given
|
||||
// repository
|
||||
func (c *Client) StartIssueStopWatch(owner, repo string, index int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/start", owner, repo, index), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
@@ -38,6 +49,9 @@ func (c *Client) StartIssueStopWatch(owner, repo string, index int64) (*Response
|
||||
// StopIssueStopWatch stops an existing stopwatch for an issue in a given
|
||||
// repository
|
||||
func (c *Client) StopIssueStopWatch(owner, repo string, index int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/stop", owner, repo, index), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
9
vendor/code.gitea.io/sdk/gitea/issue_subscription.go
generated
vendored
9
vendor/code.gitea.io/sdk/gitea/issue_subscription.go
generated
vendored
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
// GetIssueSubscribers get list of users who subscribed on an issue
|
||||
func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
subscribers := make([]*User, 0, 10)
|
||||
@@ -21,7 +21,7 @@ func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User,
|
||||
|
||||
// AddIssueSubscription Subscribe user to issue
|
||||
func (c *Client) AddIssueSubscription(owner, repo string, index int64, user string) (*Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil)
|
||||
@@ -39,7 +39,7 @@ func (c *Client) AddIssueSubscription(owner, repo string, index int64, user stri
|
||||
|
||||
// DeleteIssueSubscription unsubscribe user from issue
|
||||
func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user string) (*Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil)
|
||||
@@ -57,6 +57,9 @@ func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user s
|
||||
|
||||
// CheckIssueSubscription check if current user is subscribed to an issue
|
||||
func (c *Client) CheckIssueSubscription(owner, repo string, index int64) (*WatchInfo, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
77
vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go
generated
vendored
77
vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go
generated
vendored
@@ -8,6 +8,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -25,33 +26,50 @@ type TrackedTime struct {
|
||||
Issue *Issue `json:"issue"`
|
||||
}
|
||||
|
||||
// GetUserTrackedTimes list tracked times of a user
|
||||
func (c *Client) GetUserTrackedTimes(owner, repo, user string) ([]*TrackedTime, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
times := make([]*TrackedTime, 0, 10)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times/%s", owner, repo, user), nil, nil, ×)
|
||||
return times, resp, err
|
||||
// ListTrackedTimesOptions options for listing repository's tracked times
|
||||
type ListTrackedTimesOptions struct {
|
||||
ListOptions
|
||||
Since time.Time
|
||||
Before time.Time
|
||||
// User filter is only used by ListRepoTrackedTimes !!!
|
||||
User string
|
||||
}
|
||||
|
||||
// GetRepoTrackedTimes list tracked times of a repository
|
||||
func (c *Client) GetRepoTrackedTimes(owner, repo string) ([]*TrackedTime, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
// QueryEncode turns options into querystring argument
|
||||
func (opt *ListTrackedTimesOptions) QueryEncode() string {
|
||||
query := opt.getURLQuery()
|
||||
|
||||
if !opt.Since.IsZero() {
|
||||
query.Add("since", opt.Since.Format(time.RFC3339))
|
||||
}
|
||||
if !opt.Before.IsZero() {
|
||||
query.Add("before", opt.Before.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
if len(opt.User) != 0 {
|
||||
query.Add("user", opt.User)
|
||||
}
|
||||
|
||||
return query.Encode()
|
||||
}
|
||||
|
||||
// ListRepoTrackedTimes list tracked times of a repository
|
||||
func (c *Client) ListRepoTrackedTimes(owner, repo string, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
times := make([]*TrackedTime, 0, 10)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times", owner, repo), nil, nil, ×)
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/times", owner, repo))
|
||||
opt.setDefaults()
|
||||
link.RawQuery = opt.QueryEncode()
|
||||
times := make([]*TrackedTime, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, ×)
|
||||
return times, resp, err
|
||||
}
|
||||
|
||||
// GetMyTrackedTimes list tracked times of the current user
|
||||
func (c *Client) GetMyTrackedTimes() ([]*TrackedTime, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
times := make([]*TrackedTime, 0, 10)
|
||||
resp, err := c.getParsedResponse("GET", "/user/times", nil, nil, ×)
|
||||
resp, err := c.getParsedResponse("GET", "/user/times", jsonHeader, nil, ×)
|
||||
return times, resp, err
|
||||
}
|
||||
|
||||
@@ -75,7 +93,7 @@ func (opt AddTimeOption) Validate() error {
|
||||
|
||||
// AddTime adds time to issue with the given index
|
||||
func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*TrackedTime, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
@@ -92,36 +110,33 @@ func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*T
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// ListTrackedTimesOptions options for listing repository's tracked times
|
||||
type ListTrackedTimesOptions struct {
|
||||
ListOptions
|
||||
}
|
||||
|
||||
// ListTrackedTimes list tracked times of a single issue for a given repository
|
||||
func (c *Client) ListTrackedTimes(owner, repo string, index int64, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
// ListIssueTrackedTimes list tracked times of a single issue for a given repository
|
||||
func (c *Client) ListIssueTrackedTimes(owner, repo string, index int64, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index))
|
||||
opt.setDefaults()
|
||||
link.RawQuery = opt.QueryEncode()
|
||||
times := make([]*TrackedTime, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/times?%s", owner, repo, index, opt.getURLQuery().Encode()), nil, nil, ×)
|
||||
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, ×)
|
||||
return times, resp, err
|
||||
}
|
||||
|
||||
// ResetIssueTime reset tracked time of a single issue for a given repository
|
||||
func (c *Client) ResetIssueTime(owner, repo string, index int64) (*Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), nil, nil)
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), jsonHeader, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// DeleteTime delete a specific tracked time by id of a single issue for a given repository
|
||||
func (c *Client) DeleteTime(owner, repo string, index, timeID int64) (*Response, error) {
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times/%d", owner, repo, index, timeID), nil, nil)
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times/%d", owner, repo, index, timeID), jsonHeader, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
14
vendor/code.gitea.io/sdk/gitea/notifications.go
generated
vendored
14
vendor/code.gitea.io/sdk/gitea/notifications.go
generated
vendored
@@ -176,14 +176,17 @@ func (c *Client) ReadNotifications(opt MarkNotificationOptions) (*Response, erro
|
||||
}
|
||||
|
||||
// ListRepoNotifications list users's notification threads on a specific repo
|
||||
func (c *Client) ListRepoNotifications(owner, reponame string, opt ListNotificationOptions) ([]*NotificationThread, *Response, error) {
|
||||
func (c *Client) ListRepoNotifications(owner, repo string, opt ListNotificationOptions) ([]*NotificationThread, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(c); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, reponame))
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, repo))
|
||||
link.RawQuery = opt.QueryEncode()
|
||||
threads := make([]*NotificationThread, 0, 10)
|
||||
resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &threads)
|
||||
@@ -191,14 +194,17 @@ func (c *Client) ListRepoNotifications(owner, reponame string, opt ListNotificat
|
||||
}
|
||||
|
||||
// ReadRepoNotifications mark notification threads as read on a specific repo
|
||||
func (c *Client) ReadRepoNotifications(owner, reponame string, opt MarkNotificationOptions) (*Response, error) {
|
||||
func (c *Client) ReadRepoNotifications(owner, repo string, opt MarkNotificationOptions) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := opt.Validate(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, reponame))
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, repo))
|
||||
link.RawQuery = opt.QueryEncode()
|
||||
_, resp, err := c.getResponse("PUT", link.String(), nil, nil)
|
||||
return resp, err
|
||||
|
12
vendor/code.gitea.io/sdk/gitea/org.go
generated
vendored
12
vendor/code.gitea.io/sdk/gitea/org.go
generated
vendored
@@ -52,6 +52,9 @@ func (c *Client) ListMyOrgs(opt ListOrgsOptions) ([]*Organization, *Response, er
|
||||
|
||||
// ListUserOrgs list all of some user's organizations
|
||||
func (c *Client) ListUserOrgs(user string, opt ListOrgsOptions) ([]*Organization, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
orgs := make([]*Organization, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs?%s", user, opt.getURLQuery().Encode()), nil, nil, &orgs)
|
||||
@@ -60,6 +63,9 @@ func (c *Client) ListUserOrgs(user string, opt ListOrgsOptions) ([]*Organization
|
||||
|
||||
// GetOrg get one organization by name
|
||||
func (c *Client) GetOrg(orgname string) (*Organization, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&orgname); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
org := new(Organization)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s", orgname), nil, nil, org)
|
||||
return org, resp, err
|
||||
@@ -124,6 +130,9 @@ func (opt EditOrgOption) Validate() error {
|
||||
|
||||
// EditOrg modify one organization via options
|
||||
func (c *Client) EditOrg(orgname string, opt EditOrgOption) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&orgname); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,6 +146,9 @@ func (c *Client) EditOrg(orgname string, opt EditOrgOption) (*Response, error) {
|
||||
|
||||
// DeleteOrg deletes an organization
|
||||
func (c *Client) DeleteOrg(orgname string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&orgname); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
32
vendor/code.gitea.io/sdk/gitea/org_member.go
generated
vendored
32
vendor/code.gitea.io/sdk/gitea/org_member.go
generated
vendored
@@ -12,7 +12,10 @@ import (
|
||||
|
||||
// DeleteOrgMembership remove a member from an organization
|
||||
func (c *Client) DeleteOrgMembership(org, user string) (*Response, error) {
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
|
||||
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/members/%s", org, user), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@@ -23,10 +26,13 @@ type ListOrgMembershipOption struct {
|
||||
|
||||
// ListOrgMembership list an organization's members
|
||||
func (c *Client) ListOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
users := make([]*User, 0, opt.PageSize)
|
||||
|
||||
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/members", url.PathEscape(org)))
|
||||
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/members", org))
|
||||
link.RawQuery = opt.getURLQuery().Encode()
|
||||
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users)
|
||||
return users, resp, err
|
||||
@@ -34,10 +40,13 @@ func (c *Client) ListOrgMembership(org string, opt ListOrgMembershipOption) ([]*
|
||||
|
||||
// ListPublicOrgMembership list an organization's members
|
||||
func (c *Client) ListPublicOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
users := make([]*User, 0, opt.PageSize)
|
||||
|
||||
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/public_members", url.PathEscape(org)))
|
||||
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/public_members", org))
|
||||
link.RawQuery = opt.getURLQuery().Encode()
|
||||
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users)
|
||||
return users, resp, err
|
||||
@@ -45,7 +54,10 @@ func (c *Client) ListPublicOrgMembership(org string, opt ListOrgMembershipOption
|
||||
|
||||
// CheckOrgMembership Check if a user is a member of an organization
|
||||
func (c *Client) CheckOrgMembership(org, user string) (bool, *Response, error) {
|
||||
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
|
||||
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/members/%s", org, user), nil, nil)
|
||||
if err != nil {
|
||||
return false, resp, err
|
||||
}
|
||||
@@ -61,7 +73,10 @@ func (c *Client) CheckOrgMembership(org, user string) (bool, *Response, error) {
|
||||
|
||||
// CheckPublicOrgMembership Check if a user is a member of an organization
|
||||
func (c *Client) CheckPublicOrgMembership(org, user string) (bool, *Response, error) {
|
||||
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
|
||||
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil)
|
||||
if err != nil {
|
||||
return false, resp, err
|
||||
}
|
||||
@@ -77,15 +92,18 @@ func (c *Client) CheckPublicOrgMembership(org, user string) (bool, *Response, er
|
||||
|
||||
// SetPublicOrgMembership publicize/conceal a user's membership
|
||||
func (c *Client) SetPublicOrgMembership(org, user string, visible bool) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&org, &user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
status int
|
||||
err error
|
||||
resp *Response
|
||||
)
|
||||
if visible {
|
||||
status, resp, err = c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
|
||||
status, resp, err = c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil)
|
||||
} else {
|
||||
status, resp, err = c.getStatusCode("DELETE", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
|
||||
status, resp, err = c.getStatusCode("DELETE", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil)
|
||||
}
|
||||
if err != nil {
|
||||
return resp, err
|
||||
|
21
vendor/code.gitea.io/sdk/gitea/org_team.go
generated
vendored
21
vendor/code.gitea.io/sdk/gitea/org_team.go
generated
vendored
@@ -30,6 +30,9 @@ type ListTeamsOptions struct {
|
||||
|
||||
// ListOrgTeams lists all teams of an organization
|
||||
func (c *Client) ListOrgTeams(org string, opt ListTeamsOptions) ([]*Team, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
teams := make([]*Team, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams?%s", org, opt.getURLQuery().Encode()), nil, nil, &teams)
|
||||
@@ -83,6 +86,9 @@ func (opt CreateTeamOption) Validate() error {
|
||||
|
||||
// CreateTeam creates a team for an organization
|
||||
func (c *Client) CreateTeam(org string, opt CreateTeamOption) (*Team, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -159,6 +165,9 @@ func (c *Client) ListTeamMembers(id int64, opt ListTeamMembersOptions) ([]*User,
|
||||
|
||||
// GetTeamMember gets a member of a team
|
||||
func (c *Client) GetTeamMember(id int64, user string) (*User, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
m := new(User)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil, m)
|
||||
return m, resp, err
|
||||
@@ -166,12 +175,18 @@ func (c *Client) GetTeamMember(id int64, user string) (*User, *Response, error)
|
||||
|
||||
// AddTeamMember adds a member to a team
|
||||
func (c *Client) AddTeamMember(id int64, user string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// RemoveTeamMember removes a member from a team
|
||||
func (c *Client) RemoveTeamMember(id int64, user string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
@@ -191,12 +206,18 @@ func (c *Client) ListTeamRepositories(id int64, opt ListTeamRepositoriesOptions)
|
||||
|
||||
// AddTeamRepository adds a repository to a team
|
||||
func (c *Client) AddTeamRepository(id int64, org, repo string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&org, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// RemoveTeamRepository removes a repository from a team
|
||||
func (c *Client) RemoveTeamRepository(id int64, org, repo string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&org, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
53
vendor/code.gitea.io/sdk/gitea/pull.go
generated
vendored
53
vendor/code.gitea.io/sdk/gitea/pull.go
generated
vendored
@@ -99,19 +99,37 @@ func (opt *ListPullRequestsOptions) QueryEncode() string {
|
||||
|
||||
// ListRepoPullRequests list PRs of one repository
|
||||
func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOptions) ([]*PullRequest, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
prs := make([]*PullRequest, 0, opt.PageSize)
|
||||
|
||||
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", owner, repo))
|
||||
link.RawQuery = opt.QueryEncode()
|
||||
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &prs)
|
||||
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
|
||||
for i := range prs {
|
||||
if err := fixPullHeadSha(c, prs[i]); err != nil {
|
||||
return prs, resp, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return prs, resp, err
|
||||
}
|
||||
|
||||
// GetPullRequest get information of one PR
|
||||
func (c *Client) GetPullRequest(owner, repo string, index int64) (*PullRequest, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pr := new(PullRequest)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index), nil, nil, pr)
|
||||
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
|
||||
if err := fixPullHeadSha(c, pr); err != nil {
|
||||
return pr, resp, err
|
||||
}
|
||||
}
|
||||
return pr, resp, err
|
||||
}
|
||||
|
||||
@@ -130,6 +148,9 @@ type CreatePullRequestOption struct {
|
||||
|
||||
// CreatePullRequest create pull request with options
|
||||
func (c *Client) CreatePullRequest(owner, repo string, opt CreatePullRequestOption) (*PullRequest, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -169,6 +190,9 @@ func (opt EditPullRequestOption) Validate(c *Client) error {
|
||||
|
||||
// EditPullRequest modify pull request with PR id and options
|
||||
func (c *Client) EditPullRequest(owner, repo string, index int64, opt EditPullRequestOption) (*PullRequest, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(c); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -202,6 +226,9 @@ func (opt MergePullRequestOption) Validate(c *Client) error {
|
||||
|
||||
// MergePullRequest merge a PR to repository by PR id
|
||||
func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePullRequestOption) (bool, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
if err := opt.Validate(c); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@@ -218,6 +245,9 @@ func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePull
|
||||
|
||||
// IsPullRequestMerged test if one PR is merged to one repository
|
||||
func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil)
|
||||
|
||||
if err != nil {
|
||||
@@ -229,6 +259,9 @@ func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Re
|
||||
|
||||
// getPullRequestDiffOrPatch gets the patch or diff file as bytes for a PR
|
||||
func (c *Client) getPullRequestDiffOrPatch(owner, repo, kind string, index int64) ([]byte, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &kind); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||
r, _, err2 := c.GetRepo(owner, repo)
|
||||
if err2 != nil {
|
||||
@@ -251,3 +284,23 @@ func (c *Client) GetPullRequestPatch(owner, repo string, index int64) ([]byte, *
|
||||
func (c *Client) GetPullRequestDiff(owner, repo string, index int64) ([]byte, *Response, error) {
|
||||
return c.getPullRequestDiffOrPatch(owner, repo, "diff", index)
|
||||
}
|
||||
|
||||
// fixPullHeadSha is a workaround for https://github.com/go-gitea/gitea/issues/12675
|
||||
// When no head sha is available, this is because the branch got deleted in the base repo.
|
||||
// pr.Head.Ref points in this case not to the head repo branch name, but the base repo ref,
|
||||
// which stays available to resolve the commit sha. This is fixed for gitea >= 1.14.0
|
||||
func fixPullHeadSha(client *Client, pr *PullRequest) error {
|
||||
if pr.Base != nil && pr.Base.Repository != nil && pr.Base.Repository.Owner != nil &&
|
||||
pr.Head != nil && pr.Head.Ref != "" && pr.Head.Sha == "" {
|
||||
owner := pr.Base.Repository.Owner.UserName
|
||||
repo := pr.Base.Repository.Name
|
||||
refs, _, err := client.GetRepoRefs(owner, repo, pr.Head.Ref)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(refs) == 0 {
|
||||
return fmt.Errorf("unable to resolve PR ref '%s'", pr.Head.Ref)
|
||||
}
|
||||
pr.Head.Sha = refs[0].Object.SHA
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
123
vendor/code.gitea.io/sdk/gitea/pull_review.go
generated
vendored
123
vendor/code.gitea.io/sdk/gitea/pull_review.go
generated
vendored
@@ -33,15 +33,19 @@ const (
|
||||
|
||||
// PullReview represents a pull request review
|
||||
type PullReview struct {
|
||||
ID int64 `json:"id"`
|
||||
Reviewer *User `json:"user"`
|
||||
State ReviewStateType `json:"state"`
|
||||
Body string `json:"body"`
|
||||
CommitID string `json:"commit_id"`
|
||||
Stale bool `json:"stale"`
|
||||
Official bool `json:"official"`
|
||||
CodeCommentsCount int `json:"comments_count"`
|
||||
Submitted time.Time `json:"submitted_at"`
|
||||
ID int64 `json:"id"`
|
||||
Reviewer *User `json:"user"`
|
||||
ReviewerTeam *Team `json:"team"`
|
||||
State ReviewStateType `json:"state"`
|
||||
Body string `json:"body"`
|
||||
CommitID string `json:"commit_id"`
|
||||
// Stale indicates if the pull has changed since the review
|
||||
Stale bool `json:"stale"`
|
||||
// Official indicates if the review counts towards the required approval limit, if PR base is a protected branch
|
||||
Official bool `json:"official"`
|
||||
Dismissed bool `json:"dismissed"`
|
||||
CodeCommentsCount int `json:"comments_count"`
|
||||
Submitted time.Time `json:"submitted_at"`
|
||||
|
||||
HTMLURL string `json:"html_url"`
|
||||
HTMLPullURL string `json:"pull_request_url"`
|
||||
@@ -93,6 +97,17 @@ type SubmitPullReviewOptions struct {
|
||||
Body string `json:"body"`
|
||||
}
|
||||
|
||||
// DismissPullReviewOptions are options to dismiss a pull review
|
||||
type DismissPullReviewOptions struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// PullReviewRequestOptions are options to add or remove pull review requests
|
||||
type PullReviewRequestOptions struct {
|
||||
Reviewers []string `json:"reviewers"`
|
||||
TeamReviewers []string `json:"team_reviewers"`
|
||||
}
|
||||
|
||||
// ListPullReviewsOptions options for listing PullReviews
|
||||
type ListPullReviewsOptions struct {
|
||||
ListOptions
|
||||
@@ -132,6 +147,9 @@ func (opt CreatePullReviewComment) Validate() error {
|
||||
|
||||
// ListPullReviews lists all reviews of a pull request
|
||||
func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullReviewsOptions) ([]*PullReview, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -147,6 +165,9 @@ func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullRe
|
||||
|
||||
// GetPullReview gets a specific review of a pull request
|
||||
func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -158,6 +179,9 @@ func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview
|
||||
|
||||
// ListPullReviewComments lists all comments of a pull request review
|
||||
func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([]*PullReviewComment, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -170,6 +194,9 @@ func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([]
|
||||
|
||||
// DeletePullReview delete a specific review from a pull request
|
||||
func (c *Client) DeletePullReview(owner, repo string, index, id int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -180,6 +207,9 @@ func (c *Client) DeletePullReview(owner, repo string, index, id int64) (*Respons
|
||||
|
||||
// CreatePullReview create a review to an pull request
|
||||
func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePullReviewOptions) (*PullReview, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -200,6 +230,9 @@ func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePul
|
||||
|
||||
// SubmitPullReview submit a pending review to an pull request
|
||||
func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt SubmitPullReviewOptions) (*PullReview, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -217,3 +250,75 @@ func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt Submi
|
||||
jsonHeader, bytes.NewReader(body), r)
|
||||
return r, resp, err
|
||||
}
|
||||
|
||||
// CreateReviewRequests create review requests to an pull request
|
||||
func (c *Client) CreateReviewRequests(owner, repo string, index int64, opt PullReviewRequestOptions) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, resp, err := c.getResponse("POST",
|
||||
fmt.Sprintf("/repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, index),
|
||||
jsonHeader, bytes.NewReader(body))
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// DeleteReviewRequests delete review requests to an pull request
|
||||
func (c *Client) DeleteReviewRequests(owner, repo string, index int64, opt PullReviewRequestOptions) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, resp, err := c.getResponse("DELETE",
|
||||
fmt.Sprintf("/repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, index),
|
||||
jsonHeader, bytes.NewReader(body))
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// DismissPullReview dismiss a review for a pull request
|
||||
func (c *Client) DismissPullReview(owner, repo string, index, id int64, opt DismissPullReviewOptions) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, resp, err := c.getResponse("POST",
|
||||
fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/dismissals", owner, repo, index, id),
|
||||
jsonHeader, bytes.NewReader(body))
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// UnDismissPullReview cancel to dismiss a review for a pull request
|
||||
func (c *Client) UnDismissPullReview(owner, repo string, index, id int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, resp, err := c.getResponse("POST",
|
||||
fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/undismissals", owner, repo, index, id),
|
||||
jsonHeader, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
61
vendor/code.gitea.io/sdk/gitea/release.go
generated
vendored
61
vendor/code.gitea.io/sdk/gitea/release.go
generated
vendored
@@ -21,6 +21,7 @@ type Release struct {
|
||||
Title string `json:"name"`
|
||||
Note string `json:"body"`
|
||||
URL string `json:"url"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
TarURL string `json:"tarball_url"`
|
||||
ZipURL string `json:"zipball_url"`
|
||||
IsDraft bool `json:"draft"`
|
||||
@@ -37,32 +38,41 @@ type ListReleasesOptions struct {
|
||||
}
|
||||
|
||||
// ListReleases list releases of a repository
|
||||
func (c *Client) ListReleases(user, repo string, opt ListReleasesOptions) ([]*Release, *Response, error) {
|
||||
func (c *Client) ListReleases(owner, repo string, opt ListReleasesOptions) ([]*Release, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
releases := make([]*Release, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET",
|
||||
fmt.Sprintf("/repos/%s/%s/releases?%s", user, repo, opt.getURLQuery().Encode()),
|
||||
fmt.Sprintf("/repos/%s/%s/releases?%s", owner, repo, opt.getURLQuery().Encode()),
|
||||
nil, nil, &releases)
|
||||
return releases, resp, err
|
||||
}
|
||||
|
||||
// GetRelease get a release of a repository by id
|
||||
func (c *Client) GetRelease(user, repo string, id int64) (*Release, *Response, error) {
|
||||
func (c *Client) GetRelease(owner, repo string, id int64) (*Release, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
r := new(Release)
|
||||
resp, err := c.getParsedResponse("GET",
|
||||
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
|
||||
fmt.Sprintf("/repos/%s/%s/releases/%d", owner, repo, id),
|
||||
jsonHeader, nil, &r)
|
||||
return r, resp, err
|
||||
}
|
||||
|
||||
// GetReleaseByTag get a release of a repository by tag
|
||||
func (c *Client) GetReleaseByTag(user, repo string, tag string) (*Release, *Response, error) {
|
||||
func (c *Client) GetReleaseByTag(owner, repo string, tag string) (*Release, *Response, error) {
|
||||
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
|
||||
return c.fallbackGetReleaseByTag(user, repo, tag)
|
||||
return c.fallbackGetReleaseByTag(owner, repo, tag)
|
||||
}
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &tag); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
r := new(Release)
|
||||
resp, err := c.getParsedResponse("GET",
|
||||
fmt.Sprintf("/repos/%s/%s/releases/tags/%s", user, repo, tag),
|
||||
fmt.Sprintf("/repos/%s/%s/releases/tags/%s", owner, repo, tag),
|
||||
nil, nil, &r)
|
||||
return r, resp, err
|
||||
}
|
||||
@@ -86,7 +96,10 @@ func (opt CreateReleaseOption) Validate() error {
|
||||
}
|
||||
|
||||
// CreateRelease create a release
|
||||
func (c *Client) CreateRelease(user, repo string, opt CreateReleaseOption) (*Release, *Response, error) {
|
||||
func (c *Client) CreateRelease(owner, repo string, opt CreateReleaseOption) (*Release, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -96,7 +109,7 @@ func (c *Client) CreateRelease(user, repo string, opt CreateReleaseOption) (*Rel
|
||||
}
|
||||
r := new(Release)
|
||||
resp, err := c.getParsedResponse("POST",
|
||||
fmt.Sprintf("/repos/%s/%s/releases", user, repo),
|
||||
fmt.Sprintf("/repos/%s/%s/releases", owner, repo),
|
||||
jsonHeader, bytes.NewReader(body), r)
|
||||
return r, resp, err
|
||||
}
|
||||
@@ -112,30 +125,50 @@ type EditReleaseOption struct {
|
||||
}
|
||||
|
||||
// EditRelease edit a release
|
||||
func (c *Client) EditRelease(user, repo string, id int64, form EditReleaseOption) (*Release, *Response, error) {
|
||||
func (c *Client) EditRelease(owner, repo string, id int64, form EditReleaseOption) (*Release, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(form)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
r := new(Release)
|
||||
resp, err := c.getParsedResponse("PATCH",
|
||||
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
|
||||
fmt.Sprintf("/repos/%s/%s/releases/%d", owner, repo, id),
|
||||
jsonHeader, bytes.NewReader(body), r)
|
||||
return r, resp, err
|
||||
}
|
||||
|
||||
// DeleteRelease delete a release from a repository
|
||||
// DeleteRelease delete a release from a repository, keeping its tag
|
||||
func (c *Client) DeleteRelease(user, repo string, id int64) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE",
|
||||
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
|
||||
nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// DeleteReleaseByTag deletes a release frm a repository by tag
|
||||
func (c *Client) DeleteReleaseByTag(user, repo string, tag string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE",
|
||||
fmt.Sprintf("/repos/%s/%s/releases/tags/%s", user, repo, tag),
|
||||
nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// fallbackGetReleaseByTag is fallback for old gitea installations ( < 1.13.0 )
|
||||
func (c *Client) fallbackGetReleaseByTag(user, repo string, tag string) (*Release, *Response, error) {
|
||||
func (c *Client) fallbackGetReleaseByTag(owner, repo string, tag string) (*Release, *Response, error) {
|
||||
for i := 1; ; i++ {
|
||||
rl, resp, err := c.ListReleases(user, repo, ListReleasesOptions{ListOptions{Page: i}})
|
||||
rl, resp, err := c.ListReleases(owner, repo, ListReleasesOptions{ListOptions{Page: i}})
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
167
vendor/code.gitea.io/sdk/gitea/repo.go
generated
vendored
167
vendor/code.gitea.io/sdk/gitea/repo.go
generated
vendored
@@ -9,6 +9,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -21,42 +22,77 @@ type Permission struct {
|
||||
Pull bool `json:"pull"`
|
||||
}
|
||||
|
||||
// InternalTracker represents settings for internal tracker
|
||||
type InternalTracker struct {
|
||||
// Enable time tracking (Built-in issue tracker)
|
||||
EnableTimeTracker bool `json:"enable_time_tracker"`
|
||||
// Let only contributors track time (Built-in issue tracker)
|
||||
AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"`
|
||||
// Enable dependencies for issues and pull requests (Built-in issue tracker)
|
||||
EnableIssueDependencies bool `json:"enable_issue_dependencies"`
|
||||
}
|
||||
|
||||
// ExternalTracker represents settings for external tracker
|
||||
type ExternalTracker struct {
|
||||
// URL of external issue tracker.
|
||||
ExternalTrackerURL string `json:"external_tracker_url"`
|
||||
// External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index.
|
||||
ExternalTrackerFormat string `json:"external_tracker_format"`
|
||||
// External Issue Tracker Number Format, either `numeric` or `alphanumeric`
|
||||
ExternalTrackerStyle string `json:"external_tracker_style"`
|
||||
}
|
||||
|
||||
// ExternalWiki represents setting for external wiki
|
||||
type ExternalWiki struct {
|
||||
// URL of external wiki.
|
||||
ExternalWikiURL string `json:"external_wiki_url"`
|
||||
}
|
||||
|
||||
// Repository represents a repository
|
||||
type Repository struct {
|
||||
ID int64 `json:"id"`
|
||||
Owner *User `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
FullName string `json:"full_name"`
|
||||
Description string `json:"description"`
|
||||
Empty bool `json:"empty"`
|
||||
Private bool `json:"private"`
|
||||
Fork bool `json:"fork"`
|
||||
Parent *Repository `json:"parent"`
|
||||
Mirror bool `json:"mirror"`
|
||||
Size int `json:"size"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
CloneURL string `json:"clone_url"`
|
||||
OriginalURL string `json:"original_url"`
|
||||
Website string `json:"website"`
|
||||
Stars int `json:"stars_count"`
|
||||
Forks int `json:"forks_count"`
|
||||
Watchers int `json:"watchers_count"`
|
||||
OpenIssues int `json:"open_issues_count"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Archived bool `json:"archived"`
|
||||
Created time.Time `json:"created_at"`
|
||||
Updated time.Time `json:"updated_at"`
|
||||
Permissions *Permission `json:"permissions,omitempty"`
|
||||
HasIssues bool `json:"has_issues"`
|
||||
HasWiki bool `json:"has_wiki"`
|
||||
HasPullRequests bool `json:"has_pull_requests"`
|
||||
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
|
||||
AllowMerge bool `json:"allow_merge_commits"`
|
||||
AllowRebase bool `json:"allow_rebase"`
|
||||
AllowRebaseMerge bool `json:"allow_rebase_explicit"`
|
||||
AllowSquash bool `json:"allow_squash_merge"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
ID int64 `json:"id"`
|
||||
Owner *User `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
FullName string `json:"full_name"`
|
||||
Description string `json:"description"`
|
||||
Empty bool `json:"empty"`
|
||||
Private bool `json:"private"`
|
||||
Fork bool `json:"fork"`
|
||||
Template bool `json:"template"`
|
||||
Parent *Repository `json:"parent"`
|
||||
Mirror bool `json:"mirror"`
|
||||
Size int `json:"size"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
CloneURL string `json:"clone_url"`
|
||||
OriginalURL string `json:"original_url"`
|
||||
Website string `json:"website"`
|
||||
Stars int `json:"stars_count"`
|
||||
Forks int `json:"forks_count"`
|
||||
Watchers int `json:"watchers_count"`
|
||||
OpenIssues int `json:"open_issues_count"`
|
||||
OpenPulls int `json:"open_pr_counter"`
|
||||
Releases int `json:"release_counter"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Archived bool `json:"archived"`
|
||||
Created time.Time `json:"created_at"`
|
||||
Updated time.Time `json:"updated_at"`
|
||||
Permissions *Permission `json:"permissions,omitempty"`
|
||||
HasIssues bool `json:"has_issues"`
|
||||
InternalTracker *InternalTracker `json:"internal_tracker,omitempty"`
|
||||
ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"`
|
||||
HasWiki bool `json:"has_wiki"`
|
||||
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"`
|
||||
HasPullRequests bool `json:"has_pull_requests"`
|
||||
HasProjects bool `json:"has_projects"`
|
||||
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
|
||||
AllowMerge bool `json:"allow_merge_commits"`
|
||||
AllowRebase bool `json:"allow_rebase"`
|
||||
AllowRebaseMerge bool `json:"allow_rebase_explicit"`
|
||||
AllowSquash bool `json:"allow_squash_merge"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
Internal bool `json:"internal"`
|
||||
MirrorInterval string `json:"mirror_interval"`
|
||||
}
|
||||
|
||||
// RepoType represent repo type
|
||||
@@ -102,6 +138,9 @@ func (c *Client) ListMyRepos(opt ListReposOptions) ([]*Repository, *Response, er
|
||||
|
||||
// ListUserRepos list all repositories of one user by user's name
|
||||
func (c *Client) ListUserRepos(user string, opt ListReposOptions) ([]*Repository, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
repos := make([]*Repository, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos?%s", user, opt.getURLQuery().Encode()), nil, nil, &repos)
|
||||
@@ -115,6 +154,9 @@ type ListOrgReposOptions struct {
|
||||
|
||||
// ListOrgRepos list all repositories of one organization by organization's name
|
||||
func (c *Client) ListOrgRepos(org string, opt ListOrgReposOptions) ([]*Repository, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
repos := make([]*Repository, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos?%s", org, opt.getURLQuery().Encode()), nil, nil, &repos)
|
||||
@@ -315,6 +357,9 @@ func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, *Response, error
|
||||
|
||||
// CreateOrgRepo creates an organization repository for authenticated user.
|
||||
func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&org); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := opt.Validate(c); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -329,6 +374,9 @@ func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, *
|
||||
|
||||
// GetRepo returns information of a repository of given owner.
|
||||
func (c *Client) GetRepo(owner, reponame string) (*Repository, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &reponame); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
repo := new(Repository)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s", owner, reponame), nil, nil, repo)
|
||||
return repo, resp, err
|
||||
@@ -346,14 +394,24 @@ type EditRepoOption struct {
|
||||
// Note: you will get a 422 error if the organization restricts changing repository visibility to organization
|
||||
// owners and a non-owner tries to change the value of private.
|
||||
Private *bool `json:"private,omitempty"`
|
||||
// either `true` to make this repository a template or `false` to make it a normal repository
|
||||
Template *bool `json:"template,omitempty"`
|
||||
// either `true` to enable issues for this repository or `false` to disable them.
|
||||
HasIssues *bool `json:"has_issues,omitempty"`
|
||||
// set this structure to configure internal issue tracker (requires has_issues)
|
||||
InternalTracker *InternalTracker `json:"internal_tracker,omitempty"`
|
||||
// set this structure to use external issue tracker (requires has_issues)
|
||||
ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"`
|
||||
// either `true` to enable the wiki for this repository or `false` to disable it.
|
||||
HasWiki *bool `json:"has_wiki,omitempty"`
|
||||
// set this structure to use external wiki instead of internal (requires has_wiki)
|
||||
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"`
|
||||
// sets the default branch for this repository.
|
||||
DefaultBranch *string `json:"default_branch,omitempty"`
|
||||
// either `true` to allow pull requests, or `false` to prevent pull request.
|
||||
HasPullRequests *bool `json:"has_pull_requests,omitempty"`
|
||||
// either `true` to enable project unit, or `false` to disable them.
|
||||
HasProjects *bool `json:"has_projects,omitempty"`
|
||||
// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.
|
||||
IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace_conflicts,omitempty"`
|
||||
// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.
|
||||
@@ -366,10 +424,15 @@ type EditRepoOption struct {
|
||||
AllowSquash *bool `json:"allow_squash_merge,omitempty"`
|
||||
// set to `true` to archive this repository.
|
||||
Archived *bool `json:"archived,omitempty"`
|
||||
// set to a string like `8h30m0s` to set the mirror interval time
|
||||
MirrorInterval *string `json:"mirror_interval,omitempty"`
|
||||
}
|
||||
|
||||
// EditRepo edit the properties of a repository
|
||||
func (c *Client) EditRepo(owner, reponame string, opt EditRepoOption) (*Repository, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &reponame); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := json.Marshal(&opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -381,18 +444,27 @@ func (c *Client) EditRepo(owner, reponame string, opt EditRepoOption) (*Reposito
|
||||
|
||||
// DeleteRepo deletes a repository of user or organization.
|
||||
func (c *Client) DeleteRepo(owner, repo string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// MirrorSync adds a mirrored repository to the mirror sync queue.
|
||||
func (c *Client) MirrorSync(owner, repo string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/mirror-sync", owner, repo), nil, nil)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// GetRepoLanguages return language stats of a repo
|
||||
func (c *Client) GetRepoLanguages(owner, repo string) (map[string]int64, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
langMap := make(map[string]int64)
|
||||
|
||||
data, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/languages", owner, repo), jsonHeader, nil)
|
||||
@@ -418,5 +490,30 @@ const (
|
||||
// GetArchive get an archive of a repository by git reference
|
||||
// e.g.: ref -> master, 70b7c74b33, v1.2.1, ...
|
||||
func (c *Client) GetArchive(owner, repo, ref string, ext ArchiveType) ([]byte, *Response, error) {
|
||||
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, url.PathEscape(ref), ext), nil, nil)
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ref = pathEscapeSegments(ref)
|
||||
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, ref, ext), nil, nil)
|
||||
}
|
||||
|
||||
// GetArchiveReader gets a `git archive` for a particular tree-ish git reference
|
||||
// such as a branch name (`master`), a commit hash (`70b7c74b33`), a tag
|
||||
// (`v1.2.1`). The archive is returned as a byte stream in a ReadCloser. It is
|
||||
// the responsibility of the client to close the reader.
|
||||
func (c *Client) GetArchiveReader(owner, repo, ref string, ext ArchiveType) (io.ReadCloser, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ref = pathEscapeSegments(ref)
|
||||
resp, err := c.doRequest("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, ref, ext), nil, nil)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
if _, err := statusCodeToErr(resp); err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return resp.Body, resp, nil
|
||||
}
|
||||
|
15
vendor/code.gitea.io/sdk/gitea/repo_branch.go
generated
vendored
15
vendor/code.gitea.io/sdk/gitea/repo_branch.go
generated
vendored
@@ -20,9 +20,6 @@ type PayloadUser struct {
|
||||
UserName string `json:"username"`
|
||||
}
|
||||
|
||||
// FIXME: consider using same format as API when commits API are added.
|
||||
// applies to PayloadCommit and PayloadCommitVerification
|
||||
|
||||
// PayloadCommit represents a commit
|
||||
type PayloadCommit struct {
|
||||
// sha1 hash of the commit
|
||||
@@ -66,6 +63,9 @@ type ListRepoBranchesOptions struct {
|
||||
|
||||
// ListRepoBranches list all the branches of one repository
|
||||
func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions) ([]*Branch, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
opt.setDefaults()
|
||||
branches := make([]*Branch, 0, opt.PageSize)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &branches)
|
||||
@@ -74,6 +74,9 @@ func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions
|
||||
|
||||
// GetRepoBranch get one branch's information of one repository
|
||||
func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
b := new(Branch)
|
||||
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil, &b)
|
||||
if err != nil {
|
||||
@@ -84,6 +87,9 @@ func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, e
|
||||
|
||||
// DeleteRepoBranch delete a branch in a repository
|
||||
func (c *Client) DeleteRepoBranch(user, repo, branch string) (bool, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@@ -118,6 +124,9 @@ func (opt CreateBranchOption) Validate() error {
|
||||
|
||||
// CreateBranch creates a branch for a user's repository
|
||||
func (c *Client) CreateBranch(owner, repo string, opt CreateBranchOption) (*Branch, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
140
vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go
generated
vendored
140
vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go
generated
vendored
@@ -14,75 +14,78 @@ import (
|
||||
|
||||
// BranchProtection represents a branch protection for a repository
|
||||
type BranchProtection struct {
|
||||
BranchName string `json:"branch_name"`
|
||||
EnablePush bool `json:"enable_push"`
|
||||
EnablePushWhitelist bool `json:"enable_push_whitelist"`
|
||||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
EnableStatusCheck bool `json:"enable_status_check"`
|
||||
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||
RequiredApprovals int64 `json:"required_approvals"`
|
||||
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
|
||||
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
|
||||
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
|
||||
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
|
||||
RequireSignedCommits bool `json:"require_signed_commits"`
|
||||
ProtectedFilePatterns string `json:"protected_file_patterns"`
|
||||
Created time.Time `json:"created_at"`
|
||||
Updated time.Time `json:"updated_at"`
|
||||
BranchName string `json:"branch_name"`
|
||||
EnablePush bool `json:"enable_push"`
|
||||
EnablePushWhitelist bool `json:"enable_push_whitelist"`
|
||||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
EnableStatusCheck bool `json:"enable_status_check"`
|
||||
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||
RequiredApprovals int64 `json:"required_approvals"`
|
||||
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
|
||||
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
|
||||
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"`
|
||||
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
|
||||
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
|
||||
RequireSignedCommits bool `json:"require_signed_commits"`
|
||||
ProtectedFilePatterns string `json:"protected_file_patterns"`
|
||||
Created time.Time `json:"created_at"`
|
||||
Updated time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// CreateBranchProtectionOption options for creating a branch protection
|
||||
type CreateBranchProtectionOption struct {
|
||||
BranchName string `json:"branch_name"`
|
||||
EnablePush bool `json:"enable_push"`
|
||||
EnablePushWhitelist bool `json:"enable_push_whitelist"`
|
||||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
EnableStatusCheck bool `json:"enable_status_check"`
|
||||
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||
RequiredApprovals int64 `json:"required_approvals"`
|
||||
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
|
||||
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
|
||||
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
|
||||
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
|
||||
RequireSignedCommits bool `json:"require_signed_commits"`
|
||||
ProtectedFilePatterns string `json:"protected_file_patterns"`
|
||||
BranchName string `json:"branch_name"`
|
||||
EnablePush bool `json:"enable_push"`
|
||||
EnablePushWhitelist bool `json:"enable_push_whitelist"`
|
||||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
EnableStatusCheck bool `json:"enable_status_check"`
|
||||
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||
RequiredApprovals int64 `json:"required_approvals"`
|
||||
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
|
||||
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
|
||||
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"`
|
||||
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
|
||||
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
|
||||
RequireSignedCommits bool `json:"require_signed_commits"`
|
||||
ProtectedFilePatterns string `json:"protected_file_patterns"`
|
||||
}
|
||||
|
||||
// EditBranchProtectionOption options for editing a branch protection
|
||||
type EditBranchProtectionOption struct {
|
||||
EnablePush *bool `json:"enable_push"`
|
||||
EnablePushWhitelist *bool `json:"enable_push_whitelist"`
|
||||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist *bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
EnableStatusCheck *bool `json:"enable_status_check"`
|
||||
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||
RequiredApprovals *int64 `json:"required_approvals"`
|
||||
EnableApprovalsWhitelist *bool `json:"enable_approvals_whitelist"`
|
||||
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||
BlockOnRejectedReviews *bool `json:"block_on_rejected_reviews"`
|
||||
BlockOnOutdatedBranch *bool `json:"block_on_outdated_branch"`
|
||||
DismissStaleApprovals *bool `json:"dismiss_stale_approvals"`
|
||||
RequireSignedCommits *bool `json:"require_signed_commits"`
|
||||
ProtectedFilePatterns *string `json:"protected_file_patterns"`
|
||||
EnablePush *bool `json:"enable_push"`
|
||||
EnablePushWhitelist *bool `json:"enable_push_whitelist"`
|
||||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist *bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
EnableStatusCheck *bool `json:"enable_status_check"`
|
||||
StatusCheckContexts []string `json:"status_check_contexts"`
|
||||
RequiredApprovals *int64 `json:"required_approvals"`
|
||||
EnableApprovalsWhitelist *bool `json:"enable_approvals_whitelist"`
|
||||
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
|
||||
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
|
||||
BlockOnRejectedReviews *bool `json:"block_on_rejected_reviews"`
|
||||
BlockOnOfficialReviewRequests *bool `json:"block_on_official_review_requests"`
|
||||
BlockOnOutdatedBranch *bool `json:"block_on_outdated_branch"`
|
||||
DismissStaleApprovals *bool `json:"dismiss_stale_approvals"`
|
||||
RequireSignedCommits *bool `json:"require_signed_commits"`
|
||||
ProtectedFilePatterns *string `json:"protected_file_patterns"`
|
||||
}
|
||||
|
||||
// ListBranchProtectionsOptions list branch protection options
|
||||
@@ -92,6 +95,9 @@ type ListBranchProtectionsOptions struct {
|
||||
|
||||
// ListBranchProtections list branch protections for a repo
|
||||
func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtectionsOptions) ([]*BranchProtection, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -104,6 +110,9 @@ func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtect
|
||||
|
||||
// GetBranchProtection gets a branch protection
|
||||
func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtection, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -114,6 +123,9 @@ func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtectio
|
||||
|
||||
// CreateBranchProtection creates a branch protection for a repo
|
||||
func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProtectionOption) (*BranchProtection, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -128,6 +140,9 @@ func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProt
|
||||
|
||||
// EditBranchProtection edits a branch protection for a repo
|
||||
func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchProtectionOption) (*BranchProtection, *Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -142,6 +157,9 @@ func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchPr
|
||||
|
||||
// DeleteBranchProtection deletes a branch protection for a repo
|
||||
func (c *Client) DeleteBranchProtection(owner, repo, name string) (*Response, error) {
|
||||
if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user