Merge branch 'main' into prometheus-reorganization
@ -91,6 +91,7 @@ module.exports = {
|
|||||||
plugins: ['@vitest/eslint-plugin'],
|
plugins: ['@vitest/eslint-plugin'],
|
||||||
globals: vitestPlugin.environments.env.globals,
|
globals: vitestPlugin.environments.env.globals,
|
||||||
rules: {
|
rules: {
|
||||||
|
'github/unescaped-html-literal': [0],
|
||||||
'@vitest/consistent-test-filename': [0],
|
'@vitest/consistent-test-filename': [0],
|
||||||
'@vitest/consistent-test-it': [0],
|
'@vitest/consistent-test-it': [0],
|
||||||
'@vitest/expect-expect': [0],
|
'@vitest/expect-expect': [0],
|
||||||
@ -423,7 +424,7 @@ module.exports = {
|
|||||||
'github/no-useless-passive': [2],
|
'github/no-useless-passive': [2],
|
||||||
'github/prefer-observers': [2],
|
'github/prefer-observers': [2],
|
||||||
'github/require-passive-events': [2],
|
'github/require-passive-events': [2],
|
||||||
'github/unescaped-html-literal': [0],
|
'github/unescaped-html-literal': [2],
|
||||||
'grouped-accessor-pairs': [2],
|
'grouped-accessor-pairs': [2],
|
||||||
'guard-for-in': [0],
|
'guard-for-in': [0],
|
||||||
'id-blacklist': [0],
|
'id-blacklist': [0],
|
||||||
|
@ -50,6 +50,8 @@ linters:
|
|||||||
require-explanation: true
|
require-explanation: true
|
||||||
require-specific: true
|
require-specific: true
|
||||||
gocritic:
|
gocritic:
|
||||||
|
enabled-checks:
|
||||||
|
- equalFold
|
||||||
disabled-checks:
|
disabled-checks:
|
||||||
- ifElseChain
|
- ifElseChain
|
||||||
- singleCaseSwitch # Every time this occurred in the code, there was no other way.
|
- singleCaseSwitch # Every time this occurred in the code, there was no other way.
|
||||||
|
@ -30,7 +30,7 @@ These are the values to which people in the Gitea community should aspire.
|
|||||||
- **Be constructive.**
|
- **Be constructive.**
|
||||||
- Avoid derailing: stay on topic; if you want to talk about something else, start a new conversation.
|
- Avoid derailing: stay on topic; if you want to talk about something else, start a new conversation.
|
||||||
- Avoid unconstructive criticism: don't merely decry the current state of affairs; offer—or at least solicit—suggestions as to how things may be improved.
|
- Avoid unconstructive criticism: don't merely decry the current state of affairs; offer—or at least solicit—suggestions as to how things may be improved.
|
||||||
- Avoid snarking (pithy, unproductive, sniping comments)
|
- Avoid snarking (pithy, unproductive, sniping comments).
|
||||||
- Avoid discussing potentially offensive or sensitive issues; this all too often leads to unnecessary conflict.
|
- Avoid discussing potentially offensive or sensitive issues; this all too often leads to unnecessary conflict.
|
||||||
- Avoid microaggressions (brief and commonplace verbal, behavioral and environmental indignities that communicate hostile, derogatory or negative slights and insults to a person or group).
|
- Avoid microaggressions (brief and commonplace verbal, behavioral and environmental indignities that communicate hostile, derogatory or negative slights and insults to a person or group).
|
||||||
- **Be responsible.**
|
- **Be responsible.**
|
||||||
@ -42,7 +42,7 @@ People are complicated. You should expect to be misunderstood and to misundersta
|
|||||||
|
|
||||||
### Our Pledge
|
### Our Pledge
|
||||||
|
|
||||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
### Our Standards
|
### Our Standards
|
||||||
|
|
||||||
|
@ -80,9 +80,9 @@ Expected workflow is: Fork -> Patch -> Push -> Pull Request
|
|||||||
|
|
||||||
[](https://translate.gitea.com)
|
[](https://translate.gitea.com)
|
||||||
|
|
||||||
Translations are done through [Crowdin](https://translate.gitea.com). If you want to translate to a new language ask one of the managers in the Crowdin project to add a new language there.
|
Translations are done through [Crowdin](https://translate.gitea.com). If you want to translate to a new language, ask one of the managers in the Crowdin project to add a new language there.
|
||||||
|
|
||||||
You can also just create an issue for adding a language or ask on discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty but we hope to fill it as questions pop up.
|
You can also just create an issue for adding a language or ask on Discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty, but we hope to fill it as questions pop up.
|
||||||
|
|
||||||
Get more information from [documentation](https://docs.gitea.com/contributing/localization).
|
Get more information from [documentation](https://docs.gitea.com/contributing/localization).
|
||||||
|
|
||||||
|
54
SECURITY.md
@ -14,12 +14,12 @@ Please **DO NOT** file a public issue, instead send your report privately to `se
|
|||||||
|
|
||||||
Due to the sensitive nature of security information, you can use the below GPG public key to encrypt your mail body.
|
Due to the sensitive nature of security information, you can use the below GPG public key to encrypt your mail body.
|
||||||
|
|
||||||
The PGP key is valid until July 9, 2025.
|
The PGP key is valid until July 4, 2026.
|
||||||
|
|
||||||
```
|
```
|
||||||
Key ID: 6FCD2D5B
|
Key ID: 6FCD2D5B
|
||||||
Key Type: RSA
|
Key Type: RSA
|
||||||
Expires: 7/9/2025
|
Expires: 7/4/2026
|
||||||
Key Size: 4096/4096
|
Key Size: 4096/4096
|
||||||
Fingerprint: 3DE0 3D1E 144A 7F06 9359 99DC AAFD 2381 6FCD 2D5B
|
Fingerprint: 3DE0 3D1E 144A 7F06 9359 99DC AAFD 2381 6FCD 2D5B
|
||||||
```
|
```
|
||||||
@ -42,18 +42,18 @@ lzpAjnN9/KLtQroutrm+Ft0mdjDiJUeFVl1cOHDhoyfCsQh62HumoyZoZvqzQd6e
|
|||||||
AbN11nq6aViMe2Q3je1AbiBnRnQSHxt1Tc8X4IshO3MQK1Sk7oPI6LA5oQARAQAB
|
AbN11nq6aViMe2Q3je1AbiBnRnQSHxt1Tc8X4IshO3MQK1Sk7oPI6LA5oQARAQAB
|
||||||
tCJHaXRlYSBTZWN1cml0eSA8c2VjdXJpdHlAZ2l0ZWEuaW8+iQJXBBMBCABBAhsD
|
tCJHaXRlYSBTZWN1cml0eSA8c2VjdXJpdHlAZ2l0ZWEuaW8+iQJXBBMBCABBAhsD
|
||||||
BQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAFiEEPeA9HhRKfwaTWZncqv0jgW/N
|
BQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAFiEEPeA9HhRKfwaTWZncqv0jgW/N
|
||||||
LVsFAmaMse0FCQW4fW8ACgkQqv0jgW/NLVtXLg/+PF4G9Jhlui15BTNlEBJAV2P/
|
LVsFAmhoHmkFCQeT6esACgkQqv0jgW/NLVuFLRAAmjBQSKRAgs2bFIEj7HLAbDp4
|
||||||
1QlAV2krk0fP7tykn0FR9RfGIfVV/kwC1f+ouosYPQDDevl9LWdUIM+g94DtNo2o
|
f+XkdH+GsT3jRPOZ9QZgmtM+TfoE4yNgIVfOl+s4RdjM/W4QzqZuPQ55hbEHd056
|
||||||
7ACpcL3morvt5lVGpIZHL8TbX0qmFRXL/pB/cB+K6IwYvh2mrbp2zH+r4SCRyFYq
|
cJmm7B+6GsHFcdrPmh65sOCEIyh4+t45dUfeWpFsDPqm9j1UHXAJQIpB8vDEVAPH
|
||||||
BjgXYFTI1MylJ1ShAjU6Z+m3oJ+2xs5LzHS0X6zkTjzA2Zl4zQzciQ9T+wJcE7Zi
|
t+3wLCk8GMPJs1o5tIyMmaO23ngvkwn8eG7KgY+rp2PzObrb5g7ppci0ILzILkrp
|
||||||
HXdM1+YMF8KGNP8J9Rpug5oNDJ98lgZirRY7c3A/1xmYBiPnULwuuymdqEZO7l70
|
HVjZsEfUWRgSVF7LuU5ppqDKrlcqwUpQq6n3kGMZcLrCp6ACKP04TBmTfUxNwdL7
|
||||||
SeAlE1RWYX8kbOBnBb/KY4XwE3Vic1oEzc9DiPWVH1ElX86WNNsFzuyULiwoBoWg
|
I0N7apI2Pbct9T1Gv/lYAUFWyU2c3gh/EBLbO6BukaLOFRQHrtNfdJV/YnMPlcXr
|
||||||
pqZGhL9x1p5+46RGQSDczsHM7YGVtfYOiDo2PAVrmwsT0BnXnK8Oe3YIkvmUPEJu
|
LUJjK9K4eAH9DsrZqrisz/LthsC2BaNIN3KRMTk5YTYgmIh8GXzSgihORmtDFELC
|
||||||
OkLt0Z6A5n8pz8zhQzuApwBsK4ncJ8zTCpvz/pfKKqZC/Vnoh3gKGhDGvOZ+b5IJ
|
RroID3pTuS0zjXh+wpY9GuPTh7UW23p42Daxca4fAT4k5EclvDRUrL21xMopPMiL
|
||||||
0kUTe2JsbnwFixDUMDtacQ1op8XOyLoLVmgqLn0+Pws4XPBlMof2bioFir3yHKnP
|
HuNdELz4FVchRTy05PjzKVyjVInDNojE2KUxnjxZDzYJ6aT/g+coD5yfntYm8BEj
|
||||||
gNchsF1agrlSIo5GA8u4ga+IlCSfvFIKrl7+cxacKcJYt/vbOU5KcvVJI5EtHKCG
|
+ZzL0ndZES54hzKLpv7zwBQwFzam68clZYmDPILOPTflQDfpGEWmJK4undFU5obz
|
||||||
xfHjHY2ah1Qww7SxW6IXiRZZzPpsL2mBM2CD7N3qh9bV2s27wxYCdUodsIZbiyHe
|
ZsQRz0R3ulspChATbZxO0d5LX2obLpKO9X3b5VoO1KF+R8Vjw1Y0KxrNZ6rIcfqH
|
||||||
oWPzfBnkmiAN8KlZxHm5Ag0EYrVn/gEQALrFLQjCR3GjuHSindz0rd3Fnx/t7Sen
|
Z50QVQKSe9dm08K0ON+5Ag0EYrVn/gEQALrFLQjCR3GjuHSindz0rd3Fnx/t7Sen
|
||||||
T+p07yCSSoSlmnJHCQmwh4vfg1blyz0zZ4vkIhtpHsEgc+ZAG+WQXSsJ2iRz+eSN
|
T+p07yCSSoSlmnJHCQmwh4vfg1blyz0zZ4vkIhtpHsEgc+ZAG+WQXSsJ2iRz+eSN
|
||||||
GwoOQl4XC3n+QWkc1ws+btr48+6UqXIQU+F8TPQyx/PIgi2nZXJB7f5+mjCqsk46
|
GwoOQl4XC3n+QWkc1ws+btr48+6UqXIQU+F8TPQyx/PIgi2nZXJB7f5+mjCqsk46
|
||||||
XvH4nTr4kJjuqMSR/++wvre2qNQRa/q/dTsK0OaN/mJsdX6Oi+aGNaQJUhIG7F+E
|
XvH4nTr4kJjuqMSR/++wvre2qNQRa/q/dTsK0OaN/mJsdX6Oi+aGNaQJUhIG7F+E
|
||||||
@ -65,19 +65,19 @@ s+GsP9I3cmWWQcKYxWHtE8xTXnNCVPFZQj2nwhJzae8ypfOtulBRA3dUKWGKuDH/
|
|||||||
axFENhUsT397aOU3qkP/od4a64JyNIEo4CTTSPVeWd7njsGqli2U3A4xL2CcyYvt
|
axFENhUsT397aOU3qkP/od4a64JyNIEo4CTTSPVeWd7njsGqli2U3A4xL2CcyYvt
|
||||||
D/MWcMBGEoLSNTswwKdom4FaJpn5KThnK/T0bQcmJblJhoCtppXisbexZnCpuS0x
|
D/MWcMBGEoLSNTswwKdom4FaJpn5KThnK/T0bQcmJblJhoCtppXisbexZnCpuS0x
|
||||||
Zdlm2T14KJ3LABEBAAGJAjwEGAEIACYCGwwWIQQ94D0eFEp/BpNZmdyq/SOBb80t
|
Zdlm2T14KJ3LABEBAAGJAjwEGAEIACYCGwwWIQQ94D0eFEp/BpNZmdyq/SOBb80t
|
||||||
WwUCZoyyjQUJBbh+DwAKCRCq/SOBb80tW18XD/9MXztmf01MT+1kZdBouZ/7Rp/7
|
WwUCaGgeJAUJB5PppgAKCRCq/SOBb80tW/NWEACB6Jrf0gWlk7e+hNCdnbM0ZVWU
|
||||||
9kuqo//B1G+RXau4oFtPqb67kNe2WaIc3u5B73PUHsMf3i6z4ib2KbMhZZerLn0O
|
f2sHNFfXxxsdhpcDgKbNHtkZb8nZgv8AX+5fTtUwMVa3vKcdw30xFiIM5N7cCIPV
|
||||||
dRglcuPeNWmsASY3dH/XVG0cT0zvvWegagd12TJEl3Vs+7XNrOw4cwDj9L1+GH9m
|
vg/5z5BtfEaitnabEUG2iiVDIy8IHXIcK10rX+7BosA3QDl2PsiBHwyi5G13lRk8
|
||||||
kSt4uaANWn/6a3RvMRhiVEYuNwhAzcKaactPmYqrLJgoVLbRSDkgyHaMQ2jKgLxk
|
zGTSNDuOalug33h5/lr2dPigamkq74Aoy29q8Rjad6GfWHipL2bFimgtY+Zdi0BH
|
||||||
ifS/fvluGV0ub2Po6DJiqfRpd1tDvPhe9y1+r1WFDZsOcvTcZUfSt/7dXMGfqGu0
|
NLk4EJXxj1SgVx5dtkQzWJReBA5M+FQ4QYQZBO+f4TDoOLmjui152uhkoLBQbGAa
|
||||||
2daVFlfeSXSALrDE5uc0UxodHCpP3sqRYDZevGLBRaaTkIjYXG/+N898+7K5WJF4
|
WWJFTVxm0bG5MXloEL3gA8DfU7XDwuW/sHJC5pBko8RpQViooOhckMepZV3Y83DK
|
||||||
xXOLWxM2cwGkG7eC9pugcDnBp9XlF7O+GBiZ05JUe5flXDQFZ+h3exjopu6KHF1B
|
bwLYa3JmPgj2rEv4993dvrJbQhpGd082HOxOsllCs8pgNq1SnXpWYfcGTgGKC3ts
|
||||||
RnzNy8LC0UKb+AuvRIOLV92a9Q9wGWU/jaVDu6nZ0umAeuSzxiHoDsonm0Fl9QAz
|
U8YZUUJUQ7mi2L8Tv3ix20c9EiGmA30JAmA8eZTC3cWup91ZkkVBFRml2czTXajd
|
||||||
2/xCokebuoeLrEK7R2af3X86mqq3sVO4ax+HPYChzOaVQBiHUW/TAldWcldYYphR
|
RWZ6GbHV5503ueDQcB8yBVgF3CSixs67+dGSbD3p86OqGrjAcJzM5TFbNKcnGLdE
|
||||||
/e2WsbmQfvCRtz/bZfo+aUVnrHNjzVMtF2SszdVmA/04Y8pS28MqtuRqhm5DPOOd
|
kGbZpNwAISy750lXzXKmyrh5RTCeTOQerbwCMBvHZO+HAevA/LXDTw2OAiSIQlP5
|
||||||
g1YeUywK5jRZ1twyo1kzJEFPLaoeaXaycsR1PMVBW0Urik5mrR/pOWq7PPoZoKb2
|
sYA4sFYLQ30OAkgJcmdp/pSgVj/erNtSN07ClrOpDb/uFpQymO6K2h0Pst3feNVK
|
||||||
lXYLE8bwkuQTmsyL1g==
|
9M2VbqL9C51z/wyHLg==
|
||||||
=9i7d
|
=SfZA
|
||||||
-----END PGP PUBLIC KEY BLOCK-----
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -715,7 +715,8 @@ func (c *Comment) LoadReactions(ctx context.Context, repo *repo_model.Repository
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Comment) loadReview(ctx context.Context) (err error) {
|
// LoadReview loads the associated review
|
||||||
|
func (c *Comment) LoadReview(ctx context.Context) (err error) {
|
||||||
if c.ReviewID == 0 {
|
if c.ReviewID == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -732,11 +733,6 @@ func (c *Comment) loadReview(ctx context.Context) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadReview loads the associated review
|
|
||||||
func (c *Comment) LoadReview(ctx context.Context) error {
|
|
||||||
return c.loadReview(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DiffSide returns "previous" if Comment.Line is a LOC of the previous changes and "proposed" if it is a LOC of the proposed changes.
|
// DiffSide returns "previous" if Comment.Line is a LOC of the previous changes and "proposed" if it is a LOC of the proposed changes.
|
||||||
func (c *Comment) DiffSide() string {
|
func (c *Comment) DiffSide() string {
|
||||||
if c.Line < 0 {
|
if c.Line < 0 {
|
||||||
@ -856,7 +852,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
|
|||||||
}
|
}
|
||||||
if comment.ReviewID != 0 {
|
if comment.ReviewID != 0 {
|
||||||
if comment.Review == nil {
|
if comment.Review == nil {
|
||||||
if err := comment.loadReview(ctx); err != nil {
|
if err := comment.LoadReview(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,14 @@ type PackageVersion struct {
|
|||||||
DownloadCount int64 `xorm:"NOT NULL DEFAULT 0"`
|
DownloadCount int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsPrerelease checks if the version is a prerelease version according to semantic versioning
|
||||||
|
func (pv *PackageVersion) IsPrerelease() bool {
|
||||||
|
if pv == nil || pv.Version == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return strings.Contains(pv.Version, "-")
|
||||||
|
}
|
||||||
|
|
||||||
// GetOrInsertVersion inserts a version. If the same version exist already ErrDuplicatePackageVersion is returned
|
// GetOrInsertVersion inserts a version. If the same version exist already ErrDuplicatePackageVersion is returned
|
||||||
func GetOrInsertVersion(ctx context.Context, pv *PackageVersion) (*PackageVersion, error) {
|
func GetOrInsertVersion(ctx context.Context, pv *PackageVersion) (*PackageVersion, error) {
|
||||||
e := db.GetEngine(ctx)
|
e := db.GetEngine(ctx)
|
||||||
|
@ -157,18 +157,17 @@ func UpdateLanguageStats(ctx context.Context, repo *Repository, commitID string,
|
|||||||
for lang, size := range stats {
|
for lang, size := range stats {
|
||||||
if size > s {
|
if size > s {
|
||||||
s = size
|
s = size
|
||||||
topLang = strings.ToLower(lang)
|
topLang = lang
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for lang, size := range stats {
|
for lang, size := range stats {
|
||||||
upd := false
|
upd := false
|
||||||
llang := strings.ToLower(lang)
|
|
||||||
for _, s := range oldstats {
|
for _, s := range oldstats {
|
||||||
// Update already existing language
|
// Update already existing language
|
||||||
if strings.ToLower(s.Language) == llang {
|
if strings.EqualFold(s.Language, lang) {
|
||||||
s.CommitID = commitID
|
s.CommitID = commitID
|
||||||
s.IsPrimary = llang == topLang
|
s.IsPrimary = lang == topLang
|
||||||
s.Size = size
|
s.Size = size
|
||||||
if _, err := sess.ID(s.ID).Cols("`commit_id`", "`size`", "`is_primary`").Update(s); err != nil {
|
if _, err := sess.ID(s.ID).Cols("`commit_id`", "`size`", "`is_primary`").Update(s); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -182,7 +181,7 @@ func UpdateLanguageStats(ctx context.Context, repo *Repository, commitID string,
|
|||||||
if err := db.Insert(ctx, &LanguageStat{
|
if err := db.Insert(ctx, &LanguageStat{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
CommitID: commitID,
|
CommitID: commitID,
|
||||||
IsPrimary: llang == topLang,
|
IsPrimary: lang == topLang,
|
||||||
Language: lang,
|
Language: lang,
|
||||||
Size: size,
|
Size: size,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
47
modules/auth/httpauth/httpauth.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package httpauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BasicAuth struct {
|
||||||
|
Username, Password string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BearerToken struct {
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParsedAuthorizationHeader struct {
|
||||||
|
BasicAuth *BasicAuth
|
||||||
|
BearerToken *BearerToken
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseAuthorizationHeader(header string) (ret ParsedAuthorizationHeader, _ bool) {
|
||||||
|
parts := strings.Fields(header)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return ret, false
|
||||||
|
}
|
||||||
|
if util.AsciiEqualFold(parts[0], "basic") {
|
||||||
|
s, err := base64.StdEncoding.DecodeString(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return ret, false
|
||||||
|
}
|
||||||
|
u, p, ok := strings.Cut(string(s), ":")
|
||||||
|
if !ok {
|
||||||
|
return ret, false
|
||||||
|
}
|
||||||
|
ret.BasicAuth = &BasicAuth{Username: u, Password: p}
|
||||||
|
return ret, true
|
||||||
|
} else if util.AsciiEqualFold(parts[0], "token") || util.AsciiEqualFold(parts[0], "bearer") {
|
||||||
|
ret.BearerToken = &BearerToken{Token: parts[1]}
|
||||||
|
return ret, true
|
||||||
|
}
|
||||||
|
return ret, false
|
||||||
|
}
|
43
modules/auth/httpauth/httpauth_test.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package httpauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseAuthorizationHeader(t *testing.T) {
|
||||||
|
type parsed = ParsedAuthorizationHeader
|
||||||
|
type basic = BasicAuth
|
||||||
|
type bearer = BearerToken
|
||||||
|
cases := []struct {
|
||||||
|
headerValue string
|
||||||
|
expected parsed
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{"", parsed{}, false},
|
||||||
|
{"?", parsed{}, false},
|
||||||
|
{"foo", parsed{}, false},
|
||||||
|
{"any value", parsed{}, false},
|
||||||
|
|
||||||
|
{"Basic ?", parsed{}, false},
|
||||||
|
{"Basic " + base64.StdEncoding.EncodeToString([]byte("foo")), parsed{}, false},
|
||||||
|
{"Basic " + base64.StdEncoding.EncodeToString([]byte("foo:bar")), parsed{BasicAuth: &basic{"foo", "bar"}}, true},
|
||||||
|
{"basic " + base64.StdEncoding.EncodeToString([]byte("foo:bar")), parsed{BasicAuth: &basic{"foo", "bar"}}, true},
|
||||||
|
|
||||||
|
{"token value", parsed{BearerToken: &bearer{"value"}}, true},
|
||||||
|
{"Token value", parsed{BearerToken: &bearer{"value"}}, true},
|
||||||
|
{"bearer value", parsed{BearerToken: &bearer{"value"}}, true},
|
||||||
|
{"Bearer value", parsed{BearerToken: &bearer{"value"}}, true},
|
||||||
|
{"Bearer wrong value", parsed{}, false},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
ret, ok := ParseAuthorizationHeader(c.headerValue)
|
||||||
|
assert.Equal(t, c.ok, ok, "header %q", c.headerValue)
|
||||||
|
assert.Equal(t, c.expected, ret, "header %q", c.headerValue)
|
||||||
|
}
|
||||||
|
}
|
@ -8,13 +8,10 @@ import (
|
|||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"encoding/base64"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
@ -36,19 +33,6 @@ func ShortSha(sha1 string) string {
|
|||||||
return util.TruncateRunes(sha1, 10)
|
return util.TruncateRunes(sha1, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasicAuthDecode decode basic auth string
|
|
||||||
func BasicAuthDecode(encoded string) (string, string, error) {
|
|
||||||
s, err := base64.StdEncoding.DecodeString(encoded)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if username, password, ok := strings.Cut(string(s), ":"); ok {
|
|
||||||
return username, password, nil
|
|
||||||
}
|
|
||||||
return "", "", errors.New("invalid basic authentication")
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyTimeLimitCode verify time limit code
|
// VerifyTimeLimitCode verify time limit code
|
||||||
func VerifyTimeLimitCode(now time.Time, data string, minutes int, code string) bool {
|
func VerifyTimeLimitCode(now time.Time, data string, minutes int, code string) bool {
|
||||||
if len(code) <= 18 {
|
if len(code) <= 18 {
|
||||||
|
@ -26,25 +26,6 @@ func TestShortSha(t *testing.T) {
|
|||||||
assert.Equal(t, "veryverylo", ShortSha("veryverylong"))
|
assert.Equal(t, "veryverylo", ShortSha("veryverylong"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasicAuthDecode(t *testing.T) {
|
|
||||||
_, _, err := BasicAuthDecode("?")
|
|
||||||
assert.Equal(t, "illegal base64 data at input byte 0", err.Error())
|
|
||||||
|
|
||||||
user, pass, err := BasicAuthDecode("Zm9vOmJhcg==")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, "foo", user)
|
|
||||||
assert.Equal(t, "bar", pass)
|
|
||||||
|
|
||||||
_, _, err = BasicAuthDecode("aW52YWxpZA==")
|
|
||||||
assert.Error(t, err)
|
|
||||||
|
|
||||||
_, _, err = BasicAuthDecode("invalid")
|
|
||||||
assert.Error(t, err)
|
|
||||||
|
|
||||||
_, _, err = BasicAuthDecode("YWxpY2U=") // "alice", no colon
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVerifyTimeLimitCode(t *testing.T) {
|
func TestVerifyTimeLimitCode(t *testing.T) {
|
||||||
defer test.MockVariableValue(&setting.InstallLock, true)()
|
defer test.MockVariableValue(&setting.InstallLock, true)()
|
||||||
initGeneralSecret := func(secret string) {
|
initGeneralSecret := func(secret string) {
|
||||||
|
@ -6,17 +6,17 @@ package fileicon
|
|||||||
import "code.gitea.io/gitea/modules/git"
|
import "code.gitea.io/gitea/modules/git"
|
||||||
|
|
||||||
type EntryInfo struct {
|
type EntryInfo struct {
|
||||||
FullName string
|
BaseName string
|
||||||
EntryMode git.EntryMode
|
EntryMode git.EntryMode
|
||||||
SymlinkToMode git.EntryMode
|
SymlinkToMode git.EntryMode
|
||||||
IsOpen bool
|
IsOpen bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func EntryInfoFromGitTreeEntry(gitEntry *git.TreeEntry) *EntryInfo {
|
func EntryInfoFromGitTreeEntry(commit *git.Commit, fullPath string, gitEntry *git.TreeEntry) *EntryInfo {
|
||||||
ret := &EntryInfo{FullName: gitEntry.Name(), EntryMode: gitEntry.Mode()}
|
ret := &EntryInfo{BaseName: gitEntry.Name(), EntryMode: gitEntry.Mode()}
|
||||||
if gitEntry.IsLink() {
|
if gitEntry.IsLink() {
|
||||||
if te, err := gitEntry.FollowLink(); err == nil && te.IsDir() {
|
if res, err := git.EntryFollowLink(commit, fullPath, gitEntry); err == nil && res.TargetEntry.IsDir() {
|
||||||
ret.SymlinkToMode = te.Mode()
|
ret.SymlinkToMode = res.TargetEntry.Mode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
@ -5,7 +5,6 @@ package fileicon
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"path"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -134,7 +133,7 @@ func (m *MaterialIconProvider) FindIconName(entry *EntryInfo) string {
|
|||||||
return "folder-git"
|
return "folder-git"
|
||||||
}
|
}
|
||||||
|
|
||||||
fileNameLower := strings.ToLower(path.Base(entry.FullName))
|
fileNameLower := strings.ToLower(entry.BaseName)
|
||||||
if entry.EntryMode.IsDir() {
|
if entry.EntryMode.IsDir() {
|
||||||
if s, ok := m.rules.FolderNames[fileNameLower]; ok {
|
if s, ok := m.rules.FolderNames[fileNameLower]; ok {
|
||||||
return s
|
return s
|
||||||
|
@ -20,8 +20,8 @@ func TestMain(m *testing.M) {
|
|||||||
func TestFindIconName(t *testing.T) {
|
func TestFindIconName(t *testing.T) {
|
||||||
unittest.PrepareTestEnv(t)
|
unittest.PrepareTestEnv(t)
|
||||||
p := fileicon.DefaultMaterialIconProvider()
|
p := fileicon.DefaultMaterialIconProvider()
|
||||||
assert.Equal(t, "php", p.FindIconName(&fileicon.EntryInfo{FullName: "foo.php", EntryMode: git.EntryModeBlob}))
|
assert.Equal(t, "php", p.FindIconName(&fileicon.EntryInfo{BaseName: "foo.php", EntryMode: git.EntryModeBlob}))
|
||||||
assert.Equal(t, "php", p.FindIconName(&fileicon.EntryInfo{FullName: "foo.PHP", EntryMode: git.EntryModeBlob}))
|
assert.Equal(t, "php", p.FindIconName(&fileicon.EntryInfo{BaseName: "foo.PHP", EntryMode: git.EntryModeBlob}))
|
||||||
assert.Equal(t, "javascript", p.FindIconName(&fileicon.EntryInfo{FullName: "foo.js", EntryMode: git.EntryModeBlob}))
|
assert.Equal(t, "javascript", p.FindIconName(&fileicon.EntryInfo{BaseName: "foo.js", EntryMode: git.EntryModeBlob}))
|
||||||
assert.Equal(t, "visualstudio", p.FindIconName(&fileicon.EntryInfo{FullName: "foo.vba", EntryMode: git.EntryModeBlob}))
|
assert.Equal(t, "visualstudio", p.FindIconName(&fileicon.EntryInfo{BaseName: "foo.vba", EntryMode: git.EntryModeBlob}))
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,8 @@ import (
|
|||||||
|
|
||||||
// Commit represents a git commit.
|
// Commit represents a git commit.
|
||||||
type Commit struct {
|
type Commit struct {
|
||||||
Tree
|
Tree // FIXME: bad design, this field can be nil if the commit is from "last commit cache"
|
||||||
|
|
||||||
ID ObjectID // The ID of this commit object
|
ID ObjectID // The ID of this commit object
|
||||||
Author *Signature
|
Author *Signature
|
||||||
Committer *Signature
|
Committer *Signature
|
||||||
|
@ -32,22 +32,6 @@ func (err ErrNotExist) Unwrap() error {
|
|||||||
return util.ErrNotExist
|
return util.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrSymlinkUnresolved entry.FollowLink error
|
|
||||||
type ErrSymlinkUnresolved struct {
|
|
||||||
Name string
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err ErrSymlinkUnresolved) Error() string {
|
|
||||||
return fmt.Sprintf("%s: %s", err.Name, err.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrSymlinkUnresolved if some error is ErrSymlinkUnresolved
|
|
||||||
func IsErrSymlinkUnresolved(err error) bool {
|
|
||||||
_, ok := err.(ErrSymlinkUnresolved)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrBranchNotExist represents a "BranchNotExist" kind of error.
|
// ErrBranchNotExist represents a "BranchNotExist" kind of error.
|
||||||
type ErrBranchNotExist struct {
|
type ErrBranchNotExist struct {
|
||||||
Name string
|
Name string
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GetTreeEntryByPath get the tree entries according the sub dir
|
// GetTreeEntryByPath get the tree entries according the sub dir
|
||||||
func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
|
func (t *Tree) GetTreeEntryByPath(relpath string) (_ *TreeEntry, err error) {
|
||||||
if len(relpath) == 0 {
|
if len(relpath) == 0 {
|
||||||
return &TreeEntry{
|
return &TreeEntry{
|
||||||
ptree: t,
|
ptree: t,
|
||||||
@ -21,27 +21,25 @@ func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This should probably use git cat-file --batch to be a bit more efficient
|
|
||||||
relpath = path.Clean(relpath)
|
relpath = path.Clean(relpath)
|
||||||
parts := strings.Split(relpath, "/")
|
parts := strings.Split(relpath, "/")
|
||||||
var err error
|
|
||||||
tree := t
|
tree := t
|
||||||
for i, name := range parts {
|
for _, name := range parts[:len(parts)-1] {
|
||||||
if i == len(parts)-1 {
|
tree, err = tree.SubTree(name)
|
||||||
entries, err := tree.ListEntries()
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
}
|
||||||
}
|
}
|
||||||
for _, v := range entries {
|
|
||||||
if v.Name() == name {
|
name := parts[len(parts)-1]
|
||||||
return v, nil
|
entries, err := tree.ListEntries()
|
||||||
}
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
} else {
|
}
|
||||||
tree, err = tree.SubTree(name)
|
for _, v := range entries {
|
||||||
if err != nil {
|
if v.Name() == name {
|
||||||
return nil, err
|
return v, nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ErrNotExist{"", relpath}
|
return nil, ErrNotExist{"", relpath}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -24,77 +24,57 @@ func (te *TreeEntry) Type() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FollowLink returns the entry pointed to by a symlink
|
type EntryFollowResult struct {
|
||||||
func (te *TreeEntry) FollowLink() (*TreeEntry, error) {
|
SymlinkContent string
|
||||||
if !te.IsLink() {
|
TargetFullPath string
|
||||||
return nil, ErrSymlinkUnresolved{te.Name(), "not a symlink"}
|
TargetEntry *TreeEntry
|
||||||
}
|
|
||||||
|
|
||||||
// read the link
|
|
||||||
r, err := te.Blob().DataAsync()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
closed := false
|
|
||||||
defer func() {
|
|
||||||
if !closed {
|
|
||||||
_ = r.Close()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
buf := make([]byte, te.Size())
|
|
||||||
_, err = io.ReadFull(r, buf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
_ = r.Close()
|
|
||||||
closed = true
|
|
||||||
|
|
||||||
lnk := string(buf)
|
|
||||||
t := te.ptree
|
|
||||||
|
|
||||||
// traverse up directories
|
|
||||||
for ; t != nil && strings.HasPrefix(lnk, "../"); lnk = lnk[3:] {
|
|
||||||
t = t.ptree
|
|
||||||
}
|
|
||||||
|
|
||||||
if t == nil {
|
|
||||||
return nil, ErrSymlinkUnresolved{te.Name(), "points outside of repo"}
|
|
||||||
}
|
|
||||||
|
|
||||||
target, err := t.GetTreeEntryByPath(lnk)
|
|
||||||
if err != nil {
|
|
||||||
if IsErrNotExist(err) {
|
|
||||||
return nil, ErrSymlinkUnresolved{te.Name(), "broken link"}
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return target, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FollowLinks returns the entry ultimately pointed to by a symlink
|
func EntryFollowLink(commit *Commit, fullPath string, te *TreeEntry) (*EntryFollowResult, error) {
|
||||||
func (te *TreeEntry) FollowLinks(optLimit ...int) (*TreeEntry, error) {
|
|
||||||
if !te.IsLink() {
|
if !te.IsLink() {
|
||||||
return nil, ErrSymlinkUnresolved{te.Name(), "not a symlink"}
|
return nil, util.ErrorWrap(util.ErrUnprocessableContent, "%q is not a symlink", fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// git's filename max length is 4096, hopefully a link won't be longer than multiple of that
|
||||||
|
const maxSymlinkSize = 20 * 4096
|
||||||
|
if te.Blob().Size() > maxSymlinkSize {
|
||||||
|
return nil, util.ErrorWrap(util.ErrUnprocessableContent, "%q content exceeds symlink limit", fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
link, err := te.Blob().GetBlobContent(maxSymlinkSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(link, "/") {
|
||||||
|
// It's said that absolute path will be stored as is in Git
|
||||||
|
return &EntryFollowResult{SymlinkContent: link}, util.ErrorWrap(util.ErrUnprocessableContent, "%q is an absolute symlink", fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
targetFullPath := path.Join(path.Dir(fullPath), link)
|
||||||
|
targetEntry, err := commit.GetTreeEntryByPath(targetFullPath)
|
||||||
|
if err != nil {
|
||||||
|
return &EntryFollowResult{SymlinkContent: link}, err
|
||||||
|
}
|
||||||
|
return &EntryFollowResult{SymlinkContent: link, TargetFullPath: targetFullPath, TargetEntry: targetEntry}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EntryFollowLinks(commit *Commit, firstFullPath string, firstTreeEntry *TreeEntry, optLimit ...int) (res *EntryFollowResult, err error) {
|
||||||
limit := util.OptionalArg(optLimit, 10)
|
limit := util.OptionalArg(optLimit, 10)
|
||||||
entry := te
|
treeEntry, fullPath := firstTreeEntry, firstFullPath
|
||||||
for range limit {
|
for range limit {
|
||||||
if !entry.IsLink() {
|
res, err = EntryFollowLink(commit, fullPath, treeEntry)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
treeEntry, fullPath = res.TargetEntry, res.TargetFullPath
|
||||||
|
if !treeEntry.IsLink() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
next, err := entry.FollowLink()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if next.ID == entry.ID {
|
|
||||||
return nil, ErrSymlinkUnresolved{entry.Name(), "recursive link"}
|
|
||||||
}
|
|
||||||
entry = next
|
|
||||||
}
|
}
|
||||||
if entry.IsLink() {
|
if treeEntry.IsLink() {
|
||||||
return nil, ErrSymlinkUnresolved{te.Name(), "too many levels of symbolic links"}
|
return res, util.ErrorWrap(util.ErrUnprocessableContent, "%q has too many links", firstFullPath)
|
||||||
}
|
}
|
||||||
return entry, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the Tree pointed to by this TreeEntry, or nil if this is not a tree
|
// returns the Tree pointed to by this TreeEntry, or nil if this is not a tree
|
||||||
|
76
modules/git/tree_entry_common_test.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFollowLink(t *testing.T) {
|
||||||
|
r, err := openRepositoryWithDefaultContext("tests/repos/repo1_bare")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
commit, err := r.GetCommit("37991dec2c8e592043f47155ce4808d4580f9123")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// get the symlink
|
||||||
|
{
|
||||||
|
lnkFullPath := "foo/bar/link_to_hello"
|
||||||
|
lnk, err := commit.Tree.GetTreeEntryByPath("foo/bar/link_to_hello")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, lnk.IsLink())
|
||||||
|
|
||||||
|
// should be able to dereference to target
|
||||||
|
res, err := EntryFollowLink(commit, lnkFullPath, lnk)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "hello", res.TargetEntry.Name())
|
||||||
|
assert.Equal(t, "foo/nar/hello", res.TargetFullPath)
|
||||||
|
assert.False(t, res.TargetEntry.IsLink())
|
||||||
|
assert.Equal(t, "b14df6442ea5a1b382985a6549b85d435376c351", res.TargetEntry.ID.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// should error when called on a normal file
|
||||||
|
entry, err := commit.Tree.GetTreeEntryByPath("file1.txt")
|
||||||
|
require.NoError(t, err)
|
||||||
|
res, err := EntryFollowLink(commit, "file1.txt", entry)
|
||||||
|
assert.ErrorIs(t, err, util.ErrUnprocessableContent)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// should error for broken links
|
||||||
|
entry, err := commit.Tree.GetTreeEntryByPath("foo/broken_link")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, entry.IsLink())
|
||||||
|
res, err := EntryFollowLink(commit, "foo/broken_link", entry)
|
||||||
|
assert.ErrorIs(t, err, util.ErrNotExist)
|
||||||
|
assert.Equal(t, "nar/broken_link", res.SymlinkContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// should error for external links
|
||||||
|
entry, err := commit.Tree.GetTreeEntryByPath("foo/outside_repo")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, entry.IsLink())
|
||||||
|
res, err := EntryFollowLink(commit, "foo/outside_repo", entry)
|
||||||
|
assert.ErrorIs(t, err, util.ErrNotExist)
|
||||||
|
assert.Equal(t, "../../outside_repo", res.SymlinkContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// testing fix for short link bug
|
||||||
|
entry, err := commit.Tree.GetTreeEntryByPath("foo/link_short")
|
||||||
|
require.NoError(t, err)
|
||||||
|
res, err := EntryFollowLink(commit, "foo/link_short", entry)
|
||||||
|
assert.ErrorIs(t, err, util.ErrNotExist)
|
||||||
|
assert.Equal(t, "a", res.SymlinkContent)
|
||||||
|
}
|
||||||
|
}
|
@ -19,16 +19,12 @@ type TreeEntry struct {
|
|||||||
gogitTreeEntry *object.TreeEntry
|
gogitTreeEntry *object.TreeEntry
|
||||||
ptree *Tree
|
ptree *Tree
|
||||||
|
|
||||||
size int64
|
size int64
|
||||||
sized bool
|
sized bool
|
||||||
fullName string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name returns the name of the entry
|
// Name returns the name of the entry
|
||||||
func (te *TreeEntry) Name() string {
|
func (te *TreeEntry) Name() string {
|
||||||
if te.fullName != "" {
|
|
||||||
return te.fullName
|
|
||||||
}
|
|
||||||
return te.gogitTreeEntry.Name
|
return te.gogitTreeEntry.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +51,7 @@ func (te *TreeEntry) Size() int64 {
|
|||||||
return te.size
|
return te.size
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSubModule if the entry is a sub module
|
// IsSubModule if the entry is a submodule
|
||||||
func (te *TreeEntry) IsSubModule() bool {
|
func (te *TreeEntry) IsSubModule() bool {
|
||||||
return te.gogitTreeEntry.Mode == filemode.Submodule
|
return te.gogitTreeEntry.Mode == filemode.Submodule
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ type EntryMode int
|
|||||||
// one of these.
|
// one of these.
|
||||||
const (
|
const (
|
||||||
// EntryModeNoEntry is possible if the file was added or removed in a commit. In the case of
|
// EntryModeNoEntry is possible if the file was added or removed in a commit. In the case of
|
||||||
// added the base commit will not have the file in its tree so a mode of 0o000000 is used.
|
// when adding the base commit doesn't have the file in its tree, a mode of 0o000000 is used.
|
||||||
EntryModeNoEntry EntryMode = 0o000000
|
EntryModeNoEntry EntryMode = 0o000000
|
||||||
|
|
||||||
EntryModeBlob EntryMode = 0o100644
|
EntryModeBlob EntryMode = 0o100644
|
||||||
@ -30,7 +30,7 @@ func (e EntryMode) String() string {
|
|||||||
return strconv.FormatInt(int64(e), 8)
|
return strconv.FormatInt(int64(e), 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSubModule if the entry is a sub module
|
// IsSubModule if the entry is a submodule
|
||||||
func (e EntryMode) IsSubModule() bool {
|
func (e EntryMode) IsSubModule() bool {
|
||||||
return e == EntryModeCommit
|
return e == EntryModeCommit
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ func (te *TreeEntry) Size() int64 {
|
|||||||
return te.size
|
return te.size
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSubModule if the entry is a sub module
|
// IsSubModule if the entry is a submodule
|
||||||
func (te *TreeEntry) IsSubModule() bool {
|
func (te *TreeEntry) IsSubModule() bool {
|
||||||
return te.entryMode.IsSubModule()
|
return te.entryMode.IsSubModule()
|
||||||
}
|
}
|
||||||
|
@ -53,50 +53,3 @@ func TestEntriesCustomSort(t *testing.T) {
|
|||||||
assert.Equal(t, "bcd", entries[6].Name())
|
assert.Equal(t, "bcd", entries[6].Name())
|
||||||
assert.Equal(t, "abc", entries[7].Name())
|
assert.Equal(t, "abc", entries[7].Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFollowLink(t *testing.T) {
|
|
||||||
r, err := openRepositoryWithDefaultContext("tests/repos/repo1_bare")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
commit, err := r.GetCommit("37991dec2c8e592043f47155ce4808d4580f9123")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// get the symlink
|
|
||||||
lnk, err := commit.Tree.GetTreeEntryByPath("foo/bar/link_to_hello")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, lnk.IsLink())
|
|
||||||
|
|
||||||
// should be able to dereference to target
|
|
||||||
target, err := lnk.FollowLink()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, "hello", target.Name())
|
|
||||||
assert.False(t, target.IsLink())
|
|
||||||
assert.Equal(t, "b14df6442ea5a1b382985a6549b85d435376c351", target.ID.String())
|
|
||||||
|
|
||||||
// should error when called on normal file
|
|
||||||
target, err = commit.Tree.GetTreeEntryByPath("file1.txt")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
_, err = target.FollowLink()
|
|
||||||
assert.EqualError(t, err, "file1.txt: not a symlink")
|
|
||||||
|
|
||||||
// should error for broken links
|
|
||||||
target, err = commit.Tree.GetTreeEntryByPath("foo/broken_link")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, target.IsLink())
|
|
||||||
_, err = target.FollowLink()
|
|
||||||
assert.EqualError(t, err, "broken_link: broken link")
|
|
||||||
|
|
||||||
// should error for external links
|
|
||||||
target, err = commit.Tree.GetTreeEntryByPath("foo/outside_repo")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, target.IsLink())
|
|
||||||
_, err = target.FollowLink()
|
|
||||||
assert.EqualError(t, err, "outside_repo: points outside of repo")
|
|
||||||
|
|
||||||
// testing fix for short link bug
|
|
||||||
target, err = commit.Tree.GetTreeEntryByPath("foo/link_short")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
_, err = target.FollowLink()
|
|
||||||
assert.EqualError(t, err, "link_short: broken link")
|
|
||||||
}
|
|
||||||
|
@ -69,7 +69,7 @@ func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) {
|
|||||||
seen := map[plumbing.Hash]bool{}
|
seen := map[plumbing.Hash]bool{}
|
||||||
walker := object.NewTreeWalker(t.gogitTree, true, seen)
|
walker := object.NewTreeWalker(t.gogitTree, true, seen)
|
||||||
for {
|
for {
|
||||||
fullName, entry, err := walker.Next()
|
_, entry, err := walker.Next()
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -84,7 +84,6 @@ func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) {
|
|||||||
ID: ParseGogitHash(entry.Hash),
|
ID: ParseGogitHash(entry.Hash),
|
||||||
gogitTreeEntry: &entry,
|
gogitTreeEntry: &entry,
|
||||||
ptree: t,
|
ptree: t,
|
||||||
fullName: fullName,
|
|
||||||
}
|
}
|
||||||
entries = append(entries, convertedEntry)
|
entries = append(entries, convertedEntry)
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,7 @@ func (r *stripRenderer) processAutoLink(w io.Writer, link []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: we're not attempting to match the URL scheme (http/https)
|
// Note: we're not attempting to match the URL scheme (http/https)
|
||||||
host := strings.ToLower(u.Host)
|
if u.Host != "" && !strings.EqualFold(u.Host, r.localhost.Host) {
|
||||||
if host != "" && host != strings.ToLower(r.localhost.Host) {
|
|
||||||
// Process out of band
|
// Process out of band
|
||||||
r.links = append(r.links, linkStr)
|
r.links = append(r.links, linkStr)
|
||||||
return
|
return
|
||||||
|
@ -71,6 +71,7 @@ type Metadata struct {
|
|||||||
ReleaseNotes string `json:"release_notes,omitempty"`
|
ReleaseNotes string `json:"release_notes,omitempty"`
|
||||||
RepositoryURL string `json:"repository_url,omitempty"`
|
RepositoryURL string `json:"repository_url,omitempty"`
|
||||||
RequireLicenseAcceptance bool `json:"require_license_acceptance"`
|
RequireLicenseAcceptance bool `json:"require_license_acceptance"`
|
||||||
|
Summary string `json:"summary,omitempty"`
|
||||||
Tags string `json:"tags,omitempty"`
|
Tags string `json:"tags,omitempty"`
|
||||||
Title string `json:"title,omitempty"`
|
Title string `json:"title,omitempty"`
|
||||||
|
|
||||||
@ -105,6 +106,7 @@ type nuspecPackage struct {
|
|||||||
Readme string `xml:"readme"`
|
Readme string `xml:"readme"`
|
||||||
ReleaseNotes string `xml:"releaseNotes"`
|
ReleaseNotes string `xml:"releaseNotes"`
|
||||||
RequireLicenseAcceptance bool `xml:"requireLicenseAcceptance"`
|
RequireLicenseAcceptance bool `xml:"requireLicenseAcceptance"`
|
||||||
|
Summary string `xml:"summary"`
|
||||||
Tags string `xml:"tags"`
|
Tags string `xml:"tags"`
|
||||||
Title string `xml:"title"`
|
Title string `xml:"title"`
|
||||||
|
|
||||||
@ -204,6 +206,7 @@ func ParseNuspecMetaData(archive *zip.Reader, r io.Reader) (*Package, error) {
|
|||||||
ReleaseNotes: p.Metadata.ReleaseNotes,
|
ReleaseNotes: p.Metadata.ReleaseNotes,
|
||||||
RepositoryURL: p.Metadata.Repository.URL,
|
RepositoryURL: p.Metadata.Repository.URL,
|
||||||
RequireLicenseAcceptance: p.Metadata.RequireLicenseAcceptance,
|
RequireLicenseAcceptance: p.Metadata.RequireLicenseAcceptance,
|
||||||
|
Summary: p.Metadata.Summary,
|
||||||
Tags: p.Metadata.Tags,
|
Tags: p.Metadata.Tags,
|
||||||
Title: p.Metadata.Title,
|
Title: p.Metadata.Title,
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ func ParsePackage(r io.Reader) (*Package, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else if strings.ToLower(hd.Name) == "readme.md" {
|
} else if strings.EqualFold(hd.Name, "readme.md") {
|
||||||
data, err := io.ReadAll(tr)
|
data, err := io.ReadAll(tr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -62,11 +62,11 @@ func (c logCompression) IsValid() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c logCompression) IsNone() bool {
|
func (c logCompression) IsNone() bool {
|
||||||
return strings.ToLower(string(c)) == "none"
|
return string(c) == "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c logCompression) IsZstd() bool {
|
func (c logCompression) IsZstd() bool {
|
||||||
return c == "" || strings.ToLower(string(c)) == "zstd"
|
return c == "" || string(c) == "zstd"
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadActionsFrom(rootCfg ConfigProvider) error {
|
func loadActionsFrom(rootCfg ConfigProvider) error {
|
||||||
|
@ -116,14 +116,17 @@ type ContentsExtResponse struct {
|
|||||||
|
|
||||||
// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
|
// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
|
||||||
type ContentsResponse struct {
|
type ContentsResponse struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
SHA string `json:"sha"`
|
SHA string `json:"sha"`
|
||||||
LastCommitSHA string `json:"last_commit_sha"`
|
|
||||||
|
LastCommitSHA *string `json:"last_commit_sha,omitempty"`
|
||||||
// swagger:strfmt date-time
|
// swagger:strfmt date-time
|
||||||
LastCommitterDate time.Time `json:"last_committer_date"`
|
LastCommitterDate *time.Time `json:"last_committer_date,omitempty"`
|
||||||
// swagger:strfmt date-time
|
// swagger:strfmt date-time
|
||||||
LastAuthorDate time.Time `json:"last_author_date"`
|
LastAuthorDate *time.Time `json:"last_author_date,omitempty"`
|
||||||
|
LastCommitMessage *string `json:"last_commit_message,omitempty"`
|
||||||
|
|
||||||
// `type` will be `file`, `dir`, `symlink`, or `submodule`
|
// `type` will be `file`, `dir`, `symlink`, or `submodule`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
@ -141,8 +144,8 @@ type ContentsResponse struct {
|
|||||||
SubmoduleGitURL *string `json:"submodule_git_url"`
|
SubmoduleGitURL *string `json:"submodule_git_url"`
|
||||||
Links *FileLinksResponse `json:"_links"`
|
Links *FileLinksResponse `json:"_links"`
|
||||||
|
|
||||||
LfsOid *string `json:"lfs_oid"`
|
LfsOid *string `json:"lfs_oid,omitempty"`
|
||||||
LfsSize *int64 `json:"lfs_size"`
|
LfsSize *int64 `json:"lfs_size,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileCommitResponse contains information generated from a Git commit for a repo's file.
|
// FileCommitResponse contains information generated from a Git commit for a repo's file.
|
||||||
|
@ -40,7 +40,6 @@ func NewFuncMap() template.FuncMap {
|
|||||||
"HTMLFormat": htmlFormat,
|
"HTMLFormat": htmlFormat,
|
||||||
"QueryEscape": queryEscape,
|
"QueryEscape": queryEscape,
|
||||||
"QueryBuild": QueryBuild,
|
"QueryBuild": QueryBuild,
|
||||||
"JSEscape": jsEscapeSafe,
|
|
||||||
"SanitizeHTML": SanitizeHTML,
|
"SanitizeHTML": SanitizeHTML,
|
||||||
"URLJoin": util.URLJoin,
|
"URLJoin": util.URLJoin,
|
||||||
"DotEscape": dotEscape,
|
"DotEscape": dotEscape,
|
||||||
@ -181,10 +180,6 @@ func htmlFormat(s any, args ...any) template.HTML {
|
|||||||
panic(fmt.Sprintf("unexpected type %T", s))
|
panic(fmt.Sprintf("unexpected type %T", s))
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsEscapeSafe(s string) template.HTML {
|
|
||||||
return template.HTML(template.JSEscapeString(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
func queryEscape(s string) template.URL {
|
func queryEscape(s string) template.URL {
|
||||||
return template.URL(url.QueryEscape(s))
|
return template.URL(url.QueryEscape(s))
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,6 @@ func TestSubjectBodySeparator(t *testing.T) {
|
|||||||
"Insufficient\n--\nSeparators")
|
"Insufficient\n--\nSeparators")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJSEscapeSafe(t *testing.T) {
|
|
||||||
assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, jsEscapeSafe(`&<>'"`))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSanitizeHTML(t *testing.T) {
|
func TestSanitizeHTML(t *testing.T) {
|
||||||
assert.Equal(t, template.HTML(`<a href="/" rel="nofollow">link</a> xss <div>inline</div>`), SanitizeHTML(`<a href="/">link</a> <a href="javascript:">xss</a> <div style="dangerous">inline</div>`))
|
assert.Equal(t, template.HTML(`<a href="/" rel="nofollow">link</a> xss <div>inline</div>`), SanitizeHTML(`<a href="/">link</a> <a href="javascript:">xss</a> <div style="dangerous">inline</div>`))
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ var (
|
|||||||
ErrNotExist = errors.New("resource does not exist") // also implies HTTP 404
|
ErrNotExist = errors.New("resource does not exist") // also implies HTTP 404
|
||||||
ErrAlreadyExist = errors.New("resource already exists") // also implies HTTP 409
|
ErrAlreadyExist = errors.New("resource already exists") // also implies HTTP 409
|
||||||
|
|
||||||
// ErrUnprocessableContent implies HTTP 422, syntax of the request content was correct,
|
// ErrUnprocessableContent implies HTTP 422, the syntax of the request content is correct,
|
||||||
// but server was unable to process the contained instructions
|
// but the server is unable to process the contained instructions
|
||||||
ErrUnprocessableContent = errors.New("unprocessable content")
|
ErrUnprocessableContent = errors.New("unprocessable content")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,8 +12,7 @@ import (
|
|||||||
// SliceContainsString sequential searches if string exists in slice.
|
// SliceContainsString sequential searches if string exists in slice.
|
||||||
func SliceContainsString(slice []string, target string, insensitive ...bool) bool {
|
func SliceContainsString(slice []string, target string, insensitive ...bool) bool {
|
||||||
if len(insensitive) != 0 && insensitive[0] {
|
if len(insensitive) != 0 && insensitive[0] {
|
||||||
target = strings.ToLower(target)
|
return slices.ContainsFunc(slice, func(t string) bool { return strings.EqualFold(t, target) })
|
||||||
return slices.ContainsFunc(slice, func(t string) bool { return strings.ToLower(t) == target })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return slices.Contains(slice, target)
|
return slices.Contains(slice, target)
|
||||||
|
@ -110,3 +110,24 @@ func SplitTrimSpace(input, sep string) []string {
|
|||||||
}
|
}
|
||||||
return stringList
|
return stringList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func asciiLower(b byte) byte {
|
||||||
|
if 'A' <= b && b <= 'Z' {
|
||||||
|
return b + ('a' - 'A')
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsciiEqualFold is from Golang https://cs.opensource.google/go/go/+/refs/tags/go1.24.4:src/net/http/internal/ascii/print.go
|
||||||
|
// ASCII only. In most cases for protocols, we should only use this but not [strings.EqualFold]
|
||||||
|
func AsciiEqualFold(s, t string) bool { //nolint:revive // PascalCase
|
||||||
|
if len(s) != len(t) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if asciiLower(s[i]) != asciiLower(t[i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -59,7 +59,7 @@ func TimeEstimateParse(timeStr string) (int64, error) {
|
|||||||
unit := timeStr[match[4]:match[5]]
|
unit := timeStr[match[4]:match[5]]
|
||||||
found := false
|
found := false
|
||||||
for _, u := range timeStrGlobalVars().units {
|
for _, u := range timeStrGlobalVars().units {
|
||||||
if strings.ToLower(unit) == u.name {
|
if strings.EqualFold(unit, u.name) {
|
||||||
total += amount * u.num
|
total += amount * u.num
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
|
@ -26,6 +26,7 @@ func (g *RouterPathGroup) ServeHTTP(resp http.ResponseWriter, req *http.Request)
|
|||||||
path := chiCtx.URLParam(g.pathParam)
|
path := chiCtx.URLParam(g.pathParam)
|
||||||
for _, m := range g.matchers {
|
for _, m := range g.matchers {
|
||||||
if m.matchPath(chiCtx, path) {
|
if m.matchPath(chiCtx, path) {
|
||||||
|
chiCtx.RoutePatterns = append(chiCtx.RoutePatterns, m.pattern)
|
||||||
handler := m.handlerFunc
|
handler := m.handlerFunc
|
||||||
for i := len(m.middlewares) - 1; i >= 0; i-- {
|
for i := len(m.middlewares) - 1; i >= 0; i-- {
|
||||||
handler = m.middlewares[i](handler).ServeHTTP
|
handler = m.middlewares[i](handler).ServeHTTP
|
||||||
@ -38,6 +39,7 @@ func (g *RouterPathGroup) ServeHTTP(resp http.ResponseWriter, req *http.Request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RouterPathGroupPattern struct {
|
type RouterPathGroupPattern struct {
|
||||||
|
pattern string
|
||||||
re *regexp.Regexp
|
re *regexp.Regexp
|
||||||
params []routerPathParam
|
params []routerPathParam
|
||||||
middlewares []any
|
middlewares []any
|
||||||
@ -62,6 +64,7 @@ type routerPathParam struct {
|
|||||||
|
|
||||||
type routerPathMatcher struct {
|
type routerPathMatcher struct {
|
||||||
methods container.Set[string]
|
methods container.Set[string]
|
||||||
|
pattern string
|
||||||
re *regexp.Regexp
|
re *regexp.Regexp
|
||||||
params []routerPathParam
|
params []routerPathParam
|
||||||
middlewares []func(http.Handler) http.Handler
|
middlewares []func(http.Handler) http.Handler
|
||||||
@ -117,7 +120,7 @@ func newRouterPathMatcher(methods string, patternRegexp *RouterPathGroupPattern,
|
|||||||
}
|
}
|
||||||
p.methods.Add(method)
|
p.methods.Add(method)
|
||||||
}
|
}
|
||||||
p.re, p.params = patternRegexp.re, patternRegexp.params
|
p.pattern, p.re, p.params = patternRegexp.pattern, patternRegexp.re, patternRegexp.params
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +160,7 @@ func patternRegexp(pattern string, h ...any) *RouterPathGroupPattern {
|
|||||||
p.params = append(p.params, param)
|
p.params = append(p.params, param)
|
||||||
}
|
}
|
||||||
re = append(re, '$')
|
re = append(re, '$')
|
||||||
p.re = regexp.MustCompile(string(re))
|
p.pattern, p.re = pattern, regexp.MustCompile(string(re))
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,17 +56,20 @@ func TestRouter(t *testing.T) {
|
|||||||
recorder.Body = buff
|
recorder.Body = buff
|
||||||
|
|
||||||
type resultStruct struct {
|
type resultStruct struct {
|
||||||
method string
|
method string
|
||||||
pathParams map[string]string
|
pathParams map[string]string
|
||||||
handlerMarks []string
|
handlerMarks []string
|
||||||
|
chiRoutePattern *string
|
||||||
}
|
}
|
||||||
|
|
||||||
var res resultStruct
|
var res resultStruct
|
||||||
h := func(optMark ...string) func(resp http.ResponseWriter, req *http.Request) {
|
h := func(optMark ...string) func(resp http.ResponseWriter, req *http.Request) {
|
||||||
mark := util.OptionalArg(optMark, "")
|
mark := util.OptionalArg(optMark, "")
|
||||||
return func(resp http.ResponseWriter, req *http.Request) {
|
return func(resp http.ResponseWriter, req *http.Request) {
|
||||||
|
chiCtx := chi.RouteContext(req.Context())
|
||||||
res.method = req.Method
|
res.method = req.Method
|
||||||
res.pathParams = chiURLParamsToMap(chi.RouteContext(req.Context()))
|
res.pathParams = chiURLParamsToMap(chiCtx)
|
||||||
|
res.chiRoutePattern = util.ToPointer(chiCtx.RoutePattern())
|
||||||
if mark != "" {
|
if mark != "" {
|
||||||
res.handlerMarks = append(res.handlerMarks, mark)
|
res.handlerMarks = append(res.handlerMarks, mark)
|
||||||
}
|
}
|
||||||
@ -125,21 +128,29 @@ func TestRouter(t *testing.T) {
|
|||||||
req, err := http.NewRequest(methodPathFields[0], methodPathFields[1], nil)
|
req, err := http.NewRequest(methodPathFields[0], methodPathFields[1], nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
r.ServeHTTP(recorder, req)
|
r.ServeHTTP(recorder, req)
|
||||||
|
if expected.chiRoutePattern == nil {
|
||||||
|
res.chiRoutePattern = nil
|
||||||
|
}
|
||||||
assert.Equal(t, expected, res)
|
assert.Equal(t, expected, res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("RootRouter", func(t *testing.T) {
|
t.Run("RootRouter", func(t *testing.T) {
|
||||||
testRoute(t, "GET /the-user/the-repo/other", resultStruct{method: "GET", handlerMarks: []string{"not-found:/"}})
|
testRoute(t, "GET /the-user/the-repo/other", resultStruct{
|
||||||
|
method: "GET",
|
||||||
|
handlerMarks: []string{"not-found:/"},
|
||||||
|
chiRoutePattern: util.ToPointer(""),
|
||||||
|
})
|
||||||
testRoute(t, "GET /the-user/the-repo/pulls", resultStruct{
|
testRoute(t, "GET /the-user/the-repo/pulls", resultStruct{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "pulls"},
|
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "pulls"},
|
||||||
handlerMarks: []string{"list-issues-b"},
|
handlerMarks: []string{"list-issues-b"},
|
||||||
})
|
})
|
||||||
testRoute(t, "GET /the-user/the-repo/issues/123", resultStruct{
|
testRoute(t, "GET /the-user/the-repo/issues/123", resultStruct{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "issues", "index": "123"},
|
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "issues", "index": "123"},
|
||||||
handlerMarks: []string{"view-issue"},
|
handlerMarks: []string{"view-issue"},
|
||||||
|
chiRoutePattern: util.ToPointer("/{username}/{reponame}/{type:issues|pulls}/{index}"),
|
||||||
})
|
})
|
||||||
testRoute(t, "GET /the-user/the-repo/issues/123?stop=hijack", resultStruct{
|
testRoute(t, "GET /the-user/the-repo/issues/123?stop=hijack", resultStruct{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
@ -154,7 +165,10 @@ func TestRouter(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Sub Router", func(t *testing.T) {
|
t.Run("Sub Router", func(t *testing.T) {
|
||||||
testRoute(t, "GET /api/v1/other", resultStruct{method: "GET", handlerMarks: []string{"not-found:/api/v1"}})
|
testRoute(t, "GET /api/v1/other", resultStruct{
|
||||||
|
method: "GET",
|
||||||
|
handlerMarks: []string{"not-found:/api/v1"},
|
||||||
|
})
|
||||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches", resultStruct{
|
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches", resultStruct{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo"},
|
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo"},
|
||||||
@ -211,9 +225,10 @@ func TestRouter(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1/d2/fn?stop=s3", resultStruct{
|
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1/d2/fn?stop=s3", resultStruct{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
|
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
|
||||||
handlerMarks: []string{"s1", "s2", "s3"},
|
handlerMarks: []string{"s1", "s2", "s3"},
|
||||||
|
chiRoutePattern: util.ToPointer("/api/v1/repos/{username}/{reponame}/branches/<dir:*>/<file:[a-z]{1,2}>"),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
86
options/fileicon/material-icon-rules.json
generated
@ -3131,6 +3131,34 @@
|
|||||||
".links": "folder-link",
|
".links": "folder-link",
|
||||||
"_links": "folder-link",
|
"_links": "folder-link",
|
||||||
"__links__": "folder-link",
|
"__links__": "folder-link",
|
||||||
|
"pytorch": "folder-pytorch",
|
||||||
|
".pytorch": "folder-pytorch",
|
||||||
|
"_pytorch": "folder-pytorch",
|
||||||
|
"__pytorch__": "folder-pytorch",
|
||||||
|
"torch": "folder-pytorch",
|
||||||
|
".torch": "folder-pytorch",
|
||||||
|
"_torch": "folder-pytorch",
|
||||||
|
"__torch__": "folder-pytorch",
|
||||||
|
"blender": "folder-blender",
|
||||||
|
".blender": "folder-blender",
|
||||||
|
"_blender": "folder-blender",
|
||||||
|
"__blender__": "folder-blender",
|
||||||
|
"blender-assets": "folder-blender",
|
||||||
|
".blender-assets": "folder-blender",
|
||||||
|
"_blender-assets": "folder-blender",
|
||||||
|
"__blender-assets__": "folder-blender",
|
||||||
|
"blender-files": "folder-blender",
|
||||||
|
".blender-files": "folder-blender",
|
||||||
|
"_blender-files": "folder-blender",
|
||||||
|
"__blender-files__": "folder-blender",
|
||||||
|
"blender-project": "folder-blender",
|
||||||
|
".blender-project": "folder-blender",
|
||||||
|
"_blender-project": "folder-blender",
|
||||||
|
"__blender-project__": "folder-blender",
|
||||||
|
"blender-models": "folder-blender",
|
||||||
|
".blender-models": "folder-blender",
|
||||||
|
"_blender-models": "folder-blender",
|
||||||
|
"__blender-models__": "folder-blender",
|
||||||
"meta-inf": "folder-config",
|
"meta-inf": "folder-config",
|
||||||
".meta-inf": "folder-config",
|
".meta-inf": "folder-config",
|
||||||
"_meta-inf": "folder-config",
|
"_meta-inf": "folder-config",
|
||||||
@ -6291,7 +6319,35 @@
|
|||||||
"links": "folder-link-open",
|
"links": "folder-link-open",
|
||||||
".links": "folder-link-open",
|
".links": "folder-link-open",
|
||||||
"_links": "folder-link-open",
|
"_links": "folder-link-open",
|
||||||
"__links__": "folder-link-open"
|
"__links__": "folder-link-open",
|
||||||
|
"pytorch": "folder-pytorch-open",
|
||||||
|
".pytorch": "folder-pytorch-open",
|
||||||
|
"_pytorch": "folder-pytorch-open",
|
||||||
|
"__pytorch__": "folder-pytorch-open",
|
||||||
|
"torch": "folder-pytorch-open",
|
||||||
|
".torch": "folder-pytorch-open",
|
||||||
|
"_torch": "folder-pytorch-open",
|
||||||
|
"__torch__": "folder-pytorch-open",
|
||||||
|
"blender": "folder-blender-open",
|
||||||
|
".blender": "folder-blender-open",
|
||||||
|
"_blender": "folder-blender-open",
|
||||||
|
"__blender__": "folder-blender-open",
|
||||||
|
"blender-assets": "folder-blender-open",
|
||||||
|
".blender-assets": "folder-blender-open",
|
||||||
|
"_blender-assets": "folder-blender-open",
|
||||||
|
"__blender-assets__": "folder-blender-open",
|
||||||
|
"blender-files": "folder-blender-open",
|
||||||
|
".blender-files": "folder-blender-open",
|
||||||
|
"_blender-files": "folder-blender-open",
|
||||||
|
"__blender-files__": "folder-blender-open",
|
||||||
|
"blender-project": "folder-blender-open",
|
||||||
|
".blender-project": "folder-blender-open",
|
||||||
|
"_blender-project": "folder-blender-open",
|
||||||
|
"__blender-project__": "folder-blender-open",
|
||||||
|
"blender-models": "folder-blender-open",
|
||||||
|
".blender-models": "folder-blender-open",
|
||||||
|
"_blender-models": "folder-blender-open",
|
||||||
|
"__blender-models__": "folder-blender-open"
|
||||||
},
|
},
|
||||||
"rootFolderNames": {},
|
"rootFolderNames": {},
|
||||||
"rootFolderNamesExpanded": {},
|
"rootFolderNamesExpanded": {},
|
||||||
@ -7099,10 +7155,10 @@
|
|||||||
"fast": "lisp",
|
"fast": "lisp",
|
||||||
"stl": "3d",
|
"stl": "3d",
|
||||||
"stp": "3d",
|
"stp": "3d",
|
||||||
|
"step": "3d",
|
||||||
"obj": "3d",
|
"obj": "3d",
|
||||||
"o": "3d",
|
"o": "3d",
|
||||||
"ac": "3d",
|
"ac": "3d",
|
||||||
"blend": "3d",
|
|
||||||
"dxf": "3d",
|
"dxf": "3d",
|
||||||
"fbx": "3d",
|
"fbx": "3d",
|
||||||
"mesh": "3d",
|
"mesh": "3d",
|
||||||
@ -7115,6 +7171,12 @@
|
|||||||
"vox": "3d",
|
"vox": "3d",
|
||||||
"gltf": "3d",
|
"gltf": "3d",
|
||||||
"glb": "3d",
|
"glb": "3d",
|
||||||
|
"3ds": "3d",
|
||||||
|
"dae": "3d",
|
||||||
|
"ply": "3d",
|
||||||
|
"wrl": "3d",
|
||||||
|
"usd": "3d",
|
||||||
|
"usdz": "3d",
|
||||||
"svg": "svg",
|
"svg": "svg",
|
||||||
"ai": "adobe-illustrator",
|
"ai": "adobe-illustrator",
|
||||||
"ait": "adobe-illustrator",
|
"ait": "adobe-illustrator",
|
||||||
@ -7382,6 +7444,12 @@
|
|||||||
"snakemake": "snakemake",
|
"snakemake": "snakemake",
|
||||||
"cpn": "coloredpetrinets",
|
"cpn": "coloredpetrinets",
|
||||||
"pnml": "coloredpetrinets",
|
"pnml": "coloredpetrinets",
|
||||||
|
"pt": "pytorch",
|
||||||
|
"pth": "pytorch",
|
||||||
|
"pwf": "pytorch",
|
||||||
|
"blend": "blender",
|
||||||
|
"blend1": "blender",
|
||||||
|
"blend2": "blender",
|
||||||
"yaml-tmlanguage": "yaml",
|
"yaml-tmlanguage": "yaml",
|
||||||
"tmlanguage": "xml",
|
"tmlanguage": "xml",
|
||||||
"cljx": "clojure",
|
"cljx": "clojure",
|
||||||
@ -7545,7 +7613,6 @@
|
|||||||
"opml": "xml",
|
"opml": "xml",
|
||||||
"owl": "xml",
|
"owl": "xml",
|
||||||
"proj": "xml",
|
"proj": "xml",
|
||||||
"pt": "xml",
|
|
||||||
"publishsettings": "xml",
|
"publishsettings": "xml",
|
||||||
"pubxml": "xml",
|
"pubxml": "xml",
|
||||||
"pubxml.user": "xml",
|
"pubxml.user": "xml",
|
||||||
@ -7883,6 +7950,7 @@
|
|||||||
".pubignore": "dart",
|
".pubignore": "dart",
|
||||||
"cmakelists.txt": "cmake",
|
"cmakelists.txt": "cmake",
|
||||||
"cmakecache.txt": "cmake",
|
"cmakecache.txt": "cmake",
|
||||||
|
"CMakePresets.json": "cmake",
|
||||||
"semgrep.yml": "semgrep",
|
"semgrep.yml": "semgrep",
|
||||||
".semgrepignore": "semgrep",
|
".semgrepignore": "semgrep",
|
||||||
"vue.config.js": "vue-config",
|
"vue.config.js": "vue-config",
|
||||||
@ -8491,6 +8559,7 @@
|
|||||||
".mocharc.yml": "mocha",
|
".mocharc.yml": "mocha",
|
||||||
".mocharc.yaml": "mocha",
|
".mocharc.yaml": "mocha",
|
||||||
".mocharc.js": "mocha",
|
".mocharc.js": "mocha",
|
||||||
|
".mocharc.cjs": "mocha",
|
||||||
".mocharc.json": "mocha",
|
".mocharc.json": "mocha",
|
||||||
".mocharc.jsonc": "mocha",
|
".mocharc.jsonc": "mocha",
|
||||||
"jenkinsfile": "jenkins",
|
"jenkinsfile": "jenkins",
|
||||||
@ -8739,11 +8808,13 @@
|
|||||||
"azure-pipelines-main.yaml": "azure-pipelines",
|
"azure-pipelines-main.yaml": "azure-pipelines",
|
||||||
"vagrantfile": "vagrant",
|
"vagrantfile": "vagrant",
|
||||||
"prisma.yml": "prisma",
|
"prisma.yml": "prisma",
|
||||||
|
"prisma.config.ts": "prisma",
|
||||||
".nycrc": "istanbul",
|
".nycrc": "istanbul",
|
||||||
".nycrc.json": "istanbul",
|
".nycrc.json": "istanbul",
|
||||||
".nycrc.yaml": "istanbul",
|
".nycrc.yaml": "istanbul",
|
||||||
".nycrc.yml": "istanbul",
|
".nycrc.yml": "istanbul",
|
||||||
"nyc.config.js": "istanbul",
|
"nyc.config.js": "istanbul",
|
||||||
|
"nyc.config.cjs": "istanbul",
|
||||||
".istanbul.yml": "istanbul",
|
".istanbul.yml": "istanbul",
|
||||||
"tailwind.js": "tailwindcss",
|
"tailwind.js": "tailwindcss",
|
||||||
"tailwind.ts": "tailwindcss",
|
"tailwind.ts": "tailwindcss",
|
||||||
@ -9477,6 +9548,7 @@
|
|||||||
"hadolint.yaml": "hadolint",
|
"hadolint.yaml": "hadolint",
|
||||||
"hadolint.yml": "hadolint",
|
"hadolint.yml": "hadolint",
|
||||||
".rhistory": "r",
|
".rhistory": "r",
|
||||||
|
"cmakepresets.json": "cmake",
|
||||||
"cname": "http",
|
"cname": "http",
|
||||||
"sonarqube.analysis.xml": "sonarcloud",
|
"sonarqube.analysis.xml": "sonarcloud",
|
||||||
"owners": "codeowners",
|
"owners": "codeowners",
|
||||||
@ -9590,7 +9662,13 @@
|
|||||||
"tex": "tex",
|
"tex": "tex",
|
||||||
"latex": "latex",
|
"latex": "latex",
|
||||||
"latex-expl3": "latex",
|
"latex-expl3": "latex",
|
||||||
|
"latex-class": "latex-class",
|
||||||
|
"latex-package": "latex-package",
|
||||||
|
"context": "context",
|
||||||
"doctex": "doctex",
|
"doctex": "doctex",
|
||||||
|
"doctex-installer": "doctex-installer",
|
||||||
|
"bibtex": "bibliography",
|
||||||
|
"bibtex-style": "bibtex-style",
|
||||||
"apex": "salesforce",
|
"apex": "salesforce",
|
||||||
"sas": "sas",
|
"sas": "sas",
|
||||||
"dockerfile": "docker",
|
"dockerfile": "docker",
|
||||||
@ -9622,8 +9700,6 @@
|
|||||||
"vue-postcss": "vue",
|
"vue-postcss": "vue",
|
||||||
"vue-html": "vue",
|
"vue-html": "vue",
|
||||||
"lua": "lua",
|
"lua": "lua",
|
||||||
"bibtex": "bibliography",
|
|
||||||
"bibtex-style": "bibtex-style",
|
|
||||||
"log": "log",
|
"log": "log",
|
||||||
"jupyter": "jupyter",
|
"jupyter": "jupyter",
|
||||||
"plaintext": "document",
|
"plaintext": "document",
|
||||||
|
354
options/fileicon/material-icon-svgs.json
generated
@ -2274,8 +2274,6 @@ settings.hooks_desc=Webové háčky automaticky vytvářejí dotazy HTTP POST na
|
|||||||
settings.webhook_deletion=Odstranit webový háček
|
settings.webhook_deletion=Odstranit webový háček
|
||||||
settings.webhook_deletion_desc=Odstranění webového háčku smaže jeho nastavení a historii doručení. Pokračovat?
|
settings.webhook_deletion_desc=Odstranění webového háčku smaže jeho nastavení a historii doručení. Pokračovat?
|
||||||
settings.webhook_deletion_success=Webový háček byl smazán.
|
settings.webhook_deletion_success=Webový háček byl smazán.
|
||||||
settings.webhook.test_delivery=Test doručitelnosti
|
|
||||||
settings.webhook.test_delivery_desc=Vyzkoušet tento webový háček pomocí falešné události.
|
|
||||||
settings.webhook.test_delivery_desc_disabled=Chcete-li tento webový háček otestovat s falešnou událostí, aktivujte ho.
|
settings.webhook.test_delivery_desc_disabled=Chcete-li tento webový háček otestovat s falešnou událostí, aktivujte ho.
|
||||||
settings.webhook.request=Požadavek
|
settings.webhook.request=Požadavek
|
||||||
settings.webhook.response=Odpověď
|
settings.webhook.response=Odpověď
|
||||||
|
@ -2316,8 +2316,6 @@ settings.hooks_desc=Webhooks senden bei bestimmten Gitea-Events automatisch „H
|
|||||||
settings.webhook_deletion=Webhook löschen
|
settings.webhook_deletion=Webhook löschen
|
||||||
settings.webhook_deletion_desc=Das Entfernen eines Webhooks löscht seine Einstellungen und Zustellungsverlauf. Fortfahren?
|
settings.webhook_deletion_desc=Das Entfernen eines Webhooks löscht seine Einstellungen und Zustellungsverlauf. Fortfahren?
|
||||||
settings.webhook_deletion_success=Webhook wurde entfernt.
|
settings.webhook_deletion_success=Webhook wurde entfernt.
|
||||||
settings.webhook.test_delivery=Senden testen
|
|
||||||
settings.webhook.test_delivery_desc=Teste diesen Webhook mit einem Fake-Event.
|
|
||||||
settings.webhook.test_delivery_desc_disabled=Um diesen Webhook mit einem Fake-Event zu testen, aktiviere ihn.
|
settings.webhook.test_delivery_desc_disabled=Um diesen Webhook mit einem Fake-Event zu testen, aktiviere ihn.
|
||||||
settings.webhook.request=Anfrage
|
settings.webhook.request=Anfrage
|
||||||
settings.webhook.response=Antwort
|
settings.webhook.response=Antwort
|
||||||
|
@ -2066,8 +2066,6 @@ settings.hooks_desc=Τα Webhooks κάνουν αυτόματα αιτήσεις
|
|||||||
settings.webhook_deletion=Αφαίρεση Webhook
|
settings.webhook_deletion=Αφαίρεση Webhook
|
||||||
settings.webhook_deletion_desc=Η αφαίρεση ενός webhook διαγράφει τις ρυθμίσεις και το ιστορικό παραδόσεων. Συνέχεια;
|
settings.webhook_deletion_desc=Η αφαίρεση ενός webhook διαγράφει τις ρυθμίσεις και το ιστορικό παραδόσεων. Συνέχεια;
|
||||||
settings.webhook_deletion_success=Το webhook έχει αφαιρεθεί.
|
settings.webhook_deletion_success=Το webhook έχει αφαιρεθεί.
|
||||||
settings.webhook.test_delivery=Δοκιμή Παράδοσης
|
|
||||||
settings.webhook.test_delivery_desc=Δοκιμάστε αυτό το webhook με ένα ψεύτικο συμβάν.
|
|
||||||
settings.webhook.test_delivery_desc_disabled=Για να δοκιμάσετε αυτό το webhook με μια ψεύτικη κλήση, ενεργοποιήστε το.
|
settings.webhook.test_delivery_desc_disabled=Για να δοκιμάσετε αυτό το webhook με μια ψεύτικη κλήση, ενεργοποιήστε το.
|
||||||
settings.webhook.request=Αίτημα
|
settings.webhook.request=Αίτημα
|
||||||
settings.webhook.response=Απάντηση
|
settings.webhook.response=Απάντηση
|
||||||
|
@ -2334,8 +2334,8 @@ settings.hooks_desc = Webhooks automatically make HTTP POST requests to a server
|
|||||||
settings.webhook_deletion = Remove Webhook
|
settings.webhook_deletion = Remove Webhook
|
||||||
settings.webhook_deletion_desc = Removing a webhook deletes its settings and delivery history. Continue?
|
settings.webhook_deletion_desc = Removing a webhook deletes its settings and delivery history. Continue?
|
||||||
settings.webhook_deletion_success = The webhook has been removed.
|
settings.webhook_deletion_success = The webhook has been removed.
|
||||||
settings.webhook.test_delivery = Test Delivery
|
settings.webhook.test_delivery = Test Push Event
|
||||||
settings.webhook.test_delivery_desc = Test this webhook with a fake event.
|
settings.webhook.test_delivery_desc = Test this webhook with a fake push event.
|
||||||
settings.webhook.test_delivery_desc_disabled = To test this webhook with a fake event, activate it.
|
settings.webhook.test_delivery_desc_disabled = To test this webhook with a fake event, activate it.
|
||||||
settings.webhook.request = Request
|
settings.webhook.request = Request
|
||||||
settings.webhook.response = Response
|
settings.webhook.response = Response
|
||||||
@ -2355,6 +2355,7 @@ settings.payload_url = Target URL
|
|||||||
settings.http_method = HTTP Method
|
settings.http_method = HTTP Method
|
||||||
settings.content_type = POST Content Type
|
settings.content_type = POST Content Type
|
||||||
settings.secret = Secret
|
settings.secret = Secret
|
||||||
|
settings.webhook_secret_desc = If the webhook server supports using secret, you can follow the webhook's manual and fill in a secret here.
|
||||||
settings.slack_username = Username
|
settings.slack_username = Username
|
||||||
settings.slack_icon_url = Icon URL
|
settings.slack_icon_url = Icon URL
|
||||||
settings.slack_color = Color
|
settings.slack_color = Color
|
||||||
@ -2769,6 +2770,8 @@ branch.new_branch_from = Create new branch from "%s"
|
|||||||
branch.renamed = Branch %s was renamed to %s.
|
branch.renamed = Branch %s was renamed to %s.
|
||||||
branch.rename_default_or_protected_branch_error = Only admins can rename default or protected branches.
|
branch.rename_default_or_protected_branch_error = Only admins can rename default or protected branches.
|
||||||
branch.rename_protected_branch_failed = This branch is protected by glob-based protection rules.
|
branch.rename_protected_branch_failed = This branch is protected by glob-based protection rules.
|
||||||
|
branch.commits_divergence_from = Commits divergence: %[1]d behind and %[2]d ahead of %[3]s
|
||||||
|
branch.commits_no_divergence = The same as branch %[1]s
|
||||||
|
|
||||||
tag.create_tag = Create tag %s
|
tag.create_tag = Create tag %s
|
||||||
tag.create_tag_operation = Create tag
|
tag.create_tag_operation = Create tag
|
||||||
@ -2782,6 +2785,7 @@ topic.done = Done
|
|||||||
topic.count_prompt = You cannot select more than 25 topics
|
topic.count_prompt = You cannot select more than 25 topics
|
||||||
topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
|
topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
|
||||||
|
|
||||||
|
find_file.follow_symlink= Follow this symlink to where it is pointing at
|
||||||
find_file.go_to_file = Go to file
|
find_file.go_to_file = Go to file
|
||||||
find_file.no_matching = No matching file found
|
find_file.no_matching = No matching file found
|
||||||
|
|
||||||
|
@ -2050,8 +2050,6 @@ settings.hooks_desc=Los webhooks automáticamente hacen peticiones HTTP POST a u
|
|||||||
settings.webhook_deletion=Eliminar Webhook
|
settings.webhook_deletion=Eliminar Webhook
|
||||||
settings.webhook_deletion_desc=Eliminar un webhook borra sus ajustes e historial de entrega. ¿Continuar?
|
settings.webhook_deletion_desc=Eliminar un webhook borra sus ajustes e historial de entrega. ¿Continuar?
|
||||||
settings.webhook_deletion_success=El webhook ha sido eliminado.
|
settings.webhook_deletion_success=El webhook ha sido eliminado.
|
||||||
settings.webhook.test_delivery=Test de entrega
|
|
||||||
settings.webhook.test_delivery_desc=Prueba este webhook con un evento falso.
|
|
||||||
settings.webhook.test_delivery_desc_disabled=Para probar este webhook con un evento falso, actívalo.
|
settings.webhook.test_delivery_desc_disabled=Para probar este webhook con un evento falso, actívalo.
|
||||||
settings.webhook.request=Petición
|
settings.webhook.request=Petición
|
||||||
settings.webhook.response=Respuesta
|
settings.webhook.response=Respuesta
|
||||||
|
@ -1591,8 +1591,6 @@ settings.hooks_desc=هوک تحت وب به صورت خودکار درخواست
|
|||||||
settings.webhook_deletion=حذف Webhook
|
settings.webhook_deletion=حذف Webhook
|
||||||
settings.webhook_deletion_desc=حذف هوک تحت وب موجب حذف تنظیمات آن و تاریخچه تحویل آن میشود. همچنان ادامه میدهید؟
|
settings.webhook_deletion_desc=حذف هوک تحت وب موجب حذف تنظیمات آن و تاریخچه تحویل آن میشود. همچنان ادامه میدهید؟
|
||||||
settings.webhook_deletion_success=هوک تحت وب حذف شد.
|
settings.webhook_deletion_success=هوک تحت وب حذف شد.
|
||||||
settings.webhook.test_delivery=امتحانکردن تحویل
|
|
||||||
settings.webhook.test_delivery_desc=Webhook را با رویداد جعلی امتحان کنید.
|
|
||||||
settings.webhook.request=درخواست
|
settings.webhook.request=درخواست
|
||||||
settings.webhook.response=پاسخ
|
settings.webhook.response=پاسخ
|
||||||
settings.webhook.headers=سربرگها
|
settings.webhook.headers=سربرگها
|
||||||
|
@ -1097,7 +1097,6 @@ settings.teams=Tiimit
|
|||||||
settings.add_team=Lisää tiimi
|
settings.add_team=Lisää tiimi
|
||||||
settings.add_webhook=Lisää webkoukku
|
settings.add_webhook=Lisää webkoukku
|
||||||
settings.webhook_deletion=Poista webkoukku
|
settings.webhook_deletion=Poista webkoukku
|
||||||
settings.webhook.test_delivery=Testitoimitus
|
|
||||||
settings.webhook.request=Pyyntö
|
settings.webhook.request=Pyyntö
|
||||||
settings.webhook.response=Vastaus
|
settings.webhook.response=Vastaus
|
||||||
settings.webhook.headers=Otsikot
|
settings.webhook.headers=Otsikot
|
||||||
|
@ -1969,6 +1969,7 @@ pulls.cmd_instruction_checkout_title=Basculer
|
|||||||
pulls.cmd_instruction_checkout_desc=Depuis votre dépôt, basculer sur une nouvelle branche et tester des modifications.
|
pulls.cmd_instruction_checkout_desc=Depuis votre dépôt, basculer sur une nouvelle branche et tester des modifications.
|
||||||
pulls.cmd_instruction_merge_title=Fusionner
|
pulls.cmd_instruction_merge_title=Fusionner
|
||||||
pulls.cmd_instruction_merge_desc=Fusionner les modifications et mettre à jour sur Gitea.
|
pulls.cmd_instruction_merge_desc=Fusionner les modifications et mettre à jour sur Gitea.
|
||||||
|
pulls.cmd_instruction_merge_warning=Attention : cette opération ne peut pas fusionner la demande d’ajout car la « détection automatique de fusion manuelle » n’a pas été activée
|
||||||
pulls.clear_merge_message=Effacer le message de fusion
|
pulls.clear_merge_message=Effacer le message de fusion
|
||||||
pulls.clear_merge_message_hint=Effacer le message de fusion ne supprimera que le message de la révision, mais pas les pieds de révision générés tels que "Co-Authored-By:".
|
pulls.clear_merge_message_hint=Effacer le message de fusion ne supprimera que le message de la révision, mais pas les pieds de révision générés tels que "Co-Authored-By:".
|
||||||
|
|
||||||
@ -2333,8 +2334,6 @@ settings.hooks_desc=Les Webhooks font automatiquement des requêtes HTTP POST à
|
|||||||
settings.webhook_deletion=Retirer le Webhook
|
settings.webhook_deletion=Retirer le Webhook
|
||||||
settings.webhook_deletion_desc=Supprimer un webhook supprime ses paramètres et son historique. Continuer ?
|
settings.webhook_deletion_desc=Supprimer un webhook supprime ses paramètres et son historique. Continuer ?
|
||||||
settings.webhook_deletion_success=Le webhook a été supprimé.
|
settings.webhook_deletion_success=Le webhook a été supprimé.
|
||||||
settings.webhook.test_delivery=Tester l'envoi
|
|
||||||
settings.webhook.test_delivery_desc=Testez ce webhook avec un faux événement.
|
|
||||||
settings.webhook.test_delivery_desc_disabled=Pour tester ce webhook avec un faux événement, activez-le.
|
settings.webhook.test_delivery_desc_disabled=Pour tester ce webhook avec un faux événement, activez-le.
|
||||||
settings.webhook.request=Requête
|
settings.webhook.request=Requête
|
||||||
settings.webhook.response=Réponse
|
settings.webhook.response=Réponse
|
||||||
@ -2768,6 +2767,8 @@ branch.new_branch_from=`Créer une nouvelle branche à partir de "%s"`
|
|||||||
branch.renamed=La branche %s à été renommée en %s.
|
branch.renamed=La branche %s à été renommée en %s.
|
||||||
branch.rename_default_or_protected_branch_error=Seuls les administrateurs peuvent renommer les branches par défaut ou protégées.
|
branch.rename_default_or_protected_branch_error=Seuls les administrateurs peuvent renommer les branches par défaut ou protégées.
|
||||||
branch.rename_protected_branch_failed=Cette branche est protégée par des règles de protection basées sur des globs.
|
branch.rename_protected_branch_failed=Cette branche est protégée par des règles de protection basées sur des globs.
|
||||||
|
branch.commits_divergence_from=Divergence de révisions : %[1]d en retard et %[2]d en avance sur %[3]s
|
||||||
|
branch.commits_no_divergence=Identique à la branche %[1]s
|
||||||
|
|
||||||
tag.create_tag=Créer l'étiquette %s
|
tag.create_tag=Créer l'étiquette %s
|
||||||
tag.create_tag_operation=Créer une étiquette
|
tag.create_tag_operation=Créer une étiquette
|
||||||
|
@ -1969,6 +1969,7 @@ pulls.cmd_instruction_checkout_title=Seiceáil
|
|||||||
pulls.cmd_instruction_checkout_desc=Ó stór tionscadail, seiceáil brainse nua agus déan tástáil ar na hathruithe.
|
pulls.cmd_instruction_checkout_desc=Ó stór tionscadail, seiceáil brainse nua agus déan tástáil ar na hathruithe.
|
||||||
pulls.cmd_instruction_merge_title=Cumaisc
|
pulls.cmd_instruction_merge_title=Cumaisc
|
||||||
pulls.cmd_instruction_merge_desc=Cumaisc na hathruithe agus nuashonrú ar Gitea.
|
pulls.cmd_instruction_merge_desc=Cumaisc na hathruithe agus nuashonrú ar Gitea.
|
||||||
|
pulls.cmd_instruction_merge_warning=Rabhadh: Ní féidir iarratas tarraingthe cumaisc a dhéanamh leis an oibríocht seo mar nach bhfuil "autodetect manual merge" cumasaithe.
|
||||||
pulls.clear_merge_message=Glan an teachtaireacht chumaisc
|
pulls.clear_merge_message=Glan an teachtaireacht chumaisc
|
||||||
pulls.clear_merge_message_hint=Má imrítear an teachtaireacht chumaisc ní bhainfear ach ábhar na teachtaireachta tiomanta agus coimeádfar leantóirí git ginte ar nós "Co-Authored-By …".
|
pulls.clear_merge_message_hint=Má imrítear an teachtaireacht chumaisc ní bhainfear ach ábhar na teachtaireachta tiomanta agus coimeádfar leantóirí git ginte ar nós "Co-Authored-By …".
|
||||||
|
|
||||||
@ -2333,8 +2334,8 @@ settings.hooks_desc=Déanann Crúcaí Gréasán iarratais HTTP POST go huathoibr
|
|||||||
settings.webhook_deletion=Bain Crúca Gréasán
|
settings.webhook_deletion=Bain Crúca Gréasán
|
||||||
settings.webhook_deletion_desc=Scriostar a shocruithe agus a stair seachadta a bhaineann le Crúca Gréasán a bhaint. Lean ar aghaidh?
|
settings.webhook_deletion_desc=Scriostar a shocruithe agus a stair seachadta a bhaineann le Crúca Gréasán a bhaint. Lean ar aghaidh?
|
||||||
settings.webhook_deletion_success=Tá an Crúca Gréasán bainte amach.
|
settings.webhook_deletion_success=Tá an Crúca Gréasán bainte amach.
|
||||||
settings.webhook.test_delivery=Seachadadh Tástála
|
settings.webhook.test_delivery=Imeacht Brúigh Tástála
|
||||||
settings.webhook.test_delivery_desc=Déan tástáil ar an Crúca Gréasán seo le himeacht bhréige.
|
settings.webhook.test_delivery_desc=Déan tástáil ar an webhook seo le teagmhas brú bréige.
|
||||||
settings.webhook.test_delivery_desc_disabled=Chun an Crúca Gréasán seo a thástáil le himeacht bhréige, gníomhachtaigh é.
|
settings.webhook.test_delivery_desc_disabled=Chun an Crúca Gréasán seo a thástáil le himeacht bhréige, gníomhachtaigh é.
|
||||||
settings.webhook.request=Iarratas
|
settings.webhook.request=Iarratas
|
||||||
settings.webhook.response=Freagra
|
settings.webhook.response=Freagra
|
||||||
@ -2354,6 +2355,7 @@ settings.payload_url=URL spriocdhírithe
|
|||||||
settings.http_method=Modh HTTP
|
settings.http_method=Modh HTTP
|
||||||
settings.content_type=Cineál Ábhar POST
|
settings.content_type=Cineál Ábhar POST
|
||||||
settings.secret=Rúnda
|
settings.secret=Rúnda
|
||||||
|
settings.webhook_secret_desc=Más féidir le freastalaí an webhook rún a úsáid, is féidir leat lámhleabhar an webhook a leanúint agus rún a líonadh isteach anseo.
|
||||||
settings.slack_username=Ainm úsáideora
|
settings.slack_username=Ainm úsáideora
|
||||||
settings.slack_icon_url=URL deilbhín
|
settings.slack_icon_url=URL deilbhín
|
||||||
settings.slack_color=Dath
|
settings.slack_color=Dath
|
||||||
@ -2768,6 +2770,8 @@ branch.new_branch_from=`Cruthaigh brainse nua ó "%s"`
|
|||||||
branch.renamed=Ainmníodh brainse %s go %s.
|
branch.renamed=Ainmníodh brainse %s go %s.
|
||||||
branch.rename_default_or_protected_branch_error=Ní féidir ach le riarthóirí brainsí réamhshocraithe nó cosanta a athainmniú.
|
branch.rename_default_or_protected_branch_error=Ní féidir ach le riarthóirí brainsí réamhshocraithe nó cosanta a athainmniú.
|
||||||
branch.rename_protected_branch_failed=Tá an brainse seo faoi chosaint ag rialacha cosanta domhanda.
|
branch.rename_protected_branch_failed=Tá an brainse seo faoi chosaint ag rialacha cosanta domhanda.
|
||||||
|
branch.commits_divergence_from=Déanann sé dialltacht a thiomnú: %[1]d taobh thiar agus %[2]d chun tosaigh ar %[3]s
|
||||||
|
branch.commits_no_divergence=Mar an gcéanna le brainse %[1]s
|
||||||
|
|
||||||
tag.create_tag=Cruthaigh clib %s
|
tag.create_tag=Cruthaigh clib %s
|
||||||
tag.create_tag_operation=Cruthaigh clib
|
tag.create_tag_operation=Cruthaigh clib
|
||||||
@ -2781,6 +2785,7 @@ topic.done=Déanta
|
|||||||
topic.count_prompt=Ní féidir leat níos mó ná 25 topaicí a roghnú
|
topic.count_prompt=Ní féidir leat níos mó ná 25 topaicí a roghnú
|
||||||
topic.format_prompt=Ní mór do thopaicí tosú le litir nó uimhir, is féidir daiseanna ('-') agus poncanna ('.') a áireamh, a bheith suas le 35 carachtar ar fad. Ní mór litreacha a bheith i litreacha beaga.
|
topic.format_prompt=Ní mór do thopaicí tosú le litir nó uimhir, is féidir daiseanna ('-') agus poncanna ('.') a áireamh, a bheith suas le 35 carachtar ar fad. Ní mór litreacha a bheith i litreacha beaga.
|
||||||
|
|
||||||
|
find_file.follow_symlink=Lean an nasc siombalach seo go dtí an áit a bhfuil sé ag pointeáil air
|
||||||
find_file.go_to_file=Téigh go dtí an comhad
|
find_file.go_to_file=Téigh go dtí an comhad
|
||||||
find_file.no_matching=Níl aon chomhad meaitseála le fáil
|
find_file.no_matching=Níl aon chomhad meaitseála le fáil
|
||||||
|
|
||||||
|
@ -956,7 +956,6 @@ settings.delete_notices_1=- Operasi ini <strong>TIDAK BISA</strong> dibatalkan.
|
|||||||
settings.delete_collaborator=Menghapus
|
settings.delete_collaborator=Menghapus
|
||||||
settings.teams=Tim
|
settings.teams=Tim
|
||||||
settings.add_webhook=Tambahkan Webhook
|
settings.add_webhook=Tambahkan Webhook
|
||||||
settings.webhook.test_delivery=Percobaan Pengiriman
|
|
||||||
settings.webhook.request=Permintaan
|
settings.webhook.request=Permintaan
|
||||||
settings.webhook.response=Tanggapan
|
settings.webhook.response=Tanggapan
|
||||||
settings.webhook.headers=Tajuk
|
settings.webhook.headers=Tajuk
|
||||||
|
@ -1720,8 +1720,6 @@ settings.hooks_desc=I Webhook effettuano automaticamente richieste HTTP POST ad
|
|||||||
settings.webhook_deletion=Rimuovi Webhook
|
settings.webhook_deletion=Rimuovi Webhook
|
||||||
settings.webhook_deletion_desc=Rimuovere un webhook rimuove le sue impostazioni e la sua cronologia di consegna. Continuare?
|
settings.webhook_deletion_desc=Rimuovere un webhook rimuove le sue impostazioni e la sua cronologia di consegna. Continuare?
|
||||||
settings.webhook_deletion_success=Il webhook è stato rimosso.
|
settings.webhook_deletion_success=Il webhook è stato rimosso.
|
||||||
settings.webhook.test_delivery=Test di consegna
|
|
||||||
settings.webhook.test_delivery_desc=Prova questo webhook con un evento falso.
|
|
||||||
settings.webhook.request=Richiesta
|
settings.webhook.request=Richiesta
|
||||||
settings.webhook.response=Risposta
|
settings.webhook.response=Risposta
|
||||||
settings.webhook.headers=Intestazioni
|
settings.webhook.headers=Intestazioni
|
||||||
|
@ -2323,8 +2323,6 @@ settings.hooks_desc=Webhookは、指定したGiteaイベントが発生したと
|
|||||||
settings.webhook_deletion=Webhookの削除
|
settings.webhook_deletion=Webhookの削除
|
||||||
settings.webhook_deletion_desc=Webhook設定と配信履歴が削除されます。 続行しますか?
|
settings.webhook_deletion_desc=Webhook設定と配信履歴が削除されます。 続行しますか?
|
||||||
settings.webhook_deletion_success=Webhookを削除しました。
|
settings.webhook_deletion_success=Webhookを削除しました。
|
||||||
settings.webhook.test_delivery=テスト配信
|
|
||||||
settings.webhook.test_delivery_desc=ダミーのイベントでこのWebhookをテストします。
|
|
||||||
settings.webhook.test_delivery_desc_disabled=このWebhookをダミーのイベントでテストするには、有効にしてください。
|
settings.webhook.test_delivery_desc_disabled=このWebhookをダミーのイベントでテストするには、有効にしてください。
|
||||||
settings.webhook.request=リクエスト
|
settings.webhook.request=リクエスト
|
||||||
settings.webhook.response=レスポンス
|
settings.webhook.response=レスポンス
|
||||||
|
@ -993,8 +993,6 @@ settings.teams=팀
|
|||||||
settings.add_webhook=Webhook 추가
|
settings.add_webhook=Webhook 추가
|
||||||
settings.webhook_deletion=Webhook 삭제
|
settings.webhook_deletion=Webhook 삭제
|
||||||
settings.webhook_deletion_success=Webhook을 삭제했습니다.
|
settings.webhook_deletion_success=Webhook을 삭제했습니다.
|
||||||
settings.webhook.test_delivery=전달 시험
|
|
||||||
settings.webhook.test_delivery_desc=이 웹훅을 가상 이벤트로 테스트
|
|
||||||
settings.webhook.request=요청
|
settings.webhook.request=요청
|
||||||
settings.webhook.response=응답
|
settings.webhook.response=응답
|
||||||
settings.webhook.headers=제목
|
settings.webhook.headers=제목
|
||||||
|
@ -2072,8 +2072,6 @@ settings.hooks_desc=Tīmekļa āķi ļauj paziņot ārējiem servisiem par notei
|
|||||||
settings.webhook_deletion=Noņemt tīmekļa āķi
|
settings.webhook_deletion=Noņemt tīmekļa āķi
|
||||||
settings.webhook_deletion_desc=Noņemot tīmekļa āķi, tiks dzēsti visi tā iestatījumi un piegādes vēsture. Vai turpināt?
|
settings.webhook_deletion_desc=Noņemot tīmekļa āķi, tiks dzēsti visi tā iestatījumi un piegādes vēsture. Vai turpināt?
|
||||||
settings.webhook_deletion_success=Tīmekļa āķis tika noņemts.
|
settings.webhook_deletion_success=Tīmekļa āķis tika noņemts.
|
||||||
settings.webhook.test_delivery=Testa piegāde
|
|
||||||
settings.webhook.test_delivery_desc=Veikt viltus push-notikuma piegādi, lai notestētu Jūsu tīmekļa āķa iestatījumus.
|
|
||||||
settings.webhook.test_delivery_desc_disabled=Lai pārbaudītu šo tīmekļa āķi ar neīstu notikumu, tas ir jāiespējo.
|
settings.webhook.test_delivery_desc_disabled=Lai pārbaudītu šo tīmekļa āķi ar neīstu notikumu, tas ir jāiespējo.
|
||||||
settings.webhook.request=Pieprasījums
|
settings.webhook.request=Pieprasījums
|
||||||
settings.webhook.response=Atbilde
|
settings.webhook.response=Atbilde
|
||||||
|
@ -1666,8 +1666,6 @@ settings.hooks_desc=Webhooks maken automatisch een HTTP POST verzoek naar een se
|
|||||||
settings.webhook_deletion=Verwijder webhook
|
settings.webhook_deletion=Verwijder webhook
|
||||||
settings.webhook_deletion_desc=Verwijderen van een webhook verwijdert de instellingen en de geschiedenis van afleveringen. Doorgaan?
|
settings.webhook_deletion_desc=Verwijderen van een webhook verwijdert de instellingen en de geschiedenis van afleveringen. Doorgaan?
|
||||||
settings.webhook_deletion_success=Webhook is verwijderd.
|
settings.webhook_deletion_success=Webhook is verwijderd.
|
||||||
settings.webhook.test_delivery=Test-bezorging
|
|
||||||
settings.webhook.test_delivery_desc=Test deze webhook met een nep-gebeurtenis.
|
|
||||||
settings.webhook.request=Verzoek
|
settings.webhook.request=Verzoek
|
||||||
settings.webhook.response=Antwoord
|
settings.webhook.response=Antwoord
|
||||||
settings.webhook.headers=Headers
|
settings.webhook.headers=Headers
|
||||||
|
@ -1553,8 +1553,6 @@ settings.hooks_desc=Webhooki automatycznie tworzą zapytania HTTP POST do serwer
|
|||||||
settings.webhook_deletion=Usuń Webhooka
|
settings.webhook_deletion=Usuń Webhooka
|
||||||
settings.webhook_deletion_desc=Usunięcie Webhooka wykasuje jego ustawienia i historię dostaw. Kontynuować?
|
settings.webhook_deletion_desc=Usunięcie Webhooka wykasuje jego ustawienia i historię dostaw. Kontynuować?
|
||||||
settings.webhook_deletion_success=Webhook został usunięty.
|
settings.webhook_deletion_success=Webhook został usunięty.
|
||||||
settings.webhook.test_delivery=Testuj dostawę
|
|
||||||
settings.webhook.test_delivery_desc=Sprawdź tego Webhooka przy pomocy testowego zdarzenia.
|
|
||||||
settings.webhook.request=Żądanie
|
settings.webhook.request=Żądanie
|
||||||
settings.webhook.response=Odpowiedź
|
settings.webhook.response=Odpowiedź
|
||||||
settings.webhook.headers=Nagłówki
|
settings.webhook.headers=Nagłówki
|
||||||
|
@ -2055,8 +2055,6 @@ settings.hooks_desc=Webhooks automaticamente fazem requisições de HTTP POST pa
|
|||||||
settings.webhook_deletion=Remover webhook
|
settings.webhook_deletion=Remover webhook
|
||||||
settings.webhook_deletion_desc=A exclusão de um webhook exclui suas configurações e o histórico de entrega. Continuar?
|
settings.webhook_deletion_desc=A exclusão de um webhook exclui suas configurações e o histórico de entrega. Continuar?
|
||||||
settings.webhook_deletion_success=O webhook foi removido.
|
settings.webhook_deletion_success=O webhook foi removido.
|
||||||
settings.webhook.test_delivery=Entrega de teste
|
|
||||||
settings.webhook.test_delivery_desc=Teste este webhook com um falso evento.
|
|
||||||
settings.webhook.request=Solicitação
|
settings.webhook.request=Solicitação
|
||||||
settings.webhook.response=Resposta
|
settings.webhook.response=Resposta
|
||||||
settings.webhook.headers=Cabeçalhos
|
settings.webhook.headers=Cabeçalhos
|
||||||
|
@ -1562,8 +1562,8 @@ issues.filter_project=Planeamento
|
|||||||
issues.filter_project_all=Todos os planeamentos
|
issues.filter_project_all=Todos os planeamentos
|
||||||
issues.filter_project_none=Nenhum planeamento
|
issues.filter_project_none=Nenhum planeamento
|
||||||
issues.filter_assignee=Encarregado
|
issues.filter_assignee=Encarregado
|
||||||
issues.filter_assignee_no_assignee=Não atribuído
|
issues.filter_assignee_no_assignee=Não atribuída
|
||||||
issues.filter_assignee_any_assignee=Atribuído a qualquer pessoa
|
issues.filter_assignee_any_assignee=Atribuída a alguém
|
||||||
issues.filter_poster=Autor(a)
|
issues.filter_poster=Autor(a)
|
||||||
issues.filter_user_placeholder=Procurar utilizadores
|
issues.filter_user_placeholder=Procurar utilizadores
|
||||||
issues.filter_user_no_select=Todos os utilizadores
|
issues.filter_user_no_select=Todos os utilizadores
|
||||||
@ -1969,6 +1969,7 @@ pulls.cmd_instruction_checkout_title=Checkout
|
|||||||
pulls.cmd_instruction_checkout_desc=A partir do seu repositório, crie um novo ramo e teste nele as modificações.
|
pulls.cmd_instruction_checkout_desc=A partir do seu repositório, crie um novo ramo e teste nele as modificações.
|
||||||
pulls.cmd_instruction_merge_title=Integrar
|
pulls.cmd_instruction_merge_title=Integrar
|
||||||
pulls.cmd_instruction_merge_desc=Integrar as modificações e enviar para o Gitea.
|
pulls.cmd_instruction_merge_desc=Integrar as modificações e enviar para o Gitea.
|
||||||
|
pulls.cmd_instruction_merge_warning=Aviso: Esta operação não pode executar pedidos de integração porque a opção "auto-identificar integração manual" não está habilitada.
|
||||||
pulls.clear_merge_message=Apagar mensagem de integração
|
pulls.clear_merge_message=Apagar mensagem de integração
|
||||||
pulls.clear_merge_message_hint=Apagar a mensagem de integração apenas remove o conteúdo da mensagem de cometimento e mantém os rodapés do git, tais como "Co-Autorado-Por …".
|
pulls.clear_merge_message_hint=Apagar a mensagem de integração apenas remove o conteúdo da mensagem de cometimento e mantém os rodapés do git, tais como "Co-Autorado-Por …".
|
||||||
|
|
||||||
@ -2333,8 +2334,6 @@ settings.hooks_desc=Os automatismos web fazem pedidos HTTP POST automaticamente
|
|||||||
settings.webhook_deletion=Remover automatismo web
|
settings.webhook_deletion=Remover automatismo web
|
||||||
settings.webhook_deletion_desc=Remover um automatismo web elimina as configurações e o histórico de entrega desse automatismo. Quer continuar?
|
settings.webhook_deletion_desc=Remover um automatismo web elimina as configurações e o histórico de entrega desse automatismo. Quer continuar?
|
||||||
settings.webhook_deletion_success=O automatismo web foi removido.
|
settings.webhook_deletion_success=O automatismo web foi removido.
|
||||||
settings.webhook.test_delivery=Entrega de teste
|
|
||||||
settings.webhook.test_delivery_desc=Testar este automatismo web com um evento falso.
|
|
||||||
settings.webhook.test_delivery_desc_disabled=Para testar este automatismo web com um evento falso, habilite-o.
|
settings.webhook.test_delivery_desc_disabled=Para testar este automatismo web com um evento falso, habilite-o.
|
||||||
settings.webhook.request=Pedido
|
settings.webhook.request=Pedido
|
||||||
settings.webhook.response=Resposta
|
settings.webhook.response=Resposta
|
||||||
@ -2354,6 +2353,7 @@ settings.payload_url=URL de destino
|
|||||||
settings.http_method=Método HTTP
|
settings.http_method=Método HTTP
|
||||||
settings.content_type=Tipo de conteúdo POST
|
settings.content_type=Tipo de conteúdo POST
|
||||||
settings.secret=Segredo
|
settings.secret=Segredo
|
||||||
|
settings.webhook_secret_desc=Se o servidor de automatismos web suportar a utilização de segredos, você pode seguir o manual do automatismo web e preencher um segredo aqui.
|
||||||
settings.slack_username=Nome de utilizador
|
settings.slack_username=Nome de utilizador
|
||||||
settings.slack_icon_url=URL do ícone
|
settings.slack_icon_url=URL do ícone
|
||||||
settings.slack_color=Cor
|
settings.slack_color=Cor
|
||||||
@ -2768,6 +2768,8 @@ branch.new_branch_from=`Criar um novo ramo a partir do ramo "%s"`
|
|||||||
branch.renamed=O ramo %s foi renomeado para %s.
|
branch.renamed=O ramo %s foi renomeado para %s.
|
||||||
branch.rename_default_or_protected_branch_error=Só os administradores é que podem renomear o ramo principal ou ramos protegidos.
|
branch.rename_default_or_protected_branch_error=Só os administradores é que podem renomear o ramo principal ou ramos protegidos.
|
||||||
branch.rename_protected_branch_failed=Este ramo está protegido por regras de salvaguarda baseadas em padrões glob.
|
branch.rename_protected_branch_failed=Este ramo está protegido por regras de salvaguarda baseadas em padrões glob.
|
||||||
|
branch.commits_divergence_from=Divergência nos cometimentos: %[1]d atrás e %[2]d à frente de %[3]s
|
||||||
|
branch.commits_no_divergence=Idêntico ao ramo %[1]s
|
||||||
|
|
||||||
tag.create_tag=Criar etiqueta %s
|
tag.create_tag=Criar etiqueta %s
|
||||||
tag.create_tag_operation=Criar etiqueta
|
tag.create_tag_operation=Criar etiqueta
|
||||||
@ -2781,6 +2783,7 @@ topic.done=Concluído
|
|||||||
topic.count_prompt=Não pode escolher mais do que 25 tópicos
|
topic.count_prompt=Não pode escolher mais do que 25 tópicos
|
||||||
topic.format_prompt=Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') ou pontos ('.') e podem ter até 35 caracteres. As letras têm que ser minúsculas.
|
topic.format_prompt=Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') ou pontos ('.') e podem ter até 35 caracteres. As letras têm que ser minúsculas.
|
||||||
|
|
||||||
|
find_file.follow_symlink=Seguir esta ligação simbólica para onde ela está apontando
|
||||||
find_file.go_to_file=Ir para o ficheiro
|
find_file.go_to_file=Ir para o ficheiro
|
||||||
find_file.no_matching=Não foi encontrado qualquer ficheiro correspondente
|
find_file.no_matching=Não foi encontrado qualquer ficheiro correspondente
|
||||||
|
|
||||||
|
@ -2025,8 +2025,6 @@ settings.hooks_desc=Веб-хуки позволяют внешним служб
|
|||||||
settings.webhook_deletion=Удалить веб-хук
|
settings.webhook_deletion=Удалить веб-хук
|
||||||
settings.webhook_deletion_desc=Удаление этого веб-хука приведет к удалению всей связанной с ним информации, включая историю. Хотите продолжить?
|
settings.webhook_deletion_desc=Удаление этого веб-хука приведет к удалению всей связанной с ним информации, включая историю. Хотите продолжить?
|
||||||
settings.webhook_deletion_success=Веб-хук был удалён.
|
settings.webhook_deletion_success=Веб-хук был удалён.
|
||||||
settings.webhook.test_delivery=Проверить доставку
|
|
||||||
settings.webhook.test_delivery_desc=Отправить тестовое событие для тестирования настройки веб-хука.
|
|
||||||
settings.webhook.request=Запрос
|
settings.webhook.request=Запрос
|
||||||
settings.webhook.response=Ответ
|
settings.webhook.response=Ответ
|
||||||
settings.webhook.headers=Заголовки
|
settings.webhook.headers=Заголовки
|
||||||
|
@ -1555,8 +1555,6 @@ settings.hooks_desc=ඇතැම් Gitea සිදුවීම් අවුල
|
|||||||
settings.webhook_deletion=වෙබ්හූක් ඉවත් කරන්න
|
settings.webhook_deletion=වෙබ්හූක් ඉවත් කරන්න
|
||||||
settings.webhook_deletion_desc=වෙබ්කොක්කක් ඉවත් කිරීම එහි සැකසුම් සහ බෙදාහැරීමේ ඉතිහාසය මකා දමයි. දිගටම?
|
settings.webhook_deletion_desc=වෙබ්කොක්කක් ඉවත් කිරීම එහි සැකසුම් සහ බෙදාහැරීමේ ඉතිහාසය මකා දමයි. දිගටම?
|
||||||
settings.webhook_deletion_success=වෙබ්කොක්කෙන් ඉවත් කර ඇත.
|
settings.webhook_deletion_success=වෙබ්කොක්කෙන් ඉවත් කර ඇත.
|
||||||
settings.webhook.test_delivery=ටෙස්ට් සැපයුම්
|
|
||||||
settings.webhook.test_delivery_desc=ව්යාජ සිදුවීමකින් මෙම වෙබ්කොක්කෙන් පරීක්ෂා කරන්න.
|
|
||||||
settings.webhook.request=ඉල්ලීම
|
settings.webhook.request=ඉල්ලීම
|
||||||
settings.webhook.response=ප්රතිචාරය
|
settings.webhook.response=ප්රතිචාරය
|
||||||
settings.webhook.headers=ශීර්ෂ
|
settings.webhook.headers=ශීර්ෂ
|
||||||
|
@ -1165,7 +1165,6 @@ settings.hooks_desc=Webhooky automaticky odosielajú požiadavky HTTP POST na se
|
|||||||
settings.webhook_deletion=Odstrániť webhook
|
settings.webhook_deletion=Odstrániť webhook
|
||||||
settings.webhook_deletion_desc=Odstránením webhooku sa vymažú jeho nastavenia a história doručovania. Ďalej?
|
settings.webhook_deletion_desc=Odstránením webhooku sa vymažú jeho nastavenia a história doručovania. Ďalej?
|
||||||
settings.webhook_deletion_success=Webhook bol odstránený.
|
settings.webhook_deletion_success=Webhook bol odstránený.
|
||||||
settings.webhook.test_delivery_desc=Otestujte tento webhook pomocou testovacej udalosti.
|
|
||||||
settings.webhook.replay.description=Zopakujte tento webhook.
|
settings.webhook.replay.description=Zopakujte tento webhook.
|
||||||
settings.add_webhook_desc=Gitea odošle požiadavky <code>POST</code> so špecifikovaným typom obsahu na cieľovú adresu URL. Prečítajte si viac v <a target="_blank" rel="noopener noreferrer" href="%s">sprievodcovi webhookmi</a>.
|
settings.add_webhook_desc=Gitea odošle požiadavky <code>POST</code> so špecifikovaným typom obsahu na cieľovú adresu URL. Prečítajte si viac v <a target="_blank" rel="noopener noreferrer" href="%s">sprievodcovi webhookmi</a>.
|
||||||
settings.event_header_repository=Udalosti repozitára
|
settings.event_header_repository=Udalosti repozitára
|
||||||
|
@ -1292,8 +1292,6 @@ settings.hooks_desc=Webhooks gör automatiskt ett HTTP POST anrop mot en server
|
|||||||
settings.webhook_deletion=Ta bort Webhook
|
settings.webhook_deletion=Ta bort Webhook
|
||||||
settings.webhook_deletion_desc=Borttagning utav en webhook tar även bort dess inställningar och leveranshistorik. Vill du fortsätta?
|
settings.webhook_deletion_desc=Borttagning utav en webhook tar även bort dess inställningar och leveranshistorik. Vill du fortsätta?
|
||||||
settings.webhook_deletion_success=Webhooken har blivit borttagen.
|
settings.webhook_deletion_success=Webhooken har blivit borttagen.
|
||||||
settings.webhook.test_delivery=Testa Leverans
|
|
||||||
settings.webhook.test_delivery_desc=Testa webhooken genom ett testevent.
|
|
||||||
settings.webhook.request=Begäran
|
settings.webhook.request=Begäran
|
||||||
settings.webhook.response=Svar
|
settings.webhook.response=Svar
|
||||||
settings.webhook.headers=Huvuden
|
settings.webhook.headers=Huvuden
|
||||||
|
@ -2310,8 +2310,6 @@ settings.hooks_desc=Web istemcileri, belirli Gitea olayları tetiklendiğinde ot
|
|||||||
settings.webhook_deletion=Web İsteğini Sil
|
settings.webhook_deletion=Web İsteğini Sil
|
||||||
settings.webhook_deletion_desc=Bir web isteğini kaldırmak, ayarlarını ve teslimat geçmişini siler. Devam edilsin mi?
|
settings.webhook_deletion_desc=Bir web isteğini kaldırmak, ayarlarını ve teslimat geçmişini siler. Devam edilsin mi?
|
||||||
settings.webhook_deletion_success=Web isteği silindi.
|
settings.webhook_deletion_success=Web isteği silindi.
|
||||||
settings.webhook.test_delivery=Test Dağıtımı
|
|
||||||
settings.webhook.test_delivery_desc=Bu web isteğini sahte bir olayla test edin.
|
|
||||||
settings.webhook.test_delivery_desc_disabled=Bu web istemcisini sahte bir olayla denemek için etkinleştirin.
|
settings.webhook.test_delivery_desc_disabled=Bu web istemcisini sahte bir olayla denemek için etkinleştirin.
|
||||||
settings.webhook.request=İstekler
|
settings.webhook.request=İstekler
|
||||||
settings.webhook.response=Cevaplar
|
settings.webhook.response=Cevaplar
|
||||||
|
@ -2215,8 +2215,6 @@ settings.hooks_desc=Веб-хуки автоматично роблять HTTP P
|
|||||||
settings.webhook_deletion=Видалити веб-хук
|
settings.webhook_deletion=Видалити веб-хук
|
||||||
settings.webhook_deletion_desc=Видалення веб-хука видаляє його налаштування та історію доставки. Продовжити?
|
settings.webhook_deletion_desc=Видалення веб-хука видаляє його налаштування та історію доставки. Продовжити?
|
||||||
settings.webhook_deletion_success=Веб-хук видалено.
|
settings.webhook_deletion_success=Веб-хук видалено.
|
||||||
settings.webhook.test_delivery=Перевірити доставку
|
|
||||||
settings.webhook.test_delivery_desc=Перевірте цей веб-хук з фальшивою подією.
|
|
||||||
settings.webhook.request=Запит
|
settings.webhook.request=Запит
|
||||||
settings.webhook.response=Відповідь
|
settings.webhook.response=Відповідь
|
||||||
settings.webhook.headers=Заголовки
|
settings.webhook.headers=Заголовки
|
||||||
|
@ -420,8 +420,9 @@ remember_me=记住此设备
|
|||||||
remember_me.compromised=登录令牌不再有效,因为它可能表明帐户已被破坏。请检查您的帐户是否有异常活动。
|
remember_me.compromised=登录令牌不再有效,因为它可能表明帐户已被破坏。请检查您的帐户是否有异常活动。
|
||||||
forgot_password_title=忘记密码
|
forgot_password_title=忘记密码
|
||||||
forgot_password=忘记密码?
|
forgot_password=忘记密码?
|
||||||
need_account=需要一个帐户?
|
need_account=需要一个帐户?
|
||||||
sign_up_now=还没账号?马上注册。
|
sign_up_tip=您正在系统中注册第一个帐户,它拥有管理员权限。请仔细记住您的用户名和密码。 如果您忘记了用户名或密码,请参阅 Gitea 文档以恢复账户。
|
||||||
|
sign_up_now=立即注册。
|
||||||
sign_up_successful=帐户创建成功。欢迎!
|
sign_up_successful=帐户创建成功。欢迎!
|
||||||
confirmation_mail_sent_prompt_ex=一封新的确认邮件已经发送到 <b>%s</b>。请在下一个 %s 中检查您的收件箱以完成注册流程。 如果您的注册邮箱地址不正确,您可以重新登录并更改它。
|
confirmation_mail_sent_prompt_ex=一封新的确认邮件已经发送到 <b>%s</b>。请在下一个 %s 中检查您的收件箱以完成注册流程。 如果您的注册邮箱地址不正确,您可以重新登录并更改它。
|
||||||
must_change_password=更新您的密码
|
must_change_password=更新您的密码
|
||||||
@ -485,7 +486,7 @@ sspi_auth_failed=SSPI 认证失败
|
|||||||
password_pwned=此密码出现在 <a target="_blank" rel="noopener noreferrer" href="%s">被盗密码</a> 列表上并且曾经被公开。 请使用另一个密码再试一次。
|
password_pwned=此密码出现在 <a target="_blank" rel="noopener noreferrer" href="%s">被盗密码</a> 列表上并且曾经被公开。 请使用另一个密码再试一次。
|
||||||
password_pwned_err=无法完成对 HaveIBeenPwned 的请求
|
password_pwned_err=无法完成对 HaveIBeenPwned 的请求
|
||||||
last_admin=您不能删除最后一个管理员。必须至少保留一个管理员。
|
last_admin=您不能删除最后一个管理员。必须至少保留一个管理员。
|
||||||
signin_passkey=使用密钥登录
|
signin_passkey=使用通行密钥登录
|
||||||
back_to_sign_in=返回登录页面
|
back_to_sign_in=返回登录页面
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
@ -518,7 +519,7 @@ register_success=注册成功
|
|||||||
issue_assigned.pull=@%[1]s 已将仓库 %[3]s 中的合并请求 %[2]s 指派给您
|
issue_assigned.pull=@%[1]s 已将仓库 %[3]s 中的合并请求 %[2]s 指派给您
|
||||||
issue_assigned.issue=@%[1]s 已将仓库 %[3]s 中的工单 %[2]s 指派给您
|
issue_assigned.issue=@%[1]s 已将仓库 %[3]s 中的工单 %[2]s 指派给您
|
||||||
|
|
||||||
issue.x_mentioned_you=<b>@%s</b> 提到了您:
|
issue.x_mentioned_you=<b>@%s</b> 提及了您:
|
||||||
issue.action.force_push=<b>%[1]s</b> 强制从 %[3]s 推送 <b>%[2]s</b> 至 [4]s。
|
issue.action.force_push=<b>%[1]s</b> 强制从 %[3]s 推送 <b>%[2]s</b> 至 [4]s。
|
||||||
issue.action.push_1=<b>@%[1]s</b> 推送了 %[3]d 个提交到 %[2]s
|
issue.action.push_1=<b>@%[1]s</b> 推送了 %[3]d 个提交到 %[2]s
|
||||||
issue.action.push_n=<b>@%[1]s</b> 推送了 %[3]d 个提交到 %[2]s
|
issue.action.push_n=<b>@%[1]s</b> 推送了 %[3]d 个提交到 %[2]s
|
||||||
@ -838,7 +839,7 @@ ssh_desc=这些 SSH 公钥已经关联到您的账号。相应的私钥拥有完
|
|||||||
principal_desc=这些 SSH 证书规则已关联到您的账号将允许完全访问您所有仓库。
|
principal_desc=这些 SSH 证书规则已关联到您的账号将允许完全访问您所有仓库。
|
||||||
gpg_desc=这些 GPG 公钥已经关联到您的账号。请妥善保管您的私钥因为他们将被用于认证提交。
|
gpg_desc=这些 GPG 公钥已经关联到您的账号。请妥善保管您的私钥因为他们将被用于认证提交。
|
||||||
ssh_helper=<strong>需要帮助?</strong> 请查看有关 <a href="%s">如何生成 SSH 密钥</a> 或 <a href="%s">常见 SSH 问题</a> 寻找答案。
|
ssh_helper=<strong>需要帮助?</strong> 请查看有关 <a href="%s">如何生成 SSH 密钥</a> 或 <a href="%s">常见 SSH 问题</a> 寻找答案。
|
||||||
gpg_helper=<strong>需要帮助吗?</strong>看一看 GitHub <a href="%s">关于 GPG</a> 的指导。
|
gpg_helper=<strong>需要帮助?</strong>看一看 GitHub <a href="%s">关于 GPG</a> 的指导。
|
||||||
add_new_key=增加 SSH 密钥
|
add_new_key=增加 SSH 密钥
|
||||||
add_new_gpg_key=添加的 GPG 密钥
|
add_new_gpg_key=添加的 GPG 密钥
|
||||||
key_content_ssh_placeholder=以 'ssh-ed25519'、 'ssh-rsa'、 'ecdsa-sha2-nistp256'、'ecdsa-sha2-nistp384'、'ecdsa-sha2-nistp521'、 'sk-ecdsa-sha2-nistp256@openssh.com' 或 'sk-ssh-ed25519@openssh.com' 开头
|
key_content_ssh_placeholder=以 'ssh-ed25519'、 'ssh-rsa'、 'ecdsa-sha2-nistp256'、'ecdsa-sha2-nistp384'、'ecdsa-sha2-nistp521'、 'sk-ecdsa-sha2-nistp256@openssh.com' 或 'sk-ssh-ed25519@openssh.com' 开头
|
||||||
@ -1016,10 +1017,10 @@ delete_account_title=删除当前帐户
|
|||||||
delete_account_desc=确实要永久删除此用户帐户吗?
|
delete_account_desc=确实要永久删除此用户帐户吗?
|
||||||
|
|
||||||
email_notifications.enable=启用邮件通知
|
email_notifications.enable=启用邮件通知
|
||||||
email_notifications.onmention=只在被提到时邮件通知
|
email_notifications.onmention=仅被提及时通知
|
||||||
email_notifications.disable=停用邮件通知
|
email_notifications.disable=停用邮件通知
|
||||||
email_notifications.submit=邮件通知设置
|
email_notifications.submit=设置邮件通知
|
||||||
email_notifications.andyourown=和您自己的通知
|
email_notifications.andyourown=仅与您相关的通知
|
||||||
|
|
||||||
visibility=用户可见性
|
visibility=用户可见性
|
||||||
visibility.public=公开
|
visibility.public=公开
|
||||||
@ -1061,6 +1062,7 @@ fork_no_valid_owners=这个代码仓库无法被派生,因为没有有效的
|
|||||||
fork.blocked_user=无法克隆仓库,因为您被仓库所有者屏蔽。
|
fork.blocked_user=无法克隆仓库,因为您被仓库所有者屏蔽。
|
||||||
use_template=使用此模板
|
use_template=使用此模板
|
||||||
open_with_editor=用 %s 打开
|
open_with_editor=用 %s 打开
|
||||||
|
|
||||||
download_zip=下载 ZIP
|
download_zip=下载 ZIP
|
||||||
download_tar=下载 TAR.GZ
|
download_tar=下载 TAR.GZ
|
||||||
download_bundle=下载 BUNDLE
|
download_bundle=下载 BUNDLE
|
||||||
@ -1070,12 +1072,12 @@ repo_desc=描述
|
|||||||
repo_desc_helper=输入简要描述 (可选)
|
repo_desc_helper=输入简要描述 (可选)
|
||||||
repo_no_desc=无详细信息
|
repo_no_desc=无详细信息
|
||||||
repo_lang=语言
|
repo_lang=语言
|
||||||
repo_gitignore_helper=选择 .gitignore 模板。
|
repo_gitignore_helper=选择 .gitignore 模板
|
||||||
repo_gitignore_helper_desc=从常见语言的模板列表中选择忽略跟踪的文件。默认情况下,由开发或构建工具生成的特殊文件都包含在 .gitignore 中。
|
repo_gitignore_helper_desc=从常见语言的模板列表中选择忽略跟踪的文件。默认情况下,由开发或构建工具生成的特殊文件都包含在 .gitignore 中。
|
||||||
issue_labels=工单标签
|
issue_labels=工单标签
|
||||||
issue_labels_helper=选择一个工单标签集
|
issue_labels_helper=选择一个工单标签集
|
||||||
license=授权许可
|
license=授权许可
|
||||||
license_helper=选择授权许可文件。
|
license_helper=选择授权许可文件
|
||||||
license_helper_desc=许可证说明了其他人可以和不可以用您的代码做什么。不确定哪一个适合您的项目?见 <a target="_blank" rel="noopener noreferrer" href="%s">选择一个许可证</a>
|
license_helper_desc=许可证说明了其他人可以和不可以用您的代码做什么。不确定哪一个适合您的项目?见 <a target="_blank" rel="noopener noreferrer" href="%s">选择一个许可证</a>
|
||||||
multiple_licenses=多许可证
|
multiple_licenses=多许可证
|
||||||
object_format=对象格式
|
object_format=对象格式
|
||||||
@ -1228,6 +1230,7 @@ migrate.migrating_issues=迁移工单
|
|||||||
migrate.migrating_pulls=迁移合并请求
|
migrate.migrating_pulls=迁移合并请求
|
||||||
migrate.cancel_migrating_title=取消迁移
|
migrate.cancel_migrating_title=取消迁移
|
||||||
migrate.cancel_migrating_confirm=您想要取消此次迁移吗?
|
migrate.cancel_migrating_confirm=您想要取消此次迁移吗?
|
||||||
|
migration_status=迁移状态
|
||||||
|
|
||||||
mirror_from=镜像自地址
|
mirror_from=镜像自地址
|
||||||
forked_from=派生自
|
forked_from=派生自
|
||||||
@ -1353,6 +1356,7 @@ editor.update=更新 %s
|
|||||||
editor.delete=删除 %s
|
editor.delete=删除 %s
|
||||||
editor.patch=应用补丁
|
editor.patch=应用补丁
|
||||||
editor.patching=打补丁:
|
editor.patching=打补丁:
|
||||||
|
editor.fail_to_apply_patch=无法应用补丁
|
||||||
editor.new_patch=新补丁
|
editor.new_patch=新补丁
|
||||||
editor.commit_message_desc=添加一个可选的扩展描述...
|
editor.commit_message_desc=添加一个可选的扩展描述...
|
||||||
editor.signoff_desc=在提交日志消息末尾添加签署人信息。
|
editor.signoff_desc=在提交日志消息末尾添加签署人信息。
|
||||||
@ -1372,6 +1376,7 @@ editor.branch_already_exists=此仓库已存在名为「%s」的分支。
|
|||||||
editor.directory_is_a_file=目录名「%s」已作为文件名在此仓库中存在。
|
editor.directory_is_a_file=目录名「%s」已作为文件名在此仓库中存在。
|
||||||
editor.file_is_a_symlink=`「%s」是一个符号链接,无法在 Web 编辑器中编辑`
|
editor.file_is_a_symlink=`「%s」是一个符号链接,无法在 Web 编辑器中编辑`
|
||||||
editor.filename_is_a_directory=文件名「%s」已作为目录名在此仓库中存在。
|
editor.filename_is_a_directory=文件名「%s」已作为目录名在此仓库中存在。
|
||||||
|
editor.file_modifying_no_longer_exists=正在修改的文件「%s」已不存在于此仓库。
|
||||||
editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。<a target="_blank" rel="noopener noreferrer" href="%s">单击此处</a> 查看变动的具体内容,或者 <strong>再次提交</strong> 覆盖已发生的变动。
|
editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。<a target="_blank" rel="noopener noreferrer" href="%s">单击此处</a> 查看变动的具体内容,或者 <strong>再次提交</strong> 覆盖已发生的变动。
|
||||||
editor.file_already_exists=此仓库已经存在名为「%s」的文件。
|
editor.file_already_exists=此仓库已经存在名为「%s」的文件。
|
||||||
editor.commit_id_not_matching=提交 ID 与您开始编辑时的 ID 不匹配。请提交到补丁分支然后合并。
|
editor.commit_id_not_matching=提交 ID 与您开始编辑时的 ID 不匹配。请提交到补丁分支然后合并。
|
||||||
@ -1392,7 +1397,15 @@ editor.user_no_push_to_branch=用户不能推送到分支
|
|||||||
editor.require_signed_commit=分支需要签名提交
|
editor.require_signed_commit=分支需要签名提交
|
||||||
editor.cherry_pick=拣选提交 %s 到:
|
editor.cherry_pick=拣选提交 %s 到:
|
||||||
editor.revert=将 %s 还原到:
|
editor.revert=将 %s 还原到:
|
||||||
|
editor.failed_to_commit=提交更改失败。
|
||||||
|
editor.failed_to_commit_summary=错误信息:
|
||||||
|
|
||||||
|
editor.fork_create=派生仓库发起请求变更
|
||||||
|
editor.fork_create_description=您不能直接编辑此仓库。您可以从此仓库派生,进行编辑并创建一个拉取请求。
|
||||||
|
editor.fork_edit_description=您不能直接编辑此仓库。 更改将写入您的派生仓库 <b>%s</b>,以便您可以创建一个拉取请求。
|
||||||
|
editor.fork_not_editable=你已经派生了这个仓库,但是你的分叉是不可编辑的。
|
||||||
|
editor.fork_failed_to_push_branch=推送分支 %s 到仓库失败。
|
||||||
|
editor.fork_branch_exists=分支 "%s" 已存在于您的派生仓库中,请选择一个新的分支名称。
|
||||||
|
|
||||||
commits.desc=浏览代码修改历史
|
commits.desc=浏览代码修改历史
|
||||||
commits.commits=次代码提交
|
commits.commits=次代码提交
|
||||||
@ -1714,6 +1727,8 @@ issues.remove_time_estimate_at=删除预估时间 %s
|
|||||||
issues.time_estimate_invalid=预计时间格式无效
|
issues.time_estimate_invalid=预计时间格式无效
|
||||||
issues.start_tracking_history=`开始工作 %s`
|
issues.start_tracking_history=`开始工作 %s`
|
||||||
issues.tracker_auto_close=当此工单关闭时,自动停止计时器
|
issues.tracker_auto_close=当此工单关闭时,自动停止计时器
|
||||||
|
issues.stopwatch_already_stopped=此工单的计时器已经停止
|
||||||
|
issues.stopwatch_already_created=此工单的计时器已经存在
|
||||||
issues.tracking_already_started=`您已经开始对 <a href="%s">另一个工单</a> 进行时间跟踪!`
|
issues.tracking_already_started=`您已经开始对 <a href="%s">另一个工单</a> 进行时间跟踪!`
|
||||||
issues.stop_tracking=停止计时器
|
issues.stop_tracking=停止计时器
|
||||||
issues.stop_tracking_history=工作 <b>%[1]s</b> 于 %[2]s 停止
|
issues.stop_tracking_history=工作 <b>%[1]s</b> 于 %[2]s 停止
|
||||||
@ -1955,6 +1970,7 @@ pulls.cmd_instruction_checkout_title=检出
|
|||||||
pulls.cmd_instruction_checkout_desc=从您的仓库中检出一个新的分支并测试变更。
|
pulls.cmd_instruction_checkout_desc=从您的仓库中检出一个新的分支并测试变更。
|
||||||
pulls.cmd_instruction_merge_title=合并
|
pulls.cmd_instruction_merge_title=合并
|
||||||
pulls.cmd_instruction_merge_desc=合并变更并更新到 Gitea 上
|
pulls.cmd_instruction_merge_desc=合并变更并更新到 Gitea 上
|
||||||
|
pulls.cmd_instruction_merge_warning=警告:此操作不能合并该合并请求,因为「自动检测手动合并」未启用
|
||||||
pulls.clear_merge_message=清除合并信息
|
pulls.clear_merge_message=清除合并信息
|
||||||
pulls.clear_merge_message_hint=清除合并消息只会删除提交消息内容,并保留生成的 Git 附加内容,如「Co-Authored-By…」。
|
pulls.clear_merge_message_hint=清除合并消息只会删除提交消息内容,并保留生成的 Git 附加内容,如「Co-Authored-By…」。
|
||||||
|
|
||||||
@ -2150,6 +2166,7 @@ settings.collaboration.write=可写权限
|
|||||||
settings.collaboration.read=可读权限
|
settings.collaboration.read=可读权限
|
||||||
settings.collaboration.owner=所有者
|
settings.collaboration.owner=所有者
|
||||||
settings.collaboration.undefined=未定义
|
settings.collaboration.undefined=未定义
|
||||||
|
settings.collaboration.per_unit=单元权限
|
||||||
settings.hooks=Web 钩子
|
settings.hooks=Web 钩子
|
||||||
settings.githooks=管理 Git 钩子
|
settings.githooks=管理 Git 钩子
|
||||||
settings.basic_settings=基本设置
|
settings.basic_settings=基本设置
|
||||||
@ -2318,8 +2335,6 @@ settings.hooks_desc=当 Gitea 事件发生时,Web 钩子自动发出 HTTP POST
|
|||||||
settings.webhook_deletion=删除 Web 钩子
|
settings.webhook_deletion=删除 Web 钩子
|
||||||
settings.webhook_deletion_desc=删除 Web 钩子将删除其设置和历史记录。继续?
|
settings.webhook_deletion_desc=删除 Web 钩子将删除其设置和历史记录。继续?
|
||||||
settings.webhook_deletion_success=Web 钩子删除成功!
|
settings.webhook_deletion_success=Web 钩子删除成功!
|
||||||
settings.webhook.test_delivery=测试推送
|
|
||||||
settings.webhook.test_delivery_desc=用假事件测试这个 Web 钩子。
|
|
||||||
settings.webhook.test_delivery_desc_disabled=要用假事件测试这个 Web钩子,请激活它。
|
settings.webhook.test_delivery_desc_disabled=要用假事件测试这个 Web钩子,请激活它。
|
||||||
settings.webhook.request=请求内容
|
settings.webhook.request=请求内容
|
||||||
settings.webhook.response=响应内容
|
settings.webhook.response=响应内容
|
||||||
@ -2368,6 +2383,7 @@ settings.event_repository=仓库
|
|||||||
settings.event_repository_desc=创建或删除仓库
|
settings.event_repository_desc=创建或删除仓库
|
||||||
settings.event_header_issue=工单事件
|
settings.event_header_issue=工单事件
|
||||||
settings.event_issues=工单
|
settings.event_issues=工单
|
||||||
|
settings.event_issues_desc=工单已打开、已关闭、已重新打开或已编辑。
|
||||||
settings.event_issue_assign=工单已指派
|
settings.event_issue_assign=工单已指派
|
||||||
settings.event_issue_assign_desc=工单已指派或取消指派。
|
settings.event_issue_assign_desc=工单已指派或取消指派。
|
||||||
settings.event_issue_label=工单增删标签
|
settings.event_issue_label=工单增删标签
|
||||||
@ -2378,6 +2394,7 @@ settings.event_issue_comment=工单评论
|
|||||||
settings.event_issue_comment_desc=工单评论已创建、编辑或删除。
|
settings.event_issue_comment_desc=工单评论已创建、编辑或删除。
|
||||||
settings.event_header_pull_request=合并请求事件
|
settings.event_header_pull_request=合并请求事件
|
||||||
settings.event_pull_request=合并请求
|
settings.event_pull_request=合并请求
|
||||||
|
settings.event_pull_request_desc=合并请求已打开、关闭、重新打开或编辑。
|
||||||
settings.event_pull_request_assign=合并请求已指派
|
settings.event_pull_request_assign=合并请求已指派
|
||||||
settings.event_pull_request_assign_desc=合并请求已指派或取消指派。
|
settings.event_pull_request_assign_desc=合并请求已指派或取消指派。
|
||||||
settings.event_pull_request_label=合并请求增删标签
|
settings.event_pull_request_label=合并请求增删标签
|
||||||
@ -2395,6 +2412,8 @@ settings.event_pull_request_review_request_desc=合并请求评审已请求或
|
|||||||
settings.event_pull_request_approvals=合并请求批准
|
settings.event_pull_request_approvals=合并请求批准
|
||||||
settings.event_pull_request_merge=合并请求合并
|
settings.event_pull_request_merge=合并请求合并
|
||||||
settings.event_header_workflow=工作流程事件
|
settings.event_header_workflow=工作流程事件
|
||||||
|
settings.event_workflow_run=工作流运行
|
||||||
|
settings.event_workflow_run_desc=Gitea 工作流队列中、等待中、正在进行或已完成的任务。
|
||||||
settings.event_workflow_job=工作流任务
|
settings.event_workflow_job=工作流任务
|
||||||
settings.event_workflow_job_desc=Gitea 工作流队列中、等待中、正在进行或已完成的任务。
|
settings.event_workflow_job_desc=Gitea 工作流队列中、等待中、正在进行或已完成的任务。
|
||||||
settings.event_package=软件包
|
settings.event_package=软件包
|
||||||
@ -2773,7 +2792,7 @@ error.broken_git_hook=此仓库的 Git 钩子似乎已损坏。 请按照 <a tar
|
|||||||
[graphs]
|
[graphs]
|
||||||
component_loading=正在加载 %s...
|
component_loading=正在加载 %s...
|
||||||
component_loading_failed=无法加载 %s
|
component_loading_failed=无法加载 %s
|
||||||
component_loading_info=这可能需要一点…
|
component_loading_info=这可能需要一点时间…
|
||||||
component_failed_to_load=意外的错误发生了。
|
component_failed_to_load=意外的错误发生了。
|
||||||
code_frequency.what=代码频率
|
code_frequency.what=代码频率
|
||||||
contributors.what=贡献
|
contributors.what=贡献
|
||||||
@ -2802,6 +2821,7 @@ team_permission_desc=权限
|
|||||||
team_unit_desc=允许访问仓库单元
|
team_unit_desc=允许访问仓库单元
|
||||||
team_unit_disabled=(已禁用)
|
team_unit_disabled=(已禁用)
|
||||||
|
|
||||||
|
form.name_been_taken=组织名称「%s」已经被占用。
|
||||||
form.name_reserved=组织名称「%s」是保留的。
|
form.name_reserved=组织名称「%s」是保留的。
|
||||||
form.name_pattern_not_allowed=组织名中不允许使用「%s」格式。
|
form.name_pattern_not_allowed=组织名中不允许使用「%s」格式。
|
||||||
form.create_org_not_allowed=此账号禁止创建组织
|
form.create_org_not_allowed=此账号禁止创建组织
|
||||||
@ -2824,12 +2844,27 @@ settings.visibility.private_shortname=私有
|
|||||||
settings.update_settings=更新组织设置
|
settings.update_settings=更新组织设置
|
||||||
settings.update_setting_success=组织设置已更新。
|
settings.update_setting_success=组织设置已更新。
|
||||||
|
|
||||||
|
settings.rename=修改组织名称
|
||||||
|
settings.rename_desc=更改组织名称同时会更改组织的 URL 地址并释放旧的名称。
|
||||||
|
settings.rename_success=组织 %[1]s 已成功重命名为 %[2]s。
|
||||||
|
settings.rename_no_change=组织名称没有变化。
|
||||||
|
settings.rename_new_org_name=新组织名称
|
||||||
|
settings.rename_failed=由于内部错误,重命名组织失败
|
||||||
|
settings.rename_notices_1=此操作 <strong>无法</strong> 被回滚。
|
||||||
|
settings.rename_notices_2=在被人使用前,旧名称将会被重定向。
|
||||||
|
|
||||||
settings.update_avatar_success=组织头像已经更新。
|
settings.update_avatar_success=组织头像已经更新。
|
||||||
settings.delete=删除组织
|
settings.delete=删除组织
|
||||||
settings.delete_account=删除当前组织
|
settings.delete_account=删除当前组织
|
||||||
settings.delete_prompt=删除操作会永久清除该组织的信息,并且 <strong>不可恢复</strong>!
|
settings.delete_prompt=删除操作会永久清除该组织的信息,并且 <strong>无法</strong> 恢复!
|
||||||
|
settings.name_confirm=输入组织名称以确认:
|
||||||
|
settings.delete_notices_1=此操作 <strong>无法</strong> 被回滚。
|
||||||
|
settings.delete_notices_2=此操作将永久删除 <strong>%s</strong> 的所有<strong>仓库</strong>,包括 Git 数据、 工单、评论、百科和协作者的操作权限。
|
||||||
|
settings.delete_notices_3=此操作将永久删除 <strong>%s</strong> 的所有 <strong>软件包</strong>。
|
||||||
|
settings.delete_notices_4=此操作将永久删除 <strong>%s</strong> 的所有 <strong>项目</strong>。
|
||||||
settings.confirm_delete_account=确认删除组织
|
settings.confirm_delete_account=确认删除组织
|
||||||
|
settings.delete_failed=由于内部错误,删除组织失败
|
||||||
|
settings.delete_successful=组织 <b>%s</b> 已成功删除。
|
||||||
settings.hooks_desc=在此处添加的 Web 钩子将会应用到该组织下的 <strong>所有仓库</strong>。
|
settings.hooks_desc=在此处添加的 Web 钩子将会应用到该组织下的 <strong>所有仓库</strong>。
|
||||||
|
|
||||||
settings.labels_desc=添加能够被该组织下的 <strong>所有仓库</strong> 的工单使用的标签。
|
settings.labels_desc=添加能够被该组织下的 <strong>所有仓库</strong> 的工单使用的标签。
|
||||||
@ -3720,8 +3755,8 @@ none=还没有密钥。
|
|||||||
; These keys are also for "edit secret", the keys are kept as-is to avoid unnecessary re-translation
|
; These keys are also for "edit secret", the keys are kept as-is to avoid unnecessary re-translation
|
||||||
creation.description=组织描述
|
creation.description=组织描述
|
||||||
creation.name_placeholder=不区分大小写,仅限字母数字或下划线且不能以 GITEA_ 或 GITHUB_ 开头
|
creation.name_placeholder=不区分大小写,仅限字母数字或下划线且不能以 GITEA_ 或 GITHUB_ 开头
|
||||||
creation.value_placeholder=输入任何内容,开头和结尾的空白将会被忽略。
|
creation.value_placeholder=输入任何内容,开头和结尾的空白将会被忽略
|
||||||
creation.description_placeholder=输入简短描述(可选)。
|
creation.description_placeholder=输入简短描述(可选)
|
||||||
|
|
||||||
save_success=密钥「%s」保存成功。
|
save_success=密钥「%s」保存成功。
|
||||||
save_failed=密钥保存失败。
|
save_failed=密钥保存失败。
|
||||||
@ -3806,6 +3841,7 @@ runs.no_runs=工作流尚未运行过。
|
|||||||
runs.empty_commit_message=(空白的提交消息)
|
runs.empty_commit_message=(空白的提交消息)
|
||||||
runs.expire_log_message=旧的日志已清除。
|
runs.expire_log_message=旧的日志已清除。
|
||||||
runs.delete=删除工作流运行
|
runs.delete=删除工作流运行
|
||||||
|
runs.cancel=取消工作流运行
|
||||||
runs.delete.description=您确定要永久删除此工作流运行吗?此操作无法撤消。
|
runs.delete.description=您确定要永久删除此工作流运行吗?此操作无法撤消。
|
||||||
runs.not_done=此工作流运行尚未完成。
|
runs.not_done=此工作流运行尚未完成。
|
||||||
runs.view_workflow_file=查看工作流文件
|
runs.view_workflow_file=查看工作流文件
|
||||||
|
@ -569,7 +569,6 @@ settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滾。
|
|||||||
settings.delete_collaborator=移除成員
|
settings.delete_collaborator=移除成員
|
||||||
settings.teams=組織團隊
|
settings.teams=組織團隊
|
||||||
settings.add_webhook=建立 Webhook
|
settings.add_webhook=建立 Webhook
|
||||||
settings.webhook.test_delivery=測試推送
|
|
||||||
settings.webhook.request=請求內容
|
settings.webhook.request=請求內容
|
||||||
settings.webhook.response=響應內容
|
settings.webhook.response=響應內容
|
||||||
settings.webhook.headers=標題
|
settings.webhook.headers=標題
|
||||||
|
@ -2255,8 +2255,6 @@ settings.hooks_desc=當觸發某些 Gitea 事件時,Webhook 會自動發出 HT
|
|||||||
settings.webhook_deletion=移除 Webhook
|
settings.webhook_deletion=移除 Webhook
|
||||||
settings.webhook_deletion_desc=移除 Webhook 將刪除它的設定及傳送記錄,是否繼續?
|
settings.webhook_deletion_desc=移除 Webhook 將刪除它的設定及傳送記錄,是否繼續?
|
||||||
settings.webhook_deletion_success=Webhook 已移除。
|
settings.webhook_deletion_success=Webhook 已移除。
|
||||||
settings.webhook.test_delivery=傳送測試資料
|
|
||||||
settings.webhook.test_delivery_desc=使用假事件測試此 Webhook。
|
|
||||||
settings.webhook.test_delivery_desc_disabled=要使用假事件測試此 Webhook,請啟用它。
|
settings.webhook.test_delivery_desc_disabled=要使用假事件測試此 Webhook,請啟用它。
|
||||||
settings.webhook.request=請求
|
settings.webhook.request=請求
|
||||||
settings.webhook.response=回應
|
settings.webhook.response=回應
|
||||||
|
1592
package-lock.json
generated
53
package.json
@ -12,12 +12,12 @@
|
|||||||
"@github/relative-time-element": "4.4.8",
|
"@github/relative-time-element": "4.4.8",
|
||||||
"@github/text-expander-element": "2.9.2",
|
"@github/text-expander-element": "2.9.2",
|
||||||
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
|
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
|
||||||
"@primer/octicons": "19.15.2",
|
"@primer/octicons": "19.15.3",
|
||||||
"@silverwind/vue3-calendar-heatmap": "2.0.6",
|
"@silverwind/vue3-calendar-heatmap": "2.0.6",
|
||||||
"add-asset-webpack-plugin": "3.0.0",
|
"add-asset-webpack-plugin": "3.0.0",
|
||||||
"ansi_up": "6.0.6",
|
"ansi_up": "6.0.6",
|
||||||
"asciinema-player": "3.10.0",
|
"asciinema-player": "3.10.0",
|
||||||
"chart.js": "4.4.9",
|
"chart.js": "4.5.0",
|
||||||
"chartjs-adapter-dayjs-4": "1.0.4",
|
"chartjs-adapter-dayjs-4": "1.0.4",
|
||||||
"chartjs-plugin-zoom": "2.2.0",
|
"chartjs-plugin-zoom": "2.2.0",
|
||||||
"clippie": "4.1.7",
|
"clippie": "4.1.7",
|
||||||
@ -27,26 +27,25 @@
|
|||||||
"dropzone": "6.0.0-beta.2",
|
"dropzone": "6.0.0-beta.2",
|
||||||
"easymde": "2.20.0",
|
"easymde": "2.20.0",
|
||||||
"esbuild-loader": "4.3.0",
|
"esbuild-loader": "4.3.0",
|
||||||
"escape-goat": "4.0.0",
|
|
||||||
"fast-glob": "3.3.3",
|
"fast-glob": "3.3.3",
|
||||||
"htmx.org": "2.0.6",
|
"htmx.org": "2.0.6",
|
||||||
"idiomorph": "0.7.3",
|
"idiomorph": "0.7.3",
|
||||||
"jquery": "3.7.1",
|
"jquery": "3.7.1",
|
||||||
"katex": "0.16.22",
|
"katex": "0.16.22",
|
||||||
"license-checker-webpack-plugin": "0.2.1",
|
"license-checker-webpack-plugin": "0.2.1",
|
||||||
"mermaid": "11.6.0",
|
"mermaid": "11.8.0",
|
||||||
"mini-css-extract-plugin": "2.9.2",
|
"mini-css-extract-plugin": "2.9.2",
|
||||||
"minimatch": "10.0.2",
|
"minimatch": "10.0.3",
|
||||||
"monaco-editor": "0.52.2",
|
"monaco-editor": "0.52.2",
|
||||||
"monaco-editor-webpack-plugin": "7.1.0",
|
"monaco-editor-webpack-plugin": "7.1.0",
|
||||||
"online-3d-viewer": "0.16.0",
|
"online-3d-viewer": "0.16.0",
|
||||||
"pdfobject": "2.3.1",
|
"pdfobject": "2.3.1",
|
||||||
"perfect-debounce": "1.0.0",
|
"perfect-debounce": "1.0.0",
|
||||||
"postcss": "8.5.5",
|
"postcss": "8.5.6",
|
||||||
"postcss-loader": "8.1.1",
|
"postcss-loader": "8.1.1",
|
||||||
"postcss-nesting": "13.0.2",
|
"postcss-nesting": "13.0.2",
|
||||||
"sortablejs": "1.15.6",
|
"sortablejs": "1.15.6",
|
||||||
"swagger-ui-dist": "5.24.1",
|
"swagger-ui-dist": "5.26.0",
|
||||||
"tailwindcss": "3.4.17",
|
"tailwindcss": "3.4.17",
|
||||||
"throttle-debounce": "5.0.2",
|
"throttle-debounce": "5.0.2",
|
||||||
"tinycolor2": "1.6.0",
|
"tinycolor2": "1.6.0",
|
||||||
@ -56,7 +55,7 @@
|
|||||||
"typescript": "5.8.3",
|
"typescript": "5.8.3",
|
||||||
"uint8-to-base64": "0.2.1",
|
"uint8-to-base64": "0.2.1",
|
||||||
"vanilla-colorful": "0.7.2",
|
"vanilla-colorful": "0.7.2",
|
||||||
"vue": "3.5.16",
|
"vue": "3.5.17",
|
||||||
"vue-bar-graph": "2.2.0",
|
"vue-bar-graph": "2.2.0",
|
||||||
"vue-chartjs": "5.3.2",
|
"vue-chartjs": "5.3.2",
|
||||||
"vue-loader": "17.4.2",
|
"vue-loader": "17.4.2",
|
||||||
@ -66,55 +65,55 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint-community/eslint-plugin-eslint-comments": "4.5.0",
|
"@eslint-community/eslint-plugin-eslint-comments": "4.5.0",
|
||||||
"@playwright/test": "1.53.0",
|
"@playwright/test": "1.53.2",
|
||||||
"@stoplight/spectral-cli": "6.15.0",
|
"@stoplight/spectral-cli": "6.15.0",
|
||||||
"@stylistic/eslint-plugin-js": "3.1.0",
|
"@stylistic/eslint-plugin-js": "3.1.0",
|
||||||
"@stylistic/stylelint-plugin": "3.1.2",
|
"@stylistic/stylelint-plugin": "3.1.3",
|
||||||
"@types/dropzone": "5.7.9",
|
"@types/dropzone": "5.7.9",
|
||||||
"@types/jquery": "3.5.32",
|
"@types/jquery": "3.5.32",
|
||||||
"@types/katex": "0.16.7",
|
"@types/katex": "0.16.7",
|
||||||
"@types/license-checker-webpack-plugin": "0.2.4",
|
"@types/license-checker-webpack-plugin": "0.2.5",
|
||||||
"@types/pdfobject": "2.2.5",
|
"@types/pdfobject": "2.2.5",
|
||||||
"@types/sortablejs": "1.15.8",
|
"@types/sortablejs": "1.15.8",
|
||||||
"@types/swagger-ui-dist": "3.30.5",
|
"@types/swagger-ui-dist": "3.30.6",
|
||||||
"@types/throttle-debounce": "5.0.2",
|
"@types/throttle-debounce": "5.0.2",
|
||||||
"@types/tinycolor2": "1.4.6",
|
"@types/tinycolor2": "1.4.6",
|
||||||
"@types/toastify-js": "1.12.4",
|
"@types/toastify-js": "1.12.4",
|
||||||
"@typescript-eslint/eslint-plugin": "8.34.0",
|
"@typescript-eslint/eslint-plugin": "8.35.1",
|
||||||
"@typescript-eslint/parser": "8.34.0",
|
"@typescript-eslint/parser": "8.35.1",
|
||||||
"@vitejs/plugin-vue": "5.2.4",
|
"@vitejs/plugin-vue": "6.0.0",
|
||||||
"@vitest/eslint-plugin": "1.2.2",
|
"@vitest/eslint-plugin": "1.3.4",
|
||||||
"eslint": "8.57.0",
|
"eslint": "8.57.0",
|
||||||
"eslint-import-resolver-typescript": "4.4.3",
|
"eslint-import-resolver-typescript": "4.4.4",
|
||||||
"eslint-plugin-array-func": "4.0.0",
|
"eslint-plugin-array-func": "4.0.0",
|
||||||
"eslint-plugin-github": "5.0.2",
|
"eslint-plugin-github": "5.0.2",
|
||||||
"eslint-plugin-import-x": "4.15.2",
|
"eslint-plugin-import-x": "4.16.1",
|
||||||
"eslint-plugin-no-jquery": "3.1.1",
|
"eslint-plugin-no-jquery": "3.1.1",
|
||||||
"eslint-plugin-no-use-extend-native": "0.5.0",
|
"eslint-plugin-no-use-extend-native": "0.5.0",
|
||||||
"eslint-plugin-playwright": "2.2.0",
|
"eslint-plugin-playwright": "2.2.0",
|
||||||
"eslint-plugin-regexp": "2.9.0",
|
"eslint-plugin-regexp": "2.9.0",
|
||||||
"eslint-plugin-sonarjs": "3.0.2",
|
"eslint-plugin-sonarjs": "3.0.4",
|
||||||
"eslint-plugin-unicorn": "56.0.1",
|
"eslint-plugin-unicorn": "56.0.1",
|
||||||
"eslint-plugin-vue": "10.2.0",
|
"eslint-plugin-vue": "10.3.0",
|
||||||
"eslint-plugin-vue-scoped-css": "2.10.0",
|
"eslint-plugin-vue-scoped-css": "2.11.0",
|
||||||
"eslint-plugin-wc": "3.0.1",
|
"eslint-plugin-wc": "3.0.1",
|
||||||
"happy-dom": "18.0.1",
|
"happy-dom": "18.0.1",
|
||||||
"markdownlint-cli": "0.45.0",
|
"markdownlint-cli": "0.45.0",
|
||||||
"material-icon-theme": "5.23.0",
|
"material-icon-theme": "5.24.0",
|
||||||
"nolyfill": "1.0.44",
|
"nolyfill": "1.0.44",
|
||||||
"postcss-html": "1.8.0",
|
"postcss-html": "1.8.0",
|
||||||
"stylelint": "16.20.0",
|
"stylelint": "16.21.1",
|
||||||
"stylelint-config-recommended": "16.0.0",
|
"stylelint-config-recommended": "16.0.0",
|
||||||
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
|
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
|
||||||
"stylelint-declaration-strict-value": "1.10.11",
|
"stylelint-declaration-strict-value": "1.10.11",
|
||||||
"stylelint-define-config": "16.19.0",
|
"stylelint-define-config": "16.21.0",
|
||||||
"stylelint-value-no-unknown-custom-properties": "6.0.1",
|
"stylelint-value-no-unknown-custom-properties": "6.0.1",
|
||||||
"svgo": "3.3.2",
|
"svgo": "4.0.0",
|
||||||
"type-fest": "4.41.0",
|
"type-fest": "4.41.0",
|
||||||
"updates": "16.4.2",
|
"updates": "16.4.2",
|
||||||
"vite-string-plugin": "1.4.4",
|
"vite-string-plugin": "1.4.4",
|
||||||
"vitest": "3.2.3",
|
"vitest": "3.2.4",
|
||||||
"vue-tsc": "2.2.10"
|
"vue-tsc": "3.0.1"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"defaults"
|
"defaults"
|
||||||
|
2
public/assets/img/svg/gitea-chef.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" class="svg gitea-chef" width="16" height="16" aria-hidden="true"><g fill="none" fill-rule="evenodd"><path fill="#435363" d="M18 25.8c-4.3 0-7.7-3.6-7.7-8s3.4-7.9 7.7-7.9c3.5 0 6.4 2.4 7.3 5.7h3c-1-5-5.2-8.7-10.3-8.7-5.9 0-10.6 4.9-10.6 10.9 0 6.1 4.7 11 10.6 11 5.1 0 9.3-3.7 10.3-8.7h-3c-.9 3.3-3.8 5.7-7.3 5.7"/><path fill="#435363" d="M12.8 23.2c1.3 1.4 3.1 2.3 5.2 2.3v-3.2c-1.2 0-2.3-.5-3.1-1.3z"/><path fill="#F38B00" d="M10.6 17.8c0 1.1.3 2.2.6 3.1l2.9-1.3c-.3-.5-.4-1.1-.4-1.8 0-2.4 1.9-4.4 4.3-4.4v-3.2c-4.1 0-7.4 3.4-7.4 7.6"/><path fill="#435363" d="m20.6 10.7-1.1 3c.9.4 1.7 1.1 2.2 1.9H25c-.7-2.2-2.3-4-4.4-4.9"/><path fill="#F38B00" d="m19.5 22 1.1 2.9c2.1-.8 3.7-2.6 4.4-4.8h-3.3c-.5.8-1.3 1.5-2.2 1.9"/><path fill="#435363" d="M4.4 22.1c-.1-.2-.1-.3-.1-.5-.1-.2-.1-.3-.2-.5V21c0-.1 0-.3-.1-.4v-.5c-.1-.1-.1-.2-.1-.3-.1-.6-.1-1.3-.1-2H.9c0 .8 0 1.5.1 2.2 0 .2.1.4.1.6v.1c0 .2.1.4.1.5s0 .2.1.3v.3c.1.1.1.2.1.4 0 0 .1.1.1.2 0 .2 0 .3.1.4v.2c.2.7.5 1.3.7 2L5 23.8c-.2-.6-.4-1.1-.6-1.7"/><path fill="#F38B00" d="M18 32.6c-3.9 0-7.5-1.7-10.1-4.4l-2 2.2c3.1 3.2 7.3 5.2 12.1 5.2 8.7 0 15.8-6.8 16.9-15.5H32c-1.1 7-7 12.5-14 12.5M18 3.1c3.1 0 6.1 1.1 8.4 2.9l1.8-2.4C25.3 1.4 21.8.1 18 .1 10.7.1 4.5 4.8 2.1 11.4l2.7 1.1C6.8 7 12 3.1 18 3.1"/><path fill="#435363" d="M32 15.6h2.9c-.3-2.6-1.2-5-2.5-7.2L30 10c1 1.7 1.7 3.6 2 5.6"/><path fill="#F38B00" d="M28.7 15.6h2.9c-.8-5.1-4.1-9.3-8.6-11.1l-1.1 2.8c3.5 1.3 6 4.5 6.8 8.3"/><path fill="#435363" d="M18 6.5v-3c-5.9 0-10.9 3.8-12.9 9.1l2.7 1.1C9.4 9.5 13.3 6.5 18 6.5"/><path fill="#F38B00" d="M7 17.8H4.1c0 6.1 3.6 11.2 8.7 13.4l1.1-2.8C9.9 26.7 7 22.6 7 17.8"/><path fill="#435363" d="M18 29.2v3c6.9 0 12.6-5.3 13.6-12.1h-2.9c-1 5.2-5.4 9.1-10.7 9.1"/></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" class="svg gitea-chef" width="16" height="16" aria-hidden="true"><g fill="none" fill-rule="evenodd"><path fill="#435363" d="M18 25.8c-4.3 0-7.7-3.6-7.7-8s3.4-7.9 7.7-7.9c3.5 0 6.4 2.4 7.3 5.7h3c-1-5-5.2-8.7-10.3-8.7-5.9 0-10.6 4.9-10.6 10.9 0 6.1 4.7 11 10.6 11 5.1 0 9.3-3.7 10.3-8.7h-3c-.9 3.3-3.8 5.7-7.3 5.7"/><path fill="#435363" d="M12.8 23.2c1.3 1.4 3.1 2.3 5.2 2.3v-3.2c-1.2 0-2.3-.5-3.1-1.3z"/><path fill="#f38b00" d="M10.6 17.8c0 1.1.3 2.2.6 3.1l2.9-1.3c-.3-.5-.4-1.1-.4-1.8 0-2.4 1.9-4.4 4.3-4.4v-3.2c-4.1 0-7.4 3.4-7.4 7.6"/><path fill="#435363" d="m20.6 10.7-1.1 3c.9.4 1.7 1.1 2.2 1.9H25c-.7-2.2-2.3-4-4.4-4.9"/><path fill="#f38b00" d="m19.5 22 1.1 2.9c2.1-.8 3.7-2.6 4.4-4.8h-3.3c-.5.8-1.3 1.5-2.2 1.9"/><path fill="#435363" d="M4.4 22.1c-.1-.2-.1-.3-.1-.5-.1-.2-.1-.3-.2-.5V21c0-.1 0-.3-.1-.4v-.5c-.1-.1-.1-.2-.1-.3-.1-.6-.1-1.3-.1-2H.9c0 .8 0 1.5.1 2.2 0 .2.1.4.1.6v.1c0 .2.1.4.1.5s0 .2.1.3v.3c.1.1.1.2.1.4 0 0 .1.1.1.2 0 .2 0 .3.1.4v.2c.2.7.5 1.3.7 2L5 23.8c-.2-.6-.4-1.1-.6-1.7"/><path fill="#f38b00" d="M18 32.6c-3.9 0-7.5-1.7-10.1-4.4l-2 2.2c3.1 3.2 7.3 5.2 12.1 5.2 8.7 0 15.8-6.8 16.9-15.5H32c-1.1 7-7 12.5-14 12.5M18 3.1c3.1 0 6.1 1.1 8.4 2.9l1.8-2.4C25.3 1.4 21.8.1 18 .1 10.7.1 4.5 4.8 2.1 11.4l2.7 1.1C6.8 7 12 3.1 18 3.1"/><path fill="#435363" d="M32 15.6h2.9c-.3-2.6-1.2-5-2.5-7.2L30 10c1 1.7 1.7 3.6 2 5.6"/><path fill="#f38b00" d="M28.7 15.6h2.9c-.8-5.1-4.1-9.3-8.6-11.1l-1.1 2.8c3.5 1.3 6 4.5 6.8 8.3"/><path fill="#435363" d="M18 6.5v-3c-5.9 0-10.9 3.8-12.9 9.1l2.7 1.1C9.4 9.5 13.3 6.5 18 6.5"/><path fill="#f38b00" d="M7 17.8H4.1c0 6.1 3.6 11.2 8.7 13.4l1.1-2.8C9.9 26.7 7 22.6 7 17.8"/><path fill="#435363" d="M18 29.2v3c6.9 0 12.6-5.3 13.6-12.1h-2.9c-1 5.2-5.4 9.1-10.7 9.1"/></g></svg>
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
2
public/assets/img/svg/gitea-codecommit.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 100 100" class="svg gitea-codecommit" width="16" height="16" aria-hidden="true"><g fill="none" fill-rule="evenodd"><path fill="#C925D1" d="M0 0h80v80H0z"/><path fill="#FFF" d="M26.628 28.105h-2.017v-6.982c0-.558.36-.99.926-.99l7.144-.007v1.994H27.95l4.862 4.819-1.445 1.434-4.806-4.728zm28.07 10.867 1.869.827-6.541 14.446-1.868-.827zm1.311 10.493 4.003-2.89-3.526-3.535 1.458-1.422 4.36 4.373a1.002 1.002 0 0 1-.126 1.527l-4.963 3.58zm-9.043-8.802 1.205 1.633-4.061 2.932 3.538 3.536-1.454 1.424-4.374-4.373a1 1 0 0 1 .124-1.528zM69 24.13v42.858c0 .56-.458 1.012-1.024 1.012h-31.26c-.272 0-.53-.107-.723-.297a.96.96 0 0 1-.285-.7V55.034h2.018v10.971h29.256V25.113H37.726v-1.995h30.25c.566 0 1.024.453 1.024 1.012M33.182 34.588c0-1.927 1.585-3.495 3.535-3.495s3.535 1.568 3.535 3.495-1.585 3.495-3.535 3.495-3.535-1.568-3.535-3.495M17.549 66.009c-1.95 0-3.535-1.568-3.535-3.495s1.585-3.494 3.535-3.494 3.535 1.567 3.535 3.494-1.585 3.495-3.535 3.495m-3.535-23.442c0-1.927 1.585-3.495 3.535-3.495 1.982 0 3.535 1.535 3.535 3.495 0 1.927-1.585 3.495-3.535 3.495s-3.535-1.568-3.535-3.495m.004-25.081c0-1.925 1.584-3.491 3.53-3.491 1.948 0 3.532 1.566 3.532 3.49s-1.584 3.491-3.531 3.491-3.531-1.566-3.531-3.49m23.708 29.762v-7.276c2.57-.477 4.535-2.708 4.535-5.384 0-3.022-2.487-5.482-5.544-5.482s-5.545 2.46-5.545 5.482c0 2.676 1.966 4.907 4.536 5.384v7.276c0 1.163-.786 2.218-1.98 2.686l-10.451 4.1c-1.673.657-2.903 1.948-3.434 3.496-.433-.195-.801-.336-1.285-.416v-9.146c2.623-.433 4.535-2.687 4.535-5.401 0-2.764-1.878-4.972-4.535-5.393V22.889c2.626-.431 4.54-2.688 4.54-5.403 0-3.025-2.49-5.486-5.55-5.486S12 14.46 12 17.486c0 2.64 2.022 4.85 4.54 5.369v14.347c-2.515.518-4.536 2.727-4.536 5.365s2.02 4.846 4.536 5.365v9.217c-2.515.52-4.536 2.727-4.536 5.365 0 3.022 2.488 5.482 5.545 5.482s5.544-2.46 5.544-5.482a5.43 5.43 0 0 0-1.458-3.693c.167-1.27 1.066-2.384 2.397-2.905l10.45-4.1c1.98-.777 3.244-2.57 3.244-4.568"/></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 100 100" class="svg gitea-codecommit" width="16" height="16" aria-hidden="true"><g fill="none" fill-rule="evenodd"><path fill="#c925d1" d="M0 0h80v80H0z"/><path fill="#fff" d="M26.628 28.105h-2.017v-6.982c0-.558.36-.99.926-.99l7.144-.007v1.994H27.95l4.862 4.819-1.445 1.434-4.806-4.728zm28.07 10.867 1.869.827-6.541 14.446-1.868-.827zm1.311 10.493 4.003-2.89-3.526-3.535 1.458-1.422 4.36 4.373a1.002 1.002 0 0 1-.126 1.527l-4.963 3.58zm-9.043-8.802 1.205 1.633-4.061 2.932 3.538 3.536-1.454 1.424-4.374-4.373a1 1 0 0 1 .124-1.528zM69 24.13v42.858c0 .56-.458 1.012-1.024 1.012h-31.26c-.272 0-.53-.107-.723-.297a.96.96 0 0 1-.285-.7V55.034h2.018v10.971h29.256V25.113H37.726v-1.995h30.25c.566 0 1.024.453 1.024 1.012M33.182 34.588c0-1.927 1.585-3.495 3.535-3.495s3.535 1.568 3.535 3.495-1.585 3.495-3.535 3.495-3.535-1.568-3.535-3.495M17.549 66.009c-1.95 0-3.535-1.568-3.535-3.495s1.585-3.494 3.535-3.494 3.535 1.567 3.535 3.494-1.585 3.495-3.535 3.495m-3.535-23.442c0-1.927 1.585-3.495 3.535-3.495 1.982 0 3.535 1.535 3.535 3.495 0 1.927-1.585 3.495-3.535 3.495s-3.535-1.568-3.535-3.495m.004-25.081c0-1.925 1.584-3.491 3.53-3.491 1.948 0 3.532 1.566 3.532 3.49s-1.584 3.491-3.531 3.491-3.531-1.566-3.531-3.49m23.708 29.762v-7.276c2.57-.477 4.535-2.708 4.535-5.384 0-3.022-2.487-5.482-5.544-5.482s-5.545 2.46-5.545 5.482c0 2.676 1.966 4.907 4.536 5.384v7.276c0 1.163-.786 2.218-1.98 2.686l-10.451 4.1c-1.673.657-2.903 1.948-3.434 3.496-.433-.195-.801-.336-1.285-.416v-9.146c2.623-.433 4.535-2.687 4.535-5.401 0-2.764-1.878-4.972-4.535-5.393V22.889c2.626-.431 4.54-2.688 4.54-5.403 0-3.025-2.49-5.486-5.55-5.486S12 14.46 12 17.486c0 2.64 2.022 4.85 4.54 5.369v14.347c-2.515.518-4.536 2.727-4.536 5.365s2.02 4.846 4.536 5.365v9.217c-2.515.52-4.536 2.727-4.536 5.365 0 3.022 2.488 5.482 5.545 5.482s5.544-2.46 5.544-5.482a5.43 5.43 0 0 0-1.458-3.693c.167-1.27 1.066-2.384 2.397-2.905l10.45-4.1c1.98-.777 3.244-2.57 3.244-4.568"/></g></svg>
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
2
public/assets/img/svg/gitea-debian.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 260" class="svg gitea-debian" width="16" height="16" aria-hidden="true"><g fill="#D70751"><path d="M124.525 137.053c-4.125.058.78 2.125 6.165 2.954a55 55 0 0 0 4.04-3.479c-3.354.821-6.765.838-10.205.525m22.14-5.52c2.457-3.389 4.246-7.102 4.878-10.939-.551 2.736-2.035 5.099-3.435 7.592-7.711 4.854-.726-2.883-.004-5.824-8.29 10.436-1.138 6.257-1.439 9.171m8.174-21.265c.497-7.428-1.462-5.08-2.121-2.245.766.4 1.377 5.237 2.121 2.245M108.883 8.736c2.201.395 4.757.698 4.398 1.224 2.407-.528 2.954-1.015-4.398-1.224M113.281 9.96l-1.556.32 1.448-.127z"/><path d="M181.93 113.085c.247 6.671-1.95 9.907-3.932 15.637l-3.564 1.781c-2.919 5.666.282 3.598-1.807 8.105-4.556 4.049-13.823 12.67-16.789 13.457-2.163-.047 1.469-2.554 1.943-3.537-6.097 4.188-4.894 6.285-14.217 8.83l-.273-.607c-23.001 10.818-54.947-10.622-54.526-39.876-.246 1.857-.698 1.393-1.208 2.144-1.186-15.052 6.952-30.17 20.675-36.343 13.427-6.646 29.163-3.918 38.78 5.044-5.282-6.92-15.795-14.254-28.255-13.568-12.208.193-23.625 7.95-27.436 16.369-6.253 3.938-6.979 15.177-9.704 17.233-3.665 26.943 6.896 38.583 24.762 52.275 2.812 1.896.792 2.184 1.173 3.627-5.936-2.779-11.372-6.976-15.841-12.114 2.372 3.473 4.931 6.847 8.239 9.499-5.596-1.897-13.074-13.563-15.256-14.038 9.647 17.274 39.142 30.295 54.587 23.836-7.146.263-16.226.146-24.256-2.822-3.371-1.734-7.958-5.331-7.14-6.003 21.079 7.875 42.854 5.965 61.09-8.655 4.641-3.614 9.709-9.761 11.173-9.846-2.206 3.317.377 1.596-1.318 4.523 4.625-7.456-2.008-3.035 4.779-12.877l2.507 3.453c-.931-6.188 7.687-13.704 6.813-23.492 1.975-2.994 2.206 3.22.107 10.107 2.912-7.64.767-8.867 1.516-15.171.81 2.118 1.867 4.37 2.412 6.606-1.895-7.382 1.948-12.433 2.898-16.724-.937-.415-2.928 3.264-3.383-5.457.065-3.788 1.054-1.985 1.435-2.917-.744-.427-2.694-3.33-3.88-8.9.86-1.308 2.3 3.393 3.47 3.586-.753-4.429-2.049-7.805-2.103-11.202-3.421-7.149-1.211.953-3.985-3.069-3.641-11.357 3.021-2.637 3.47-7.796 5.52 7.995 8.667 20.387 10.11 25.519-1.103-6.258-2.883-12.32-5.058-18.185 1.677.705-2.699-12.875 2.18-3.882-5.21-19.172-22.302-37.087-38.025-45.493 1.924 1.76 4.354 3.971 3.481 4.317-7.819-4.656-6.444-5.018-7.565-6.985-6.369-2.591-6.788.208-11.007.004-12.005-6.368-14.318-5.69-25.368-9.681l.502 2.349c-7.953-2.649-9.265 1.005-17.862.009-.523-.409 2.753-1.479 5.452-1.871-7.69 1.015-7.329-1.515-14.854.279 1.855-1.301 3.815-2.162 5.793-3.269-6.271.381-14.971 3.649-12.286.677-10.235 4.569-28.403 10.976-38.597 20.535l-.321-2.142c-4.672 5.608-20.371 16.748-21.622 24.011l-1.249.291c-2.431 4.116-4.004 8.781-5.932 13.016-3.18 5.417-4.661 2.085-4.208 2.934-6.253 12.679-9.359 23.332-12.043 32.069 1.912 2.858.046 17.206.769 28.688-3.141 56.709 39.8 111.77 86.737 124.48 6.88 2.459 17.11 2.364 25.813 2.618-10.268-2.937-11.595-1.556-21.595-5.044-7.215-3.398-8.797-7.277-13.907-11.711l2.022 3.573c-10.021-3.547-5.829-4.39-13.982-6.972l2.16-2.82c-3.249-.246-8.604-5.475-10.069-8.371l-3.553.14c-4.27-5.269-6.545-9.063-6.379-12.005l-1.148 2.047c-1.301-2.235-15.709-19.759-8.234-15.679-1.389-1.271-3.235-2.067-5.237-5.703l1.522-1.739c-3.597-4.627-6.621-10.562-6.391-12.536 1.919 2.592 3.25 3.075 4.568 3.52-9.083-22.539-9.593-1.242-16.474-22.942l1.456-.116c-1.116-1.682-1.793-3.506-2.69-5.298l.633-6.313c-6.541-7.562-1.829-32.151-.887-45.637.655-5.485 5.459-11.322 9.114-20.477l-2.227-.384c4.256-7.423 24.301-29.814 33.583-28.662 4.499-5.649-.892-.02-1.772-1.443 9.878-10.223 12.984-7.222 19.65-9.061 7.19-4.268-6.17 1.664-2.761-1.628 12.427-3.174 8.808-7.216 25.021-8.828 1.71.973-3.969 1.503-5.395 2.766 10.354-5.066 32.769-3.914 47.326 2.811 16.895 7.896 35.873 31.232 36.622 53.189l.852.229c-.431 8.729 1.336 18.822-1.727 28.094l2.1-4.385"/><path d="m79.5 142.715-.578 2.893c2.71 3.683 4.861 7.673 8.323 10.552-2.49-4.863-4.341-6.872-7.745-13.445m6.409-.251c-1.435-1.587-2.284-3.497-3.235-5.4.909 3.345 2.771 6.219 4.504 9.143zm113.411-24.65-.605 1.52c-1.111 7.892-3.511 15.701-7.189 22.941a72.1 72.1 0 0 0 7.79-24.461M109.698 6.757c2.789-1.022 6.855-.56 9.814-1.233-3.855.324-7.693.517-11.484 1.005zM11.781 58.824c.642 5.951-4.477 8.26 1.134 4.337 3.007-6.773-1.175-1.87-1.134-4.337M5.188 86.362c1.292-3.967 1.526-6.349 2.02-8.645-3.571 4.566-1.643 5.539-2.02 8.645"/></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 260" class="svg gitea-debian" width="16" height="16" aria-hidden="true"><g fill="#d70751"><path d="M124.525 137.053c-4.125.058.78 2.125 6.165 2.954a55 55 0 0 0 4.04-3.479c-3.354.821-6.765.838-10.205.525m22.14-5.52c2.457-3.389 4.246-7.102 4.878-10.939-.551 2.736-2.035 5.099-3.435 7.592-7.711 4.854-.726-2.883-.004-5.824-8.29 10.436-1.138 6.257-1.439 9.171m8.174-21.265c.497-7.428-1.462-5.08-2.121-2.245.766.4 1.377 5.237 2.121 2.245M108.883 8.736c2.201.395 4.757.698 4.398 1.224 2.407-.528 2.954-1.015-4.398-1.224M113.281 9.96l-1.556.32 1.448-.127z"/><path d="M181.93 113.085c.247 6.671-1.95 9.907-3.932 15.637l-3.564 1.781c-2.919 5.666.282 3.598-1.807 8.105-4.556 4.049-13.823 12.67-16.789 13.457-2.163-.047 1.469-2.554 1.943-3.537-6.097 4.188-4.894 6.285-14.217 8.83l-.273-.607c-23.001 10.818-54.947-10.622-54.526-39.876-.246 1.857-.698 1.393-1.208 2.144-1.186-15.052 6.952-30.17 20.675-36.343 13.427-6.646 29.163-3.918 38.78 5.044-5.282-6.92-15.795-14.254-28.255-13.568-12.208.193-23.625 7.95-27.436 16.369-6.253 3.938-6.979 15.177-9.704 17.233-3.665 26.943 6.896 38.583 24.762 52.275 2.812 1.896.792 2.184 1.173 3.627-5.936-2.779-11.372-6.976-15.841-12.114 2.372 3.473 4.931 6.847 8.239 9.499-5.596-1.897-13.074-13.563-15.256-14.038 9.647 17.274 39.142 30.295 54.587 23.836-7.146.263-16.226.146-24.256-2.822-3.371-1.734-7.958-5.331-7.14-6.003 21.079 7.875 42.854 5.965 61.09-8.655 4.641-3.614 9.709-9.761 11.173-9.846-2.206 3.317.377 1.596-1.318 4.523 4.625-7.456-2.008-3.035 4.779-12.877l2.507 3.453c-.931-6.188 7.687-13.704 6.813-23.492 1.975-2.994 2.206 3.22.107 10.107 2.912-7.64.767-8.867 1.516-15.171.81 2.118 1.867 4.37 2.412 6.606-1.895-7.382 1.948-12.433 2.898-16.724-.937-.415-2.928 3.264-3.383-5.457.065-3.788 1.054-1.985 1.435-2.917-.744-.427-2.694-3.33-3.88-8.9.86-1.308 2.3 3.393 3.47 3.586-.753-4.429-2.049-7.805-2.103-11.202-3.421-7.149-1.211.953-3.985-3.069-3.641-11.357 3.021-2.637 3.47-7.796 5.52 7.995 8.667 20.387 10.11 25.519-1.103-6.258-2.883-12.32-5.058-18.185 1.677.705-2.699-12.875 2.18-3.882-5.21-19.172-22.302-37.087-38.025-45.493 1.924 1.76 4.354 3.971 3.481 4.317-7.819-4.656-6.444-5.018-7.565-6.985-6.369-2.591-6.788.208-11.007.004-12.005-6.368-14.318-5.69-25.368-9.681l.502 2.349c-7.953-2.649-9.265 1.005-17.862.009-.523-.409 2.753-1.479 5.452-1.871-7.69 1.015-7.329-1.515-14.854.279 1.855-1.301 3.815-2.162 5.793-3.269-6.271.381-14.971 3.649-12.286.677-10.235 4.569-28.403 10.976-38.597 20.535l-.321-2.142c-4.672 5.608-20.371 16.748-21.622 24.011l-1.249.291c-2.431 4.116-4.004 8.781-5.932 13.016-3.18 5.417-4.661 2.085-4.208 2.934-6.253 12.679-9.359 23.332-12.043 32.069 1.912 2.858.046 17.206.769 28.688-3.141 56.709 39.8 111.77 86.737 124.48 6.88 2.459 17.11 2.364 25.813 2.618-10.268-2.937-11.595-1.556-21.595-5.044-7.215-3.398-8.797-7.277-13.907-11.711l2.022 3.573c-10.021-3.547-5.829-4.39-13.982-6.972l2.16-2.82c-3.249-.246-8.604-5.475-10.069-8.371l-3.553.14c-4.27-5.269-6.545-9.063-6.379-12.005l-1.148 2.047c-1.301-2.235-15.709-19.759-8.234-15.679-1.389-1.271-3.235-2.067-5.237-5.703l1.522-1.739c-3.597-4.627-6.621-10.562-6.391-12.536 1.919 2.592 3.25 3.075 4.568 3.52-9.083-22.539-9.593-1.242-16.474-22.942l1.456-.116c-1.116-1.682-1.793-3.506-2.69-5.298l.633-6.313c-6.541-7.562-1.829-32.151-.887-45.637.655-5.485 5.459-11.322 9.114-20.477l-2.227-.384c4.256-7.423 24.301-29.814 33.583-28.662 4.499-5.649-.892-.02-1.772-1.443 9.878-10.223 12.984-7.222 19.65-9.061 7.19-4.268-6.17 1.664-2.761-1.628 12.427-3.174 8.808-7.216 25.021-8.828 1.71.973-3.969 1.503-5.395 2.766 10.354-5.066 32.769-3.914 47.326 2.811 16.895 7.896 35.873 31.232 36.622 53.189l.852.229c-.431 8.729 1.336 18.822-1.727 28.094l2.1-4.385"/><path d="m79.5 142.715-.578 2.893c2.71 3.683 4.861 7.673 8.323 10.552-2.49-4.863-4.341-6.872-7.745-13.445m6.409-.251c-1.435-1.587-2.284-3.497-3.235-5.4.909 3.345 2.771 6.219 4.504 9.143zm113.411-24.65-.605 1.52c-1.111 7.892-3.511 15.701-7.189 22.941a72.1 72.1 0 0 0 7.79-24.461M109.698 6.757c2.789-1.022 6.855-.56 9.814-1.233-3.855.324-7.693.517-11.484 1.005zM11.781 58.824c.642 5.951-4.477 8.26 1.134 4.337 3.007-6.773-1.175-1.87-1.134-4.337M5.188 86.362c1.292-3.967 1.526-6.349 2.02-8.645-3.571 4.566-1.643 5.539-2.02 8.645"/></g></svg>
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
2
public/assets/img/svg/gitea-gitbucket.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 316 329" class="svg gitea-gitbucket" width="16" height="16" aria-hidden="true"><path d="M123 21.1c-44.8 2.8-84 12.8-97.1 24.6-5 4.5-5 7.1 0 11.6C41.7 71.5 96.6 82.9 150 83h10.6l5.4-5.6c11.8-12.1 21.3-12.4 32.6-1.2l5.2 5 13.3-1.7c33.8-4.2 61.5-12.7 71.8-22 5.3-4.8 5.3-7.2 0-12-10.1-9.1-39.1-18.1-70.4-21.9-28.3-3.4-65.6-4.4-95.5-2.5M23.2 80.6c.4 1.6 7 42.9 14.8 91.9 7.9 49 14.7 89.5 15.2 90.2 1.7 2.1 25.8 11.4 41.6 15.9 13 3.7 35.1 8.4 40 8.4.6 0 1.2-.6 1.2-1.3 0-.6-17.4-18.5-38.6-39.7C57.9 206.6 55 203.2 55 196s3-10.7 38.3-45.9c30.1-30 34.8-34.3 36.6-33.5 1.1.5 8.7 7.4 17 15.2l15.1 14.4v5.9c0 7.3 2.4 12.4 7.7 16.7l3.8 3v61.8l-3.8 3.4c-10.2 8.9-10.2 22.9-.1 30.7 3.1 2.3 4.9 2.8 10.8 3.1 8.2.4 11.5-1.1 16.2-7.3 2.2-3 2.9-5.1 3.2-10 .4-6.5-.2-8.3-5.3-15.4l-2.5-3.4v-26.6c0-26.7.3-31.1 2.3-31.1.5 0 5.4 4.4 10.9 9.7 9.6 9.5 9.9 10 10.8 15.7 1.7 10.3 8.9 16.6 19 16.6 7.6 0 13.5-3.9 17.4-11.7 3.2-6.4 1.6-14.3-4.3-20.6-4.1-4.4-7.3-5.7-14.9-5.7h-6.8l-12.7-12.1c-10.7-10.1-12.7-12.6-13.2-15.7-1.2-7.2-1.6-8.2-4.7-11.7-3.9-4.5-7.7-6.5-12.2-6.5-1.9 0-4.5-.4-5.8-.9s-9.9-8.2-19.3-17l-17-16-7.1-.1c-10.6 0-36-2.7-52.4-5.5-22.8-4-38.5-8.6-57.9-17.2-1.1-.5-1.3 0-.9 2.3M278.5 83.6c-8.6 3.6-28 8.8-42.5 11.4-6.9 1.2-12.9 2.6-13.5 3.1-.6.6 9.3 11.2 27.5 29.4 15.6 15.6 28.5 28.3 28.7 28.1s1.9-15.8 3.8-34.7 3.7-35.6 4-37.2c.6-3.4-.2-3.4-8-.1M255.2 259.3c-7.8 7.8-14.2 14.6-14.2 15s.7.7 1.6.7c2.2 0 23-8.9 24.2-10.3.9-1.1 3.5-18.7 2.9-19.3-.2-.2-6.7 6.1-14.5 13.9M56 283.5c0 3.4 4 9.5 8.4 12.9 6.1 4.6 19.7 10.4 31.7 13.5 16.9 4.3 32.1 6.2 53.4 6.8l19 .5-7-7.1c-6.8-6.9-7.1-7.1-12-7.1-18.9 0-55.1-7.9-80.6-17.6C62.5 283 57 281 56.6 281c-.3 0-.6 1.1-.6 2.5M262 283.4c-5.3 2.8-25 9.7-36 12.6l-11.4 2.9-7.8 7.8c-4.2 4.2-7.6 7.9-7.4 8.1.9.8 24.4-4.1 33.4-6.9 16.4-5.3 26.7-11.4 30.8-18.5 2.4-4 3.1-7.4 1.7-7.4-.5.1-1.9.7-3.3 1.4"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 316 329" class="svg gitea-gitbucket" width="16" height="16" aria-hidden="true"><path d="M123 21.1c-44.8 2.8-84 12.8-97.1 24.6-5 4.5-5 7.1 0 11.6C41.7 71.5 96.6 82.9 150 83h10.6l5.4-5.6c11.8-12.1 21.3-12.4 32.6-1.2l5.2 5 13.3-1.7c33.8-4.2 61.5-12.7 71.8-22 5.3-4.8 5.3-7.2 0-12-10.1-9.1-39.1-18.1-70.4-21.9-28.3-3.4-65.6-4.4-95.5-2.5M23.2 80.6c.4 1.6 7 42.9 14.8 91.9 7.9 49 14.7 89.5 15.2 90.2 1.7 2.1 25.8 11.4 41.6 15.9 13 3.7 35.1 8.4 40 8.4.6 0 1.2-.6 1.2-1.3 0-.6-17.4-18.5-38.6-39.7C57.9 206.6 55 203.2 55 196s3-10.7 38.3-45.9c30.1-30 34.8-34.3 36.6-33.5 1.1.5 8.7 7.4 17 15.2l15.1 14.4v5.9c0 7.3 2.4 12.4 7.7 16.7l3.8 3v61.8l-3.8 3.4c-10.2 8.9-10.2 22.9-.1 30.7 3.1 2.3 4.9 2.8 10.8 3.1 8.2.4 11.5-1.1 16.2-7.3 2.2-3 2.9-5.1 3.2-10 .4-6.5-.2-8.3-5.3-15.4l-2.5-3.4v-26.6c0-26.7.3-31.1 2.3-31.1.5 0 5.4 4.4 10.9 9.7 9.6 9.5 9.9 10 10.8 15.7 1.7 10.3 8.9 16.6 19 16.6 7.6 0 13.5-3.9 17.4-11.7 3.2-6.4 1.6-14.3-4.3-20.6-4.1-4.4-7.3-5.7-14.9-5.7h-6.8l-12.7-12.1c-10.7-10.1-12.7-12.6-13.2-15.7-1.2-7.2-1.6-8.2-4.7-11.7-3.9-4.5-7.7-6.5-12.2-6.5-1.9 0-4.5-.4-5.8-.9s-9.9-8.2-19.3-17l-17-16-7.1-.1c-10.6 0-36-2.7-52.4-5.5-22.8-4-38.5-8.6-57.9-17.2-1.1-.5-1.3 0-.9 2.3M278.5 83.6c-8.6 3.6-28 8.8-42.5 11.4-6.9 1.2-12.9 2.6-13.5 3.1-.6.6 9.3 11.2 27.5 29.4 15.6 15.6 28.5 28.3 28.7 28.1s1.9-15.8 3.8-34.7 3.7-35.6 4-37.2c.6-3.4-.2-3.4-8-.1M255.2 259.3c-7.8 7.8-14.2 14.6-14.2 15s.7.7 1.6.7c2.2 0 23-8.9 24.2-10.3.9-1.1 3.5-18.7 2.9-19.3-.2-.2-6.7 6.1-14.5 13.9M56 283.5c0 3.4 4 9.5 8.4 12.9 6.1 4.6 19.7 10.4 31.7 13.5 16.9 4.3 32.1 6.2 53.4 6.8l19 .5-7-7.1c-6.8-6.9-7.1-7.1-12-7.1-18.9 0-55.1-7.9-80.6-17.6C62.5 283 57 281 56.6 281c-.3 0-.6 1.1-.6 2.5M262 283.4c-5.3 2.8-25 9.7-36 12.6l-11.4 2.9-7.8 7.8c-4.2 4.2-7.6 7.9-7.4 8.1.9.8 24.4-4.1 33.4-6.9 16.4-5.3 26.7-11.4 30.8-18.5 2.4-4 3.1-7.4 1.7-7.4-.5.1-1.9.7-3.3 1.4"/></svg>
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
2
public/assets/img/svg/gitea-gitlab.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" class="svg gitea-gitlab" width="16" height="16" aria-hidden="true"><path fill="#E24329" d="m31.462 12.779-.045-.115-4.35-11.35a1.14 1.14 0 0 0-.447-.541 1.16 1.16 0 0 0-1.343.071c-.187.15-.322.356-.386.587l-2.94 9.001h-11.9l-2.941-9a1.14 1.14 0 0 0-1.045-.84 1.15 1.15 0 0 0-1.13.72L.579 12.68l-.045.113a8.09 8.09 0 0 0 2.68 9.34l.016.012.038.03 6.635 4.967 3.28 2.484 1.994 1.51a1.35 1.35 0 0 0 1.627 0l1.994-1.51 3.282-2.484 6.673-4.997.018-.013a8.09 8.09 0 0 0 2.69-9.352Z"/><path fill="#FC6D26" d="m31.462 12.779-.045-.115a14.75 14.75 0 0 0-5.856 2.634l-9.553 7.24L22.1 27.14l6.673-4.997.019-.013a8.09 8.09 0 0 0 2.67-9.352Z"/><path fill="#FCA326" d="m9.908 27.14 3.275 2.485 1.994 1.51a1.35 1.35 0 0 0 1.627 0l1.994-1.51 3.282-2.484s-2.835-2.14-6.092-4.603z"/><path fill="#FC6D26" d="M6.435 15.305A14.7 14.7 0 0 0 .58 12.672l-.045.113a8.09 8.09 0 0 0 2.68 9.347l.016.012.038.03 6.635 4.967 6.105-4.603-9.573-7.233Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" class="svg gitea-gitlab" width="16" height="16" aria-hidden="true"><path fill="#e24329" d="m31.462 12.779-.045-.115-4.35-11.35a1.14 1.14 0 0 0-.447-.541 1.16 1.16 0 0 0-1.343.071c-.187.15-.322.356-.386.587l-2.94 9.001h-11.9l-2.941-9a1.14 1.14 0 0 0-1.045-.84 1.15 1.15 0 0 0-1.13.72L.579 12.68l-.045.113a8.09 8.09 0 0 0 2.68 9.34l.016.012.038.03 6.635 4.967 3.28 2.484 1.994 1.51a1.35 1.35 0 0 0 1.627 0l1.994-1.51 3.282-2.484 6.673-4.997.018-.013a8.09 8.09 0 0 0 2.69-9.352Z"/><path fill="#fc6d26" d="m31.462 12.779-.045-.115a14.75 14.75 0 0 0-5.856 2.634l-9.553 7.24L22.1 27.14l6.673-4.997.019-.013a8.09 8.09 0 0 0 2.67-9.352Z"/><path fill="#fca326" d="m9.908 27.14 3.275 2.485 1.994 1.51a1.35 1.35 0 0 0 1.627 0l1.994-1.51 3.282-2.484s-2.835-2.14-6.092-4.603z"/><path fill="#fc6d26" d="M6.435 15.305A14.7 14.7 0 0 0 .58 12.672l-.045.113a8.09 8.09 0 0 0 2.68 9.347l.016.012.038.03 6.635 4.967 6.105-4.603-9.573-7.233Z"/></svg>
|
Before Width: | Height: | Size: 988 B After Width: | Height: | Size: 988 B |
2
public/assets/img/svg/gitea-google.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="gitea-google__svg gitea-google__gitea-google svg gitea-google" viewBox="0 0 24 24" width="16" height="16"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53"/><path fill="none" d="M1 1h22v22H1z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="gitea-google__svg gitea-google__gitea-google svg gitea-google" viewBox="0 0 24 24" width="16" height="16"><path fill="#4285f4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09"/><path fill="#34a853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23"/><path fill="#fbbc05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22z"/><path fill="#ea4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53"/><path fill="none" d="M1 1h22v22H1z"/></svg>
|
Before Width: | Height: | Size: 821 B After Width: | Height: | Size: 821 B |
2
public/assets/img/svg/gitea-maven.svg
generated
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
2
public/assets/img/svg/gitea-microsoftonline.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48" class="svg gitea-microsoftonline" width="16" height="16" aria-hidden="true"><path fill="url(#gitea-microsoftonline__a)" d="m20.084 3.026-.224.136a8 8 0 0 0-1.009.722l.648-.456H25L26 11l-5 5-5 3.475v4.008a8 8 0 0 0 3.857 6.844l5.264 3.186L14 40h-2.145l-3.998-2.42A8 8 0 0 1 4 30.737V17.26a8 8 0 0 1 3.86-6.846l12-7.258q.111-.068.224-.131Z"/><path fill="url(#gitea-microsoftonline__b)" d="m20.084 3.026-.224.136a8 8 0 0 0-1.009.722l.648-.456H25L26 11l-5 5-5 3.475v4.008a8 8 0 0 0 3.857 6.844l5.264 3.186L14 40h-2.145l-3.998-2.42A8 8 0 0 1 4 30.737V17.26a8 8 0 0 1 3.86-6.846l12-7.258q.111-.068.224-.131Z"/><path fill="url(#gitea-microsoftonline__c)" d="M32 19v4.48a8 8 0 0 1-3.857 6.844l-12 7.264a8 8 0 0 1-8.008.16l11.722 7.096a8 8 0 0 0 8.286 0l12-7.264A8 8 0 0 0 44 30.736V27.5L43 26z"/><path fill="url(#gitea-microsoftonline__d)" d="M32 19v4.48a8 8 0 0 1-3.857 6.844l-12 7.264a8 8 0 0 1-8.008.16l11.722 7.096a8 8 0 0 0 8.286 0l12-7.264A8 8 0 0 0 44 30.736V27.5L43 26z"/><path fill="url(#gitea-microsoftonline__e)" d="m40.14 10.415-12-7.258a8 8 0 0 0-8.042-.139l-.238.144A8 8 0 0 0 16 10.008v9.483l3.86-2.334a8 8 0 0 1 8.28 0l12 7.258A8 8 0 0 1 43.997 31q.004-.132.004-.263V17.26a8 8 0 0 0-3.86-6.845Z"/><path fill="url(#gitea-microsoftonline__f)" d="m40.14 10.415-12-7.258a8 8 0 0 0-8.042-.139l-.238.144A8 8 0 0 0 16 10.008v9.483l3.86-2.334a8 8 0 0 1 8.28 0l12 7.258A8 8 0 0 1 43.997 31q.004-.132.004-.263V17.26a8 8 0 0 0-3.86-6.845Z"/><path fill="url(#gitea-microsoftonline__g)" d="M4.004 30.998"/><path fill="url(#gitea-microsoftonline__h)" d="M4.004 30.998"/><defs><radialGradient id="gitea-microsoftonline__a" cx="0" cy="0" r="1" gradientTransform="rotate(110.528 5.021 11.358)scale(33.3657 58.1966)" gradientUnits="userSpaceOnUse"><stop offset=".064" stop-color="#AE7FE2"/><stop offset="1" stop-color="#0078D4"/></radialGradient><radialGradient id="gitea-microsoftonline__c" cx="0" cy="0" r="1" gradientTransform="matrix(30.7198 -4.51832 2.98465 20.29248 10.43 36.351)" gradientUnits="userSpaceOnUse"><stop offset=".134" stop-color="#D59DFF"/><stop offset="1" stop-color="#5E438F"/></radialGradient><radialGradient id="gitea-microsoftonline__e" cx="0" cy="0" r="1" gradientTransform="matrix(-24.1583 -6.12555 10.3118 -40.66824 41.055 26.504)" gradientUnits="userSpaceOnUse"><stop offset=".058" stop-color="#50E6FF"/><stop offset="1" stop-color="#436DCD"/></radialGradient><radialGradient id="gitea-microsoftonline__g" cx="0" cy="0" r="1" gradientTransform="matrix(-24.1583 -6.12555 10.3118 -40.66824 41.055 26.504)" gradientUnits="userSpaceOnUse"><stop offset=".058" stop-color="#50E6FF"/><stop offset="1" stop-color="#436DCD"/></radialGradient><linearGradient id="gitea-microsoftonline__b" x1="17.512" x2="12.751" y1="37.868" y2="29.635" gradientUnits="userSpaceOnUse"><stop stop-color="#114A8B"/><stop offset="1" stop-color="#0078D4" stop-opacity="0"/></linearGradient><linearGradient id="gitea-microsoftonline__d" x1="40.357" x2="35.255" y1="25.377" y2="32.692" gradientUnits="userSpaceOnUse"><stop stop-color="#493474"/><stop offset="1" stop-color="#8C66BA" stop-opacity="0"/></linearGradient><linearGradient id="gitea-microsoftonline__f" x1="16.976" x2="24.487" y1="3.057" y2="3.057" gradientUnits="userSpaceOnUse"><stop stop-color="#2D3F80"/><stop offset="1" stop-color="#436DCD" stop-opacity="0"/></linearGradient><linearGradient id="gitea-microsoftonline__h" x1="16.976" x2="24.487" y1="3.057" y2="3.057" gradientUnits="userSpaceOnUse"><stop stop-color="#2D3F80"/><stop offset="1" stop-color="#436DCD" stop-opacity="0"/></linearGradient></defs></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48" class="svg gitea-microsoftonline" width="16" height="16" aria-hidden="true"><path fill="url(#gitea-microsoftonline__a)" d="m20.084 3.026-.224.136a8 8 0 0 0-1.009.722l.648-.456H25L26 11l-5 5-5 3.475v4.008a8 8 0 0 0 3.857 6.844l5.264 3.186L14 40h-2.145l-3.998-2.42A8 8 0 0 1 4 30.737V17.26a8 8 0 0 1 3.86-6.846l12-7.258q.111-.068.224-.131Z"/><path fill="url(#gitea-microsoftonline__b)" d="m20.084 3.026-.224.136a8 8 0 0 0-1.009.722l.648-.456H25L26 11l-5 5-5 3.475v4.008a8 8 0 0 0 3.857 6.844l5.264 3.186L14 40h-2.145l-3.998-2.42A8 8 0 0 1 4 30.737V17.26a8 8 0 0 1 3.86-6.846l12-7.258q.111-.068.224-.131Z"/><path fill="url(#gitea-microsoftonline__c)" d="M32 19v4.48a8 8 0 0 1-3.857 6.844l-12 7.264a8 8 0 0 1-8.008.16l11.722 7.096a8 8 0 0 0 8.286 0l12-7.264A8 8 0 0 0 44 30.736V27.5L43 26z"/><path fill="url(#gitea-microsoftonline__d)" d="M32 19v4.48a8 8 0 0 1-3.857 6.844l-12 7.264a8 8 0 0 1-8.008.16l11.722 7.096a8 8 0 0 0 8.286 0l12-7.264A8 8 0 0 0 44 30.736V27.5L43 26z"/><path fill="url(#gitea-microsoftonline__e)" d="m40.14 10.415-12-7.258a8 8 0 0 0-8.042-.139l-.238.144A8 8 0 0 0 16 10.008v9.483l3.86-2.334a8 8 0 0 1 8.28 0l12 7.258A8 8 0 0 1 43.997 31q.004-.132.004-.263V17.26a8 8 0 0 0-3.86-6.845Z"/><path fill="url(#gitea-microsoftonline__f)" d="m40.14 10.415-12-7.258a8 8 0 0 0-8.042-.139l-.238.144A8 8 0 0 0 16 10.008v9.483l3.86-2.334a8 8 0 0 1 8.28 0l12 7.258A8 8 0 0 1 43.997 31q.004-.132.004-.263V17.26a8 8 0 0 0-3.86-6.845Z"/><path fill="url(#gitea-microsoftonline__g)" d="M4.004 30.998"/><path fill="url(#gitea-microsoftonline__h)" d="M4.004 30.998"/><defs><radialGradient id="gitea-microsoftonline__a" cx="0" cy="0" r="1" gradientTransform="rotate(110.528 5.021 11.358)scale(33.3657 58.1966)" gradientUnits="userSpaceOnUse"><stop offset=".064" stop-color="#ae7fe2"/><stop offset="1" stop-color="#0078d4"/></radialGradient><radialGradient id="gitea-microsoftonline__c" cx="0" cy="0" r="1" gradientTransform="rotate(-8.367 253.693 -53.118)scale(31.0503 20.5108)" gradientUnits="userSpaceOnUse"><stop offset=".134" stop-color="#d59dff"/><stop offset="1" stop-color="#5e438f"/></radialGradient><radialGradient id="gitea-microsoftonline__e" cx="0" cy="0" r="1" gradientTransform="rotate(194.228 22.182 10.69)scale(24.9228 41.9552)" gradientUnits="userSpaceOnUse"><stop offset=".058" stop-color="#50e6ff"/><stop offset="1" stop-color="#436dcd"/></radialGradient><radialGradient id="gitea-microsoftonline__g" cx="0" cy="0" r="1" gradientTransform="rotate(194.228 22.182 10.69)scale(24.9228 41.9552)" gradientUnits="userSpaceOnUse"><stop offset=".058" stop-color="#50e6ff"/><stop offset="1" stop-color="#436dcd"/></radialGradient><linearGradient id="gitea-microsoftonline__b" x1="17.512" x2="12.751" y1="37.868" y2="29.635" gradientUnits="userSpaceOnUse"><stop stop-color="#114a8b"/><stop offset="1" stop-color="#0078d4" stop-opacity="0"/></linearGradient><linearGradient id="gitea-microsoftonline__d" x1="40.357" x2="35.255" y1="25.377" y2="32.692" gradientUnits="userSpaceOnUse"><stop stop-color="#493474"/><stop offset="1" stop-color="#8c66ba" stop-opacity="0"/></linearGradient><linearGradient id="gitea-microsoftonline__f" x1="16.976" x2="24.487" y1="3.057" y2="3.057" gradientUnits="userSpaceOnUse"><stop stop-color="#2d3f80"/><stop offset="1" stop-color="#436dcd" stop-opacity="0"/></linearGradient><linearGradient id="gitea-microsoftonline__h" x1="16.976" x2="24.487" y1="3.057" y2="3.057" gradientUnits="userSpaceOnUse"><stop stop-color="#2d3f80"/><stop offset="1" stop-color="#436dcd" stop-opacity="0"/></linearGradient></defs></svg>
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.5 KiB |
2
public/assets/img/svg/gitea-npm.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 7" class="svg gitea-npm" width="16" height="16" aria-hidden="true"><path fill="#CB3837" d="M0 0h18v6H9v1H5V6H0zm1 5h2V2h1v3h1V1H1zm5-4v5h2V5h2V1zm2 1h1v2H8zm3-1v4h2V2h1v3h1V2h1v3h1V1z"/><path fill="#fff" d="M1 5h2V2h1v3h1V1H1zM6 1v5h2V5h2V1zm3 3H8V2h1zM11 1v4h2V2h1v3h1V2h1v3h1V1z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 7" class="svg gitea-npm" width="16" height="16" aria-hidden="true"><path fill="#cb3837" d="M0 0h18v6H9v1H5V6H0zm1 5h2V2h1v3h1V1H1zm5-4v5h2V5h2V1zm2 1h1v2H8zm3-1v4h2V2h1v3h1V2h1v3h1V1z"/><path fill="#fff" d="M1 5h2V2h1v3h1V1H1zM6 1v5h2V5h2V1zm3 3H8V2h1zM11 1v4h2V2h1v3h1V2h1v3h1V1z"/></svg>
|
Before Width: | Height: | Size: 345 B After Width: | Height: | Size: 345 B |
2
public/assets/img/svg/gitea-onedev.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 700 700" class="svg gitea-onedev" width="16" height="16" aria-hidden="true"><path d="M315.5 99.6c-29.5 4-55.8 12-81.2 24.8L223 130l-5.2-4c-14.9-11.3-37.6-14.9-55.8-9-19.1 6.3-35.1 22.2-41.1 41-2.7 8.3-3.6 22.9-1.9 31.2 1.5 8 5 16.5 9.1 22.5 3.1 4.7 3.1 4.8 1.4 7.8C106 260 95.1 294.4 92 337.7c-1.1 15.7-.1 40.2 2.1 53l1.1 6.5-4.9 4.4c-2.8 2.3-7.5 7.6-10.6 11.6-19.4 25.5-24.7 57.9-14.4 88.3 9.2 26.9 31.2 48.8 58.4 58.1 20.6 6.9 40.6 7 61.1.1l6.7-2.2 10.5 7.1c45.6 31 92 45.5 146 45.5 33 0 61.6-5.2 91-16.4 67.6-25.8 122.9-81.1 148.4-148.4l2.7-7.2 7.7-3.8c9.1-4.5 21.1-15.7 25.9-24.3 21.1-37.5-1-84.3-43.2-91.7-19.9-3.5-39.3 2.7-53.9 17.2-7.1 7.1-11.7 14.5-15.3 24.7-3.4 9.4-3.8 25.8-.9 35.3 2.8 9.5 8.5 19.3 15.3 26.4 7.2 7.6 7.2 6 0 20.5-8.9 18.1-20.3 34.1-35.2 49.5-34.6 35.7-78.2 56.3-128.3 60.3-42.8 3.4-89.3-8.9-125-33-1.1-.8-1-1.7.8-5.2 12.1-23.6 13.5-53.7 3.9-78-8.7-21.8-27.5-41.6-48.6-51.2-9-4.1-22.7-7.4-34-8.3l-9.1-.7-.8-9.6c-3.5-46.9 13.5-99.8 45.5-141.7 6.5-8.6 24.3-26.7 33.6-34.2 43.8-35.6 101.3-52.8 158.1-47.2 39.9 3.9 79 19.1 110.6 43 16.9 12.8 37.5 34.9 48.6 52l4.3 6.7-3.3 5.2c-2.9 4.7-3.3 6.3-3.6 13.4-.3 7.3-.1 8.6 2.5 13.6 3.2 6.1 10.2 12 16.3 13.9 22.8 6.8 43-16.9 32.6-38.2-3.1-6.4-9.3-12.2-14.7-13.8-2.5-.8-4.1-2.1-5.2-4.3-.9-1.7-3.2-5.8-5.1-9.2l-3.5-6 3.6-5c17.7-24.4 15.8-57.5-4.4-79.4-8-8.6-15.5-13.6-25.9-17.2-19.8-6.8-38.9-4.2-56.5 7.8l-7.8 5.3-15.3-7.4c-27.9-13.4-55-21.3-84-24.4-13.3-1.5-48.1-1.2-60.3.5"/><path d="M271.8 271.1c-13.9 2.1-30.5 17.3-40.5 37.4-18.3 36.4-13.4 81.5 9.8 91.5 15.2 6.5 34.5-2.7 48.6-23.2 5.5-8 9.7-15.7 9-16.5-.3-.2-2 .3-3.8 1.2-2.4 1.3-5.1 1.6-10.5 1.3-6.1-.3-7.9-.8-11.6-3.4-8.9-6.2-12.4-19.1-7.9-29 2.4-5.2 9-10.8 14.7-12.4 9.1-2.6 20 1.4 25.2 9.2l2.7 4.2.3-12.4c.4-18.9-3.4-31.6-12.4-40.5-6.3-6.3-14.2-8.8-23.6-7.4M420.5 271c-11.6 1.9-20.2 11.3-24.9 27-2.1 6.9-3.1 20-2.2 27.4l.8 5.7 2.1-3.2c10.2-15 31.6-14 39.9 2 6 11.5 1.5 25.1-10.4 31.2-5 2.5-15 2.6-20 .1l-3.6-1.9 1.4 3.3c6.1 14.5 20 30.1 32.3 36.1 5.7 2.8 14.4 4 20.4 2.9 5.2-1 12.1-6.1 16.1-11.9 18.1-26.4 8.1-79-20-105.8-10.8-10.2-21.6-14.6-31.9-12.9M322.5 431.9c-16.1 1.6-23.5 6.1-23.5 14.3 0 11.4 13 21.1 34 25.4 10.2 2 31.2 1.5 40.5-1 13.5-3.7 23.8-10.3 27.6-17.7 4.9-9.7-.2-17.1-13.8-20-6.1-1.2-54.2-2-64.8-1"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" class="svg gitea-onedev" width="16" height="16" aria-hidden="true"><path d="M315.5 99.6c-29.5 4-55.8 12-81.2 24.8L223 130l-5.2-4c-14.9-11.3-37.6-14.9-55.8-9-19.1 6.3-35.1 22.2-41.1 41-2.7 8.3-3.6 22.9-1.9 31.2 1.5 8 5 16.5 9.1 22.5 3.1 4.7 3.1 4.8 1.4 7.8C106 260 95.1 294.4 92 337.7c-1.1 15.7-.1 40.2 2.1 53l1.1 6.5-4.9 4.4c-2.8 2.3-7.5 7.6-10.6 11.6-19.4 25.5-24.7 57.9-14.4 88.3 9.2 26.9 31.2 48.8 58.4 58.1 20.6 6.9 40.6 7 61.1.1l6.7-2.2 10.5 7.1c45.6 31 92 45.5 146 45.5 33 0 61.6-5.2 91-16.4 67.6-25.8 122.9-81.1 148.4-148.4l2.7-7.2 7.7-3.8c9.1-4.5 21.1-15.7 25.9-24.3 21.1-37.5-1-84.3-43.2-91.7-19.9-3.5-39.3 2.7-53.9 17.2-7.1 7.1-11.7 14.5-15.3 24.7-3.4 9.4-3.8 25.8-.9 35.3 2.8 9.5 8.5 19.3 15.3 26.4 7.2 7.6 7.2 6 0 20.5-8.9 18.1-20.3 34.1-35.2 49.5-34.6 35.7-78.2 56.3-128.3 60.3-42.8 3.4-89.3-8.9-125-33-1.1-.8-1-1.7.8-5.2 12.1-23.6 13.5-53.7 3.9-78-8.7-21.8-27.5-41.6-48.6-51.2-9-4.1-22.7-7.4-34-8.3l-9.1-.7-.8-9.6c-3.5-46.9 13.5-99.8 45.5-141.7 6.5-8.6 24.3-26.7 33.6-34.2 43.8-35.6 101.3-52.8 158.1-47.2 39.9 3.9 79 19.1 110.6 43 16.9 12.8 37.5 34.9 48.6 52l4.3 6.7-3.3 5.2c-2.9 4.7-3.3 6.3-3.6 13.4-.3 7.3-.1 8.6 2.5 13.6 3.2 6.1 10.2 12 16.3 13.9 22.8 6.8 43-16.9 32.6-38.2-3.1-6.4-9.3-12.2-14.7-13.8-2.5-.8-4.1-2.1-5.2-4.3-.9-1.7-3.2-5.8-5.1-9.2l-3.5-6 3.6-5c17.7-24.4 15.8-57.5-4.4-79.4-8-8.6-15.5-13.6-25.9-17.2-19.8-6.8-38.9-4.2-56.5 7.8l-7.8 5.3-15.3-7.4c-27.9-13.4-55-21.3-84-24.4-13.3-1.5-48.1-1.2-60.3.5"/><path d="M271.8 271.1c-13.9 2.1-30.5 17.3-40.5 37.4-18.3 36.4-13.4 81.5 9.8 91.5 15.2 6.5 34.5-2.7 48.6-23.2 5.5-8 9.7-15.7 9-16.5-.3-.2-2 .3-3.8 1.2-2.4 1.3-5.1 1.6-10.5 1.3-6.1-.3-7.9-.8-11.6-3.4-8.9-6.2-12.4-19.1-7.9-29 2.4-5.2 9-10.8 14.7-12.4 9.1-2.6 20 1.4 25.2 9.2l2.7 4.2.3-12.4c.4-18.9-3.4-31.6-12.4-40.5-6.3-6.3-14.2-8.8-23.6-7.4M420.5 271c-11.6 1.9-20.2 11.3-24.9 27-2.1 6.9-3.1 20-2.2 27.4l.8 5.7 2.1-3.2c10.2-15 31.6-14 39.9 2 6 11.5 1.5 25.1-10.4 31.2-5 2.5-15 2.6-20 .1l-3.6-1.9 1.4 3.3c6.1 14.5 20 30.1 32.3 36.1 5.7 2.8 14.4 4 20.4 2.9 5.2-1 12.1-6.1 16.1-11.9 18.1-26.4 8.1-79-20-105.8-10.8-10.2-21.6-14.6-31.9-12.9M322.5 431.9c-16.1 1.6-23.5 6.1-23.5 14.3 0 11.4 13 21.1 34 25.4 10.2 2 31.2 1.5 40.5-1 13.5-3.7 23.8-10.3 27.6-17.7 4.9-9.7-.2-17.1-13.8-20-6.1-1.2-54.2-2-64.8-1"/></svg>
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.2 KiB |
2
public/assets/img/svg/gitea-openid.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 2400 2400" class="svg gitea-openid" width="16" height="16" aria-hidden="true"><path fill="#ff7c00" d="m1270 218.3-173.1 84.3-.7 981.8c-.3 540 .2 981.4 1.1 981l174.5-81.8 172.3-80.8v-984.4c0-541.7-.2-984.7-.4-984.4z"/><path fill="#aaa" d="M981.9 785.5c-425.3 63.2-766.5 264.1-889 523a491.5 491.5 0 0 0-43.6 146c-4.2 29.2-4.7 95-1.2 124 19 152.6 115.2 299.9 273.2 418.8 147.7 111 350.5 196.5 568.6 239.7 59 11.6 179 29 200.5 29 2.3 0 3-23.2 3-109.1v-109.2l-5.1-1-37.9-6a1182 1182 0 0 1-305.4-90.6c-122.2-55.7-225.1-137.7-284.6-226.4-107.5-160.5-81.3-344.3 70-491.3 57-55.5 115.4-95.2 199.5-136.1a1112.6 1112.6 0 0 1 269.4-89.2l29.7-6c3.7-1.2 4-8.6 4-111.5V779.5l-6.3.2a823 823 0 0 0-44.8 5.8m525 104c0 103 .2 110.4 4.1 111.6l29.5 6a1221.6 1221.6 0 0 1 207.7 61.3A1088 1088 0 0 1 1862 1123c4.6 3.7 1.4 5.8-88 56-51.1 28.5-93 52.7-93 53.4 0 1.9 671.6 146.8 673.2 145.2 1.2-1.2-45.5-496-47-497.6-.2-.2-38.5 21-85 47.2l-89.6 50.2c-4.2 2-8.8.2-27.9-10.7-130.8-75-289.6-132.2-460.8-166.1a1871 1871 0 0 0-132.9-21.1c-4 0-4.2 6.7-4.2 110z"/><path fill="#cbaa7c" d="M1094.5 2156.9c0 60.6.3 85.5.5 55 .5-30.2.5-79.9 0-110.3-.2-30.2-.5-5.3-.5 55.3"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2400 2400" class="svg gitea-openid" width="16" height="16" aria-hidden="true"><path fill="#ff7c00" d="m1270 218.3-173.1 84.3-.7 981.8c-.3 540 .2 981.4 1.1 981l174.5-81.8 172.3-80.8v-984.4c0-541.7-.2-984.7-.4-984.4z"/><path fill="#aaa" d="M981.9 785.5c-425.3 63.2-766.5 264.1-889 523a491.5 491.5 0 0 0-43.6 146c-4.2 29.2-4.7 95-1.2 124 19 152.6 115.2 299.9 273.2 418.8 147.7 111 350.5 196.5 568.6 239.7 59 11.6 179 29 200.5 29 2.3 0 3-23.2 3-109.1v-109.2l-5.1-1-37.9-6a1182 1182 0 0 1-305.4-90.6c-122.2-55.7-225.1-137.7-284.6-226.4-107.5-160.5-81.3-344.3 70-491.3 57-55.5 115.4-95.2 199.5-136.1a1112.6 1112.6 0 0 1 269.4-89.2l29.7-6c3.7-1.2 4-8.6 4-111.5V779.5l-6.3.2a823 823 0 0 0-44.8 5.8m525 104c0 103 .2 110.4 4.1 111.6l29.5 6a1221.6 1221.6 0 0 1 207.7 61.3A1088 1088 0 0 1 1862 1123c4.6 3.7 1.4 5.8-88 56-51.1 28.5-93 52.7-93 53.4 0 1.9 671.6 146.8 673.2 145.2 1.2-1.2-45.5-496-47-497.6-.2-.2-38.5 21-85 47.2l-89.6 50.2c-4.2 2-8.8.2-27.9-10.7-130.8-75-289.6-132.2-460.8-166.1a1871 1871 0 0 0-132.9-21.1c-4 0-4.2 6.7-4.2 110z"/><path fill="#cbaa7c" d="M1094.5 2156.9c0 60.6.3 85.5.5 55 .5-30.2.5-79.9 0-110.3-.2-30.2-.5-5.3-.5 55.3"/></svg>
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
2
public/assets/img/svg/gitea-rubygems.svg
generated
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
2
public/assets/img/svg/gitea-swift.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 59.5 59.5" class="svg gitea-swift" width="16" height="16" aria-hidden="true"><path fill="#F05138" d="M59.387 16.45a83 83 0 0 0-.027-1.792c-.034-1.301-.111-2.614-.343-3.9-.234-1.308-.618-2.523-1.222-3.71a12.46 12.46 0 0 0-5.452-5.452C51.156.992 49.94.609 48.635.374c-1.287-.232-2.6-.308-3.902-.343a86 86 0 0 0-1.792-.027Q41.876-.001 40.813 0H18.578q-1.064-.001-2.127.004c-.598.004-1.196.01-1.793.027q-.488.012-.978.036c-.978.047-1.959.133-2.924.307-.98.176-1.908.436-2.811.81A12.5 12.5 0 0 0 3.89 3.89a12.5 12.5 0 0 0-2.294 3.158C.992 8.235.61 9.45.374 10.758c-.231 1.286-.308 2.599-.343 3.9a86 86 0 0 0-.027 1.792Q-.002 17.515 0 18.578v22.234q-.001 1.064.004 2.129c.004.597.01 1.194.027 1.79.035 1.302.112 2.615.343 3.902.235 1.306.618 2.522 1.222 3.71a12.457 12.457 0 0 0 5.453 5.453c1.186.603 2.401.986 3.707 1.22 1.287.232 2.6.309 3.902.344q.896.023 1.793.026 1.063.006 2.127.004h22.235q1.065.002 2.128-.004.897-.003 1.792-.026c1.302-.035 2.615-.112 3.902-.344 1.306-.234 2.521-.617 3.708-1.221a12.46 12.46 0 0 0 5.452-5.453c.604-1.187.988-2.403 1.223-3.71.23-1.286.308-2.599.342-3.9.017-.597.023-1.194.027-1.791q.006-1.065.004-2.129V18.578q.001-1.065-.004-2.128"/><path fill="#fff" d="m47.061 36.661-.004-.005c.066-.223.133-.446.19-.675 2.466-9.82-3.55-21.432-13.731-27.545 4.461 6.048 6.434 13.373 4.681 19.78-.156.572-.344 1.12-.552 1.653-.225-.148-.51-.316-.89-.526 0 0-10.128-6.253-21.104-17.312-.288-.29 5.853 8.776 12.822 16.14-3.283-1.843-12.434-8.5-18.227-13.802.712 1.186 1.559 2.33 2.49 3.43 4.837 6.135 11.145 13.704 18.703 19.517-5.31 3.25-12.814 3.502-20.285.003a30.7 30.7 0 0 1-5.193-3.098c3.162 5.058 8.033 9.423 13.96 11.97 7.07 3.039 14.1 2.833 19.337.05l-.004.007.079-.047q.323-.172.637-.358c2.516-1.306 7.485-2.63 10.152 2.559.653 1.27 2.041-5.46-3.062-11.739z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 59.5 59.5" class="svg gitea-swift" width="16" height="16" aria-hidden="true"><path fill="#f05138" d="M59.387 16.45a83 83 0 0 0-.027-1.792c-.034-1.301-.111-2.614-.343-3.9-.234-1.308-.618-2.523-1.222-3.71a12.46 12.46 0 0 0-5.452-5.452C51.156.992 49.94.609 48.635.374c-1.287-.232-2.6-.308-3.902-.343a86 86 0 0 0-1.792-.027Q41.876-.001 40.813 0H18.578q-1.064-.001-2.127.004c-.598.004-1.196.01-1.793.027q-.488.012-.978.036c-.978.047-1.959.133-2.924.307-.98.176-1.908.436-2.811.81A12.5 12.5 0 0 0 3.89 3.89a12.5 12.5 0 0 0-2.294 3.158C.992 8.235.61 9.45.374 10.758c-.231 1.286-.308 2.599-.343 3.9a86 86 0 0 0-.027 1.792Q-.002 17.515 0 18.578v22.234q-.001 1.064.004 2.129c.004.597.01 1.194.027 1.79.035 1.302.112 2.615.343 3.902.235 1.306.618 2.522 1.222 3.71a12.457 12.457 0 0 0 5.453 5.453c1.186.603 2.401.986 3.707 1.22 1.287.232 2.6.309 3.902.344q.896.023 1.793.026 1.063.006 2.127.004h22.235q1.065.002 2.128-.004.897-.003 1.792-.026c1.302-.035 2.615-.112 3.902-.344 1.306-.234 2.521-.617 3.708-1.221a12.46 12.46 0 0 0 5.452-5.453c.604-1.187.988-2.403 1.223-3.71.23-1.286.308-2.599.342-3.9.017-.597.023-1.194.027-1.791q.006-1.065.004-2.129V18.578q.001-1.065-.004-2.128"/><path fill="#fff" d="m47.061 36.661-.004-.005c.066-.223.133-.446.19-.675 2.466-9.82-3.55-21.432-13.731-27.545 4.461 6.048 6.434 13.373 4.681 19.78-.156.572-.344 1.12-.552 1.653-.225-.148-.51-.316-.89-.526 0 0-10.128-6.253-21.104-17.312-.288-.29 5.853 8.776 12.822 16.14-3.283-1.843-12.434-8.5-18.227-13.802.712 1.186 1.559 2.33 2.49 3.43 4.837 6.135 11.145 13.704 18.703 19.517-5.31 3.25-12.814 3.502-20.285.003a30.7 30.7 0 0 1-5.193-3.098c3.162 5.058 8.033 9.423 13.96 11.97 7.07 3.039 14.1 2.833 19.337.05l-.004.007.079-.047q.323-.172.637-.358c2.516-1.306 7.485-2.63 10.152 2.559.653 1.27 2.041-5.46-3.062-11.739z"/></svg>
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
2
public/assets/img/svg/gitea-vagrant.svg
generated
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 255 263" class="svg gitea-vagrant" width="16" height="16" aria-hidden="true"><path fill="#1159CC" d="M254.22 20.234 196.03 53.47l-1.64 20.618-44.19 99.772-26.27 17.34 3.18 71.6 49.53-28.55 77.58-189.946zM92.45 56.933V34.051l-.238-.136-38.483 19.102 1.642 23.034L103.4 180.6l26.02-14.71-2.31-28.09z"/><path fill="#127EFF" d="m219.56 0-57.75 33.814h-.04v23.119L127.11 137.8v27.02l-23.12 13.41L57.788 74.146V53.81L92.45 33.848 34.668 0 .006 20.234v24.783L78.022 234.49l49.088 28.31v-71.16l23.09-13.41-.27-.17 46.51-103.914V53.81l57.78-33.576z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 255 263" class="svg gitea-vagrant" width="16" height="16" aria-hidden="true"><path fill="#1159cc" d="M254.22 20.234 196.03 53.47l-1.64 20.618-44.19 99.772-26.27 17.34 3.18 71.6 49.53-28.55 77.58-189.946zM92.45 56.933V34.051l-.238-.136-38.483 19.102 1.642 23.034L103.4 180.6l26.02-14.71-2.31-28.09z"/><path fill="#127eff" d="m219.56 0-57.75 33.814h-.04v23.119L127.11 137.8v27.02l-23.12 13.41L57.788 74.146V53.81L92.45 33.848 34.668 0 .006 20.234v24.783L78.022 234.49l49.088 28.31v-71.16l23.09-13.41-.27-.17 46.51-103.914V53.81l57.78-33.576z"/></svg>
|
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 632 B |
1
public/assets/img/svg/octicon-sparkle.svg
generated
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="svg octicon-sparkle" width="16" height="16" aria-hidden="true"><path d="M7.198.57c.275-.752 1.34-.752 1.615 0l.849 2.317a5.82 5.82 0 0 0 3.462 3.463l2.317.848c.753.275.753 1.34 0 1.615l-2.317.849a5.82 5.82 0 0 0-3.462 3.462l-.849 2.317c-.275.753-1.34.753-1.615 0l-.848-2.317a5.82 5.82 0 0 0-3.463-3.462L.57 8.813c-.752-.275-.752-1.34 0-1.615l2.317-.848A5.82 5.82 0 0 0 6.35 2.887zm.562 2.833A7.32 7.32 0 0 1 3.403 7.76l-.673.246.673.246a7.32 7.32 0 0 1 4.357 4.356l.246.673.246-.673a7.32 7.32 0 0 1 4.356-4.356l.673-.246-.673-.246a7.32 7.32 0 0 1-4.356-4.357l-.246-.673z"/></svg>
|
After Width: | Height: | Size: 646 B |
@ -467,7 +467,9 @@ func CommonRoutes() *web.Router {
|
|||||||
g.MatchPath("HEAD", "/<group:*>/repodata/<filename>", rpm.CheckRepositoryFileExistence)
|
g.MatchPath("HEAD", "/<group:*>/repodata/<filename>", rpm.CheckRepositoryFileExistence)
|
||||||
g.MatchPath("GET", "/<group:*>/repodata/<filename>", rpm.GetRepositoryFile)
|
g.MatchPath("GET", "/<group:*>/repodata/<filename>", rpm.GetRepositoryFile)
|
||||||
g.MatchPath("PUT", "/<group:*>/upload", reqPackageAccess(perm.AccessModeWrite), rpm.UploadPackageFile)
|
g.MatchPath("PUT", "/<group:*>/upload", reqPackageAccess(perm.AccessModeWrite), rpm.UploadPackageFile)
|
||||||
|
// this URL pattern is only used internally in the RPM index, it is generated by us, the filename part is not really used (can be anything)
|
||||||
g.MatchPath("HEAD,GET", "/<group:*>/package/<name>/<version>/<architecture>", rpm.DownloadPackageFile)
|
g.MatchPath("HEAD,GET", "/<group:*>/package/<name>/<version>/<architecture>", rpm.DownloadPackageFile)
|
||||||
|
g.MatchPath("HEAD,GET", "/<group:*>/package/<name>/<version>/<architecture>/<filename>", rpm.DownloadPackageFile)
|
||||||
g.MatchPath("DELETE", "/<group:*>/package/<name>/<version>/<architecture>", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile)
|
g.MatchPath("DELETE", "/<group:*>/package/<name>/<version>/<architecture>", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile)
|
||||||
}, reqPackageAccess(perm.AccessModeRead))
|
}, reqPackageAccess(perm.AccessModeRead))
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ func ListOrGetPackages(ctx *context.Context) {
|
|||||||
DownloadPackageFile(ctx)
|
DownloadPackageFile(ctx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.NotFound(nil)
|
http.NotFound(ctx.Resp, ctx.Req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EnumeratePackages(ctx *context.Context) {
|
func EnumeratePackages(ctx *context.Context) {
|
||||||
|
@ -53,15 +53,23 @@ type RegistrationIndexPageItem struct {
|
|||||||
// https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource#catalog-entry
|
// https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource#catalog-entry
|
||||||
type CatalogEntry struct {
|
type CatalogEntry struct {
|
||||||
CatalogLeafURL string `json:"@id"`
|
CatalogLeafURL string `json:"@id"`
|
||||||
PackageContentURL string `json:"packageContent"`
|
|
||||||
ID string `json:"id"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
ReleaseNotes string `json:"releaseNotes"`
|
|
||||||
Authors string `json:"authors"`
|
Authors string `json:"authors"`
|
||||||
RequireLicenseAcceptance bool `json:"requireLicenseAcceptance"`
|
Copyright string `json:"copyright"`
|
||||||
ProjectURL string `json:"projectURL"`
|
|
||||||
DependencyGroups []*PackageDependencyGroup `json:"dependencyGroups"`
|
DependencyGroups []*PackageDependencyGroup `json:"dependencyGroups"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
IconURL string `json:"iconUrl"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
IsPrerelease bool `json:"isPrerelease"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
LicenseURL string `json:"licenseUrl"`
|
||||||
|
PackageContentURL string `json:"packageContent"`
|
||||||
|
ProjectURL string `json:"projectUrl"`
|
||||||
|
RequireLicenseAcceptance bool `json:"requireLicenseAcceptance"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
Tags string `json:"tags"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
ReleaseNotes string `json:"releaseNotes"`
|
||||||
|
Published time.Time `json:"published"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource#package-dependency-group
|
// https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource#package-dependency-group
|
||||||
@ -109,15 +117,24 @@ func createRegistrationIndexPageItem(l *linkBuilder, pd *packages_model.PackageD
|
|||||||
RegistrationLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
RegistrationLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
||||||
PackageContentURL: l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version),
|
PackageContentURL: l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version),
|
||||||
CatalogEntry: &CatalogEntry{
|
CatalogEntry: &CatalogEntry{
|
||||||
CatalogLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
CatalogLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
||||||
PackageContentURL: l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version),
|
Authors: metadata.Authors,
|
||||||
ID: pd.Package.Name,
|
Copyright: metadata.Copyright,
|
||||||
Version: pd.Version.Version,
|
DependencyGroups: createDependencyGroups(pd),
|
||||||
Description: metadata.Description,
|
Description: metadata.Description,
|
||||||
ReleaseNotes: metadata.ReleaseNotes,
|
IconURL: metadata.IconURL,
|
||||||
Authors: metadata.Authors,
|
ID: pd.Package.Name,
|
||||||
ProjectURL: metadata.ProjectURL,
|
IsPrerelease: pd.Version.IsPrerelease(),
|
||||||
DependencyGroups: createDependencyGroups(pd),
|
Language: metadata.Language,
|
||||||
|
LicenseURL: metadata.LicenseURL,
|
||||||
|
PackageContentURL: l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version),
|
||||||
|
ProjectURL: metadata.ProjectURL,
|
||||||
|
RequireLicenseAcceptance: metadata.RequireLicenseAcceptance,
|
||||||
|
Summary: metadata.Summary,
|
||||||
|
Tags: metadata.Tags,
|
||||||
|
Version: pd.Version.Version,
|
||||||
|
ReleaseNotes: metadata.ReleaseNotes,
|
||||||
|
Published: pd.Version.CreatedUnix.AsLocalTime(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,22 +162,42 @@ func createDependencyGroups(pd *packages_model.PackageDescriptor) []*PackageDepe
|
|||||||
|
|
||||||
// https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource#registration-leaf
|
// https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource#registration-leaf
|
||||||
type RegistrationLeafResponse struct {
|
type RegistrationLeafResponse struct {
|
||||||
RegistrationLeafURL string `json:"@id"`
|
RegistrationLeafURL string `json:"@id"`
|
||||||
Type []string `json:"@type"`
|
Type []string `json:"@type"`
|
||||||
Listed bool `json:"listed"`
|
PackageContentURL string `json:"packageContent"`
|
||||||
PackageContentURL string `json:"packageContent"`
|
RegistrationIndexURL string `json:"registration"`
|
||||||
Published time.Time `json:"published"`
|
CatalogEntry CatalogEntry `json:"catalogEntry"`
|
||||||
RegistrationIndexURL string `json:"registration"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRegistrationLeafResponse(l *linkBuilder, pd *packages_model.PackageDescriptor) *RegistrationLeafResponse {
|
func createRegistrationLeafResponse(l *linkBuilder, pd *packages_model.PackageDescriptor) *RegistrationLeafResponse {
|
||||||
|
registrationLeafURL := l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version)
|
||||||
|
packageDownloadURL := l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version)
|
||||||
|
metadata := pd.Metadata.(*nuget_module.Metadata)
|
||||||
return &RegistrationLeafResponse{
|
return &RegistrationLeafResponse{
|
||||||
Type: []string{"Package", "http://schema.nuget.org/catalog#Permalink"},
|
RegistrationLeafURL: registrationLeafURL,
|
||||||
Listed: true,
|
|
||||||
Published: pd.Version.CreatedUnix.AsLocalTime(),
|
|
||||||
RegistrationLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
|
||||||
PackageContentURL: l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version),
|
|
||||||
RegistrationIndexURL: l.GetRegistrationIndexURL(pd.Package.Name),
|
RegistrationIndexURL: l.GetRegistrationIndexURL(pd.Package.Name),
|
||||||
|
PackageContentURL: packageDownloadURL,
|
||||||
|
Type: []string{"Package", "http://schema.nuget.org/catalog#Permalink"},
|
||||||
|
CatalogEntry: CatalogEntry{
|
||||||
|
CatalogLeafURL: registrationLeafURL,
|
||||||
|
Authors: metadata.Authors,
|
||||||
|
Copyright: metadata.Copyright,
|
||||||
|
DependencyGroups: createDependencyGroups(pd),
|
||||||
|
Description: metadata.Description,
|
||||||
|
IconURL: metadata.IconURL,
|
||||||
|
ID: pd.Package.Name,
|
||||||
|
IsPrerelease: pd.Version.IsPrerelease(),
|
||||||
|
Language: metadata.Language,
|
||||||
|
LicenseURL: metadata.LicenseURL,
|
||||||
|
PackageContentURL: packageDownloadURL,
|
||||||
|
ProjectURL: metadata.ProjectURL,
|
||||||
|
RequireLicenseAcceptance: metadata.RequireLicenseAcceptance,
|
||||||
|
Summary: metadata.Summary,
|
||||||
|
Tags: metadata.Tags,
|
||||||
|
Version: pd.Version.Version,
|
||||||
|
ReleaseNotes: metadata.ReleaseNotes,
|
||||||
|
Published: pd.Version.CreatedUnix.AsLocalTime(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,13 +225,24 @@ type SearchResultResponse struct {
|
|||||||
|
|
||||||
// https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-result
|
// https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-result
|
||||||
type SearchResult struct {
|
type SearchResult struct {
|
||||||
ID string `json:"id"`
|
Authors string `json:"authors"`
|
||||||
Version string `json:"version"`
|
Copyright string `json:"copyright"`
|
||||||
Versions []*SearchResultVersion `json:"versions"`
|
DependencyGroups []*PackageDependencyGroup `json:"dependencyGroups"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Authors string `json:"authors"`
|
IconURL string `json:"iconUrl"`
|
||||||
ProjectURL string `json:"projectURL"`
|
ID string `json:"id"`
|
||||||
RegistrationIndexURL string `json:"registration"`
|
IsPrerelease bool `json:"isPrerelease"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
LicenseURL string `json:"licenseUrl"`
|
||||||
|
ProjectURL string `json:"projectUrl"`
|
||||||
|
RequireLicenseAcceptance bool `json:"requireLicenseAcceptance"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
Tags string `json:"tags"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
TotalDownloads int64 `json:"totalDownloads"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Versions []*SearchResultVersion `json:"versions"`
|
||||||
|
RegistrationIndexURL string `json:"registration"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-result
|
// https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-result
|
||||||
@ -230,11 +278,12 @@ func createSearchResultResponse(l *linkBuilder, totalHits int64, pds []*packages
|
|||||||
func createSearchResult(l *linkBuilder, pds []*packages_model.PackageDescriptor) *SearchResult {
|
func createSearchResult(l *linkBuilder, pds []*packages_model.PackageDescriptor) *SearchResult {
|
||||||
latest := pds[0]
|
latest := pds[0]
|
||||||
versions := make([]*SearchResultVersion, 0, len(pds))
|
versions := make([]*SearchResultVersion, 0, len(pds))
|
||||||
|
totalDownloads := int64(0)
|
||||||
for _, pd := range pds {
|
for _, pd := range pds {
|
||||||
if latest.SemVer.LessThan(pd.SemVer) {
|
if latest.SemVer.LessThan(pd.SemVer) {
|
||||||
latest = pd
|
latest = pd
|
||||||
}
|
}
|
||||||
|
totalDownloads += pd.Version.DownloadCount
|
||||||
versions = append(versions, &SearchResultVersion{
|
versions = append(versions, &SearchResultVersion{
|
||||||
RegistrationLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
RegistrationLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
||||||
Version: pd.Version.Version,
|
Version: pd.Version.Version,
|
||||||
@ -244,12 +293,23 @@ func createSearchResult(l *linkBuilder, pds []*packages_model.PackageDescriptor)
|
|||||||
metadata := latest.Metadata.(*nuget_module.Metadata)
|
metadata := latest.Metadata.(*nuget_module.Metadata)
|
||||||
|
|
||||||
return &SearchResult{
|
return &SearchResult{
|
||||||
ID: latest.Package.Name,
|
Authors: metadata.Authors,
|
||||||
Version: latest.Version.Version,
|
Copyright: metadata.Copyright,
|
||||||
Versions: versions,
|
Description: metadata.Description,
|
||||||
Description: metadata.Description,
|
DependencyGroups: createDependencyGroups(latest),
|
||||||
Authors: metadata.Authors,
|
IconURL: metadata.IconURL,
|
||||||
ProjectURL: metadata.ProjectURL,
|
ID: latest.Package.Name,
|
||||||
RegistrationIndexURL: l.GetRegistrationIndexURL(latest.Package.Name),
|
IsPrerelease: latest.Version.IsPrerelease(),
|
||||||
|
Language: metadata.Language,
|
||||||
|
LicenseURL: metadata.LicenseURL,
|
||||||
|
ProjectURL: metadata.ProjectURL,
|
||||||
|
RequireLicenseAcceptance: metadata.RequireLicenseAcceptance,
|
||||||
|
Summary: metadata.Summary,
|
||||||
|
Tags: metadata.Tags,
|
||||||
|
Title: metadata.Title,
|
||||||
|
TotalDownloads: totalDownloads,
|
||||||
|
Version: latest.Version.Version,
|
||||||
|
Versions: versions,
|
||||||
|
RegistrationIndexURL: l.GetRegistrationIndexURL(latest.Package.Name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ func repoAssignment() func(ctx *context.APIContext) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Check if the user is the same as the repository owner.
|
// Check if the user is the same as the repository owner.
|
||||||
if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(userName) {
|
if ctx.IsSigned && strings.EqualFold(ctx.Doer.LowerName, userName) {
|
||||||
owner = ctx.Doer
|
owner = ctx.Doer
|
||||||
} else {
|
} else {
|
||||||
owner, err = user_model.GetUserByName(ctx, userName)
|
owner, err = user_model.GetUserByName(ctx, userName)
|
||||||
|
@ -276,7 +276,7 @@ func GetRepoPermissions(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/forbidden"
|
// "$ref": "#/responses/forbidden"
|
||||||
|
|
||||||
collaboratorUsername := ctx.PathParam("collaborator")
|
collaboratorUsername := ctx.PathParam("collaborator")
|
||||||
if !ctx.Doer.IsAdmin && ctx.Doer.LowerName != strings.ToLower(collaboratorUsername) && !ctx.IsUserRepoAdmin() {
|
if !ctx.Doer.IsAdmin && !strings.EqualFold(ctx.Doer.LowerName, collaboratorUsername) && !ctx.IsUserRepoAdmin() {
|
||||||
ctx.APIError(http.StatusForbidden, "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")
|
ctx.APIError(http.StatusForbidden, "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -812,7 +812,8 @@ func GetContentsExt(ctx *context.APIContext) {
|
|||||||
// required: true
|
// required: true
|
||||||
// - name: filepath
|
// - name: filepath
|
||||||
// in: path
|
// in: path
|
||||||
// description: path of the dir, file, symlink or submodule in the repo
|
// description: path of the dir, file, symlink or submodule in the repo. Swagger requires path parameter to be "required",
|
||||||
|
// you can leave it empty or pass a single dot (".") to get the root directory.
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
// - name: ref
|
// - name: ref
|
||||||
@ -823,7 +824,8 @@ func GetContentsExt(ctx *context.APIContext) {
|
|||||||
// - name: includes
|
// - name: includes
|
||||||
// in: query
|
// in: query
|
||||||
// description: By default this API's response only contains file's metadata. Use comma-separated "includes" options to retrieve more fields.
|
// description: By default this API's response only contains file's metadata. Use comma-separated "includes" options to retrieve more fields.
|
||||||
// Option "file_content" will try to retrieve the file content, option "lfs_metadata" will try to retrieve LFS metadata.
|
// Option "file_content" will try to retrieve the file content, "lfs_metadata" will try to retrieve LFS metadata,
|
||||||
|
// "commit_metadata" will try to retrieve commit metadata, and "commit_message" will try to retrieve commit message.
|
||||||
// type: string
|
// type: string
|
||||||
// required: false
|
// required: false
|
||||||
// responses:
|
// responses:
|
||||||
@ -832,6 +834,9 @@ func GetContentsExt(ctx *context.APIContext) {
|
|||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
|
if treePath := ctx.PathParam("*"); treePath == "." || treePath == "/" {
|
||||||
|
ctx.SetPathParam("*", "") // workaround for swagger, it requires path parameter to be "required", but we need to list root directory
|
||||||
|
}
|
||||||
opts := files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*")}
|
opts := files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*")}
|
||||||
for includeOpt := range strings.SplitSeq(ctx.FormString("includes"), ",") {
|
for includeOpt := range strings.SplitSeq(ctx.FormString("includes"), ",") {
|
||||||
if includeOpt == "" {
|
if includeOpt == "" {
|
||||||
@ -842,6 +847,10 @@ func GetContentsExt(ctx *context.APIContext) {
|
|||||||
opts.IncludeSingleFileContent = true
|
opts.IncludeSingleFileContent = true
|
||||||
case "lfs_metadata":
|
case "lfs_metadata":
|
||||||
opts.IncludeLfsMetadata = true
|
opts.IncludeLfsMetadata = true
|
||||||
|
case "commit_metadata":
|
||||||
|
opts.IncludeCommitMetadata = true
|
||||||
|
case "commit_message":
|
||||||
|
opts.IncludeCommitMessage = true
|
||||||
default:
|
default:
|
||||||
ctx.APIError(http.StatusBadRequest, fmt.Sprintf("unknown include option %q", includeOpt))
|
ctx.APIError(http.StatusBadRequest, fmt.Sprintf("unknown include option %q", includeOpt))
|
||||||
return
|
return
|
||||||
@ -883,7 +892,11 @@ func GetContents(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/ContentsResponse"
|
// "$ref": "#/responses/ContentsResponse"
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
ret := getRepoContents(ctx, files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*"), IncludeSingleFileContent: true})
|
ret := getRepoContents(ctx, files_service.GetContentsOrListOptions{
|
||||||
|
TreePath: ctx.PathParam("*"),
|
||||||
|
IncludeSingleFileContent: true,
|
||||||
|
IncludeCommitMetadata: true,
|
||||||
|
})
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -669,7 +669,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
|
|||||||
newRepoName = *opts.Name
|
newRepoName = *opts.Name
|
||||||
}
|
}
|
||||||
// Check if repository name has been changed and not just a case change
|
// Check if repository name has been changed and not just a case change
|
||||||
if repo.LowerName != strings.ToLower(newRepoName) {
|
if !strings.EqualFold(repo.LowerName, newRepoName) {
|
||||||
if err := repo_service.ChangeRepositoryName(ctx, ctx.Doer, repo, newRepoName); err != nil {
|
if err := repo_service.ChangeRepositoryName(ctx, ctx.Doer, repo, newRepoName); err != nil {
|
||||||
switch {
|
switch {
|
||||||
case repo_model.IsErrRepoAlreadyExist(err):
|
case repo_model.IsErrRepoAlreadyExist(err):
|
||||||
|
@ -6,6 +6,7 @@ package common
|
|||||||
import (
|
import (
|
||||||
goctx "context"
|
goctx "context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"sync"
|
||||||
|
|
||||||
activities_model "code.gitea.io/gitea/models/activities"
|
activities_model "code.gitea.io/gitea/models/activities"
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
@ -22,8 +23,7 @@ type StopwatchTmplInfo struct {
|
|||||||
Seconds int64
|
Seconds int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func getActiveStopwatch(goCtx goctx.Context) *StopwatchTmplInfo {
|
func getActiveStopwatch(ctx *context.Context) *StopwatchTmplInfo {
|
||||||
ctx := context.GetWebContext(goCtx)
|
|
||||||
if ctx.Doer == nil {
|
if ctx.Doer == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -48,8 +48,7 @@ func getActiveStopwatch(goCtx goctx.Context) *StopwatchTmplInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func notificationUnreadCount(goCtx goctx.Context) int64 {
|
func notificationUnreadCount(ctx *context.Context) int64 {
|
||||||
ctx := context.GetWebContext(goCtx)
|
|
||||||
if ctx.Doer == nil {
|
if ctx.Doer == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -66,10 +65,19 @@ func notificationUnreadCount(goCtx goctx.Context) int64 {
|
|||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
func PageTmplFunctions(ctx *context.Context) {
|
type pageGlobalDataType struct {
|
||||||
if ctx.IsSigned {
|
IsSigned bool
|
||||||
// defer the function call to the last moment when the tmpl renders
|
IsSiteAdmin bool
|
||||||
ctx.Data["NotificationUnreadCount"] = notificationUnreadCount
|
|
||||||
ctx.Data["GetActiveStopwatch"] = getActiveStopwatch
|
GetNotificationUnreadCount func() int64
|
||||||
}
|
GetActiveStopwatch func() *StopwatchTmplInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func PageGlobalData(ctx *context.Context) {
|
||||||
|
var data pageGlobalDataType
|
||||||
|
data.IsSigned = ctx.Doer != nil
|
||||||
|
data.IsSiteAdmin = ctx.Doer != nil && ctx.Doer.IsAdmin
|
||||||
|
data.GetNotificationUnreadCount = sync.OnceValue(func() int64 { return notificationUnreadCount(ctx) })
|
||||||
|
data.GetActiveStopwatch = sync.OnceValue(func() *StopwatchTmplInfo { return getActiveStopwatch(ctx) })
|
||||||
|
ctx.Data["PageGlobalData"] = data
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
"html/template"
|
"html/template"
|
||||||
@ -15,7 +14,7 @@ import (
|
|||||||
|
|
||||||
"code.gitea.io/gitea/models/auth"
|
"code.gitea.io/gitea/models/auth"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/auth/httpauth"
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
@ -108,9 +107,8 @@ func InfoOAuth(ctx *context.Context) {
|
|||||||
|
|
||||||
var accessTokenScope auth.AccessTokenScope
|
var accessTokenScope auth.AccessTokenScope
|
||||||
if auHead := ctx.Req.Header.Get("Authorization"); auHead != "" {
|
if auHead := ctx.Req.Header.Get("Authorization"); auHead != "" {
|
||||||
auths := strings.Fields(auHead)
|
if parsed, ok := httpauth.ParseAuthorizationHeader(auHead); ok && parsed.BearerToken != nil {
|
||||||
if len(auths) == 2 && (auths[0] == "token" || strings.ToLower(auths[0]) == "bearer") {
|
accessTokenScope, _ = auth_service.GetOAuthAccessTokenScopeAndUserID(ctx, parsed.BearerToken.Token)
|
||||||
accessTokenScope, _ = auth_service.GetOAuthAccessTokenScopeAndUserID(ctx, auths[1])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,18 +125,12 @@ func InfoOAuth(ctx *context.Context) {
|
|||||||
ctx.JSON(http.StatusOK, response)
|
ctx.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseBasicAuth(ctx *context.Context) (username, password string, err error) {
|
|
||||||
authHeader := ctx.Req.Header.Get("Authorization")
|
|
||||||
if authType, authData, ok := strings.Cut(authHeader, " "); ok && strings.EqualFold(authType, "Basic") {
|
|
||||||
return base.BasicAuthDecode(authData)
|
|
||||||
}
|
|
||||||
return "", "", errors.New("invalid basic authentication")
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntrospectOAuth introspects an oauth token
|
// IntrospectOAuth introspects an oauth token
|
||||||
func IntrospectOAuth(ctx *context.Context) {
|
func IntrospectOAuth(ctx *context.Context) {
|
||||||
clientIDValid := false
|
clientIDValid := false
|
||||||
if clientID, clientSecret, err := parseBasicAuth(ctx); err == nil {
|
authHeader := ctx.Req.Header.Get("Authorization")
|
||||||
|
if parsed, ok := httpauth.ParseAuthorizationHeader(authHeader); ok && parsed.BasicAuth != nil {
|
||||||
|
clientID, clientSecret := parsed.BasicAuth.Username, parsed.BasicAuth.Password
|
||||||
app, err := auth.GetOAuth2ApplicationByClientID(ctx, clientID)
|
app, err := auth.GetOAuth2ApplicationByClientID(ctx, clientID)
|
||||||
if err != nil && !auth.IsErrOauthClientIDInvalid(err) {
|
if err != nil && !auth.IsErrOauthClientIDInvalid(err) {
|
||||||
// this is likely a database error; log it and respond without details
|
// this is likely a database error; log it and respond without details
|
||||||
@ -170,9 +162,7 @@ func IntrospectOAuth(ctx *context.Context) {
|
|||||||
if err == nil && app != nil {
|
if err == nil && app != nil {
|
||||||
response.Active = true
|
response.Active = true
|
||||||
response.Scope = grant.Scope
|
response.Scope = grant.Scope
|
||||||
response.Issuer = setting.AppURL
|
response.RegisteredClaims = oauth2_provider.NewJwtRegisteredClaimsFromUser(app.ClientID, grant.UserID, nil /*exp*/)
|
||||||
response.Audience = []string{app.ClientID}
|
|
||||||
response.Subject = strconv.FormatInt(grant.UserID, 10)
|
|
||||||
}
|
}
|
||||||
if user, err := user_model.GetUserByID(ctx, grant.UserID); err == nil {
|
if user, err := user_model.GetUserByID(ctx, grant.UserID); err == nil {
|
||||||
response.Username = user.Name
|
response.Username = user.Name
|
||||||
@ -432,7 +422,14 @@ func GrantApplicationOAuth(ctx *context.Context) {
|
|||||||
|
|
||||||
// OIDCWellKnown generates JSON so OIDC clients know Gitea's capabilities
|
// OIDCWellKnown generates JSON so OIDC clients know Gitea's capabilities
|
||||||
func OIDCWellKnown(ctx *context.Context) {
|
func OIDCWellKnown(ctx *context.Context) {
|
||||||
ctx.Data["SigningKey"] = oauth2_provider.DefaultSigningKey
|
if !setting.OAuth2.Enabled {
|
||||||
|
http.NotFound(ctx.Resp, ctx.Req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
jwtRegisteredClaims := oauth2_provider.NewJwtRegisteredClaimsFromUser("well-known", 0, nil)
|
||||||
|
ctx.Data["OidcIssuer"] = jwtRegisteredClaims.Issuer // use the consistent issuer from the JWT registered claims
|
||||||
|
ctx.Data["OidcBaseUrl"] = strings.TrimSuffix(setting.AppURL, "/")
|
||||||
|
ctx.Data["SigningKeyMethodAlg"] = oauth2_provider.DefaultSigningKey.SigningMethod().Alg()
|
||||||
ctx.JSONTemplate("user/auth/oidc_wellknown")
|
ctx.JSONTemplate("user/auth/oidc_wellknown")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,16 +462,16 @@ func AccessTokenOAuth(ctx *context.Context) {
|
|||||||
form := *web.GetForm(ctx).(*forms.AccessTokenForm)
|
form := *web.GetForm(ctx).(*forms.AccessTokenForm)
|
||||||
// if there is no ClientID or ClientSecret in the request body, fill these fields by the Authorization header and ensure the provided field matches the Authorization header
|
// if there is no ClientID or ClientSecret in the request body, fill these fields by the Authorization header and ensure the provided field matches the Authorization header
|
||||||
if form.ClientID == "" || form.ClientSecret == "" {
|
if form.ClientID == "" || form.ClientSecret == "" {
|
||||||
authHeader := ctx.Req.Header.Get("Authorization")
|
if authHeader := ctx.Req.Header.Get("Authorization"); authHeader != "" {
|
||||||
if authType, authData, ok := strings.Cut(authHeader, " "); ok && strings.EqualFold(authType, "Basic") {
|
parsed, ok := httpauth.ParseAuthorizationHeader(authHeader)
|
||||||
clientID, clientSecret, err := base.BasicAuthDecode(authData)
|
if !ok || parsed.BasicAuth == nil {
|
||||||
if err != nil {
|
|
||||||
handleAccessTokenError(ctx, oauth2_provider.AccessTokenError{
|
handleAccessTokenError(ctx, oauth2_provider.AccessTokenError{
|
||||||
ErrorCode: oauth2_provider.AccessTokenErrorCodeInvalidRequest,
|
ErrorCode: oauth2_provider.AccessTokenErrorCodeInvalidRequest,
|
||||||
ErrorDescription: "cannot parse basic auth header",
|
ErrorDescription: "cannot parse basic auth header",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
clientID, clientSecret := parsed.BasicAuth.Username, parsed.BasicAuth.Password
|
||||||
// validate that any fields present in the form match the Basic auth header
|
// validate that any fields present in the form match the Basic auth header
|
||||||
if form.ClientID != "" && form.ClientID != clientID {
|
if form.ClientID != "" && form.ClientID != clientID {
|
||||||
handleAccessTokenError(ctx, oauth2_provider.AccessTokenError{
|
handleAccessTokenError(ctx, oauth2_provider.AccessTokenError{
|
||||||
|
@ -249,7 +249,7 @@ func ViewPost(ctx *context_module.Context) {
|
|||||||
ID: v.ID,
|
ID: v.ID,
|
||||||
Name: v.Name,
|
Name: v.Name,
|
||||||
Status: v.Status.String(),
|
Status: v.Status.String(),
|
||||||
CanRerun: v.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions),
|
CanRerun: resp.State.Run.CanRerun,
|
||||||
Duration: v.Duration().String(),
|
Duration: v.Duration().String(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -445,7 +445,7 @@ func Rerun(ctx *context_module.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.JSON(http.StatusOK, struct{}{})
|
ctx.JSONOK()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,12 +460,12 @@ func Rerun(ctx *context_module.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, struct{}{})
|
ctx.JSONOK()
|
||||||
}
|
}
|
||||||
|
|
||||||
func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shouldBlock bool) error {
|
func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shouldBlock bool) error {
|
||||||
status := job.Status
|
status := job.Status
|
||||||
if !status.IsDone() {
|
if !status.IsDone() || !job.Run.Status.IsDone() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,10 +166,13 @@ func Graph(ctx *context.Context) {
|
|||||||
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
||||||
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
||||||
|
|
||||||
|
divOnly := ctx.FormBool("div-only")
|
||||||
|
queryParams := ctx.Req.URL.Query()
|
||||||
|
queryParams.Del("div-only")
|
||||||
paginator := context.NewPagination(int(graphCommitsCount), setting.UI.GraphMaxCommitNum, page, 5)
|
paginator := context.NewPagination(int(graphCommitsCount), setting.UI.GraphMaxCommitNum, page, 5)
|
||||||
paginator.AddParamFromRequest(ctx.Req)
|
paginator.AddParamFromQuery(queryParams)
|
||||||
ctx.Data["Page"] = paginator
|
ctx.Data["Page"] = paginator
|
||||||
if ctx.FormBool("div-only") {
|
if divOnly {
|
||||||
ctx.HTML(http.StatusOK, tplGraphDiv)
|
ctx.HTML(http.StatusOK, tplGraphDiv)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -443,6 +443,10 @@ func ViewPullMergeBox(ctx *context.Context) {
|
|||||||
preparePullViewPullInfo(ctx, issue)
|
preparePullViewPullInfo(ctx, issue)
|
||||||
preparePullViewReviewAndMerge(ctx, issue)
|
preparePullViewReviewAndMerge(ctx, issue)
|
||||||
ctx.Data["PullMergeBoxReloading"] = issue.PullRequest.IsChecking()
|
ctx.Data["PullMergeBoxReloading"] = issue.PullRequest.IsChecking()
|
||||||
|
|
||||||
|
// TODO: it should use a dedicated struct to render the pull merge box, to make sure all data is prepared correctly
|
||||||
|
ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.Doer.ID)
|
||||||
|
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
|
||||||
ctx.HTML(http.StatusOK, tplPullMergeBox)
|
ctx.HTML(http.StatusOK, tplPullMergeBox)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ func handleSettingsPostUpdate(ctx *context.Context) {
|
|||||||
|
|
||||||
newRepoName := form.RepoName
|
newRepoName := form.RepoName
|
||||||
// Check if repository name has been changed.
|
// Check if repository name has been changed.
|
||||||
if repo.LowerName != strings.ToLower(newRepoName) {
|
if !strings.EqualFold(repo.LowerName, newRepoName) {
|
||||||
// Close the GitRepo if open
|
// Close the GitRepo if open
|
||||||
if ctx.Repo.GitRepo != nil {
|
if ctx.Repo.GitRepo != nil {
|
||||||
ctx.Repo.GitRepo.Close()
|
ctx.Repo.GitRepo.Close()
|
||||||
|
@ -198,7 +198,6 @@ type webhookParams struct {
|
|||||||
|
|
||||||
URL string
|
URL string
|
||||||
ContentType webhook.HookContentType
|
ContentType webhook.HookContentType
|
||||||
Secret string
|
|
||||||
HTTPMethod string
|
HTTPMethod string
|
||||||
WebhookForm forms.WebhookForm
|
WebhookForm forms.WebhookForm
|
||||||
Meta any
|
Meta any
|
||||||
@ -237,7 +236,7 @@ func createWebhook(ctx *context.Context, params webhookParams) {
|
|||||||
URL: params.URL,
|
URL: params.URL,
|
||||||
HTTPMethod: params.HTTPMethod,
|
HTTPMethod: params.HTTPMethod,
|
||||||
ContentType: params.ContentType,
|
ContentType: params.ContentType,
|
||||||
Secret: params.Secret,
|
Secret: params.WebhookForm.Secret,
|
||||||
HookEvent: ParseHookEvent(params.WebhookForm),
|
HookEvent: ParseHookEvent(params.WebhookForm),
|
||||||
IsActive: params.WebhookForm.Active,
|
IsActive: params.WebhookForm.Active,
|
||||||
Type: params.Type,
|
Type: params.Type,
|
||||||
@ -290,7 +289,7 @@ func editWebhook(ctx *context.Context, params webhookParams) {
|
|||||||
|
|
||||||
w.URL = params.URL
|
w.URL = params.URL
|
||||||
w.ContentType = params.ContentType
|
w.ContentType = params.ContentType
|
||||||
w.Secret = params.Secret
|
w.Secret = params.WebhookForm.Secret
|
||||||
w.HookEvent = ParseHookEvent(params.WebhookForm)
|
w.HookEvent = ParseHookEvent(params.WebhookForm)
|
||||||
w.IsActive = params.WebhookForm.Active
|
w.IsActive = params.WebhookForm.Active
|
||||||
w.HTTPMethod = params.HTTPMethod
|
w.HTTPMethod = params.HTTPMethod
|
||||||
@ -336,7 +335,6 @@ func giteaHookParams(ctx *context.Context) webhookParams {
|
|||||||
Type: webhook_module.GITEA,
|
Type: webhook_module.GITEA,
|
||||||
URL: form.PayloadURL,
|
URL: form.PayloadURL,
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
Secret: form.Secret,
|
|
||||||
HTTPMethod: form.HTTPMethod,
|
HTTPMethod: form.HTTPMethod,
|
||||||
WebhookForm: form.WebhookForm,
|
WebhookForm: form.WebhookForm,
|
||||||
}
|
}
|
||||||
@ -364,7 +362,6 @@ func gogsHookParams(ctx *context.Context) webhookParams {
|
|||||||
Type: webhook_module.GOGS,
|
Type: webhook_module.GOGS,
|
||||||
URL: form.PayloadURL,
|
URL: form.PayloadURL,
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
Secret: form.Secret,
|
|
||||||
WebhookForm: form.WebhookForm,
|
WebhookForm: form.WebhookForm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ package repo
|
|||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
pull_model "code.gitea.io/gitea/models/pull"
|
pull_model "code.gitea.io/gitea/models/pull"
|
||||||
@ -111,7 +112,7 @@ func transformDiffTreeForWeb(renderedIconPool *fileicon.RenderedIconPool, diffTr
|
|||||||
item := &WebDiffFileItem{FullName: file.HeadPath, DiffStatus: file.Status}
|
item := &WebDiffFileItem{FullName: file.HeadPath, DiffStatus: file.Status}
|
||||||
item.IsViewed = filesViewedState[item.FullName] == pull_model.Viewed
|
item.IsViewed = filesViewedState[item.FullName] == pull_model.Viewed
|
||||||
item.NameHash = git.HashFilePathForWebUI(item.FullName)
|
item.NameHash = git.HashFilePathForWebUI(item.FullName)
|
||||||
item.FileIcon = fileicon.RenderEntryIconHTML(renderedIconPool, &fileicon.EntryInfo{FullName: file.HeadPath, EntryMode: file.HeadMode})
|
item.FileIcon = fileicon.RenderEntryIconHTML(renderedIconPool, &fileicon.EntryInfo{BaseName: path.Base(file.HeadPath), EntryMode: file.HeadMode})
|
||||||
|
|
||||||
switch file.HeadMode {
|
switch file.HeadMode {
|
||||||
case git.EntryModeTree:
|
case git.EntryModeTree:
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -260,7 +261,9 @@ func prepareDirectoryFileIcons(ctx *context.Context, files []git.CommitInfo) {
|
|||||||
renderedIconPool := fileicon.NewRenderedIconPool()
|
renderedIconPool := fileicon.NewRenderedIconPool()
|
||||||
fileIcons := map[string]template.HTML{}
|
fileIcons := map[string]template.HTML{}
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
fileIcons[f.Entry.Name()] = fileicon.RenderEntryIconHTML(renderedIconPool, fileicon.EntryInfoFromGitTreeEntry(f.Entry))
|
fullPath := path.Join(ctx.Repo.TreePath, f.Entry.Name())
|
||||||
|
entryInfo := fileicon.EntryInfoFromGitTreeEntry(ctx.Repo.Commit, fullPath, f.Entry)
|
||||||
|
fileIcons[f.Entry.Name()] = fileicon.RenderEntryIconHTML(renderedIconPool, entryInfo)
|
||||||
}
|
}
|
||||||
fileIcons[".."] = fileicon.RenderEntryIconHTML(renderedIconPool, fileicon.EntryInfoFolder())
|
fileIcons[".."] = fileicon.RenderEntryIconHTML(renderedIconPool, fileicon.EntryInfoFolder())
|
||||||
ctx.Data["FileIcons"] = fileIcons
|
ctx.Data["FileIcons"] = fileIcons
|
||||||
|