mirror of
https://github.com/go-gitea/gitea.git
synced 2024-09-01 14:56:30 +00:00
Merge branch 'main' into feature-pin-repos
This commit is contained in:
commit
9479423403
@ -10,7 +10,8 @@
|
||||
"ghcr.io/devcontainers-contrib/features/poetry:2": {},
|
||||
"ghcr.io/devcontainers/features/python:1": {
|
||||
"version": "3.12"
|
||||
}
|
||||
},
|
||||
"ghcr.io/warrenbuckley/codespace-features/sqlite:1": {}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
@ -25,7 +26,7 @@
|
||||
"Vue.volar",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"vitest.explorer",
|
||||
"qwtel.sqlite-viewer",
|
||||
"cweijan.vscode-database-client2",
|
||||
"GitHub.vscode-pull-request-github",
|
||||
"Azurite.azurite"
|
||||
]
|
||||
|
@ -324,7 +324,7 @@ rules:
|
||||
jquery/no-sizzle: [2]
|
||||
jquery/no-slide: [2]
|
||||
jquery/no-submit: [2]
|
||||
jquery/no-text: [0]
|
||||
jquery/no-text: [2]
|
||||
jquery/no-toggle: [2]
|
||||
jquery/no-trigger: [0]
|
||||
jquery/no-trim: [2]
|
||||
@ -477,7 +477,7 @@ rules:
|
||||
no-jquery/no-slide: [2]
|
||||
no-jquery/no-sub: [2]
|
||||
no-jquery/no-support: [2]
|
||||
no-jquery/no-text: [0]
|
||||
no-jquery/no-text: [2]
|
||||
no-jquery/no-trigger: [0]
|
||||
no-jquery/no-trim: [2]
|
||||
no-jquery/no-type: [2]
|
||||
@ -798,7 +798,7 @@ rules:
|
||||
unicorn/prefer-object-has-own: [0]
|
||||
unicorn/prefer-optional-catch-binding: [2]
|
||||
unicorn/prefer-prototype-methods: [0]
|
||||
unicorn/prefer-query-selector: [0]
|
||||
unicorn/prefer-query-selector: [2]
|
||||
unicorn/prefer-reflect-apply: [0]
|
||||
unicorn/prefer-regexp-test: [2]
|
||||
unicorn/prefer-set-has: [0]
|
||||
|
@ -43,7 +43,7 @@ vscode:
|
||||
- Vue.volar
|
||||
- ms-azuretools.vscode-docker
|
||||
- vitest.explorer
|
||||
- qwtel.sqlite-viewer
|
||||
- cweijan.vscode-database-client2
|
||||
- GitHub.vscode-pull-request-github
|
||||
|
||||
ports:
|
||||
|
18
Makefile
18
Makefile
@ -25,10 +25,10 @@ COMMA := ,
|
||||
|
||||
XGO_VERSION := go-1.22.x
|
||||
|
||||
AIR_PACKAGE ?= github.com/cosmtrek/air@v1
|
||||
AIR_PACKAGE ?= github.com/air-verse/air@v1
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.7.0
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.6.0
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.57.2
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.0
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
|
||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.5.1
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@db51e79a0e37c572d8b59ae0c58bf2bbbbe53285
|
||||
@ -36,6 +36,7 @@ XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1
|
||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
|
||||
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1
|
||||
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.15.3
|
||||
|
||||
DOCKER_IMAGE ?= gitea/gitea
|
||||
DOCKER_TAG ?= latest
|
||||
@ -213,6 +214,7 @@ help:
|
||||
@echo " - lint-go lint go files"
|
||||
@echo " - lint-go-fix lint go files and fix issues"
|
||||
@echo " - lint-go-vet lint go files with vet"
|
||||
@echo " - lint-go-gopls lint go files with gopls"
|
||||
@echo " - lint-js lint js files"
|
||||
@echo " - lint-js-fix lint js files and fix issues"
|
||||
@echo " - lint-css lint css files"
|
||||
@ -366,7 +368,7 @@ lint-frontend: lint-js lint-css
|
||||
lint-frontend-fix: lint-js-fix lint-css-fix
|
||||
|
||||
.PHONY: lint-backend
|
||||
lint-backend: lint-go lint-go-vet lint-editorconfig
|
||||
lint-backend: lint-go lint-go-vet lint-go-gopls lint-editorconfig
|
||||
|
||||
.PHONY: lint-backend-fix
|
||||
lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig
|
||||
@ -424,6 +426,11 @@ lint-go-vet:
|
||||
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
|
||||
@$(GO) vet -vettool=gitea-vet ./...
|
||||
|
||||
.PHONY: lint-go-gopls
|
||||
lint-go-gopls:
|
||||
@echo "Running gopls check..."
|
||||
@GO=$(GO) GOPLS_PACKAGE=$(GOPLS_PACKAGE) tools/lint-go-gopls.sh $(GO_SOURCES_NO_BINDATA)
|
||||
|
||||
.PHONY: lint-editorconfig
|
||||
lint-editorconfig:
|
||||
@$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) $(EDITORCONFIG_FILES)
|
||||
@ -864,13 +871,14 @@ deps-tools:
|
||||
$(GO) install $(GO_LICENSES_PACKAGE)
|
||||
$(GO) install $(GOVULNCHECK_PACKAGE)
|
||||
$(GO) install $(ACTIONLINT_PACKAGE)
|
||||
$(GO) install $(GOPLS_PACKAGE)
|
||||
|
||||
node_modules: package-lock.json
|
||||
npm install --no-save
|
||||
@touch node_modules
|
||||
|
||||
.venv: poetry.lock
|
||||
poetry install --no-root
|
||||
poetry install
|
||||
@touch .venv
|
||||
|
||||
.PHONY: update
|
||||
@ -887,7 +895,7 @@ update-js: node-check | node_modules
|
||||
update-py: node-check | node_modules
|
||||
npx updates -u -f pyproject.toml
|
||||
rm -rf .venv poetry.lock
|
||||
poetry install --no-root
|
||||
poetry install
|
||||
@touch .venv
|
||||
|
||||
.PHONY: fomantic
|
||||
|
@ -5,7 +5,9 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"strings"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
@ -194,8 +196,20 @@ func migrateActionsLog(ctx context.Context, dstStorage storage.ObjectStorage) er
|
||||
|
||||
func migrateActionsArtifacts(ctx context.Context, dstStorage storage.ObjectStorage) error {
|
||||
return db.Iterate(ctx, nil, func(ctx context.Context, artifact *actions_model.ActionArtifact) error {
|
||||
_, err := storage.Copy(dstStorage, artifact.ArtifactPath, storage.ActionsArtifacts, artifact.ArtifactPath)
|
||||
return err
|
||||
if artifact.Status == int64(actions_model.ArtifactStatusExpired) {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := storage.Copy(dstStorage, artifact.StoragePath, storage.ActionsArtifacts, artifact.StoragePath)
|
||||
if err != nil {
|
||||
// ignore files that do not exist
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1334,6 +1334,9 @@ LEVEL = Info
|
||||
;;
|
||||
;; Maximum allowed file size in bytes to render CSV files as table. (Set to 0 for no limit).
|
||||
;MAX_FILE_SIZE = 524288
|
||||
;;
|
||||
;; Maximum allowed rows to render CSV files. (Set to 0 for no limit)
|
||||
;MAX_ROWS = 2500
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -1687,6 +1690,16 @@ LEVEL = Info
|
||||
;; convert \r\n to \n for Sendmail
|
||||
;SENDMAIL_CONVERT_CRLF = true
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[mailer.override_header]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; This is empty by default, use it only if you know what you need it for.
|
||||
;Reply-To = test@example.com, test2@example.com
|
||||
;Content-Type = text/html; charset=utf-8
|
||||
;In-Reply-To =
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[email.incoming]
|
||||
|
@ -724,11 +724,13 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||
|
||||
## Mailer (`mailer`)
|
||||
|
||||
⚠️ This section is for Gitea 1.18 and later. If you are using Gitea 1.17 or older,
|
||||
:::warning
|
||||
This section is for Gitea 1.18 and later. If you are using Gitea 1.17 or older,
|
||||
please refer to
|
||||
[Gitea 1.17 app.ini example](https://github.com/go-gitea/gitea/blob/release/v1.17/custom/conf/app.example.ini)
|
||||
and
|
||||
[Gitea 1.17 configuration document](https://github.com/go-gitea/gitea/blob/release/v1.17/docs/content/doc/advanced/config-cheat-sheet.en-us.md)
|
||||
:::
|
||||
|
||||
- `ENABLED`: **false**: Enable to use a mail service.
|
||||
- `PROTOCOL`: **_empty_**: Mail server protocol. One of "smtp", "smtps", "smtp+starttls", "smtp+unix", "sendmail", "dummy". _Before 1.18, this was inferred from a combination of `MAILER_TYPE` and `IS_TLS_ENABLED`._
|
||||
@ -761,6 +763,21 @@ and
|
||||
- `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue. **DEPRECATED** use `LENGTH` in `[queue.mailer]`
|
||||
- `SEND_AS_PLAIN_TEXT`: **false**: Send mails only in plain text, without HTML alternative.
|
||||
|
||||
## Override Email Headers (`mailer.override_header`)
|
||||
|
||||
:::warning
|
||||
This is empty by default, use it only if you know what you need it for.
|
||||
:::
|
||||
|
||||
examples would be:
|
||||
|
||||
```ini
|
||||
[mailer.override_header]
|
||||
Reply-To = test@example.com, test2@example.com
|
||||
Content-Type = text/html; charset=utf-8
|
||||
In-Reply-To =
|
||||
```
|
||||
|
||||
## Incoming Email (`email.incoming`)
|
||||
|
||||
- `ENABLED`: **false**: Enable handling of incoming emails.
|
||||
|
@ -47,7 +47,7 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h
|
||||
9. Avoid unnecessary `!important` in CSS, add comments to explain why it's necessary if it can't be avoided.
|
||||
10. Avoid mixing different events in one event listener, prefer to use individual event listeners for every event.
|
||||
11. Custom event names are recommended to use `ce-` prefix.
|
||||
12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-word-break`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`).
|
||||
12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-ellipsis`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`).
|
||||
13. Avoid inline scripts & styles as much as possible, it's recommended to put JS code into JS files and use CSS classes. If inline scripts & styles are unavoidable, explain the reason why it can't be avoided.
|
||||
|
||||
### Accessibility / ARIA
|
||||
|
@ -47,7 +47,7 @@ HTML 页面由[Go HTML Template](https://pkg.go.dev/html/template)渲染。
|
||||
9. 避免在 CSS 中使用不必要的`!important`,如果无法避免,添加注释解释为什么需要它。
|
||||
10. 避免在一个事件监听器中混合不同的事件,优先为每个事件使用独立的事件监听器。
|
||||
11. 推荐使用自定义事件名称前缀`ce-`。
|
||||
12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-word-break`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。
|
||||
12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-ellipsis`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。
|
||||
13. 尽量避免内联脚本和样式,建议将JS代码放入JS文件中并使用CSS类。如果内联脚本和样式不可避免,请解释无法避免的原因。
|
||||
|
||||
### 可访问性 / ARIA
|
||||
|
@ -44,6 +44,8 @@ You can use the following variables enclosed in `${}` inside these templates whi
|
||||
- PullRequestIndex: Pull request's index number
|
||||
- PullRequestReference: Pull request's reference char with index number. i.e. #1, !2
|
||||
- ClosingIssues: return a string contains all issues which will be closed by this pull request i.e. `close #1, close #2`
|
||||
- ReviewedOn: Which pull request this commit belongs to. For example `Reviewed-on: https://gitea.com/foo/bar/pulls/1`
|
||||
- ReviewedBy: Who approved the pull request before the merge. For example `Reviewed-by: Jane Doe <jane.doe@example.com>`
|
||||
|
||||
## Rebase
|
||||
|
||||
|
6
flake.lock
generated
6
flake.lock
generated
@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1715534503,
|
||||
"narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
|
||||
"lastModified": 1717974879,
|
||||
"narHash": "sha256-GTO3C88+5DX171F/gVS3Qga/hOs/eRMxPFpiHq2t+D8=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
|
||||
"rev": "c7b821ba2e1e635ba5a76d299af62821cbcb09f3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
19
go.mod
19
go.mod
@ -20,7 +20,7 @@ require (
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358
|
||||
github.com/ProtonMail/go-crypto v1.0.0
|
||||
github.com/PuerkitoBio/goquery v1.9.1
|
||||
github.com/alecthomas/chroma/v2 v2.13.0
|
||||
github.com/alecthomas/chroma/v2 v2.14.0
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
||||
github.com/blevesearch/bleve/v2 v2.3.10
|
||||
github.com/buildkite/terminal-to-html/v3 v3.11.0
|
||||
@ -108,13 +108,13 @@ require (
|
||||
github.com/yuin/goldmark v1.7.0
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||
github.com/yuin/goldmark-meta v1.1.0
|
||||
golang.org/x/crypto v0.22.0
|
||||
golang.org/x/crypto v0.24.0
|
||||
golang.org/x/image v0.15.0
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/oauth2 v0.18.0
|
||||
golang.org/x/sys v0.19.0
|
||||
golang.org/x/text v0.14.0
|
||||
golang.org/x/tools v0.19.0
|
||||
golang.org/x/sys v0.21.0
|
||||
golang.org/x/text v0.16.0
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
|
||||
google.golang.org/grpc v1.62.1
|
||||
google.golang.org/protobuf v1.33.0
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
@ -293,8 +293,8 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f // indirect
|
||||
golang.org/x/mod v0.16.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect
|
||||
@ -311,6 +311,9 @@ replace github.com/nektos/act => gitea.com/gitea/act v0.259.1
|
||||
|
||||
replace github.com/gorilla/feeds => github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5
|
||||
|
||||
// TODO: This could be removed after https://github.com/mholt/archiver/pull/396 merged
|
||||
replace github.com/mholt/archiver/v3 => github.com/anchore/archiver/v3 v3.5.2
|
||||
|
||||
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
||||
|
||||
exclude github.com/gofrs/uuid v4.0.0+incompatible
|
||||
|
43
go.sum
43
go.sum
@ -82,16 +82,18 @@ github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06
|
||||
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
|
||||
github.com/RoaringBitmap/roaring v1.9.0 h1:lwKhr90/j0jVXJyh5X+vQN1VVn77rQFfYnh6RDRGCcE=
|
||||
github.com/RoaringBitmap/roaring v1.9.0/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
|
||||
github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU=
|
||||
github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=
|
||||
github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
|
||||
github.com/alecthomas/chroma/v2 v2.13.0 h1:VP72+99Fb2zEcYM0MeaWJmV+xQvz5v5cxRHd+ooU1lI=
|
||||
github.com/alecthomas/chroma/v2 v2.13.0/go.mod h1:BUGjjsD+ndS6eX37YgTchSEG+Jg9Jv1GiZs9sqPqztk=
|
||||
github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E=
|
||||
github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I=
|
||||
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA=
|
||||
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/anchore/archiver/v3 v3.5.2 h1:Bjemm2NzuRhmHy3m0lRe5tNoClB9A4zYyDV58PaB6aA=
|
||||
github.com/anchore/archiver/v3 v3.5.2/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
@ -564,8 +566,6 @@ github.com/meilisearch/meilisearch-go v0.26.2 h1:3gTlmiV1dHHumVUhYdJbvh3camiNiyq
|
||||
github.com/meilisearch/meilisearch-go v0.26.2/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
|
||||
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
|
||||
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
|
||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
|
||||
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
|
||||
github.com/microsoft/go-mssqldb v1.7.0 h1:sgMPW0HA6Ihd37Yx0MzHyKD726C2kY/8KJsQtXHNaAs=
|
||||
@ -866,8 +866,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f h1:3CW0unweImhOzd5FmYuRsD4Y4oQFKZIjAnKbjV4WIrw=
|
||||
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
||||
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
|
||||
@ -878,8 +878,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@ -900,8 +900,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -912,8 +912,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -951,8 +951,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
@ -962,8 +962,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@ -975,8 +975,9 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -991,8 +992,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -32,7 +32,9 @@ func (comments CommentList) LoadPosters(ctx context.Context) error {
|
||||
}
|
||||
|
||||
for _, comment := range comments {
|
||||
comment.Poster = getPoster(comment.PosterID, posterMaps)
|
||||
if comment.Poster == nil {
|
||||
comment.Poster = getPoster(comment.PosterID, posterMaps)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -87,7 +87,9 @@ func (issues IssueList) LoadPosters(ctx context.Context) error {
|
||||
}
|
||||
|
||||
for _, issue := range issues {
|
||||
issue.Poster = getPoster(issue.PosterID, posterMaps)
|
||||
if issue.Poster == nil {
|
||||
issue.Poster = getPoster(issue.PosterID, posterMaps)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ func addObjectFormatNameToRepository(x *xorm.Engine) error {
|
||||
|
||||
// Here to catch weird edge-cases where column constraints above are
|
||||
// not applied by the DB backend
|
||||
_, err := x.Exec("UPDATE repository set object_format_name = 'sha1' WHERE object_format_name = '' or object_format_name IS NULL")
|
||||
_, err := x.Exec("UPDATE `repository` set `object_format_name` = 'sha1' WHERE `object_format_name` = '' or `object_format_name` IS NULL")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,13 @@ func (repo *Repository) relAvatarLink(ctx context.Context) string {
|
||||
return setting.AppSubURL + "/repo-avatars/" + url.PathEscape(repo.Avatar)
|
||||
}
|
||||
|
||||
// AvatarLink returns the full avatar url with http host. TODO: refactor it to a relative URL, but it is still used in API response at the moment
|
||||
// AvatarLink returns the full avatar url with http host or the empty string if the repo doesn't have an avatar.
|
||||
//
|
||||
// TODO: refactor it to a relative URL, but it is still used in API response at the moment
|
||||
func (repo *Repository) AvatarLink(ctx context.Context) string {
|
||||
return httplib.MakeAbsoluteURL(ctx, repo.relAvatarLink(ctx))
|
||||
relLink := repo.relAvatarLink(ctx)
|
||||
if relLink != "" {
|
||||
return httplib.MakeAbsoluteURL(ctx, relLink)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ package markup
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"regexp"
|
||||
@ -15,6 +13,8 @@ import (
|
||||
"code.gitea.io/gitea/modules/csv"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -81,86 +81,38 @@ func writeField(w io.Writer, element, class, field string) error {
|
||||
func (r Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
|
||||
tmpBlock := bufio.NewWriter(output)
|
||||
maxSize := setting.UI.CSV.MaxFileSize
|
||||
maxRows := setting.UI.CSV.MaxRows
|
||||
|
||||
if maxSize == 0 {
|
||||
return r.tableRender(ctx, input, tmpBlock)
|
||||
if maxSize != 0 {
|
||||
input = io.LimitReader(input, maxSize+1)
|
||||
}
|
||||
|
||||
rawBytes, err := io.ReadAll(io.LimitReader(input, maxSize+1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if int64(len(rawBytes)) <= maxSize {
|
||||
return r.tableRender(ctx, bytes.NewReader(rawBytes), tmpBlock)
|
||||
}
|
||||
return r.fallbackRender(io.MultiReader(bytes.NewReader(rawBytes), input), tmpBlock)
|
||||
}
|
||||
|
||||
func (Renderer) fallbackRender(input io.Reader, tmpBlock *bufio.Writer) error {
|
||||
_, err := tmpBlock.WriteString("<pre>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scan := bufio.NewScanner(input)
|
||||
scan.Split(bufio.ScanRunes)
|
||||
for scan.Scan() {
|
||||
switch scan.Text() {
|
||||
case `&`:
|
||||
_, err = tmpBlock.WriteString("&")
|
||||
case `'`:
|
||||
_, err = tmpBlock.WriteString("'") // "'" is shorter than "'" and apos was not in HTML until HTML5.
|
||||
case `<`:
|
||||
_, err = tmpBlock.WriteString("<")
|
||||
case `>`:
|
||||
_, err = tmpBlock.WriteString(">")
|
||||
case `"`:
|
||||
_, err = tmpBlock.WriteString(""") // """ is shorter than """.
|
||||
default:
|
||||
_, err = tmpBlock.Write(scan.Bytes())
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = scan.Err(); err != nil {
|
||||
return fmt.Errorf("fallbackRender scan: %w", err)
|
||||
}
|
||||
|
||||
_, err = tmpBlock.WriteString("</pre>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpBlock.Flush()
|
||||
}
|
||||
|
||||
func (Renderer) tableRender(ctx *markup.RenderContext, input io.Reader, tmpBlock *bufio.Writer) error {
|
||||
rd, err := csv.CreateReaderAndDetermineDelimiter(ctx, input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := tmpBlock.WriteString(`<table class="data-table">`); err != nil {
|
||||
return err
|
||||
}
|
||||
row := 1
|
||||
|
||||
row := 0
|
||||
for {
|
||||
fields, err := rd.Read()
|
||||
if err == io.EOF {
|
||||
if err == io.EOF || (row >= maxRows && maxRows != 0) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err := tmpBlock.WriteString("<tr>"); err != nil {
|
||||
return err
|
||||
}
|
||||
element := "td"
|
||||
if row == 1 {
|
||||
if row == 0 {
|
||||
element = "th"
|
||||
}
|
||||
if err := writeField(tmpBlock, element, "line-num", strconv.Itoa(row)); err != nil {
|
||||
if err := writeField(tmpBlock, element, "line-num", strconv.Itoa(row+1)); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, field := range fields {
|
||||
@ -174,8 +126,32 @@ func (Renderer) tableRender(ctx *markup.RenderContext, input io.Reader, tmpBlock
|
||||
|
||||
row++
|
||||
}
|
||||
|
||||
if _, err = tmpBlock.WriteString("</table>"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if maxRows or maxSize is reached, and if true, warn.
|
||||
if (row >= maxRows && maxRows != 0) || (rd.InputOffset() >= maxSize && maxSize != 0) {
|
||||
warn := `<table class="data-table"><tr><td>`
|
||||
rawLink := ` <a href="` + ctx.Links.RawLink() + `/` + util.PathEscapeSegments(ctx.RelativePath) + `">`
|
||||
|
||||
// Try to get the user translation
|
||||
if locale, ok := ctx.Ctx.Value(translation.ContextKey).(translation.Locale); ok {
|
||||
warn += locale.TrString("repo.file_too_large")
|
||||
rawLink += locale.TrString("repo.file_view_raw")
|
||||
} else {
|
||||
warn += "The file is too large to be shown."
|
||||
rawLink += "View Raw"
|
||||
}
|
||||
|
||||
warn += rawLink + `</a></td></tr></table>`
|
||||
|
||||
// Write the HTML string to the output
|
||||
if _, err := tmpBlock.WriteString(warn); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tmpBlock.Flush()
|
||||
}
|
||||
|
@ -4,8 +4,6 @@
|
||||
package markup
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@ -31,12 +29,4 @@ func TestRenderCSV(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, v, buf.String())
|
||||
}
|
||||
|
||||
t.Run("fallbackRender", func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
err := render.fallbackRender(strings.NewReader("1,<a>\n2,<b>"), bufio.NewWriter(&buf))
|
||||
assert.NoError(t, err)
|
||||
want := "<pre>1,<a>\n2,<b></pre>"
|
||||
assert.Equal(t, want, buf.String())
|
||||
})
|
||||
}
|
||||
|
@ -372,7 +372,42 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
|
||||
return nil
|
||||
}
|
||||
|
||||
func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
|
||||
func handleNodeImg(ctx *RenderContext, img *html.Node) {
|
||||
for i, attr := range img.Attr {
|
||||
if attr.Key != "src" {
|
||||
continue
|
||||
}
|
||||
|
||||
if attr.Val != "" && !IsFullURLString(attr.Val) && !strings.HasPrefix(attr.Val, "/") {
|
||||
attr.Val = util.URLJoin(ctx.Links.ResolveMediaLink(ctx.IsWiki), attr.Val)
|
||||
|
||||
// By default, the "<img>" tag should also be clickable,
|
||||
// because frontend use `<img>` to paste the re-scaled image into the markdown,
|
||||
// so it must match the default markdown image behavior.
|
||||
hasParentAnchor := false
|
||||
for p := img.Parent; p != nil; p = p.Parent {
|
||||
if hasParentAnchor = p.Type == html.ElementNode && p.Data == "a"; hasParentAnchor {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasParentAnchor {
|
||||
imgA := &html.Node{Type: html.ElementNode, Data: "a", Attr: []html.Attribute{
|
||||
{Key: "href", Val: attr.Val},
|
||||
{Key: "target", Val: "_blank"},
|
||||
}}
|
||||
parent := img.Parent
|
||||
imgNext := img.NextSibling
|
||||
parent.RemoveChild(img)
|
||||
parent.InsertBefore(imgA, imgNext)
|
||||
imgA.AppendChild(img)
|
||||
}
|
||||
}
|
||||
attr.Val = camoHandleLink(attr.Val)
|
||||
img.Attr[i] = attr
|
||||
}
|
||||
}
|
||||
|
||||
func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Node {
|
||||
// Add user-content- to IDs and "#" links if they don't already have them
|
||||
for idx, attr := range node.Attr {
|
||||
val := strings.TrimPrefix(attr.Val, "#")
|
||||
@ -397,21 +432,14 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
|
||||
textNode(ctx, procs, node)
|
||||
case html.ElementNode:
|
||||
if node.Data == "img" {
|
||||
for i, attr := range node.Attr {
|
||||
if attr.Key != "src" {
|
||||
continue
|
||||
}
|
||||
if len(attr.Val) > 0 && !IsFullURLString(attr.Val) && !strings.HasPrefix(attr.Val, "data:image/") {
|
||||
attr.Val = util.URLJoin(ctx.Links.ResolveMediaLink(ctx.IsWiki), attr.Val)
|
||||
}
|
||||
attr.Val = camoHandleLink(attr.Val)
|
||||
node.Attr[i] = attr
|
||||
}
|
||||
next := node.NextSibling
|
||||
handleNodeImg(ctx, node)
|
||||
return next
|
||||
} else if node.Data == "a" {
|
||||
// Restrict text in links to emojis
|
||||
procs = emojiProcessors
|
||||
} else if node.Data == "code" || node.Data == "pre" {
|
||||
return
|
||||
return node.NextSibling
|
||||
} else if node.Data == "i" {
|
||||
for _, attr := range node.Attr {
|
||||
if attr.Key != "class" {
|
||||
@ -434,11 +462,11 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
for n := node.FirstChild; n != nil; n = n.NextSibling {
|
||||
visitNode(ctx, procs, n)
|
||||
for n := node.FirstChild; n != nil; {
|
||||
n = visitNode(ctx, procs, n)
|
||||
}
|
||||
}
|
||||
// ignore everything else
|
||||
return node.NextSibling
|
||||
}
|
||||
|
||||
// textNode runs the passed node through various processors, in order to handle
|
||||
@ -851,7 +879,7 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
|
||||
|
||||
// FIXME: the use of "mode" is quite dirty and hacky, for example: what is a "document"? how should it be rendered?
|
||||
// The "mode" approach should be refactored to some other more clear&reliable way.
|
||||
crossLinkOnly := (ctx.Metas["mode"] == "document" && !ctx.IsWiki)
|
||||
crossLinkOnly := ctx.Metas["mode"] == "document" && !ctx.IsWiki
|
||||
|
||||
var (
|
||||
found bool
|
||||
|
@ -18,8 +18,7 @@ import (
|
||||
|
||||
const (
|
||||
TestAppURL = "http://localhost:3000/"
|
||||
TestOrgRepo = "gogits/gogs"
|
||||
TestRepoURL = TestAppURL + TestOrgRepo + "/"
|
||||
TestRepoURL = TestAppURL + "test-owner/test-repo/"
|
||||
)
|
||||
|
||||
// externalIssueLink an HTML link to an alphanumeric-style issue
|
||||
@ -64,8 +63,8 @@ var regexpMetas = map[string]string{
|
||||
|
||||
// these values should match the TestOrgRepo const above
|
||||
var localMetas = map[string]string{
|
||||
"user": "gogits",
|
||||
"repo": "gogs",
|
||||
"user": "test-owner",
|
||||
"repo": "test-repo",
|
||||
}
|
||||
|
||||
func TestRender_IssueIndexPattern(t *testing.T) {
|
||||
@ -362,12 +361,12 @@ func TestRender_FullIssueURLs(t *testing.T) {
|
||||
`Look here <a href="http://localhost:3000/person/repo/issues/4" class="ref-issue">person/repo#4</a>`)
|
||||
test("http://localhost:3000/person/repo/issues/4#issuecomment-1234",
|
||||
`<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234" class="ref-issue">person/repo#4 (comment)</a>`)
|
||||
test("http://localhost:3000/gogits/gogs/issues/4",
|
||||
`<a href="http://localhost:3000/gogits/gogs/issues/4" class="ref-issue">#4</a>`)
|
||||
test("http://localhost:3000/gogits/gogs/issues/4 test",
|
||||
`<a href="http://localhost:3000/gogits/gogs/issues/4" class="ref-issue">#4</a> test`)
|
||||
test("http://localhost:3000/gogits/gogs/issues/4?a=1&b=2#comment-123 test",
|
||||
`<a href="http://localhost:3000/gogits/gogs/issues/4?a=1&b=2#comment-123" class="ref-issue">#4 (comment)</a> test`)
|
||||
test("http://localhost:3000/test-owner/test-repo/issues/4",
|
||||
`<a href="http://localhost:3000/test-owner/test-repo/issues/4" class="ref-issue">#4</a>`)
|
||||
test("http://localhost:3000/test-owner/test-repo/issues/4 test",
|
||||
`<a href="http://localhost:3000/test-owner/test-repo/issues/4" class="ref-issue">#4</a> test`)
|
||||
test("http://localhost:3000/test-owner/test-repo/issues/4?a=1&b=2#comment-123 test",
|
||||
`<a href="http://localhost:3000/test-owner/test-repo/issues/4?a=1&b=2#comment-123" class="ref-issue">#4 (comment)</a> test`)
|
||||
test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24",
|
||||
"http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24")
|
||||
test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/files",
|
||||
|
@ -120,8 +120,8 @@ func TestRender_CrossReferences(t *testing.T) {
|
||||
}
|
||||
|
||||
test(
|
||||
"gogits/gogs#12345",
|
||||
`<p><a href="`+util.URLJoin(markup.TestAppURL, "gogits", "gogs", "issues", "12345")+`" class="ref-issue" rel="nofollow">gogits/gogs#12345</a></p>`)
|
||||
"test-owner/test-repo#12345",
|
||||
`<p><a href="`+util.URLJoin(markup.TestAppURL, "test-owner", "test-repo", "issues", "12345")+`" class="ref-issue" rel="nofollow">test-owner/test-repo#12345</a></p>`)
|
||||
test(
|
||||
"go-gitea/gitea#12345",
|
||||
`<p><a href="`+util.URLJoin(markup.TestAppURL, "go-gitea", "gitea", "issues", "12345")+`" class="ref-issue" rel="nofollow">go-gitea/gitea#12345</a></p>`)
|
||||
@ -530,43 +530,31 @@ func TestRender_ShortLinks(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRender_RelativeImages(t *testing.T) {
|
||||
setting.AppURL = markup.TestAppURL
|
||||
|
||||
test := func(input, expected, expectedWiki string) {
|
||||
render := func(input string, isWiki bool, links markup.Links) string {
|
||||
buffer, err := markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: git.DefaultContext,
|
||||
Links: markup.Links{
|
||||
Base: markup.TestRepoURL,
|
||||
BranchPath: "master",
|
||||
},
|
||||
Metas: localMetas,
|
||||
}, input)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
|
||||
buffer, err = markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: git.DefaultContext,
|
||||
Links: markup.Links{
|
||||
Base: markup.TestRepoURL,
|
||||
},
|
||||
Ctx: git.DefaultContext,
|
||||
Links: links,
|
||||
Metas: localMetas,
|
||||
IsWiki: true,
|
||||
IsWiki: isWiki,
|
||||
}, input)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
|
||||
return strings.TrimSpace(string(buffer))
|
||||
}
|
||||
|
||||
rawwiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw")
|
||||
mediatree := util.URLJoin(markup.TestRepoURL, "media", "master")
|
||||
out := render(`<img src="LINK">`, false, markup.Links{Base: "/test-owner/test-repo"})
|
||||
assert.Equal(t, `<a href="/test-owner/test-repo/LINK" target="_blank" rel="nofollow noopener"><img src="/test-owner/test-repo/LINK"/></a>`, out)
|
||||
|
||||
test(
|
||||
`<img src="Link">`,
|
||||
`<img src="`+util.URLJoin(mediatree, "Link")+`"/>`,
|
||||
`<img src="`+util.URLJoin(rawwiki, "Link")+`"/>`)
|
||||
out = render(`<img src="LINK">`, true, markup.Links{Base: "/test-owner/test-repo"})
|
||||
assert.Equal(t, `<a href="/test-owner/test-repo/wiki/raw/LINK" target="_blank" rel="nofollow noopener"><img src="/test-owner/test-repo/wiki/raw/LINK"/></a>`, out)
|
||||
|
||||
test(
|
||||
`<img src="./icon.png">`,
|
||||
`<img src="`+util.URLJoin(mediatree, "icon.png")+`"/>`,
|
||||
`<img src="`+util.URLJoin(rawwiki, "icon.png")+`"/>`)
|
||||
out = render(`<img src="LINK">`, false, markup.Links{Base: "/test-owner/test-repo", BranchPath: "test-branch"})
|
||||
assert.Equal(t, `<a href="/test-owner/test-repo/media/test-branch/LINK" target="_blank" rel="nofollow noopener"><img src="/test-owner/test-repo/media/test-branch/LINK"/></a>`, out)
|
||||
|
||||
out = render(`<img src="LINK">`, true, markup.Links{Base: "/test-owner/test-repo", BranchPath: "test-branch"})
|
||||
assert.Equal(t, `<a href="/test-owner/test-repo/wiki/raw/LINK" target="_blank" rel="nofollow noopener"><img src="/test-owner/test-repo/wiki/raw/LINK"/></a>`, out)
|
||||
|
||||
out = render(`<img src="/LINK">`, true, markup.Links{Base: "/test-owner/test-repo", BranchPath: "test-branch"})
|
||||
assert.Equal(t, `<img src="/LINK"/>`, out)
|
||||
}
|
||||
|
||||
func Test_ParseClusterFuzz(t *testing.T) {
|
||||
@ -719,5 +707,6 @@ func TestIssue18471(t *testing.T) {
|
||||
func TestIsFullURL(t *testing.T) {
|
||||
assert.True(t, markup.IsFullURLString("https://example.com"))
|
||||
assert.True(t, markup.IsFullURLString("mailto:test@example.com"))
|
||||
assert.True(t, markup.IsFullURLString("data:image/11111"))
|
||||
assert.False(t, markup.IsFullURLString("/foo:bar"))
|
||||
}
|
||||
|
@ -1019,4 +1019,10 @@ func TestAttention(t *testing.T) {
|
||||
test(`> [!important]`, renderAttention("important", "octicon-report")+"\n</blockquote>")
|
||||
test(`> [!warning]`, renderAttention("warning", "octicon-alert")+"\n</blockquote>")
|
||||
test(`> [!caution]`, renderAttention("caution", "octicon-stop")+"\n</blockquote>")
|
||||
|
||||
// escaped by mdformat
|
||||
test(`> \[!NOTE\]`, renderAttention("note", "octicon-info")+"\n</blockquote>")
|
||||
|
||||
// legacy GitHub style
|
||||
test(`> **warning**`, renderAttention("warning", "octicon-alert")+"\n</blockquote>")
|
||||
}
|
||||
|
@ -31,10 +31,16 @@ func (b *blockParser) Open(parent ast.Node, reader text.Reader, pc parser.Contex
|
||||
return nil, parser.NoChildren
|
||||
}
|
||||
|
||||
dollars := false
|
||||
var dollars bool
|
||||
if b.parseDollars && line[pos] == '$' && line[pos+1] == '$' {
|
||||
dollars = true
|
||||
} else if line[pos] != '\\' || line[pos+1] != '[' {
|
||||
} else if line[pos] == '\\' && line[pos+1] == '[' {
|
||||
if len(line[pos:]) >= 3 && line[pos+2] == '!' && bytes.Contains(line[pos:], []byte(`\]`)) {
|
||||
// do not process escaped attention block: "> \[!NOTE\]"
|
||||
return nil, parser.NoChildren
|
||||
}
|
||||
dollars = false
|
||||
} else {
|
||||
return nil, parser.NoChildren
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// renderAttention renders a quote marked with i.e. "> **Note**" or "> **Warning**" with a corresponding svg
|
||||
// renderAttention renders a quote marked with i.e. "> **Note**" or "> [!Warning]" with a corresponding svg
|
||||
func (r *HTMLRenderer) renderAttention(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
if entering {
|
||||
n := node.(*Attention)
|
||||
@ -37,38 +37,93 @@ func (r *HTMLRenderer) renderAttention(w util.BufWriter, source []byte, node ast
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
func (g *ASTTransformer) transformBlockquote(v *ast.Blockquote, reader text.Reader) (ast.WalkStatus, error) {
|
||||
// We only want attention blockquotes when the AST looks like:
|
||||
// > Text("[") Text("!TYPE") Text("]")
|
||||
func (g *ASTTransformer) extractBlockquoteAttentionEmphasis(firstParagraph ast.Node, reader text.Reader) (string, []ast.Node) {
|
||||
if firstParagraph.ChildCount() < 1 {
|
||||
return "", nil
|
||||
}
|
||||
node1, ok := firstParagraph.FirstChild().(*ast.Emphasis)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
val1 := string(node1.Text(reader.Source()))
|
||||
attentionType := strings.ToLower(val1)
|
||||
if g.attentionTypes.Contains(attentionType) {
|
||||
return attentionType, []ast.Node{node1}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// grab these nodes and make sure we adhere to the attention blockquote structure
|
||||
firstParagraph := v.FirstChild()
|
||||
g.applyElementDir(firstParagraph)
|
||||
if firstParagraph.ChildCount() < 3 {
|
||||
return ast.WalkContinue, nil
|
||||
func (g *ASTTransformer) extractBlockquoteAttention2(firstParagraph ast.Node, reader text.Reader) (string, []ast.Node) {
|
||||
if firstParagraph.ChildCount() < 2 {
|
||||
return "", nil
|
||||
}
|
||||
node1, ok := firstParagraph.FirstChild().(*ast.Text)
|
||||
if !ok {
|
||||
return ast.WalkContinue, nil
|
||||
return "", nil
|
||||
}
|
||||
node2, ok := node1.NextSibling().(*ast.Text)
|
||||
if !ok {
|
||||
return ast.WalkContinue, nil
|
||||
return "", nil
|
||||
}
|
||||
val1 := string(node1.Segment.Value(reader.Source()))
|
||||
val2 := string(node2.Segment.Value(reader.Source()))
|
||||
if strings.HasPrefix(val1, `\[!`) && val2 == `\]` {
|
||||
attentionType := strings.ToLower(val1[3:])
|
||||
if g.attentionTypes.Contains(attentionType) {
|
||||
return attentionType, []ast.Node{node1, node2}
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (g *ASTTransformer) extractBlockquoteAttention3(firstParagraph ast.Node, reader text.Reader) (string, []ast.Node) {
|
||||
if firstParagraph.ChildCount() < 3 {
|
||||
return "", nil
|
||||
}
|
||||
node1, ok := firstParagraph.FirstChild().(*ast.Text)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
node2, ok := node1.NextSibling().(*ast.Text)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
node3, ok := node2.NextSibling().(*ast.Text)
|
||||
if !ok {
|
||||
return ast.WalkContinue, nil
|
||||
return "", nil
|
||||
}
|
||||
val1 := string(node1.Segment.Value(reader.Source()))
|
||||
val2 := string(node2.Segment.Value(reader.Source()))
|
||||
val3 := string(node3.Segment.Value(reader.Source()))
|
||||
if val1 != "[" || val3 != "]" || !strings.HasPrefix(val2, "!") {
|
||||
return ast.WalkContinue, nil
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// grab attention type from markdown source
|
||||
attentionType := strings.ToLower(val2[1:])
|
||||
if !g.attentionTypes.Contains(attentionType) {
|
||||
if g.attentionTypes.Contains(attentionType) {
|
||||
return attentionType, []ast.Node{node1, node2, node3}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (g *ASTTransformer) transformBlockquote(v *ast.Blockquote, reader text.Reader) (ast.WalkStatus, error) {
|
||||
// We only want attention blockquotes when the AST looks like:
|
||||
// > Text("[") Text("!TYPE") Text("]")
|
||||
// > Text("\[!TYPE") TEXT("\]")
|
||||
// > Text("**TYPE**")
|
||||
|
||||
// grab these nodes and make sure we adhere to the attention blockquote structure
|
||||
firstParagraph := v.FirstChild()
|
||||
g.applyElementDir(firstParagraph)
|
||||
|
||||
attentionType, processedNodes := g.extractBlockquoteAttentionEmphasis(firstParagraph, reader)
|
||||
if attentionType == "" {
|
||||
attentionType, processedNodes = g.extractBlockquoteAttention2(firstParagraph, reader)
|
||||
}
|
||||
if attentionType == "" {
|
||||
attentionType, processedNodes = g.extractBlockquoteAttention3(firstParagraph, reader)
|
||||
}
|
||||
if attentionType == "" {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
@ -88,9 +143,9 @@ func (g *ASTTransformer) transformBlockquote(v *ast.Blockquote, reader text.Read
|
||||
attentionParagraph.AppendChild(attentionParagraph, NewAttention(attentionType))
|
||||
attentionParagraph.AppendChild(attentionParagraph, emphasis)
|
||||
firstParagraph.Parent().InsertBefore(firstParagraph.Parent(), firstParagraph, attentionParagraph)
|
||||
firstParagraph.RemoveChild(firstParagraph, node1)
|
||||
firstParagraph.RemoveChild(firstParagraph, node2)
|
||||
firstParagraph.RemoveChild(firstParagraph, node3)
|
||||
for _, processed := range processedNodes {
|
||||
firstParagraph.RemoveChild(firstParagraph, processed)
|
||||
}
|
||||
if firstParagraph.ChildCount() == 0 {
|
||||
firstParagraph.Parent().RemoveChild(firstParagraph.Parent(), firstParagraph)
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ type RenderContext struct {
|
||||
Type string
|
||||
IsWiki bool
|
||||
Links Links
|
||||
Metas map[string]string
|
||||
Metas map[string]string // user, repo, mode(comment/document)
|
||||
DefaultLink string
|
||||
GitRepo *git.Repository
|
||||
Repo gitrepo.Repository
|
||||
|
@ -18,14 +18,15 @@ import (
|
||||
// Mailer represents mail service.
|
||||
type Mailer struct {
|
||||
// Mailer
|
||||
Name string `ini:"NAME"`
|
||||
From string `ini:"FROM"`
|
||||
EnvelopeFrom string `ini:"ENVELOPE_FROM"`
|
||||
OverrideEnvelopeFrom bool `ini:"-"`
|
||||
FromName string `ini:"-"`
|
||||
FromEmail string `ini:"-"`
|
||||
SendAsPlainText bool `ini:"SEND_AS_PLAIN_TEXT"`
|
||||
SubjectPrefix string `ini:"SUBJECT_PREFIX"`
|
||||
Name string `ini:"NAME"`
|
||||
From string `ini:"FROM"`
|
||||
EnvelopeFrom string `ini:"ENVELOPE_FROM"`
|
||||
OverrideEnvelopeFrom bool `ini:"-"`
|
||||
FromName string `ini:"-"`
|
||||
FromEmail string `ini:"-"`
|
||||
SendAsPlainText bool `ini:"SEND_AS_PLAIN_TEXT"`
|
||||
SubjectPrefix string `ini:"SUBJECT_PREFIX"`
|
||||
OverrideHeader map[string][]string `ini:"-"`
|
||||
|
||||
// SMTP sender
|
||||
Protocol string `ini:"PROTOCOL"`
|
||||
@ -151,6 +152,12 @@ func loadMailerFrom(rootCfg ConfigProvider) {
|
||||
log.Fatal("Unable to map [mailer] section on to MailService. Error: %v", err)
|
||||
}
|
||||
|
||||
overrideHeader := rootCfg.Section("mailer.override_header").Keys()
|
||||
MailService.OverrideHeader = make(map[string][]string)
|
||||
for _, key := range overrideHeader {
|
||||
MailService.OverrideHeader[key.Name()] = key.Strings(",")
|
||||
}
|
||||
|
||||
// Infer SMTPPort if not set
|
||||
if MailService.SMTPPort == "" {
|
||||
switch MailService.Protocol {
|
||||
|
@ -6,7 +6,6 @@ package setting
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@ -19,7 +18,6 @@ var (
|
||||
Storage *Storage
|
||||
Enabled bool
|
||||
ChunkedUploadPath string
|
||||
RegistryHost string
|
||||
|
||||
LimitTotalOwnerCount int64
|
||||
LimitTotalOwnerSize int64
|
||||
@ -66,9 +64,6 @@ func loadPackagesFrom(rootCfg ConfigProvider) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
appURL, _ := url.Parse(AppURL)
|
||||
Packages.RegistryHost = appURL.Host
|
||||
|
||||
Packages.ChunkedUploadPath = filepath.ToSlash(sec.Key("CHUNKED_UPLOAD_PATH").MustString("tmp/package-upload"))
|
||||
if !filepath.IsAbs(Packages.ChunkedUploadPath) {
|
||||
Packages.ChunkedUploadPath = filepath.ToSlash(filepath.Join(AppDataPath, Packages.ChunkedUploadPath))
|
||||
|
@ -52,6 +52,7 @@ var UI = struct {
|
||||
|
||||
CSV struct {
|
||||
MaxFileSize int64
|
||||
MaxRows int
|
||||
} `ini:"ui.csv"`
|
||||
|
||||
Admin struct {
|
||||
@ -107,8 +108,10 @@ var UI = struct {
|
||||
},
|
||||
CSV: struct {
|
||||
MaxFileSize int64
|
||||
MaxRows int
|
||||
}{
|
||||
MaxFileSize: 524288,
|
||||
MaxRows: 2500,
|
||||
},
|
||||
Admin: struct {
|
||||
UserPagingNum int
|
||||
|
@ -6,8 +6,11 @@ package structs
|
||||
import "time"
|
||||
|
||||
type Activity struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"` // Receiver user
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"` // Receiver user
|
||||
// the type of action
|
||||
//
|
||||
// enum: create_repo,rename_repo,star_repo,watch_repo,commit_repo,create_issue,create_pull_request,transfer_repo,push_tag,comment_issue,merge_pull_request,close_issue,reopen_issue,close_pull_request,reopen_pull_request,delete_tag,delete_branch,mirror_sync_push,mirror_sync_create,mirror_sync_delete,approve_pull_request,reject_pull_request,comment_pull,publish_release,pull_review_dismissed,pull_request_ready_for_review,auto_merge_pull_request
|
||||
OpType string `json:"op_type"`
|
||||
ActUserID int64 `json:"act_user_id"`
|
||||
ActUser *User `json:"act_user"`
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"html"
|
||||
"html/template"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
@ -237,8 +238,8 @@ func DotEscape(raw string) string {
|
||||
|
||||
// Iif is an "inline-if", similar util.Iif[T] but templates need the non-generic version,
|
||||
// and it could be simply used as "{{Iif expr trueVal}}" (omit the falseVal).
|
||||
func Iif(condition bool, vals ...any) any {
|
||||
if condition {
|
||||
func Iif(condition any, vals ...any) any {
|
||||
if isTemplateTruthy(condition) {
|
||||
return vals[0]
|
||||
} else if len(vals) > 1 {
|
||||
return vals[1]
|
||||
@ -246,6 +247,32 @@ func Iif(condition bool, vals ...any) any {
|
||||
return nil
|
||||
}
|
||||
|
||||
func isTemplateTruthy(v any) bool {
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
switch rv.Kind() {
|
||||
case reflect.Bool:
|
||||
return rv.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return rv.Int() != 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return rv.Uint() != 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return rv.Float() != 0
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
return rv.Complex() != 0
|
||||
case reflect.String, reflect.Slice, reflect.Array, reflect.Map:
|
||||
return rv.Len() > 0
|
||||
case reflect.Struct:
|
||||
return true
|
||||
default:
|
||||
return !rv.IsNil()
|
||||
}
|
||||
}
|
||||
|
||||
// Eval the expression and return the result, see the comment of eval.Expr for details.
|
||||
// To use this helper function in templates, pass each token as a separate parameter.
|
||||
//
|
||||
|
@ -5,8 +5,11 @@ package templates
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -65,3 +68,41 @@ func TestHTMLFormat(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>`))
|
||||
}
|
||||
|
||||
func TestTemplateTruthy(t *testing.T) {
|
||||
tmpl := template.New("test")
|
||||
tmpl.Funcs(template.FuncMap{"Iif": Iif})
|
||||
template.Must(tmpl.Parse(`{{if .Value}}true{{else}}false{{end}}:{{Iif .Value "true" "false"}}`))
|
||||
|
||||
cases := []any{
|
||||
nil, false, true, "", "string", 0, 1,
|
||||
byte(0), byte(1), int64(0), int64(1), float64(0), float64(1),
|
||||
complex(0, 0), complex(1, 0),
|
||||
(chan int)(nil), make(chan int),
|
||||
(func())(nil), func() {},
|
||||
util.ToPointer(0), util.ToPointer(util.ToPointer(0)),
|
||||
util.ToPointer(1), util.ToPointer(util.ToPointer(1)),
|
||||
[0]int{},
|
||||
[1]int{0},
|
||||
[]int(nil),
|
||||
[]int{},
|
||||
[]int{0},
|
||||
map[any]any(nil),
|
||||
map[any]any{},
|
||||
map[any]any{"k": "v"},
|
||||
(*struct{})(nil),
|
||||
struct{}{},
|
||||
util.ToPointer(struct{}{}),
|
||||
}
|
||||
w := &strings.Builder{}
|
||||
truthyCount := 0
|
||||
for i, v := range cases {
|
||||
w.Reset()
|
||||
assert.NoError(t, tmpl.Execute(w, struct{ Value any }{v}), "case %d (%T) %#v fails", i, v, v)
|
||||
out := w.String()
|
||||
truthyCount += util.Iif(out == "true:true", 1, 0)
|
||||
truthyMatches := out == "true:true" || out == "false:false"
|
||||
assert.True(t, truthyMatches, "case %d (%T) %#v fail: %s", i, v, v, out)
|
||||
}
|
||||
assert.True(t, truthyCount != 0 && truthyCount != len(cases))
|
||||
}
|
||||
|
@ -34,8 +34,10 @@ func IsNormalPageCompleted(s string) bool {
|
||||
return strings.Contains(s, `<footer class="page-footer"`) && strings.Contains(s, `</html>`)
|
||||
}
|
||||
|
||||
func MockVariableValue[T any](p *T, v T) (reset func()) {
|
||||
func MockVariableValue[T any](p *T, v ...T) (reset func()) {
|
||||
old := *p
|
||||
*p = v
|
||||
if len(v) > 0 {
|
||||
*p = v[0]
|
||||
}
|
||||
return func() { *p = old }
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ func GetSiteCookie(req *http.Request, name string) string {
|
||||
|
||||
// SetSiteCookie returns given cookie value from request header.
|
||||
func SetSiteCookie(resp http.ResponseWriter, name, value string, maxAge int) {
|
||||
// Previous versions would use a cookie path with a trailing /.
|
||||
// These are more specific than cookies without a trailing /, so
|
||||
// we need to delete these if they exist.
|
||||
deleteLegacySiteCookie(resp, name)
|
||||
cookie := &http.Cookie{
|
||||
Name: name,
|
||||
Value: url.QueryEscape(value),
|
||||
@ -46,10 +50,6 @@ func SetSiteCookie(resp http.ResponseWriter, name, value string, maxAge int) {
|
||||
SameSite: setting.SessionConfig.SameSite,
|
||||
}
|
||||
resp.Header().Add("Set-Cookie", cookie.String())
|
||||
// Previous versions would use a cookie path with a trailing /.
|
||||
// These are more specific than cookies without a trailing /, so
|
||||
// we need to delete these if they exist.
|
||||
deleteLegacySiteCookie(resp, name)
|
||||
}
|
||||
|
||||
// deleteLegacySiteCookie deletes the cookie with the given name at the cookie
|
||||
|
44
options/gitignore/Alteryx
Normal file
44
options/gitignore/Alteryx
Normal file
@ -0,0 +1,44 @@
|
||||
# gitignore template for Alteryx Designer
|
||||
# website: https://www.alteryx.com/
|
||||
# website: https://help.alteryx.com/current/designer/alteryx-file-types
|
||||
|
||||
# Alteryx Data Files
|
||||
*.yxdb
|
||||
*.cydb
|
||||
*.cyidx
|
||||
*.rptx
|
||||
*.vvf
|
||||
*.aws
|
||||
|
||||
# Alteryx Special Files
|
||||
*.yxwv
|
||||
*.yxft
|
||||
*.yxbe
|
||||
*.bak
|
||||
*.pcxml
|
||||
*.log
|
||||
*.bin
|
||||
*.yxlang
|
||||
CASS.ini
|
||||
|
||||
# Alteryx License Files
|
||||
*.yxlc
|
||||
*.slc
|
||||
*.cylc
|
||||
*.alc
|
||||
*.gzlc
|
||||
|
||||
## gitignore reference sites
|
||||
# https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#Ignoring-Files
|
||||
# https://git-scm.com/docs/gitignore
|
||||
# https://help.github.com/articles/ignoring-files/
|
||||
|
||||
## Useful knowledge from stackoverflow
|
||||
# Even if you haven't tracked the files so far, git seems to be able to "know" about them even after you add them to .gitignore.
|
||||
# WARNING: First commit your current changes, or you will lose them.
|
||||
# Then run the following commands from the top folder of your git repo:
|
||||
# git rm -r --cached .
|
||||
# git add .
|
||||
# git commit -m "fixed untracked files"
|
||||
|
||||
# author: Kacper Ksieski
|
@ -14,6 +14,8 @@
|
||||
*.lzma
|
||||
*.cab
|
||||
*.xar
|
||||
*.zst
|
||||
*.tzst
|
||||
|
||||
# Packing-only formats
|
||||
*.iso
|
||||
|
11
options/gitignore/Ballerina
Normal file
11
options/gitignore/Ballerina
Normal file
@ -0,0 +1,11 @@
|
||||
# generated files
|
||||
target/
|
||||
generated/
|
||||
|
||||
# dependencies
|
||||
Dependencies.toml
|
||||
|
||||
# config files
|
||||
Config.toml
|
||||
# the config files used for testing, Uncomment the following line if you want to commit the test config files
|
||||
#!**/tests/Config.toml
|
@ -9,3 +9,4 @@ install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
CMakeUserPresets.json
|
||||
|
@ -26,6 +26,18 @@
|
||||
#*.obj
|
||||
#
|
||||
|
||||
# Default Delphi compiler directories
|
||||
# Content of this directories are generated with each Compile/Construct of a project.
|
||||
# Most of the time, files here have not there place in a code repository.
|
||||
#Win32/
|
||||
#Win64/
|
||||
#OSX64/
|
||||
#OSXARM64/
|
||||
#Android/
|
||||
#Android64/
|
||||
#iOSDevice64/
|
||||
#Linux64/
|
||||
|
||||
# Delphi compiler-generated binaries (safe to delete)
|
||||
*.exe
|
||||
*.dll
|
||||
|
18
options/gitignore/GitHubPages
Normal file
18
options/gitignore/GitHubPages
Normal file
@ -0,0 +1,18 @@
|
||||
# This .gitignore is appropriate for repositories deployed to GitHub Pages and using
|
||||
# a Gemfile as specified at https://github.com/github/pages-gem#conventional
|
||||
|
||||
# Basic Jekyll gitignores (synchronize to Jekyll.gitignore)
|
||||
_site/
|
||||
.sass-cache/
|
||||
.jekyll-cache/
|
||||
.jekyll-metadata
|
||||
|
||||
# Additional Ruby/bundler ignore for when you run: bundle install
|
||||
/vendor
|
||||
|
||||
# Specific ignore for GitHub Pages
|
||||
# GitHub Pages will always use its own deployed version of pages-gem
|
||||
# This means GitHub Pages will NOT use your Gemfile.lock and therefore it is
|
||||
# counterproductive to check this file into the repository.
|
||||
# Details at https://github.com/github/pages-gem/issues/768
|
||||
Gemfile.lock
|
@ -20,3 +20,6 @@
|
||||
# Go workspace file
|
||||
go.work
|
||||
go.work.sum
|
||||
|
||||
# env file
|
||||
.env
|
||||
|
@ -5,23 +5,6 @@
|
||||
## User settings
|
||||
xcuserdata/
|
||||
|
||||
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
|
||||
*.xcscmblueprint
|
||||
*.xccheckout
|
||||
|
||||
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
|
||||
build/
|
||||
DerivedData/
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
|
||||
## Obj-C/Swift specific
|
||||
*.hmap
|
||||
|
||||
|
@ -12,3 +12,10 @@ Cargo.lock
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# RustRover
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
@ -5,23 +5,6 @@
|
||||
## User settings
|
||||
xcuserdata/
|
||||
|
||||
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
|
||||
*.xcscmblueprint
|
||||
*.xccheckout
|
||||
|
||||
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
|
||||
build/
|
||||
DerivedData/
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
|
||||
## Obj-C/Swift specific
|
||||
*.hmap
|
||||
|
||||
@ -66,10 +49,6 @@ playground.xcworkspace
|
||||
|
||||
Carthage/Build/
|
||||
|
||||
# Accio dependency management
|
||||
Dependencies/
|
||||
.accio/
|
||||
|
||||
# fastlane
|
||||
#
|
||||
# It is recommended to not store the screenshots in the git repo.
|
||||
@ -81,10 +60,3 @@ fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots/**/*.png
|
||||
fastlane/test_output
|
||||
|
||||
# Code Injection
|
||||
#
|
||||
# After new code Injection tools there's a generated folder /iOSInjectionProject
|
||||
# https://github.com/johnno1962/injectionforxcode
|
||||
|
||||
iOSInjectionProject/
|
||||
|
@ -39,6 +39,8 @@
|
||||
*.synctex.gz
|
||||
*.synctex.gz(busy)
|
||||
*.pdfsync
|
||||
*.rubbercache
|
||||
rubber.cache
|
||||
|
||||
## Build tool directories for auxiliary files
|
||||
# latexrun
|
||||
@ -138,6 +140,9 @@ acs-*.bib
|
||||
*.trc
|
||||
*.xref
|
||||
|
||||
# hypdoc
|
||||
*.hd
|
||||
|
||||
# hyperref
|
||||
*.brf
|
||||
|
||||
|
@ -23,6 +23,9 @@ override.tf.json
|
||||
*_override.tf
|
||||
*_override.tf.json
|
||||
|
||||
# Ignore transient lock info files created by terraform apply
|
||||
.terraform.tfstate.lock.info
|
||||
|
||||
# Include override files you do wish to add to version control using negated pattern
|
||||
# !example_override.tf
|
||||
|
||||
@ -32,3 +35,6 @@ override.tf.json
|
||||
# Ignore CLI configuration files
|
||||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
# Ignore hcl file
|
||||
.terraform.lock.hcl
|
||||
|
11
options/gitignore/UiPath
Normal file
11
options/gitignore/UiPath
Normal file
@ -0,0 +1,11 @@
|
||||
# gitignore template for RPA development using UiPath Studio
|
||||
# website: https://www.uipath.com/product/studio
|
||||
#
|
||||
# Recommended: n/a
|
||||
|
||||
# Ignore folders that could cause issues if accidentally tracked
|
||||
**/.local/**
|
||||
**/.settings/**
|
||||
**/.objects/**
|
||||
**/.tmh/**
|
||||
**/*.log
|
@ -47,7 +47,7 @@ SourceArt/**/*.tga
|
||||
|
||||
# Binary Files
|
||||
Binaries/*
|
||||
Plugins/*/Binaries/*
|
||||
Plugins/**/Binaries/*
|
||||
|
||||
# Builds
|
||||
Build/*
|
||||
@ -68,7 +68,7 @@ Saved/*
|
||||
|
||||
# Compiled source files for the engine to use
|
||||
Intermediate/*
|
||||
Plugins/*/Intermediate/*
|
||||
Plugins/**/Intermediate/*
|
||||
|
||||
# Cache files for the editor to use
|
||||
DerivedDataCache/*
|
||||
|
@ -1,6 +1,2 @@
|
||||
## User settings
|
||||
xcuserdata/
|
||||
|
||||
## Xcode 8 and earlier
|
||||
*.xcscmblueprint
|
||||
*.xccheckout
|
||||
|
@ -25,6 +25,7 @@ enable_javascript=Ce site Web nécessite JavaScript.
|
||||
toc=Sommaire
|
||||
licenses=Licences
|
||||
return_to_gitea=Revenir à Gitea
|
||||
more_items=Plus d'éléments
|
||||
|
||||
username=Nom d'utilisateur
|
||||
email=Courriel
|
||||
@ -113,6 +114,7 @@ loading=Chargement…
|
||||
error=Erreur
|
||||
error404=La page que vous essayez d'atteindre <strong>n'existe pas</strong> ou <strong>vous n'êtes pas autorisé</strong> à la voir.
|
||||
go_back=Retour
|
||||
invalid_data=Données invalides : %v
|
||||
|
||||
never=Jamais
|
||||
unknown=Inconnu
|
||||
@ -143,17 +145,43 @@ name=Nom
|
||||
value=Valeur
|
||||
|
||||
filter=Filtrer
|
||||
filter.clear=Effacer le filtre
|
||||
filter.is_archived=Archivé
|
||||
filter.not_archived=Non archivé
|
||||
filter.is_fork=Bifurqué
|
||||
filter.not_fork=Non bifurqué
|
||||
filter.is_mirror=Miroité
|
||||
filter.not_mirror=Non miroité
|
||||
filter.is_template=Modèle
|
||||
filter.not_template=Pas un modèle
|
||||
filter.public=Public
|
||||
filter.private=Privé
|
||||
|
||||
no_results_found=Aucun résultat trouvé.
|
||||
|
||||
[search]
|
||||
search=Rechercher…
|
||||
type_tooltip=Type de recherche
|
||||
fuzzy=Approximative
|
||||
fuzzy_tooltip=Inclure également les résultats proches de la recherche
|
||||
exact=Exact
|
||||
exact_tooltip=Inclure uniquement les résultats qui correspondent exactement au terme de recherche
|
||||
repo_kind=Chercher des dépôts…
|
||||
user_kind=Chercher des utilisateurs…
|
||||
org_kind=Chercher des organisations…
|
||||
team_kind=Chercher des équipes…
|
||||
code_kind=Chercher du code…
|
||||
code_search_unavailable=La recherche dans le code n’est pas disponible actuellement. Veuillez contacter l’administrateur de votre instance Gitea.
|
||||
code_search_by_git_grep=Les résultats de recherche de code actuels sont fournis par « git grep ». L’administrateur peut activer l’indexeur de dépôt, qui pourrait fournir de meilleurs résultats.
|
||||
package_kind=Chercher des paquets…
|
||||
project_kind=Chercher des projets…
|
||||
branch_kind=Chercher des branches…
|
||||
commit_kind=Chercher des révisions…
|
||||
runner_kind=Chercher des exécuteurs…
|
||||
no_results=Aucun résultat correspondant trouvé.
|
||||
issue_kind=Recherche de tickets…
|
||||
pull_kind=Recherche de demandes d’ajouts…
|
||||
keyword_search_unavailable=La recherche par mot clé n’est pas disponible actuellement. Veuillez contacter l’administrateur de votre instance Gitea.
|
||||
|
||||
[aria]
|
||||
navbar=Barre de navigation
|
||||
@ -260,6 +288,7 @@ email_title=Paramètres de Messagerie
|
||||
smtp_addr=Hôte SMTP
|
||||
smtp_port=Port SMTP
|
||||
smtp_from=Envoyer les courriels en tant que
|
||||
smtp_from_invalid=L’adresse « Envoyer le courriel sous » est invalide
|
||||
smtp_from_helper=Adresse courriel utilisée par Gitea. Utilisez directement votre adresse ou la forme « Nom <email@example.com> ».
|
||||
mailer_user=Utilisateur SMTP
|
||||
mailer_password=Mot de passe SMTP
|
||||
@ -319,6 +348,7 @@ env_config_keys=Configuration de l'environnement
|
||||
env_config_keys_prompt=Les variables d'environnement suivantes seront également ajoutées à votre fichier de configuration :
|
||||
|
||||
[home]
|
||||
nav_menu=Menu de navigation
|
||||
uname_holder=Nom d’utilisateur ou adresse courriel
|
||||
password_holder=Mot de passe
|
||||
switch_dashboard_context=Basculer le contexte du tableau de bord
|
||||
@ -333,14 +363,14 @@ filter_by_team_repositories=Dépôts filtrés par équipe
|
||||
feed_of=Flux de « %s »
|
||||
|
||||
show_archived=Archivé
|
||||
show_both_archived_unarchived=Afficher à la fois archivé et non archivé
|
||||
show_only_archived=Afficher uniquement les archivés
|
||||
show_only_unarchived=Afficher uniquement les non archivés
|
||||
show_both_archived_unarchived=Afficher à la fois les dépôts archivés et non archivés
|
||||
show_only_archived=Afficher uniquement les dépôts archivés
|
||||
show_only_unarchived=Afficher uniquement les dépôts non archivés
|
||||
|
||||
show_private=Privé
|
||||
show_both_private_public=Afficher les publics et privés
|
||||
show_only_private=Afficher uniquement les privés
|
||||
show_only_public=Afficher uniquement les publics
|
||||
show_both_private_public=Afficher les dépôts publics et privés
|
||||
show_only_private=Afficher uniquement les dépôts privés
|
||||
show_only_public=Afficher uniquement les dépôts publics
|
||||
|
||||
issues.in_your_repos=Dans vos dépôts
|
||||
|
||||
@ -367,6 +397,7 @@ forgot_password_title=Mot de passe oublié
|
||||
forgot_password=Mot de passe oublié ?
|
||||
sign_up_now=Pas de compte ? Inscrivez-vous maintenant.
|
||||
sign_up_successful=Le compte a été créé avec succès. Bienvenue !
|
||||
confirmation_mail_sent_prompt_ex=Un nouveau courriel de confirmation a été envoyé à <b>%s</b>. Veuillez vérifier votre boîte de réception dans la prochaine %s pour terminer le processus d’inscription. Si votre adresse courriel est incorrecte, vous pouvez vous reconnecter et la modifier.
|
||||
must_change_password=Réinitialisez votre mot de passe
|
||||
allow_password_change=Demande à l'utilisateur de changer son mot de passe (recommandé)
|
||||
reset_password_mail_sent_prompt=Un mail de confirmation a été envoyé à <b>%s</b>. Veuillez vérifier votre boîte de réception dans les prochaines %s pour terminer la procédure de récupération du compte.
|
||||
@ -376,6 +407,7 @@ prohibit_login=Connexion interdite
|
||||
prohibit_login_desc=Votre compte n'autorise pas la connexion, veuillez contacter l'administrateur de votre site.
|
||||
resent_limit_prompt=Désolé, vous avez récemment demandé un courriel d'activation. Veuillez réessayer dans 3 minutes.
|
||||
has_unconfirmed_mail=Bonjour %s, votre adresse courriel (<b>%s</b>) n’a pas été confirmée. Si vous n’avez reçu aucun mail de confirmation ou souhaitez renouveler l’envoi, cliquez sur le bouton ci-dessous.
|
||||
change_unconfirmed_mail_address=Si votre adresse courriel d’inscription est incorrecte, vous pouvez la modifier ici et renvoyer un nouvel courriel de confirmation.
|
||||
resend_mail=Cliquez ici pour renvoyer un mail de confirmation
|
||||
email_not_associate=L’adresse courriel n’est associée à aucun compte.
|
||||
send_reset_mail=Envoyer un courriel de récupération du compte
|
||||
@ -404,6 +436,7 @@ oauth_signin_submit=Lier un compte
|
||||
oauth.signin.error=Une erreur s'est produite lors du traitement de la demande d'autorisation. Si cette erreur persiste, veuillez contacter l'administrateur du site.
|
||||
oauth.signin.error.access_denied=La demande d'autorisation a été refusée.
|
||||
oauth.signin.error.temporarily_unavailable=L'autorisation a échoué car le serveur d'authentification est temporairement indisponible. Veuillez réessayer plus tard.
|
||||
oauth_callback_unable_auto_reg=L’inscription automatique est activée, mais le fournisseur OAuth2 %[1]s a signalé des champs manquants : %[2]s, impossible de créer un compte automatiquement, veuillez créer ou lier un compte, ou bien contacter l’administrateur du site.
|
||||
openid_connect_submit=Se connecter
|
||||
openid_connect_title=Se connecter à un compte existant
|
||||
openid_connect_desc=L'URI OpenID choisie est inconnue. Associez-le à un nouveau compte ici.
|
||||
@ -556,6 +589,7 @@ team_name_been_taken=Le nom d'équipe est déjà pris.
|
||||
team_no_units_error=Autoriser l’accès à au moins une section du dépôt.
|
||||
email_been_used=Cette adresse courriel est déjà utilisée.
|
||||
email_invalid=Cette adresse courriel est invalide.
|
||||
email_domain_is_not_allowed=Le domaine <b>%s</b> du courriel utilisateur entre en conflit avec EMAIL_DOMAIN_ALLOWLIST ou EMAIL_DOMAIN_BLOCKLIST. Veuillez vous assurer que votre opération est attendue.
|
||||
openid_been_used=Adresse OpenID "%s" déjà utilisée.
|
||||
username_password_incorrect=Identifiant ou mot de passe invalide.
|
||||
password_complexity=Le mot de passe ne respecte pas les exigences de complexité:
|
||||
@ -567,6 +601,8 @@ enterred_invalid_repo_name=Le nom de dépôt saisi est incorrect.
|
||||
enterred_invalid_org_name=Le nom de l'organisation que vous avez entré est incorrect.
|
||||
enterred_invalid_owner_name=Le nom du nouveau propriétaire est invalide.
|
||||
enterred_invalid_password=Le mot de passe saisi est incorrect.
|
||||
unset_password=L’utilisateur n’a pas défini de mot de passe.
|
||||
unsupported_login_type=Le type de connexion n’est pas pris en charge pour supprimer le compte.
|
||||
user_not_exist=Cet utilisateur n'existe pas.
|
||||
team_not_exist=L'équipe n'existe pas.
|
||||
last_org_owner=Vous ne pouvez pas retirer le dernier utilisateur de l’équipe « propriétaires ». Il doit y avoir au moins un propriétaire dans chaque organisation.
|
||||
@ -616,6 +652,29 @@ form.name_reserved=Le nom d’utilisateur "%s" est réservé.
|
||||
form.name_pattern_not_allowed=Le motif « %s » n’est pas autorisé dans un nom de d'utilisateur.
|
||||
form.name_chars_not_allowed=Le nom d'utilisateur "%s" contient des caractères non valides.
|
||||
|
||||
block.block=Bloquer
|
||||
block.block.user=Bloquer l’utilisateur
|
||||
block.block.org=Bloquer l’utilisateur pour l’organisation
|
||||
block.block.failure=Impossible de bloquer l’utilisateur : %s
|
||||
block.unblock=Débloquer
|
||||
block.unblock.failure=Impossible de débloquer l’utilisateur : %s
|
||||
block.blocked=Vous avez bloqué cet utilisateur.
|
||||
block.title=Bloquer un utilisateur
|
||||
block.info=Bloquer un utilisateur l’empêche d’interagir avec des dépôts, comme ouvrir ou commenter des demandes de fusion ou des tickets. Apprenez-en plus sur le blocage d’un utilisateur.
|
||||
block.info_1=Bloquer un utilisateur empêche les actions suivantes sur votre compte et vos dépôts :
|
||||
block.info_2=suivre votre compte
|
||||
block.info_3=vous envoyer des notifications en vous @mentionnant
|
||||
block.info_4=vous inviter en tant que collaborateur de son(ses) dépôt(s)
|
||||
block.info_5=aimer, bifurquer ou suivre vos dépôts
|
||||
block.info_6=ouvrir ou commenter vos tickets et demandes d’ajouts
|
||||
block.info_7=réagir à vos commentaires dans les tickets ou les demandes d’ajout
|
||||
block.user_to_block=Utilisateur à bloquer
|
||||
block.note=Note
|
||||
block.note.title=Note facultative :
|
||||
block.note.info=La note n’est pas visible par l’utilisateur bloqué.
|
||||
block.note.edit=Modifier la note
|
||||
block.list=Utilisateurs bloqués
|
||||
block.list.none=Vous n’avez bloqué aucun utilisateur.
|
||||
|
||||
[settings]
|
||||
profile=Profil
|
||||
@ -658,6 +717,7 @@ cancel=Annuler
|
||||
language=Langue
|
||||
ui=Thème
|
||||
hidden_comment_types=Catégories de commentaires masqués
|
||||
hidden_comment_types_description=Cochez les catégories suivantes pour masquer les commentaires correspondants des fils d'activité. Par exemple, « Label » cache les commentaires du genre « Cerise a attribué le label Bug il y a 2 heures. »
|
||||
hidden_comment_types.ref_tooltip=Commentaires où ce ticket a été référencé sur un autre ticket, révision, etc.
|
||||
hidden_comment_types.issue_ref_tooltip=Commentaires où l’utilisateur change la branche/étiquette associée au ticket
|
||||
comment_type_group_reference=Référence
|
||||
@ -704,6 +764,8 @@ manage_themes=Sélectionner le thème par défaut
|
||||
manage_openid=Gérer les adresses OpenID
|
||||
email_desc=Votre adresse courriel principale sera utilisée pour les notifications, la récupération de mot de passe et, à condition qu'elle ne soit pas cachée, les opérations Git basées sur le Web.
|
||||
theme_desc=Ce sera votre thème par défaut sur le site.
|
||||
theme_colorblindness_help=Support du thème daltonien
|
||||
theme_colorblindness_prompt=Gitea fournit depuis peu des thèmes daltonien basé sur un spectre coloré réduit. Encore en développement, de futures améliorations devraient enrichir les fichiers de thèmes CSS.
|
||||
primary=Principale
|
||||
activated=Activé
|
||||
requires_activation=Nécessite une activation
|
||||
@ -953,7 +1015,9 @@ fork_visibility_helper=La visibilité d'un dépôt bifurqué ne peut pas être m
|
||||
fork_branch=Branche à cloner sur la bifurcation
|
||||
all_branches=Toutes les branches
|
||||
fork_no_valid_owners=Ce dépôt ne peut pas être bifurqué car il n’a pas de propriétaire valide.
|
||||
fork.blocked_user=Impossible de bifurquer le dépôt car vous êtes bloqué par son propriétaire.
|
||||
use_template=Utiliser ce modèle
|
||||
open_with_editor=Ouvrir avec %s
|
||||
download_zip=Télécharger le ZIP
|
||||
download_tar=Télécharger le TAR.GZ
|
||||
download_bundle=Télécharger le BUNDLE
|
||||
@ -1006,6 +1070,7 @@ watchers=Observateurs
|
||||
stargazers=Fans
|
||||
stars_remove_warning=Ceci supprimera toutes les étoiles de ce dépôt.
|
||||
forks=Bifurcations
|
||||
stars=Favoris
|
||||
reactions_more=et %d de plus
|
||||
unit_disabled=L'administrateur du site a désactivé cette section du dépôt.
|
||||
language_other=Autre
|
||||
@ -1127,6 +1192,7 @@ watch=Suivre
|
||||
unstar=Retirer des favoris
|
||||
star=Ajouter aux favoris
|
||||
fork=Bifurcation
|
||||
action.blocked_user=Impossible d’effectuer cette action car vous êtes bloqué par le propriétaire du dépôt.
|
||||
download_archive=Télécharger ce dépôt
|
||||
more_operations=Plus d'opérations
|
||||
|
||||
@ -1172,6 +1238,8 @@ file_view_rendered=Voir le rendu
|
||||
file_view_raw=Voir le Raw
|
||||
file_permalink=Lien permanent
|
||||
file_too_large=Le fichier est trop gros pour être affiché.
|
||||
code_preview_line_from_to=Lignes %[1]d à %[2]d dans %[3]s
|
||||
code_preview_line_in=Ligne %[1]d dans %[2]s
|
||||
invisible_runes_header=`Ce fichier contient des caractères Unicode invisibles.`
|
||||
invisible_runes_description=`Ce fichier contient des caractères Unicode invisibles à l'œil nu, mais peuvent être traités différemment par un ordinateur. Si vous pensez que c'est intentionnel, vous pouvez ignorer cet avertissement. Utilisez le bouton Échappe pour les dévoiler.`
|
||||
ambiguous_runes_header=`Ce fichier contient des caractères Unicode ambigus.`
|
||||
@ -1226,6 +1294,7 @@ editor.or=ou
|
||||
editor.cancel_lower=Annuler
|
||||
editor.commit_signed_changes=Réviser les changements (signé)
|
||||
editor.commit_changes=Réviser les changements
|
||||
editor.add_tmpl=Ajouter {filename}
|
||||
editor.add=Ajouter %s
|
||||
editor.update=Actualiser %s
|
||||
editor.delete=Supprimer %s
|
||||
@ -1253,6 +1322,8 @@ editor.file_editing_no_longer_exists=Impossible de modifier le fichier « %s
|
||||
editor.file_deleting_no_longer_exists=Impossible de supprimer le fichier « %s » car il n’existe plus dans ce dépôt.
|
||||
editor.file_changed_while_editing=Le contenu du fichier a changé depuis que vous avez commencé à éditer. <a target="_blank" rel="noopener noreferrer" href="%s">Cliquez ici</a> pour voir les changements ou <strong>soumettez de nouveau</strong> pour les écraser.
|
||||
editor.file_already_exists=Un fichier nommé "%s" existe déjà dans ce dépôt.
|
||||
editor.commit_id_not_matching=L’ID de la révision ne correspond pas à l’ID lorsque vous avez commencé à éditer. Faites une révision dans une branche de correctif puis fusionnez.
|
||||
editor.push_out_of_date=Cet envoi semble être obsolète.
|
||||
editor.commit_empty_file_header=Réviser un fichier vide
|
||||
editor.commit_empty_file_text=Le fichier que vous allez réviser est vide. Continuer ?
|
||||
editor.no_changes_to_show=Il n’y a aucune modification à afficher.
|
||||
@ -1277,6 +1348,7 @@ commits.commits=Révisions
|
||||
commits.no_commits=Pas de révisions en commun. "%s" et "%s" ont des historiques entièrement différents.
|
||||
commits.nothing_to_compare=Ces branches sont égales.
|
||||
commits.search.tooltip=Vous pouvez utiliser les mots-clés "author:", "committer:", "after:", ou "before:" pour filtrer votre recherche, ex.: "revert author:Alice before:2019-01-13".
|
||||
commits.search_branch=Cette branche
|
||||
commits.search_all=Toutes les branches
|
||||
commits.author=Auteur
|
||||
commits.message=Message
|
||||
@ -1306,6 +1378,7 @@ commitstatus.success=Succès
|
||||
ext_issues=Accès aux tickets externes
|
||||
ext_issues.desc=Lien vers un gestionnaire de tickets externe.
|
||||
|
||||
projects.desc=Gérer les tickets et les demandes d’ajouts dans les projets.
|
||||
projects.description=Description (facultative)
|
||||
projects.description_placeholder=Description
|
||||
projects.create=Créer un projet
|
||||
@ -1333,6 +1406,7 @@ projects.column.new=Nouvelle colonne
|
||||
projects.column.set_default=Définir par défaut
|
||||
projects.column.set_default_desc=Les tickets et demandes d’ajout non-catégorisés seront placés dans cette colonne.
|
||||
projects.column.delete=Supprimer la colonne
|
||||
projects.column.deletion_desc=La suppression d’une colonne déplace tous ses tickets dans la colonne par défaut. Continuer ?
|
||||
projects.column.color=Couleur
|
||||
projects.open=Ouvrir
|
||||
projects.close=Fermer
|
||||
@ -1367,6 +1441,9 @@ issues.new.assignees=Assignés
|
||||
issues.new.clear_assignees=Supprimer les affectations
|
||||
issues.new.no_assignees=Sans assignation
|
||||
issues.new.no_reviewers=Sans évaluateur
|
||||
issues.new.blocked_user=Impossible de créer un ticket car vous êtes bloqué par le propriétaire du dépôt.
|
||||
issues.edit.already_changed=Impossible d’enregistrer le ticket. Il semble que le contenu ait été modifié par un autre utilisateur. Veuillez rafraîchir la page et réessayer pour éviter d’écraser ses modifications.
|
||||
issues.edit.blocked_user=Impossible de modifier ce contenu car vous êtes bloqué par son propriétaire.
|
||||
issues.choose.get_started=Démarrons
|
||||
issues.choose.open_external_link=Ouvrir
|
||||
issues.choose.blank=Par défaut
|
||||
@ -1477,8 +1554,11 @@ issues.no_content=Sans contenu.
|
||||
issues.close=Fermer le ticket
|
||||
issues.comment_pull_merged_at=a fusionné la révision %[1]s dans %[2]s %[3]s
|
||||
issues.comment_manually_pull_merged_at=a fusionné manuellement la révision %[1]s dans %[2]s %[3]s
|
||||
issues.close_comment_issue=Commenter et Fermer
|
||||
issues.reopen_issue=Rouvrir
|
||||
issues.reopen_comment_issue=Commenter et Réouvrir
|
||||
issues.create_comment=Commenter
|
||||
issues.comment.blocked_user=Impossible créer ou de modifier un commentaire car vous êtes bloqué par le propriétaire du dépôt.
|
||||
issues.closed_at=`a fermé ce ticket <a id="%[1]s" href="#%[1]s">%[2]s</a>.`
|
||||
issues.reopened_at=`a réouvert ce ticket <a id="%[1]s" href="#%[1]s">%[2]s</a>.`
|
||||
issues.commit_ref_at=`a référencé ce ticket depuis une révision <a id="%[1]s" href="#%[1]s"> %[2]s</a>.`
|
||||
@ -1677,6 +1757,8 @@ compare.compare_head=comparer
|
||||
|
||||
pulls.desc=Active les demandes d’ajouts et l’évaluation du code.
|
||||
pulls.new=Nouvelle demande d'ajout
|
||||
pulls.new.blocked_user=Impossible de créer une demande d’ajout car vous êtes bloqué par le propriétaire du dépôt.
|
||||
pulls.edit.already_changed=Impossible d’enregistrer la demande d’ajout. Il semble que le contenu ait été modifié par un autre utilisateur. Veuillez rafraîchir la page et réessayer afin d’éviter d’écraser leurs modifications.
|
||||
pulls.view=Voir la demande d'ajout
|
||||
pulls.compare_changes=Nouvelle demande d’ajout
|
||||
pulls.allow_edits_from_maintainers=Autoriser les modifications des mainteneurs
|
||||
@ -1822,6 +1904,7 @@ pulls.recently_pushed_new_branches=Vous avez soumis sur la branche <strong>%[1]s
|
||||
|
||||
pull.deleted_branch=(supprimé) : %s
|
||||
|
||||
comments.edit.already_changed=Impossible d’enregistrer ce commentaire. Il semble que le contenu ait été modifié par un autre utilisateur. Veuillez rafraîchir la page et réessayer afin d’éviter d’écraser leurs modifications.
|
||||
|
||||
milestones.new=Nouveau jalon
|
||||
milestones.closed=%s fermé
|
||||
@ -1898,7 +1981,10 @@ wiki.page_name_desc=Entrez un nom pour cette page Wiki. Certains noms spéciaux
|
||||
wiki.original_git_entry_tooltip=Voir le fichier Git original au lieu d'utiliser un lien convivial.
|
||||
|
||||
activity=Activité
|
||||
activity.navbar.pulse=Impulsion
|
||||
activity.navbar.code_frequency=Fréquence du code
|
||||
activity.navbar.contributors=Contributeurs
|
||||
activity.navbar.recent_commits=Révisions récentes
|
||||
activity.period.filter_label=Période :
|
||||
activity.period.daily=1 jour
|
||||
activity.period.halfweekly=3 jours
|
||||
@ -2017,7 +2103,9 @@ settings.branches.add_new_rule=Ajouter une nouvelle règle
|
||||
settings.advanced_settings=Paramètres avancés
|
||||
settings.wiki_desc=Activer le wiki du dépôt
|
||||
settings.use_internal_wiki=Utiliser le wiki interne
|
||||
settings.default_wiki_branch_name=Nom de la branche du Wiki par défaut
|
||||
settings.default_wiki_everyone_access=Autorisation d’accès par défaut pour les utilisateurs connectés :
|
||||
settings.failed_to_change_default_wiki_branch=Impossible de modifier la branche du wiki par défaut.
|
||||
settings.use_external_wiki=Utiliser un wiki externe
|
||||
settings.external_wiki_url=URL Wiki externe
|
||||
settings.external_wiki_url_error=L’URL du wiki externe n’est pas une URL valide.
|
||||
@ -2048,6 +2136,9 @@ settings.pulls.default_allow_edits_from_maintainers=Autoriser les modifications
|
||||
settings.releases_desc=Activer les publications du dépôt
|
||||
settings.packages_desc=Activer le registre des paquets du dépôt
|
||||
settings.projects_desc=Activer les projets de dépôt
|
||||
settings.projects_mode_desc=Mode Projets (type de projets à afficher)
|
||||
settings.projects_mode_repo=Projets de dépôt uniquement
|
||||
settings.projects_mode_owner=Projets d’utilisateur ou d’organisation uniquement
|
||||
settings.projects_mode_all=Tous les projets
|
||||
settings.actions_desc=Activer les actions du dépôt
|
||||
settings.admin_settings=Paramètres administrateur
|
||||
@ -2074,6 +2165,7 @@ settings.convert_fork_succeed=La bifurcation a été convertie en dépôt standa
|
||||
settings.transfer=Changer de propriétaire
|
||||
settings.transfer.rejected=Le transfert du dépôt a été rejeté.
|
||||
settings.transfer.success=Le transfert du dépôt a réussi.
|
||||
settings.transfer.blocked_user=Impossible de transférer ce dépôt car vous êtes bloqué par l’acquéreur.
|
||||
settings.transfer_abort=Annuler le transfert
|
||||
settings.transfer_abort_invalid=Vous ne pouvez pas annuler un transfert de dépôt inexistant.
|
||||
settings.transfer_abort_success=Le transfert du dépôt vers %s a bien été stoppé.
|
||||
@ -2119,6 +2211,7 @@ settings.add_collaborator_success=Le collaborateur a été ajouté.
|
||||
settings.add_collaborator_inactive_user=Impossible d'ajouter un utilisateur inactif en tant que collaborateur.
|
||||
settings.add_collaborator_owner=Impossible d'ajouter un propriétaire en tant que collaborateur.
|
||||
settings.add_collaborator_duplicate=Le collaborateur est déjà ajouté à ce dépôt.
|
||||
settings.add_collaborator.blocked_user=Ce collaborateur est bloqué par le propriétaire du dépôt ou inversement.
|
||||
settings.delete_collaborator=Supprimer
|
||||
settings.collaborator_deletion=Supprimer le collaborateur
|
||||
settings.collaborator_deletion_desc=La suppression d'un collaborateur révoque son accès à ce dépôt. Continuer ?
|
||||
@ -2557,13 +2650,16 @@ find_file.no_matching=Aucun fichier correspondant trouvé
|
||||
error.csv.too_large=Impossible de visualiser le fichier car il est trop volumineux.
|
||||
error.csv.unexpected=Impossible de visualiser ce fichier car il contient un caractère inattendu ligne %d, colonne %d.
|
||||
error.csv.invalid_field_count=Impossible de visualiser ce fichier car il contient un nombre de champs incorrect à la ligne %d.
|
||||
error.broken_git_hook=Les crochets Git de ce dépôt semblent cassés. Veuillez suivre la <a target="_blank" rel="noreferrer" href="%s">documentation</a> pour les corriger, puis pousser des révisions pour actualiser le statut.
|
||||
|
||||
[graphs]
|
||||
component_loading=Chargement de %s…
|
||||
component_loading_failed=Impossible de charger %s.
|
||||
component_loading_info=Ça prend son temps…
|
||||
component_failed_to_load=Une erreur inattendue s’est produite.
|
||||
code_frequency.what=fréquence du code
|
||||
contributors.what=contributions
|
||||
recent_commits.what=révisions récentes
|
||||
|
||||
[org]
|
||||
org_name_holder=Nom de l'organisation
|
||||
@ -2677,6 +2773,7 @@ teams.add_nonexistent_repo=Le dépôt que vous essayez d'ajouter n'existe pas, v
|
||||
teams.add_duplicate_users=L’utilisateur est déjà un membre de l’équipe.
|
||||
teams.repos.none=Aucun dépôt n'est accessible par cette équipe.
|
||||
teams.members.none=Aucun membre dans cette équipe.
|
||||
teams.members.blocked_user=Impossible d’ajouter l’utilisateur car il est bloqué par l’organisation.
|
||||
teams.specific_repositories=Dépôts spécifiques
|
||||
teams.specific_repositories_helper=Les membres auront seulement accès aux dépôts explicitement ajoutés à l'équipe. Sélectionner ceci <strong>ne supprimera pas automatiquement</strong> les dépôts déjà ajoutés avec <i>Tous les dépôts</i>.
|
||||
teams.all_repositories=Tous les dépôts
|
||||
@ -2689,6 +2786,7 @@ teams.invite.by=Invité par %s
|
||||
teams.invite.description=Veuillez cliquer sur le bouton ci-dessous pour rejoindre l’équipe.
|
||||
|
||||
[admin]
|
||||
maintenance=Maintenance
|
||||
dashboard=Tableau de bord
|
||||
self_check=Autodiagnostique
|
||||
identity_access=Identité et accès
|
||||
@ -2712,6 +2810,7 @@ settings=Paramètres administrateur
|
||||
|
||||
dashboard.new_version_hint=Gitea %s est maintenant disponible, vous utilisez %s. Consultez <a target="_blank" rel="noreferrer" href="https://blog.gitea.io">le blog</a> pour plus de détails.
|
||||
dashboard.statistic=Résumé
|
||||
dashboard.maintenance_operations=Opérations de maintenance
|
||||
dashboard.system_status=État du système
|
||||
dashboard.operation_name=Nom de l'Opération
|
||||
dashboard.operation_switch=Basculer
|
||||
@ -2997,11 +3096,14 @@ auths.tips=Conseils
|
||||
auths.tips.oauth2.general=Authentification OAuth2
|
||||
auths.tips.oauth2.general.tip=Lors de l'enregistrement d'une nouvelle authentification OAuth2, l'URL de rappel/redirection doit être :
|
||||
auths.tip.oauth2_provider=Fournisseur OAuth2
|
||||
auths.tip.bitbucket=Créez un nouveau jeton OAuth sur https://bitbucket.org/account/user/{your username}/oauth-consumers/new et ajoutez la permission “Compte” - “Lecture”.
|
||||
auths.tip.nextcloud=`Enregistrez un nouveau consommateur OAuth sur votre instance en utilisant le menu "Paramètres -> Sécurité -> Client OAuth 2.0"`
|
||||
auths.tip.dropbox=Créez une nouvelle application sur https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Enregistrez une nouvelle application sur https://developers.facebook.com/apps et ajoutez le produit "Facebook Login"`
|
||||
auths.tip.github=Créez une nouvelle application OAuth sur https://github.com/settings/applications/new
|
||||
auths.tip.gitlab_new=Enregistrez une nouvelle application sur https://gitlab.com/-/profile/applications
|
||||
auths.tip.google_plus=Obtenez des identifiants OAuth2 sur la console API de Google (https://console.developers.google.com/)
|
||||
auths.tip.openid_connect=Utilisez l’URL de découverte OpenID « https://{server}/.well-known/openid-configuration » pour spécifier les points d'accès.
|
||||
auths.tip.twitter=Rendez-vous sur https://dev.twitter.com/apps, créez une application et assurez-vous que l'option "Autoriser l'application à être utilisée avec Twitter Connect" est activée
|
||||
auths.tip.discord=Enregistrer une nouvelle application sur https://discordapp.com/developers/applications/me
|
||||
auths.tip.gitea=Enregistrez une nouvelle application OAuth2. Le guide peut être trouvé sur https://docs.gitea.com/development/oauth2-provider
|
||||
@ -3135,6 +3237,7 @@ config.picture_config=Configuration de l'avatar
|
||||
config.picture_service=Service d'Imagerie
|
||||
config.disable_gravatar=Désactiver Gravatar
|
||||
config.enable_federated_avatar=Activer les avatars unifiés
|
||||
config.open_with_editor_app_help=Les éditeurs disponibles via « Ouvrir avec ». Si laissé vide, la valeur par défaut sera utilisée. Développez pour voir la valeur par défaut.
|
||||
|
||||
config.git_config=Configuration de Git
|
||||
config.git_disable_diff_highlight=Désactiver la surbrillance syntaxique de Diff
|
||||
@ -3214,11 +3317,13 @@ notices.op=Opération
|
||||
notices.delete_success=Les informations systèmes ont été supprimées.
|
||||
|
||||
self_check.no_problem_found=Aucun problème trouvé pour l’instant.
|
||||
self_check.startup_warnings=Avertissements au démarrage :
|
||||
self_check.database_collation_mismatch=Exige que la base de données utilise la collation %s.
|
||||
self_check.database_collation_case_insensitive=La base de données utilise la collation %s, insensible à la casse. Bien que Gitea soit compatible, il peut y avoir quelques rares cas qui ne fonctionnent pas comme prévu.
|
||||
self_check.database_inconsistent_collation_columns=La base de données utilise la collation %s, mais ces colonnes utilisent des collations différentes. Cela peut causer des problèmes imprévus.
|
||||
self_check.database_fix_mysql=Pour les utilisateurs de MySQL ou MariaDB, vous pouvez utiliser la commande « gitea doctor convert » dans un terminal ou exécuter une requête du type « ALTER … COLLATE ... » pour résoudre les problèmes de collation.
|
||||
self_check.database_fix_mssql=Pour les utilisateurs de MSSQL, vous ne pouvez résoudre le problème qu’en exécutant une requête SQL du type « ALTER … COLLATE … ».
|
||||
self_check.location_origin_mismatch=L’URL actuelle (%[1]s) ne correspond pas à l’URL vue par Gitea (%[2]). Si vous utilisez un proxy inverse, assurez-vous que les en-têtes « Host » et « X-Forwarded-Proto » sont correctement définis.
|
||||
|
||||
[action]
|
||||
create_repo=a créé le dépôt <a href="%s">%s</a>
|
||||
@ -3246,6 +3351,7 @@ mirror_sync_create=a synchronisé la nouvelle référence <a href="%[2]s">%[3]s<
|
||||
mirror_sync_delete=a synchronisé puis supprimé la nouvelle référence <code>%[2]s</code> vers <a href="%[1]s">%[3]s</a> depuis le miroir
|
||||
approve_pull_request=`a approuvé <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
reject_pull_request=`a suggérés des changements pour <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
publish_release=`a publié <a href="%[2]s"> "%[4]s" </a> dans <a href="%[1]s">%[3]s</a>`
|
||||
review_dismissed=`a révoqué l’évaluation de <b>%[4]s</b> dans <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
review_dismissed_reason=Raison :
|
||||
create_branch=a créé la branche <a href="%[2]s">%[3]s</a> dans <a href="%[1]s">%[4]s</a>
|
||||
@ -3312,6 +3418,7 @@ error.unit_not_allowed=Vous n'êtes pas autorisé à accéder à cette section d
|
||||
title=Paquets
|
||||
desc=Gérer les paquets du dépôt.
|
||||
empty=Il n'y pas de paquet pour le moment.
|
||||
no_metadata=Pas de métadonnées.
|
||||
empty.documentation=Pour plus d'informations sur le registre de paquets, voir <a target="_blank" rel="noopener noreferrer" href="%s">la documentation</a>.
|
||||
empty.repo=Avez-vous téléchargé un paquet, mais il n'est pas affiché ici? Allez dans les <a href="%[1]s">paramètres du paquet</a> et liez le à ce dépôt.
|
||||
registry.documentation=Pour plus d’informations sur le registre %s, voir <a target="_blank" rel="noopener noreferrer" href="%s">la documentation</a>.
|
||||
@ -3393,6 +3500,7 @@ npm.install=Pour installer le paquet en utilisant npm, exécutez la commande sui
|
||||
npm.install2=ou ajoutez-le au fichier package.json :
|
||||
npm.dependencies=Dépendances
|
||||
npm.dependencies.development=Dépendances de développement
|
||||
npm.dependencies.bundle=Dépendances emballées
|
||||
npm.dependencies.peer=Dépendances de pairs
|
||||
npm.dependencies.optional=Dépendances optionnelles
|
||||
npm.details.tag=Balise
|
||||
@ -3532,6 +3640,8 @@ runs.scheduled=Planifié
|
||||
runs.pushed_by=soumis par
|
||||
runs.invalid_workflow_helper=La configuration du flux de travail est invalide. Veuillez vérifier votre fichier %s.
|
||||
runs.no_matching_online_runner_helper=Aucun exécuteur en ligne correspondant au libellé %s
|
||||
runs.no_job_without_needs=Le flux de travail doit contenir au moins une tâche sans dépendance.
|
||||
runs.no_job=Le flux de travail doit contenir au moins une tâche
|
||||
runs.actor=Acteur
|
||||
runs.status=Statut
|
||||
runs.actors_no_select=Tous les acteurs
|
||||
|
@ -1378,6 +1378,7 @@ commitstatus.success=成功
|
||||
ext_issues=外部イシューへのアクセス
|
||||
ext_issues.desc=外部のイシュートラッカーへのリンク。
|
||||
|
||||
projects.desc=プロジェクトでイシューとプルリクエストを管理します。
|
||||
projects.description=説明 (オプション)
|
||||
projects.description_placeholder=説明
|
||||
projects.create=プロジェクトを作成
|
||||
@ -1552,7 +1553,9 @@ issues.no_content=説明はありません。
|
||||
issues.close=イシューをクローズ
|
||||
issues.comment_pull_merged_at=がコミット %[1]s を %[2]s にマージ %[3]s
|
||||
issues.comment_manually_pull_merged_at=がコミット %[1]s を %[2]s に手動マージ %[3]s
|
||||
issues.close_comment_issue=コメントしてクローズ
|
||||
issues.reopen_issue=再オープンする
|
||||
issues.reopen_comment_issue=コメントして再オープン
|
||||
issues.create_comment=コメントする
|
||||
issues.comment.blocked_user=投稿者またはリポジトリのオーナーがあなたをブロックしているため、コメントの作成や編集はできません。
|
||||
issues.closed_at=`がイシューをクローズ <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
@ -3412,6 +3415,7 @@ error.unit_not_allowed=このセクションへのアクセスが許可されて
|
||||
title=パッケージ
|
||||
desc=リポジトリ パッケージを管理します。
|
||||
empty=パッケージはまだありません。
|
||||
no_metadata=メタデータがありません。
|
||||
empty.documentation=パッケージレジストリの詳細については、 <a target="_blank" rel="noopener noreferrer" href="%s">ドキュメント</a> を参照してください。
|
||||
empty.repo=パッケージはアップロード済みで、ここに表示されていないですか? <a href="%[1]s">パッケージ設定</a>を開いて、パッケージをこのリポジトリにリンクしてください。
|
||||
registry.documentation=%sレジストリの詳細については、 <a target="_blank" rel="noopener noreferrer" href="%s">ドキュメント</a> を参照してください。
|
||||
@ -3634,6 +3638,7 @@ runs.pushed_by=pushed by
|
||||
runs.invalid_workflow_helper=ワークフロー設定ファイルは無効です。あなたの設定ファイルを確認してください: %s
|
||||
runs.no_matching_online_runner_helper=ラベルに一致するオンラインのランナーが見つかりません: %s
|
||||
runs.no_job_without_needs=ワークフローには依存関係のないジョブが少なくとも1つ含まれている必要があります。
|
||||
runs.no_job=ワークフローには少なくとも1つのジョブが含まれている必要があります
|
||||
runs.actor=アクター
|
||||
runs.status=ステータス
|
||||
runs.actors_no_select=すべてのアクター
|
||||
|
8
package-lock.json
generated
8
package-lock.json
generated
@ -10,7 +10,7 @@
|
||||
"@citation-js/plugin-csl": "0.7.11",
|
||||
"@citation-js/plugin-software-formats": "0.6.1",
|
||||
"@github/markdown-toolbar-element": "2.2.3",
|
||||
"@github/relative-time-element": "4.4.0",
|
||||
"@github/relative-time-element": "4.4.1",
|
||||
"@github/text-expander-element": "2.6.1",
|
||||
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
|
||||
"@primer/octicons": "19.9.0",
|
||||
@ -1028,9 +1028,9 @@
|
||||
"integrity": "sha512-AlquKGee+IWiAMYVB0xyHFZRMnu4n3X4HTvJHu79GiVJ1ojTukCWyxMlF5NMsecoLcBKsuBhx3QPv2vkE/zQ0A=="
|
||||
},
|
||||
"node_modules/@github/relative-time-element": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.4.0.tgz",
|
||||
"integrity": "sha512-CrI6oAecoahG7PF5dsgjdvlF5kCtusVMjg810EULD81TvnDsP+k/FRi/ClFubWLgBo4EGpr2EfvmumtqQFo7ow=="
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.4.1.tgz",
|
||||
"integrity": "sha512-E2vRcIgDj8AHv/iHpQMLJ/RqKOJ704OXkKw6+Zdhk3X+kVQhOf3Wj8KVz4DfCQ1eOJR8XxY6XVv73yd+pjMfXA=="
|
||||
},
|
||||
"node_modules/@github/text-expander-element": {
|
||||
"version": "2.6.1",
|
||||
|
@ -9,7 +9,7 @@
|
||||
"@citation-js/plugin-csl": "0.7.11",
|
||||
"@citation-js/plugin-software-formats": "0.6.1",
|
||||
"@github/markdown-toolbar-element": "2.2.3",
|
||||
"@github/relative-time-element": "4.4.0",
|
||||
"@github/relative-time-element": "4.4.1",
|
||||
"@github/text-expander-element": "2.6.1",
|
||||
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
|
||||
"@primer/octicons": "19.9.0",
|
||||
|
@ -1,8 +1,5 @@
|
||||
[tool.poetry]
|
||||
name = "gitea"
|
||||
version = "0.0.0"
|
||||
description = ""
|
||||
authors = []
|
||||
package-mode = false
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
|
@ -116,9 +116,9 @@ func apiErrorDefined(ctx *context.Context, err *namedError) {
|
||||
}
|
||||
|
||||
func apiUnauthorizedError(ctx *context.Context) {
|
||||
// TODO: it doesn't seem quite right but it doesn't really cause problem at the moment.
|
||||
// container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed, ideally.
|
||||
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+httplib.GuessCurrentAppURL(ctx)+`v2/token",service="container_registry",scope="*"`)
|
||||
// container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed
|
||||
realmURL := strings.TrimSuffix(httplib.GuessCurrentAppURL(ctx), setting.AppSubURL+"/") + "/v2/token"
|
||||
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+realmURL+`",service="container_registry",scope="*"`)
|
||||
apiErrorDefined(ctx, errUnauthorized)
|
||||
}
|
||||
|
||||
|
@ -96,20 +96,34 @@ func FeedCapabilityResource(ctx *context.Context) {
|
||||
xmlResponse(ctx, http.StatusOK, Metadata)
|
||||
}
|
||||
|
||||
var searchTermExtract = regexp.MustCompile(`'([^']+)'`)
|
||||
var (
|
||||
searchTermExtract = regexp.MustCompile(`'([^']+)'`)
|
||||
searchTermExact = regexp.MustCompile(`\s+eq\s+'`)
|
||||
)
|
||||
|
||||
func getSearchTerm(ctx *context.Context) string {
|
||||
func getSearchTerm(ctx *context.Context) packages_model.SearchValue {
|
||||
searchTerm := strings.Trim(ctx.FormTrim("searchTerm"), "'")
|
||||
if searchTerm == "" {
|
||||
// $filter contains a query like:
|
||||
// (((Id ne null) and substringof('microsoft',tolower(Id)))
|
||||
// We don't support these queries, just extract the search term.
|
||||
match := searchTermExtract.FindStringSubmatch(ctx.FormTrim("$filter"))
|
||||
if len(match) == 2 {
|
||||
searchTerm = strings.TrimSpace(match[1])
|
||||
if searchTerm != "" {
|
||||
return packages_model.SearchValue{
|
||||
Value: searchTerm,
|
||||
ExactMatch: false,
|
||||
}
|
||||
}
|
||||
return searchTerm
|
||||
|
||||
// $filter contains a query like:
|
||||
// (((Id ne null) and substringof('microsoft',tolower(Id)))
|
||||
// https://www.odata.org/documentation/odata-version-2-0/uri-conventions/ section 4.5
|
||||
// We don't support these queries, just extract the search term.
|
||||
filter := ctx.FormTrim("$filter")
|
||||
match := searchTermExtract.FindStringSubmatch(filter)
|
||||
if len(match) == 2 {
|
||||
return packages_model.SearchValue{
|
||||
Value: strings.TrimSpace(match[1]),
|
||||
ExactMatch: searchTermExact.MatchString(filter),
|
||||
}
|
||||
}
|
||||
|
||||
return packages_model.SearchValue{}
|
||||
}
|
||||
|
||||
// https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/LegacyFeed/V2FeedQueryBuilder.cs
|
||||
@ -118,11 +132,9 @@ func SearchServiceV2(ctx *context.Context) {
|
||||
paginator := db.NewAbsoluteListOptions(skip, take)
|
||||
|
||||
pvs, total, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
|
||||
OwnerID: ctx.Package.Owner.ID,
|
||||
Type: packages_model.TypeNuGet,
|
||||
Name: packages_model.SearchValue{
|
||||
Value: getSearchTerm(ctx),
|
||||
},
|
||||
OwnerID: ctx.Package.Owner.ID,
|
||||
Type: packages_model.TypeNuGet,
|
||||
Name: getSearchTerm(ctx),
|
||||
IsInternal: optional.Some(false),
|
||||
Paginator: paginator,
|
||||
})
|
||||
@ -169,10 +181,8 @@ func SearchServiceV2(ctx *context.Context) {
|
||||
// http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752351
|
||||
func SearchServiceV2Count(ctx *context.Context) {
|
||||
count, err := nuget_model.CountPackages(ctx, &packages_model.PackageSearchOptions{
|
||||
OwnerID: ctx.Package.Owner.ID,
|
||||
Name: packages_model.SearchValue{
|
||||
Value: getSearchTerm(ctx),
|
||||
},
|
||||
OwnerID: ctx.Package.Owner.ID,
|
||||
Name: getSearchTerm(ctx),
|
||||
IsInternal: optional.Some(false),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -19,14 +19,8 @@ const (
|
||||
// Contributors render the page to show repository contributors graph
|
||||
func Contributors(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.activity.navbar.contributors")
|
||||
|
||||
ctx.Data["PageIsActivity"] = true
|
||||
ctx.Data["PageIsContributors"] = true
|
||||
|
||||
ctx.PageData["contributionType"] = "commits"
|
||||
|
||||
ctx.PageData["repoLink"] = ctx.Repo.RepoLink
|
||||
|
||||
ctx.HTML(http.StatusOK, tplContributors)
|
||||
}
|
||||
|
||||
|
@ -1794,6 +1794,7 @@ func ViewIssue(ctx *context.Context) {
|
||||
pull.Issue = issue
|
||||
canDelete := false
|
||||
allowMerge := false
|
||||
canWriteToHeadRepo := false
|
||||
|
||||
if ctx.IsSigned {
|
||||
if err := pull.LoadHeadRepo(ctx); err != nil {
|
||||
@ -1814,7 +1815,7 @@ func ViewIssue(ctx *context.Context) {
|
||||
ctx.Data["DeleteBranchLink"] = issue.Link() + "/cleanup"
|
||||
}
|
||||
}
|
||||
ctx.Data["CanWriteToHeadRepo"] = true
|
||||
canWriteToHeadRepo = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -1826,6 +1827,9 @@ func ViewIssue(ctx *context.Context) {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return
|
||||
}
|
||||
if !canWriteToHeadRepo { // maintainers maybe allowed to push to head repo even if they can't write to it
|
||||
canWriteToHeadRepo = pull.AllowMaintainerEdit && perm.CanWrite(unit.TypeCode)
|
||||
}
|
||||
allowMerge, err = pull_service.IsUserAllowedToMerge(ctx, pull, perm, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("IsUserAllowedToMerge", err)
|
||||
@ -1838,6 +1842,8 @@ func ViewIssue(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["CanWriteToHeadRepo"] = canWriteToHeadRepo
|
||||
ctx.Data["ShowMergeInstructions"] = canWriteToHeadRepo
|
||||
ctx.Data["AllowMerge"] = allowMerge
|
||||
|
||||
prUnit, err := repo.GetUnit(ctx, unit.TypePullRequests)
|
||||
@ -1892,13 +1898,9 @@ func ViewIssue(ctx *context.Context) {
|
||||
ctx.ServerError("LoadProtectedBranch", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["ShowMergeInstructions"] = true
|
||||
|
||||
if pb != nil {
|
||||
pb.Repo = pull.BaseRepo
|
||||
var showMergeInstructions bool
|
||||
if ctx.Doer != nil {
|
||||
showMergeInstructions = pb.CanUserPush(ctx, ctx.Doer)
|
||||
}
|
||||
ctx.Data["ProtectedBranch"] = pb
|
||||
ctx.Data["IsBlockedByApprovals"] = !issues_model.HasEnoughApprovals(ctx, pb, pull)
|
||||
ctx.Data["IsBlockedByRejection"] = issues_model.MergeBlockedByRejectedReview(ctx, pb, pull)
|
||||
@ -1909,7 +1911,6 @@ func ViewIssue(ctx *context.Context) {
|
||||
ctx.Data["ChangedProtectedFiles"] = pull.ChangedProtectedFiles
|
||||
ctx.Data["IsBlockedByChangedProtectedFiles"] = len(pull.ChangedProtectedFiles) != 0
|
||||
ctx.Data["ChangedProtectedFilesNum"] = len(pull.ChangedProtectedFiles)
|
||||
ctx.Data["ShowMergeInstructions"] = showMergeInstructions
|
||||
}
|
||||
ctx.Data["WillSign"] = false
|
||||
if ctx.Doer != nil {
|
||||
|
@ -156,7 +156,7 @@ func GetContentHistoryDetail(ctx *context.Context) {
|
||||
|
||||
// use chroma to render the diff html
|
||||
diffHTMLBuf := bytes.Buffer{}
|
||||
diffHTMLBuf.WriteString("<pre class='chroma' style='tab-size: 4'>")
|
||||
diffHTMLBuf.WriteString("<pre class='chroma'>")
|
||||
for _, it := range diff {
|
||||
if it.Type == diffmatchpatch.DiffInsert {
|
||||
diffHTMLBuf.WriteString("<span class='gi'>")
|
||||
|
@ -5,6 +5,7 @@ package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
org_model "code.gitea.io/gitea/models/organization"
|
||||
@ -15,6 +16,7 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/httplib"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
alpine_module "code.gitea.io/gitea/modules/packages/alpine"
|
||||
@ -178,7 +180,11 @@ func ViewPackageVersion(ctx *context.Context) {
|
||||
|
||||
switch pd.Package.Type {
|
||||
case packages_model.TypeContainer:
|
||||
ctx.Data["RegistryHost"] = setting.Packages.RegistryHost
|
||||
registryAppURL, err := url.Parse(httplib.GuessCurrentAppURL(ctx))
|
||||
if err != nil {
|
||||
registryAppURL, _ = url.Parse(setting.AppURL)
|
||||
}
|
||||
ctx.Data["RegistryHost"] = registryAppURL.Host
|
||||
case packages_model.TypeAlpine:
|
||||
branches := make(container.Set[string])
|
||||
repositories := make(container.Set[string])
|
||||
|
@ -1061,7 +1061,7 @@ func readFileName(rd *strings.Reader) (string, bool) {
|
||||
char, _ := rd.ReadByte()
|
||||
_ = rd.UnreadByte()
|
||||
if char == '"' {
|
||||
fmt.Fscanf(rd, "%q ", &name)
|
||||
_, _ = fmt.Fscanf(rd, "%q ", &name)
|
||||
if len(name) == 0 {
|
||||
log.Error("Reader has no file name: reader=%+v", rd)
|
||||
return "", true
|
||||
@ -1073,12 +1073,12 @@ func readFileName(rd *strings.Reader) (string, bool) {
|
||||
} else {
|
||||
// This technique is potentially ambiguous it may not be possible to uniquely identify the filenames from the diff line alone
|
||||
ambiguity = true
|
||||
fmt.Fscanf(rd, "%s ", &name)
|
||||
_, _ = fmt.Fscanf(rd, "%s ", &name)
|
||||
char, _ := rd.ReadByte()
|
||||
_ = rd.UnreadByte()
|
||||
for !(char == 0 || char == '"' || char == 'b') {
|
||||
var suffix string
|
||||
fmt.Fscanf(rd, "%s ", &suffix)
|
||||
_, _ = fmt.Fscanf(rd, "%s ", &suffix)
|
||||
name += " " + suffix
|
||||
char, _ = rd.ReadByte()
|
||||
_ = rd.UnreadByte()
|
||||
|
@ -57,7 +57,7 @@ func (m *Message) ToMessage() *gomail.Message {
|
||||
msg.SetHeader(header, m.Headers[header]...)
|
||||
}
|
||||
|
||||
if len(setting.MailService.SubjectPrefix) > 0 {
|
||||
if setting.MailService.SubjectPrefix != "" {
|
||||
msg.SetHeader("Subject", setting.MailService.SubjectPrefix+" "+m.Subject)
|
||||
} else {
|
||||
msg.SetHeader("Subject", m.Subject)
|
||||
@ -79,6 +79,14 @@ func (m *Message) ToMessage() *gomail.Message {
|
||||
if len(msg.GetHeader("Message-ID")) == 0 {
|
||||
msg.SetHeader("Message-ID", m.generateAutoMessageID())
|
||||
}
|
||||
|
||||
for k, v := range setting.MailService.OverrideHeader {
|
||||
if len(msg.GetHeader(k)) != 0 {
|
||||
log.Debug("Mailer override header '%s' as per config", k)
|
||||
}
|
||||
msg.SetHeader(k, v...)
|
||||
}
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
package mailer
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -36,3 +37,78 @@ func TestGenerateMessageID(t *testing.T) {
|
||||
gm = m.ToMessage()
|
||||
assert.Equal(t, "<msg-d@domain.com>", gm.GetHeader("Message-ID")[0])
|
||||
}
|
||||
|
||||
func TestToMessage(t *testing.T) {
|
||||
oldConf := *setting.MailService
|
||||
defer func() {
|
||||
setting.MailService = &oldConf
|
||||
}()
|
||||
setting.MailService.From = "test@gitea.com"
|
||||
|
||||
m1 := Message{
|
||||
Info: "info",
|
||||
FromAddress: "test@gitea.com",
|
||||
FromDisplayName: "Test Gitea",
|
||||
To: "a@b.com",
|
||||
Subject: "Issue X Closed",
|
||||
Body: "Some Issue got closed by Y-Man",
|
||||
}
|
||||
|
||||
buf := &strings.Builder{}
|
||||
_, err := m1.ToMessage().WriteTo(buf)
|
||||
assert.NoError(t, err)
|
||||
header, _ := extractMailHeaderAndContent(t, buf.String())
|
||||
assert.EqualValues(t, map[string]string{
|
||||
"Content-Type": "multipart/alternative;",
|
||||
"Date": "Mon, 01 Jan 0001 00:00:00 +0000",
|
||||
"From": "\"Test Gitea\" <test@gitea.com>",
|
||||
"Message-ID": "<autogen--6795364578871-69c000786adc60dc@localhost>",
|
||||
"Mime-Version": "1.0",
|
||||
"Subject": "Issue X Closed",
|
||||
"To": "a@b.com",
|
||||
"X-Auto-Response-Suppress": "All",
|
||||
}, header)
|
||||
|
||||
setting.MailService.OverrideHeader = map[string][]string{
|
||||
"Message-ID": {""}, // delete message id
|
||||
"Auto-Submitted": {"auto-generated"}, // suppress auto replay
|
||||
}
|
||||
|
||||
buf = &strings.Builder{}
|
||||
_, err = m1.ToMessage().WriteTo(buf)
|
||||
assert.NoError(t, err)
|
||||
header, _ = extractMailHeaderAndContent(t, buf.String())
|
||||
assert.EqualValues(t, map[string]string{
|
||||
"Content-Type": "multipart/alternative;",
|
||||
"Date": "Mon, 01 Jan 0001 00:00:00 +0000",
|
||||
"From": "\"Test Gitea\" <test@gitea.com>",
|
||||
"Message-ID": "",
|
||||
"Mime-Version": "1.0",
|
||||
"Subject": "Issue X Closed",
|
||||
"To": "a@b.com",
|
||||
"X-Auto-Response-Suppress": "All",
|
||||
"Auto-Submitted": "auto-generated",
|
||||
}, header)
|
||||
}
|
||||
|
||||
func extractMailHeaderAndContent(t *testing.T, mail string) (map[string]string, string) {
|
||||
header := make(map[string]string)
|
||||
|
||||
parts := strings.SplitN(mail, "boundary=", 2)
|
||||
if !assert.Len(t, parts, 2) {
|
||||
return nil, ""
|
||||
}
|
||||
content := strings.TrimSpace("boundary=" + parts[1])
|
||||
|
||||
hParts := strings.Split(parts[0], "\n")
|
||||
|
||||
for _, hPart := range hParts {
|
||||
parts := strings.SplitN(hPart, ":", 2)
|
||||
hk := strings.TrimSpace(parts[0])
|
||||
if hk != "" {
|
||||
header[hk] = strings.TrimSpace(parts[1])
|
||||
}
|
||||
}
|
||||
|
||||
return header, content
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ func newDownloader(ctx context.Context, ownerName string, opts base.MigrateOptio
|
||||
// migrateRepository will download information and then upload it to Uploader, this is a simple
|
||||
// process for small repository. For a big repository, save all the data to disk
|
||||
// before upload is better
|
||||
func migrateRepository(ctx context.Context, doer *user_model.User, downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions, messenger base.Messenger) error {
|
||||
func migrateRepository(_ context.Context, doer *user_model.User, downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions, messenger base.Messenger) error {
|
||||
if messenger == nil {
|
||||
messenger = base.NilMessenger
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
|
||||
if err := pr.Issue.LoadPoster(ctx); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if err := pr.Issue.LoadRepo(ctx); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
isExternalTracker := pr.BaseRepo.UnitEnabled(ctx, unit.TypeExternalTracker)
|
||||
issueReference := "#"
|
||||
@ -53,6 +56,9 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
|
||||
issueReference = "!"
|
||||
}
|
||||
|
||||
reviewedOn := fmt.Sprintf("Reviewed-on: %s/%s", setting.AppURL, pr.Issue.Link())
|
||||
reviewedBy := pr.GetApprovers(ctx)
|
||||
|
||||
if mergeStyle != "" {
|
||||
templateFilepath := fmt.Sprintf(".gitea/default_merge_message/%s_TEMPLATE.md", strings.ToUpper(string(mergeStyle)))
|
||||
commit, err := baseGitRepo.GetBranchCommit(pr.BaseRepo.DefaultBranch)
|
||||
@ -77,6 +83,8 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
|
||||
"PullRequestPosterName": pr.Issue.Poster.Name,
|
||||
"PullRequestIndex": strconv.FormatInt(pr.Index, 10),
|
||||
"PullRequestReference": fmt.Sprintf("%s%d", issueReference, pr.Index),
|
||||
"ReviewedOn": reviewedOn,
|
||||
"ReviewedBy": reviewedBy,
|
||||
}
|
||||
if pr.HeadRepo != nil {
|
||||
vars["HeadRepoOwnerName"] = pr.HeadRepo.OwnerName
|
||||
@ -116,20 +124,22 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
body = fmt.Sprintf("%s\n%s", reviewedOn, reviewedBy)
|
||||
|
||||
// Squash merge has a different from other styles.
|
||||
if mergeStyle == repo_model.MergeStyleSquash {
|
||||
return fmt.Sprintf("%s (%s%d)", pr.Issue.Title, issueReference, pr.Issue.Index), "", nil
|
||||
return fmt.Sprintf("%s (%s%d)", pr.Issue.Title, issueReference, pr.Issue.Index), body, nil
|
||||
}
|
||||
|
||||
if pr.BaseRepoID == pr.HeadRepoID {
|
||||
return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), "", nil
|
||||
return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), body, nil
|
||||
}
|
||||
|
||||
if pr.HeadRepo == nil {
|
||||
return fmt.Sprintf("Merge pull request '%s' (%s%d) from <deleted>:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), "", nil
|
||||
return fmt.Sprintf("Merge pull request '%s' (%s%d) from <deleted>:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), body, nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch), "", nil
|
||||
return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch), body, nil
|
||||
}
|
||||
|
||||
func expandDefaultMergeMessage(template string, vars map[string]string) (message, body string) {
|
||||
|
@ -285,7 +285,7 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
|
||||
}
|
||||
|
||||
// changeRepositoryName changes all corresponding setting from old repository name to new one.
|
||||
func changeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, newRepoName string) (err error) {
|
||||
func changeRepositoryName(ctx context.Context, repo *repo_model.Repository, newRepoName string) (err error) {
|
||||
oldRepoName := repo.Name
|
||||
newRepoName = strings.ToLower(newRepoName)
|
||||
if err = repo_model.IsUsableRepoName(newRepoName); err != nil {
|
||||
@ -347,7 +347,7 @@ func ChangeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo
|
||||
// local copy's origin accordingly.
|
||||
|
||||
repoWorkingPool.CheckIn(fmt.Sprint(repo.ID))
|
||||
if err := changeRepositoryName(ctx, doer, repo, newRepoName); err != nil {
|
||||
if err := changeRepositoryName(ctx, repo, newRepoName); err != nil {
|
||||
repoWorkingPool.CheckOut(fmt.Sprint(repo.ID))
|
||||
return err
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {readFileSync} from 'node:fs';
|
||||
import {env} from 'node:process';
|
||||
import {parse} from 'postcss';
|
||||
import plugin from 'tailwindcss/plugin.js';
|
||||
|
||||
const isProduction = env.NODE_ENV !== 'development';
|
||||
|
||||
@ -98,4 +99,26 @@ export default {
|
||||
})),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
plugin(({addUtilities}) => {
|
||||
addUtilities({
|
||||
// tw-hidden must win all other "display: xxx !important" classes to get the chance to "hide" an element.
|
||||
// do not use:
|
||||
// * "[hidden]" attribute: it's too weak, can not be applied to an element with "display: flex"
|
||||
// * ".hidden" class: it has been polluted by Fomantic UI in many cases
|
||||
// * inline style="display: none": it's difficult to tweak
|
||||
// * jQuery's show/hide/toggle: it can not show/hide elements with "display: xxx !important"
|
||||
// only use:
|
||||
// * this ".tw-hidden" class
|
||||
// * showElem/hideElem/toggleElem functions in "utils/dom.js"
|
||||
'.hidden.hidden': {
|
||||
'display': 'none',
|
||||
},
|
||||
// proposed class from https://github.com/tailwindlabs/tailwindcss/pull/12128
|
||||
'.break-anywhere': {
|
||||
'overflow-wrap': 'anywhere',
|
||||
},
|
||||
});
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
@ -25,7 +25,7 @@
|
||||
<td>{{.ID}}</td>
|
||||
<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{.Name}}</a></td>
|
||||
<td>{{.TypeName}}</td>
|
||||
<td>{{if .IsActive}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{svg (Iif .IsActive "octicon-check" "octicon-x")}}</td>
|
||||
<td>{{DateTime "short" .UpdatedUnix}}</td>
|
||||
<td>{{DateTime "short" .CreatedUnix}}</td>
|
||||
<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{svg "octicon-pencil"}}</a></td>
|
||||
|
@ -16,9 +16,9 @@
|
||||
<dt>{{ctx.Locale.Tr "admin.config.domain"}}</dt>
|
||||
<dd>{{.Domain}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.offline_mode"}}</dt>
|
||||
<dd>{{if .OfflineMode}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .OfflineMode "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.disable_router_log"}}</dt>
|
||||
<dd>{{if .DisableRouterLog}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .DisableRouterLog "octicon-check" "octicon-x")}}</dd>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
@ -55,10 +55,10 @@
|
||||
<div class="ui attached table segment">
|
||||
<dl class="admin-dl-horizontal">
|
||||
<dt>{{ctx.Locale.Tr "admin.config.ssh_enabled"}}</dt>
|
||||
<dd>{{if not .SSH.Disabled}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif (not .SSH.Disabled) "octicon-check" "octicon-x")}}</dd>
|
||||
{{if not .SSH.Disabled}}
|
||||
<dt>{{ctx.Locale.Tr "admin.config.ssh_start_builtin_server"}}</dt>
|
||||
<dd>{{if .SSH.StartBuiltinServer}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .SSH.StartBuiltinServer "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.ssh_domain"}}</dt>
|
||||
<dd>{{.SSH.Domain}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.ssh_port"}}</dt>
|
||||
@ -74,7 +74,7 @@
|
||||
<dt>{{ctx.Locale.Tr "admin.config.ssh_keygen_path"}}</dt>
|
||||
<dd>{{.SSH.KeygenPath}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.ssh_minimum_key_size_check"}}</dt>
|
||||
<dd>{{if .SSH.MinimumKeySizeCheck}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .SSH.MinimumKeySizeCheck "octicon-check" "octicon-x")}}</dd>
|
||||
{{if .SSH.MinimumKeySizeCheck}}
|
||||
<dt>{{ctx.Locale.Tr "admin.config.ssh_minimum_key_sizes"}}</dt>
|
||||
<dd>{{.SSH.MinimumKeySizes}}</dd>
|
||||
@ -90,7 +90,7 @@
|
||||
<div class="ui attached table segment">
|
||||
<dl class="admin-dl-horizontal">
|
||||
<dt>{{ctx.Locale.Tr "admin.config.lfs_enabled"}}</dt>
|
||||
<dd>{{if .LFS.StartServer}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .LFS.StartServer "octicon-check" "octicon-x")}}</dd>
|
||||
{{if .LFS.StartServer}}
|
||||
<dt>{{ctx.Locale.Tr "admin.config.lfs_content_path"}}</dt>
|
||||
<dd>{{JsonUtils.EncodeToString .LFS.Storage.ToShadowCopy}}</dd>
|
||||
@ -134,36 +134,36 @@
|
||||
<div class="ui attached table segment">
|
||||
<dl class="admin-dl-horizontal">
|
||||
<dt>{{ctx.Locale.Tr "admin.config.register_email_confirm"}}</dt>
|
||||
<dd>{{if .Service.RegisterEmailConfirm}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.RegisterEmailConfirm "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.disable_register"}}</dt>
|
||||
<dd>{{if .Service.DisableRegistration}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.DisableRegistration "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.allow_only_internal_registration"}}</dt>
|
||||
<dd>{{if .Service.AllowOnlyInternalRegistration}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.AllowOnlyInternalRegistration "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.allow_only_external_registration"}}</dt>
|
||||
<dd>{{if .Service.AllowOnlyExternalRegistration}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.AllowOnlyExternalRegistration "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.show_registration_button"}}</dt>
|
||||
<dd>{{if .Service.ShowRegistrationButton}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.ShowRegistrationButton "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.enable_openid_signup"}}</dt>
|
||||
<dd>{{if .Service.EnableOpenIDSignUp}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.EnableOpenIDSignUp "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.enable_openid_signin"}}</dt>
|
||||
<dd>{{if .Service.EnableOpenIDSignIn}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.EnableOpenIDSignIn "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.require_sign_in_view"}}</dt>
|
||||
<dd>{{if .Service.RequireSignInView}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.RequireSignInView "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.mail_notify"}}</dt>
|
||||
<dd>{{if .Service.EnableNotifyMail}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.EnableNotifyMail "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.enable_captcha"}}</dt>
|
||||
<dd>{{if .Service.EnableCaptcha}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.EnableCaptcha "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.default_keep_email_private"}}</dt>
|
||||
<dd>{{if .Service.DefaultKeepEmailPrivate}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.DefaultKeepEmailPrivate "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.default_allow_create_organization"}}</dt>
|
||||
<dd>{{if .Service.DefaultAllowCreateOrganization}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.DefaultAllowCreateOrganization "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.enable_timetracking"}}</dt>
|
||||
<dd>{{if .Service.EnableTimetracking}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.EnableTimetracking "octicon-check" "octicon-x")}}</dd>
|
||||
{{if .Service.EnableTimetracking}}
|
||||
<dt>{{ctx.Locale.Tr "admin.config.default_enable_timetracking"}}</dt>
|
||||
<dd>{{if .Service.DefaultEnableTimetracking}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.DefaultEnableTimetracking "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.default_allow_only_contributors_to_track_time"}}</dt>
|
||||
<dd>{{if .Service.DefaultAllowOnlyContributorsToTrackTime}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.DefaultAllowOnlyContributorsToTrackTime "octicon-check" "octicon-x")}}</dd>
|
||||
{{end}}
|
||||
<dt>{{ctx.Locale.Tr "admin.config.default_visibility_organization"}}</dt>
|
||||
<dd>{{.Service.DefaultOrgVisibility}}</dd>
|
||||
@ -171,7 +171,7 @@
|
||||
<dt>{{ctx.Locale.Tr "admin.config.no_reply_address"}}</dt>
|
||||
<dd>{{if .Service.NoReplyAddress}}{{.Service.NoReplyAddress}}{{else}}-{{end}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.default_enable_dependencies"}}</dt>
|
||||
<dd>{{if .Service.DefaultEnableDependencies}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Service.DefaultEnableDependencies "octicon-check" "octicon-x")}}</dd>
|
||||
<div class="divider"></div>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.active_code_lives"}}</dt>
|
||||
<dd>{{.Service.ActiveCodeLives}} {{ctx.Locale.Tr "tool.raw_minutes"}}</dd>
|
||||
@ -190,7 +190,7 @@
|
||||
<dt>{{ctx.Locale.Tr "admin.config.deliver_timeout"}}</dt>
|
||||
<dd>{{.Webhook.DeliverTimeout}} {{ctx.Locale.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.skip_tls_verify"}}</dt>
|
||||
<dd>{{if .Webhook.SkipTLSVerify}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Webhook.SkipTLSVerify "octicon-check" "octicon-x")}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -200,7 +200,7 @@
|
||||
<div class="ui attached table segment">
|
||||
<dl class="admin-dl-horizontal">
|
||||
<dt>{{ctx.Locale.Tr "admin.config.mailer_enabled"}}</dt>
|
||||
<dd>{{if .MailerEnabled}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .MailerEnabled "octicon-check" "octicon-x")}}</dd>
|
||||
{{if .MailerEnabled}}
|
||||
<dt>{{ctx.Locale.Tr "admin.config.mailer_name"}}</dt>
|
||||
<dd>{{.Mailer.Name}}</dd>
|
||||
@ -220,7 +220,7 @@
|
||||
<dt>{{ctx.Locale.Tr "admin.config.mailer_protocol"}}</dt>
|
||||
<dd>{{.Mailer.Protocol}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.mailer_enable_helo"}}</dt>
|
||||
<dd>{{if .Mailer.EnableHelo}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Mailer.EnableHelo "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.mailer_smtp_addr"}}</dt>
|
||||
<dd>{{.Mailer.SMTPAddr}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.mailer_smtp_port"}}</dt>
|
||||
@ -279,7 +279,7 @@
|
||||
<dt>{{ctx.Locale.Tr "admin.config.session_life_time"}}</dt>
|
||||
<dd>{{.SessionConfig.Maxlifetime}} {{ctx.Locale.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.https_only"}}</dt>
|
||||
<dd>{{if .SessionConfig.Secure}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .SessionConfig.Secure "octicon-check" "octicon-x")}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -289,7 +289,7 @@
|
||||
<div class="ui attached table segment">
|
||||
<dl class="admin-dl-horizontal">
|
||||
<dt>{{ctx.Locale.Tr "admin.config.git_disable_diff_highlight"}}</dt>
|
||||
<dd>{{if .Git.DisableDiffHighlight}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif .Git.DisableDiffHighlight "octicon-check" "octicon-x")}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.git_max_diff_lines"}}</dt>
|
||||
<dd>{{.Git.MaxGitDiffLines}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.git_max_diff_line_characters"}}</dt>
|
||||
@ -321,7 +321,7 @@
|
||||
<dl class="admin-dl-horizontal">
|
||||
{{if .Loggers.xorm.IsEnabled}}
|
||||
<dt>{{ctx.Locale.Tr "admin.config.xorm_log_sql"}}</dt>
|
||||
<dd>{{if $.LogSQL}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
|
||||
<dd>{{svg (Iif $.LogSQL "octicon-check" "octicon-x")}}</dd>
|
||||
{{end}}
|
||||
|
||||
{{if .Loggers.access.IsEnabled}}
|
||||
|
@ -26,7 +26,7 @@
|
||||
<td>{{DateTime "full" .Next}}</td>
|
||||
<td>{{if gt .Prev.Year 1}}{{DateTime "full" .Prev}}{{else}}-{{end}}</td>
|
||||
<td>{{.ExecTimes}}</td>
|
||||
<td {{if ne .Status ""}}data-tooltip-content="{{.FormatLastMessage ctx.Locale}}"{{end}} >{{if eq .Status ""}}—{{else if eq .Status "finished"}}{{svg "octicon-check" 16}}{{else}}{{svg "octicon-x" 16}}{{end}}</td>
|
||||
<td {{if ne .Status ""}}data-tooltip-content="{{.FormatLastMessage ctx.Locale}}"{{end}} >{{if eq .Status ""}}—{{else}}{{svg (Iif (eq .Status "finished") "octicon-check" "octicon-x") 16}}{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
|
@ -46,17 +46,17 @@
|
||||
<td><a href="{{AppSubUrl}}/{{.Name | PathEscape}}">{{.Name}}</a></td>
|
||||
<td class="gt-ellipsis tw-max-w-48">{{.FullName}}</td>
|
||||
<td class="gt-ellipsis tw-max-w-48">{{.Email}}</td>
|
||||
<td>{{if .IsPrimary}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{svg (Iif .IsPrimary "octicon-check" "octicon-x")}}</td>
|
||||
<td>
|
||||
{{if .CanChange}}
|
||||
<a class="link-email-action" href data-uid="{{.UID}}"
|
||||
data-email="{{.Email}}"
|
||||
data-primary="{{if .IsPrimary}}1{{else}}0{{end}}"
|
||||
data-activate="{{if .IsActivated}}0{{else}}1{{end}}">
|
||||
{{if .IsActivated}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
|
||||
{{svg (Iif .IsActivated "octicon-check" "octicon-x")}}
|
||||
</a>
|
||||
{{else}}
|
||||
{{if .IsActivated}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
|
||||
{{svg (Iif .IsActivated "octicon-check" "octicon-x")}}
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -5,7 +5,7 @@
|
||||
{{ctx.Locale.Tr "admin.packages.total_size" (FileSize .TotalBlobSize)}},
|
||||
{{ctx.Locale.Tr "admin.packages.unreferenced_size" (FileSize .TotalUnreferencedBlobSize)}})
|
||||
<div class="ui right">
|
||||
<form method="post" action="/admin/packages/cleanup">
|
||||
<form method="post" action="{{AppSubUrl}}/admin/packages/cleanup">
|
||||
{{.CsrfTokenHtml}}
|
||||
<button class="ui primary tiny button">{{ctx.Locale.Tr "admin.packages.cleanup"}}</button>
|
||||
</form>
|
||||
|
@ -47,13 +47,13 @@
|
||||
<tr>
|
||||
<td>{{.ID}}</td>
|
||||
<td>
|
||||
<a class="gt-word-break" href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a>
|
||||
<a class="tw-break-anywhere" href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a>
|
||||
{{if .Owner.Visibility.IsPrivate}}
|
||||
<span class="text gold">{{svg "octicon-lock"}}</span>
|
||||
{{end}}
|
||||
</td>
|
||||
<td>
|
||||
<a class="gt-word-break" href="{{.Link}}">{{.Name}}</a>
|
||||
<a class="tw-break-anywhere" href="{{.Link}}">{{.Name}}</a>
|
||||
{{if .IsArchived}}
|
||||
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.archived"}}</span>
|
||||
{{end}}
|
||||
|
@ -93,9 +93,9 @@
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="gt-ellipsis tw-max-w-48">{{.Email}}</td>
|
||||
<td>{{if .IsActive}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{if .IsRestricted}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{if index $.UsersTwoFaStatus .ID}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{svg (Iif .IsActive "octicon-check" "octicon-x")}}</td>
|
||||
<td>{{svg (Iif .IsRestricted "octicon-check" "octicon-x")}}</td>
|
||||
<td>{{svg (Iif (index $.UsersTwoFaStatus .ID) "octicon-check" "octicon-x")}}</td>
|
||||
<td>{{DateTime "short" .CreatedUnix}}</td>
|
||||
{{if .LastLoginUnix}}
|
||||
<td>{{DateTime "short" .LastLoginUnix}}</td>
|
||||
|
@ -104,7 +104,7 @@
|
||||
<span class="not-mobile">{{svg "octicon-triangle-down"}}</span>
|
||||
<span class="only-mobile">{{ctx.Locale.Tr "create_new"}}</span>
|
||||
</span>
|
||||
<div class="menu">
|
||||
<div class="menu left">
|
||||
<a class="item" href="{{AppSubUrl}}/repo/create">
|
||||
{{svg "octicon-plus"}} {{ctx.Locale.Tr "new_repo"}}
|
||||
</a>
|
||||
|
@ -25,7 +25,7 @@
|
||||
<div><label><input name="check" type="checkbox"> check</label></div>
|
||||
<div><button name="btn">submit post</button></div>
|
||||
</form>
|
||||
<form method="post" action="/no-such-uri" class="form-fetch-action">
|
||||
<form method="post" action="no-such-uri" class="form-fetch-action">
|
||||
<div class="tw-py-8">bad action url</div>
|
||||
<div><button name="btn">submit test</button></div>
|
||||
</form>
|
||||
|
@ -54,7 +54,7 @@
|
||||
{{end}}
|
||||
{{if .PackageDescriptor.Metadata.ImageLayers}}
|
||||
<h4 class="ui top attached header">{{ctx.Locale.Tr "packages.container.layers"}}</h4>
|
||||
<div class="ui attached segment gt-word-break">
|
||||
<div class="ui attached segment tw-break-anywhere">
|
||||
<table class="ui very basic compact table">
|
||||
<tbody>
|
||||
{{range .PackageDescriptor.Metadata.ImageLayers}}
|
||||
@ -80,7 +80,7 @@
|
||||
{{range $key, $value := .PackageDescriptor.Metadata.Labels}}
|
||||
<tr>
|
||||
<td class="top aligned">{{$key}}</td>
|
||||
<td class="gt-word-break">{{$value}}</td>
|
||||
<td class="tw-break-anywhere">{{$value}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
|
@ -59,7 +59,7 @@
|
||||
{{ctx.Locale.Tr "packages.settings.delete"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message gt-word-break">
|
||||
<div class="ui warning message tw-break-anywhere">
|
||||
{{ctx.Locale.Tr "packages.settings.delete.notice" .PackageDescriptor.Package.Name .PackageDescriptor.Version.Version}}
|
||||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
|
@ -66,7 +66,7 @@
|
||||
<div id="project-board">
|
||||
<div class="board {{if .CanWriteProjects}}sortable{{end}}"{{if .CanWriteProjects}} data-url="{{$.Link}}/move"{{end}}>
|
||||
{{range .Columns}}
|
||||
<div class="ui segment project-column"{{if .Color}} style="background: {{.Color}} !important; color: {{ContrastColor .Color}} !important"{{end}} data-id="{{.ID}}" data-sorting="{{.Sorting}}" data-url="{{$.Link}}/{{.ID}}">
|
||||
<div class="project-column"{{if .Color}} style="background: {{.Color}} !important; color: {{ContrastColor .Color}} !important"{{end}} data-id="{{.ID}}" data-sorting="{{.Sorting}}" data-url="{{$.Link}}/{{.ID}}">
|
||||
<div class="project-column-header{{if $canWriteProject}} tw-cursor-grab{{end}}">
|
||||
<div class="ui circular label project-column-issue-count">
|
||||
{{.NumIssues ctx}}
|
||||
@ -152,7 +152,7 @@
|
||||
<div class="divider"{{if .Color}} style="color: {{ContrastColor .Color}} !important"{{end}}></div>
|
||||
<div class="ui cards" data-url="{{$.Link}}/{{.ID}}" data-project="{{$.Project.ID}}" data-board="{{.ID}}" id="board_{{.ID}}">
|
||||
{{range (index $.IssuesMap .ID)}}
|
||||
<div class="issue-card gt-word-break {{if $canWriteProject}}tw-cursor-grab{{end}}" data-issue="{{.ID}}">
|
||||
<div class="issue-card tw-break-anywhere {{if $canWriteProject}}tw-cursor-grab{{end}}" data-issue="{{.ID}}">
|
||||
{{template "repo/issue/card" (dict "Issue" . "Page" $)}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{{range .RecentlyPushedNewBranches}}
|
||||
<div class="ui positive message tw-flex tw-items-center">
|
||||
<div class="tw-flex-1">
|
||||
<div class="ui positive message tw-flex tw-items-center tw-gap-2">
|
||||
<div class="tw-flex-1 tw-break-anywhere">
|
||||
{{$timeSince := TimeSince .CommitTime.AsTime ctx.Locale}}
|
||||
{{$branchLink := HTMLFormat `<a href="%s">%s</a>` .BranchLink .BranchDisplayName}}
|
||||
{{ctx.Locale.Tr "repo.pulls.recently_pushed_new_branches" $branchLink $timeSince}}
|
||||
|
@ -1,5 +1,6 @@
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
<div id="repo-contributors-chart"
|
||||
data-repo-link="{{.RepoLink}}"
|
||||
data-locale-filter-label="{{ctx.Locale.Tr "repo.contributors.contribution_type.filter_label"}}"
|
||||
data-locale-contribution-type-commits="{{ctx.Locale.Tr "repo.contributors.contribution_type.commits"}}"
|
||||
data-locale-contribution-type-additions="{{ctx.Locale.Tr "repo.contributors.contribution_type.additions"}}"
|
||||
|
@ -27,4 +27,4 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<a class="ui tiny basic button" href="?style={{if .IsSplitStyle}}unified{{else}}split{{end}}&whitespace={{$.WhitespaceBehavior}}&show-outdated={{$.ShowOutdatedComments}}" data-tooltip-content="{{if .IsSplitStyle}}{{ctx.Locale.Tr "repo.diff.show_unified_view"}}{{else}}{{ctx.Locale.Tr "repo.diff.show_split_view"}}{{end}}">{{if .IsSplitStyle}}{{svg "gitea-join"}}{{else}}{{svg "gitea-split"}}{{end}}</a>
|
||||
<a class="ui tiny basic button" href="?style={{if .IsSplitStyle}}unified{{else}}split{{end}}&whitespace={{$.WhitespaceBehavior}}&show-outdated={{$.ShowOutdatedComments}}" data-tooltip-content="{{if .IsSplitStyle}}{{ctx.Locale.Tr "repo.diff.show_unified_view"}}{{else}}{{ctx.Locale.Tr "repo.diff.show_split_view"}}{{end}}">{{svg (Iif .IsSplitStyle "gitea-join" "gitea-split")}}</a>
|
||||
|
@ -23,7 +23,7 @@
|
||||
<div class="quick-pull-choice js-quick-pull-choice">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox {{if not .CanCommitToBranch.CanCommitToBranch}}disabled{{end}}">
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="direct" button_text="{{ctx.Locale.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "direct"}}checked{{end}}>
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="direct" data-button-text="{{ctx.Locale.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "direct"}}checked{{end}}>
|
||||
<label>
|
||||
{{svg "octicon-git-commit"}}
|
||||
{{ctx.Locale.Tr "repo.editor.commit_directly_to_this_branch" .BranchName}}
|
||||
@ -43,9 +43,9 @@
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
{{if .CanCreatePullRequest}}
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" button_text="{{ctx.Locale.Tr "repo.editor.propose_file_change"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" data-button-text="{{ctx.Locale.Tr "repo.editor.propose_file_change"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
|
||||
{{else}}
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" button_text="{{ctx.Locale.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" data-button-text="{{ctx.Locale.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
|
||||
{{end}}
|
||||
<label>
|
||||
{{svg "octicon-git-pull-request"}}
|
||||
|
@ -5,7 +5,7 @@
|
||||
{{template "base/alert" .}}
|
||||
{{template "repo/code/recently_pushed_new_branches" .}}
|
||||
{{if and (not .HideRepoInfo) (not .IsBlame)}}
|
||||
<div class="repo-description gt-word-break">
|
||||
<div class="repo-description tw-break-anywhere">
|
||||
{{- $description := .Repository.DescriptionHTML ctx -}}
|
||||
{{if $description}}{{$description | RenderCodeBlock}}{{end}}
|
||||
{{if .Repository.Website}}<a href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}}
|
||||
|
@ -14,7 +14,7 @@
|
||||
<div class="issue-card-icon">
|
||||
{{template "shared/issueicon" .}}
|
||||
</div>
|
||||
<a class="issue-card-title muted issue-title" href="{{.Link}}">{{.Title | RenderEmoji ctx | RenderCodeBlock}}</a>
|
||||
<a class="issue-card-title muted issue-title tw-break-anywhere" href="{{.Link}}">{{.Title | RenderEmoji ctx | RenderCodeBlock}}</a>
|
||||
{{if and $.isPinnedIssueCard $.Page.IsRepoAdmin}}
|
||||
<a role="button" class="issue-card-unpin muted tw-flex tw-items-center" data-tooltip-content={{ctx.Locale.Tr "repo.issues.unpin_issue"}} data-issue-id="{{.ID}}" data-unpin-url="{{$.Page.Link}}/unpin/{{.Index}}">
|
||||
{{svg "octicon-x" 16}}
|
||||
|
@ -30,7 +30,7 @@
|
||||
{{end}}
|
||||
{{$previousExclusiveScope = $exclusiveScope}}
|
||||
<div class="item issue-action tw-flex tw-justify-between" data-action="toggle" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/labels">
|
||||
{{if SliceUtils.Contains $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context ctx.Locale .}}
|
||||
{{if SliceUtils.Contains $.SelLabelIDs .ID}}{{svg (Iif $exclusiveScope "octicon-dot-fill" "octicon-check")}}{{end}} {{RenderLabel $.Context ctx.Locale .}}
|
||||
{{template "repo/issue/labels/label_archived" .}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -21,7 +21,7 @@
|
||||
<div class="divider"></div>
|
||||
{{end}}
|
||||
{{$previousExclusiveScope = $exclusiveScope}}
|
||||
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span> {{RenderLabel $.Context ctx.Locale .}}
|
||||
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{svg (Iif $exclusiveScope "octicon-dot-fill" "octicon-check")}}</span> {{RenderLabel $.Context ctx.Locale .}}
|
||||
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
|
||||
<p class="archived-label-hint">{{template "repo/issue/labels/label_archived" .}}</p>
|
||||
</a>
|
||||
@ -34,7 +34,7 @@
|
||||
<div class="divider"></div>
|
||||
{{end}}
|
||||
{{$previousExclusiveScope = $exclusiveScope}}
|
||||
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span> {{RenderLabel $.Context ctx.Locale .}}
|
||||
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{svg (Iif $exclusiveScope "octicon-dot-fill" "octicon-check")}}</span> {{RenderLabel $.Context ctx.Locale .}}
|
||||
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
|
||||
<p class="archived-label-hint">{{template "repo/issue/labels/label_archived" .}}</p>
|
||||
</a>
|
||||
|
@ -7,7 +7,7 @@
|
||||
{{if .PinnedIssues}}
|
||||
<div id="issue-pins" {{if .IsRepoAdmin}}data-is-repo-admin{{end}}>
|
||||
{{range .PinnedIssues}}
|
||||
<div class="issue-card gt-word-break {{if $.IsRepoAdmin}}tw-cursor-grab{{end}}" data-move-url="{{$.Link}}/move_pin" data-issue-id="{{.ID}}">
|
||||
<div class="issue-card tw-break-anywhere {{if $.IsRepoAdmin}}tw-cursor-grab{{end}}" data-move-url="{{$.Link}}/move_pin" data-issue-id="{{.ID}}">
|
||||
{{template "repo/issue/card" (dict "Issue" . "Page" $ "isPinnedIssueCard" true)}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class="ui segments conversation-holder">
|
||||
<div class="ui segment collapsible-comment-box tw-py-2 tw-flex tw-items-center tw-justify-between">
|
||||
<div class="tw-flex tw-items-center">
|
||||
<a href="{{$comment.CodeCommentLink ctx}}" class="file-comment tw-ml-2 gt-word-break">{{$comment.TreePath}}</a>
|
||||
<a href="{{$comment.CodeCommentLink ctx}}" class="file-comment tw-ml-2 tw-break-anywhere">{{$comment.TreePath}}</a>
|
||||
{{if $invalid}}
|
||||
<span class="ui label basic small tw-ml-2" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.review.outdated_description"}}">
|
||||
{{ctx.Locale.Tr "repo.issues.review.outdated"}}
|
||||
|
@ -199,7 +199,6 @@
|
||||
|
||||
{{if .AllowMerge}} {{/* user is allowed to merge */}}
|
||||
{{$prUnit := .Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypePullRequests}}
|
||||
{{$approvers := (.Issue.PullRequest.GetApprovers ctx)}}
|
||||
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash $prUnit.PullRequestsConfig.AllowFastForwardOnly}}
|
||||
{{$hasPendingPullRequestMergeTip := ""}}
|
||||
{{if .HasPendingPullRequestMerge}}
|
||||
@ -208,11 +207,10 @@
|
||||
{{end}}
|
||||
<div class="divider"></div>
|
||||
<script type="module">
|
||||
const issueUrl = window.location.origin + {{$.Issue.Link}};
|
||||
const defaultMergeTitle = {{.DefaultMergeMessage}};
|
||||
const defaultSquashMergeTitle = {{.DefaultSquashMergeMessage}};
|
||||
const defaultMergeMessage = {{if .DefaultMergeBody}}{{.DefaultMergeBody}}{{else}}`Reviewed-on: ${issueUrl}\n` + {{$approvers}}{{end}};
|
||||
const defaultSquashMergeMessage = {{if .DefaultSquashMergeBody}}{{.DefaultSquashMergeBody}}{{else}}`Reviewed-on: ${issueUrl}\n` + {{$approvers}}{{end}};
|
||||
const defaultMergeMessage = {{.DefaultMergeBody}};
|
||||
const defaultSquashMergeMessage = {{.DefaultSquashMergeBody}};
|
||||
const mergeForm = {
|
||||
'baseLink': {{.Link}},
|
||||
'textCancel': {{ctx.Locale.Tr "cancel"}},
|
||||
|
@ -9,10 +9,10 @@
|
||||
<div class="ui secondary segment">
|
||||
{{if eq .PullRequest.Flow 0}}
|
||||
<div>git fetch -u {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}<origin-url data-url="{{.PullRequest.HeadRepo.Link}}"></origin-url>{{else}}origin{{end}} {{.PullRequest.HeadBranch}}:{{$localBranch}}</div>
|
||||
<div>git checkout {{$localBranch}}</div>
|
||||
{{else}}
|
||||
<div>git fetch -u origin {{.GetGitRefName}}:{{$localBranch}}</div>
|
||||
<div>git fetch -u origin {{.PullRequest.GetGitRefName}}:{{$localBranch}}</div>
|
||||
{{end}}
|
||||
<div>git checkout {{$localBranch}}</div>
|
||||
</div>
|
||||
{{if .ShowMergeInstructions}}
|
||||
<div><h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}</h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}}</div>
|
||||
|
@ -92,7 +92,7 @@
|
||||
</span>
|
||||
{{end}}
|
||||
{{if and .CanChange (or .Checked (and (not $.Issue.IsClosed) (not $.Issue.PullRequest.HasMerged)))}}
|
||||
<a href="#" class="ui muted icon re-request-review{{if .Checked}} checked{{end}}" data-tooltip-content="{{if .Checked}}{{ctx.Locale.Tr "repo.issues.remove_request_review"}}{{else}}{{ctx.Locale.Tr "repo.issues.re_request_review"}}{{end}}" data-issue-id="{{$.Issue.ID}}" data-id="{{.ItemID}}" data-update-url="{{$.RepoLink}}/issues/request_review">{{if .Checked}}{{svg "octicon-trash"}}{{else}}{{svg "octicon-sync"}}{{end}}</a>
|
||||
<a href="#" class="ui muted icon re-request-review{{if .Checked}} checked{{end}}" data-tooltip-content="{{if .Checked}}{{ctx.Locale.Tr "repo.issues.remove_request_review"}}{{else}}{{ctx.Locale.Tr "repo.issues.re_request_review"}}{{end}}" data-issue-id="{{$.Issue.ID}}" data-id="{{.ItemID}}" data-update-url="{{$.RepoLink}}/issues/request_review">{{svg (Iif .Checked "octicon-trash" "octicon-sync")}}</a>
|
||||
{{end}}
|
||||
{{svg (printf "octicon-%s" .Review.Type.Icon) 16 (printf "text %s" (.Review.HTMLTypeColorName))}}
|
||||
</div>
|
||||
|
@ -36,7 +36,7 @@
|
||||
{{if .HasMerged}}
|
||||
<div class="ui purple label issue-state-label">{{svg "octicon-git-merge" 16 "tw-mr-1"}} {{if eq .Issue.PullRequest.Status 3}}{{ctx.Locale.Tr "repo.pulls.manually_merged"}}{{else}}{{ctx.Locale.Tr "repo.pulls.merged"}}{{end}}</div>
|
||||
{{else if .Issue.IsClosed}}
|
||||
<div class="ui red label issue-state-label">{{if .Issue.IsPull}}{{svg "octicon-git-pull-request"}}{{else}}{{svg "octicon-issue-closed"}}{{end}} {{ctx.Locale.Tr "repo.issues.closed_title"}}</div>
|
||||
<div class="ui red label issue-state-label">{{svg (Iif .Issue.IsPull "octicon-git-pull-request" "octicon-issue-closed")}} {{ctx.Locale.Tr "repo.issues.closed_title"}}</div>
|
||||
{{else if .Issue.IsPull}}
|
||||
{{if .IsPullWorkInProgress}}
|
||||
<div class="ui grey label issue-state-label">{{svg "octicon-git-pull-request-draft"}} {{ctx.Locale.Tr "repo.issues.draft_title"}}</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</div>
|
||||
<div class="ui segment detail">
|
||||
<div class="tw-flex tw-items-center tw-justify-between tw-flex-wrap tw-mb-2">
|
||||
<h4 class="release-list-title gt-word-break">
|
||||
<h4 class="release-list-title tw-break-anywhere">
|
||||
{{if $.PageIsSingleTag}}{{$release.Title}}{{else}}<a class="muted" href="{{$.RepoLink}}/releases/tag/{{$release.TagName | PathEscapeSegments}}">{{$release.Title}}</a>{{end}}
|
||||
{{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "tw-flex"}}
|
||||
{{if $release.IsDraft}}
|
||||
|
@ -19,13 +19,13 @@
|
||||
<div class="flex-item-trailing">
|
||||
<div class="flex-text-block">
|
||||
{{svg "octicon-shield-lock"}}
|
||||
<div class="ui inline dropdown access-mode" data-url="{{$.Link}}/access_mode" data-uid="{{.ID}}" data-last-value="{{printf "%d" .Collaboration.Mode}}">
|
||||
<div class="ui dropdown custom access-mode" data-url="{{$.Link}}/access_mode" data-uid="{{.ID}}" data-last-value="{{.Collaboration.Mode}}">
|
||||
<div class="text">{{if eq .Collaboration.Mode 1}}{{ctx.Locale.Tr "repo.settings.collaboration.read"}}{{else if eq .Collaboration.Mode 2}}{{ctx.Locale.Tr "repo.settings.collaboration.write"}}{{else if eq .Collaboration.Mode 3}}{{ctx.Locale.Tr "repo.settings.collaboration.admin"}}{{else}}{{ctx.Locale.Tr "repo.settings.collaboration.undefined"}}{{end}}</div>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="menu">
|
||||
<div class="item" data-text="{{ctx.Locale.Tr "repo.settings.collaboration.admin"}}" data-value="3">{{ctx.Locale.Tr "repo.settings.collaboration.admin"}}</div>
|
||||
<div class="item" data-text="{{ctx.Locale.Tr "repo.settings.collaboration.write"}}" data-value="2">{{ctx.Locale.Tr "repo.settings.collaboration.write"}}</div>
|
||||
<div class="item" data-text="{{ctx.Locale.Tr "repo.settings.collaboration.read"}}" data-value="1">{{ctx.Locale.Tr "repo.settings.collaboration.read"}}</div>
|
||||
<div class="item" data-value="3">{{ctx.Locale.Tr "repo.settings.collaboration.admin"}}</div>
|
||||
<div class="item" data-value="2">{{ctx.Locale.Tr "repo.settings.collaboration.write"}}</div>
|
||||
<div class="item" data-value="1">{{ctx.Locale.Tr "repo.settings.collaboration.read"}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -41,9 +41,9 @@
|
||||
{{ShortSha .Oid}}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{if .InRepo}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{if .Exists}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{if .Accessible}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
|
||||
<td>{{svg (Iif .InRepo "octicon-check" "octicon-x")}}</td>
|
||||
<td>{{svg (Iif .Exists "octicon-check" "octicon-x")}}</td>
|
||||
<td>{{svg (Iif .Accessible "octicon-check" "octicon-x")}}</td>
|
||||
<td class="tw-text-right">
|
||||
<a class="ui primary button" href="{{$.LFSFilesLink}}/find?oid={{.Oid}}&size={{.Size}}&sha={{.SHA}}">{{ctx.Locale.Tr "repo.settings.lfs_findcommits"}}</a>
|
||||
</td>
|
||||
|
@ -217,7 +217,7 @@
|
||||
<tbody>
|
||||
{{range .PushMirrors}}
|
||||
<tr>
|
||||
<td class="gt-word-break">{{.RemoteAddress}}</td>
|
||||
<td class="tw-break-anywhere">{{.RemoteAddress}}</td>
|
||||
<td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.push"}}</td>
|
||||
<td>{{if .LastUpdateUnix}}{{DateTime "full" .LastUpdateUnix}}{{else}}{{ctx.Locale.Tr "never"}}{{end}} {{if .LastError}}<div class="ui red label" data-tooltip-content="{{.LastError}}">{{ctx.Locale.Tr "error"}}</div>{{end}}</td>
|
||||
<td class="right aligned">
|
||||
|
@ -3,7 +3,7 @@
|
||||
{{$buttonText := ctx.Locale.Tr "repo.star"}}
|
||||
{{if $.IsStaringRepo}}{{$buttonText = ctx.Locale.Tr "repo.unstar"}}{{end}}
|
||||
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
|
||||
{{if $.IsStaringRepo}}{{svg "octicon-star-fill"}}{{else}}{{svg "octicon-star"}}{{end}}
|
||||
{{svg (Iif $.IsStaringRepo "octicon-star-fill" "octicon-star")}}
|
||||
<span aria-hidden="true">{{$buttonText}}</span>
|
||||
</button>
|
||||
<a hx-boost="false" class="ui basic label" href="{{$.RepoLink}}/stars">
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class="ui header">
|
||||
<a class="file-revisions-btn ui basic button" title="{{ctx.Locale.Tr "repo.wiki.back_to_wiki"}}" href="{{.RepoLink}}/wiki/{{.PageURL}}"><span>{{.revision}}</span> {{svg "octicon-home"}}</a>
|
||||
{{$title}}
|
||||
<div class="ui sub header gt-word-break">
|
||||
<div class="ui sub header tw-break-anywhere">
|
||||
{{$timeSince := TimeSince .Author.When ctx.Locale}}
|
||||
{{ctx.Locale.Tr "repo.wiki.last_commit_info" .Author.Name $timeSince}}
|
||||
</div>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user