mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-04-23 03:21:35 +02:00
Merge branch 'forgejo' into upload_with_path_structure
This commit is contained in:
commit
007d1c62bd
138 changed files with 1678 additions and 1493 deletions
|
@ -10,25 +10,10 @@ code.gitea.io/gitea/cmd/forgejo
|
|||
ContextSetStdin
|
||||
|
||||
code.gitea.io/gitea/models
|
||||
IsErrUpdateTaskNotExist
|
||||
ErrUpdateTaskNotExist.Error
|
||||
ErrUpdateTaskNotExist.Unwrap
|
||||
IsErrSHANotFound
|
||||
IsErrMergeDivergingFastForwardOnly
|
||||
|
||||
code.gitea.io/gitea/models/actions
|
||||
ScheduleList.GetUserIDs
|
||||
ScheduleList.GetRepoIDs
|
||||
ScheduleList.LoadTriggerUser
|
||||
ScheduleList.LoadRepos
|
||||
|
||||
code.gitea.io/gitea/models/asymkey
|
||||
ErrGPGKeyAccessDenied.Error
|
||||
ErrGPGKeyAccessDenied.Unwrap
|
||||
HasDeployKey
|
||||
|
||||
code.gitea.io/gitea/models/auth
|
||||
GetSourceByName
|
||||
WebAuthnCredentials
|
||||
|
||||
code.gitea.io/gitea/models/db
|
||||
|
@ -54,43 +39,24 @@ code.gitea.io/gitea/models/git
|
|||
|
||||
code.gitea.io/gitea/models/issues
|
||||
IsErrUnknownDependencyType
|
||||
ErrNewIssueInsert.Error
|
||||
IsErrIssueWasClosed
|
||||
ChangeMilestoneStatus
|
||||
|
||||
code.gitea.io/gitea/models/organization
|
||||
GetTeamNamesByID
|
||||
UpdateTeamUnits
|
||||
SearchMembersOptions.ToConds
|
||||
UsersInTeamsCount
|
||||
|
||||
code.gitea.io/gitea/models/perm/access
|
||||
GetRepoWriters
|
||||
|
||||
code.gitea.io/gitea/models/project
|
||||
UpdateColumnSorting
|
||||
ChangeProjectStatus
|
||||
|
||||
code.gitea.io/gitea/models/repo
|
||||
DeleteAttachmentsByIssue
|
||||
FindReposMapByIDs
|
||||
IsErrTopicNotExist
|
||||
ErrTopicNotExist.Error
|
||||
ErrTopicNotExist.Unwrap
|
||||
GetTopicByName
|
||||
WatchRepoMode
|
||||
|
||||
code.gitea.io/gitea/models/user
|
||||
ErrUserInactive.Error
|
||||
ErrUserInactive.Unwrap
|
||||
IsErrExternalLoginUserAlreadyExist
|
||||
IsErrExternalLoginUserNotExist
|
||||
NewFederatedUser
|
||||
IsErrUserSettingIsNotExist
|
||||
GetUserAllSettings
|
||||
DeleteUserSetting
|
||||
GetUserEmailsByNames
|
||||
GetUserNamesByIDs
|
||||
|
||||
code.gitea.io/gitea/modules/activitypub
|
||||
NewContext
|
||||
|
@ -114,9 +80,6 @@ code.gitea.io/gitea/modules/cache
|
|||
WithNoCacheContext
|
||||
RemoveContextData
|
||||
|
||||
code.gitea.io/gitea/modules/charset
|
||||
BreakWriter.Write
|
||||
|
||||
code.gitea.io/gitea/modules/emoji
|
||||
ReplaceCodes
|
||||
|
||||
|
@ -138,10 +101,7 @@ code.gitea.io/gitea/modules/git
|
|||
CommitChangesWithArgs
|
||||
SetUpdateHook
|
||||
openRepositoryWithDefaultContext
|
||||
IsTagExist
|
||||
ToEntryMode
|
||||
LimitedReaderCloser.Read
|
||||
LimitedReaderCloser.Close
|
||||
|
||||
code.gitea.io/gitea/modules/gitgraph
|
||||
Parser.Reset
|
||||
|
@ -182,16 +142,8 @@ code.gitea.io/gitea/modules/markup/console
|
|||
RenderString
|
||||
|
||||
code.gitea.io/gitea/modules/markup/markdown
|
||||
IsDetails
|
||||
IsSummary
|
||||
IsTaskCheckBoxListItem
|
||||
IsIcon
|
||||
RenderRawString
|
||||
|
||||
code.gitea.io/gitea/modules/markup/markdown/math
|
||||
WithInlineDollarParser
|
||||
WithBlockDollarParser
|
||||
|
||||
code.gitea.io/gitea/modules/markup/mdstripper
|
||||
stripRenderer.AddOptions
|
||||
StripMarkdown
|
||||
|
@ -199,9 +151,6 @@ code.gitea.io/gitea/modules/markup/mdstripper
|
|||
code.gitea.io/gitea/modules/markup/orgmode
|
||||
RenderString
|
||||
|
||||
code.gitea.io/gitea/modules/private
|
||||
ActionsRunnerRegister
|
||||
|
||||
code.gitea.io/gitea/modules/process
|
||||
Manager.ExecTimeout
|
||||
|
||||
|
@ -224,14 +173,6 @@ code.gitea.io/gitea/modules/setting
|
|||
GitConfigType.GetOption
|
||||
InitLoggersForTest
|
||||
|
||||
code.gitea.io/gitea/modules/storage
|
||||
ErrInvalidConfiguration.Error
|
||||
IsErrInvalidConfiguration
|
||||
|
||||
code.gitea.io/gitea/modules/structs
|
||||
ParseCreateHook
|
||||
ParsePushHook
|
||||
|
||||
code.gitea.io/gitea/modules/sync
|
||||
StatusTable.Start
|
||||
StatusTable.IsRunning
|
||||
|
@ -263,9 +204,6 @@ code.gitea.io/gitea/modules/web
|
|||
RouteMock
|
||||
RouteMockReset
|
||||
|
||||
code.gitea.io/gitea/modules/web/middleware
|
||||
DeleteLocaleCookie
|
||||
|
||||
code.gitea.io/gitea/modules/zstd
|
||||
NewWriter
|
||||
Writer.Write
|
||||
|
@ -280,23 +218,11 @@ code.gitea.io/gitea/routers/web/org
|
|||
code.gitea.io/gitea/services/context
|
||||
GetPrivateContext
|
||||
|
||||
code.gitea.io/gitea/services/convert
|
||||
ToSecret
|
||||
|
||||
code.gitea.io/gitea/services/forms
|
||||
DeadlineForm.Validate
|
||||
|
||||
code.gitea.io/gitea/services/pull
|
||||
IsCommitStatusContextSuccess
|
||||
|
||||
code.gitea.io/gitea/services/repository
|
||||
IsErrForkAlreadyExist
|
||||
|
||||
code.gitea.io/gitea/services/repository/files
|
||||
ContentType.String
|
||||
GetFileResponseFromCommit
|
||||
TemporaryUploadRepository.GetLastCommit
|
||||
TemporaryUploadRepository.GetLastCommitByRef
|
||||
|
||||
code.gitea.io/gitea/services/webhook
|
||||
NewNotifier
|
||||
|
|
|
@ -3,7 +3,7 @@ runs:
|
|||
steps:
|
||||
- run: |
|
||||
su forgejo -c 'make deps-backend'
|
||||
- uses: actions/cache@v4
|
||||
- uses: https://data.forgejo.org/actions/cache@v4
|
||||
id: cache-backend
|
||||
with:
|
||||
path: ${{github.workspace}}/gitea
|
||||
|
|
|
@ -49,7 +49,7 @@ runs:
|
|||
|
||||
- name: "Restore Go dependencies from cache or mark for later caching"
|
||||
id: cache-deps
|
||||
uses: actions/cache@v4
|
||||
uses: https://data.forgejo.org/actions/cache@v4
|
||||
with:
|
||||
key: setup-cache-go-deps-${{ runner.os }}-${{ inputs.username }}-${{ steps.go-version.outputs.go_version }}-${{ hashFiles('go.sum', 'go.mod') }}
|
||||
restore-keys: |
|
||||
|
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
if: vars.ROLE == 'forgejo-coding'
|
||||
runs-on: lxc-bookworm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://data.forgejo.org/actions/checkout@v4
|
||||
|
||||
- id: forgejo
|
||||
uses: https://data.forgejo.org/actions/setup-forgejo@v2.0.4
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# root is used for testing, allow it
|
||||
if: vars.ROLE == 'forgejo-integration' || github.repository_owner == 'root'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://data.forgejo.org/actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
|
@ -37,11 +37,11 @@ jobs:
|
|||
container:
|
||||
image: data.forgejo.org/oci/node:20-bookworm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://data.forgejo.org/actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
show-progress: 'false'
|
||||
- uses: https://code.forgejo.org/actions/cascading-pr@v2.2.0
|
||||
- uses: https://data.forgejo.org/actions/cascading-pr@v2.2.0
|
||||
with:
|
||||
origin-url: ${{ env.GITHUB_SERVER_URL }}
|
||||
origin-repo: ${{ github.repository }}
|
||||
|
|
|
@ -39,7 +39,7 @@ jobs:
|
|||
runs-on: lxc-bookworm
|
||||
if: vars.DOER != '' && vars.FORGEJO != '' && vars.TO_OWNER != '' && vars.FROM_OWNER != '' && secrets.TOKEN != ''
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://data.forgejo.org/actions/checkout@v4
|
||||
|
||||
- name: copy & sign
|
||||
uses: https://data.forgejo.org/forgejo/forgejo-build-publish/publish@v5.3.1
|
||||
|
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
|
||||
runs-on: docker
|
||||
container:
|
||||
image: data.forgejo.org/renovate/renovate:39.136.1
|
||||
image: data.forgejo.org/renovate/renovate:39.156.1
|
||||
|
||||
steps:
|
||||
- name: Load renovate repo cache
|
||||
|
|
|
@ -46,7 +46,7 @@ jobs:
|
|||
apt-get update -qq
|
||||
apt-get -q install -qq -y zstd
|
||||
- name: "Cache frontend build for playwright testing"
|
||||
uses: actions/cache/save@v4
|
||||
uses: https://data.forgejo.org/actions/cache/save@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/public/assets
|
||||
key: frontend-build-${{ github.sha }}
|
||||
|
@ -104,7 +104,7 @@ jobs:
|
|||
fetch-depth: 20
|
||||
- uses: ./.forgejo/workflows-composite/setup-env
|
||||
- name: "Restore frontend build"
|
||||
uses: actions/cache/restore@v4
|
||||
uses: https://data.forgejo.org/actions/cache/restore@v4
|
||||
id: cache-frontend
|
||||
with:
|
||||
path: ${{github.workspace}}/public/assets
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/xx AS xx
|
||||
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/xx AS xx
|
||||
|
||||
FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.23-alpine3.21 as build-env
|
||||
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/golang:1.23-alpine3.21 as build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY=${GOPROXY:-direct}
|
||||
|
@ -51,7 +51,7 @@ RUN chmod 755 /tmp/local/usr/bin/entrypoint \
|
|||
/go/src/code.gitea.io/gitea/environment-to-ini
|
||||
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
|
||||
|
||||
FROM code.forgejo.org/oci/alpine:3.21
|
||||
FROM data.forgejo.org/oci/alpine:3.21
|
||||
ARG RELEASE_VERSION
|
||||
LABEL maintainer="contact@forgejo.org" \
|
||||
org.opencontainers.image.authors="Forgejo" \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/xx AS xx
|
||||
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/xx AS xx
|
||||
|
||||
FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.23-alpine3.21 as build-env
|
||||
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/golang:1.23-alpine3.21 as build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY=${GOPROXY:-direct}
|
||||
|
@ -49,7 +49,7 @@ RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
|
|||
/go/src/code.gitea.io/gitea/environment-to-ini
|
||||
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
|
||||
|
||||
FROM code.forgejo.org/oci/alpine:3.21
|
||||
FROM data.forgejo.org/oci/alpine:3.21
|
||||
LABEL maintainer="contact@forgejo.org" \
|
||||
org.opencontainers.image.authors="Forgejo" \
|
||||
org.opencontainers.image.url="https://forgejo.org" \
|
||||
|
|
4
Makefile
4
Makefile
|
@ -37,7 +37,7 @@ endif
|
|||
XGO_VERSION := go-1.21.x
|
||||
|
||||
AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.1.1 # renovate: datasource=go
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.2.0 # renovate: datasource=go
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.7.0 # renovate: datasource=go
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.2 # renovate: datasource=go
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go
|
||||
|
@ -49,7 +49,7 @@ GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasour
|
|||
DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.29.0 # renovate: datasource=go
|
||||
GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go
|
||||
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.17.1 # renovate: datasource=go
|
||||
RENOVATE_NPM_PACKAGE ?= renovate@39.136.1 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate
|
||||
RENOVATE_NPM_PACKAGE ?= renovate@39.156.1 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate
|
||||
|
||||
# https://github.com/disposable-email-domains/disposable-email-domains/commits/main/
|
||||
DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ...
|
||||
|
|
|
@ -14,6 +14,8 @@ import (
|
|||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// ActionSchedule represents a schedule of a workflow file
|
||||
|
@ -140,3 +142,25 @@ func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository, ca
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type FindScheduleOptions struct {
|
||||
db.ListOptions
|
||||
RepoID int64
|
||||
OwnerID int64
|
||||
}
|
||||
|
||||
func (opts FindScheduleOptions) ToConds() builder.Cond {
|
||||
cond := builder.NewCond()
|
||||
if opts.RepoID > 0 {
|
||||
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
|
||||
}
|
||||
if opts.OwnerID > 0 {
|
||||
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
|
||||
}
|
||||
|
||||
return cond
|
||||
}
|
||||
|
||||
func (opts FindScheduleOptions) ToOrders() string {
|
||||
return "`id` DESC"
|
||||
}
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package actions
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
type ScheduleList []*ActionSchedule
|
||||
|
||||
// GetUserIDs returns a slice of user's id
|
||||
func (schedules ScheduleList) GetUserIDs() []int64 {
|
||||
return container.FilterSlice(schedules, func(schedule *ActionSchedule) (int64, bool) {
|
||||
return schedule.TriggerUserID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (schedules ScheduleList) GetRepoIDs() []int64 {
|
||||
return container.FilterSlice(schedules, func(schedule *ActionSchedule) (int64, bool) {
|
||||
return schedule.RepoID, true
|
||||
})
|
||||
}
|
||||
|
||||
func (schedules ScheduleList) LoadTriggerUser(ctx context.Context) error {
|
||||
userIDs := schedules.GetUserIDs()
|
||||
users := make(map[int64]*user_model.User, len(userIDs))
|
||||
if err := db.GetEngine(ctx).In("id", userIDs).Find(&users); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, schedule := range schedules {
|
||||
if schedule.TriggerUserID == user_model.ActionsUserID {
|
||||
schedule.TriggerUser = user_model.NewActionsUser()
|
||||
} else {
|
||||
schedule.TriggerUser = users[schedule.TriggerUserID]
|
||||
if schedule.TriggerUser == nil {
|
||||
schedule.TriggerUser = user_model.NewGhostUser()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (schedules ScheduleList) LoadRepos(ctx context.Context) error {
|
||||
repoIDs := schedules.GetRepoIDs()
|
||||
repos, err := repo_model.GetRepositoriesMapByIDs(ctx, repoIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, schedule := range schedules {
|
||||
schedule.Repo = repos[schedule.RepoID]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type FindScheduleOptions struct {
|
||||
db.ListOptions
|
||||
RepoID int64
|
||||
OwnerID int64
|
||||
}
|
||||
|
||||
func (opts FindScheduleOptions) ToConds() builder.Cond {
|
||||
cond := builder.NewCond()
|
||||
if opts.RepoID > 0 {
|
||||
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
|
||||
}
|
||||
if opts.OwnerID > 0 {
|
||||
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
|
||||
}
|
||||
|
||||
return cond
|
||||
}
|
||||
|
||||
func (opts FindScheduleOptions) ToOrders() string {
|
||||
return "`id` DESC"
|
||||
}
|
|
@ -192,28 +192,6 @@ func (err ErrGPGKeyIDAlreadyUsed) Unwrap() error {
|
|||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
|
||||
type ErrGPGKeyAccessDenied struct {
|
||||
UserID int64
|
||||
KeyID int64
|
||||
}
|
||||
|
||||
// IsErrGPGKeyAccessDenied checks if an error is a ErrGPGKeyAccessDenied.
|
||||
func IsErrGPGKeyAccessDenied(err error) bool {
|
||||
_, ok := err.(ErrGPGKeyAccessDenied)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Error pretty-prints an error of type ErrGPGKeyAccessDenied.
|
||||
func (err ErrGPGKeyAccessDenied) Error() string {
|
||||
return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d]",
|
||||
err.UserID, err.KeyID)
|
||||
}
|
||||
|
||||
func (err ErrGPGKeyAccessDenied) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
|
||||
type ErrKeyAccessDenied struct {
|
||||
UserID int64
|
||||
|
|
|
@ -105,14 +105,6 @@ func addDeployKey(ctx context.Context, keyID, repoID int64, name, fingerprint st
|
|||
return key, db.Insert(ctx, key)
|
||||
}
|
||||
|
||||
// HasDeployKey returns true if public key is a deploy key of given repository.
|
||||
func HasDeployKey(ctx context.Context, keyID, repoID int64) bool {
|
||||
has, _ := db.GetEngine(ctx).
|
||||
Where("key_id = ? AND repo_id = ?", keyID, repoID).
|
||||
Get(new(DeployKey))
|
||||
return has
|
||||
}
|
||||
|
||||
// AddDeployKey add new deploy key to database and authorized_keys file.
|
||||
func AddDeployKey(ctx context.Context, repoID int64, name, content string, readOnly bool) (*DeployKey, error) {
|
||||
fingerprint, err := CalcFingerprint(content)
|
||||
|
|
|
@ -299,17 +299,6 @@ func GetSourceByID(ctx context.Context, id int64) (*Source, error) {
|
|||
return source, nil
|
||||
}
|
||||
|
||||
func GetSourceByName(ctx context.Context, name string) (*Source, error) {
|
||||
source := &Source{}
|
||||
has, err := db.GetEngine(ctx).Where("name = ?", name).Get(source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrSourceNotExist{}
|
||||
}
|
||||
return source, nil
|
||||
}
|
||||
|
||||
// UpdateSource updates a Source record in DB.
|
||||
func UpdateSource(ctx context.Context, source *Source) error {
|
||||
var originalSource *Source
|
||||
|
|
|
@ -151,25 +151,6 @@ func (err *ErrInvalidCloneAddr) Unwrap() error {
|
|||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrUpdateTaskNotExist represents a "UpdateTaskNotExist" kind of error.
|
||||
type ErrUpdateTaskNotExist struct {
|
||||
UUID string
|
||||
}
|
||||
|
||||
// IsErrUpdateTaskNotExist checks if an error is a ErrUpdateTaskNotExist.
|
||||
func IsErrUpdateTaskNotExist(err error) bool {
|
||||
_, ok := err.(ErrUpdateTaskNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUpdateTaskNotExist) Error() string {
|
||||
return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID)
|
||||
}
|
||||
|
||||
func (err ErrUpdateTaskNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrInvalidTagName represents a "InvalidTagName" kind of error.
|
||||
type ErrInvalidTagName struct {
|
||||
TagName string
|
||||
|
|
|
@ -63,21 +63,6 @@ func (err ErrIssueIsClosed) Error() string {
|
|||
return fmt.Sprintf("issue is closed [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index)
|
||||
}
|
||||
|
||||
// ErrNewIssueInsert is used when the INSERT statement in newIssue fails
|
||||
type ErrNewIssueInsert struct {
|
||||
OriginalError error
|
||||
}
|
||||
|
||||
// IsErrNewIssueInsert checks if an error is a ErrNewIssueInsert.
|
||||
func IsErrNewIssueInsert(err error) bool {
|
||||
_, ok := err.(ErrNewIssueInsert)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrNewIssueInsert) Error() string {
|
||||
return err.OriginalError.Error()
|
||||
}
|
||||
|
||||
// ErrIssueWasClosed is used when close a closed issue
|
||||
type ErrIssueWasClosed struct {
|
||||
ID int64
|
||||
|
|
|
@ -433,7 +433,7 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, la
|
|||
LabelIDs: labelIDs,
|
||||
Attachments: uuids,
|
||||
}); err != nil {
|
||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
|
||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("newIssue: %w", err)
|
||||
|
|
|
@ -251,21 +251,6 @@ func ChangeMilestoneStatusByRepoIDAndID(ctx context.Context, repoID, milestoneID
|
|||
return committer.Commit()
|
||||
}
|
||||
|
||||
// ChangeMilestoneStatus changes the milestone open/closed status.
|
||||
func ChangeMilestoneStatus(ctx context.Context, m *Milestone, isClosed bool) (err error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
if err := changeMilestoneStatus(ctx, m, isClosed); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
func changeMilestoneStatus(ctx context.Context, m *Milestone, isClosed bool) error {
|
||||
m.IsClosed = isClosed
|
||||
if isClosed {
|
||||
|
|
|
@ -298,17 +298,16 @@ func TestNewMilestone(t *testing.T) {
|
|||
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{})
|
||||
}
|
||||
|
||||
func TestChangeMilestoneStatus(t *testing.T) {
|
||||
func TestChangeMilestoneStatusByRepoIDAndID(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
|
||||
|
||||
require.NoError(t, issues_model.ChangeMilestoneStatus(db.DefaultContext, milestone, true))
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1")
|
||||
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{})
|
||||
require.NoError(t, issues_model.ChangeMilestoneStatusByRepoIDAndID(db.DefaultContext, 1, 1, true))
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1, IsClosed: true})
|
||||
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}, &issues_model.Milestone{})
|
||||
|
||||
require.NoError(t, issues_model.ChangeMilestoneStatus(db.DefaultContext, milestone, false))
|
||||
require.NoError(t, issues_model.ChangeMilestoneStatusByRepoIDAndID(db.DefaultContext, 1, 1, false))
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=0")
|
||||
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{})
|
||||
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}, &issues_model.Milestone{})
|
||||
}
|
||||
|
||||
func TestDeleteMilestoneByRepoID(t *testing.T) {
|
||||
|
|
|
@ -575,7 +575,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Iss
|
|||
Attachments: uuids,
|
||||
IsPull: true,
|
||||
}); err != nil {
|
||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
|
||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("newIssue: %w", err)
|
||||
|
|
|
@ -247,22 +247,6 @@ func GetTeamByID(ctx context.Context, teamID int64) (*Team, error) {
|
|||
return t, nil
|
||||
}
|
||||
|
||||
// GetTeamNamesByID returns team's lower name from a list of team ids.
|
||||
func GetTeamNamesByID(ctx context.Context, teamIDs []int64) ([]string, error) {
|
||||
if len(teamIDs) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
var teamNames []string
|
||||
err := db.GetEngine(ctx).Table("team").
|
||||
Select("lower_name").
|
||||
In("id", teamIDs).
|
||||
Asc("name").
|
||||
Find(&teamNames)
|
||||
|
||||
return teamNames, err
|
||||
}
|
||||
|
||||
// IncrTeamRepoNum increases the number of repos for the given team by 1
|
||||
func IncrTeamRepoNum(ctx context.Context, teamID int64) error {
|
||||
_, err := db.GetEngine(ctx).Incr("num_repos").ID(teamID).Update(new(Team))
|
||||
|
|
|
@ -188,20 +188,6 @@ func TestHasTeamRepo(t *testing.T) {
|
|||
test(2, 5, false)
|
||||
}
|
||||
|
||||
func TestUsersInTeamsCount(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
test := func(teamIDs, userIDs []int64, expected int64) {
|
||||
count, err := organization.UsersInTeamsCount(db.DefaultContext, teamIDs, userIDs)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expected, count)
|
||||
}
|
||||
|
||||
test([]int64{2}, []int64{1, 2, 3, 4}, 1) // only userid 2
|
||||
test([]int64{1, 2, 3, 4, 5}, []int64{2, 5}, 2) // userid 2,4
|
||||
test([]int64{1, 2, 3, 4, 5}, []int64{2, 3, 5}, 3) // userid 2,4,5
|
||||
}
|
||||
|
||||
func TestInconsistentOwnerTeam(t *testing.T) {
|
||||
defer unittest.OverrideFixtures(
|
||||
unittest.FixturesOptions{
|
||||
|
|
|
@ -28,24 +28,3 @@ func (t *TeamUnit) Unit() unit.Unit {
|
|||
func getUnitsByTeamID(ctx context.Context, teamID int64) (units []*TeamUnit, err error) {
|
||||
return units, db.GetEngine(ctx).Where("team_id = ?", teamID).Find(&units)
|
||||
}
|
||||
|
||||
// UpdateTeamUnits updates a teams's units
|
||||
func UpdateTeamUnits(ctx context.Context, team *Team, units []TeamUnit) (err error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
if _, err = db.GetEngine(ctx).Where("team_id = ?", team.ID).Delete(new(TeamUnit)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(units) > 0 {
|
||||
if err = db.Insert(ctx, units); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
|
|
@ -76,14 +76,3 @@ func GetTeamMembers(ctx context.Context, opts *SearchMembersOptions) ([]*user_mo
|
|||
func IsUserInTeams(ctx context.Context, userID int64, teamIDs []int64) (bool, error) {
|
||||
return db.GetEngine(ctx).Where("uid=?", userID).In("team_id", teamIDs).Exist(new(TeamUser))
|
||||
}
|
||||
|
||||
// UsersInTeamsCount counts the number of users which are in userIDs and teamIDs
|
||||
func UsersInTeamsCount(ctx context.Context, userIDs, teamIDs []int64) (int64, error) {
|
||||
var ids []int64
|
||||
if err := db.GetEngine(ctx).In("uid", userIDs).In("team_id", teamIDs).
|
||||
Table("team_user").
|
||||
Cols("uid").GroupBy("uid").Find(&ids); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int64(len(ids)), nil
|
||||
}
|
||||
|
|
|
@ -305,20 +305,6 @@ func SetDefaultColumn(ctx context.Context, projectID, columnID int64) error {
|
|||
})
|
||||
}
|
||||
|
||||
// UpdateColumnSorting update project column sorting
|
||||
func UpdateColumnSorting(ctx context.Context, cl ColumnList) error {
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
for i := range cl {
|
||||
if _, err := db.GetEngine(ctx).ID(cl[i].ID).Cols(
|
||||
"sorting",
|
||||
).Update(cl[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func GetColumnsByIDs(ctx context.Context, projectID int64, columnsIDs []int64) (ColumnList, error) {
|
||||
columns := make([]*Column, 0, 5)
|
||||
if err := db.GetEngine(ctx).
|
||||
|
|
|
@ -368,21 +368,6 @@ func ChangeProjectStatusByRepoIDAndID(ctx context.Context, repoID, projectID int
|
|||
return committer.Commit()
|
||||
}
|
||||
|
||||
// ChangeProjectStatus toggle a project between opened and closed
|
||||
func ChangeProjectStatus(ctx context.Context, p *Project, isClosed bool) error {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
if err := changeProjectStatus(ctx, p, isClosed); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
func changeProjectStatus(ctx context.Context, p *Project, isClosed bool) error {
|
||||
p.IsClosed = isClosed
|
||||
p.ClosedDateUnix = timeutil.TimeStampNow()
|
||||
|
|
|
@ -75,7 +75,7 @@ func TestProject(t *testing.T) {
|
|||
|
||||
assert.Equal(t, project.Title, projectFromDB.Title)
|
||||
|
||||
require.NoError(t, ChangeProjectStatus(db.DefaultContext, project, true))
|
||||
require.NoError(t, ChangeProjectStatusByRepoIDAndID(db.DefaultContext, project.RepoID, project.ID, true))
|
||||
|
||||
// Retrieve from DB afresh to check if it is truly closed
|
||||
projectFromDB, err = GetProjectByID(db.DefaultContext, project.ID)
|
||||
|
|
|
@ -219,16 +219,6 @@ func DeleteAttachments(ctx context.Context, attachments []*Attachment, remove bo
|
|||
return int(cnt), nil
|
||||
}
|
||||
|
||||
// DeleteAttachmentsByIssue deletes all attachments associated with the given issue.
|
||||
func DeleteAttachmentsByIssue(ctx context.Context, issueID int64, remove bool) (int, error) {
|
||||
attachments, err := GetAttachmentsByIssueID(ctx, issueID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return DeleteAttachments(ctx, attachments, remove)
|
||||
}
|
||||
|
||||
// DeleteAttachmentsByComment deletes all attachments associated with the given comment.
|
||||
func DeleteAttachmentsByComment(ctx context.Context, commentID int64, remove bool) (int, error) {
|
||||
attachments, err := GetAttachmentsByCommentID(ctx, commentID)
|
||||
|
|
|
@ -46,11 +46,7 @@ func TestGetByCommentOrIssueID(t *testing.T) {
|
|||
func TestDeleteAttachments(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
count, err := repo_model.DeleteAttachmentsByIssue(db.DefaultContext, 4, false)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, count)
|
||||
|
||||
count, err = repo_model.DeleteAttachmentsByComment(db.DefaultContext, 2, false)
|
||||
count, err := repo_model.DeleteAttachmentsByComment(db.DefaultContext, 2, false)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, count)
|
||||
|
||||
|
|
|
@ -21,11 +21,6 @@ import (
|
|||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// FindReposMapByIDs find repos as map
|
||||
func FindReposMapByIDs(ctx context.Context, repoIDs []int64, res map[int64]*Repository) error {
|
||||
return db.GetEngine(ctx).In("id", repoIDs).Find(&res)
|
||||
}
|
||||
|
||||
// RepositoryListDefaultPageSize is the default number of repositories
|
||||
// to load in memory when running administrative tasks on all (or almost
|
||||
// all) of them.
|
||||
|
|
|
@ -5,14 +5,12 @@ package repo
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
@ -39,26 +37,6 @@ type RepoTopic struct { //revive:disable-line:exported
|
|||
TopicID int64 `xorm:"pk"`
|
||||
}
|
||||
|
||||
// ErrTopicNotExist represents an error that a topic is not exist
|
||||
type ErrTopicNotExist struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsErrTopicNotExist checks if an error is an ErrTopicNotExist.
|
||||
func IsErrTopicNotExist(err error) bool {
|
||||
_, ok := err.(ErrTopicNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Error implements error interface
|
||||
func (err ErrTopicNotExist) Error() string {
|
||||
return fmt.Sprintf("topic is not exist [name: %s]", err.Name)
|
||||
}
|
||||
|
||||
func (err ErrTopicNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ValidateTopic checks a topic by length and match pattern rules
|
||||
func ValidateTopic(topic string) bool {
|
||||
return len(topic) <= 35 && topicPattern.MatchString(topic)
|
||||
|
@ -91,17 +69,6 @@ func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []st
|
|||
return validTopics, invalidTopics
|
||||
}
|
||||
|
||||
// GetTopicByName retrieves topic by name
|
||||
func GetTopicByName(ctx context.Context, name string) (*Topic, error) {
|
||||
var topic Topic
|
||||
if has, err := db.GetEngine(ctx).Where("name = ?", name).Get(&topic); err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTopicNotExist{name}
|
||||
}
|
||||
return &topic, nil
|
||||
}
|
||||
|
||||
// addTopicByNameToRepo adds a topic name to a repo and increments the topic count.
|
||||
// Returns topic after the addition
|
||||
func addTopicByNameToRepo(ctx context.Context, repoID int64, topicName string) (*Topic, error) {
|
||||
|
|
|
@ -52,8 +52,7 @@ func TestAddTopic(t *testing.T) {
|
|||
require.NoError(t, repo_model.SaveTopics(db.DefaultContext, 2, "golang", "gitea"))
|
||||
repo2NrOfTopics = 2
|
||||
totalNrOfTopics++
|
||||
topic, err := repo_model.GetTopicByName(db.DefaultContext, "gitea")
|
||||
require.NoError(t, err)
|
||||
topic := unittest.AssertExistsAndLoadBean(t, &repo_model.Topic{Name: "gitea"})
|
||||
assert.EqualValues(t, 1, topic.RepoCount)
|
||||
|
||||
topics, _, err = repo_model.FindTopics(db.DefaultContext, &repo_model.FindTopicOptions{})
|
||||
|
|
|
@ -71,27 +71,6 @@ func (err ErrUserProhibitLogin) Unwrap() error {
|
|||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrUserInactive represents a "ErrUserInactive" kind of error.
|
||||
type ErrUserInactive struct {
|
||||
UID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsErrUserInactive checks if an error is a ErrUserInactive
|
||||
func IsErrUserInactive(err error) bool {
|
||||
_, ok := err.(ErrUserInactive)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserInactive) Error() string {
|
||||
return fmt.Sprintf("user is inactive [uid: %d, name: %s]", err.UID, err.Name)
|
||||
}
|
||||
|
||||
// Unwrap unwraps this error as a ErrPermission error
|
||||
func (err ErrUserInactive) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrUserIsNotLocal represents a "ErrUserIsNotLocal" kind of error.
|
||||
type ErrUserIsNotLocal struct {
|
||||
UID int64
|
||||
|
|
|
@ -40,6 +40,7 @@ type SearchUserOptions struct {
|
|||
IsProhibitLogin optional.Option[bool]
|
||||
IncludeReserved bool
|
||||
|
||||
Load2FAStatus bool
|
||||
ExtraParamStrings map[string]string
|
||||
}
|
||||
|
||||
|
@ -126,17 +127,15 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess
|
|||
return e.Where(cond)
|
||||
}
|
||||
|
||||
// 2fa filter uses LEFT JOIN to check whether a user has a 2fa record
|
||||
// While using LEFT JOIN, sometimes the performance might not be good, but it won't be a problem now, such SQL is seldom executed.
|
||||
// There are some possible methods to refactor this SQL in future when we really need to optimize the performance (but not now):
|
||||
// (1) add a column in user table (2) add a setting value in user_setting table (3) use search engines (bleve/elasticsearch)
|
||||
// Check if the user has two factor enabled, which is TOTP or Webauthn.
|
||||
if opts.IsTwoFactorEnabled.Value() {
|
||||
cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL"))
|
||||
cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL OR webauthn_credential.user_id IS NOT NULL"))
|
||||
} else {
|
||||
cond = cond.And(builder.Expr("two_factor.uid IS NULL"))
|
||||
cond = cond.And(builder.Expr("two_factor.uid IS NULL AND webauthn_credential.user_id IS NULL"))
|
||||
}
|
||||
|
||||
return e.Join("LEFT OUTER", "two_factor", "two_factor.uid = `user`.id").
|
||||
Join("LEFT OUTER", "webauthn_credential", "webauthn_credential.user_id = `user`.id").
|
||||
Where(cond)
|
||||
}
|
||||
|
||||
|
|
|
@ -1043,22 +1043,6 @@ func GetUserByName(ctx context.Context, name string) (*User, error) {
|
|||
return u, nil
|
||||
}
|
||||
|
||||
// GetUserEmailsByNames returns a list of e-mails corresponds to names of users
|
||||
// that have their email notifications set to enabled or onmention.
|
||||
func GetUserEmailsByNames(ctx context.Context, names []string) []string {
|
||||
mails := make([]string, 0, len(names))
|
||||
for _, name := range names {
|
||||
u, err := GetUserByName(ctx, name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if u.IsMailable() && u.EmailNotificationsPreference != EmailNotificationsDisabled {
|
||||
mails = append(mails, u.Email)
|
||||
}
|
||||
}
|
||||
return mails
|
||||
}
|
||||
|
||||
// GetMaileableUsersByIDs gets users from ids, but only if they can receive mails
|
||||
func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([]*User, error) {
|
||||
if len(ids) == 0 {
|
||||
|
@ -1085,17 +1069,6 @@ func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([
|
|||
Find(&ous)
|
||||
}
|
||||
|
||||
// GetUserNamesByIDs returns usernames for all resolved users from a list of Ids.
|
||||
func GetUserNamesByIDs(ctx context.Context, ids []int64) ([]string, error) {
|
||||
unames := make([]string, 0, len(ids))
|
||||
err := db.GetEngine(ctx).In("id", ids).
|
||||
Table("user").
|
||||
Asc("name").
|
||||
Cols("name").
|
||||
Find(&unames)
|
||||
return unames, err
|
||||
}
|
||||
|
||||
// GetUserNameByID returns username for the id
|
||||
func GetUserNameByID(ctx context.Context, id int64) (string, error) {
|
||||
var name string
|
||||
|
|
|
@ -102,16 +102,6 @@ func TestGetUserByName(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetUserEmailsByNames(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
// ignore none active user email
|
||||
assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user9"}))
|
||||
assert.ElementsMatch(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user5"}))
|
||||
|
||||
assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "org7"}))
|
||||
}
|
||||
|
||||
func TestCanCreateOrganization(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
|
@ -222,7 +212,7 @@ func TestSearchUsers(t *testing.T) {
|
|||
[]int64{1041, 37})
|
||||
|
||||
testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsTwoFactorEnabled: optional.Some(true)},
|
||||
[]int64{24})
|
||||
[]int64{24, 32})
|
||||
}
|
||||
|
||||
func TestEmailNotificationPreferences(t *testing.T) {
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package charset
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
)
|
||||
|
||||
// BreakWriter wraps an io.Writer to always write '\n' as '<br>'
|
||||
type BreakWriter struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// Write writes the provided byte slice transparently replacing '\n' with '<br>'
|
||||
func (b *BreakWriter) Write(bs []byte) (n int, err error) {
|
||||
pos := 0
|
||||
for pos < len(bs) {
|
||||
idx := bytes.IndexByte(bs[pos:], '\n')
|
||||
if idx < 0 {
|
||||
wn, err := b.Writer.Write(bs[pos:])
|
||||
return n + wn, err
|
||||
}
|
||||
|
||||
if idx > 0 {
|
||||
wn, err := b.Writer.Write(bs[pos : pos+idx])
|
||||
n += wn
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = b.Writer.Write([]byte("<br>")); err != nil {
|
||||
return n, err
|
||||
}
|
||||
pos += idx + 1
|
||||
|
||||
n++
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package charset
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBreakWriter_Write(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
kase string
|
||||
expect string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "noline",
|
||||
kase: "abcdefghijklmnopqrstuvwxyz",
|
||||
expect: "abcdefghijklmnopqrstuvwxyz",
|
||||
},
|
||||
{
|
||||
name: "endline",
|
||||
kase: "abcdefghijklmnopqrstuvwxyz\n",
|
||||
expect: "abcdefghijklmnopqrstuvwxyz<br>",
|
||||
},
|
||||
{
|
||||
name: "startline",
|
||||
kase: "\nabcdefghijklmnopqrstuvwxyz",
|
||||
expect: "<br>abcdefghijklmnopqrstuvwxyz",
|
||||
},
|
||||
{
|
||||
name: "onlyline",
|
||||
kase: "\n\n\n",
|
||||
expect: "<br><br><br>",
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
kase: "",
|
||||
expect: "",
|
||||
},
|
||||
{
|
||||
name: "midline",
|
||||
kase: "\nabc\ndefghijkl\nmnopqrstuvwxy\nz",
|
||||
expect: "<br>abc<br>defghijkl<br>mnopqrstuvwxy<br>z",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
buf := &strings.Builder{}
|
||||
b := &BreakWriter{
|
||||
Writer: buf,
|
||||
}
|
||||
n, err := b.Write([]byte(tt.kase))
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("BreakWriter.Write() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if n != len(tt.kase) {
|
||||
t.Errorf("BreakWriter.Write() = %v, want %v", n, len(tt.kase))
|
||||
}
|
||||
if buf.String() != tt.expect {
|
||||
t.Errorf("BreakWriter.Write() wrote %q, want %v", buf.String(), tt.expect)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -20,11 +19,6 @@ import (
|
|||
// TagPrefix tags prefix path on the repository
|
||||
const TagPrefix = "refs/tags/"
|
||||
|
||||
// IsTagExist returns true if given tag exists in the repository.
|
||||
func IsTagExist(ctx context.Context, repoPath, name string) bool {
|
||||
return IsReferenceExist(ctx, repoPath, TagPrefix+name)
|
||||
}
|
||||
|
||||
// CreateTag create one tag in the repository
|
||||
func (repo *Repository) CreateTag(name, revision string) error {
|
||||
_, _, err := NewCommand(repo.Ctx, "tag").AddDashesAndList(name, revision).RunStdString(&RunOpts{Dir: repo.Path})
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -105,32 +104,6 @@ func ParseBool(value string) (result, valid bool) {
|
|||
return intValue != 0, true
|
||||
}
|
||||
|
||||
// LimitedReaderCloser is a limited reader closer
|
||||
type LimitedReaderCloser struct {
|
||||
R io.Reader
|
||||
C io.Closer
|
||||
N int64
|
||||
}
|
||||
|
||||
// Read implements io.Reader
|
||||
func (l *LimitedReaderCloser) Read(p []byte) (n int, err error) {
|
||||
if l.N <= 0 {
|
||||
_ = l.C.Close()
|
||||
return 0, io.EOF
|
||||
}
|
||||
if int64(len(p)) > l.N {
|
||||
p = p[0:l.N]
|
||||
}
|
||||
n, err = l.R.Read(p)
|
||||
l.N -= int64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Close implements io.Closer
|
||||
func (l *LimitedReaderCloser) Close() error {
|
||||
return l.C.Close()
|
||||
}
|
||||
|
||||
func HashFilePathForWebUI(s string) string {
|
||||
h := sha1.New()
|
||||
_, _ = h.Write([]byte(s))
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"bytes"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
@ -83,6 +84,10 @@ func newFilePreview(ctx *RenderContext, node *html.Node, locale translation.Loca
|
|||
} else if Type(filePath) != "" {
|
||||
urlFullSource = node.Data[m[0]:m[6]] + filePath + "?display=source#" + node.Data[m[8]:m[1]]
|
||||
}
|
||||
filePath, err := url.QueryUnescape(filePath)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
hash := node.Data[m[8]:m[9]]
|
||||
|
||||
preview.start = m[0]
|
||||
|
|
|
@ -759,9 +759,6 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
|
|||
title = path.Base(name)
|
||||
}
|
||||
alt := props["alt"]
|
||||
if alt == "" {
|
||||
alt = name
|
||||
}
|
||||
|
||||
// make the childNode an image - if we can, we also place the alt
|
||||
childNode.Type = html.ElementNode
|
||||
|
@ -772,9 +769,6 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
|
|||
{Key: "title", Val: title},
|
||||
{Key: "alt", Val: alt},
|
||||
}
|
||||
if alt == "" {
|
||||
childNode.Attr = childNode.Attr[:2]
|
||||
}
|
||||
} else {
|
||||
if !absoluteLink {
|
||||
if ctx.IsWiki {
|
||||
|
|
|
@ -416,7 +416,7 @@ func TestRender_ShortLinks(t *testing.T) {
|
|||
otherImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "Link+Other.jpg")
|
||||
encodedImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "Link+%23.jpg")
|
||||
notencodedImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "some", "path", "Link+#.jpg")
|
||||
favicon := "http://google.com/favicon.ico"
|
||||
favicon := "https://forgejo.org/favicon.ico"
|
||||
|
||||
test(
|
||||
"[[Link]]",
|
||||
|
@ -424,28 +424,28 @@ func TestRender_ShortLinks(t *testing.T) {
|
|||
`<p><a href="`+urlWiki+`" rel="nofollow">Link</a></p>`)
|
||||
test(
|
||||
"[[Link.jpg]]",
|
||||
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Link.jpg" alt="Link.jpg"/></a></p>`,
|
||||
`<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" title="Link.jpg" alt="Link.jpg"/></a></p>`)
|
||||
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Link.jpg" alt=""/></a></p>`,
|
||||
`<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" title="Link.jpg" alt=""/></a></p>`)
|
||||
test(
|
||||
"[["+favicon+"]]",
|
||||
`<p><a href="`+favicon+`" rel="nofollow"><img src="`+favicon+`" title="favicon.ico" alt="`+favicon+`"/></a></p>`,
|
||||
`<p><a href="`+favicon+`" rel="nofollow"><img src="`+favicon+`" title="favicon.ico" alt="`+favicon+`"/></a></p>`)
|
||||
`<p><a href="`+favicon+`" rel="nofollow"><img src="`+favicon+`" title="favicon.ico" alt=""/></a></p>`,
|
||||
`<p><a href="`+favicon+`" rel="nofollow"><img src="`+favicon+`" title="favicon.ico" alt=""/></a></p>`)
|
||||
test(
|
||||
"[[Name|Link]]",
|
||||
`<p><a href="`+url+`" rel="nofollow">Name</a></p>`,
|
||||
`<p><a href="`+urlWiki+`" rel="nofollow">Name</a></p>`)
|
||||
test(
|
||||
"[[Name|Link.jpg]]",
|
||||
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Name" alt="Name"/></a></p>`,
|
||||
`<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" title="Name" alt="Name"/></a></p>`)
|
||||
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Name" alt=""/></a></p>`,
|
||||
`<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" title="Name" alt=""/></a></p>`)
|
||||
test(
|
||||
"[[Name|Link.jpg|alt=AltName]]",
|
||||
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="AltName" alt="AltName"/></a></p>`,
|
||||
`<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" title="AltName" alt="AltName"/></a></p>`)
|
||||
test(
|
||||
"[[Name|Link.jpg|title=Title]]",
|
||||
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Title" alt="Title"/></a></p>`,
|
||||
`<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" title="Title" alt="Title"/></a></p>`)
|
||||
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Title" alt=""/></a></p>`,
|
||||
`<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" title="Title" alt=""/></a></p>`)
|
||||
test(
|
||||
"[[Name|Link.jpg|alt=AltName|title=Title]]",
|
||||
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Title" alt="AltName"/></a></p>`,
|
||||
|
@ -472,16 +472,16 @@ func TestRender_ShortLinks(t *testing.T) {
|
|||
`<p><a href="`+urlWiki+`" rel="nofollow">Link</a> <a href="`+otherURLWiki+`" rel="nofollow">Other Link</a> <a href="`+encodedURLWiki+`" rel="nofollow">Link?</a></p>`)
|
||||
test(
|
||||
"[[Link #.jpg]]",
|
||||
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`" title="Link #.jpg" alt="Link #.jpg"/></a></p>`,
|
||||
`<p><a href="`+encodedImgurlWiki+`" rel="nofollow"><img src="`+encodedImgurlWiki+`" title="Link #.jpg" alt="Link #.jpg"/></a></p>`)
|
||||
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`" title="Link #.jpg" alt=""/></a></p>`,
|
||||
`<p><a href="`+encodedImgurlWiki+`" rel="nofollow"><img src="`+encodedImgurlWiki+`" title="Link #.jpg" alt=""/></a></p>`)
|
||||
test(
|
||||
"[[Name|Link #.jpg|alt=\"AltName\"|title='Title']]",
|
||||
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`" title="Title" alt="AltName"/></a></p>`,
|
||||
`<p><a href="`+encodedImgurlWiki+`" rel="nofollow"><img src="`+encodedImgurlWiki+`" title="Title" alt="AltName"/></a></p>`)
|
||||
test(
|
||||
"[[some/path/Link #.jpg]]",
|
||||
`<p><a href="`+notencodedImgurl+`" rel="nofollow"><img src="`+notencodedImgurl+`" title="Link #.jpg" alt="some/path/Link #.jpg"/></a></p>`,
|
||||
`<p><a href="`+notencodedImgurlWiki+`" rel="nofollow"><img src="`+notencodedImgurlWiki+`" title="Link #.jpg" alt="some/path/Link #.jpg"/></a></p>`)
|
||||
`<p><a href="`+notencodedImgurl+`" rel="nofollow"><img src="`+notencodedImgurl+`" title="Link #.jpg" alt=""/></a></p>`,
|
||||
`<p><a href="`+notencodedImgurlWiki+`" rel="nofollow"><img src="`+notencodedImgurlWiki+`" title="Link #.jpg" alt=""/></a></p>`)
|
||||
test(
|
||||
"<p><a href=\"https://example.org\">[[foobar]]</a></p>",
|
||||
`<p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p>`,
|
||||
|
@ -1129,4 +1129,35 @@ func TestRender_FilePreview(t *testing.T) {
|
|||
localMetas,
|
||||
)
|
||||
})
|
||||
|
||||
commitFileURL = util.URLJoin(markup.TestRepoURL, "src", "commit", "eeb243c3395e1921c5d90e73bd739827251fc99d", "path", "to", "file%20%23.txt")
|
||||
|
||||
t.Run("file with strange characters in name", func(t *testing.T) {
|
||||
testRender(
|
||||
commitFileURL+"#L1",
|
||||
`<p></p>`+
|
||||
`<div class="file-preview-box">`+
|
||||
`<div class="header">`+
|
||||
`<div>`+
|
||||
`<a href="http://localhost:3000/gogits/gogs/src/commit/eeb243c3395e1921c5d90e73bd739827251fc99d/path/to/file%20%23.txt#L1" class="muted" rel="nofollow">path/to/file #.txt</a>`+
|
||||
`</div>`+
|
||||
`<span class="text small grey">`+
|
||||
`Line 1 in <a href="http://localhost:3000/gogits/gogs/src/commit/eeb243c3395e1921c5d90e73bd739827251fc99d" class="text black" rel="nofollow">eeb243c</a>`+
|
||||
`</span>`+
|
||||
`</div>`+
|
||||
`<div class="ui table">`+
|
||||
`<table class="file-preview">`+
|
||||
`<tbody>`+
|
||||
`<tr>`+
|
||||
`<td class="lines-num"><span data-line-number="1"></span></td>`+
|
||||
`<td class="lines-code chroma"><code class="code-inner">A`+"\n"+`</code></td>`+
|
||||
`</tr>`+
|
||||
`</tbody>`+
|
||||
`</table>`+
|
||||
`</div>`+
|
||||
`</div>`+
|
||||
`<p></p>`,
|
||||
localMetas,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -34,13 +34,6 @@ func NewDetails() *Details {
|
|||
}
|
||||
}
|
||||
|
||||
// IsDetails returns true if the given node implements the Details interface,
|
||||
// otherwise false.
|
||||
func IsDetails(node ast.Node) bool {
|
||||
_, ok := node.(*Details)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Summary is a block that contains the summary of details block
|
||||
type Summary struct {
|
||||
ast.BaseBlock
|
||||
|
@ -66,13 +59,6 @@ func NewSummary() *Summary {
|
|||
}
|
||||
}
|
||||
|
||||
// IsSummary returns true if the given node implements the Summary interface,
|
||||
// otherwise false.
|
||||
func IsSummary(node ast.Node) bool {
|
||||
_, ok := node.(*Summary)
|
||||
return ok
|
||||
}
|
||||
|
||||
// TaskCheckBoxListItem is a block that represents a list item of a markdown block with a checkbox
|
||||
type TaskCheckBoxListItem struct {
|
||||
*ast.ListItem
|
||||
|
@ -103,13 +89,6 @@ func NewTaskCheckBoxListItem(listItem *ast.ListItem) *TaskCheckBoxListItem {
|
|||
}
|
||||
}
|
||||
|
||||
// IsTaskCheckBoxListItem returns true if the given node implements the TaskCheckBoxListItem interface,
|
||||
// otherwise false.
|
||||
func IsTaskCheckBoxListItem(node ast.Node) bool {
|
||||
_, ok := node.(*TaskCheckBoxListItem)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Icon is an inline for a fomantic icon
|
||||
type Icon struct {
|
||||
ast.BaseInline
|
||||
|
@ -139,13 +118,6 @@ func NewIcon(name string) *Icon {
|
|||
}
|
||||
}
|
||||
|
||||
// IsIcon returns true if the given node implements the Icon interface,
|
||||
// otherwise false.
|
||||
func IsIcon(node ast.Node) bool {
|
||||
_, ok := node.(*Icon)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ColorPreview is an inline for a color preview
|
||||
type ColorPreview struct {
|
||||
ast.BaseInline
|
||||
|
|
|
@ -108,7 +108,7 @@ func TestRender_Images(t *testing.T) {
|
|||
|
||||
test(
|
||||
"[["+title+"|"+url+"]]",
|
||||
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt="`+title+`"/></a></p>`)
|
||||
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt=""/></a></p>`)
|
||||
test(
|
||||
"[]("+href+")",
|
||||
`<p><a href="`+href+`" rel="nofollow"><img src="`+result+`" alt="`+title+`"/></a></p>`)
|
||||
|
@ -119,7 +119,7 @@ func TestRender_Images(t *testing.T) {
|
|||
|
||||
test(
|
||||
"[["+title+"|"+url+"]]",
|
||||
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt="`+title+`"/></a></p>`)
|
||||
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt=""/></a></p>`)
|
||||
test(
|
||||
"[]("+href+")",
|
||||
`<p><a href="`+href+`" rel="nofollow"><img src="`+result+`" alt="`+title+`"/></a></p>`)
|
||||
|
@ -149,13 +149,13 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
|
|||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><a href="` + baseURLImages + `/images/icon-install.png" rel="nofollow"><img src="` + baseURLImages + `/images/icon-install.png" title="icon-install.png" alt="images/icon-install.png"/></a></th>
|
||||
<th><a href="` + baseURLImages + `/images/icon-install.png" rel="nofollow"><img src="` + baseURLImages + `/images/icon-install.png" title="icon-install.png" alt=""/></a></th>
|
||||
<th><a href="` + baseURLContent + `/Installation" rel="nofollow">Installation</a></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="` + baseURLImages + `/images/icon-usage.png" rel="nofollow"><img src="` + baseURLImages + `/images/icon-usage.png" title="icon-usage.png" alt="images/icon-usage.png"/></a></td>
|
||||
<td><a href="` + baseURLImages + `/images/icon-usage.png" rel="nofollow"><img src="` + baseURLImages + `/images/icon-usage.png" title="icon-usage.png" alt=""/></a></td>
|
||||
<td><a href="` + baseURLContent + `/Usage" rel="nofollow">Usage</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -164,9 +164,9 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
|
|||
`<p><a href="http://www.excelsiorjet.com/" rel="nofollow">Excelsior JET</a> allows you to create native executables for Windows, Linux and Mac OS X.</p>
|
||||
<ol>
|
||||
<li><a href="https://github.com/libgdx/libgdx/wiki/Gradle-on-the-Commandline#packaging-for-the-desktop" rel="nofollow">Package your libGDX application</a><br/>
|
||||
<a href="` + baseURLImages + `/images/1.png" rel="nofollow"><img src="` + baseURLImages + `/images/1.png" title="1.png" alt="images/1.png"/></a></li>
|
||||
<a href="` + baseURLImages + `/images/1.png" rel="nofollow"><img src="` + baseURLImages + `/images/1.png" title="1.png" alt=""/></a></li>
|
||||
<li>Perform a test run by hitting the Run! button.<br/>
|
||||
<a href="` + baseURLImages + `/images/2.png" rel="nofollow"><img src="` + baseURLImages + `/images/2.png" title="2.png" alt="images/2.png"/></a></li>
|
||||
<a href="` + baseURLImages + `/images/2.png" rel="nofollow"><img src="` + baseURLImages + `/images/2.png" title="2.png" alt=""/></a></li>
|
||||
</ol>
|
||||
<h2 id="user-content-custom-id">More tests</h2>
|
||||
<p>(from <a href="https://www.markdownguide.org/extended-syntax/" rel="nofollow">https://www.markdownguide.org/extended-syntax/</a>)</p>
|
||||
|
@ -849,8 +849,8 @@ mail@domain.com
|
|||
<a href="/path/file" target="_blank" rel="nofollow noopener"><img src="/path/file" alt="local image"/></a><br/>
|
||||
<a href="/path/file" target="_blank" rel="nofollow noopener"><img src="/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/image.jpg" rel="nofollow"><img src="/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/image.jpg" rel="nofollow"><img src="/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -876,8 +876,8 @@ space</p>
|
|||
<a href="/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/wiki/raw/image.jpg" rel="nofollow"><img src="/wiki/raw/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/wiki/raw/image.jpg" rel="nofollow"><img src="/wiki/raw/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -905,8 +905,8 @@ space</p>
|
|||
<a href="https://gitea.io/path/file" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://gitea.io/path/file" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="https://gitea.io/image.jpg" rel="nofollow"><img src="https://gitea.io/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="https://gitea.io/image.jpg" rel="nofollow"><img src="https://gitea.io/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -934,8 +934,8 @@ space</p>
|
|||
<a href="https://gitea.io/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://gitea.io/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="https://gitea.io/wiki/raw/image.jpg" rel="nofollow"><img src="https://gitea.io/wiki/raw/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="https://gitea.io/wiki/raw/image.jpg" rel="nofollow"><img src="https://gitea.io/wiki/raw/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -963,8 +963,8 @@ space</p>
|
|||
<a href="/relative/path/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/path/file" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/relative/path/image.jpg" rel="nofollow"><img src="/relative/path/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/relative/path/image.jpg" rel="nofollow"><img src="/relative/path/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -992,8 +992,8 @@ space</p>
|
|||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" rel="nofollow"><img src="/relative/path/wiki/raw/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" rel="nofollow"><img src="/relative/path/wiki/raw/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -1022,8 +1022,8 @@ space</p>
|
|||
<a href="/user/repo/media/branch/main/path/file" target="_blank" rel="nofollow noopener"><img src="/user/repo/media/branch/main/path/file" alt="local image"/></a><br/>
|
||||
<a href="/user/repo/media/branch/main/path/file" target="_blank" rel="nofollow noopener"><img src="/user/repo/media/branch/main/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/user/repo/media/branch/main/image.jpg" rel="nofollow"><img src="/user/repo/media/branch/main/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/user/repo/media/branch/main/image.jpg" rel="nofollow"><img src="/user/repo/media/branch/main/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -1052,8 +1052,8 @@ space</p>
|
|||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" rel="nofollow"><img src="/relative/path/wiki/raw/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" rel="nofollow"><img src="/relative/path/wiki/raw/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -1082,8 +1082,8 @@ space</p>
|
|||
<a href="/user/repo/path/file" target="_blank" rel="nofollow noopener"><img src="/user/repo/path/file" alt="local image"/></a><br/>
|
||||
<a href="/user/repo/path/file" target="_blank" rel="nofollow noopener"><img src="/user/repo/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/user/repo/image.jpg" rel="nofollow"><img src="/user/repo/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/user/repo/image.jpg" rel="nofollow"><img src="/user/repo/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -1112,8 +1112,8 @@ space</p>
|
|||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" rel="nofollow"><img src="/relative/path/wiki/raw/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" rel="nofollow"><img src="/relative/path/wiki/raw/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -1143,8 +1143,8 @@ space</p>
|
|||
<a href="/user/repo/media/branch/main/sub/folder/path/file" target="_blank" rel="nofollow noopener"><img src="/user/repo/media/branch/main/sub/folder/path/file" alt="local image"/></a><br/>
|
||||
<a href="/user/repo/media/branch/main/sub/folder/path/file" target="_blank" rel="nofollow noopener"><img src="/user/repo/media/branch/main/sub/folder/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/user/repo/media/branch/main/sub/folder/image.jpg" rel="nofollow"><img src="/user/repo/media/branch/main/sub/folder/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/user/repo/media/branch/main/sub/folder/image.jpg" rel="nofollow"><img src="/user/repo/media/branch/main/sub/folder/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
@ -1174,8 +1174,8 @@ space</p>
|
|||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" rel="nofollow"><img src="/relative/path/wiki/raw/image.jpg" title="local image" alt="local image"/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a><br/>
|
||||
<a href="/relative/path/wiki/raw/image.jpg" rel="nofollow"><img src="/relative/path/wiki/raw/image.jpg" title="local image" alt=""/></a><br/>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a><br/>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow">https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash</a><br/>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare<br/>
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow">https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb</a><br/>
|
||||
|
|
|
@ -39,28 +39,6 @@ func Enabled(enable ...bool) Option {
|
|||
})
|
||||
}
|
||||
|
||||
// WithInlineDollarParser enables or disables the parsing of $...$
|
||||
func WithInlineDollarParser(enable ...bool) Option {
|
||||
value := true
|
||||
if len(enable) > 0 {
|
||||
value = enable[0]
|
||||
}
|
||||
return extensionFunc(func(e *Extension) {
|
||||
e.parseDollarInline = value
|
||||
})
|
||||
}
|
||||
|
||||
// WithBlockDollarParser enables or disables the parsing of $$...$$
|
||||
func WithBlockDollarParser(enable ...bool) Option {
|
||||
value := true
|
||||
if len(enable) > 0 {
|
||||
value = enable[0]
|
||||
}
|
||||
return extensionFunc(func(e *Extension) {
|
||||
e.parseDollarBlock = value
|
||||
})
|
||||
}
|
||||
|
||||
// Math represents a math extension with default rendered delimiters
|
||||
var Math = &Extension{
|
||||
enabled: true,
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
x•ŽANÃ0EYû³GB;a U=D9€=þ&–ÚÙÓr} 7èêÞÓÓëåÒŒBœ^¬´¤˜yY8Ï:AІX}<7D>R×XkÎs"î;uìFº®9x” Œ ÊEdÐ’%Í~**Zß3\ºÙvíô9Й>nÿ8Žfxkû=<3D>[9K”%L>®ôêÙ{§<>7Ãs–;aÕvý4ÛhXOûH·Ô“þÕ†ûð`KÑ
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
|||
c9913120ed2c1e27c1d7752ecdb7a504dc7cf6be
|
||||
eeb243c3395e1921c5d90e73bd739827251fc99d
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package private
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
type ActionsRunnerRegisterRequest struct {
|
||||
Token string
|
||||
Scope string
|
||||
Labels []string
|
||||
Name string
|
||||
Version string
|
||||
}
|
||||
|
||||
func ActionsRunnerRegister(ctx context.Context, token, scope string, labels []string, name, version string) (string, ResponseExtra) {
|
||||
reqURL := setting.LocalURL + "api/internal/actions/register"
|
||||
|
||||
req := newInternalRequest(ctx, reqURL, "POST", ActionsRunnerRegisterRequest{
|
||||
Token: token,
|
||||
Scope: scope,
|
||||
Labels: labels,
|
||||
Name: name,
|
||||
Version: version,
|
||||
})
|
||||
|
||||
resp, extra := requestJSONResp(req, &ResponseText{})
|
||||
return resp.Text, extra
|
||||
}
|
|
@ -272,8 +272,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
|
|||
|
||||
// update team information and then check permission
|
||||
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5})
|
||||
err = organization.UpdateTeamUnits(db.DefaultContext, team, nil)
|
||||
require.NoError(t, err)
|
||||
unittest.AssertSuccessfulDelete(t, &organization.TeamUnit{TeamID: team.ID})
|
||||
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner)
|
||||
require.NoError(t, err)
|
||||
for _, unit := range repo.Units {
|
||||
|
|
|
@ -18,25 +18,6 @@ import (
|
|||
// ErrURLNotSupported represents url is not supported
|
||||
var ErrURLNotSupported = errors.New("url method not supported")
|
||||
|
||||
// ErrInvalidConfiguration is called when there is invalid configuration for a storage
|
||||
type ErrInvalidConfiguration struct {
|
||||
cfg any
|
||||
err error
|
||||
}
|
||||
|
||||
func (err ErrInvalidConfiguration) Error() string {
|
||||
if err.err != nil {
|
||||
return fmt.Sprintf("Invalid Configuration Argument: %v: Error: %v", err.cfg, err.err)
|
||||
}
|
||||
return fmt.Sprintf("Invalid Configuration Argument: %v", err.cfg)
|
||||
}
|
||||
|
||||
// IsErrInvalidConfiguration checks if an error is an ErrInvalidConfiguration
|
||||
func IsErrInvalidConfiguration(err error) bool {
|
||||
_, ok := err.(ErrInvalidConfiguration)
|
||||
return ok
|
||||
}
|
||||
|
||||
type Type = setting.StorageType
|
||||
|
||||
// NewStorageFunc is a function that creates a storage
|
||||
|
|
|
@ -141,26 +141,6 @@ func (p *CreatePayload) JSONPayload() ([]byte, error) {
|
|||
return json.MarshalIndent(p, "", " ")
|
||||
}
|
||||
|
||||
// ParseCreateHook parses create event hook content.
|
||||
func ParseCreateHook(raw []byte) (*CreatePayload, error) {
|
||||
hook := new(CreatePayload)
|
||||
if err := json.Unmarshal(raw, hook); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// it is possible the JSON was parsed, however,
|
||||
// was not from Gogs (maybe was from Bitbucket)
|
||||
// So we'll check to be sure certain key fields
|
||||
// were populated
|
||||
switch {
|
||||
case hook.Repo == nil:
|
||||
return nil, ErrInvalidReceiveHook
|
||||
case len(hook.Ref) == 0:
|
||||
return nil, ErrInvalidReceiveHook
|
||||
}
|
||||
return hook, nil
|
||||
}
|
||||
|
||||
// ________ .__ __
|
||||
// \______ \ ____ | | _____/ |_ ____
|
||||
// | | \_/ __ \| | _/ __ \ __\/ __ \
|
||||
|
@ -292,22 +272,6 @@ func (p *PushPayload) JSONPayload() ([]byte, error) {
|
|||
return json.MarshalIndent(p, "", " ")
|
||||
}
|
||||
|
||||
// ParsePushHook parses push event hook content.
|
||||
func ParsePushHook(raw []byte) (*PushPayload, error) {
|
||||
hook := new(PushPayload)
|
||||
if err := json.Unmarshal(raw, hook); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case hook.Repo == nil:
|
||||
return nil, ErrInvalidReceiveHook
|
||||
case len(hook.Ref) == 0:
|
||||
return nil, ErrInvalidReceiveHook
|
||||
}
|
||||
return hook, nil
|
||||
}
|
||||
|
||||
// Branch returns branch name from a payload
|
||||
func (p *PushPayload) Branch() string {
|
||||
return strings.ReplaceAll(p.Ref, "refs/heads/", "")
|
||||
|
|
|
@ -34,7 +34,7 @@ func AvatarHTML(src string, size int, class, name string) template.HTML {
|
|||
name = "avatar"
|
||||
}
|
||||
|
||||
return template.HTML(`<img loading="lazy" class="` + class + `" src="` + src + `" title="` + html.EscapeString(name) + `" width="` + sizeStr + `" height="` + sizeStr + `"/>`)
|
||||
return template.HTML(`<img loading="lazy" alt="" class="` + class + `" src="` + src + `" title="` + html.EscapeString(name) + `" width="` + sizeStr + `" height="` + sizeStr + `"/>`)
|
||||
}
|
||||
|
||||
// Avatar renders user avatars. args: user, size (int), class (string)
|
||||
|
|
|
@ -194,8 +194,8 @@ func TestRenderMarkdownToHtml(t *testing.T) {
|
|||
<a href="https://example.com" rel="nofollow">remote link</a>
|
||||
<a href="/image.jpg" target="_blank" rel="nofollow noopener"><img src="/image.jpg" alt="local image"/></a>
|
||||
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a>
|
||||
<a href="/image.jpg" rel="nofollow"><img src="/image.jpg" title="local image" alt="local image"/></a>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt="remote link"/></a>
|
||||
<a href="/image.jpg" rel="nofollow"><img src="/image.jpg" title="local image" alt=""/></a>
|
||||
<a href="https://example.com/image.jpg" rel="nofollow"><img src="https://example.com/image.jpg" title="remote link" alt=""/></a>
|
||||
<a href="https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash" rel="nofollow"><code>88fc37a3c0...12fc37a3c0 (hash)</code></a>
|
||||
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
|
||||
<a href="https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb" rel="nofollow"><code>88fc37a3c0</code></a>
|
||||
|
|
|
@ -158,6 +158,7 @@ commits = fallback value for commits
|
|||
|
||||
found := lang1.HasKey("no-such")
|
||||
assert.False(t, found)
|
||||
assert.EqualValues(t, "no-such", lang1.TrString("no-such"))
|
||||
require.NoError(t, ls.Close())
|
||||
}
|
||||
|
||||
|
|
|
@ -225,9 +225,9 @@ func (l *locale) TrString(trKey string, trArgs ...any) string {
|
|||
format = msg
|
||||
} else {
|
||||
// First fallback: old-style translation
|
||||
idx, ok := l.store.trKeyToIdxMap[trKey]
|
||||
idx, foundIndex := l.store.trKeyToIdxMap[trKey]
|
||||
found := false
|
||||
if ok {
|
||||
if foundIndex {
|
||||
if msg, ok := l.idxToMsgMap[idx]; ok {
|
||||
format = msg // use the found translation
|
||||
found = true
|
||||
|
@ -239,7 +239,7 @@ func (l *locale) TrString(trKey string, trArgs ...any) string {
|
|||
if defaultLang, ok := l.store.localeMap[l.store.defaultLang]; ok {
|
||||
if msg := defaultLang.LookupNewStyleMessage(trKey); msg != "" {
|
||||
format = msg
|
||||
} else {
|
||||
} else if foundIndex {
|
||||
// Third fallback: old-style default language
|
||||
if msg, ok := defaultLang.idxToMsgMap[idx]; ok {
|
||||
format = msg
|
||||
|
|
|
@ -53,9 +53,3 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale {
|
|||
func SetLocaleCookie(resp http.ResponseWriter, lang string, maxAge int) {
|
||||
SetSiteCookie(resp, "lang", lang, maxAge)
|
||||
}
|
||||
|
||||
// DeleteLocaleCookie convenience function to delete the locale cookie consistently
|
||||
// Setting the lang cookie will trigger the middleware to reset the language to previous state.
|
||||
func DeleteLocaleCookie(resp http.ResponseWriter) {
|
||||
SetSiteCookie(resp, "lang", "", -1)
|
||||
}
|
||||
|
|
|
@ -680,6 +680,8 @@ Location = Umístění
|
|||
To = Název větve
|
||||
Biography = Životopis
|
||||
AccessToken = Přístupový token
|
||||
username_claiming_cooldown = Uživatelské jméno nelze získat, protože ještě neskončila doba jeho platnosti. Půjde jej získat %[1]s.
|
||||
email_domain_is_not_allowed = Doména uživatelské e-mailové adresy <b>%s</b> je v rozporu se seznamem EMAIL_DOMAIN_ALLOWLIST nebo EMAIL_DOMAIN_BLOCKLIST. Ujistěte se, že je vaše adresa správně nastavena.
|
||||
|
||||
[user]
|
||||
change_avatar=Změnit váš avatar…
|
||||
|
@ -804,7 +806,7 @@ old_password=Stávající heslo
|
|||
new_password=Nové heslo
|
||||
retype_new_password=Potvrzení nového hesla
|
||||
password_incorrect=Zadané heslo není správné.
|
||||
change_password_success=Vaše heslo bylo aktualizováno. Od teď se přihlašujte novým heslem.
|
||||
change_password_success=Vaše heslo bylo aktualizováno. Od nynějška používejte kpřihlášení nové heslo.
|
||||
password_change_disabled=Externě ověřovaní uživatelé nemohou aktualizovat své heslo prostřednictvím webového rozhraní Forgejo.
|
||||
|
||||
emails=E-mailové adresy
|
||||
|
@ -1056,6 +1058,8 @@ language.description = Tento jazyk bude uložen do vašeho účtu a po přihlá
|
|||
language.localization_project = Pomozte nám s překladem Forgejo do vašeho jazyka! <a href="%s">Více informací</a>.
|
||||
user_block_yourself = Nemůžete zablokovat sami sebe.
|
||||
pronouns_custom_label = Vlastní zájmena
|
||||
change_username_redirect_prompt.with_cooldown.few = Staré uživatelské jméno bude dostupné ostatním po %[1]d dnech. Do té doby budete moci své staré uživatelské jméno znovu získat.
|
||||
change_username_redirect_prompt.with_cooldown.one = Staré uživatelské jméno bude dostupné ostatním po %[1]d dni. Do té doby budete moci své staré uživatelské jméno znovu získat.
|
||||
|
||||
[repo]
|
||||
new_repo_helper=Repozitář obsahuje všechny soubory projektu, včetně historie revizí. Už jej hostujete jinde? <a href="%s">Migrovat repozitář</a>.
|
||||
|
@ -3001,6 +3005,8 @@ teams.invite.by=Pozvání od %s
|
|||
teams.invite.description=Pro připojení k týmu klikněte na tlačítko níže.
|
||||
follow_blocked_user = Tuto organizaci nemůžete sledovat, protože jste v ní zablokováni.
|
||||
open_dashboard = Otevřít nástěnku
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = Staré uživatelské jméno bude dostupné ostatním po %[1]d dni. Do té doby budete moci své staré uživatelské jméno znovu získat.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = Staré uživatelské jméno bude dostupné ostatním po %[1]d dnech. Do té doby budete moci své staré uživatelské jméno znovu získat.
|
||||
|
||||
[admin]
|
||||
dashboard=Přehled
|
||||
|
|
|
@ -629,6 +629,8 @@ password_special_one = Mindst ét specialtegn (tegnsætning, parenteser, anførs
|
|||
unsupported_login_type = Login typen understøttes ikke for at slette kontoen.
|
||||
cannot_add_org_to_team = En organisation kan ikke tilføjes som et holdmedlem.
|
||||
must_use_public_key = Nøglen du har angivet er en privat nøgle. Lad være med at uploade din private nøgle nogen steder. Brug din offentlige nøgle i stedet.
|
||||
username_claiming_cooldown = Brugernavnet kan ikke gøres krav på, fordi dets nedkølingsperiode endnu ikke er forbi. Det kan gøres krav på %[1]s.
|
||||
email_domain_is_not_allowed = Domænet for brugerens e-mailadresse <b>%s</b> er i konflikt med EMAIL_DOMAIN_ALLOWLIST eller EMAIL_DOMAIN_BLOCKLIST. Sørg for, at du har indstillet e-mailadressen korrekt.
|
||||
|
||||
[user]
|
||||
change_avatar = Skift din avatar…
|
||||
|
@ -782,7 +784,7 @@ uploaded_avatar_is_too_big = Den uploadede filstørrelse (%d KiB) overstiger den
|
|||
email_deletion_desc = E-mailadressen og relaterede oplysninger vil blive fjernet fra din konto. Git commits af denne e-mailadresse forbliver uændret. Fortsætte?
|
||||
choose_new_avatar = Vælg ny avatar
|
||||
update_avatar = Opdater avatar
|
||||
change_password_success = Din adgangskode er blevet opdateret. Log ind med din nye adgangskode fra nu af.
|
||||
change_password_success = Din adgangskode er blevet opdateret. Fra nu af skal du bruge din nye adgangskode til at logge ind.
|
||||
add_email = Tilføj e-mailadresse
|
||||
add_openid = Tilføj OpenID URI
|
||||
add_email_confirmation_sent = En bekræftelses-e-mail er blevet sendt til "%s". For at bekræfte din e-mailadresse, tjek venligst din indbakke og følg det medfølgende link inden for de næste %s.
|
||||
|
@ -972,6 +974,8 @@ delete_with_all_comments = Din konto er yngre end %s. For at undgå spøgelsesko
|
|||
delete_account_title = Slet brugerkonto
|
||||
user_block_yourself = Du kan ikke blokere dig selv.
|
||||
pronouns_custom_label = Brugerdefinerede stedord
|
||||
change_username_redirect_prompt.with_cooldown.one = Det gamle brugernavn vil være tilgængeligt for alle efter en nedkølingsperiode på %[1]d dag, du kan stadig kræve det gamle brugernavn tilbage i nedkølingsperioden.
|
||||
change_username_redirect_prompt.with_cooldown.few = Det gamle brugernavn vil være tilgængeligt for alle efter en nedkølingsperiode på %[1]d dage, du kan stadig kræve det gamle brugernavn tilbage i nedkølingsperioden.
|
||||
|
||||
[repo]
|
||||
rss.must_be_on_branch = Du skal være på en gren for at have et RSS-feed.
|
||||
|
@ -1761,6 +1765,28 @@ pulls.compare_changes = Ny pull-anmodning
|
|||
issues.summary_card_alt = Oversigtskort over et problem med titlen "%s" i depotet %s
|
||||
pulls.edit.already_changed = Kunne ikke gemme ændringer af pull-anmodningen. Det ser ud til, at indholdet allerede er blevet ændret af en anden bruger. Opdater siden, og prøv at redigere igen for at undgå at overskrive deres ændringer
|
||||
pulls.sign_in_require = <a href="%s">Log ind</a> for at oprette en ny pull-anmodning.
|
||||
pulls.allow_edits_from_maintainers = Tillad redigeringer fra vedligeholdere
|
||||
pulls.allow_edits_from_maintainers_desc = Brugere med skriveadgang til basisgrenen kan også trykke til denne gren
|
||||
pulls.allow_edits_from_maintainers_err = Opdatering mislykkedes
|
||||
pulls.compare_base = flet ind i
|
||||
pulls.compare_compare = pull fra
|
||||
pulls.switch_comparison_type = Skift sammenligningstype
|
||||
pulls.switch_head_and_base = Skift hoved og base
|
||||
pulls.filter_branch = Filter gren
|
||||
pulls.compare_changes_desc = Vælg den gren, der skal flettes ind i, og den gren, der skal trækkes fra.
|
||||
pulls.has_viewed_file = Set
|
||||
pulls.has_changed_since_last_review = Ændret siden din sidste gennemgang
|
||||
pulls.no_results = Ingen resultater fundet.
|
||||
pulls.show_all_commits = Vis alle commits
|
||||
pulls.show_changes_since_your_last_review = Vis ændringer siden din sidste gennemgang
|
||||
pulls.showing_only_single_commit = Viser kun ændringer af commit %[1]s
|
||||
pulls.showing_specified_commit_range = Viser kun ændringer mellem %[1]s..%[2]s
|
||||
pulls.select_commit_hold_shift_for_range = Vælg commit. Hold Shift + klik for at vælge et område
|
||||
pulls.review_only_possible_for_full_diff = Gennemgang er kun mulig, når du ser den fulde diff
|
||||
pulls.filter_changes_by_commit = Filtrer efter commit
|
||||
pulls.expand_files = Udvid alle filer
|
||||
pulls.collapse_files = Skjul alle filer
|
||||
pulls.viewed_files_label = %[1]d / %[2]d filer set
|
||||
|
||||
[notification]
|
||||
watching = Overvåger
|
||||
|
|
|
@ -681,6 +681,8 @@ Website = Webseite
|
|||
Location = Ort
|
||||
To = Branchname
|
||||
AccessToken = Zugangstoken
|
||||
username_claiming_cooldown = Der Benutzername kann nicht beansprucht werden, weil seine Schutzzeit noch nicht vorbei ist. Er kann am %[1]s beansprucht werden.
|
||||
email_domain_is_not_allowed = Die Domain der E-Mail-Adresse des Benutzers <b>%s</b> steht in Konflikt mit EMAIL_DOMAIN_ALLOWLIST oder EMAIL_DOMAIN_BLOCKLIST. Bitte stelle sicher, dass du die E-Mail-Adresse richtig gesetzt hast.
|
||||
|
||||
|
||||
[user]
|
||||
|
@ -806,7 +808,7 @@ old_password=Aktuelles Passwort
|
|||
new_password=Neues Passwort
|
||||
retype_new_password=Neues Passwort bestätigen
|
||||
password_incorrect=Das aktuelle Passwort ist falsch.
|
||||
change_password_success=Dein Passwort wurde aktualisiert. Bitte verwende dieses beim nächsten Einloggen.
|
||||
change_password_success=Dein Passwort wurde aktualisiert. Verwende ab jetzt dein neues Passwort zum Einloggen.
|
||||
password_change_disabled=Benutzer, die nicht von Forgejo verwaltet werden, können ihr Passwort im Web-Interface nicht ändern.
|
||||
|
||||
emails=E-Mail-Adressen
|
||||
|
@ -1058,6 +1060,8 @@ language.localization_project = Hilf uns, Forgejo in deine Sprache zu übersetze
|
|||
language.description = Diese Sprache wird in deinem Konto gespeichert und standardmäßig nach dem Anmelden benutzt.
|
||||
user_block_yourself = Du kannst dich nicht selbst blockieren.
|
||||
pronouns_custom_label = Individuelle Pronomen
|
||||
change_username_redirect_prompt.with_cooldown.one = Der alte Benutzername ist nach einer Schutzzeit von einem Tag wieder für alle Verfügbar. Du kannst den alten Benutzername während dieser Schutzzeit erneut beanspruchen.
|
||||
change_username_redirect_prompt.with_cooldown.few = Der alte Benutzername ist nach einer Schutzzeit von %[1]d Tagen wieder für alle Verfügbar. Du kannst den alten Benutzername während dieser Schutzzeit erneut beanspruchen.
|
||||
|
||||
[repo]
|
||||
owner=Besitzer
|
||||
|
@ -3004,6 +3008,8 @@ teams.invite.by=Von %s eingeladen
|
|||
teams.invite.description=Bitte klicke auf die folgende Schaltfläche, um dem Team beizutreten.
|
||||
follow_blocked_user = Du kannst dieser Organisation nicht folgen, weil diese Organisation dich blockiert hat.
|
||||
open_dashboard = Übersicht öffnen
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = Der alte Benutzername ist nach einer Schutzzeit von einem Tag wieder für alle Verfügbar. Du kannst den alten Benutzername während dieser Schutzzeit erneut beanspruchen.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = Der alte Benutzername ist nach einer Schutzzeit von %[1]d Tagen wieder für alle Verfügbar. Du kannst den alten Benutzername während dieser Schutzzeit erneut beanspruchen.
|
||||
|
||||
[admin]
|
||||
dashboard=Übersicht
|
||||
|
@ -3109,7 +3115,7 @@ dashboard.sync_branch.started=Synchronisierung der Branches gestartet
|
|||
dashboard.rebuild_issue_indexer=Issue-Indexer neu bauen
|
||||
|
||||
users.user_manage_panel=Benutzerkonten verwalten
|
||||
users.new_account=Benutzerkonto erstellen
|
||||
users.new_account=Benutzeraccount erstellen
|
||||
users.name=Benutzername
|
||||
users.full_name=Vollständiger Name
|
||||
users.activated=Aktiviert
|
||||
|
@ -3579,7 +3585,7 @@ comment_pull=`hat den Pull-Request <a href="%[1]s">%[3]s#%[2]s</a> kommentiert`
|
|||
merge_pull_request=`führte Pull-Request <a href="%[1]s">%[3]s#%[2]s</a> zusammen`
|
||||
auto_merge_pull_request=`führte Pull-Request <a href="%[1]s">%[3]s#%[2]s</a> automatisch zusammen`
|
||||
transfer_repo=hat Repository <code>%s</code> übertragen zu <a href="%s">%s</a>
|
||||
push_tag=Tag <a href="%[2]s">%[3]s</a> nach <a href="%[1]s">%[4]s</a> wurde gepusht
|
||||
push_tag=hat Tag <a href="%[2]s">%[3]s</a> auf <a href="%[1]s">%[4]s</a> gepusht
|
||||
delete_tag=hat Tag %[2]s in <a href="%[1]s">%[3]s</a> gelöscht
|
||||
delete_branch=hat Branch %[2]s in <a href="%[1]s">%[3]s</a> gelöscht
|
||||
compare_branch=Vergleichen
|
||||
|
|
|
@ -1193,6 +1193,7 @@ archive.title = This repository is archived. You can view files and clone it, bu
|
|||
archive.title_date = This repository has been archived on %s. You can view files and clone it, but cannot push or open issues or pull requests.
|
||||
archive.issue.nocomment = This repository is archived. You cannot comment on issues.
|
||||
archive.pull.nocomment = This repository is archived. You cannot comment on pull requests.
|
||||
archive.pull.noreview = This repository is archived. You cannot review pull requests.
|
||||
|
||||
form.reach_limit_of_creation_1 = The owner has already reached the limit of %d repository.
|
||||
form.reach_limit_of_creation_n = The owner has already reached the limit of %d repositories.
|
||||
|
@ -1431,6 +1432,7 @@ editor.user_no_push_to_branch = User cannot push to branch
|
|||
editor.require_signed_commit = Branch requires a signed commit
|
||||
editor.cherry_pick = Cherry-pick %s onto:
|
||||
editor.revert = Revert %s onto:
|
||||
editor.commit_email = Commit email
|
||||
|
||||
commits.desc = Browse source code change history.
|
||||
commits.commits = Commits
|
||||
|
|
|
@ -56,7 +56,7 @@ mirror=Réplica
|
|||
new_repo=Nuevo repositorio
|
||||
new_migrate=Nueva migración
|
||||
new_mirror=Nueva réplica
|
||||
new_fork=Nuevo fork de repositorio
|
||||
new_fork=Nueva bifurcación del repositorio
|
||||
new_org=Nueva organización
|
||||
new_project=Nuevo proyecto
|
||||
new_project_column=Nueva columna
|
||||
|
@ -75,7 +75,7 @@ collaborative=Colaborativo
|
|||
forks=Forks
|
||||
|
||||
activities=Actividades
|
||||
pull_requests=Pull requests
|
||||
pull_requests=Solicitudes de incorporación de cambios
|
||||
issues=Incidencias
|
||||
milestones=Hitos
|
||||
|
||||
|
@ -156,8 +156,8 @@ invalid_data = Datos inválidos: %v
|
|||
confirm_delete_artifact = ¿Estás seguro de que deseas eliminar el artefacto "%s"?
|
||||
more_items = Mas cosas
|
||||
copy_generic = Copiar al portapapeles
|
||||
filter.not_fork = No forks
|
||||
filter.is_fork = Forks
|
||||
filter.not_fork = No hay bifurcaciones
|
||||
filter.is_fork = Bifurcaciones
|
||||
test = Test
|
||||
error413 = Has agotado tu cuota.
|
||||
new_repo.title = Nuevo repositorio
|
||||
|
@ -397,8 +397,8 @@ code_search_results=Resultados de búsqueda para «%s»
|
|||
code_last_indexed_at=Indexado por última vez %s
|
||||
relevant_repositories_tooltip=Repositorios que son bifurcaciones o que no tienen ningún tema, ningún icono, y ninguna descripción están ocultos.
|
||||
relevant_repositories=Solo se muestran repositorios relevantes, <a href="%s">mostrar resultados sin filtrar</a>.
|
||||
forks_few = %d forks
|
||||
forks_one = %d fork
|
||||
forks_few = %d bifurcaciones
|
||||
forks_one = %d bifurcación
|
||||
stars_few = %d estrellas
|
||||
stars_one = %d estrella
|
||||
|
||||
|
@ -1070,10 +1070,10 @@ visibility=Visibilidad
|
|||
visibility_description=Sólo el propietario o los miembros de la organización -si tienen derechos- podrán verlo.
|
||||
visibility_helper=Hacer el repositorio privado
|
||||
visibility_helper_forced=El administrador de su sitio obliga a nuevos repositorios a ser privados.
|
||||
visibility_fork_helper=(Cambiar esto afectará a la visibilidad de todos los forks.)
|
||||
visibility_fork_helper=(Cambiar esto afectará a la visibilidad de todas las bifurcaciones.)
|
||||
clone_helper=¿Necesita ayuda para clonar? Visite <a target="_blank" rel="noopener noreferrer" href="%s">Ayuda</a>.
|
||||
fork_repo=Hacer fork del repositorio
|
||||
fork_from=Crear un fork desde
|
||||
fork_repo=Hacer una bifurcación del repositorio
|
||||
fork_from=Crear una bifurcación desde
|
||||
already_forked=Ya ha forkeado %s
|
||||
fork_to_different_account=Forkear a una cuenta diferente
|
||||
fork_visibility_helper=La visibilidad de un repositorio del cual se ha hecho fork no puede ser cambiada.
|
||||
|
@ -3852,7 +3852,7 @@ search = Buscar...
|
|||
type_tooltip = Tipo de búsqueda
|
||||
project_kind = Buscar proyectos...
|
||||
branch_kind = Buscar ramas...
|
||||
commit_kind = Buscar commits...
|
||||
commit_kind = Buscar confirmaciones...
|
||||
repo_kind = Buscar repositorios...
|
||||
user_kind = Buscar usuarios...
|
||||
org_kind = Buscar organizaciones...
|
||||
|
|
|
@ -108,7 +108,7 @@ never = Mitte kunagi
|
|||
unknown = Teadmata
|
||||
rss_feed = RSS infovoog
|
||||
confirm_delete_artifact = Kas oled kindel et soovite artefakti "%s" kustutada?
|
||||
pin =
|
||||
pin =
|
||||
artifacts = Artefaktid
|
||||
archived = Arhiveeritud
|
||||
concept_system_global = Ülemaailmne
|
||||
|
|
|
@ -1756,7 +1756,7 @@ issues.close = Sulje ongelma
|
|||
issues.no_content = Ei kuvausta.
|
||||
pulls.reject_count_1 = %d muutospyyntö
|
||||
pulls.update_branch_success = Haarapäivitys onnistui
|
||||
milestones.completeness = <strong>%d%%</strong> valmiina
|
||||
milestones.completeness = <strong>%d% %</strong> valmiina
|
||||
contributors.contribution_type.additions = Lisäykset
|
||||
contributors.contribution_type.deletions = Poistot
|
||||
settings.webhook_deletion_success = Webkoukku on poistettu.
|
||||
|
@ -2088,6 +2088,9 @@ new_from_template_description = Voit valita olemassa olevan repon mallipohjan ja
|
|||
new_advanced = Lisäasetukset
|
||||
new_advanced_expand = Laajenna napsauttamalla
|
||||
template_description = Repojen mallipohjat mahdollistavat uusien repojen luomisen halutulla hakemistorakenteella, tiedostoilla ja valinnaisilla asetuksilla.
|
||||
settings.enter_repo_name = Kirjoita omistajan ja repon nimi täsmälleen kuten esitetty:
|
||||
settings.confirmation_string = Vahvistusteksti
|
||||
settings.delete_notices_2 = - Tämä toiminto poistaa pysyvästi repon <strong>%s</strong> mukaan lukien koodin, ongelmat, kommentit, wikidatan ja avustaja-asetukset.
|
||||
|
||||
|
||||
|
||||
|
@ -2578,6 +2581,12 @@ commit_repo = työnsi haaraan <a href="%[2]s">%[3]s</a> repossa <a href="%[1]s">
|
|||
create_issue = `avasi ongelman <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
reopen_issue = `avasi uudelleen ongelman <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
create_pull_request = `loi vetopyynnön <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
reopen_pull_request = `avasi uudelleen vetopyynnön <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
close_pull_request = `sulki vetopyynnön <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
comment_issue = `kommentoi ongelmaa <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
close_issue = `sulki ongelman <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
merge_pull_request = `yhdisti vetopyynnön <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
comment_pull = `kommentoi vetopyyntöä <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
|
||||
[tool]
|
||||
now=nyt
|
||||
|
@ -2624,6 +2633,7 @@ error.not_signed_commit=Kommitti ei ole allekirjoitettu
|
|||
error.extract_sign = Allekirjoituksen purkaminen epäonnistui
|
||||
default_key = Allekirjoitettu oletusavaimella
|
||||
error.failed_retrieval_gpg_keys = Ei saatu yhtäkään kommitin tekijän tiliin liitettyä avainta
|
||||
error.generate_hash = Tiivisteen luominen kommitista epäonnistui
|
||||
|
||||
[units]
|
||||
unit = Yksikkö
|
||||
|
@ -2765,6 +2775,11 @@ alpine.registry.info = Valitse $branch ja $repository alla olevasta listasta.
|
|||
container.images.title = Levykuvat
|
||||
owner.settings.cargo.initialize = Alusta indeksi
|
||||
owner.settings.cargo.initialize.description = Erityinen Git-repoindeksi vaaditaan Cargo-rekisterin käyttämiseksi. Tämän valinnan käyttäminen luo (tarvittaessa uudelleen) repon ja määrittää sen asetukset automaattisesti.
|
||||
settings.link.error = Repositorion linkin päivittäminen epäonnistui.
|
||||
alt.repository.multiple_groups = Tämä paketti on saatavilla useissa ryhmissä.
|
||||
alt.repository.architectures = Arkkitehtuurit
|
||||
alt.install = Asenna paketti
|
||||
alt.registry.install = Asenna paketti suorittamalla komento:
|
||||
|
||||
[secrets]
|
||||
creation.failed = Salaisuuden lisääminen epäonnistui.
|
||||
|
|
|
@ -640,6 +640,8 @@ AccessToken = Token ng pag-access
|
|||
Biography = Byograpya
|
||||
Location = Lokasyon
|
||||
visit_rate_limit = Natugunan ang limitasyon sa rate ng malayuang pagbisita.
|
||||
username_claiming_cooldown = Hindi ma-claim ang username na ito, dahil hindi pa tapos ang panahon ng cooldown. Maari itong i-claim sa %[1]s.
|
||||
email_domain_is_not_allowed = Sumasalungat ang domain ng email address ng user <b>%s</b> sa EMAIL_DOMAIN_ALLOWLIST o EMAIL_DOMAIN_BLOCKLIST. Siguraduhing natakda mo ang email address nang tama.
|
||||
|
||||
[user]
|
||||
joined_on = Sumali noong %s
|
||||
|
@ -784,7 +786,7 @@ old_password = Kasalukuyang password
|
|||
new_password = Bagong password
|
||||
retype_new_password = Kumpirmahin ang bagong password
|
||||
password_incorrect = Mali ang kasalukuyang password.
|
||||
change_password_success = Na-update na ang iyong password. Mag-sign in gamit ng bagong password simula ngayon.
|
||||
change_password_success = Na-update na ang iyong password. Simula ngayon, gamitin ang iyong bagong password para mag-sign in.
|
||||
password_change_disabled = Hindi mababago ng mga di-lokal na gumagamit ang kanilang password sa pamamagitan ng Forgejo web interface.
|
||||
emails = Mga email address
|
||||
manage_emails = Ipamahala ang mga email address
|
||||
|
@ -999,6 +1001,8 @@ language.description = Mase-save ang wika sa iyong account at gagamitin bilang d
|
|||
language.localization_project = Tulungan kaming isalin ang Forgejo sa iyong wika! <a href="%s">Matuto pa</a>.
|
||||
pronouns_custom_label = Mga pasadyang pronoun
|
||||
user_block_yourself = Hindi mo maaring harangan ang sarili mo.
|
||||
change_username_redirect_prompt.with_cooldown.one = Magiging available ang lumang username sa lahat pagkatapos ng panahon ng cooldown ng %[1]d araw, maari mo pa ring ma-claim muli ang lumang username sa panahon ng panahon ng cooldown.
|
||||
change_username_redirect_prompt.with_cooldown.few = Magiging available ang lumang username sa lahat pagkatapos ng panahon ng cooldown ng %[1]d araw, maari mo pa ring ma-claim muli ang lumang username sa panahon ng panahon ng cooldown.
|
||||
|
||||
[repo]
|
||||
template_description = Ang mga template na repositoryo ay pinapayagan ang mga gumagamit na mag-generate ng mga bagong repositoryo na may magkatulad na istraktura ng direktoryo, mga file, at opsyonal na mga setting.
|
||||
|
@ -2911,7 +2915,7 @@ dashboard.delete_old_system_notices = Burahin ang lahat ng mga lumang paunawa ng
|
|||
dashboard.gc_lfs = I-garbage collect ang mga LFS meta object
|
||||
dashboard.stop_zombie_tasks = Itigil ang mga zombie action task
|
||||
users.user_manage_panel = Ipamahala ang mga user account
|
||||
users.new_account = Gumawa ng User Account
|
||||
users.new_account = Gumawa ng user account
|
||||
users.auth_login_name = Pangalan ng sign-in authentication
|
||||
users.password_helper = Iwanang walang laman ang password upang panatilihing hindi nabago.
|
||||
users.max_repo_creation = Pinakamataas na numero ng mga repositoryo
|
||||
|
@ -3394,6 +3398,8 @@ teams.owners_permission_desc = Ang mga owner ay may punong access sa <strong>lah
|
|||
teams.add_nonexistent_repo = Hindi pa umiiral ang repositoryo na sinusubukan mong idagdag. Mangyaring gawin iyan muna.
|
||||
teams.all_repositories = Lahat ng mga repositoryo
|
||||
teams.all_repositories_helper = Ang koponan ay may access sa lahat ng mga repositoryo. Ang pagpili nito ay <strong>idadagdag ang lahat ng mga umiiral</strong> na repositoryo sa koponan.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = Magiging available ang lumang username sa lahat pagkatapos ng panahon ng cooldown ng %[1]d araw, maari mo pa ring ma-claim muli ang lumang username sa panahon ng panahon ng cooldown.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = Magiging available ang lumang username sa lahat pagkatapos ng panahon ng cooldown ng %[1]d araw, maari mo pa ring ma-claim muli ang lumang username sa panahon ng panahon ng cooldown.
|
||||
|
||||
|
||||
[packages]
|
||||
|
@ -3571,7 +3577,7 @@ alt.registry = I-setup ang registry na ito mula sa command line:
|
|||
alt.registry.install = Para i-install ang package na ito, patakbuhin ang sumusunod na command:
|
||||
alt.install = I-install ang package
|
||||
alt.setup = Idagdag ang repositoryo sa listahan ng mga nakakonektang repositoryo (piliin ang kinakailangang architechture sa halip ng '_arch_'):
|
||||
alt.repository = Info ng Repositoryo
|
||||
alt.repository = Info ng repositoryo
|
||||
alt.repository.architectures = Mga architechture
|
||||
alt.repository.multiple_groups = Available ang package na ito sa iba't ibang grupo.
|
||||
|
||||
|
@ -3693,7 +3699,7 @@ approve_pull_request = `inaprubahan ang <a href="%[1]s">%[3]s#%[2]s</a>`
|
|||
review_dismissed_reason = Dahilan:
|
||||
compare_branch = Ikumpara
|
||||
reject_pull_request = `nagmungkahi ng mga pagbabago para sa <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
rename_repo = pinalitan ang pangalan ng repositoryo mula <code>%[1]s</code> sa <a href="%[2]s">%[3]#</a>
|
||||
rename_repo = pinalitan ang pangalan ng repositoryo mula <code>%[1]s</code> sa <a href="%[2]s">%[3]s</a>
|
||||
close_issue = `sinara ang isyu na <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
review_dismissed = `na-dismiss ang pagsusuri mula <b>%[4]s</b> para sa <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
close_pull_request = `sinara ang hiling sa paghila na <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
|
|
|
@ -680,6 +680,7 @@ Biography = Biographie
|
|||
Website = Site web
|
||||
Location = Emplacement
|
||||
To = Nom de la branche
|
||||
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 le courriel est renseigné.
|
||||
|
||||
[user]
|
||||
change_avatar=Changer votre avatar…
|
||||
|
|
|
@ -75,7 +75,7 @@ mirrors=Spoguļglabātavas
|
|||
collaborative=Līdzdarbošanās
|
||||
forks=Atzarojumi
|
||||
|
||||
activities=Aktivitāte
|
||||
activities=Darbības
|
||||
pull_requests=Izmaiņu pieprasījumi
|
||||
issues=Pieteikumi
|
||||
milestones=Atskaites punkti
|
||||
|
@ -678,6 +678,8 @@ Biography = Dzīves un darbības apraksts
|
|||
Website = Tīmekļvietne
|
||||
AccessToken = Piekļuves pilnvara
|
||||
To = Zara nosaukums
|
||||
username_claiming_cooldown = Šo lietotājvārdu vēl nevar izmantot, jo tā noilgums vēl nav beidzies. To varēs izmantot %[1]s.
|
||||
email_domain_is_not_allowed = Lietotāja e-pasta adreses <b>%s</b> domēna vārds ir pretrunāt ar EMAIL_DOMAIN_ALLOWLIST vai EMAIL_DOMAIN_BLOCKLIST. Jāpārliecinās, ka e-pasta adrese ir norādīta pareizi.
|
||||
|
||||
|
||||
[user]
|
||||
|
@ -695,7 +697,7 @@ following_few=%d seko
|
|||
follow=Sekot
|
||||
unfollow=Nesekot
|
||||
user_bio=Biogrāfija
|
||||
disabled_public_activity=Šis lietotājs ir atslēdzies iespēju aplūkot tā aktivitāti.
|
||||
disabled_public_activity=Šis lietotājs ir atspējojis darbību redzamību visiem.
|
||||
email_visibility.limited=E-pasta adrese ir redzama visiem autentificētajiem lietotājiem
|
||||
email_visibility.private=E-pasta adrese ir redzama tikai administratoriem
|
||||
show_on_map=Rādīt šo vietu kartē
|
||||
|
@ -803,7 +805,7 @@ old_password=Pašreizējā parole
|
|||
new_password=Jaunā parole
|
||||
retype_new_password=Apstiprināt jauno paroli
|
||||
password_incorrect=Ievadīta nepareiza pašreizējā parole.
|
||||
change_password_success=Parole tika sekmīgi nomainīta. Turpmāk jāpiesakās ar savu jauno paroli.
|
||||
change_password_success=Parole tika atjaunināta. Turpmāk jāizmanto sava jaunā parole, lai pieteiktos.
|
||||
password_change_disabled=Ārējie lietotāji nevar mainīt savu paroli Forgejo tīmekļa saskarnē.
|
||||
|
||||
emails=E-pasta adreses
|
||||
|
@ -904,7 +906,7 @@ added_on=Pievienots %s
|
|||
valid_until_date=Derīgs līdz %s
|
||||
valid_forever=Derīgs mūžīgi
|
||||
last_used=Pēdējo reizi izmantota
|
||||
no_activity=Nav nesenas aktivitātes
|
||||
no_activity=Nav nesenu darbību
|
||||
can_read_info=Lasīt
|
||||
can_write_info=Rakstīt
|
||||
key_state_desc=Šī atslēga ir izmantota pēdējo 7 dienu laikā
|
||||
|
@ -1055,6 +1057,8 @@ additional_repo_units_hint_description = Attēlot norādi "Iespējot vēl" glab
|
|||
language.description = Šī valoda tiks saglabāta kontā un pēc pieteikšanās tiks izmantota kā noklusējuma.
|
||||
user_block_yourself = Nevar liegt sevi.
|
||||
pronouns_custom_label = Pielāgoti vietniekvārdi
|
||||
change_username_redirect_prompt.with_cooldown.one = Vecais lietotājvārds būs pieejams visiem pēc noilguma, kas ir %[1]d diena. Šajā laikā ir iespējams to atkal sākt izmantot.
|
||||
change_username_redirect_prompt.with_cooldown.few = Vecais lietotājvārds būs pieejams visiem pēc noilguma, kas ir %[1]d dienas. Šajā laikā ir iespējams to atkal sākt izmantot.
|
||||
|
||||
[repo]
|
||||
new_repo_helper=Glabātava satur visas projekta datnes, tajā skaitā izmaiņu vēsturi. Jau tiek izmantota kaut kur citur? <a href="%s">Pārcelt glabātavu</a>.
|
||||
|
@ -1652,7 +1656,7 @@ issues.save=Saglabāt
|
|||
issues.label_title=Nosaukums
|
||||
issues.label_description=Apraksts
|
||||
issues.label_color=Krāsa
|
||||
issues.label_exclusive=Ekskluzīvs
|
||||
issues.label_exclusive=Sevišķa
|
||||
issues.label_archive=Arhivēt iezīmi
|
||||
issues.label_archived_filter=Rādīt arhivētās iezīmes
|
||||
issues.label_archive_tooltip=Arhivētās iezīmes pēc noklusējuma netiek iekļautas ieteikumos, kad meklē pēc iezīmes.
|
||||
|
@ -2033,7 +2037,7 @@ wiki.last_updated=Pēdējo reizi labota %s
|
|||
wiki.page_name_desc=Jāievada šīs vikivietnes lapas nosaukums. Daži īpašie nosaukumi ir: "Home", "_Sidebar" un "_Footer".
|
||||
wiki.original_git_entry_tooltip=Rādīt sākotnējo Git datni, nevis izmantot draudzīgo saiti.
|
||||
|
||||
activity=Aktivitāte
|
||||
activity=Notikumi
|
||||
activity.period.filter_label=Laika periods:
|
||||
activity.period.daily=1 diena
|
||||
activity.period.halfweekly=3 dienas
|
||||
|
@ -2999,6 +3003,8 @@ teams.invite.by=Uzaicināja %s
|
|||
teams.invite.description=Lūgums nospiest zemāk esošo pogu, lai pievienotos komandai.
|
||||
open_dashboard = Atvērt pārskata paneli
|
||||
follow_blocked_user = Tu nevari sekot šai apvienībai, jo tā ir liegusi Tevi.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = Vecais lietotājvārds būs pieejams visiem pēc noilguma, kas ir %[1]d diena. Šajā laikā ir iespējams to atkal sākt izmantot.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = Vecais lietotājvārds būs pieejams visiem pēc noilguma, kas ir %[1]d dienas. Šajā laikā ir iespējams to atkal sākt izmantot.
|
||||
|
||||
[admin]
|
||||
dashboard=Pārskata panelis
|
||||
|
@ -3761,7 +3767,7 @@ settings.link.select=Atlasīt glabātavu
|
|||
settings.link.button=Atjaunināt glabātavas saiti
|
||||
settings.link.success=Glabātavas saite tika sekmīgi atjaunināta.
|
||||
settings.link.error=Neizdevās atjaunināt glabātavas saiti.
|
||||
settings.delete=Dzēst pakotni
|
||||
settings.delete=Izdzēst pakotni
|
||||
settings.delete.description=Pakotne tiks neatgriezeniski izdzēsta.
|
||||
settings.delete.notice=Tiks izdzēsta pakotne %s (%s). Šī darbība ir neatgriezeniska. Tiešām turpināt?
|
||||
settings.delete.success=Pakotne tika izdzēsta.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[common]
|
||||
enable_javascript = Denne nettsiden behøver JavaScript.
|
||||
enable_javascript = Denne nettsiden krever JavaScript.
|
||||
toc = Innholdsfortegnelse
|
||||
licenses = Lisenser
|
||||
return_to_forgejo = Tilbake til Forgejo
|
||||
|
@ -126,6 +126,13 @@ webauthn_sign_in = Trykk på knappen på sikkerhetsnøkkelen din. Dersom nøkkel
|
|||
copy_path = Kopier sti
|
||||
webauthn_error_unable_to_process = Tjeneren kunne ikke behandle forespørselen din.
|
||||
webauthn_error_empty = Du må gi nøkkelen et navn.
|
||||
toggle_menu = Åpne/lukke meny
|
||||
twofa_scratch = To-faktor skrapekode
|
||||
webauthn_press_button = Vennligst trykk på knappen på sikkerhetsnøkkelen…
|
||||
webauthn_error_duplicated = Sikkerhetsnøkkelen er ikke tillatt for denne forespørselen. Vennligst sørg for at nøkkelen ikke allerede er registrert.
|
||||
webauthn_error_timeout = Et tidsavbrudd oppsto før nøkkelen din kunne leses. Vennligst last inn siden på nytt og prøv igjen.
|
||||
new_fork = Ny fork av repository
|
||||
collaborative = Samarbeidende
|
||||
|
||||
[search]
|
||||
search = Søk...
|
||||
|
|
|
@ -681,6 +681,8 @@ To = Branch naam
|
|||
Website = Website
|
||||
AccessToken = Toegangstoken
|
||||
Pronouns = Voornaamwoorden
|
||||
username_claiming_cooldown = De gebruikersnaam kan niet opgeëist worden, omdat de afkoelperiode nog niet voorbij is. Hij kan worden opgeëist op %[1]s.
|
||||
email_domain_is_not_allowed = Het domein van het e-mailadres van de gebruiker <b>%s</b> is in strijd met EMAIL_DOMAIN_ALLOWLIST of EMAIL_DOMAIN_BLOCKLIST. Controleer of u het e-mailadres correct hebt ingesteld.
|
||||
|
||||
|
||||
[user]
|
||||
|
@ -1058,6 +1060,8 @@ language.description = Deze taal wordt opgeslagen in uw account en wordt als sta
|
|||
language.localization_project = Help ons Forgejo in uw taal te vertalen! <a href="%s">Leer meer</a>.
|
||||
user_block_yourself = U kunt niet zichzelf blokkeren.
|
||||
pronouns_custom_label = Aangepaste voornaamwoorden
|
||||
change_username_redirect_prompt.with_cooldown.few = De oude gebruikersnaam zal voor iedereen beschikbaar zijn na een afkoelperiode van %[1]d dagen. U kunt de oude gebruikersnaam nog steeds opeisen tijdens de afkoelperiode.
|
||||
change_username_redirect_prompt.with_cooldown.one = De oude gebruikersnaam zal voor iedereen beschikbaar zijn na een afkoelperiode van %[1]d dag. U kunt de oude gebruikersnaam nog steeds opeisen tijdens de afkoelperiode.
|
||||
|
||||
[repo]
|
||||
owner=Eigenaar
|
||||
|
@ -2863,6 +2867,7 @@ summary_card_alt = Overzichtskaart van repository %s
|
|||
release.summary_card_alt = Samenvattende kaart van een release met de titel "%s" in repository %s
|
||||
issues.reaction.alt_remove = Verwijder %[1]s reactie van bericht.
|
||||
issues.reaction.alt_many = %[1]s en %[2]d meer gereageerd %[3]s.
|
||||
editor.commit_email = Commit e-mail
|
||||
|
||||
|
||||
|
||||
|
@ -3001,6 +3006,8 @@ settings.visibility.limited = Beperkt (alleen zichtbaar voor ingelogde gebruiker
|
|||
teams.add_nonexistent_repo = De repository die u probeert toe te voegen bestaat niet, maak deze eerst aan alstublieft.
|
||||
teams.all_repositories_write_permission_desc = Dit team verleent <strong>Schrijf</strong> permissies tot <strong>alle repositories</strong>: leden kunnen lezen en pushen naar repositories.
|
||||
open_dashboard = Open dashboard
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = De oude gebruikersnaam zal voor iedereen beschikbaar zijn na een afkoelperiode van %[1]d dag. U kunt de oude gebruikersnaam nog steeds opeisen tijdens de afkoelperiode.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = De oude gebruikersnaam zal voor iedereen beschikbaar zijn na een afkoelperiode van %[1]d dagen. U kunt de oude gebruikersnaam nog steeds opeisen tijdens de afkoelperiode.
|
||||
|
||||
[admin]
|
||||
dashboard=Overzicht
|
||||
|
@ -3083,7 +3090,7 @@ dashboard.gc_times=GC verwerkingen
|
|||
dashboard.delete_old_system_notices=Verwijder alle oude systeemmededelingen uit de database
|
||||
|
||||
users.user_manage_panel=Gebruikersaccounts beheren
|
||||
users.new_account=Nieuw account aanmaken
|
||||
users.new_account=Gebruikersaccount aanmaken
|
||||
users.name=Gebruikersnaam
|
||||
users.full_name=Volledige naam
|
||||
users.activated=Geactiveerd
|
||||
|
|
|
@ -680,6 +680,8 @@ required_prefix = A entrada deve começar com "%s"
|
|||
FullName = Nome completo
|
||||
Description = Descrição
|
||||
unset_password = O usuário de login não definiu a senha.
|
||||
username_claiming_cooldown = Este nome de usuário não pode ser registrado porque o período de espera ainda não acabou. Ele poderá ser registrado em %[1]s.
|
||||
email_domain_is_not_allowed = O domínio do endereço de email da conta <b>%s</b> está em conflito com EMAIL_DOMAIN_ALLOWLIST ou EMAIL_DOMAIN_BLOCKLIST. Certifique-se de que você colocou o endereço de email correto.
|
||||
|
||||
|
||||
[user]
|
||||
|
@ -805,7 +807,7 @@ old_password=Senha atual
|
|||
new_password=Nova senha
|
||||
retype_new_password=Confirme a nova senha
|
||||
password_incorrect=A senha atual está incorreta.
|
||||
change_password_success=Sua senha foi atualizada. Acesse usando sua nova senha de agora em diante.
|
||||
change_password_success=Sua senha foi atualizada. A partir de agora, use sua nova senha para acessar sua conta.
|
||||
password_change_disabled=Contas não-locais não podem alterar sua senha através da interface web do Forgejo.
|
||||
|
||||
emails=Endereços de e-mail
|
||||
|
@ -1057,6 +1059,8 @@ language.localization_project = Ajude-nos a traduzir Forgejo para o seu idioma!
|
|||
language.description = Essa língua será salva em sua conta e será usada como padrão após você iniciar a sessão.
|
||||
user_block_yourself = Você não pode se bloquear.
|
||||
pronouns_custom_label = Pronomes personalizados
|
||||
change_username_redirect_prompt.with_cooldown.one = O nome de usuário antigo ficará disponível para qualquer pessoa após um período de espera de %[1]d dia, você ainda pode recuperar o nome de usuário antigo durante este período de espera.
|
||||
change_username_redirect_prompt.with_cooldown.few = O nome de usuário antigo ficará disponível para qualquer pessoa após um período de espera de %[1]d dias, você ainda pode recuperar o nome de usuário antigo durante este período de espera.
|
||||
|
||||
[repo]
|
||||
owner=Proprietário
|
||||
|
@ -2619,7 +2623,7 @@ tag.create_tag_from=`Criar nova tag a partir de "%s"`
|
|||
|
||||
tag.create_success=Tag "%s" criada.
|
||||
|
||||
topic.manage_topics=Gerenciar Tópicos
|
||||
topic.manage_topics=Gerenciar tópicos
|
||||
topic.done=Feito
|
||||
topic.count_prompt=Você não pode selecionar mais de 25 tópicos
|
||||
|
||||
|
@ -3000,6 +3004,8 @@ open_dashboard = Abrir painel
|
|||
settings.change_orgname_prompt = Obs.: Alterar o nome de uma organização resultará na alteração do URL dela e disponibilizará o nome antigo para uso.
|
||||
follow_blocked_user = Não foi possível seguir esta organização porque ela bloqueou-o(a).
|
||||
form.name_pattern_not_allowed = O padrão "%s" não é permitido no nome de uma organização.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = O nome de usuário antigo ficará disponível para qualquer pessoa após um período de espera de %[1]d dia, você ainda pode recuperar o nome de usuário antigo durante este período de espera.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = O nome de usuário antigo ficará disponível para qualquer pessoa após um período de espera de %[1]d dias, você ainda pode recuperar o nome de usuário antigo durante este período de espera.
|
||||
|
||||
[admin]
|
||||
dashboard=Painel
|
||||
|
@ -3820,6 +3826,13 @@ owner.settings.cargo.initialize.description = É necessário um repositório Git
|
|||
owner.settings.chef.keypair.description = É necessário um par de chaves para autenticar no registro Chef. Se você já gerou um par de chaves, gere um novo par e descarte o antigo.
|
||||
container.images.title = Imagens
|
||||
search_in_external_registry = Buscar em %s
|
||||
alt.registry.install = Para instalar o pacote, execute o seguinte comando:
|
||||
alt.registry = Configurar este registro da linha de comando:
|
||||
alt.install = Instalar pacote
|
||||
alt.repository = Informação do repositório
|
||||
alt.repository.architectures = Arquiteturas
|
||||
alt.repository.multiple_groups = Este pacote está disponível em múltiplos grupos.
|
||||
alt.setup = Adicionar um repositório à lista de repositórios conectados (escolha a arquitetura necessária em vez de '_arch_'):
|
||||
|
||||
[secrets]
|
||||
secrets=Segredos
|
||||
|
|
|
@ -681,6 +681,8 @@ AccessToken = Código de acesso
|
|||
FullName = Nome completo
|
||||
Description = Descrição
|
||||
Pronouns = Pronomes
|
||||
username_claiming_cooldown = O nome de utilizador não pode ser reivindicado, porque o período de espera do mesmo ainda não terminou. Pode ser reivindicado em %[1]s.
|
||||
email_domain_is_not_allowed = O domínio do endereço de email <b>%s</b> do utilizador entra em conflito com EMAIL_DOMAIN_ALLOWLIST ou EMAIL_DOMAIN_BLOCKLIST. Certifique-se de que definiu corretamente o endereço de email.
|
||||
|
||||
[user]
|
||||
change_avatar=Mude o seu avatar…
|
||||
|
@ -805,7 +807,7 @@ old_password=Senha corrente
|
|||
new_password=Nova senha
|
||||
retype_new_password=Confirme a nova senha
|
||||
password_incorrect=A senha corrente está errada.
|
||||
change_password_success=A sua senha foi substituída. Inicie a sessão com a nova senha a partir de agora.
|
||||
change_password_success=A sua senha foi atualizada. A partir de agora, utilize a sua nova senha para iniciar sessão.
|
||||
password_change_disabled=Os utilizadores não-locais não podem alterar a sua senha através da interface web do Forgejo.
|
||||
|
||||
emails=Endereços de email
|
||||
|
@ -1057,6 +1059,8 @@ language.description = Este idioma vai ser guardado na sua conta e ser usado com
|
|||
language.localization_project = Ajude-nos a traduzir o Forgejo para o seu idioma! <a href="%s">Saiba mais</a>.
|
||||
pronouns_custom_label = Pronomes personalizados
|
||||
user_block_yourself = Não se pode bloquear a si próprio.
|
||||
change_username_redirect_prompt.with_cooldown.one = O nome de utilizador antigo estará disponível para todos após um período de espera de %[1]d dia, podendo ainda reivindicar o nome de utilizador antigo durante o período de espera.
|
||||
change_username_redirect_prompt.with_cooldown.few = O nome de utilizador antigo ficará disponível para todos após um período de espera de %[1]d dias, podendo ainda reivindicar o nome de utilizador antigo durante o período de espera.
|
||||
|
||||
[repo]
|
||||
new_repo_helper=Um repositório contém todos os ficheiros do trabalho, incluindo o histórico das revisões. Já tem um hospedado noutro sítio? <a href="%s">Migre o repositório</a>.
|
||||
|
@ -3001,6 +3005,8 @@ teams.invite.by=Convidado(a) por %s
|
|||
teams.invite.description=Clique no botão abaixo para se juntar à equipa.
|
||||
follow_blocked_user = Não pode seguir esta organização porque esta organização bloqueou-o/a.
|
||||
open_dashboard = Abrir painel de controlo
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = O nome de utilizador antigo estará disponível para todos após um período de espera de %[1]d dia, podendo ainda reivindicar o nome de utilizador antigo durante o período de espera.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = O nome de utilizador antigo estará disponível para todos após um período de espera de %[1]d dias, podendo ainda reivindicar o nome de utilizador antigo durante o período de espera.
|
||||
|
||||
[admin]
|
||||
dashboard=Painel de controlo
|
||||
|
@ -3821,6 +3827,13 @@ arch.version.backup = Cópia de segurança
|
|||
arch.version.replaces = Substitui
|
||||
container.images.title = Imagens
|
||||
search_in_external_registry = Procurar em %s
|
||||
alt.registry = Configure este registo a partir da linha de comandos:
|
||||
alt.registry.install = Para instalar o pacote, execute o seguinte comando:
|
||||
alt.install = Instalar pacote
|
||||
alt.repository = Informação do repositório
|
||||
alt.repository.architectures = Arquiteturas
|
||||
alt.repository.multiple_groups = Este pacote está disponível em vários grupos.
|
||||
alt.setup = Adicionar um repositório à lista de repositórios ligados (escolha a arquitetura necessária em vez de '_arch_'):
|
||||
|
||||
[secrets]
|
||||
secrets=Segredos
|
||||
|
|
|
@ -680,6 +680,8 @@ Biography = О себе
|
|||
Website = Веб-сайт
|
||||
Location = Местоположение
|
||||
To = Название ветви
|
||||
email_domain_is_not_allowed = Домен адреса эл. почты <b>%s</b> не разрешён к использованию. Убедитесь, что он введён правильно или попробуйте другой адрес.
|
||||
username_claiming_cooldown = Это имя пока не может быть занято, т.к. срок его защиты ещё не вышел. Его получится занять после %[1]s.
|
||||
|
||||
|
||||
[user]
|
||||
|
@ -761,7 +763,7 @@ update_language_success=Язык обновлён.
|
|||
update_profile_success=Ваш профиль успешно обновлён.
|
||||
change_username=Ваше имя пользователя было изменено.
|
||||
change_username_prompt=Обратите внимание: изменение имени пользователя также меняет URL вашей учётной записи.
|
||||
change_username_redirect_prompt=Старое имя пользователя будет перенаправлять на новое до тех пор, пока его не займут.
|
||||
change_username_redirect_prompt=Старое имя будет перенаправлять на новое до тех пор, пока оно не будет занято.
|
||||
continue=Далее
|
||||
cancel=Отмена
|
||||
language=Язык
|
||||
|
@ -1057,6 +1059,8 @@ language.description = Выбранный язык будет сохранён
|
|||
language.localization_project = Помогите с переводом Forgejo на свой язык! <a href="%s">Подробнее</a>.
|
||||
user_block_yourself = Нельзя заблокировать себя.
|
||||
pronouns_custom_label = Другие местоимения
|
||||
change_username_redirect_prompt.with_cooldown.one = Прежнее имя будет доступно для использования другим пользователям после истечения защиты в %[1]d день. Вы сможете вернуть его себе во время срока защиты.
|
||||
change_username_redirect_prompt.with_cooldown.few = Прежнее имя будет доступно для использования другим пользователям после истечения защиты в %[1]d дней. Вы сможете вернуть его себе во время срока защиты.
|
||||
|
||||
[repo]
|
||||
owner=Владелец
|
||||
|
@ -2650,7 +2654,7 @@ tag.create_tag_from=Создать новый тег из «%s»
|
|||
|
||||
tag.create_success=Тег «%s» создан.
|
||||
|
||||
topic.manage_topics=Редактировать тематические метки
|
||||
topic.manage_topics=Изменить темы
|
||||
topic.done=Сохранить
|
||||
topic.count_prompt=Нельзя выбрать более 25 тем
|
||||
topic.format_prompt=Темы должны начинаться с буквы или цифры и могут содержать дефисы («-») и точки («.»). Длина темы не должна превышать 35 символов. Все буквы должны быть строчными.
|
||||
|
@ -3003,6 +3007,8 @@ teams.invite.description=Нажмите на кнопку ниже, чтобы
|
|||
follow_blocked_user = Вы не можете подписаться на эту организацию, т.к. вы в ней заблокированы.
|
||||
teams.general_access = Настраиваемый доступ
|
||||
open_dashboard = Открыть панель
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = Прежнее название будет доступно для использования другим пользователям после истечения защиты в %[1]d дней. Вы сможете вернуть его во время срока защиты.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = Прежнее название будет доступно для использования другим пользователям после истечения защиты в %[1]d день. Вы сможете вернуть его во время срока защиты.
|
||||
|
||||
[admin]
|
||||
dashboard=Панель управления
|
||||
|
@ -3708,7 +3714,7 @@ composer.install=Чтобы установить пакет с помощью Co
|
|||
composer.dependencies=Зависимости
|
||||
composer.dependencies.development=Зависимости для разработки
|
||||
conan.details.repository=Репозиторий
|
||||
conan.registry=Настроить реестр из командной строки:
|
||||
conan.registry=Добавьте реестр командой:
|
||||
conan.install=Чтобы установить пакет с помощью Conan, выполните следующую команду:
|
||||
conda.registry=Пропишите этот реестр в качестве репозитория Conda в своём файле <code>.condarc</code>:
|
||||
conda.install=Чтобы установить пакет с помощью Conda, выполните следующую команду:
|
||||
|
@ -3723,7 +3729,7 @@ container.labels.key=Ключ
|
|||
container.labels.value=Значение
|
||||
cran.registry=Настройте этот реестр в файле <code>Rprofile.site</code>:
|
||||
cran.install=Чтобы установить пакет, выполните следующую команду:
|
||||
debian.registry=Настроить реестр из командной строки:
|
||||
debian.registry=Добавьте реестр командой:
|
||||
debian.registry.info=Выберите $distribution и $component из списка ниже.
|
||||
debian.install=Чтобы установить пакет, выполните следующую команду:
|
||||
debian.repository=О репозитории
|
||||
|
@ -3732,13 +3738,13 @@ debian.repository.components=Компоненты
|
|||
debian.repository.architectures=Архитектуры
|
||||
generic.download=Скачать пакет из командной строки:
|
||||
go.install=Установите пакет из командной строки:
|
||||
helm.registry=Настроить реестр из командной строки:
|
||||
helm.registry=Добавьте реестр командой:
|
||||
helm.install=Чтобы установить пакет, выполните следующую команду:
|
||||
maven.registry=Настройте реестр в файле <code>pom.xml</code> вашего проекта:
|
||||
maven.install=Чтобы использовать пакет, включите в блок <code>dependencies</code> в файле <code>pom.xml</code> следующее:
|
||||
maven.install2=Выполнить через командную строку:
|
||||
maven.download=Чтобы скачать зависимость, запустите в командной строке:
|
||||
nuget.registry=Настроить реестр из командной строки:
|
||||
nuget.registry=Добавьте реестр командой:
|
||||
nuget.install=Чтобы установить пакет с помощью NuGet, выполните следующую команду:
|
||||
nuget.dependency.framework=Целевой фреймворк
|
||||
npm.registry=Настройте реестр в файле <code>.npmrc</code> вашего проекта:
|
||||
|
@ -3752,7 +3758,7 @@ npm.details.tag=Тег
|
|||
pub.install=Чтобы установить пакет с помощью Dart, выполните следующую команду:
|
||||
pypi.requires=Требуется Python
|
||||
pypi.install=Чтобы установить пакет с помощью pip, выполните следующую команду:
|
||||
rpm.registry=Настроить реестр из командной строки:
|
||||
rpm.registry=Добавьте реестр командой:
|
||||
rpm.distros.redhat=на дистрибутивах семейства RedHat
|
||||
rpm.distros.suse=на дистрибутивах семейства SUSE
|
||||
rpm.install=Чтобы установить пакет, выполните следующую команду:
|
||||
|
@ -3764,7 +3770,7 @@ rubygems.dependencies.runtime=Зависимости времени выполн
|
|||
rubygems.dependencies.development=Зависимости для разработки
|
||||
rubygems.required.ruby=Требуется версия Ruby
|
||||
rubygems.required.rubygems=Требуется версия RubyGem
|
||||
swift.registry=Настроить реестр из командной строки:
|
||||
swift.registry=Добавьте реестр командой:
|
||||
swift.install=Добавьте пакет в свой файл <code>Package.swift</code>:
|
||||
swift.install2=и запустите следующую команду:
|
||||
vagrant.install=Чтобы добавить бокс Vagrant, выполните следующую команду:
|
||||
|
@ -3834,6 +3840,9 @@ container.images.title = Образы
|
|||
search_in_external_registry = Найти в %s
|
||||
alt.repository = О репозитории
|
||||
alt.repository.architectures = Архитектуры
|
||||
alt.registry = Добавьте реестр командой:
|
||||
alt.repository.multiple_groups = Этот пакет доступен в нескольких группах.
|
||||
alt.setup = Добавьте репозиторий в свой список репозиториев (выберите подходящую архитектуру вместо «_arch_»):
|
||||
|
||||
[secrets]
|
||||
secrets=Секреты
|
||||
|
|
|
@ -666,6 +666,8 @@ invalid_group_team_map_error = ` призначення недійсне: %s`
|
|||
unsupported_login_type = Цей тип входу не підтримує видалення облікового запису.
|
||||
admin_cannot_delete_self = Ви не можете видалити себе, якщо ви є адміністратором. Спочатку зніміть із себе права адміністратора.
|
||||
unset_password = Для користувача не встановлено пароль.
|
||||
username_claiming_cooldown = Це ім'я користувача не можна присвоїти, оскільки його період захисту ще не закінчився. Ім'я можна буде присвоїти %[1]s.
|
||||
email_domain_is_not_allowed = Домен адреси електронної пошти <b>%s</b> конфліктує з EMAIL_DOMAIN_ALLOWLIST або EMAIL_DOMAIN_BLOCKLIST. Перевірте, чи ви правильно вказали адресу електронної пошти.
|
||||
|
||||
|
||||
[user]
|
||||
|
@ -761,7 +763,7 @@ update_password=Оновити пароль
|
|||
old_password=Поточний пароль
|
||||
new_password=Новий пароль
|
||||
password_incorrect=Поточний пароль неправильний.
|
||||
change_password_success=Ваш пароль був оновлений. Тепер увійдіть в систему, використовуючи новий пароль.
|
||||
change_password_success=Ваш пароль оновлено. Відтепер входьте в систему, використовуючи новий пароль.
|
||||
password_change_disabled=Нелокальні акаунти не можуть змінити пароль через Forgejo.
|
||||
|
||||
emails=Адреса електронної пошти
|
||||
|
@ -1006,6 +1008,9 @@ key_signature_ssh_placeholder = Починається з «-----BEGIN SSH SIGNA
|
|||
user_block_yourself = Ви не можете заблокувати себе.
|
||||
pronouns_custom_label = Інші займенники
|
||||
repo_and_org_access = Доступ до репозиторію та організації
|
||||
change_username_redirect_prompt.with_cooldown.few = Старе ім'я користувача буде доступне всім після періоду захисту, який триватиме %[1]d днів. Протягом періоду захисту ви ще можете повернути собі старе ім'я.
|
||||
change_username_redirect_prompt.with_cooldown.one = Старе ім'я користувача буде доступне всім після періоду захисту, який триватиме %[1]d день. Протягом періоду захисту ви ще можете повернути собі старе ім'я.
|
||||
change_username_redirect_prompt = Старе ім'я користувача буде перенаправленням, поки хтось не присвоїть ім'я собі.
|
||||
|
||||
[repo]
|
||||
owner=Власник
|
||||
|
@ -2595,6 +2600,8 @@ follow_blocked_user = Ви не можете стежити за цією орг
|
|||
teams.invite.description = Щоб приєднатися до команди, натисніть кнопку нижче.
|
||||
teams.invite.title = Вас запрошено приєднатися до команди <strong>%s</strong> в організації <strong>%s</strong>.
|
||||
form.name_reserved = Назву організації «%s» зарезервовано.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = Стара назва буде доступна всім після періоду захисту, який триватиме %[1]d день. Протягом періоду захисту ви ще можете повернути стару назву.
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = Стара назва буде доступна всім після періоду захисту, який триватиме %[1]d днів. Протягом періоду захисту ви ще можете повернути стару назву.
|
||||
|
||||
[admin]
|
||||
dashboard=Панель управління
|
||||
|
|
|
@ -680,6 +680,8 @@ AccessToken = 访问令牌
|
|||
Description = 描述
|
||||
Pronouns = 代称
|
||||
Biography = 简历
|
||||
username_claiming_cooldown = 用户名不能被认领,因为其仍处于冷却期间。其可以在%[1]s后被认领。
|
||||
email_domain_is_not_allowed = 用户电子邮箱的域名<b>%s</b>与EMAIL_DOMAIN_ALLOWLIST或EMAIL_DOMAIN_BLOCKLIST冲突。请确保您正确设置了电子邮件地址。
|
||||
|
||||
[user]
|
||||
change_avatar=修改头像…
|
||||
|
@ -804,7 +806,7 @@ old_password=当前密码
|
|||
new_password=新的密码
|
||||
retype_new_password=确认新密码
|
||||
password_incorrect=当前密码不正确。
|
||||
change_password_success=您的密码已更新。从现在开始使用您的新密码登录。
|
||||
change_password_success=您的密码已更新。从现在开始请使用您的新密码登录。
|
||||
password_change_disabled=非本地帐户不能通过 Forgejo 的 web 界面更改密码。
|
||||
|
||||
emails=邮箱地址
|
||||
|
@ -1056,6 +1058,8 @@ language.description = 此语言将保存到您的账号中,并在您登录后
|
|||
language.localization_project = 帮助我们将 Forgejo 翻译成您的语言!<a href="%s">了解更多</a>。
|
||||
user_block_yourself = 您不能屏蔽自己。
|
||||
pronouns_custom_label = 自定义代词
|
||||
change_username_redirect_prompt.with_cooldown.one = 旧的用户名将在%[1]d天的冷却期后对所有人可用,您仍可以在此期间重新认领旧的用户名。
|
||||
change_username_redirect_prompt.with_cooldown.few = 旧的用户名将在%[1]d天的冷却期后对所有人可用,您仍可以在此期间重新认领旧的用户名。
|
||||
|
||||
[repo]
|
||||
new_repo_helper=代码仓库包含了所有的项目文件,包括版本历史记录。已经在其他地方托管了?<a href="%s">迁移仓库</a>。
|
||||
|
@ -2866,6 +2870,7 @@ issues.context.menu = 评论菜单
|
|||
issues.reaction.alt_add = 对评论添加 %[1]s 回应。
|
||||
release.summary_card_alt = 仓库 %[2]s 中标题为 %[1]s 的版本发布的摘要卡片
|
||||
summary_card_alt = 仓库 %s 的摘要卡片
|
||||
editor.commit_email = 提交电子邮件
|
||||
|
||||
[graphs]
|
||||
component_loading=正在加载 %s…
|
||||
|
@ -3001,6 +3006,8 @@ teams.invite.by=邀请人 %s
|
|||
teams.invite.description=请点击下面的按钮加入团队。
|
||||
follow_blocked_user = 你无法关注此组织,因为此组织已屏蔽你。
|
||||
open_dashboard = 打开仪表盘
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.one = 旧的用户名将在%[1]d天的冷却期后对所有人可用,您仍可以在此期间重新认领旧的用户名。
|
||||
settings.change_orgname_redirect_prompt.with_cooldown.few = 旧的用户名将在%[1]d天的冷却期后对所有人可用,您仍可以在此期间重新认领旧的用户名。
|
||||
|
||||
[admin]
|
||||
dashboard=管理面板
|
||||
|
|
1220
package-lock.json
generated
1220
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -61,7 +61,7 @@
|
|||
"devDependencies": {
|
||||
"@axe-core/playwright": "4.10.1",
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.4.1",
|
||||
"@playwright/test": "1.49.1",
|
||||
"@playwright/test": "1.50.1",
|
||||
"@stoplight/spectral-cli": "6.14.2",
|
||||
"@stylistic/eslint-plugin-js": "2.12.1",
|
||||
"@stylistic/stylelint-plugin": "3.1.1",
|
||||
|
@ -85,9 +85,9 @@
|
|||
"eslint-plugin-vue-scoped-css": "2.9.0",
|
||||
"eslint-plugin-wc": "2.2.0",
|
||||
"globals": "15.14.0",
|
||||
"happy-dom": "16.3.0",
|
||||
"happy-dom": "16.8.1",
|
||||
"license-checker-rseidelsohn": "4.4.2",
|
||||
"markdownlint-cli": "0.43.0",
|
||||
"markdownlint-cli": "0.44.0",
|
||||
"postcss-html": "1.8.0",
|
||||
"stylelint": "16.12.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
|
||||
|
|
6
poetry.lock
generated
6
poetry.lock
generated
|
@ -16,13 +16,13 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
|||
|
||||
[[package]]
|
||||
name = "codespell"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
description = "Fix common misspellings in text files"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "codespell-2.4.0-py3-none-any.whl", hash = "sha256:b4c5b779f747dd481587aeecb5773301183f52b94b96ed51a28126d0482eec1d"},
|
||||
{file = "codespell-2.4.0.tar.gz", hash = "sha256:587d45b14707fb8ce51339ba4cce50ae0e98ce228ef61f3c5e160e34f681be58"},
|
||||
{file = "codespell-2.4.1-py3-none-any.whl", hash = "sha256:3dadafa67df7e4a3dbf51e0d7315061b80d265f9552ebd699b3dd6834b47e425"},
|
||||
{file = "codespell-2.4.1.tar.gz", hash = "sha256:299fcdcb09d23e81e35a671bbe746d5ad7e8385972e65dbb833a2eaac33c01e5"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
"description": "Group nodejs packages",
|
||||
"matchPackageNames": [
|
||||
"code.forgejo.org/oci/node",
|
||||
"data.forgejo.org/oci/node",
|
||||
"docker.io/library/node",
|
||||
"docker.io/node",
|
||||
"node"
|
||||
|
|
|
@ -112,7 +112,7 @@ Here are some links to the most important topics. You can find the full list of
|
|||
<h2 id="user-content-quick-links">Quick Links</h2>
|
||||
<p>Here are some links to the most important topics. You can find the full list of pages at the sidebar.</p>
|
||||
<p><a href="` + FullURL + `wiki/Configuration" rel="nofollow">Configuration</a>
|
||||
<a href="` + FullURL + `wiki/raw/images/icon-bug.png" rel="nofollow"><img src="` + FullURL + `wiki/raw/images/icon-bug.png" title="icon-bug.png" alt="images/icon-bug.png"/></a></p>
|
||||
<a href="` + FullURL + `wiki/raw/images/icon-bug.png" rel="nofollow"><img src="` + FullURL + `wiki/raw/images/icon-bug.png" title="icon-bug.png" alt=""/></a></p>
|
||||
`,
|
||||
}
|
||||
|
||||
|
|
|
@ -303,11 +303,7 @@ func DeleteGPGKey(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.ParamsInt64(":id")); err != nil {
|
||||
if asymkey_model.IsErrGPGKeyAccessDenied(err) {
|
||||
ctx.Error(http.StatusForbidden, "", "You do not have access to this key")
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteGPGKey", err)
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteGPGKey", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -317,8 +313,6 @@ func DeleteGPGKey(ctx *context.APIContext) {
|
|||
// HandleAddGPGKeyError handle add GPGKey error
|
||||
func HandleAddGPGKeyError(ctx *context.APIContext, err error, token string) {
|
||||
switch {
|
||||
case asymkey_model.IsErrGPGKeyAccessDenied(err):
|
||||
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyAccessDenied", "You do not have access to this GPG key")
|
||||
case asymkey_model.IsErrGPGKeyIDAlreadyUsed(err):
|
||||
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyIDAlreadyUsed", "A key with the same id already exists")
|
||||
case asymkey_model.IsErrGPGKeyParsing(err):
|
||||
|
|
|
@ -83,6 +83,7 @@ func Users(ctx *context.Context) {
|
|||
IsTwoFactorEnabled: util.OptionalBoolParse(statusFilterMap["is_2fa_enabled"]),
|
||||
IsProhibitLogin: util.OptionalBoolParse(statusFilterMap["is_prohibit_login"]),
|
||||
IncludeReserved: true, // administrator needs to list all accounts include reserved, bot, remote ones
|
||||
Load2FAStatus: true,
|
||||
ExtraParamStrings: extraParamStrings,
|
||||
}, tplUsers)
|
||||
}
|
||||
|
|
|
@ -225,15 +225,6 @@ func SignInPost(ctx *context.Context) {
|
|||
log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
} else if user_model.IsErrUserInactive(err) {
|
||||
if setting.Service.RegisterEmailConfirm {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||
ctx.HTML(http.StatusOK, TplActivate)
|
||||
} else {
|
||||
log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("UserSignIn", err)
|
||||
}
|
||||
|
|
|
@ -99,16 +99,6 @@ func handleSignInError(ctx *context.Context, userName string, ptrForm any, tmpl
|
|||
log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
} else if user_model.IsErrUserInactive(err) {
|
||||
ctx.Data["user_exists"] = true
|
||||
if setting.Service.RegisterEmailConfirm {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||
ctx.HTML(http.StatusOK, TplActivate)
|
||||
} else {
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError(invoker, err)
|
||||
}
|
||||
|
|
|
@ -39,7 +39,11 @@ func Organizations(ctx *context.Context) {
|
|||
)
|
||||
sortOrder := ctx.FormString("sort")
|
||||
if sortOrder == "" {
|
||||
sortOrder = "newest"
|
||||
if supportedSortOrders.Contains(setting.UI.ExploreDefaultSort) {
|
||||
sortOrder = setting.UI.ExploreDefaultSort
|
||||
} else {
|
||||
sortOrder = "newest"
|
||||
}
|
||||
ctx.SetFormString("sort", sortOrder)
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,9 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
|
|||
ctx.Data["Keyword"] = opts.Keyword
|
||||
ctx.Data["Total"] = count
|
||||
ctx.Data["Users"] = users
|
||||
ctx.Data["UsersTwoFaStatus"] = user_model.UserList(users).GetTwoFaStatus(ctx)
|
||||
if opts.Load2FAStatus {
|
||||
ctx.Data["UsersTwoFaStatus"] = user_model.UserList(users).GetTwoFaStatus(ctx)
|
||||
}
|
||||
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail
|
||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
|
||||
|
@ -149,7 +151,11 @@ func Users(ctx *context.Context) {
|
|||
)
|
||||
sortOrder := ctx.FormString("sort")
|
||||
if sortOrder == "" {
|
||||
sortOrder = "newest"
|
||||
if supportedSortOrders.Contains(setting.UI.ExploreDefaultSort) {
|
||||
sortOrder = setting.UI.ExploreDefaultSort
|
||||
} else {
|
||||
sortOrder = "newest"
|
||||
}
|
||||
ctx.SetFormString("sort", sortOrder)
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue