diff --git a/.air.toml b/.air.toml index 4b3297fc1a..0610088303 100644 --- a/.air.toml +++ b/.air.toml @@ -7,4 +7,4 @@ bin = "gitea" include_ext = ["go", "tmpl"] exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata"] include_dir = ["cmd", "models", "modules", "options", "routers", "services", "templates"] -exclude_regex = ["_test.go$"] +exclude_regex = ["_test.go$", "_gen.go$"] diff --git a/.golangci.yml b/.golangci.yml index 6e80af8c0e..982ab06f0b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -171,3 +171,7 @@ issues: - path: models/user/openid.go linters: - golint + - path: models/user/badge.go + linters: + - revive + text: "exported: type name will be used as user.UserBadge by other packages, and that stutters; consider calling this Badge" diff --git a/MAINTAINERS b/MAINTAINERS index ec49f3f140..802f04cd93 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -47,3 +47,4 @@ Leon Hofmeister (@delvh) Gusted (@silentcodeg) Wim (@42wim) +xinyu (@penlinux) diff --git a/Makefile b/Makefile index 77aac782e1..44e245d225 100644 --- a/Makefile +++ b/Makefile @@ -364,7 +364,7 @@ test\#%: coverage: grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' coverage.out > coverage-bodged.out grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' integration.coverage.out > integration.coverage-bodged.out - $(GO) run build/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all || (echo "gocovmerge failed"; echo "integration.coverage.out"; cat integration.coverage.out; echo "coverage.out"; cat coverage.out; exit 1) + $(GO) run build/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all .PHONY: unit-test-coverage unit-test-coverage: diff --git a/cmd/doctor.go b/cmd/doctor.go index 1a15dd2941..a118484052 100644 --- a/cmd/doctor.go +++ b/cmd/doctor.go @@ -5,6 +5,7 @@ package cmd import ( + "errors" "fmt" golog "log" "os" @@ -14,7 +15,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/migrations" "code.gitea.io/gitea/modules/doctor" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -124,25 +124,11 @@ func runRecreateTable(ctx *cli.Context) error { }) } -func runDoctor(ctx *cli.Context) error { - stdCtx, cancel := installSignals() - defer cancel() - - // some doctor sub-commands need to use git command - if err := git.InitFull(stdCtx); err != nil { - return err - } - - // Silence the default loggers - log.DelNamedLogger("console") - log.DelNamedLogger(log.DEFAULT) - - // Now setup our own +func setDoctorLogger(ctx *cli.Context) { logFile := ctx.String("log-file") if !ctx.IsSet("log-file") { logFile = "doctor.log" } - colorize := log.CanColorStdout if ctx.IsSet("color") { colorize = ctx.Bool("color") @@ -150,11 +136,50 @@ func runDoctor(ctx *cli.Context) error { if len(logFile) == 0 { log.NewLogger(1000, "doctor", "console", fmt.Sprintf(`{"level":"NONE","stacktracelevel":"NONE","colorize":%t}`, colorize)) - } else if logFile == "-" { + return + } + + defer func() { + recovered := recover() + if recovered == nil { + return + } + + err, ok := recovered.(error) + if !ok { + panic(recovered) + } + if errors.Is(err, os.ErrPermission) { + fmt.Fprintf(os.Stderr, "ERROR: Unable to write logs to provided file due to permissions error: %s\n %v\n", logFile, err) + } else { + fmt.Fprintf(os.Stderr, "ERROR: Unable to write logs to provided file: %s\n %v\n", logFile, err) + } + fmt.Fprintf(os.Stderr, "WARN: Logging will be disabled\n Use `--log-file` to configure log file location\n") + log.NewLogger(1000, "doctor", "console", fmt.Sprintf(`{"level":"NONE","stacktracelevel":"NONE","colorize":%t}`, colorize)) + }() + + if logFile == "-" { log.NewLogger(1000, "doctor", "console", fmt.Sprintf(`{"level":"trace","stacktracelevel":"NONE","colorize":%t}`, colorize)) } else { log.NewLogger(1000, "doctor", "file", fmt.Sprintf(`{"filename":%q,"level":"trace","stacktracelevel":"NONE"}`, logFile)) } +} + +func runDoctor(ctx *cli.Context) error { + stdCtx, cancel := installSignals() + defer cancel() + + // Silence the default loggers + log.DelNamedLogger("console") + log.DelNamedLogger(log.DEFAULT) + + // Now setup our own + setDoctorLogger(ctx) + + colorize := log.CanColorStdout + if ctx.IsSet("color") { + colorize = ctx.Bool("color") + } // Finally redirect the default golog to here golog.SetFlags(0) diff --git a/cmd/main_test.go b/cmd/main_test.go new file mode 100644 index 0000000000..9cce0ef036 --- /dev/null +++ b/cmd/main_test.go @@ -0,0 +1,23 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cmd + +import ( + "testing" + + "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/modules/setting" +) + +func init() { + setting.SetCustomPathAndConf("", "", "") + setting.LoadForTest() +} + +func TestMain(m *testing.M) { + unittest.MainTest(m, &unittest.TestOptions{ + GiteaRootPath: "..", + }) +} diff --git a/cmd/migrate_storage.go b/cmd/migrate_storage.go index 93fb64a4d3..f11cf9b11f 100644 --- a/cmd/migrate_storage.go +++ b/cmd/migrate_storage.go @@ -12,9 +12,11 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/migrations" + packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" + packages_module "code.gitea.io/gitea/modules/packages" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" @@ -25,13 +27,13 @@ import ( var CmdMigrateStorage = cli.Command{ Name: "migrate-storage", Usage: "Migrate the storage", - Description: "This is a command for migrating storage.", + Description: "Copies stored files from storage configured in app.ini to parameter-configured storage", Action: runMigrateStorage, Flags: []cli.Flag{ cli.StringFlag{ Name: "type, t", Value: "", - Usage: "Kinds of files to migrate, currently only 'attachments' is supported", + Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages'", }, cli.StringFlag{ Name: "storage, s", @@ -80,34 +82,53 @@ var CmdMigrateStorage = cli.Command{ }, } -func migrateAttachments(dstStorage storage.ObjectStorage) error { - return repo_model.IterateAttachment(func(attach *repo_model.Attachment) error { +func migrateAttachments(ctx context.Context, dstStorage storage.ObjectStorage) error { + return db.IterateObjects(ctx, func(attach *repo_model.Attachment) error { _, err := storage.Copy(dstStorage, attach.RelativePath(), storage.Attachments, attach.RelativePath()) return err }) } -func migrateLFS(dstStorage storage.ObjectStorage) error { - return git_model.IterateLFS(func(mo *git_model.LFSMetaObject) error { +func migrateLFS(ctx context.Context, dstStorage storage.ObjectStorage) error { + return db.IterateObjects(ctx, func(mo *git_model.LFSMetaObject) error { _, err := storage.Copy(dstStorage, mo.RelativePath(), storage.LFS, mo.RelativePath()) return err }) } -func migrateAvatars(dstStorage storage.ObjectStorage) error { - return user_model.IterateUser(func(user *user_model.User) error { +func migrateAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error { + return db.IterateObjects(ctx, func(user *user_model.User) error { _, err := storage.Copy(dstStorage, user.CustomAvatarRelativePath(), storage.Avatars, user.CustomAvatarRelativePath()) return err }) } -func migrateRepoAvatars(dstStorage storage.ObjectStorage) error { - return repo_model.IterateRepository(func(repo *repo_model.Repository) error { +func migrateRepoAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error { + return db.IterateObjects(ctx, func(repo *repo_model.Repository) error { _, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath()) return err }) } +func migrateRepoArchivers(ctx context.Context, dstStorage storage.ObjectStorage) error { + return db.IterateObjects(ctx, func(archiver *repo_model.RepoArchiver) error { + p, err := archiver.RelativePath() + if err != nil { + return err + } + _, err = storage.Copy(dstStorage, p, storage.RepoArchives, p) + return err + }) +} + +func migratePackages(ctx context.Context, dstStorage storage.ObjectStorage) error { + return db.IterateObjects(ctx, func(pb *packages_model.PackageBlob) error { + p := packages_module.KeyToRelativePath(packages_module.BlobHash256Key(pb.HashSHA256)) + _, err := storage.Copy(dstStorage, p, storage.Packages, p) + return err + }) +} + func runMigrateStorage(ctx *cli.Context) error { stdCtx, cancel := installSignals() defer cancel() @@ -127,8 +148,6 @@ func runMigrateStorage(ctx *cli.Context) error { return err } - goCtx := context.Background() - if err := storage.Init(); err != nil { return err } @@ -145,13 +164,13 @@ func runMigrateStorage(ctx *cli.Context) error { return nil } dstStorage, err = storage.NewLocalStorage( - goCtx, + stdCtx, storage.LocalStorageConfig{ Path: p, }) case string(storage.MinioStorageType): dstStorage, err = storage.NewMinioStorage( - goCtx, + stdCtx, storage.MinioStorageConfig{ Endpoint: ctx.String("minio-endpoint"), AccessKeyID: ctx.String("minio-access-key-id"), @@ -162,35 +181,29 @@ func runMigrateStorage(ctx *cli.Context) error { UseSSL: ctx.Bool("minio-use-ssl"), }) default: - return fmt.Errorf("Unsupported storage type: %s", ctx.String("storage")) + return fmt.Errorf("unsupported storage type: %s", ctx.String("storage")) } if err != nil { return err } - tp := strings.ToLower(ctx.String("type")) - switch tp { - case "attachments": - if err := migrateAttachments(dstStorage); err != nil { - return err - } - case "lfs": - if err := migrateLFS(dstStorage); err != nil { - return err - } - case "avatars": - if err := migrateAvatars(dstStorage); err != nil { - return err - } - case "repo-avatars": - if err := migrateRepoAvatars(dstStorage); err != nil { - return err - } - default: - return fmt.Errorf("Unsupported storage: %s", ctx.String("type")) + migratedMethods := map[string]func(context.Context, storage.ObjectStorage) error{ + "attachments": migrateAttachments, + "lfs": migrateLFS, + "avatars": migrateAvatars, + "repo-avatars": migrateRepoAvatars, + "repo-archivers": migrateRepoArchivers, + "packages": migratePackages, } - log.Warn("All files have been copied to the new placement but old files are still on the original placement.") + tp := strings.ToLower(ctx.String("type")) + if m, ok := migratedMethods[tp]; ok { + if err := m(stdCtx, dstStorage); err != nil { + return err + } + log.Info("%s files have successfully been copied to the new storage.", tp) + return nil + } - return nil + return fmt.Errorf("unsupported storage: %s", ctx.String("type")) } diff --git a/cmd/migrate_storage_test.go b/cmd/migrate_storage_test.go new file mode 100644 index 0000000000..e6d205e410 --- /dev/null +++ b/cmd/migrate_storage_test.go @@ -0,0 +1,74 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cmd + +import ( + "context" + "os" + "strings" + "testing" + + "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + packages_module "code.gitea.io/gitea/modules/packages" + "code.gitea.io/gitea/modules/storage" + packages_service "code.gitea.io/gitea/services/packages" + + "github.com/stretchr/testify/assert" +) + +func TestMigratePackages(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + creator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + + content := "package main\n\nfunc main() {\nfmt.Println(\"hi\")\n}\n" + buf, err := packages_module.CreateHashedBufferFromReader(strings.NewReader(content), 1024) + assert.NoError(t, err) + defer buf.Close() + + v, f, err := packages_service.CreatePackageAndAddFile(&packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: creator, + PackageType: packages.TypeGeneric, + Name: "test", + Version: "1.0.0", + }, + Creator: creator, + SemverCompatible: true, + VersionProperties: map[string]string{}, + }, &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: "a.go", + }, + Data: buf, + IsLead: true, + }) + assert.NoError(t, err) + assert.NotNil(t, v) + assert.NotNil(t, f) + + ctx := context.Background() + + p, err := os.MkdirTemp(os.TempDir(), "migrated_packages") + assert.NoError(t, err) + + dstStorage, err := storage.NewLocalStorage( + ctx, + storage.LocalStorageConfig{ + Path: p, + }) + assert.NoError(t, err) + + err = migratePackages(ctx, dstStorage) + assert.NoError(t, err) + + entries, err := os.ReadDir(p) + assert.NoError(t, err) + assert.EqualValues(t, 2, len(entries)) + assert.EqualValues(t, "01", entries[0].Name()) + assert.EqualValues(t, "tmp", entries[1].Name()) +} diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 8ca57ea7ac..d8ef50f968 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -377,9 +377,10 @@ INTERNAL_TOKEN= ;; Name of cookie used to store authentication information. ;COOKIE_REMEMBER_NAME = gitea_incredible ;; -;; Reverse proxy authentication header name of user name and email +;; Reverse proxy authentication header name of user name, email, and full name ;REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER ;REVERSE_PROXY_AUTHENTICATION_EMAIL = X-WEBAUTH-EMAIL +;REVERSE_PROXY_AUTHENTICATION_FULL_NAME = X-WEBAUTH-FULLNAME ;; ;; Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request ;REVERSE_PROXY_LIMIT = 1 @@ -694,6 +695,7 @@ ROUTER = console ;ENABLE_REVERSE_PROXY_AUTHENTICATION = false ;ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false ;ENABLE_REVERSE_PROXY_EMAIL = false +;ENABLE_REVERSE_PROXY_FULL_NAME = false ;; ;; Enable captcha validation for registration ;ENABLE_CAPTCHA = false diff --git a/docker/rootless/usr/local/bin/docker-setup.sh b/docker/rootless/usr/local/bin/docker-setup.sh index 47645726c4..feab02a379 100755 --- a/docker/rootless/usr/local/bin/docker-setup.sh +++ b/docker/rootless/usr/local/bin/docker-setup.sh @@ -5,7 +5,7 @@ mkdir -p ${HOME} && chmod 0700 ${HOME} if [ ! -w ${HOME} ]; then echo "${HOME} is not writable"; exit 1; fi # Prepare custom folder -mkdir -p ${GITEA_CUSTOM} && chmod 0500 ${GITEA_CUSTOM} +mkdir -p ${GITEA_CUSTOM} && chmod 0700 ${GITEA_CUSTOM} # Prepare temp folder mkdir -p ${GITEA_TEMP} && chmod 0700 ${GITEA_TEMP} diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 2cd4795e68..37f887d4aa 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -492,6 +492,8 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o authentication. - `REVERSE_PROXY_AUTHENTICATION_EMAIL`: **X-WEBAUTH-EMAIL**: Header name for reverse proxy authentication provided email. +- `REVERSE_PROXY_AUTHENTICATION_FULL_NAME`: **X-WEBAUTH-FULLNAME**: Header name for reverse proxy + authentication provided full name. - `REVERSE_PROXY_LIMIT`: **1**: Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request. Number of trusted proxy count. Set to zero to not use these headers. - `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: List of IP addresses and networks separated by comma of trusted proxy servers. Use `*` to trust all. @@ -577,6 +579,8 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o for reverse authentication. - `ENABLE_REVERSE_PROXY_EMAIL`: **false**: Enable this to allow to auto-registration with a provided email rather than a generated email. +- `ENABLE_REVERSE_PROXY_FULL_NAME`: **false**: Enable this to allow to auto-registration with a + provided full name for the user. - `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration. - `REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA`: **false**: Enable this to force captcha validation even for External Accounts (i.e. GitHub, OpenID Connect, etc). You also must enable `ENABLE_CAPTCHA`. diff --git a/docs/content/doc/features/comparison.en-us.md b/docs/content/doc/features/comparison.en-us.md index 36180e3f5b..db13c87d5f 100644 --- a/docs/content/doc/features/comparison.en-us.md +++ b/docs/content/doc/features/comparison.en-us.md @@ -122,6 +122,7 @@ _Symbols used in table:_ | AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | +| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | [✘](https://github.com/gogs/gogs/issues/1221) | ✓ | ✓ | ✓ | ✓ | ✘ | | OpenId Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ | | OAuth 2.0 integration (external authorization) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ | | Act as OAuth 2.0 provider | [✓](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | diff --git a/docs/content/doc/features/comparison.zh-cn.md b/docs/content/doc/features/comparison.zh-cn.md index 15ff4a6560..f0eac22a26 100644 --- a/docs/content/doc/features/comparison.zh-cn.md +++ b/docs/content/doc/features/comparison.zh-cn.md @@ -120,6 +120,7 @@ _表格中的符号含义:_ | 集成 AD / LDAP | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | 支持多个 LDAP / AD 服务 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | LDAP 用户同步 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | +| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | [✘](https://github.com/gogs/gogs/issues/1221) | ✓ | ✓ | ✓ | ✓ | ✘ | | 支持 OpenId 连接 | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ | | 集成 OAuth 2.0(外部授权) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ | | 作为 OAuth 2.0 provider | [✓](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | diff --git a/docs/content/doc/features/comparison.zh-tw.md b/docs/content/doc/features/comparison.zh-tw.md index a2604c9052..015955f0a8 100644 --- a/docs/content/doc/features/comparison.zh-tw.md +++ b/docs/content/doc/features/comparison.zh-tw.md @@ -121,6 +121,7 @@ menu: | 整合 AD / LDAP | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | 支援多重 LDAP / AD 伺服器 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | 同步 LDAP 使用者 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | +| SAML 2.0 service provider | [✘](https://github.com/go-gitea/gitea/issues/5512) | [✘](https://github.com/gogs/gogs/issues/1221) | ✓ | ✓ | ✓ | ✓ | ✘ | | 支援 OpenId Connect | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ | | 整合 OAuth 2.0 (外部驗證) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ | | 成為 OAuth 2.0 提供者 | [✓](https://github.com/go-gitea/gitea/pull/5378) | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | diff --git a/docs/content/doc/installation/from-source.zh-cn.md b/docs/content/doc/installation/from-source.zh-cn.md index 275b0c2f74..008566e57d 100644 --- a/docs/content/doc/installation/from-source.zh-cn.md +++ b/docs/content/doc/installation/from-source.zh-cn.md @@ -15,29 +15,35 @@ menu: # 从源代码安装 -首先你需要安装Golang,关于Golang的安装,参见官方文档 [install instructions](https://golang.org/doc/install)。 +首先你需要安装Golang,关于Golang的安装,参见[官方文档](https://golang.google.cn/doc/install)。 + +其次你需要[安装Node.js](https://nodejs.org/zh-cn/download/),Node.js 和 npm 将用于构建 Gitea 前端。 + +**目录** + +{{< toc >}} ## 下载 -你需要获取Gitea的源码,最方便的方式是使用 go 命令。执行以下命令: +你需要获取Gitea的源码,最方便的方式是使用 `git` 命令。执行以下命令: ``` -go get -d -u code.gitea.io/gitea -cd $GOPATH/src/code.gitea.io/gitea +git clone https://github.com/go-gitea/gitea +cd gitea ``` -然后你可以选择编译和安装的版本,当前你有多个选择。如果你想编译 `master` 版本,你可以直接跳到 [编译](#编译) 部分,这是我们的开发分支,虽然也很稳定但不建议您在正式产品中使用。 +然后你可以选择编译和安装的版本,当前你有多个选择。如果你想编译 `main` 版本,你可以直接跳到 [编译](#编译) 部分,这是我们的开发分支,虽然也很稳定但不建议您在正式产品中使用。 如果你想编译最新稳定分支,你可以执行以下命令签出源码: -``` +```bash git branch -a git checkout v{{< version >}} ``` 最后,你也可以直接使用标签版本如 `v{{< version >}}`。你可以执行以下命令列出可用的版本并选择某个版本签出: -``` +```bash git tag -l git checkout v{{< version >}} ``` @@ -46,11 +52,11 @@ git checkout v{{< version >}} 要从源代码进行编译,以下依赖程序必须事先安装好: -- `go` {{< min-go-version >}} 或以上版本, 详见 [here](https://golang.org/dl/) -- `node` {{< min-node-version >}} 或以上版本,并且安装 `npm`, 详见 [here](https://nodejs.org/en/download/) -- `make`, 详见 这里 +- `go` {{< min-go-version >}} 或以上版本, 详见[这里](https://golang.google.cn/doc/install) +- `node` {{< min-node-version >}} 或以上版本,并且安装 `npm`, 详见[这里](https://nodejs.org/zh-cn/download/) +- `make`, 详见[这里]({{< relref "make.zh-cn.md" >}}) -各种可用的 [make 任务](https://github.com/go-gitea/gitea/blob/master/Makefile) +各种可用的 [make 任务](https://github.com/go-gitea/gitea/blob/main/Makefile) 可以用来使编译过程更方便。 按照您的编译需求,以下 tags 可以使用: @@ -76,10 +82,26 @@ TAGS="bindata sqlite sqlite_unlock_notify" make build 在执行了以上步骤之后,你将会获得 `gitea` 的二进制文件,在你复制到部署的机器之前可以先测试一下。在命令行执行完后,你可以 `Ctrl + C` 关掉程序。 -``` +```bash ./gitea web ``` +## 交叉编译 + +Go 编译器支持交叉编译到不同的目标架构。有关 Go 支持的目标架构列表,请参见 [Optional environment variables](https://go.dev/doc/install/source#environment)。 + +交叉构建适用于 Linux ARM64 的 Gitea: + +```bash +GOOS=linux GOARCH=arm64 make build +``` + +交叉构建适用于 Linux ARM64 的 Gitea,并且带上 Gitea 发行版采用的编译选项: + +```bash +CC=aarch64-unknown-linux-gnu-gcc GOOS=linux GOARCH=arm64 TAGS="bindata sqlite sqlite_unlock_notify" make build +``` + ## 需要帮助? 如果从本页中没有找到你需要的内容,请访问 [帮助页面]({{< relref "seek-help.zh-cn.md" >}}) diff --git a/docs/content/doc/installation/with-docker.zh-cn.md b/docs/content/doc/installation/with-docker.zh-cn.md index 91892fdaf9..2c63c9d4e1 100644 --- a/docs/content/doc/installation/with-docker.zh-cn.md +++ b/docs/content/doc/installation/with-docker.zh-cn.md @@ -23,7 +23,7 @@ Gitea 在其 Docker Hub 组织内提供自动更新的 Docker 镜像。可以始 ## 基本 -最简单的设置只是创建一个卷和一个网络,然后将 `gitea/gitea:latest` 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 `gitea` 的目录,并将以下内容粘贴到名为 `docker-compose.yml` 的文件中。请注意,该卷应由配置文件中指定的 UID/GID 的用户/组拥有。如果您不授予卷正确的权限,则容器可能无法启动。另请注意,标签 `:latest` 将安装当前的开发版本。对于稳定的发行版,您可以使用 `:1` 或指定某个发行版,例如 `:1.13.0`。 +最简单的设置只是创建一个卷和一个网络,然后将 `gitea/gitea:latest` 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 `gitea` 的目录,并将以下内容粘贴到名为 `docker-compose.yml` 的文件中。请注意,该卷应由配置文件中指定的 UID/GID 的用户/组拥有。如果您不授予卷正确的权限,则容器可能无法启动。另请注意,标签 `:latest` 将安装当前的开发版本。对于稳定的发行版,您可以使用 `:1` 或指定某个发行版,例如 `{{< version >}}`。 ```yaml version: "3" @@ -103,11 +103,11 @@ services: environment: - USER_UID=1000 - USER_GID=1000 -+ - DB_TYPE=mysql -+ - DB_HOST=db:3306 -+ - DB_NAME=gitea -+ - DB_USER=gitea -+ - DB_PASSWD=gitea ++ - GITEA__database__DB_TYPE=mysql ++ - GITEA__database__HOST=db:3306 ++ - GITEA__database__NAME=gitea ++ - GITEA__database__USER=gitea ++ - GITEA__database__PASSWD=gitea restart: always networks: - gitea @@ -153,11 +153,11 @@ services: environment: - USER_UID=1000 - USER_GID=1000 -+ - DB_TYPE=postgres -+ - DB_HOST=db:5432 -+ - DB_NAME=gitea -+ - DB_USER=gitea -+ - DB_PASSWD=gitea ++ - GITEA__database__DB_TYPE=postgres ++ - GITEA__database__HOST=db:5432 ++ - GITEA__database__NAME=gitea ++ - GITEA__database__USER=gitea ++ - GITEA__database__PASSWD=gitea restart: always networks: - gitea @@ -276,6 +276,42 @@ docker-compose pull docker-compose up -d ``` +## 使用环境变量管理部署 + +除了上面的环境变量之外,`app.ini` 中的任何设置都可以使用以下形式的环境变量进行设置或覆盖:`GITEA__SECTION_NAME__KEY_NAME`。 每次 docker 容器启动时都会应用这些设置。 完整信息在[这里](https://github.com/go-gitea/gitea/tree/master/contrib/environment-to-ini)。 + +```bash +... +services: + server: + environment: + - GITEA__mailer__ENABLED=true + - GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set} + - GITEA__mailer__MAILER_TYPE=smtp + - GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set} + - GITEA__mailer__IS_TLS_ENABLED=true + - GITEA__mailer__USER=${GITEA__mailer__USER:-apikey} + - GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}""" +``` + +Gitea 将为每次新安装自动生成新的 `SECRET_KEY` 并将它们写入 `app.ini`。 如果您想手动设置 `SECRET_KEY`,您可以使用以下 docker 命令来使用 Gitea 内置的[方法](https://docs.gitea.io/en-us/command-line/#generate)生成 `SECRET_KEY`。 安装后请妥善保管您的 `SECRET_KEY`,如若丢失则无法解密已加密的数据。 + +以下命令将向 `stdout` 输出一个新的 `SECRET_KEY` 和 `INTERNAL_TOKEN`,然后您可以将其放入环境变量中。 + +```bash +docker run -it --rm gitea/gitea:1 gitea generate secret SECRET_KEY +docker run -it --rm gitea/gitea:1 gitea generate secret INTERNAL_TOKEN +``` + +```yaml +... +services: + server: + environment: + - GITEA__security__SECRET_KEY=[value returned by generate secret SECRET_KEY] + - GITEA__security__INTERNAL_TOKEN=[value returned by generate secret INTERNAL_TOKEN] +``` + ## SSH 容器直通 由于 SSH 在容器内运行,因此,如果需要 SSH 支持,则需要将 SSH 从主机传递到容器。一种选择是在非标准端口上运行容器 SSH(或将主机端口移至非标准端口)。另一个可能更直接的选择是将 SSH 连接从主机转发到容器。下面将说明此设置。 diff --git a/integrations/admin_user_test.go b/integrations/admin_user_test.go index a2020652b7..2225c903df 100644 --- a/integrations/admin_user_test.go +++ b/integrations/admin_user_test.go @@ -61,7 +61,7 @@ func makeRequest(t *testing.T, formData user_model.User, headerCode int) { }) session.MakeRequest(t, req, headerCode) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: formData.ID}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: formData.ID}) assert.Equal(t, formData.Name, user.Name) assert.Equal(t, formData.LoginName, user.LoginName) assert.Equal(t, formData.Email, user.Email) diff --git a/integrations/api_admin_test.go b/integrations/api_admin_test.go index 62c7d7eaf7..e32b866844 100644 --- a/integrations/api_admin_test.go +++ b/integrations/api_admin_test.go @@ -22,7 +22,7 @@ func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) { defer prepareTestEnv(t)() // user1 is an admin user session := loginUser(t, "user1") - keyOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}).(*user_model.User) + keyOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}) token := getTokenForLoggedInUser(t, session) urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys?token=%s", keyOwner.Name, token) @@ -194,7 +194,7 @@ func TestAPIEditUser(t *testing.T) { json.Unmarshal(resp.Body.Bytes(), &errMap) assert.EqualValues(t, "email is not allowed to be empty string", errMap["message"].(string)) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"}) assert.False(t, user2.IsRestricted) bTrue := true req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{ @@ -205,6 +205,6 @@ func TestAPIEditUser(t *testing.T) { Restricted: &bTrue, }) session.MakeRequest(t, req, http.StatusOK) - user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"}).(*user_model.User) + user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"}) assert.True(t, user2.IsRestricted) } diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index 7dcc0279fc..ac1079b02d 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -24,10 +24,10 @@ func TestAPIListRepoComments(t *testing.T) { defer prepareTestEnv(t)() comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, - unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + unittest.Cond("type = ?", issues_model.CommentTypeComment)) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments", repoOwner.Name, repo.Name)) @@ -70,10 +70,10 @@ func TestAPIListIssueComments(t *testing.T) { defer prepareTestEnv(t)() comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, - unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + unittest.Cond("type = ?", issues_model.CommentTypeComment)) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/comments", @@ -91,9 +91,9 @@ func TestAPICreateComment(t *testing.T) { defer prepareTestEnv(t)() const commentBody = "Comment body" - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session) @@ -113,10 +113,10 @@ func TestAPICreateComment(t *testing.T) { func TestAPIGetComment(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}).(*issues_model.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}) assert.NoError(t, comment.LoadIssue()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session) @@ -142,10 +142,10 @@ func TestAPIEditComment(t *testing.T) { const newCommentBody = "This is the new comment body" comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, - unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + unittest.Cond("type = ?", issues_model.CommentTypeComment)) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session) @@ -167,10 +167,10 @@ func TestAPIDeleteComment(t *testing.T) { defer prepareTestEnv(t)() comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, - unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + unittest.Cond("type = ?", issues_model.CommentTypeComment)) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session) @@ -185,9 +185,9 @@ func TestAPIListIssueTimeline(t *testing.T) { defer prepareTestEnv(t)() // load comment - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) // make request session := loginUser(t, repoOwner.Name) diff --git a/integrations/api_issue_label_test.go b/integrations/api_issue_label_test.go index 9b6333b2a2..9d9fdcfbc3 100644 --- a/integrations/api_issue_label_test.go +++ b/integrations/api_issue_label_test.go @@ -22,8 +22,8 @@ import ( func TestAPIModifyLabels(t *testing.T) { assert.NoError(t, unittest.LoadFixtures()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels?token=%s", owner.Name, repo.Name, token) @@ -37,7 +37,7 @@ func TestAPIModifyLabels(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusCreated) apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) - dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, RepoID: repo.ID}).(*issues_model.Label) + dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, RepoID: repo.ID}) assert.EqualValues(t, dbLabel.Name, apiLabel.Name) assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) @@ -91,10 +91,10 @@ func TestAPIModifyLabels(t *testing.T) { func TestAPIAddIssueLabels(t *testing.T) { assert.NoError(t, unittest.LoadFixtures()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}).(*issues_model.Issue) - _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID, ID: 2}).(*issues_model.Label) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}) + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID, ID: 2}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) @@ -114,10 +114,10 @@ func TestAPIAddIssueLabels(t *testing.T) { func TestAPIReplaceIssueLabels(t *testing.T) { assert.NoError(t, unittest.LoadFixtures()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}).(*issues_model.Issue) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID}).(*issues_model.Label) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) @@ -140,8 +140,8 @@ func TestAPIReplaceIssueLabels(t *testing.T) { func TestAPIModifyOrgLabels(t *testing.T) { assert.NoError(t, unittest.LoadFixtures()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) user := "user1" session := loginUser(t, user) token := getTokenForLoggedInUser(t, session) @@ -156,7 +156,7 @@ func TestAPIModifyOrgLabels(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusCreated) apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) - dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, OrgID: owner.ID}).(*issues_model.Label) + dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, OrgID: owner.ID}) assert.EqualValues(t, dbLabel.Name, apiLabel.Name) assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) diff --git a/integrations/api_issue_milestone_test.go b/integrations/api_issue_milestone_test.go index a7f89721a5..ba97c99b9d 100644 --- a/integrations/api_issue_milestone_test.go +++ b/integrations/api_issue_milestone_test.go @@ -21,9 +21,9 @@ import ( func TestAPIIssuesMilestone(t *testing.T) { defer prepareTestEnv(t)() - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: milestone.RepoID}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: milestone.RepoID}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) assert.Equal(t, int64(1), int64(milestone.NumIssues)) assert.Equal(t, structs.StateOpen, milestone.State()) diff --git a/integrations/api_issue_reaction_test.go b/integrations/api_issue_reaction_test.go index 3834af2130..ca6b69721c 100644 --- a/integrations/api_issue_reaction_test.go +++ b/integrations/api_issue_reaction_test.go @@ -23,14 +23,14 @@ import ( func TestAPIIssuesReactions(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) _ = issue.LoadRepo(db.DefaultContext) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions?token=%s", owner.Name, issue.Repo.Name, issue.Index, token) @@ -80,17 +80,17 @@ func TestAPIIssuesReactions(t *testing.T) { func TestAPICommentReactions(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}).(*issues_model.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}) _ = comment.LoadIssue() issue := comment.Issue _ = issue.LoadRepo(db.DefaultContext) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/reactions?token=%s", owner.Name, issue.Repo.Name, comment.ID, token) diff --git a/integrations/api_issue_stopwatch_test.go b/integrations/api_issue_stopwatch_test.go index b4e5f90543..052a1ad9fc 100644 --- a/integrations/api_issue_stopwatch_test.go +++ b/integrations/api_issue_stopwatch_test.go @@ -21,8 +21,8 @@ import ( func TestAPIListStopWatches(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) @@ -30,8 +30,8 @@ func TestAPIListStopWatches(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches) - stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}).(*issues_model.Stopwatch) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}).(*issues_model.Issue) + stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}) if assert.Len(t, apiWatches, 1) { assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex) @@ -45,10 +45,10 @@ func TestAPIListStopWatches(t *testing.T) { func TestAPIStopStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) _ = issue.LoadRepo(db.DefaultContext) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -61,10 +61,10 @@ func TestAPIStopStopWatches(t *testing.T) { func TestAPICancelStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) _ = issue.LoadRepo(db.DefaultContext) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -77,10 +77,10 @@ func TestAPICancelStopWatches(t *testing.T) { func TestAPIStartStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) _ = issue.LoadRepo(db.DefaultContext) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_issue_subscription_test.go b/integrations/api_issue_subscription_test.go index 2c6cddcab9..db3d1694d6 100644 --- a/integrations/api_issue_subscription_test.go +++ b/integrations/api_issue_subscription_test.go @@ -21,19 +21,19 @@ import ( func TestAPIIssueSubscriptions(t *testing.T) { defer prepareTestEnv(t)() - issue1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) - issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) - issue3 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) - issue4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue) - issue5 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 8}).(*issues_model.Issue) + issue1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) + issue3 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) + issue4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}) + issue5 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 8}) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue1.PosterID}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue1.PosterID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) testSubscription := func(issue *issues_model.Issue, isWatching bool) { - issueRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) + issueRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/check?token=%s", issueRepo.OwnerName, issueRepo.Name, issue.Index, token) req := NewRequest(t, "GET", urlStr) @@ -54,7 +54,7 @@ func TestAPIIssueSubscriptions(t *testing.T) { testSubscription(issue4, false) testSubscription(issue5, false) - issue1Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue1.RepoID}).(*repo_model.Repository) + issue1Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue1.RepoID}) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/%s?token=%s", issue1Repo.OwnerName, issue1Repo.Name, issue1.Index, owner.Name, token) req := NewRequest(t, "DELETE", urlStr) session.MakeRequest(t, req, http.StatusCreated) @@ -64,7 +64,7 @@ func TestAPIIssueSubscriptions(t *testing.T) { session.MakeRequest(t, req, http.StatusOK) testSubscription(issue1, false) - issue5Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue5.RepoID}).(*repo_model.Repository) + issue5Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue5.RepoID}) urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/%s?token=%s", issue5Repo.OwnerName, issue5Repo.Name, issue5.Index, owner.Name, token) req = NewRequest(t, "PUT", urlStr) session.MakeRequest(t, req, http.StatusCreated) diff --git a/integrations/api_issue_test.go b/integrations/api_issue_test.go index bb4e2f0c72..afb2f75c15 100644 --- a/integrations/api_issue_test.go +++ b/integrations/api_issue_test.go @@ -25,8 +25,8 @@ import ( func TestAPIListIssues(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) @@ -76,8 +76,8 @@ func TestAPICreateIssue(t *testing.T) { defer prepareTestEnv(t)() const body, title = "apiTestBody", "apiTestTitle" - repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User) + repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) @@ -100,7 +100,7 @@ func TestAPICreateIssue(t *testing.T) { Title: title, }) - repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.Equal(t, repoBefore.NumIssues+1, repoAfter.NumIssues) assert.Equal(t, repoBefore.NumClosedIssues, repoAfter.NumClosedIssues) } @@ -108,9 +108,9 @@ func TestAPICreateIssue(t *testing.T) { func TestAPIEditIssue(t *testing.T) { defer prepareTestEnv(t)() - issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) - repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) + repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}) assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix)) assert.Equal(t, api.StateOpen, issueBefore.State()) @@ -139,8 +139,8 @@ func TestAPIEditIssue(t *testing.T) { var apiIssue api.Issue DecodeJSON(t, resp, &apiIssue) - issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) - repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) + repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}) // check deleted user assert.Equal(t, int64(500), issueAfter.PosterID) diff --git a/integrations/api_issue_tracked_time_test.go b/integrations/api_issue_tracked_time_test.go index a6846cb786..504aacf000 100644 --- a/integrations/api_issue_tracked_time_test.go +++ b/integrations/api_issue_tracked_time_test.go @@ -22,8 +22,8 @@ import ( func TestAPIGetTrackedTimes(t *testing.T) { defer prepareTestEnv(t)() - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) session := loginUser(t, user2.Name) @@ -64,10 +64,10 @@ func TestAPIGetTrackedTimes(t *testing.T) { func TestAPIDeleteTrackedTime(t *testing.T) { defer prepareTestEnv(t)() - time6 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 6}).(*issues_model.TrackedTime) - issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) + time6 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 6}) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user2.Name) token := getTokenForLoggedInUser(t, session) @@ -76,7 +76,7 @@ func TestAPIDeleteTrackedTime(t *testing.T) { req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time6.ID, token) session.MakeRequest(t, req, http.StatusForbidden) - time3 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 3}).(*issues_model.TrackedTime) + time3 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 3}) req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time3.ID, token) session.MakeRequest(t, req, http.StatusNoContent) // Delete non existing time @@ -99,10 +99,10 @@ func TestAPIDeleteTrackedTime(t *testing.T) { func TestAPIAddTrackedTimes(t *testing.T) { defer prepareTestEnv(t)() - issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) session := loginUser(t, admin.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_keys_test.go b/integrations/api_keys_test.go index 198da29b8a..76d1122086 100644 --- a/integrations/api_keys_test.go +++ b/integrations/api_keys_test.go @@ -49,8 +49,8 @@ func TestDeleteDeployKeyNoLogin(t *testing.T) { func TestCreateReadOnlyDeployKey(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session) @@ -75,8 +75,8 @@ func TestCreateReadOnlyDeployKey(t *testing.T) { func TestCreateReadWriteDeployKey(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session) @@ -100,7 +100,7 @@ func TestCreateReadWriteDeployKey(t *testing.T) { func TestCreateUserKey(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) session := loginUser(t, "user1") token := url.QueryEscape(getTokenForLoggedInUser(t, session)) diff --git a/integrations/api_notification_test.go b/integrations/api_notification_test.go index 4bf18632ca..ad6a8af0a5 100644 --- a/integrations/api_notification_test.go +++ b/integrations/api_notification_test.go @@ -21,9 +21,9 @@ import ( func TestAPINotification(t *testing.T) { defer prepareTestEnv(t)() - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}) assert.NoError(t, thread5.LoadAttributes()) session := loginUser(t, user2.Name) token := getTokenForLoggedInUser(t, session) @@ -127,7 +127,7 @@ func TestAPINotification(t *testing.T) { session.MakeRequest(t, req, http.StatusResetContent) assert.Equal(t, models.NotificationStatusUnread, thread5.Status) - thread5 = unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification) + thread5 = unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}) assert.Equal(t, models.NotificationStatusRead, thread5.Status) // -- check notifications -- @@ -140,8 +140,8 @@ func TestAPINotification(t *testing.T) { func TestAPINotificationPUT(t *testing.T) { defer prepareTestEnv(t)() - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}) assert.NoError(t, thread5.LoadAttributes()) session := loginUser(t, user2.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_oauth2_apps_test.go b/integrations/api_oauth2_apps_test.go index 2c08338b25..4eead582d1 100644 --- a/integrations/api_oauth2_apps_test.go +++ b/integrations/api_oauth2_apps_test.go @@ -27,7 +27,7 @@ func TestOAuth2Application(t *testing.T) { } func testAPICreateOAuth2Application(t *testing.T) { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) appBody := api.CreateOAuth2ApplicationOptions{ Name: "test-app-1", RedirectURIs: []string{ @@ -51,7 +51,7 @@ func testAPICreateOAuth2Application(t *testing.T) { } func testAPIListOAuth2Applications(t *testing.T) { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -61,7 +61,7 @@ func testAPIListOAuth2Applications(t *testing.T) { RedirectURIs: []string{ "http://www.google.com", }, - }).(*auth.OAuth2Application) + }) urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2?token=%s", token) req := NewRequest(t, "GET", urlStr) @@ -80,14 +80,14 @@ func testAPIListOAuth2Applications(t *testing.T) { } func testAPIDeleteOAuth2Application(t *testing.T) { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) oldApp := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ UID: user.ID, Name: "test-app-1", - }).(*auth.OAuth2Application) + }) urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d?token=%s", oldApp.ID, token) req := NewRequest(t, "DELETE", urlStr) @@ -101,7 +101,7 @@ func testAPIDeleteOAuth2Application(t *testing.T) { } func testAPIGetOAuth2Application(t *testing.T) { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -111,7 +111,7 @@ func testAPIGetOAuth2Application(t *testing.T) { RedirectURIs: []string{ "http://www.google.com", }, - }).(*auth.OAuth2Application) + }) urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d?token=%s", existApp.ID, token) req := NewRequest(t, "GET", urlStr) @@ -131,7 +131,7 @@ func testAPIGetOAuth2Application(t *testing.T) { } func testAPIUpdateOAuth2Application(t *testing.T) { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) existApp := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ UID: user.ID, @@ -139,7 +139,7 @@ func testAPIUpdateOAuth2Application(t *testing.T) { RedirectURIs: []string{ "http://www.google.com", }, - }).(*auth.OAuth2Application) + }) appBody := api.CreateOAuth2ApplicationOptions{ Name: "test-app-1", diff --git a/integrations/api_packages_composer_test.go b/integrations/api_packages_composer_test.go index 59b975408d..7c58ae62be 100644 --- a/integrations/api_packages_composer_test.go +++ b/integrations/api_packages_composer_test.go @@ -25,7 +25,7 @@ import ( func TestPackageComposer(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) vendorName := "gitea" projectName := "composer-package" diff --git a/integrations/api_packages_conan_test.go b/integrations/api_packages_conan_test.go index 65d16801fc..e14555d1d0 100644 --- a/integrations/api_packages_conan_test.go +++ b/integrations/api_packages_conan_test.go @@ -205,7 +205,7 @@ func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, cha func TestPackageConan(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) name := "ConanPackage" version1 := "1.2" diff --git a/integrations/api_packages_container_test.go b/integrations/api_packages_container_test.go index 1c4f9e7475..c62ab5dbb8 100644 --- a/integrations/api_packages_container_test.go +++ b/integrations/api_packages_container_test.go @@ -28,7 +28,7 @@ import ( func TestPackageContainer(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) has := func(l packages_model.PackagePropertyList, name string) bool { for _, pp := range l { diff --git a/integrations/api_packages_generic_test.go b/integrations/api_packages_generic_test.go index c60a387f53..f2aff8ed24 100644 --- a/integrations/api_packages_generic_test.go +++ b/integrations/api_packages_generic_test.go @@ -20,7 +20,7 @@ import ( func TestPackageGeneric(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) packageName := "te-st_pac.kage" packageVersion := "1.0.3-te st" diff --git a/integrations/api_packages_helm_test.go b/integrations/api_packages_helm_test.go index fcf5d2f762..8ea5e8a7b0 100644 --- a/integrations/api_packages_helm_test.go +++ b/integrations/api_packages_helm_test.go @@ -26,7 +26,7 @@ import ( func TestPackageHelm(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) packageName := "test-chart" packageVersion := "1.0.3" diff --git a/integrations/api_packages_maven_test.go b/integrations/api_packages_maven_test.go index e7ab3bfe4b..512039b6a5 100644 --- a/integrations/api_packages_maven_test.go +++ b/integrations/api_packages_maven_test.go @@ -21,7 +21,7 @@ import ( func TestPackageMaven(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) groupID := "com.gitea" artifactID := "test-project" diff --git a/integrations/api_packages_npm_test.go b/integrations/api_packages_npm_test.go index 23f13866bf..8b22ead6d9 100644 --- a/integrations/api_packages_npm_test.go +++ b/integrations/api_packages_npm_test.go @@ -24,7 +24,7 @@ import ( func TestPackageNpm(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) token := fmt.Sprintf("Bearer %s", getTokenForLoggedInUser(t, loginUser(t, user.Name))) diff --git a/integrations/api_packages_nuget_test.go b/integrations/api_packages_nuget_test.go index 06eb485541..5b662309ea 100644 --- a/integrations/api_packages_nuget_test.go +++ b/integrations/api_packages_nuget_test.go @@ -32,7 +32,7 @@ func addNuGetAPIKeyHeader(request *http.Request, token string) *http.Request { func TestPackageNuGet(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) token := getUserToken(t, user.Name) packageName := "test.package" diff --git a/integrations/api_packages_pub_test.go b/integrations/api_packages_pub_test.go index d64f88def7..76d5116158 100644 --- a/integrations/api_packages_pub_test.go +++ b/integrations/api_packages_pub_test.go @@ -27,7 +27,7 @@ import ( func TestPackagePub(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) token := "Bearer " + getUserToken(t, user.Name) diff --git a/integrations/api_packages_pypi_test.go b/integrations/api_packages_pypi_test.go index 5d610df39d..a4c49ef101 100644 --- a/integrations/api_packages_pypi_test.go +++ b/integrations/api_packages_pypi_test.go @@ -25,7 +25,7 @@ import ( func TestPackagePyPI(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) packageName := "test-package" packageVersion := "1.0.1" diff --git a/integrations/api_packages_rubygems_test.go b/integrations/api_packages_rubygems_test.go index 269bc953b4..2228d3d0c1 100644 --- a/integrations/api_packages_rubygems_test.go +++ b/integrations/api_packages_rubygems_test.go @@ -23,7 +23,7 @@ import ( func TestPackageRubyGems(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) packageName := "gitea" packageVersion := "1.0.5" diff --git a/integrations/api_packages_test.go b/integrations/api_packages_test.go index 1f24807060..fcdacacea0 100644 --- a/integrations/api_packages_test.go +++ b/integrations/api_packages_test.go @@ -24,7 +24,7 @@ import ( func TestPackageAPI(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_pull_commits_test.go b/integrations/api_pull_commits_test.go index 3b75fbcb4a..693011c235 100644 --- a/integrations/api_pull_commits_test.go +++ b/integrations/api_pull_commits_test.go @@ -18,9 +18,9 @@ import ( func TestAPIPullCommits(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) assert.NoError(t, pullIssue.LoadIssue()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.HeadRepoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.HeadRepoID}) session := loginUser(t, "user2") req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/commits", repo.OwnerName, repo.Name, pullIssue.Index) diff --git a/integrations/api_pull_review_test.go b/integrations/api_pull_review_test.go index b601ca1d41..024ead9050 100644 --- a/integrations/api_pull_review_test.go +++ b/integrations/api_pull_review_test.go @@ -21,9 +21,9 @@ import ( func TestAPIPullReview(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext)) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}) // test ListPullReviews session := loginUser(t, "user2") @@ -65,7 +65,7 @@ func TestAPIPullReview(t *testing.T) { assert.EqualValues(t, *reviews[5], review) // test GetPullReviewComments - comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7}).(*issues_model.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7}) req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d/comments?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, 10, token) resp = session.MakeRequest(t, req, http.StatusOK) var reviewComments []*api.PullReviewComment @@ -200,9 +200,9 @@ func TestAPIPullReview(t *testing.T) { // test get review requests // to make it simple, use same api with get review - pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}).(*issues_model.Issue) + pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}) assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext)) - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}).(*repo_model.Repository) + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}) req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token) resp = session.MakeRequest(t, req, http.StatusOK) @@ -224,9 +224,9 @@ func TestAPIPullReview(t *testing.T) { func TestAPIPullReviewRequest(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext)) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}) // Test add Review Request session := loginUser(t, "user2") @@ -269,9 +269,9 @@ func TestAPIPullReviewRequest(t *testing.T) { session.MakeRequest(t, req, http.StatusNoContent) // Test team review request - pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}).(*issues_model.Issue) + pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}) assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext)) - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}).(*repo_model.Repository) + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}) // Test add Team Review Request req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token), &api.PullReviewRequestOptions{ diff --git a/integrations/api_pull_test.go b/integrations/api_pull_test.go index 0c63ec2c00..4cb1b43cbb 100644 --- a/integrations/api_pull_test.go +++ b/integrations/api_pull_test.go @@ -23,8 +23,8 @@ import ( func TestAPIViewPulls(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, "user2") token := getTokenForLoggedInUser(t, session) @@ -40,9 +40,9 @@ func TestAPIViewPulls(t *testing.T) { // TestAPIMergePullWIP ensures that we can't merge a WIP pull request func TestAPIMergePullWIP(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{Status: issues_model.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false)).(*issues_model.PullRequest) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{Status: issues_model.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false)) pr.LoadIssue() issue_service.ChangeTitle(pr.Issue, owner, setting.Repository.PullRequest.WorkInProgressPrefixes[0]+" "+pr.Issue.Title) @@ -63,12 +63,12 @@ func TestAPIMergePullWIP(t *testing.T) { func TestAPICreatePullSuccess(t *testing.T) { defer prepareTestEnv(t)() - repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) + repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) // repo10 have code, pulls units. - repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}).(*repo_model.Repository) + repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}) // repo11 only have code unit but should still create pulls - owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}).(*user_model.User) - owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}).(*user_model.User) + owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}) + owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}) session := loginUser(t, owner11.Name) token := getTokenForLoggedInUser(t, session) @@ -84,11 +84,11 @@ func TestAPICreatePullSuccess(t *testing.T) { func TestAPICreatePullWithFieldsSuccess(t *testing.T) { defer prepareTestEnv(t)() // repo10 have code, pulls units. - repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) - owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}).(*user_model.User) + repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) + owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}) // repo11 only have code unit but should still create pulls - repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}).(*repo_model.Repository) - owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}).(*user_model.User) + repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}) + owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}) session := loginUser(t, owner11.Name) token := getTokenForLoggedInUser(t, session) @@ -121,11 +121,11 @@ func TestAPICreatePullWithFieldsSuccess(t *testing.T) { func TestAPICreatePullWithFieldsFailure(t *testing.T) { defer prepareTestEnv(t)() // repo10 have code, pulls units. - repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) - owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}).(*user_model.User) + repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) + owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}) // repo11 only have code unit but should still create pulls - repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}).(*repo_model.Repository) - owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}).(*user_model.User) + repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}) + owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}) session := loginUser(t, owner11.Name) token := getTokenForLoggedInUser(t, session) @@ -154,8 +154,8 @@ func TestAPICreatePullWithFieldsFailure(t *testing.T) { func TestAPIEditPull(t *testing.T) { defer prepareTestEnv(t)() - repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) - owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}).(*user_model.User) + repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) + owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}) session := loginUser(t, owner10.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_releases_test.go b/integrations/api_releases_test.go index 74639e9007..9561e3f488 100644 --- a/integrations/api_releases_test.go +++ b/integrations/api_releases_test.go @@ -23,8 +23,8 @@ import ( func TestAPIListReleases(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) token := getUserToken(t, user2.LowerName) link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/releases", user2.Name, repo.Name)) @@ -98,8 +98,8 @@ func createNewReleaseUsingAPI(t *testing.T, session *TestSession, token string, func TestAPICreateAndUpdateRelease(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.LowerName) token := getTokenForLoggedInUser(t, session) @@ -150,8 +150,8 @@ func TestAPICreateAndUpdateRelease(t *testing.T) { func TestAPICreateReleaseToDefaultBranch(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.LowerName) token := getTokenForLoggedInUser(t, session) @@ -161,8 +161,8 @@ func TestAPICreateReleaseToDefaultBranch(t *testing.T) { func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.LowerName) token := getTokenForLoggedInUser(t, session) @@ -179,8 +179,8 @@ func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) { func TestAPIGetReleaseByTag(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.LowerName) tag := "v1.1" @@ -212,8 +212,8 @@ func TestAPIGetReleaseByTag(t *testing.T) { func TestAPIDeleteReleaseByTagName(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.LowerName) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_archive_test.go b/integrations/api_repo_archive_test.go index 7778b7ff69..ca959a1287 100644 --- a/integrations/api_repo_archive_test.go +++ b/integrations/api_repo_archive_test.go @@ -21,8 +21,8 @@ import ( func TestAPIDownloadArchive(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user2.LowerName) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_collaborator_test.go b/integrations/api_repo_collaborator_test.go index fdca1d9150..f2e5bf648d 100644 --- a/integrations/api_repo_collaborator_test.go +++ b/integrations/api_repo_collaborator_test.go @@ -20,13 +20,13 @@ import ( func TestAPIRepoCollaboratorPermission(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - repo2Owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo2.OwnerID}).(*user_model.User) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + repo2Owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo2.OwnerID}) - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) - user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) - user10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10}).(*user_model.User) - user11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 11}).(*user_model.User) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) + user10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10}) + user11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 11}) session := loginUser(t, repo2Owner.Name) testCtx := NewAPITestContext(t, repo2Owner.Name, repo2.Name) diff --git a/integrations/api_repo_edit_test.go b/integrations/api_repo_edit_test.go index f3f0139d95..677fc0beff 100644 --- a/integrations/api_repo_edit_test.go +++ b/integrations/api_repo_edit_test.go @@ -135,13 +135,13 @@ func TestAPIRepoEdit(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { bFalse, bTrue := false, true - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo - repo15 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}).(*repo_model.Repository) // empty repo - repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo + repo15 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}) // empty repo + repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo // Get user2's token session := loginUser(t, user2.Name) @@ -166,7 +166,7 @@ func TestAPIRepoEdit(t *testing.T) { assert.Equal(t, *repoEditOption.Website, repo.Website) assert.Equal(t, *repoEditOption.Archived, repo.Archived) // check repo1 from database - repo1edited := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1edited := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1editedOption := getRepoEditOptionFromRepo(repo1edited) assert.Equal(t, *repoEditOption.Name, *repo1editedOption.Name) assert.Equal(t, *repoEditOption.Description, *repo1editedOption.Description) @@ -191,7 +191,7 @@ func TestAPIRepoEdit(t *testing.T) { DecodeJSON(t, resp, &repo) assert.NotNil(t, repo) // check repo1 was written to database - repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1editedOption = getRepoEditOptionFromRepo(repo1edited) assert.Equal(t, *repo1editedOption.HasIssues, true) assert.Nil(t, repo1editedOption.ExternalTracker) @@ -213,7 +213,7 @@ func TestAPIRepoEdit(t *testing.T) { DecodeJSON(t, resp, &repo) assert.NotNil(t, repo) // check repo1 was written to database - repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1editedOption = getRepoEditOptionFromRepo(repo1edited) assert.Equal(t, *repo1editedOption.HasIssues, true) assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker) @@ -244,7 +244,7 @@ func TestAPIRepoEdit(t *testing.T) { DecodeJSON(t, resp, &repo) assert.NotNil(t, repo) // check repo1 was written to database - repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1editedOption = getRepoEditOptionFromRepo(repo1edited) assert.Equal(t, *repo1editedOption.Description, *repoEditOption.Description) assert.Equal(t, *repo1editedOption.HasIssues, true) @@ -289,7 +289,7 @@ func TestAPIRepoEdit(t *testing.T) { _ = session.MakeRequest(t, req, http.StatusOK) // Test making a repo public that is private - repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) + repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) assert.True(t, repo16.IsPrivate) repoEditOption = &api.EditRepoOption{ Private: &bFalse, @@ -297,7 +297,7 @@ func TestAPIRepoEdit(t *testing.T) { url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token2) req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) _ = session.MakeRequest(t, req, http.StatusOK) - repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) + repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) assert.False(t, repo16.IsPrivate) // Make it private again repoEditOption.Private = &bTrue @@ -311,7 +311,7 @@ func TestAPIRepoEdit(t *testing.T) { Archived: &bTrue, }) _ = session.MakeRequest(t, req, http.StatusOK) - repo15 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}).(*repo_model.Repository) + repo15 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}) assert.True(t, repo15.IsArchived) req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{ Archived: &bFalse, diff --git a/integrations/api_repo_file_create_test.go b/integrations/api_repo_file_create_test.go index fd460ce564..f9ed479ca2 100644 --- a/integrations/api_repo_file_create_test.go +++ b/integrations/api_repo_file_create_test.go @@ -112,8 +112,8 @@ func getExpectedFileResponseForCreate(repoFullName, commitID, treePath, latestCo func BenchmarkAPICreateFileSmall(b *testing.B) { onGiteaRunTB(b, func(t testing.TB, u *url.URL) { b := t.(*testing.B) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo for n := 0; n < b.N; n++ { treePath := fmt.Sprintf("update/file%d.txt", n) @@ -127,8 +127,8 @@ func BenchmarkAPICreateFileMedium(b *testing.B) { onGiteaRunTB(b, func(t testing.TB, u *url.URL) { b := t.(*testing.B) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo b.ResetTimer() for n := 0; n < b.N; n++ { @@ -141,12 +141,12 @@ func BenchmarkAPICreateFileMedium(b *testing.B) { func TestAPICreateFile(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo - repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo + repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo fileID := 0 // Get user2's token @@ -288,7 +288,7 @@ func TestAPICreateFile(t *testing.T) { url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, "empty-repo", treePath, token2) req = NewRequestWithJSON(t, "POST", url, &createFileOptions) resp = session.MakeRequest(t, req, http.StatusCreated) - emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}).(*repo_model.Repository) // public repo + emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}) // public repo gitRepo, _ := git.OpenRepository(stdCtx.Background(), emptyRepo.RepoPath()) commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName) latestCommit, _ := gitRepo.GetCommitByPath(treePath) diff --git a/integrations/api_repo_file_delete_test.go b/integrations/api_repo_file_delete_test.go index 42df869d69..340ffe362e 100644 --- a/integrations/api_repo_file_delete_test.go +++ b/integrations/api_repo_file_delete_test.go @@ -39,12 +39,12 @@ func getDeleteFileOptions() *api.DeleteFileOptions { func TestAPIDeleteFile(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo - repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo + repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo fileID := 0 // Get user2's token diff --git a/integrations/api_repo_file_update_test.go b/integrations/api_repo_file_update_test.go index e39d83e49e..3044f03844 100644 --- a/integrations/api_repo_file_update_test.go +++ b/integrations/api_repo_file_update_test.go @@ -107,12 +107,12 @@ func getExpectedFileResponseForUpdate(commitID, treePath, lastCommitSHA string) func TestAPIUpdateFile(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo - repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo + repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo fileID := 0 // Get user2's token diff --git a/integrations/api_repo_get_contents_list_test.go b/integrations/api_repo_get_contents_list_test.go index 97b152bf1b..18231a2caf 100644 --- a/integrations/api_repo_get_contents_list_test.go +++ b/integrations/api_repo_get_contents_list_test.go @@ -55,13 +55,13 @@ func TestAPIGetContentsList(t *testing.T) { func testAPIGetContentsList(t *testing.T, u *url.URL) { /*** SETUP ***/ - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo - repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo - treePath := "" // root dir + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo + repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo + treePath := "" // root dir // Get user2's token session := loginUser(t, user2.Name) diff --git a/integrations/api_repo_get_contents_test.go b/integrations/api_repo_get_contents_test.go index 56f5336b7b..1fb8b9bf0d 100644 --- a/integrations/api_repo_get_contents_test.go +++ b/integrations/api_repo_get_contents_test.go @@ -56,12 +56,12 @@ func TestAPIGetContents(t *testing.T) { func testAPIGetContents(t *testing.T, u *url.URL) { /*** SETUP ***/ - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo - repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo + repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo treePath := "README.md" // Get user2's token diff --git a/integrations/api_repo_git_blobs_test.go b/integrations/api_repo_git_blobs_test.go index 0a3cf632cc..7b990450d8 100644 --- a/integrations/api_repo_git_blobs_test.go +++ b/integrations/api_repo_git_blobs_test.go @@ -18,12 +18,12 @@ import ( func TestAPIReposGitBlobs(t *testing.T) { defer prepareTestEnv(t)() - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3 - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo - repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3 + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo + repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo repo1ReadmeSHA := "65f1bf27bc3bf70f64657658635e66094edbcb4d" repo3ReadmeSHA := "d56a3073c1dbb7b15963110a049d50cdb5db99fc" repo16ReadmeSHA := "f90451c72ef61a7645293d17b47be7a8e983da57" diff --git a/integrations/api_repo_git_commits_test.go b/integrations/api_repo_git_commits_test.go index f5a64490b9..7eba5bd223 100644 --- a/integrations/api_repo_git_commits_test.go +++ b/integrations/api_repo_git_commits_test.go @@ -25,7 +25,7 @@ func compareCommitFiles(t *testing.T, expect []string, files []*api.CommitAffect func TestAPIReposGitCommits(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -53,7 +53,7 @@ func TestAPIReposGitCommits(t *testing.T) { func TestAPIReposGitCommitList(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -76,7 +76,7 @@ func TestAPIReposGitCommitList(t *testing.T) { func TestAPIReposGitCommitListPage2Empty(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -93,7 +93,7 @@ func TestAPIReposGitCommitListPage2Empty(t *testing.T) { func TestAPIReposGitCommitListDifferentBranch(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -112,7 +112,7 @@ func TestAPIReposGitCommitListDifferentBranch(t *testing.T) { func TestDownloadCommitDiffOrPatch(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -134,7 +134,7 @@ func TestDownloadCommitDiffOrPatch(t *testing.T) { func TestGetFileHistory(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_git_hook_test.go b/integrations/api_repo_git_hook_test.go index a31b27c456..b90d66c175 100644 --- a/integrations/api_repo_git_hook_test.go +++ b/integrations/api_repo_git_hook_test.go @@ -25,8 +25,8 @@ echo Hello, World! func TestAPIListGitHooks(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) // user1 is an admin user session := loginUser(t, "user1") @@ -51,8 +51,8 @@ func TestAPIListGitHooks(t *testing.T) { func TestAPIListGitHooksNoHooks(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) // user1 is an admin user session := loginUser(t, "user1") @@ -72,8 +72,8 @@ func TestAPIListGitHooksNoHooks(t *testing.T) { func TestAPIListGitHooksNoAccess(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) @@ -85,8 +85,8 @@ func TestAPIListGitHooksNoAccess(t *testing.T) { func TestAPIGetGitHook(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) // user1 is an admin user session := loginUser(t, "user1") @@ -103,8 +103,8 @@ func TestAPIGetGitHook(t *testing.T) { func TestAPIGetGitHookNoAccess(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) @@ -116,8 +116,8 @@ func TestAPIGetGitHookNoAccess(t *testing.T) { func TestAPIEditGitHook(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) // user1 is an admin user session := loginUser(t, "user1") @@ -146,8 +146,8 @@ func TestAPIEditGitHook(t *testing.T) { func TestAPIEditGitHookNoAccess(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) @@ -162,8 +162,8 @@ func TestAPIEditGitHookNoAccess(t *testing.T) { func TestAPIDeleteGitHook(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) // user1 is an admin user session := loginUser(t, "user1") @@ -185,8 +185,8 @@ func TestAPIDeleteGitHook(t *testing.T) { func TestAPIDeleteGitHookNoAccess(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_git_notes_test.go b/integrations/api_repo_git_notes_test.go index 08b885bd2f..733e0575dc 100644 --- a/integrations/api_repo_git_notes_test.go +++ b/integrations/api_repo_git_notes_test.go @@ -18,7 +18,7 @@ import ( func TestAPIReposGitNotes(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_git_ref_test.go b/integrations/api_repo_git_ref_test.go index f0fc3c81fa..7ff16eb1c5 100644 --- a/integrations/api_repo_git_ref_test.go +++ b/integrations/api_repo_git_ref_test.go @@ -14,7 +14,7 @@ import ( func TestAPIReposGitRefs(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_git_tags_test.go b/integrations/api_repo_git_tags_test.go index 9e870d2489..45551a4d7b 100644 --- a/integrations/api_repo_git_tags_test.go +++ b/integrations/api_repo_git_tags_test.go @@ -21,8 +21,8 @@ import ( func TestAPIGitTags(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -66,8 +66,8 @@ func TestAPIGitTags(t *testing.T) { func TestAPIDeleteTagByName(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.LowerName) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_git_trees_test.go b/integrations/api_repo_git_trees_test.go index 03e065645b..d80bcadb69 100644 --- a/integrations/api_repo_git_trees_test.go +++ b/integrations/api_repo_git_trees_test.go @@ -15,12 +15,12 @@ import ( func TestAPIReposGitTrees(t *testing.T) { defer prepareTestEnv(t)() - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3 - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo - repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3 + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo + repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo repo1TreeSHA := "65f1bf27bc3bf70f64657658635e66094edbcb4d" repo3TreeSHA := "2a47ca4b614a9f5a43abbd5ad851a54a616ffee6" repo16TreeSHA := "69554a64c1e6030f051e5c3f94bfbd773cd6a324" diff --git a/integrations/api_repo_lfs_locks_test.go b/integrations/api_repo_lfs_locks_test.go index ca7bd35001..3fd8f48f97 100644 --- a/integrations/api_repo_lfs_locks_test.go +++ b/integrations/api_repo_lfs_locks_test.go @@ -23,8 +23,8 @@ import ( func TestAPILFSLocksNotStarted(t *testing.T) { defer prepareTestEnv(t)() setting.LFS.StartServer = false - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name) MakeRequest(t, req, http.StatusNotFound) @@ -39,8 +39,8 @@ func TestAPILFSLocksNotStarted(t *testing.T) { func TestAPILFSLocksNotLogin(t *testing.T) { defer prepareTestEnv(t)() setting.LFS.StartServer = true - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name) req.Header.Set("Accept", lfs.MediaType) @@ -53,11 +53,11 @@ func TestAPILFSLocksNotLogin(t *testing.T) { func TestAPILFSLocksLogged(t *testing.T) { defer prepareTestEnv(t)() setting.LFS.StartServer = true - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // in org 3 - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // in org 3 + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // in org 3 + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // in org 3 - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // own by org 3 + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // own by org 3 tests := []struct { user *user_model.User diff --git a/integrations/api_repo_lfs_migrate_test.go b/integrations/api_repo_lfs_migrate_test.go index 6d41a48529..1f6893f32a 100644 --- a/integrations/api_repo_lfs_migrate_test.go +++ b/integrations/api_repo_lfs_migrate_test.go @@ -28,7 +28,7 @@ func TestAPIRepoLFSMigrateLocal(t *testing.T) { setting.Migrations.AllowLocalNetworks = true assert.NoError(t, migrations.Init()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_lfs_test.go b/integrations/api_repo_lfs_test.go index 6a2fccebb5..8bbc019953 100644 --- a/integrations/api_repo_lfs_test.go +++ b/integrations/api_repo_lfs_test.go @@ -28,8 +28,8 @@ func TestAPILFSNotStarted(t *testing.T) { setting.LFS.StartServer = false - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) req := NewRequestf(t, "POST", "/%s/%s.git/info/lfs/objects/batch", user.Name, repo.Name) MakeRequest(t, req, http.StatusNotFound) @@ -48,8 +48,8 @@ func TestAPILFSMediaType(t *testing.T) { setting.LFS.StartServer = true - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) req := NewRequestf(t, "POST", "/%s/%s.git/info/lfs/objects/batch", user.Name, repo.Name) MakeRequest(t, req, http.StatusUnsupportedMediaType) diff --git a/integrations/api_repo_raw_test.go b/integrations/api_repo_raw_test.go index 258b409bef..8e8cc750dd 100644 --- a/integrations/api_repo_raw_test.go +++ b/integrations/api_repo_raw_test.go @@ -16,7 +16,7 @@ import ( func TestAPIReposRaw(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_tags_test.go b/integrations/api_repo_tags_test.go index 14a24cf5eb..4b87093cdf 100644 --- a/integrations/api_repo_tags_test.go +++ b/integrations/api_repo_tags_test.go @@ -19,7 +19,7 @@ import ( func TestAPIRepoTags(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/api_repo_teams_test.go b/integrations/api_repo_teams_test.go index efd6ddb457..2ec6958286 100644 --- a/integrations/api_repo_teams_test.go +++ b/integrations/api_repo_teams_test.go @@ -23,9 +23,9 @@ func TestAPIRepoTeams(t *testing.T) { defer prepareTestEnv(t)() // publicOrgRepo = user3/repo21 - publicOrgRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}).(*repo_model.Repository) + publicOrgRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}) // user4 - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -65,7 +65,7 @@ func TestAPIRepoTeams(t *testing.T) { session.MakeRequest(t, req, http.StatusForbidden) // AddTeam with user2 - user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session = loginUser(t, user.Name) token = getTokenForLoggedInUser(t, session) url = fmt.Sprintf("/api/v1/repos/%s/teams/%s?token=%s", publicOrgRepo.FullName(), "team1", token) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 57fe65f4bf..5631df323a 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -26,7 +26,7 @@ import ( func TestAPIUserReposNotLogin(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) req := NewRequestf(t, "GET", "/api/v1/users/%s/repos", user.Name) resp := MakeRequest(t, req, http.StatusOK) @@ -57,11 +57,11 @@ func TestAPISearchRepo(t *testing.T) { assert.False(t, repo.Private) } - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 16}).(*user_model.User) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 18}).(*user_model.User) - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}).(*user_model.User) - orgUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 17}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 16}) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 18}) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}) + orgUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 17}) oldAPIDefaultNum := setting.API.DefaultPagingNum defer func() { @@ -241,7 +241,7 @@ var repoCache = make(map[int64]*repo_model.Repository) func getRepo(t *testing.T, repoID int64) *repo_model.Repository { if _, ok := repoCache[repoID]; !ok { - repoCache[repoID] = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repoCache[repoID] = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) } return repoCache[repoID] } @@ -278,11 +278,11 @@ func TestAPIViewRepo(t *testing.T) { func TestAPIOrgRepos(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) // User3 is an Org. Check their repos. - sourceOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + sourceOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) expectedResults := map[*user_model.User]struct { count int @@ -324,7 +324,7 @@ func TestAPIOrgRepos(t *testing.T) { func TestAPIGetRepoByIDUnauthorized(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) req := NewRequestf(t, "GET", "/api/v1/repositories/2?token="+token) @@ -348,7 +348,7 @@ func TestAPIRepoMigrate(t *testing.T) { defer prepareTestEnv(t)() for _, testCase := range testCases { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+token, &api.MigrateRepoOptions{ @@ -448,7 +448,7 @@ func TestAPIOrgRepoCreate(t *testing.T) { defer prepareTestEnv(t)() for _, testCase := range testCases { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos?token="+token, testCase.orgName), &api.CreateRepoOption{ @@ -515,7 +515,7 @@ func TestAPIRepoTransfer(t *testing.T) { defer prepareTestEnv(t)() // create repo to move - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) repoName := "moveME" @@ -532,8 +532,8 @@ func TestAPIRepoTransfer(t *testing.T) { // start testing for _, testCase := range testCases { - user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}).(*repo_model.Repository) + user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}) session = loginUser(t, user.Name) token = getTokenForLoggedInUser(t, session) req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer?token=%s", repo.OwnerName, repo.Name, token), &api.TransferRepoOption{ @@ -544,13 +544,13 @@ func TestAPIRepoTransfer(t *testing.T) { } // cleanup - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}) _ = models.DeleteRepository(user, repo.OwnerID, repo.ID) } func transfer(t *testing.T) *repo_model.Repository { // create repo to move - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) repoName := "moveME" @@ -566,7 +566,7 @@ func transfer(t *testing.T) *repo_model.Repository { resp := session.MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, apiRepo) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}) req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer?token=%s", repo.OwnerName, repo.Name, token), &api.TransferRepoOption{ NewOwner: "user4", }) @@ -630,11 +630,11 @@ func TestAPIRejectTransfer(t *testing.T) { func TestAPIGenerateRepo(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) - templateRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 44}).(*repo_model.Repository) + templateRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 44}) // user repo := new(api.Repository) @@ -666,10 +666,10 @@ func TestAPIGenerateRepo(t *testing.T) { func TestAPIRepoGetReviewers(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/reviewers?token=%s", user.Name, repo.Name, token) resp := session.MakeRequest(t, req, http.StatusOK) @@ -680,10 +680,10 @@ func TestAPIRepoGetReviewers(t *testing.T) { func TestAPIRepoGetAssignees(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/assignees?token=%s", user.Name, repo.Name, token) resp := session.MakeRequest(t, req, http.StatusOK) diff --git a/integrations/api_repo_topic_test.go b/integrations/api_repo_topic_test.go index 04295724a7..e99c682e21 100644 --- a/integrations/api_repo_topic_test.go +++ b/integrations/api_repo_topic_test.go @@ -52,11 +52,11 @@ func TestAPITopicSearch(t *testing.T) { func TestAPIRepoTopic(t *testing.T) { defer prepareTestEnv(t)() - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of repo2 - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of repo3 - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // write access to repo 3 - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of repo2 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of repo3 + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // write access to repo 3 + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // Get user2's token token2 := getUserToken(t, user2.Name) diff --git a/integrations/api_team_test.go b/integrations/api_team_test.go index d571342c3d..82824d610b 100644 --- a/integrations/api_team_test.go +++ b/integrations/api_team_test.go @@ -24,9 +24,9 @@ import ( func TestAPITeam(t *testing.T) { defer prepareTestEnv(t)() - teamUser := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{}).(*organization.TeamUser) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamUser.TeamID}).(*organization.Team) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser.UID}).(*user_model.User) + teamUser := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{}) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamUser.TeamID}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser.UID}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) @@ -39,8 +39,8 @@ func TestAPITeam(t *testing.T) { assert.Equal(t, team.Name, apiTeam.Name) // non team member user will not access the teams details - teamUser2 := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{ID: 3}).(*organization.TeamUser) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser2.UID}).(*user_model.User) + teamUser2 := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{ID: 3}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser2.UID}) session = loginUser(t, user2.Name) token = getTokenForLoggedInUser(t, session) @@ -51,11 +51,11 @@ func TestAPITeam(t *testing.T) { _ = session.MakeRequest(t, req, http.StatusUnauthorized) // Get an admin user able to create, update and delete teams. - user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) session = loginUser(t, user.Name) token = getTokenForLoggedInUser(t, session) - org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 6}).(*user_model.User) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 6}) // Create team. teamToCreate := &api.CreateTeamOption{ @@ -108,7 +108,7 @@ func TestAPITeam(t *testing.T) { teamToEdit.Permission, unit.AllUnitKeyNames(), nil) // Read team. - teamRead := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + teamRead := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, teamRead.GetUnits()) req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamID) resp = session.MakeRequest(t, req, http.StatusOK) @@ -174,7 +174,7 @@ func TestAPITeam(t *testing.T) { "read", nil, teamToEdit.UnitsMap) // Read team. - teamRead = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + teamRead = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamID) resp = session.MakeRequest(t, req, http.StatusOK) apiTeam = api.Team{} @@ -207,7 +207,7 @@ func checkTeamResponse(t *testing.T, testName string, apiTeam *api.Team, name, d } func checkTeamBean(t *testing.T, id int64, name, description string, includesAllRepositories bool, permission string, units []string, unitsMap map[string]string) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: id}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: id}) assert.NoError(t, team.GetUnits(), "GetUnits") apiTeam, err := convert.ToTeam(team) assert.NoError(t, err) @@ -222,8 +222,8 @@ type TeamSearchResults struct { func TestAPITeamSearch(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) var results TeamSearchResults @@ -236,7 +236,7 @@ func TestAPITeamSearch(t *testing.T) { assert.Equal(t, "test_team", results.Data[0].Name) // no access if not organization member - user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) token5 := getUserToken(t, user5.Name) req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "team", token5) @@ -246,9 +246,9 @@ func TestAPITeamSearch(t *testing.T) { func TestAPIGetTeamRepo(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User) - teamRepo := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 24}).(*repo.Repository) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) + teamRepo := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 24}) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}) var results api.Repository @@ -259,7 +259,7 @@ func TestAPIGetTeamRepo(t *testing.T) { assert.Equal(t, "big_test_private_4", teamRepo.Name) // no access if not organization member - user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) token5 := getUserToken(t, user5.Name) req = NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/?token=%s", team.ID, teamRepo.FullName(), token5) diff --git a/integrations/api_team_user_test.go b/integrations/api_team_user_test.go index 7263408bee..9b3364b5b1 100644 --- a/integrations/api_team_user_test.go +++ b/integrations/api_team_user_test.go @@ -31,7 +31,7 @@ func TestAPITeamUser(t *testing.T) { var user2 *api.User DecodeJSON(t, resp, &user2) user2.Created = user2.Created.In(time.Local) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}) expectedUser := convert.ToUser(user, user) diff --git a/integrations/api_token_test.go b/integrations/api_token_test.go index aca4768503..17e8fb5e25 100644 --- a/integrations/api_token_test.go +++ b/integrations/api_token_test.go @@ -17,7 +17,7 @@ import ( // TestAPICreateAndDeleteToken tests that token that was just created can be deleted func TestAPICreateAndDeleteToken(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) req := NewRequestWithJSON(t, "POST", "/api/v1/users/user1/tokens", map[string]string{ "name": "test-key-1", @@ -57,7 +57,7 @@ func TestAPICreateAndDeleteToken(t *testing.T) { // TestAPIDeleteMissingToken ensures that error is thrown when token not found func TestAPIDeleteMissingToken(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) req := NewRequestf(t, "DELETE", "/api/v1/users/user1/tokens/%d", unittest.NonexistentID) req = AddBasicAuthHeader(req, user.Name) diff --git a/integrations/api_user_orgs_test.go b/integrations/api_user_orgs_test.go index 219bd273c9..9f3487cb7f 100644 --- a/integrations/api_user_orgs_test.go +++ b/integrations/api_user_orgs_test.go @@ -25,7 +25,7 @@ func TestUserOrgs(t *testing.T) { orgs := getUserOrgs(t, adminUsername, normalUsername) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user3"}).(*user_model.User) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user3"}) assert.Equal(t, []*api.Organization{ { @@ -81,7 +81,7 @@ func TestMyOrgs(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var orgs []*api.Organization DecodeJSON(t, resp, &orgs) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user3"}).(*user_model.User) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user3"}) assert.Equal(t, []*api.Organization{ { diff --git a/integrations/api_user_search_test.go b/integrations/api_user_search_test.go index 41f14cf944..dbaca24981 100644 --- a/integrations/api_user_search_test.go +++ b/integrations/api_user_search_test.go @@ -52,7 +52,7 @@ func TestAPIUserSearchNotLoggedIn(t *testing.T) { var modelUser *user_model.User for _, user := range results.Data { assert.Contains(t, user.UserName, query) - modelUser = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID}).(*user_model.User) + modelUser = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID}) if modelUser.KeepEmailPrivate { assert.EqualValues(t, fmt.Sprintf("%s@%s", modelUser.LowerName, setting.Service.NoReplyAddress), user.Email) } else { diff --git a/integrations/auth_ldap_test.go b/integrations/auth_ldap_test.go index 492a4fdadf..892ff38134 100644 --- a/integrations/auth_ldap_test.go +++ b/integrations/auth_ldap_test.go @@ -326,7 +326,7 @@ func TestLDAPGroupTeamSyncAddMember(t *testing.T) { for _, gitLDAPUser := range gitLDAPUsers { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ Name: gitLDAPUser.UserName, - }).(*user_model.User) + }) usersOrgs, err := organization.FindOrgs(organization.FindOrgOptions{ UserID: user.ID, IncludePrivate: true, @@ -370,7 +370,7 @@ func TestLDAPGroupTeamSyncRemoveMember(t *testing.T) { loginUserWithPassword(t, gitLDAPUsers[0].UserName, gitLDAPUsers[0].Password) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ Name: gitLDAPUsers[0].UserName, - }).(*user_model.User) + }) err = organization.AddOrgUser(org.ID, user.ID) assert.NoError(t, err) err = models.AddTeamMember(team, user.ID) diff --git a/integrations/benchmarks_test.go b/integrations/benchmarks_test.go index ffae471307..a63c363683 100644 --- a/integrations/benchmarks_test.go +++ b/integrations/benchmarks_test.go @@ -33,7 +33,7 @@ func BenchmarkRepoBranchCommit(b *testing.B) { for _, repoID := range samples { b.StopTimer() - repo := unittest.AssertExistsAndLoadBean(b, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(b, &repo_model.Repository{ID: repoID}) b.StartTimer() b.Run(repo.Name, func(b *testing.B) { session := loginUser(b, "user2") diff --git a/integrations/change_default_branch_test.go b/integrations/change_default_branch_test.go index 096afa28f4..6fe7305d45 100644 --- a/integrations/change_default_branch_test.go +++ b/integrations/change_default_branch_test.go @@ -16,8 +16,8 @@ import ( func TestChangeDefaultBranch(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) branchesURL := fmt.Sprintf("/%s/%s/settings/branches", owner.Name, repo.Name) diff --git a/integrations/csrf_test.go b/integrations/csrf_test.go index 5bfc97bbd1..2c61f95426 100644 --- a/integrations/csrf_test.go +++ b/integrations/csrf_test.go @@ -20,7 +20,7 @@ func TestCsrfProtection(t *testing.T) { defer prepareTestEnv(t)() // test web form csrf via form - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ "_csrf": "fake_csrf", diff --git a/integrations/dump_restore_test.go b/integrations/dump_restore_test.go index ef869c4dda..7395bd5bd9 100644 --- a/integrations/dump_restore_test.go +++ b/integrations/dump_restore_test.go @@ -48,8 +48,8 @@ func TestDumpRestore(t *testing.T) { assert.NoError(t, err) defer util.RemoveAll(basePath) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session) @@ -90,7 +90,7 @@ func TestDumpRestore(t *testing.T) { }, false) assert.NoError(t, err) - newrepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: newreponame}).(*repo_model.Repository) + newrepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: newreponame}) // // Phase 3: dump restored from the Gitea instance to the filesystem diff --git a/integrations/empty_repo_test.go b/integrations/empty_repo_test.go index abc28b74c8..daf153a183 100644 --- a/integrations/empty_repo_test.go +++ b/integrations/empty_repo_test.go @@ -21,8 +21,8 @@ func TestEmptyRepo(t *testing.T) { "commit/1ae57b34ccf7e18373", "graph", } - emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}, unittest.Cond("is_empty = ?", true)).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: emptyRepo.OwnerID}).(*user_model.User) + emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}, unittest.Cond("is_empty = ?", true)) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: emptyRepo.OwnerID}) for _, subpath := range subpaths { req := NewRequestf(t, "GET", "/%s/%s/%s", owner.Name, emptyRepo.Name, subpath) MakeRequest(t, req, http.StatusNotFound) diff --git a/integrations/eventsource_test.go b/integrations/eventsource_test.go index ff32988634..e2465e9e56 100644 --- a/integrations/eventsource_test.go +++ b/integrations/eventsource_test.go @@ -53,9 +53,9 @@ func TestEventSourceManagerRun(t *testing.T) { } } - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}) assert.NoError(t, thread5.LoadAttributes()) session := loginUser(t, user2.Name) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/git_test.go b/integrations/git_test.go index f9e1eafb65..9018374514 100644 --- a/integrations/git_test.go +++ b/integrations/git_test.go @@ -754,7 +754,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB pr1 = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo.ID, Flow: issues_model.PullRequestFlowAGit, - }).(*issues_model.PullRequest) + }) if !assert.NotEmpty(t, pr1) { return } @@ -776,7 +776,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB HeadRepoID: repo.ID, Index: pr1.Index + 1, Flow: issues_model.PullRequestFlowAGit, - }).(*issues_model.PullRequest) + }) if !assert.NotEmpty(t, pr2) { return } diff --git a/integrations/gpg_git_test.go b/integrations/gpg_git_test.go index 461f3c503d..6edce606f2 100644 --- a/integrations/gpg_git_test.go +++ b/integrations/gpg_git_test.go @@ -61,7 +61,7 @@ func TestGPGGit(t *testing.T) { setting.Repository.Signing.SigningKey = rootKeyID setting.Repository.Signing.SigningName = "gitea" setting.Repository.Signing.SigningEmail = "gitea@fake.local" - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: username}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: username}) setting.Repository.Signing.InitialCommit = []string{"never"} setting.Repository.Signing.CRUDActions = []string{"never"} diff --git a/integrations/issue_test.go b/integrations/issue_test.go index e1d3b1b21e..4bbb4744ea 100644 --- a/integrations/issue_test.go +++ b/integrations/issue_test.go @@ -41,7 +41,7 @@ func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *is indexStr := href[strings.LastIndexByte(href, '/')+1:] index, err := strconv.Atoi(indexStr) assert.NoError(t, err, "Invalid issue href: %s", href) - return unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repoID, Index: int64(index)}).(*issues_model.Issue) + return unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repoID, Index: int64(index)}) } func assertMatch(t testing.TB, issue *issues_model.Issue, keyword string) { @@ -66,8 +66,8 @@ func TestNoLoginViewIssues(t *testing.T) { func TestViewIssuesSortByType(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) session := loginUser(t, user.Name) req := NewRequest(t, "GET", repo.Link()+"/issues?type=created_by") @@ -94,11 +94,11 @@ func TestViewIssuesSortByType(t *testing.T) { func TestViewIssuesKeyword(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ RepoID: repo.ID, Index: 1, - }).(*issues_model.Issue) + }) issues.UpdateIssueIndexer(issue) time.Sleep(time.Second * 1) const keyword = "first" @@ -510,9 +510,9 @@ func TestSearchIssuesWithLabels(t *testing.T) { func TestGetIssueInfo(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) assert.NoError(t, issue.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issue.DeadlineUnix)) assert.Equal(t, api.StateOpen, issue.State()) @@ -531,9 +531,9 @@ func TestGetIssueInfo(t *testing.T) { func TestUpdateIssueDeadline(t *testing.T) { defer prepareTestEnv(t)() - issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) - repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) + repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}) assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix)) assert.Equal(t, api.StateOpen, issueBefore.State()) diff --git a/integrations/migrate_test.go b/integrations/migrate_test.go index f67e4ed229..d16f74ab6d 100644 --- a/integrations/migrate_test.go +++ b/integrations/migrate_test.go @@ -24,7 +24,7 @@ import ( func TestMigrateLocalPath(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}).(*user_model.User) + adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) old := setting.ImportLocalPaths setting.ImportLocalPaths = true @@ -62,7 +62,7 @@ func TestMigrateGiteaForm(t *testing.T) { ownerName := "user2" repoName := "repo1" - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: ownerName}).(*user_model.User) + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: ownerName}) session := loginUser(t, ownerName) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/mirror_pull_test.go b/integrations/mirror_pull_test.go index 8f74d5fe16..3a45fa7cc2 100644 --- a/integrations/mirror_pull_test.go +++ b/integrations/mirror_pull_test.go @@ -24,8 +24,8 @@ import ( func TestMirrorPull(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repoPath := repo_model.RepoPath(user.Name, repo.Name) opts := migration.MigrateOptions{ diff --git a/integrations/mirror_push_test.go b/integrations/mirror_push_test.go index 3a22b00754..5a226c5a92 100644 --- a/integrations/mirror_push_test.go +++ b/integrations/mirror_push_test.go @@ -36,8 +36,8 @@ func testMirrorPush(t *testing.T, u *url.URL) { setting.Migrations.AllowLocalNetworks = true assert.NoError(t, migrations.Init()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) mirrorRepo, err := repository.CreateRepository(user, user, models.CreateRepoOptions{ Name: "test-push-mirror", diff --git a/integrations/org_count_test.go b/integrations/org_count_test.go index eca51eb0f6..2bffa90034 100644 --- a/integrations/org_count_test.go +++ b/integrations/org_count_test.go @@ -115,7 +115,7 @@ func doCheckOrgCounts(username string, orgCounts map[string]int, strict bool, ca return func(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ Name: username, - }).(*user_model.User) + }) orgs, err := organization.FindOrgs(organization.FindOrgOptions{ UserID: user.ID, diff --git a/integrations/org_test.go b/integrations/org_test.go index d787e6f791..e4677f58de 100644 --- a/integrations/org_test.go +++ b/integrations/org_test.go @@ -197,8 +197,8 @@ func TestOrgRestrictedUser(t *testing.T) { func TestTeamSearch(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) var results TeamSearchResults @@ -213,7 +213,7 @@ func TestTeamSearch(t *testing.T) { assert.Equal(t, "test_team", results.Data[0].Name) // no access if not organization member - user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) session = loginUser(t, user5.Name) csrf = GetCSRF(t, session, "/"+org.Name) req = NewRequestf(t, "GET", "/org/%s/teams/-/search?q=%s", org.Name, "team") diff --git a/integrations/privateactivity_test.go b/integrations/privateactivity_test.go index c5cdc27d6e..8e6a538c59 100644 --- a/integrations/privateactivity_test.go +++ b/integrations/privateactivity_test.go @@ -29,8 +29,8 @@ const privateActivityTestOtherUser = "user4" // activity helpers func testPrivateActivityDoSomethingForActionEntries(t *testing.T) { - repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User) + repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}) session := loginUser(t, privateActivityTestUser) token := getTokenForLoggedInUser(t, session) diff --git a/integrations/pull_merge_test.go b/integrations/pull_merge_test.go index 2a3a461efd..13c2ff973a 100644 --- a/integrations/pull_merge_test.go +++ b/integrations/pull_merge_test.go @@ -228,18 +228,18 @@ func TestCantMergeConflict(t *testing.T) { // Now this PR will be marked conflict - or at least a race will do - so drop down to pure code at this point... user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ Name: "user1", - }).(*user_model.User) + }) repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ OwnerID: user1.ID, Name: "repo1", - }).(*repo_model.Repository) + }) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo1.ID, BaseRepoID: repo1.ID, HeadBranch: "conflict", BaseBranch: "base", - }).(*issues_model.PullRequest) + }) gitRepo, err := git.OpenRepository(git.DefaultContext, repo_model.RepoPath(user1.Name, repo1.Name)) assert.NoError(t, err) @@ -265,11 +265,11 @@ func TestCantMergeUnrelated(t *testing.T) { // Drop down to pure code at this point user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ Name: "user1", - }).(*user_model.User) + }) repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ OwnerID: user1.ID, Name: "repo1", - }).(*repo_model.Repository) + }) path := repo_model.RepoPath(user1.Name, repo1.Name) err := git.NewCommand(git.DefaultContext, "read-tree", "--empty").Run(&git.RunOpts{Dir: path}) @@ -341,7 +341,7 @@ func TestCantMergeUnrelated(t *testing.T) { BaseRepoID: repo1.ID, HeadBranch: "unrelated", BaseBranch: "base", - }).(*issues_model.PullRequest) + }) err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "UNRELATED") assert.Error(t, err, "Merge should return an error due to unrelated") @@ -352,7 +352,7 @@ func TestCantMergeUnrelated(t *testing.T) { func TestConflictChecking(t *testing.T) { onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Create new clean repo to test conflict checking. baseRepo, err := repo_service.CreateRepository(user, user, models.CreateRepoOptions{ @@ -408,7 +408,7 @@ func TestConflictChecking(t *testing.T) { err = pull.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) assert.NoError(t, err) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "PR with conflict!"}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "PR with conflict!"}) conflictingPR, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID) assert.NoError(t, err) diff --git a/integrations/pull_update_test.go b/integrations/pull_update_test.go index 47ada91e1a..056d06189a 100644 --- a/integrations/pull_update_test.go +++ b/integrations/pull_update_test.go @@ -26,8 +26,8 @@ import ( func TestAPIPullUpdate(t *testing.T) { onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { // Create PR to test - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26}) pr := createOutdatedPR(t, user, org26) // Test GetDiverging @@ -54,8 +54,8 @@ func TestAPIPullUpdate(t *testing.T) { func TestAPIPullUpdateByRebase(t *testing.T) { onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { // Create PR to test - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26}) pr := createOutdatedPR(t, user, org26) // Test GetDiverging @@ -166,7 +166,7 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_mod err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) assert.NoError(t, err) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Test Pull -to-update-"}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Test Pull -to-update-"}) pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID) assert.NoError(t, err) diff --git a/integrations/release_test.go b/integrations/release_test.go index dd32a64ed5..5c6290422d 100644 --- a/integrations/release_test.go +++ b/integrations/release_test.go @@ -134,7 +134,7 @@ func TestCreateReleasePaging(t *testing.T) { func TestViewReleaseListNoLogin(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) link := repo.Link() + "/releases" @@ -160,7 +160,7 @@ func TestViewReleaseListNoLogin(t *testing.T) { func TestViewReleaseListLogin(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) link := repo.Link() + "/releases" @@ -191,7 +191,7 @@ func TestViewReleaseListLogin(t *testing.T) { func TestViewTagsList(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) link := repo.Link() + "/tags" diff --git a/integrations/rename_branch_test.go b/integrations/rename_branch_test.go index 7760a2d946..ad27869cde 100644 --- a/integrations/rename_branch_test.go +++ b/integrations/rename_branch_test.go @@ -40,6 +40,6 @@ func TestRenameBranch(t *testing.T) { assert.Equal(t, "/user2/repo1/src/branch/main/README.md", location) // check db - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.Equal(t, "main", repo1.DefaultBranch) } diff --git a/integrations/repo_fork_test.go b/integrations/repo_fork_test.go index 5f28e66ac8..17133621d6 100644 --- a/integrations/repo_fork_test.go +++ b/integrations/repo_fork_test.go @@ -17,7 +17,7 @@ import ( ) func testRepoFork(t *testing.T, session *TestSession, ownerName, repoName, forkOwnerName, forkRepoName string) *httptest.ResponseRecorder { - forkOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: forkOwnerName}).(*user_model.User) + forkOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: forkOwnerName}) // Step0: check the existence of the to-fork repo req := NewRequestf(t, "GET", "/%s/%s", forkOwnerName, forkRepoName) diff --git a/integrations/repo_generate_test.go b/integrations/repo_generate_test.go index 0123932a74..d34983f528 100644 --- a/integrations/repo_generate_test.go +++ b/integrations/repo_generate_test.go @@ -17,7 +17,7 @@ import ( ) func testRepoGenerate(t *testing.T, session *TestSession, templateOwnerName, templateRepoName, generateOwnerName, generateRepoName string) *httptest.ResponseRecorder { - generateOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: generateOwnerName}).(*user_model.User) + generateOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: generateOwnerName}) // Step0: check the existence of the generated repo req := NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName) diff --git a/integrations/repo_tag_test.go b/integrations/repo_tag_test.go index 793cf724eb..1b3e30106b 100644 --- a/integrations/repo_tag_test.go +++ b/integrations/repo_tag_test.go @@ -24,8 +24,8 @@ import ( func TestCreateNewTagProtected(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) t.Run("API", func(t *testing.T) { defer PrintCurrentTest(t)() diff --git a/integrations/repo_test.go b/integrations/repo_test.go index 872d3f24d1..c2ac6183f0 100644 --- a/integrations/repo_test.go +++ b/integrations/repo_test.go @@ -64,7 +64,7 @@ func testViewRepo(t *testing.T) { } }) - f.commitTime, _ = s.Find("span.time-since").Attr("title") + f.commitTime, _ = s.Find("span.time-since").Attr("data-content") items = append(items, f) }) diff --git a/integrations/signin_test.go b/integrations/signin_test.go index 952efcfdd9..568ceb40ca 100644 --- a/integrations/signin_test.go +++ b/integrations/signin_test.go @@ -34,7 +34,7 @@ func testLoginFailed(t *testing.T, username, password, message string) { func TestSignin(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // add new user with user2's email user.Name = "testuser" diff --git a/integrations/signup_test.go b/integrations/signup_test.go index b34e40f286..071ece9fa1 100644 --- a/integrations/signup_test.go +++ b/integrations/signup_test.go @@ -54,7 +54,7 @@ func TestSignupAsRestricted(t *testing.T) { req = NewRequest(t, "GET", "/restrictedUser") MakeRequest(t, req, http.StatusOK) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "restrictedUser"}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "restrictedUser"}) assert.True(t, user2.IsRestricted) } diff --git a/integrations/user_avatar_test.go b/integrations/user_avatar_test.go index 2bf6fde5ff..ee532bb64a 100644 --- a/integrations/user_avatar_test.go +++ b/integrations/user_avatar_test.go @@ -22,7 +22,7 @@ import ( func TestUserAvatar(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo3, is an org + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org seed := user2.Email if len(seed) == 0 { @@ -72,7 +72,7 @@ func TestUserAvatar(t *testing.T) { session.MakeRequest(t, req, http.StatusSeeOther) - user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo3, is an org + user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org req = NewRequest(t, "GET", user2.AvatarLinkWithSize(0)) _ = session.MakeRequest(t, req, http.StatusOK) diff --git a/integrations/user_test.go b/integrations/user_test.go index 33113369a7..b0c1cd42eb 100644 --- a/integrations/user_test.go +++ b/integrations/user_test.go @@ -229,16 +229,16 @@ func testExportUserGPGKeys(t *testing.T, user, expected string) { func TestListStopWatches(t *testing.T) { defer prepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) req := NewRequestf(t, "GET", "/user/stopwatches") resp := session.MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches) - stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}).(*issues_model.Stopwatch) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}).(*issues_model.Issue) + stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}) if assert.Len(t, apiWatches, 1) { assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex) diff --git a/integrations/webfinger_test.go b/integrations/webfinger_test.go index 07bf58b509..3574941e42 100644 --- a/integrations/webfinger_test.go +++ b/integrations/webfinger_test.go @@ -25,7 +25,7 @@ func TestWebfinger(t *testing.T) { setting.Federation.Enabled = false }() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) appURL, _ := url.Parse(setting.AppURL) diff --git a/integrations/xss_test.go b/integrations/xss_test.go index 1ce25e1bf5..d5ce94b0c6 100644 --- a/integrations/xss_test.go +++ b/integrations/xss_test.go @@ -16,7 +16,7 @@ import ( func TestXSSUserFullName(t *testing.T) { defer prepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) const fullName = `name & ` session := loginUser(t, user.Name) diff --git a/models/action_test.go b/models/action_test.go index 2d46bd3e80..5c61736a61 100644 --- a/models/action_test.go +++ b/models/action_test.go @@ -19,16 +19,16 @@ import ( func TestAction_GetRepoPath(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) action := &Action{RepoID: repo.ID} assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath()) } func TestAction_GetRepoLink(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) action := &Action{RepoID: repo.ID} setting.AppSubURL = "/suburl" expected := path.Join(setting.AppSubURL, owner.Name, repo.Name) @@ -38,7 +38,7 @@ func TestAction_GetRepoLink(t *testing.T) { func TestGetFeeds(t *testing.T) { // test with an individual user assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ RequestedUser: user, @@ -65,9 +65,9 @@ func TestGetFeeds(t *testing.T) { func TestGetFeedsForRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - privRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + privRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}) // private repo & no login actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ @@ -107,8 +107,8 @@ func TestGetFeedsForRepos(t *testing.T) { func TestGetFeeds2(t *testing.T) { // test with an organization user assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ RequestedUser: org, @@ -214,7 +214,7 @@ func TestNotifyWatchers(t *testing.T) { func TestGetFeedsCorrupted(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) unittest.AssertExistsAndLoadBean(t, &Action{ ID: 8, RepoID: 1700, diff --git a/models/asymkey/gpg_key_test.go b/models/asymkey/gpg_key_test.go index 07bb77bdf4..2cee45d98f 100644 --- a/models/asymkey/gpg_key_test.go +++ b/models/asymkey/gpg_key_test.go @@ -196,7 +196,7 @@ Unknown GPG key with good email func TestCheckGPGUserEmail(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) testEmailWithUpperCaseLetters := `-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1 diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go index 5a58ec62b7..ad1d80e25a 100644 --- a/models/auth/oauth2.go +++ b/models/auth/oauth2.go @@ -512,10 +512,14 @@ func GetActiveOAuth2ProviderSources() ([]*Source, error) { func GetActiveOAuth2SourceByName(name string) (*Source, error) { authSource := new(Source) has, err := db.GetEngine(db.DefaultContext).Where("name = ? and type = ? and is_active = ?", name, OAuth2, true).Get(authSource) - if !has || err != nil { + if err != nil { return nil, err } + if !has { + return nil, fmt.Errorf("oauth2 source not found, name: %q", name) + } + return authSource, nil } diff --git a/models/auth/oauth2_test.go b/models/auth/oauth2_test.go index cb8c4aeb6a..2a74f39998 100644 --- a/models/auth/oauth2_test.go +++ b/models/auth/oauth2_test.go @@ -17,7 +17,7 @@ import ( func TestOAuth2Application_GenerateClientSecret(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application) + app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) secret, err := app.GenerateClientSecret() assert.NoError(t, err) assert.True(t, len(secret) > 0) @@ -26,7 +26,7 @@ func TestOAuth2Application_GenerateClientSecret(t *testing.T) { func BenchmarkOAuth2Application_GenerateClientSecret(b *testing.B) { assert.NoError(b, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(b, &OAuth2Application{ID: 1}).(*OAuth2Application) + app := unittest.AssertExistsAndLoadBean(b, &OAuth2Application{ID: 1}) for i := 0; i < b.N; i++ { _, _ = app.GenerateClientSecret() } @@ -44,7 +44,7 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) { func TestOAuth2Application_ValidateClientSecret(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application) + app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) secret, err := app.GenerateClientSecret() assert.NoError(t, err) assert.True(t, app.ValidateClientSecret([]byte(secret))) @@ -77,7 +77,7 @@ func TestOAuth2Application_TableName(t *testing.T) { func TestOAuth2Application_GetGrantByUserID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application) + app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) grant, err := app.GetGrantByUserID(db.DefaultContext, 1) assert.NoError(t, err) assert.Equal(t, int64(1), grant.UserID) @@ -89,7 +89,7 @@ func TestOAuth2Application_GetGrantByUserID(t *testing.T) { func TestOAuth2Application_CreateGrant(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application) + app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) grant, err := app.CreateGrant(db.DefaultContext, 2, "") assert.NoError(t, err) assert.NotNil(t, grant) @@ -113,7 +113,7 @@ func TestGetOAuth2GrantByID(t *testing.T) { func TestOAuth2Grant_IncreaseCounter(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 1}).(*OAuth2Grant) + grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 1}) assert.NoError(t, grant.IncreaseCounter(db.DefaultContext)) assert.Equal(t, int64(2), grant.Counter) unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 2}) @@ -121,7 +121,7 @@ func TestOAuth2Grant_IncreaseCounter(t *testing.T) { func TestOAuth2Grant_ScopeContains(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Scope: "openid profile"}).(*OAuth2Grant) + grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Scope: "openid profile"}) assert.True(t, grant.ScopeContains("openid")) assert.True(t, grant.ScopeContains("profile")) assert.False(t, grant.ScopeContains("profil")) @@ -130,7 +130,7 @@ func TestOAuth2Grant_ScopeContains(t *testing.T) { func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1}).(*OAuth2Grant) + grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1}) code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256") assert.NoError(t, err) assert.NotNil(t, code) @@ -224,7 +224,7 @@ func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) { func TestOAuth2AuthorizationCode_Invalidate(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - code := unittest.AssertExistsAndLoadBean(t, &OAuth2AuthorizationCode{Code: "authcode"}).(*OAuth2AuthorizationCode) + code := unittest.AssertExistsAndLoadBean(t, &OAuth2AuthorizationCode{Code: "authcode"}) assert.NoError(t, code.Invalidate(db.DefaultContext)) unittest.AssertNotExistsBean(t, &OAuth2AuthorizationCode{Code: "authcode"}) } diff --git a/models/auth/webauthn_test.go b/models/auth/webauthn_test.go index cc39691ce2..edbb7ecd5b 100644 --- a/models/auth/webauthn_test.go +++ b/models/auth/webauthn_test.go @@ -40,7 +40,7 @@ func TestWebAuthnCredential_TableName(t *testing.T) { func TestWebAuthnCredential_UpdateSignCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}).(*WebAuthnCredential) + cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}) cred.SignCount = 1 assert.NoError(t, cred.UpdateSignCount()) unittest.AssertExistsIf(t, true, &WebAuthnCredential{ID: 1, SignCount: 1}) @@ -48,7 +48,7 @@ func TestWebAuthnCredential_UpdateSignCount(t *testing.T) { func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}).(*WebAuthnCredential) + cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}) cred.SignCount = 0xffffffff assert.NoError(t, cred.UpdateSignCount()) unittest.AssertExistsIf(t, true, &WebAuthnCredential{ID: 1, SignCount: 0xffffffff}) diff --git a/models/db/iterate.go b/models/db/iterate.go new file mode 100644 index 0000000000..3d4fa06eeb --- /dev/null +++ b/models/db/iterate.go @@ -0,0 +1,34 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package db + +import ( + "context" + + "code.gitea.io/gitea/modules/setting" +) + +// IterateObjects iterate all the Bean object +func IterateObjects[Object any](ctx context.Context, f func(repo *Object) error) error { + var start int + batchSize := setting.Database.IterateBufferSize + sess := GetEngine(ctx) + for { + repos := make([]*Object, 0, batchSize) + if err := sess.Limit(batchSize, start).Find(&repos); err != nil { + return err + } + if len(repos) == 0 { + return nil + } + start += len(repos) + + for _, repo := range repos { + if err := f(repo); err != nil { + return err + } + } + } +} diff --git a/models/git/branches_test.go b/models/git/branches_test.go index 8102d28d48..58c4ad027b 100644 --- a/models/git/branches_test.go +++ b/models/git/branches_test.go @@ -18,8 +18,8 @@ import ( func TestAddDeletedBranch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}) assert.Error(t, git_model.AddDeletedBranch(repo.ID, firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID)) assert.NoError(t, git_model.AddDeletedBranch(repo.ID, "test", "5655464564554545466464656", int64(1))) @@ -27,7 +27,7 @@ func TestAddDeletedBranch(t *testing.T) { func TestGetDeletedBranches(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) branches, err := git_model.GetDeletedBranches(repo.ID) assert.NoError(t, err) @@ -36,7 +36,7 @@ func TestGetDeletedBranches(t *testing.T) { func TestGetDeletedBranch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch) + firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}) assert.NotNil(t, getDeletedBranch(t, firstBranch)) } @@ -44,8 +44,8 @@ func TestGetDeletedBranch(t *testing.T) { func TestDeletedBranchLoadUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch) - secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 2}).(*git_model.DeletedBranch) + firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}) + secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 2}) branch := getDeletedBranch(t, firstBranch) assert.Nil(t, branch.DeletedBy) @@ -62,9 +62,9 @@ func TestDeletedBranchLoadUser(t *testing.T) { func TestRemoveDeletedBranch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch) + firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}) err := git_model.RemoveDeletedBranchByID(repo.ID, 1) assert.NoError(t, err) @@ -73,7 +73,7 @@ func TestRemoveDeletedBranch(t *testing.T) { } func getDeletedBranch(t *testing.T, branch *git_model.DeletedBranch) *git_model.DeletedBranch { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) deletedBranch, err := git_model.GetDeletedBranchByID(repo.ID, branch.ID) assert.NoError(t, err) @@ -99,7 +99,7 @@ func TestFindRenamedBranch(t *testing.T) { func TestRenameBranch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) _isDefault := false ctx, committer, err := db.TxContext() @@ -117,16 +117,16 @@ func TestRenameBranch(t *testing.T) { })) assert.Equal(t, true, _isDefault) - repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.Equal(t, "main", repo1.DefaultBranch) - pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) // merged + pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) // merged assert.Equal(t, "master", pull.BaseBranch) - pull = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) // open + pull = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) // open assert.Equal(t, "main", pull.BaseBranch) - renamedBranch := unittest.AssertExistsAndLoadBean(t, &git_model.RenamedBranch{ID: 2}).(*git_model.RenamedBranch) + renamedBranch := unittest.AssertExistsAndLoadBean(t, &git_model.RenamedBranch{ID: 2}) assert.Equal(t, "master", renamedBranch.From) assert.Equal(t, "main", renamedBranch.To) assert.Equal(t, int64(1), renamedBranch.RepoID) @@ -143,7 +143,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) { // Get deletedBranch with ID of 1 on repo with ID 2. // This should return a nil branch as this deleted branch // is actually on repo with ID 1. - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) deletedBranch, err := git_model.GetDeletedBranchByID(repo2.ID, 1) @@ -153,7 +153,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) { // Now get the deletedBranch with ID of 1 on repo with ID 1. // This should return the deletedBranch. - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) deletedBranch, err = git_model.GetDeletedBranchByID(repo1.ID, 1) diff --git a/models/git/commit_status_test.go b/models/git/commit_status_test.go index 9919297430..7b81b1549c 100644 --- a/models/git/commit_status_test.go +++ b/models/git/commit_status_test.go @@ -19,7 +19,7 @@ import ( func TestGetCommitStatuses(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) sha1 := "1234123412341234123412341234123412341234" diff --git a/models/git/lfs.go b/models/git/lfs.go index ec963cf593..179da3120a 100644 --- a/models/git/lfs.go +++ b/models/git/lfs.go @@ -278,29 +278,6 @@ func LFSAutoAssociate(metas []*LFSMetaObject, user *user_model.User, repoID int6 return committer.Commit() } -// IterateLFS iterates lfs object -func IterateLFS(f func(mo *LFSMetaObject) error) error { - var start int - const batchSize = 100 - e := db.GetEngine(db.DefaultContext) - for { - mos := make([]*LFSMetaObject, 0, batchSize) - if err := e.Limit(batchSize, start).Find(&mos); err != nil { - return err - } - if len(mos) == 0 { - return nil - } - start += len(mos) - - for _, mo := range mos { - if err := f(mo); err != nil { - return err - } - } - } -} - // CopyLFS copies LFS data from one repo to another func CopyLFS(ctx context.Context, newRepo, oldRepo *repo_model.Repository) error { var lfsObjects []*LFSMetaObject diff --git a/models/issues/assignees_test.go b/models/issues/assignees_test.go index 37d966f140..291bb673da 100644 --- a/models/issues/assignees_test.go +++ b/models/issues/assignees_test.go @@ -68,8 +68,8 @@ func TestUpdateAssignee(t *testing.T) { func TestMakeIDsFromAPIAssigneesToAdd(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{""}) assert.NoError(t, err) diff --git a/models/issues/comment_test.go b/models/issues/comment_test.go index 06b0b85e3c..f12da0177f 100644 --- a/models/issues/comment_test.go +++ b/models/issues/comment_test.go @@ -20,9 +20,9 @@ import ( func TestCreateComment(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) now := time.Now().Unix() comment, err := issues_model.CreateComment(&issues_model.CreateCommentOptions{ @@ -42,15 +42,15 @@ func TestCreateComment(t *testing.T) { unittest.AssertInt64InRange(t, now, then, int64(comment.CreatedUnix)) unittest.AssertExistsAndLoadBean(t, comment) // assert actually added to DB - updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}).(*issues_model.Issue) + updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}) unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) } func TestFetchCodeComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) res, err := issues_model.FetchCodeComments(db.DefaultContext, issue, user) assert.NoError(t, err) assert.Contains(t, res, "README.md") @@ -58,7 +58,7 @@ func TestFetchCodeComments(t *testing.T) { assert.Len(t, res["README.md"][4], 1) assert.Equal(t, int64(4), res["README.md"][4][0].ID) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) res, err = issues_model.FetchCodeComments(db.DefaultContext, issue, user2) assert.NoError(t, err) assert.Len(t, res, 1) diff --git a/models/issues/issue_list_test.go b/models/issues/issue_list_test.go index 6b978f9ae6..f2cfca9bc0 100644 --- a/models/issues/issue_list_test.go +++ b/models/issues/issue_list_test.go @@ -18,9 +18,9 @@ func TestIssueList_LoadRepositories(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issueList := issues_model.IssueList{ - unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue), - unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue), - unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}), } repos, err := issueList.LoadRepositories() @@ -35,8 +35,8 @@ func TestIssueList_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) setting.Service.EnableTimetracking = true issueList := issues_model.IssueList{ - unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue), - unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}), } assert.NoError(t, issueList.LoadAttributes()) diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go index 019e578da8..bef5d03e8a 100644 --- a/models/issues/issue_test.go +++ b/models/issues/issue_test.go @@ -29,13 +29,13 @@ func TestIssue_ReplaceLabels(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(issueID int64, labelIDs []int64) { - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}).(*issues_model.Issue) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) labels := make([]*issues_model.Label, len(labelIDs)) for i, labelID := range labelIDs { - labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID, RepoID: repo.ID}).(*issues_model.Label) + labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID, RepoID: repo.ID}) } assert.NoError(t, issues_model.ReplaceIssueLabels(issue, labels, doer)) unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issueID}, len(labelIDs)) @@ -59,7 +59,7 @@ func Test_GetIssueIDsByRepoID(t *testing.T) { func TestIssueAPIURL(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) err := issue.LoadAttributes(db.DefaultContext) assert.NoError(t, err) @@ -117,8 +117,8 @@ func TestIssue_ClearLabels(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}) assert.NoError(t, issues_model.ClearIssueLabels(issue, doer)) unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: test.issueID}) } @@ -126,7 +126,7 @@ func TestIssue_ClearLabels(t *testing.T) { func TestUpdateIssueCols(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}) const newTitle = "New Title for unit test" issue.Title = newTitle @@ -138,7 +138,7 @@ func TestUpdateIssueCols(t *testing.T) { assert.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "name")) then := time.Now().Unix() - updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}).(*issues_model.Issue) + updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}) assert.EqualValues(t, newTitle, updatedIssue.Title) assert.EqualValues(t, prevContent, updatedIssue.Content) unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) @@ -291,8 +291,8 @@ func TestGetUserIssueStats(t *testing.T) { { issues_model.UserIssueStatsOptions{ UserID: 2, - Org: unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization), - Team: unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 7}).(*organization.Team), + Org: unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}), + Team: unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 7}), FilterMode: issues_model.FilterModeAll, }, issues_model.IssueStats{ @@ -347,7 +347,7 @@ func TestIssue_SearchIssueIDsByKeyword(t *testing.T) { func TestGetRepoIDsForIssuesOptions(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) for _, test := range []struct { Opts issues_model.IssuesOptions ExpectedRepoIDs []int64 @@ -378,8 +378,8 @@ func TestGetRepoIDsForIssuesOptions(t *testing.T) { func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *issues_model.Issue { var newIssue issues_model.Issue t.Run(title, func(t *testing.T) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) issue := issues_model.Issue{ RepoID: repo.ID, @@ -420,10 +420,10 @@ func TestIssue_ResolveMentions(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(owner, repo, doer string, mentions []string, expected []int64) { - o := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: owner}).(*user_model.User) - r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: o.ID, LowerName: repo}).(*repo_model.Repository) + o := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: owner}) + r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: o.ID, LowerName: repo}) issue := &issues_model.Issue{RepoID: r.ID} - d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer}).(*user_model.User) + d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer}) resolved, err := issues_model.ResolveIssueMentionsByVisibility(db.DefaultContext, issue, d, mentions) assert.NoError(t, err) ids := make([]int64, len(resolved)) @@ -504,7 +504,7 @@ func TestCorrectIssueStats(t *testing.T) { func TestIssueForeignReference(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}) assert.NotEqualValues(t, issue.Index, issue.ID) // make sure they are different to avoid false positive // it is fine for an issue to not have a foreign reference @@ -537,7 +537,7 @@ func TestIssueForeignReference(t *testing.T) { func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) miles := issues_model.MilestoneList{ - unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone), + unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}), } assert.NoError(t, miles.LoadTotalTrackedTimes()) @@ -547,7 +547,7 @@ func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) { func TestLoadTotalTrackedTime(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) assert.NoError(t, milestone.LoadTotalTrackedTime()) diff --git a/models/issues/issue_user_test.go b/models/issues/issue_user_test.go index 33e9f98ecc..7dd84ed68c 100644 --- a/models/issues/issue_user_test.go +++ b/models/issues/issue_user_test.go @@ -18,7 +18,7 @@ import ( func Test_NewIssueUsers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) newIssue := &issues_model.Issue{ RepoID: repo.ID, PosterID: 4, @@ -39,7 +39,7 @@ func Test_NewIssueUsers(t *testing.T) { func TestUpdateIssueUserByRead(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) assert.NoError(t, issues_model.UpdateIssueUserByRead(4, issue.ID)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") @@ -52,7 +52,7 @@ func TestUpdateIssueUserByRead(t *testing.T) { func TestUpdateIssueUsersByMentions(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) uids := []int64{2, 5} assert.NoError(t, issues_model.UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids)) diff --git a/models/issues/issue_watch_test.go b/models/issues/issue_watch_test.go index c6b6416d9b..7aaf9f7f5d 100644 --- a/models/issues/issue_watch_test.go +++ b/models/issues/issue_watch_test.go @@ -18,11 +18,11 @@ func TestCreateOrUpdateIssueWatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(3, 1, true)) - iw := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 3, IssueID: 1}).(*issues_model.IssueWatch) + iw := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 3, IssueID: 1}) assert.True(t, iw.IsWatching) assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(1, 1, false)) - iw = unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 1, IssueID: 1}).(*issues_model.IssueWatch) + iw = unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 1, IssueID: 1}) assert.False(t, iw.IsWatching) } diff --git a/models/issues/issue_xref_test.go b/models/issues/issue_xref_test.go index 6bb19d5328..af1c8bc685 100644 --- a/models/issues/issue_xref_test.go +++ b/models/issues/issue_xref_test.go @@ -27,7 +27,7 @@ func TestXRef_AddCrossReferences(t *testing.T) { // PR to close issue #1 content := fmt.Sprintf("content2, closes #%d", itarget.Index) pr := testCreateIssue(t, 1, 2, "title2", content, true) - ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}).(*issues_model.Comment) + ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}) assert.Equal(t, issues_model.CommentTypePullRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.True(t, ref.RefIsPull) @@ -36,7 +36,7 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Comment on PR to reopen issue #1 content = fmt.Sprintf("content2, reopens #%d", itarget.Index) c := testCreateComment(t, 1, 2, pr.ID, content) - ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}).(*issues_model.Comment) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}) assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.True(t, ref.RefIsPull) @@ -45,7 +45,7 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Issue mentioning issue #1 content = fmt.Sprintf("content3, mentions #%d", itarget.Index) i := testCreateIssue(t, 1, 2, "title3", content, false) - ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.False(t, ref.RefIsPull) @@ -57,7 +57,7 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Cross-reference to issue #4 by admin content = fmt.Sprintf("content5, mentions user3/repo3#%d", itarget.Index) i = testCreateIssue(t, 2, 1, "title5", content, false) - ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, i.RepoID, ref.RefRepoID) assert.False(t, ref.RefIsPull) @@ -78,15 +78,15 @@ func TestXRef_NeuterCrossReferences(t *testing.T) { // Issue mentioning issue #1 title := fmt.Sprintf("title2, mentions #%d", itarget.Index) i := testCreateIssue(t, 1, 2, title, "content2", false) - ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, references.XRefActionNone, ref.RefAction) - d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) i.Title = "title2, no mentions" assert.NoError(t, issues_model.ChangeIssueTitle(i, d, title)) - ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, references.XRefActionNeutered, ref.RefAction) } @@ -94,7 +94,7 @@ func TestXRef_NeuterCrossReferences(t *testing.T) { func TestXRef_ResolveCrossReferences(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) i1 := testCreateIssue(t, 1, 2, "title1", "content1", false) i2 := testCreateIssue(t, 1, 2, "title2", "content2", false) @@ -103,10 +103,10 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { assert.NoError(t, err) pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index)) - rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}).(*issues_model.Comment) + rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}) c1 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i2.Index)) - r1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}).(*issues_model.Comment) + r1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}) // Must be ignored c2 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("mentions #%d", i2.Index)) @@ -117,7 +117,7 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID}) c4 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index)) - r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}).(*issues_model.Comment) + r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}) refs, err := pr.ResolveCrossReferences(db.DefaultContext) assert.NoError(t, err) @@ -128,8 +128,8 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { } func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *issues_model.Issue { - r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository) - d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) + r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}) + d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}) idx, err := db.GetNextResourceIndex("issue_index", r.ID) assert.NoError(t, err) @@ -159,8 +159,8 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu } func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues_model.PullRequest { - r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository) - d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) + r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}) + d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}) i := &issues_model.Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true} pr := &issues_model.PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: issues_model.PullRequestStatusMergeable} assert.NoError(t, issues_model.NewPullRequest(db.DefaultContext, r, i, nil, nil, pr)) @@ -169,8 +169,8 @@ func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues } func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *issues_model.Comment { - d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) - i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue}).(*issues_model.Issue) + d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}) + i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue}) c := &issues_model.Comment{Type: issues_model.CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} ctx, committer, err := db.TxContext() diff --git a/models/issues/label_test.go b/models/issues/label_test.go index 33f114b5fe..9ad6fd427b 100644 --- a/models/issues/label_test.go +++ b/models/issues/label_test.go @@ -21,17 +21,17 @@ import ( func TestLabel_CalOpenIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) label.CalOpenIssues() assert.EqualValues(t, 2, label.NumOpenIssues) } func TestLabel_ForegroundColor(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) assert.Equal(t, template.CSS("#000"), label.ForegroundColor()) - label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}) assert.Equal(t, template.CSS("#fff"), label.ForegroundColor()) } @@ -260,7 +260,7 @@ func TestGetLabelsByIssueID(t *testing.T) { func TestUpdateLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) // make sure update wont overwrite it update := &issues_model.Label{ ID: label.ID, @@ -271,7 +271,7 @@ func TestUpdateLabel(t *testing.T) { label.Color = update.Color label.Name = update.Name assert.NoError(t, issues_model.UpdateLabel(update)) - newLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + newLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) assert.EqualValues(t, label.ID, newLabel.ID) assert.EqualValues(t, label.Color, newLabel.Color) assert.EqualValues(t, label.Name, newLabel.Name) @@ -281,7 +281,7 @@ func TestUpdateLabel(t *testing.T) { func TestDeleteLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) assert.NoError(t, issues_model.DeleteLabel(label.RepoID, label.ID)) unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID, RepoID: label.RepoID}) @@ -301,9 +301,9 @@ func TestHasIssueLabel(t *testing.T) { func TestNewIssueLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // add new IssueLabel prevNumIssues := label.NumIssues @@ -316,7 +316,7 @@ func TestNewIssueLabel(t *testing.T) { LabelID: label.ID, Content: "1", }) - label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}) assert.EqualValues(t, prevNumIssues+1, label.NumIssues) // re-add existing IssueLabel @@ -326,10 +326,10 @@ func TestNewIssueLabel(t *testing.T) { func TestNewIssueLabels(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) - label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5}).(*issues_model.Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) + label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) assert.NoError(t, issues_model.NewIssueLabels(issue, []*issues_model.Label{label1, label2}, doer)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) @@ -341,10 +341,10 @@ func TestNewIssueLabels(t *testing.T) { Content: "1", }) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) - label1 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label1 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) assert.EqualValues(t, 3, label1.NumIssues) assert.EqualValues(t, 1, label1.NumClosedIssues) - label2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + label2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}) assert.EqualValues(t, 1, label2.NumIssues) assert.EqualValues(t, 1, label2.NumClosedIssues) @@ -357,9 +357,9 @@ func TestNewIssueLabels(t *testing.T) { func TestDeleteIssueLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(labelID, issueID, doerID int64) { - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}).(*issues_model.Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID}).(*user_model.User) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID}) expectedNumIssues := label.NumIssues expectedNumClosedIssues := label.NumClosedIssues @@ -383,7 +383,7 @@ func TestDeleteIssueLabel(t *testing.T) { IssueID: issueID, LabelID: labelID, }, `content=""`) - label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}) assert.EqualValues(t, expectedNumIssues, label.NumIssues) assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues) } diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index a6fbf9c23b..f04a2b2b3b 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -40,7 +40,7 @@ func TestGetMilestoneByRepoID(t *testing.T) { func TestGetMilestonesByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64, state api.StateType) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{ RepoID: repo.ID, State: state, @@ -88,7 +88,7 @@ func TestGetMilestonesByRepoID(t *testing.T) { func TestGetMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{ @@ -150,7 +150,7 @@ func TestGetMilestones(t *testing.T) { func TestCountRepoMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ RepoID: repoID, State: api.StateAll, @@ -173,7 +173,7 @@ func TestCountRepoMilestones(t *testing.T) { func TestCountRepoClosedMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ RepoID: repoID, State: api.StateClosed, @@ -196,7 +196,7 @@ func TestCountRepoClosedMilestones(t *testing.T) { func TestCountMilestonesByRepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) milestonesCount := func(repoID int64) (int, int) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) return repo.NumOpenMilestones, repo.NumClosedMilestones } repo1OpenCount, repo1ClosedCount := milestonesCount(1) @@ -215,8 +215,8 @@ func TestCountMilestonesByRepoIDs(t *testing.T) { func TestGetMilestonesByRepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { openMilestones, err := issues_model.GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, false, sortType) @@ -262,7 +262,7 @@ func TestGetMilestonesStats(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) stats, err := issues_model.GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": repoID})) assert.NoError(t, err) assert.EqualValues(t, repo.NumMilestones-repo.NumClosedMilestones, stats.OpenCount) @@ -277,8 +277,8 @@ func TestGetMilestonesStats(t *testing.T) { assert.EqualValues(t, 0, stats.OpenCount) assert.EqualValues(t, 0, stats.ClosedCount) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) milestoneStats, err := issues_model.GetMilestonesStatsByRepoCond(builder.In("repo_id", []int64{repo1.ID, repo2.ID})) assert.NoError(t, err) @@ -301,7 +301,7 @@ func TestNewMilestone(t *testing.T) { func TestChangeMilestoneStatus(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, true)) unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1") @@ -324,11 +324,11 @@ func TestDeleteMilestoneByRepoID(t *testing.T) { func TestUpdateMilestone(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) milestone.Name = " newMilestoneName " milestone.Content = "newMilestoneContent" assert.NoError(t, issues_model.UpdateMilestone(milestone, milestone.IsClosed)) - milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) assert.EqualValues(t, "newMilestoneName", milestone.Name) unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) } @@ -336,7 +336,7 @@ func TestUpdateMilestone(t *testing.T) { func TestUpdateMilestoneCounters(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{MilestoneID: 1}, - "is_closed=0").(*issues_model.Issue) + "is_closed=0") issue.IsClosed = true issue.ClosedUnix = timeutil.TimeStampNow() diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index 0d1991383d..fb46e3071e 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -16,7 +16,7 @@ import ( func TestPullRequest_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) assert.NoError(t, pr.LoadAttributes()) assert.NotNil(t, pr.Merger) assert.Equal(t, pr.MergerID, pr.Merger.ID) @@ -24,7 +24,7 @@ func TestPullRequest_LoadAttributes(t *testing.T) { func TestPullRequest_LoadIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) assert.NoError(t, pr.LoadIssue()) assert.NotNil(t, pr.Issue) assert.Equal(t, int64(2), pr.Issue.ID) @@ -35,7 +35,7 @@ func TestPullRequest_LoadIssue(t *testing.T) { func TestPullRequest_LoadBaseRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) assert.NoError(t, pr.LoadBaseRepo()) assert.NotNil(t, pr.BaseRepo) assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID) @@ -46,7 +46,7 @@ func TestPullRequest_LoadBaseRepo(t *testing.T) { func TestPullRequest_LoadHeadRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) assert.NoError(t, pr.LoadHeadRepo()) assert.NotNil(t, pr.HeadRepo) assert.Equal(t, pr.HeadRepoID, pr.HeadRepo.ID) @@ -180,12 +180,12 @@ func TestGetPullRequestByIssueID(t *testing.T) { func TestPullRequest_Update(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) pr.BaseBranch = "baseBranch" pr.HeadBranch = "headBranch" pr.Update() - pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}).(*issues_model.PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) assert.Equal(t, "baseBranch", pr.BaseBranch) assert.Equal(t, "headBranch", pr.HeadBranch) unittest.CheckConsistencyFor(t, pr) @@ -200,7 +200,7 @@ func TestPullRequest_UpdateCols(t *testing.T) { } assert.NoError(t, pr.UpdateCols("head_branch")) - pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) assert.Equal(t, "master", pr.BaseBranch) assert.Equal(t, "headBranch", pr.HeadBranch) unittest.CheckConsistencyFor(t, pr) @@ -210,8 +210,8 @@ func TestPullRequestList_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) prs := []*issues_model.PullRequest{ - unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest), - unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest), + unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}), + unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}), } assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes()) for _, pr := range prs { @@ -227,7 +227,7 @@ func TestPullRequestList_LoadAttributes(t *testing.T) { func TestPullRequest_IsWorkInProgress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) pr.LoadIssue() assert.False(t, pr.IsWorkInProgress()) @@ -242,7 +242,7 @@ func TestPullRequest_IsWorkInProgress(t *testing.T) { func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) pr.LoadIssue() assert.Empty(t, pr.GetWorkInProgressPrefix()) diff --git a/models/issues/reaction_test.go b/models/issues/reaction_test.go index ee1b6687a2..835a667619 100644 --- a/models/issues/reaction_test.go +++ b/models/issues/reaction_test.go @@ -32,7 +32,7 @@ func addReaction(t *testing.T, doerID, issueID, commentID int64, content string) func TestIssueAddReaction(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) var issue1ID int64 = 1 @@ -44,7 +44,7 @@ func TestIssueAddReaction(t *testing.T) { func TestIssueAddDuplicateReaction(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) var issue1ID int64 = 1 @@ -58,14 +58,14 @@ func TestIssueAddDuplicateReaction(t *testing.T) { assert.Error(t, err) assert.Equal(t, issues_model.ErrReactionAlreadyExist{Reaction: "heart"}, err) - existingR := unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}).(*issues_model.Reaction) + existingR := unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) assert.Equal(t, existingR.ID, reaction.ID) } func TestIssueDeleteReaction(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) var issue1ID int64 = 1 @@ -82,14 +82,14 @@ func TestIssueReactionCount(t *testing.T) { setting.UI.ReactionMaxUserNum = 2 - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) ghost := user_model.NewGhostUser() var issueID int64 = 2 - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) addReaction(t, user1.ID, issueID, 0, "heart") addReaction(t, user2.ID, issueID, 0, "heart") @@ -122,7 +122,7 @@ func TestIssueReactionCount(t *testing.T) { func TestIssueCommentAddReaction(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) var issue1ID int64 = 1 var comment1ID int64 = 1 @@ -135,10 +135,10 @@ func TestIssueCommentAddReaction(t *testing.T) { func TestIssueCommentDeleteReaction(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) var issue1ID int64 = 1 var comment1ID int64 = 1 @@ -163,7 +163,7 @@ func TestIssueCommentDeleteReaction(t *testing.T) { func TestIssueCommentReactionCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) var issue1ID int64 = 1 var comment1ID int64 = 1 diff --git a/models/issues/review_test.go b/models/issues/review_test.go index 3506604b46..46d1cc777b 100644 --- a/models/issues/review_test.go +++ b/models/issues/review_test.go @@ -29,22 +29,22 @@ func TestGetReviewByID(t *testing.T) { func TestReview_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 1}).(*issues_model.Review) + review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 1}) assert.NoError(t, review.LoadAttributes(db.DefaultContext)) assert.NotNil(t, review.Issue) assert.NotNil(t, review.Reviewer) - invalidReview1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 2}).(*issues_model.Review) + invalidReview1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 2}) assert.Error(t, invalidReview1.LoadAttributes(db.DefaultContext)) - invalidReview2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 3}).(*issues_model.Review) + invalidReview2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 3}) assert.Error(t, invalidReview2.LoadAttributes(db.DefaultContext)) } func TestReview_LoadCodeComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 4}).(*issues_model.Review) + review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 4}) assert.NoError(t, review.LoadAttributes(db.DefaultContext)) assert.NoError(t, review.LoadCodeComments(db.DefaultContext)) assert.Len(t, review.CodeComments, 1) @@ -74,8 +74,8 @@ func TestFindReviews(t *testing.T) { func TestGetCurrentReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) review, err := issues_model.GetCurrentReview(db.DefaultContext, user, issue) assert.NoError(t, err) @@ -83,7 +83,7 @@ func TestGetCurrentReview(t *testing.T) { assert.Equal(t, issues_model.ReviewTypePending, review.Type) assert.Equal(t, "Pending Review", review.Content) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 7}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 7}) review2, err := issues_model.GetCurrentReview(db.DefaultContext, user2, issue) assert.Error(t, err) assert.True(t, issues_model.IsErrReviewNotExist(err)) @@ -93,8 +93,8 @@ func TestGetCurrentReview(t *testing.T) { func TestCreateReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) review, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ Content: "New Review", @@ -110,10 +110,10 @@ func TestCreateReview(t *testing.T) { func TestGetReviewersByIssueID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) - user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) expectedReviews := []*issues_model.Review{} expectedReviews = append(expectedReviews, @@ -150,43 +150,43 @@ func TestGetReviewersByIssueID(t *testing.T) { func TestDismissReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) - requestReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) - approveReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 8}).(*issues_model.Review) + rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) + requestReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) + approveReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 8}) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) assert.NoError(t, issues_model.DismissReview(rejectReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.NoError(t, issues_model.DismissReview(requestReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) assert.NoError(t, issues_model.DismissReview(requestReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) assert.NoError(t, issues_model.DismissReview(requestReviewExample, false)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) assert.NoError(t, issues_model.DismissReview(requestReviewExample, false)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) diff --git a/models/issues/stopwatch_test.go b/models/issues/stopwatch_test.go index c0573964d5..a5e33f1cf6 100644 --- a/models/issues/stopwatch_test.go +++ b/models/issues/stopwatch_test.go @@ -70,7 +70,7 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) { assert.NoError(t, err) assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(user3, issue1)) - sw := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: 3, IssueID: 1}).(*issues_model.Stopwatch) + sw := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: 3, IssueID: 1}) assert.LessOrEqual(t, sw.CreatedUnix, timeutil.TimeStampNow()) assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(user2, issue2)) diff --git a/models/issues/tracked_time_test.go b/models/issues/tracked_time_test.go index 787ba9b701..ba8b242d99 100644 --- a/models/issues/tracked_time_test.go +++ b/models/issues/tracked_time_test.go @@ -32,10 +32,10 @@ func TestAddTime(t *testing.T) { assert.Equal(t, int64(1), trackedTime.IssueID) assert.Equal(t, int64(3661), trackedTime.Time) - tt := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 3, IssueID: 1}).(*issues_model.TrackedTime) + tt := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 3, IssueID: 1}) assert.Equal(t, int64(3661), tt.Time) - comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}).(*issues_model.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}) assert.Equal(t, comment.Content, "1 hour 1 minute") } diff --git a/models/migrate_test.go b/models/migrate_test.go index b6525278ec..627fb1ae73 100644 --- a/models/migrate_test.go +++ b/models/migrate_test.go @@ -21,7 +21,7 @@ import ( func TestMigrate_InsertMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) reponame := "repo1" - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}) name := "milestonetest1" ms := &issues_model.Milestone{ RepoID: repo.ID, @@ -30,7 +30,7 @@ func TestMigrate_InsertMilestones(t *testing.T) { err := InsertMilestones(ms) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, ms) - repoModified := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}).(*repo_model.Repository) + repoModified := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}) assert.EqualValues(t, repo.NumMilestones+1, repoModified.NumMilestones) unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) @@ -39,10 +39,10 @@ func TestMigrate_InsertMilestones(t *testing.T) { func assertCreateIssues(t *testing.T, isPull bool) { assert.NoError(t, unittest.PrepareTestDatabase()) reponame := "repo1" - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) assert.EqualValues(t, milestone.ID, 1) reaction := &issues_model.Reaction{ Type: "heart", @@ -72,7 +72,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { err := InsertIssues(is) assert.NoError(t, err) - i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title}).(*issues_model.Issue) + i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title}) assert.Nil(t, i.ForeignReference) err = i.LoadAttributes(db.DefaultContext) assert.NoError(t, err) @@ -90,9 +90,9 @@ func TestMigrate_CreateIssuesIsPullTrue(t *testing.T) { func TestMigrate_InsertIssueComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) _ = issue.LoadRepo(db.DefaultContext) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}) reaction := &issues_model.Reaction{ Type: "heart", UserID: owner.ID, @@ -109,7 +109,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) { err := InsertIssueComments([]*issues_model.Comment{comment}) assert.NoError(t, err) - issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) assert.EqualValues(t, issue.NumComments+1, issueModified.NumComments) unittest.CheckConsistencyFor(t, &issues_model.Issue{}) @@ -118,8 +118,8 @@ func TestMigrate_InsertIssueComments(t *testing.T) { func TestMigrate_InsertPullRequests(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) reponame := "repo1" - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) i := &issues_model.Issue{ RepoID: repo.ID, @@ -138,7 +138,7 @@ func TestMigrate_InsertPullRequests(t *testing.T) { err := InsertPullRequests(p) assert.NoError(t, err) - _ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID}).(*issues_model.PullRequest) + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID}) unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.PullRequest{}) } diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 2719f45efb..30c4ad250c 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -406,6 +406,8 @@ var migrations = []Migration{ NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn), // v223 -> v224 NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes), + // v224 -> v225 + NewMigration("Add badges to users", creatUserBadgesTable), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v224.go b/models/migrations/v224.go new file mode 100644 index 0000000000..d684d538df --- /dev/null +++ b/models/migrations/v224.go @@ -0,0 +1,28 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "xorm.io/xorm" +) + +func creatUserBadgesTable(x *xorm.Engine) error { + type Badge struct { + ID int64 `xorm:"pk autoincr"` + Description string + ImageURL string + } + + type userBadge struct { + ID int64 `xorm:"pk autoincr"` + BadgeID int64 + UserID int64 `xorm:"INDEX"` + } + + if err := x.Sync2(new(Badge)); err != nil { + return err + } + return x.Sync2(new(userBadge)) +} diff --git a/models/notification_test.go b/models/notification_test.go index 16ff02d6c0..340fb4337a 100644 --- a/models/notification_test.go +++ b/models/notification_test.go @@ -17,22 +17,22 @@ import ( func TestCreateOrUpdateIssueNotifications(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) assert.NoError(t, CreateOrUpdateIssueNotifications(issue.ID, 0, 2, 0)) // User 9 is inactive, thus notifications for user 1 and 4 are created - notf := unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID}).(*Notification) + notf := unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID}) assert.Equal(t, NotificationStatusUnread, notf.Status) unittest.CheckConsistencyFor(t, &issues_model.Issue{ID: issue.ID}) - notf = unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID}).(*Notification) + notf = unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID}) assert.Equal(t, NotificationStatusUnread, notf.Status) } func TestNotificationsForUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) statuses := []NotificationStatus{NotificationStatusRead, NotificationStatusUnread} notfs, err := NotificationsForUser(db.DefaultContext, user, statuses, 1, 10) assert.NoError(t, err) @@ -48,7 +48,7 @@ func TestNotificationsForUser(t *testing.T) { func TestNotification_GetRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}).(*Notification) + notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}) repo, err := notf.GetRepo() assert.NoError(t, err) assert.Equal(t, repo, notf.Repository) @@ -57,7 +57,7 @@ func TestNotification_GetRepo(t *testing.T) { func TestNotification_GetIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}).(*Notification) + notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}) issue, err := notf.GetIssue() assert.NoError(t, err) assert.Equal(t, issue, notf.Issue) @@ -66,7 +66,7 @@ func TestNotification_GetIssue(t *testing.T) { func TestGetNotificationCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) cnt, err := GetNotificationCount(db.DefaultContext, user, NotificationStatusRead) assert.NoError(t, err) assert.EqualValues(t, 0, cnt) @@ -78,9 +78,9 @@ func TestGetNotificationCount(t *testing.T) { func TestSetNotificationStatus(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) notf := unittest.AssertExistsAndLoadBean(t, - &Notification{UserID: user.ID, Status: NotificationStatusRead}).(*Notification) + &Notification{UserID: user.ID, Status: NotificationStatusRead}) _, err := SetNotificationStatus(notf.ID, user, NotificationStatusPinned) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, @@ -94,13 +94,13 @@ func TestSetNotificationStatus(t *testing.T) { func TestUpdateNotificationStatuses(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) notfUnread := unittest.AssertExistsAndLoadBean(t, - &Notification{UserID: user.ID, Status: NotificationStatusUnread}).(*Notification) + &Notification{UserID: user.ID, Status: NotificationStatusUnread}) notfRead := unittest.AssertExistsAndLoadBean(t, - &Notification{UserID: user.ID, Status: NotificationStatusRead}).(*Notification) + &Notification{UserID: user.ID, Status: NotificationStatusRead}) notfPinned := unittest.AssertExistsAndLoadBean(t, - &Notification{UserID: user.ID, Status: NotificationStatusPinned}).(*Notification) + &Notification{UserID: user.ID, Status: NotificationStatusPinned}) assert.NoError(t, UpdateNotificationStatuses(user, NotificationStatusUnread, NotificationStatusRead)) unittest.AssertExistsAndLoadBean(t, &Notification{ID: notfUnread.ID, Status: NotificationStatusRead}) diff --git a/models/org_team_test.go b/models/org_team_test.go index 35ee9af85a..a0de6d73f1 100644 --- a/models/org_team_test.go +++ b/models/org_team_test.go @@ -23,7 +23,7 @@ func TestTeam_AddMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(teamID, userID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, AddTeamMember(team, userID)) unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID}) @@ -37,7 +37,7 @@ func TestTeam_RemoveMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(teamID, userID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, RemoveTeamMember(team, userID)) unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}) @@ -47,7 +47,7 @@ func TestTeam_RemoveMember(t *testing.T) { testSuccess(3, 2) testSuccess(3, unittest.NonexistentID) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) err := RemoveTeamMember(team, 2) assert.True(t, organization.IsErrLastOrgOwner(err)) } @@ -56,7 +56,7 @@ func TestTeam_HasRepository(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(teamID, repoID int64, expected bool) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.Equal(t, expected, HasRepository(team, repoID)) } test(1, 1, false) @@ -72,8 +72,8 @@ func TestTeam_AddRepository(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(teamID, repoID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) assert.NoError(t, AddRepository(team, repo)) unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID}) @@ -81,8 +81,8 @@ func TestTeam_AddRepository(t *testing.T) { testSuccess(2, 3) testSuccess(2, 5) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.Error(t, AddRepository(team, repo)) unittest.CheckConsistencyFor(t, &organization.Team{ID: 1}, &repo_model.Repository{ID: 1}) } @@ -91,7 +91,7 @@ func TestTeam_RemoveRepository(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(teamID, repoID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, RemoveRepository(team, repoID)) unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID}) @@ -120,17 +120,17 @@ func TestUpdateTeam(t *testing.T) { // successful update assert.NoError(t, unittest.PrepareTestDatabase()) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) team.LowerName = "newname" team.Name = "newName" team.Description = strings.Repeat("A long description!", 100) team.AccessMode = perm.AccessModeAdmin assert.NoError(t, UpdateTeam(team, true, false)) - team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"}).(*organization.Team) + team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"}) assert.True(t, strings.HasPrefix(team.Description, "A long description!")) - access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3}).(*access_model.Access) + access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3}) assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}) @@ -140,7 +140,7 @@ func TestUpdateTeam2(t *testing.T) { // update to already-existing team assert.NoError(t, unittest.PrepareTestDatabase()) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) team.LowerName = "owners" team.Name = "Owners" team.Description = strings.Repeat("A long description!", 100) @@ -153,15 +153,15 @@ func TestUpdateTeam2(t *testing.T) { func TestDeleteTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) assert.NoError(t, DeleteTeam(team)) unittest.AssertNotExistsBean(t, &organization.Team{ID: team.ID}) unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: team.ID}) unittest.AssertNotExistsBean(t, &organization.TeamUser{TeamID: team.ID}) // check that team members don't have "leftover" access to repos - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) accessMode, err := access_model.AccessLevel(user, repo) assert.NoError(t, err) assert.True(t, accessMode < perm.AccessModeWrite) @@ -171,7 +171,7 @@ func TestAddTeamMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(teamID, userID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, AddTeamMember(team, userID)) unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID}) @@ -185,7 +185,7 @@ func TestRemoveTeamMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(teamID, userID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, RemoveTeamMember(team, userID)) unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}) @@ -195,15 +195,15 @@ func TestRemoveTeamMember(t *testing.T) { testSuccess(3, 2) testSuccess(3, unittest.NonexistentID) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) err := RemoveTeamMember(team, 2) assert.True(t, organization.IsErrLastOrgOwner(err)) } func TestRepository_RecalculateAccesses3(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - team5 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team) - user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}).(*user_model.User) + team5 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}) + user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}) has, err := db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 29, RepoID: 23}) assert.NoError(t, err) diff --git a/models/org_test.go b/models/org_test.go index af11bed280..23b417119e 100644 --- a/models/org_test.go +++ b/models/org_test.go @@ -16,14 +16,14 @@ import ( func TestUser_RemoveMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) // remove a user that is a member unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{UID: 4, OrgID: 3}) prevNumMembers := org.NumMembers assert.NoError(t, RemoveOrgUser(org.ID, 4)) unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: 4, OrgID: 3}) - org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) assert.Equal(t, prevNumMembers-1, org.NumMembers) // remove a user that is not a member @@ -31,7 +31,7 @@ func TestUser_RemoveMember(t *testing.T) { prevNumMembers = org.NumMembers assert.NoError(t, RemoveOrgUser(org.ID, 5)) unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: 5, OrgID: 3}) - org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) assert.Equal(t, prevNumMembers, org.NumMembers) unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{}) @@ -40,14 +40,14 @@ func TestUser_RemoveMember(t *testing.T) { func TestRemoveOrgUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(orgID, userID int64) { - org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}).(*user_model.User) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}) expectedNumMembers := org.NumMembers if unittest.BeanExists(t, &organization.OrgUser{OrgID: orgID, UID: userID}) { expectedNumMembers-- } assert.NoError(t, RemoveOrgUser(orgID, userID)) unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: orgID, UID: userID}) - org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}).(*user_model.User) + org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}) assert.EqualValues(t, expectedNumMembers, org.NumMembers) } testSuccess(3, 4) diff --git a/models/organization/org_test.go b/models/organization/org_test.go index 3a135498a3..0fba6e2592 100644 --- a/models/organization/org_test.go +++ b/models/organization/org_test.go @@ -31,7 +31,7 @@ func TestUser_IsOwnedBy(t *testing.T) { {2, 2, false}, // user2 is not an organization {2, 3, false}, } { - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID}) isOwner, err := org.IsOwnedBy(testCase.UserID) assert.NoError(t, err) assert.Equal(t, testCase.ExpectedOwner, isOwner) @@ -52,7 +52,7 @@ func TestUser_IsOrgMember(t *testing.T) { {2, 2, false}, // user2 is not an organization {2, 3, false}, } { - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID}) isMember, err := org.IsOrgMember(testCase.UserID) assert.NoError(t, err) assert.Equal(t, testCase.ExpectedMember, isMember) @@ -61,7 +61,7 @@ func TestUser_IsOrgMember(t *testing.T) { func TestUser_GetTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) team, err := org.GetTeam("team1") assert.NoError(t, err) assert.Equal(t, org.ID, team.OrgID) @@ -70,26 +70,26 @@ func TestUser_GetTeam(t *testing.T) { _, err = org.GetTeam("does not exist") assert.True(t, organization.IsErrTeamNotExist(err)) - nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2}).(*organization.Organization) + nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2}) _, err = nonOrg.GetTeam("team") assert.True(t, organization.IsErrTeamNotExist(err)) } func TestUser_GetOwnerTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) team, err := org.GetOwnerTeam() assert.NoError(t, err) assert.Equal(t, org.ID, team.OrgID) - nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2}).(*organization.Organization) + nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2}) _, err = nonOrg.GetOwnerTeam() assert.True(t, organization.IsErrTeamNotExist(err)) } func TestUser_GetTeams(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) teams, err := org.LoadTeams() assert.NoError(t, err) if assert.Len(t, teams, 4) { @@ -102,7 +102,7 @@ func TestUser_GetTeams(t *testing.T) { func TestUser_GetMembers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) members, _, err := org.GetMembers() assert.NoError(t, err) if assert.Len(t, members, 3) { @@ -275,7 +275,7 @@ func TestChangeOrgUserStatus(t *testing.T) { testSuccess := func(orgID, userID int64, public bool) { assert.NoError(t, organization.ChangeOrgUserStatus(orgID, userID, public)) - orgUser := unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{OrgID: orgID, UID: userID}).(*organization.OrgUser) + orgUser := unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{OrgID: orgID, UID: userID}) assert.Equal(t, public, orgUser.IsPublic) } @@ -287,7 +287,7 @@ func TestChangeOrgUserStatus(t *testing.T) { func TestUser_GetUserTeamIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expected []int64) { teamIDs, err := org.GetUserTeamIDs(userID) assert.NoError(t, err) @@ -300,7 +300,7 @@ func TestUser_GetUserTeamIDs(t *testing.T) { func TestAccessibleReposEnv_CountRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID, expectedCount int64) { env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) @@ -314,7 +314,7 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) { func TestAccessibleReposEnv_RepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID, _, pageSize int64, expectedRepoIDs []int64) { env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) @@ -328,7 +328,7 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) { func TestAccessibleReposEnv_Repos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expectedRepoIDs []int64) { env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) @@ -337,7 +337,7 @@ func TestAccessibleReposEnv_Repos(t *testing.T) { expectedRepos := make([]*repo_model.Repository, len(expectedRepoIDs)) for i, repoID := range expectedRepoIDs { expectedRepos[i] = unittest.AssertExistsAndLoadBean(t, - &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + &repo_model.Repository{ID: repoID}) } assert.Equal(t, expectedRepos, repos) } @@ -347,7 +347,7 @@ func TestAccessibleReposEnv_Repos(t *testing.T) { func TestAccessibleReposEnv_MirrorRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expectedRepoIDs []int64) { env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) @@ -356,7 +356,7 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) { expectedRepos := make([]*repo_model.Repository, len(expectedRepoIDs)) for i, repoID := range expectedRepoIDs { expectedRepos[i] = unittest.AssertExistsAndLoadBean(t, - &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + &repo_model.Repository{ID: repoID}) } assert.Equal(t, expectedRepos, repos) } @@ -366,8 +366,8 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) { func TestHasOrgVisibleTypePublic(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) const newOrgName = "test-org-public" org := &organization.Organization{ @@ -378,7 +378,7 @@ func TestHasOrgVisibleTypePublic(t *testing.T) { unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization}) assert.NoError(t, organization.CreateOrganization(org, owner)) org = unittest.AssertExistsAndLoadBean(t, - &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}).(*organization.Organization) + &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}) test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner) test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), user3) test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil) @@ -389,8 +389,8 @@ func TestHasOrgVisibleTypePublic(t *testing.T) { func TestHasOrgVisibleTypeLimited(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) const newOrgName = "test-org-limited" org := &organization.Organization{ @@ -401,7 +401,7 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) { unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization}) assert.NoError(t, organization.CreateOrganization(org, owner)) org = unittest.AssertExistsAndLoadBean(t, - &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}).(*organization.Organization) + &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}) test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner) test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), user3) test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil) @@ -412,8 +412,8 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) { func TestHasOrgVisibleTypePrivate(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) const newOrgName = "test-org-private" org := &organization.Organization{ @@ -424,7 +424,7 @@ func TestHasOrgVisibleTypePrivate(t *testing.T) { unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization}) assert.NoError(t, organization.CreateOrganization(org, owner)) org = unittest.AssertExistsAndLoadBean(t, - &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}).(*organization.Organization) + &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}) test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner) test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), user3) test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil) @@ -453,8 +453,8 @@ func TestGetUsersWhoCanCreateOrgRepo(t *testing.T) { func TestUser_RemoveOrgRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: org.ID}).(*repo_model.Repository) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: org.ID}) // remove a repo that does belong to org unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{RepoID: repo.ID, OrgID: org.ID}) @@ -478,7 +478,7 @@ func TestCreateOrganization(t *testing.T) { // successful creation of org assert.NoError(t, unittest.PrepareTestDatabase()) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) const newOrgName = "neworg" org := &organization.Organization{ Name: newOrgName, @@ -487,9 +487,9 @@ func TestCreateOrganization(t *testing.T) { unittest.AssertNotExistsBean(t, &user_model.User{Name: newOrgName, Type: user_model.UserTypeOrganization}) assert.NoError(t, organization.CreateOrganization(org, owner)) org = unittest.AssertExistsAndLoadBean(t, - &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization}).(*organization.Organization) + &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization}) ownerTeam := unittest.AssertExistsAndLoadBean(t, - &organization.Team{Name: organization.OwnerTeamName, OrgID: org.ID}).(*organization.Team) + &organization.Team{Name: organization.OwnerTeamName, OrgID: org.ID}) unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: owner.ID, TeamID: ownerTeam.ID}) unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{}) } @@ -498,7 +498,7 @@ func TestCreateOrganization2(t *testing.T) { // unauthorized creation of org assert.NoError(t, unittest.PrepareTestDatabase()) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) const newOrgName = "neworg" org := &organization.Organization{ Name: newOrgName, @@ -516,7 +516,7 @@ func TestCreateOrganization3(t *testing.T) { // create org with same name as existent org assert.NoError(t, unittest.PrepareTestDatabase()) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) org := &organization.Organization{Name: "user3"} // should already exist unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: org.Name}) // sanity check err := organization.CreateOrganization(org, owner) @@ -529,7 +529,7 @@ func TestCreateOrganization4(t *testing.T) { // create org with unusable name assert.NoError(t, unittest.PrepareTestDatabase()) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) err := organization.CreateOrganization(&organization.Organization{Name: "assets"}, owner) assert.Error(t, err) assert.True(t, db.IsErrNameReserved(err)) diff --git a/models/organization/org_user_test.go b/models/organization/org_user_test.go index 22ee5217f9..aed3ea23cf 100644 --- a/models/organization/org_user_test.go +++ b/models/organization/org_user_test.go @@ -130,7 +130,7 @@ func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bo func TestAddOrgUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(orgID, userID int64, isPublic bool) { - org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}).(*user_model.User) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}) expectedNumMembers := org.NumMembers if !unittest.BeanExists(t, &organization.OrgUser{OrgID: orgID, UID: userID}) { expectedNumMembers++ @@ -139,7 +139,7 @@ func TestAddOrgUser(t *testing.T) { ou := &organization.OrgUser{OrgID: orgID, UID: userID} unittest.AssertExistsAndLoadBean(t, ou) assert.Equal(t, isPublic, ou.IsPublic) - org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}).(*user_model.User) + org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}) assert.EqualValues(t, expectedNumMembers, org.NumMembers) } diff --git a/models/organization/team_test.go b/models/organization/team_test.go index 829c440c29..c8d58a0eb7 100644 --- a/models/organization/team_test.go +++ b/models/organization/team_test.go @@ -17,22 +17,22 @@ import ( func TestTeam_IsOwnerTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) assert.True(t, team.IsOwnerTeam()) - team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team) + team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) assert.False(t, team.IsOwnerTeam()) } func TestTeam_IsMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) assert.True(t, team.IsMember(2)) assert.False(t, team.IsMember(4)) assert.False(t, team.IsMember(unittest.NonexistentID)) - team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team) + team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) assert.True(t, team.IsMember(2)) assert.True(t, team.IsMember(4)) assert.False(t, team.IsMember(unittest.NonexistentID)) @@ -42,7 +42,7 @@ func TestTeam_GetRepositories(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(teamID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, team.GetRepositoriesCtx(db.DefaultContext)) assert.Len(t, team.Repos, team.NumRepos) for _, repo := range team.Repos { @@ -57,7 +57,7 @@ func TestTeam_GetMembers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(teamID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, team.GetMembersCtx(db.DefaultContext)) assert.Len(t, team.Members, team.NumMembers) for _, member := range team.Members { @@ -126,7 +126,7 @@ func TestGetTeamMembers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(teamID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) members, err := organization.GetTeamMembers(db.DefaultContext, &organization.SearchMembersOptions{ TeamID: teamID, }) @@ -173,7 +173,7 @@ func TestHasTeamRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(teamID, repoID int64, expected bool) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.Equal(t, expected, organization.HasTeamRepo(db.DefaultContext, team.OrgID, teamID, repoID)) } test(1, 1, false) diff --git a/models/perm/access/access_test.go b/models/perm/access/access_test.go index a5e0448d3d..8e75792e0c 100644 --- a/models/perm/access/access_test.go +++ b/models/perm/access/access_test.go @@ -23,21 +23,21 @@ import ( func TestAccessLevel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) - user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) + user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}) // A public repository owned by User 2 - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.False(t, repo1.IsPrivate) // A private repository owned by Org 3 - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) assert.True(t, repo3.IsPrivate) // Another public repository - repo4 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) + repo4 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) assert.False(t, repo4.IsPrivate) // org. owned private repo - repo24 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}).(*repo_model.Repository) + repo24 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}) level, err := access_model.AccessLevel(user2, repo1) assert.NoError(t, err) @@ -74,13 +74,13 @@ func TestAccessLevel(t *testing.T) { func TestHasAccess(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) // A public repository owned by User 2 - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.False(t, repo1.IsPrivate) // A private repository owned by Org 3 - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) assert.True(t, repo2.IsPrivate) has, err := access_model.HasAccess(db.DefaultContext, user1.ID, repo1) @@ -100,7 +100,7 @@ func TestHasAccess(t *testing.T) { func TestRepository_RecalculateAccesses(t *testing.T) { // test with organization repo assert.NoError(t, unittest.PrepareTestDatabase()) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) assert.NoError(t, repo1.GetOwner(db.DefaultContext)) _, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 2, RepoID: 3}) @@ -117,7 +117,7 @@ func TestRepository_RecalculateAccesses(t *testing.T) { func TestRepository_RecalculateAccesses2(t *testing.T) { // test with non-organization repo assert.NoError(t, unittest.PrepareTestDatabase()) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) assert.NoError(t, repo1.GetOwner(db.DefaultContext)) _, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 4, RepoID: 4}) @@ -133,11 +133,11 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // public non-organization repo - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) assert.NoError(t, repo.LoadUnits(db.DefaultContext)) // plain user - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) assert.NoError(t, err) for _, unit := range repo.Units { @@ -155,7 +155,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { } // collaborator - collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) + collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, collaborator) assert.NoError(t, err) for _, unit := range repo.Units { @@ -164,7 +164,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { } // owner - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) assert.NoError(t, err) for _, unit := range repo.Units { @@ -173,7 +173,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { } // admin - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) assert.NoError(t, err) for _, unit := range repo.Units { @@ -186,11 +186,11 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // private non-organization repo - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) assert.NoError(t, repo.LoadUnits(db.DefaultContext)) // plain user - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) assert.NoError(t, err) for _, unit := range repo.Units { @@ -216,7 +216,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { } // owner - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) assert.NoError(t, err) for _, unit := range repo.Units { @@ -225,7 +225,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { } // admin - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) assert.NoError(t, err) for _, unit := range repo.Units { @@ -238,11 +238,11 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // public organization repo - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}) assert.NoError(t, repo.LoadUnits(db.DefaultContext)) // plain user - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) assert.NoError(t, err) for _, unit := range repo.Units { @@ -268,7 +268,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { } // org member team owner - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) assert.NoError(t, err) for _, unit := range repo.Units { @@ -277,7 +277,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { } // org member team tester - member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User) + member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, member) assert.NoError(t, err) for _, unit := range repo.Units { @@ -287,7 +287,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { assert.False(t, perm.CanWrite(unit.TypeCode)) // admin - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) assert.NoError(t, err) for _, unit := range repo.Units { @@ -300,11 +300,11 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // private organization repo - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}) assert.NoError(t, repo.LoadUnits(db.DefaultContext)) // plain user - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) assert.NoError(t, err) for _, unit := range repo.Units { @@ -330,7 +330,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { } // org member team owner - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) assert.NoError(t, err) for _, unit := range repo.Units { @@ -339,7 +339,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { } // update team information and then check permission - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}) err = organization.UpdateTeamUnits(team, nil) assert.NoError(t, err) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) @@ -350,7 +350,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { } // org member team tester - tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, tester) assert.NoError(t, err) assert.True(t, perm.CanWrite(unit.TypeIssues)) @@ -358,7 +358,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { assert.False(t, perm.CanRead(unit.TypeCode)) // org member team reviewer - reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}).(*user_model.User) + reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, reviewer) assert.NoError(t, err) assert.False(t, perm.CanRead(unit.TypeIssues)) @@ -366,7 +366,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { assert.True(t, perm.CanRead(unit.TypeCode)) // admin - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) assert.NoError(t, err) for _, unit := range repo.Units { diff --git a/models/repo/attachment.go b/models/repo/attachment.go index ddddac2c3d..afec78a425 100644 --- a/models/repo/attachment.go +++ b/models/repo/attachment.go @@ -226,28 +226,6 @@ func DeleteAttachmentsByRelease(releaseID int64) error { return err } -// IterateAttachment iterates attachments; it should not be used when Gitea is servicing users. -func IterateAttachment(f func(attach *Attachment) error) error { - var start int - const batchSize = 100 - for { - attachments := make([]*Attachment, 0, batchSize) - if err := db.GetEngine(db.DefaultContext).Limit(batchSize, start).Find(&attachments); err != nil { - return err - } - if len(attachments) == 0 { - return nil - } - start += len(attachments) - - for _, attach := range attachments { - if err := f(attach); err != nil { - return err - } - } - } -} - // CountOrphanedAttachments returns the number of bad attachments func CountOrphanedAttachments() (int64, error) { return db.GetEngine(db.DefaultContext).Where("(issue_id > 0 and issue_id not in (select id from issue)) or (release_id > 0 and release_id not in (select id from `release`))"). diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go index 2e6253d561..cbf46dd286 100644 --- a/models/repo/collaboration_test.go +++ b/models/repo/collaboration_test.go @@ -19,7 +19,7 @@ import ( func TestRepository_GetCollaborators(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) collaborators, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{}) assert.NoError(t, err) expectedLen, err := db.GetEngine(db.DefaultContext).Count(&repo_model.Collaboration{RepoID: repoID}) @@ -40,7 +40,7 @@ func TestRepository_IsCollaborator(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID, userID int64, expected bool) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) actual, err := repo_model.IsCollaborator(db.DefaultContext, repo.ID, userID) assert.NoError(t, err) assert.Equal(t, expected, actual) @@ -54,13 +54,13 @@ func TestRepository_IsCollaborator(t *testing.T) { func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin)) - collaboration := unittest.AssertExistsAndLoadBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}).(*repo_model.Collaboration) + collaboration := unittest.AssertExistsAndLoadBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}) assert.EqualValues(t, perm.AccessModeAdmin, collaboration.Mode) - access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: repo.ID}).(*access_model.Access) + access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: repo.ID}) assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin)) diff --git a/models/repo/mirror.go b/models/repo/mirror.go index 8f96e8cee1..297ffd594a 100644 --- a/models/repo/mirror.go +++ b/models/repo/mirror.go @@ -8,7 +8,6 @@ package repo import ( "context" "errors" - "fmt" "time" "code.gitea.io/gitea/models/db" @@ -108,12 +107,14 @@ func DeleteMirrorByRepoID(repoID int64) error { // MirrorsIterate iterates all mirror repositories. func MirrorsIterate(limit int, f func(idx int, bean interface{}) error) error { - return db.GetEngine(db.DefaultContext). + sess := db.GetEngine(db.DefaultContext). Where("next_update_unix<=?", time.Now().Unix()). And("next_update_unix!=0"). - OrderBy("updated_unix ASC"). - Limit(limit). - Iterate(new(Mirror), f) + OrderBy("updated_unix ASC") + if limit > 0 { + sess = sess.Limit(limit) + } + return sess.Iterate(new(Mirror), f) } // InsertMirror inserts a mirror to database @@ -121,53 +122,3 @@ func InsertMirror(ctx context.Context, mirror *Mirror) error { _, err := db.GetEngine(ctx).Insert(mirror) return err } - -// MirrorRepositoryList contains the mirror repositories -type MirrorRepositoryList []*Repository - -func (repos MirrorRepositoryList) loadAttributes(ctx context.Context) error { - if len(repos) == 0 { - return nil - } - - // Load mirrors. - repoIDs := make([]int64, 0, len(repos)) - for i := range repos { - if !repos[i].IsMirror { - continue - } - - repoIDs = append(repoIDs, repos[i].ID) - } - mirrors := make([]*Mirror, 0, len(repoIDs)) - if err := db.GetEngine(ctx). - Where("id > 0"). - In("repo_id", repoIDs). - Find(&mirrors); err != nil { - return fmt.Errorf("find mirrors: %v", err) - } - - set := make(map[int64]*Mirror) - for i := range mirrors { - set[mirrors[i].RepoID] = mirrors[i] - } - for i := range repos { - repos[i].Mirror = set[repos[i].ID] - repos[i].Mirror.Repo = repos[i] - } - return nil -} - -// LoadAttributes loads the attributes for the given MirrorRepositoryList -func (repos MirrorRepositoryList) LoadAttributes() error { - return repos.loadAttributes(db.DefaultContext) -} - -// GetUserMirrorRepositories returns a list of mirror repositories of given user. -func GetUserMirrorRepositories(userID int64) ([]*Repository, error) { - repos := make([]*Repository, 0, 10) - return repos, db.GetEngine(db.DefaultContext). - Where("owner_id = ?", userID). - And("is_mirror = ?", true). - Find(&repos) -} diff --git a/models/repo/pushmirror.go b/models/repo/pushmirror.go index 02ffcbee76..38d6e72019 100644 --- a/models/repo/pushmirror.go +++ b/models/repo/pushmirror.go @@ -129,10 +129,12 @@ func GetPushMirrorsSyncedOnCommit(repoID int64) ([]*PushMirror, error) { // PushMirrorsIterate iterates all push-mirror repositories. func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean interface{}) error) error { - return db.GetEngine(ctx). + sess := db.GetEngine(ctx). Where("last_update + (`interval` / ?) <= ?", time.Second, time.Now().Unix()). And("`interval` != 0"). - OrderBy("last_update ASC"). - Limit(limit). - Iterate(new(PushMirror), f) + OrderBy("last_update ASC") + if limit > 0 { + sess = sess.Limit(limit) + } + return sess.Iterate(new(PushMirror), f) } diff --git a/models/repo/redirect_test.go b/models/repo/redirect_test.go index 05b105cf63..90114667e5 100644 --- a/models/repo/redirect_test.go +++ b/models/repo/redirect_test.go @@ -29,7 +29,7 @@ func TestNewRedirect(t *testing.T) { // redirect to a completely new name assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame")) unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{ @@ -48,7 +48,7 @@ func TestNewRedirect2(t *testing.T) { // redirect to previously used name assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "oldrepo1")) unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{ @@ -67,7 +67,7 @@ func TestNewRedirect3(t *testing.T) { // redirect for a previously-unredirected repo assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame")) unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{ diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index 9de76fa5ff..1fa469fcfe 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -15,36 +15,12 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) -// IterateRepository iterate repositories -func IterateRepository(f func(repo *Repository) error) error { - var start int - batchSize := setting.Database.IterateBufferSize - sess := db.GetEngine(db.DefaultContext) - for { - repos := make([]*Repository, 0, batchSize) - if err := sess.Limit(batchSize, start).Find(&repos); err != nil { - return err - } - if len(repos) == 0 { - return nil - } - start += len(repos) - - for _, repo := range repos { - if err := f(repo); err != nil { - return err - } - } - } -} - // FindReposMapByIDs find repos as map func FindReposMapByIDs(repoIDs []int64, res map[int64]*Repository) error { return db.GetEngine(db.DefaultContext).In("id", repoIDs).Find(&res) diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go index 6f8b282a66..617ec12798 100644 --- a/models/repo/repo_test.go +++ b/models/repo/repo_test.go @@ -56,7 +56,7 @@ func TestGetPrivateRepositoryCount(t *testing.T) { func TestRepoAPIURL(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL()) } diff --git a/models/repo/star_test.go b/models/repo/star_test.go index aa72b1dac8..1b53e17d27 100644 --- a/models/repo/star_test.go +++ b/models/repo/star_test.go @@ -36,7 +36,7 @@ func TestIsStaring(t *testing.T) { func TestRepository_GetStargazers(t *testing.T) { // repo with stargazers assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) gazers, err := repo_model.GetStargazers(repo, db.ListOptions{Page: 0}) assert.NoError(t, err) if assert.Len(t, gazers, 1) { @@ -47,7 +47,7 @@ func TestRepository_GetStargazers(t *testing.T) { func TestRepository_GetStargazers2(t *testing.T) { // repo with stargazers assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) gazers, err := repo_model.GetStargazers(repo, db.ListOptions{Page: 0}) assert.NoError(t, err) assert.Len(t, gazers, 0) diff --git a/models/repo/user_repo_test.go b/models/repo/user_repo_test.go index d024729b9c..6409145920 100644 --- a/models/repo/user_repo_test.go +++ b/models/repo/user_repo_test.go @@ -17,13 +17,13 @@ import ( func TestRepoAssignees(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) users, err := repo_model.GetRepoAssignees(db.DefaultContext, repo2) assert.NoError(t, err) assert.Len(t, users, 1) assert.Equal(t, users[0].ID, int64(2)) - repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21}).(*repo_model.Repository) + repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21}) users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21) assert.NoError(t, err) assert.Len(t, users, 3) @@ -36,7 +36,7 @@ func TestRepoGetReviewers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // test public repo - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) ctx := db.DefaultContext reviewers, err := repo_model.GetReviewers(ctx, repo1, 2, 2) @@ -54,7 +54,7 @@ func TestRepoGetReviewers(t *testing.T) { assert.Len(t, reviewers, 3) // test private user repo - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) reviewers, err = repo_model.GetReviewers(ctx, repo2, 2, 4) assert.NoError(t, err) @@ -62,7 +62,7 @@ func TestRepoGetReviewers(t *testing.T) { assert.EqualValues(t, reviewers[0].ID, 2) // test private org repo - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) reviewers, err = repo_model.GetReviewers(ctx, repo3, 2, 1) assert.NoError(t, err) diff --git a/models/repo/watch_test.go b/models/repo/watch_test.go index 3875e63fd8..18a2d5d5fd 100644 --- a/models/repo/watch_test.go +++ b/models/repo/watch_test.go @@ -30,7 +30,7 @@ func TestIsWatching(t *testing.T) { func TestGetWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) watches, err := repo_model.GetWatchers(db.DefaultContext, repo.ID) assert.NoError(t, err) // One watchers are inactive, thus minus 1 @@ -47,7 +47,7 @@ func TestGetWatchers(t *testing.T) { func TestRepository_GetWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) watchers, err := repo_model.GetRepoWatchers(repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, repo.NumWatches) @@ -55,7 +55,7 @@ func TestRepository_GetWatchers(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: watcher.ID, RepoID: repo.ID}) } - repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 9}).(*repo_model.Repository) + repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 9}) watchers, err = repo_model.GetRepoWatchers(repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, 0) @@ -64,7 +64,7 @@ func TestRepository_GetWatchers(t *testing.T) { func TestWatchIfAuto(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) watchers, err := repo_model.GetRepoWatchers(repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, repo.NumWatches) diff --git a/models/repo/wiki_test.go b/models/repo/wiki_test.go index 339289e05d..8631736276 100644 --- a/models/repo/wiki_test.go +++ b/models/repo/wiki_test.go @@ -18,7 +18,7 @@ import ( func TestRepository_WikiCloneLink(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) cloneLink := repo.WikiCloneLink() assert.Equal(t, "ssh://sshuser@try.gitea.io:3000/user2/repo1.wiki.git", cloneLink.SSH) assert.Equal(t, "https://try.gitea.io/user2/repo1.wiki.git", cloneLink.HTTPS) @@ -32,15 +32,15 @@ func TestWikiPath(t *testing.T) { func TestRepository_WikiPath(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) expected := filepath.Join(setting.RepoRootPath, "user2/repo1.wiki.git") assert.Equal(t, expected, repo.WikiPath()) } func TestRepository_HasWiki(t *testing.T) { unittest.PrepareTestEnv(t) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.True(t, repo1.HasWiki()) - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) assert.False(t, repo2.HasWiki()) } diff --git a/models/repo_collaboration_test.go b/models/repo_collaboration_test.go index 4cf4d61218..72b354f1a5 100644 --- a/models/repo_collaboration_test.go +++ b/models/repo_collaboration_test.go @@ -19,9 +19,9 @@ func TestRepository_AddCollaborator(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(repoID, userID int64) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) assert.NoError(t, repo.GetOwner(db.DefaultContext)) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) assert.NoError(t, AddCollaborator(repo, user)) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID}) } @@ -33,7 +33,7 @@ func TestRepository_AddCollaborator(t *testing.T) { func TestRepository_DeleteCollaboration(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) assert.NoError(t, repo.GetOwner(db.DefaultContext)) assert.NoError(t, DeleteCollaboration(repo, 4)) unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}) diff --git a/models/repo_transfer_test.go b/models/repo_transfer_test.go index 9125bb8c8d..7904b04e98 100644 --- a/models/repo_transfer_test.go +++ b/models/repo_transfer_test.go @@ -17,8 +17,8 @@ import ( func TestRepositoryTransfer(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) transfer, err := GetPendingRepositoryTransfer(repo) assert.NoError(t, err) @@ -32,7 +32,7 @@ func TestRepositoryTransfer(t *testing.T) { assert.Nil(t, transfer) assert.True(t, IsErrNoPendingTransfer(err)) - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) assert.NoError(t, CreatePendingRepositoryTransfer(doer, user2, repo.ID, nil)) @@ -41,7 +41,7 @@ func TestRepositoryTransfer(t *testing.T) { assert.NoError(t, transfer.LoadAttributes()) assert.Equal(t, "user2", transfer.Recipient.Name) - user6 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user6 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Only transfer can be started at any given time err = CreatePendingRepositoryTransfer(doer, user6, repo.ID, nil) diff --git a/models/unittest/unit_tests.go b/models/unittest/unit_tests.go index 6c20c2781b..c8673debed 100644 --- a/models/unittest/unit_tests.go +++ b/models/unittest/unit_tests.go @@ -55,7 +55,7 @@ func BeanExists(t assert.TestingT, bean interface{}, conditions ...interface{}) } // AssertExistsAndLoadBean assert that a bean exists and load it from the test database -func AssertExistsAndLoadBean(t assert.TestingT, bean interface{}, conditions ...interface{}) interface{} { +func AssertExistsAndLoadBean[T any](t assert.TestingT, bean T, conditions ...interface{}) T { exists, err := LoadBeanIfExists(bean, conditions...) assert.NoError(t, err) assert.True(t, exists, diff --git a/models/user.go b/models/user.go index 86a714e746..4afbb9bea5 100644 --- a/models/user.go +++ b/models/user.go @@ -85,6 +85,7 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) &organization.TeamUser{UID: u.ID}, &issues_model.Stopwatch{UserID: u.ID}, &user_model.Setting{UserID: u.ID}, + &user_model.UserBadge{UserID: u.ID}, &pull_model.AutoMerge{DoerID: u.ID}, &pull_model.ReviewState{UserID: u.ID}, ); err != nil { diff --git a/models/user/badge.go b/models/user/badge.go new file mode 100644 index 0000000000..5ff840cb8c --- /dev/null +++ b/models/user/badge.go @@ -0,0 +1,42 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package user + +import ( + "context" + + "code.gitea.io/gitea/models/db" +) + +// Badge represents a user badge +type Badge struct { + ID int64 `xorm:"pk autoincr"` + Description string + ImageURL string +} + +// UserBadge represents a user badge +type UserBadge struct { + ID int64 `xorm:"pk autoincr"` + BadgeID int64 + UserID int64 `xorm:"INDEX"` +} + +func init() { + db.RegisterModel(new(Badge)) + db.RegisterModel(new(UserBadge)) +} + +// GetUserBadges returns the user's badges. +func GetUserBadges(ctx context.Context, u *User) ([]*Badge, int64, error) { + sess := db.GetEngine(ctx). + Select("`badge`.*"). + Join("INNER", "user_badge", "`user_badge`.badge_id=badge.id"). + Where("user_badge.user_id=?", u.ID) + + badges := make([]*Badge, 0, 8) + count, err := sess.FindAndCount(&badges) + return badges, count, err +} diff --git a/models/user/search.go b/models/user/search.go index f8e6c89f06..0aa9949367 100644 --- a/models/user/search.go +++ b/models/user/search.go @@ -9,7 +9,6 @@ import ( "strings" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" @@ -125,28 +124,6 @@ func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) { return users, count, sessQuery.Find(&users) } -// IterateUser iterate users -func IterateUser(f func(user *User) error) error { - var start int - batchSize := setting.Database.IterateBufferSize - for { - users := make([]*User, 0, batchSize) - if err := db.GetEngine(db.DefaultContext).Limit(batchSize, start).Find(&users); err != nil { - return err - } - if len(users) == 0 { - return nil - } - start += len(users) - - for _, user := range users { - if err := f(user); err != nil { - return err - } - } - } -} - // BuildCanSeeUserCondition creates a condition which can be used to restrict results to users/orgs the actor can see func BuildCanSeeUserCondition(actor *User) builder.Cond { if actor != nil { diff --git a/models/user/user_test.go b/models/user/user_test.go index 489ee3b05d..940382cdaf 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -22,7 +22,7 @@ import ( func TestOAuth2Application_LoadUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: 1}).(*auth.OAuth2Application) + app := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: 1}) user, err := user_model.GetUserByID(app.UID) assert.NoError(t, err) assert.NotNil(t, user) @@ -41,10 +41,10 @@ func TestGetUserEmailsByNames(t *testing.T) { func TestCanCreateOrganization(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) assert.True(t, admin.CanCreateOrganization()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) assert.True(t, user.CanCreateOrganization()) // Disable user create organization permission. user.AllowCreateOrganization = false @@ -141,7 +141,7 @@ func TestEmailNotificationPreferences(t *testing.T) { {user_model.EmailNotificationsEnabled, 8}, {user_model.EmailNotificationsOnMention, 9}, } { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.userID}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.userID}) assert.Equal(t, test.expected, user.EmailNotifications()) // Try all possible settings @@ -242,7 +242,7 @@ func TestCreateUserInvalidEmail(t *testing.T) { func TestCreateUserEmailAlreadyUsed(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // add new user with user2's email user.Name = "testuser" @@ -288,18 +288,18 @@ func TestGetMaileableUsersByIDs(t *testing.T) { func TestUpdateUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user.KeepActivityPrivate = true assert.NoError(t, user_model.UpdateUser(db.DefaultContext, user, false)) - user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) assert.True(t, user.KeepActivityPrivate) setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, false} user.KeepActivityPrivate = false user.Visibility = structs.VisibleTypePrivate assert.Error(t, user_model.UpdateUser(db.DefaultContext, user, false)) - user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) assert.True(t, user.KeepActivityPrivate) user.Email = "no mail@mail.org" @@ -310,7 +310,7 @@ func TestNewUserRedirect(t *testing.T) { // redirect to a completely new name assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername")) unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{ @@ -327,7 +327,7 @@ func TestNewUserRedirect2(t *testing.T) { // redirect to previously used name assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "olduser1")) unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{ @@ -344,7 +344,7 @@ func TestNewUserRedirect3(t *testing.T) { // redirect for a previously-unredirected user assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername")) unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{ diff --git a/models/user_heatmap_test.go b/models/user_heatmap_test.go index 9361cb3452..1ff7bc6ed2 100644 --- a/models/user_heatmap_test.go +++ b/models/user_heatmap_test.go @@ -63,7 +63,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) { defer timeutil.Unset() for _, tc := range testCases { - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tc.userID}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tc.userID}) doer := &user_model.User{ID: tc.doerID} _, err := unittest.LoadBeanIfExists(doer) diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go index 4bc811586d..1d77ee2a41 100644 --- a/models/webhook/webhook_test.go +++ b/models/webhook/webhook_test.go @@ -31,14 +31,14 @@ func TestIsValidHookContentType(t *testing.T) { func TestWebhook_History(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1}).(*Webhook) + webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1}) tasks, err := webhook.History(0) assert.NoError(t, err) if assert.Len(t, tasks, 1) { assert.Equal(t, int64(1), tasks[0].ID) } - webhook = unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2}).(*Webhook) + webhook = unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2}) tasks, err = webhook.History(0) assert.NoError(t, err) assert.Len(t, tasks, 0) @@ -46,7 +46,7 @@ func TestWebhook_History(t *testing.T) { func TestWebhook_UpdateEvent(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1}).(*Webhook) + webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1}) hookEvent := &HookEvent{ PushOnly: true, SendEverything: false, @@ -162,7 +162,7 @@ func TestGetWebhooksByOrgID(t *testing.T) { func TestUpdateWebhook(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2}).(*Webhook) + hook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2}) hook.IsActive = true hook.ContentType = ContentTypeForm unittest.AssertNotExistsBean(t, hook) @@ -220,7 +220,7 @@ func TestCreateHookTask(t *testing.T) { func TestUpdateHookTask(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hook := unittest.AssertExistsAndLoadBean(t, &HookTask{ID: 1}).(*HookTask) + hook := unittest.AssertExistsAndLoadBean(t, &HookTask{ID: 1}) hook.PayloadContent = "new payload content" hook.DeliveredString = "new delivered string" hook.IsDelivered = true diff --git a/modules/activitypub/client_test.go b/modules/activitypub/client_test.go index b93ef5ac98..62068d53b3 100644 --- a/modules/activitypub/client_test.go +++ b/modules/activitypub/client_test.go @@ -23,7 +23,7 @@ import ( func TestActivityPubSignedPost(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) pubID := "https://example.com/pubID" c, err := NewClient(user, pubID) assert.NoError(t, err) diff --git a/modules/activitypub/user_settings_test.go b/modules/activitypub/user_settings_test.go index 90c6f680f9..beefde232f 100644 --- a/modules/activitypub/user_settings_test.go +++ b/modules/activitypub/user_settings_test.go @@ -17,7 +17,7 @@ import ( func TestUserSettings(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) pub, priv, err := GetKeyPair(user1) assert.NoError(t, err) pub1, err := GetPublicKey(user1) diff --git a/modules/charset/ambiguous.go b/modules/charset/ambiguous.go new file mode 100644 index 0000000000..9dab3b0951 --- /dev/null +++ b/modules/charset/ambiguous.go @@ -0,0 +1,54 @@ +// This file is generated by modules/charset/ambiguous/generate.go DO NOT EDIT +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import ( + "sort" + "strings" + "unicode" + + "code.gitea.io/gitea/modules/translation" +) + +// AmbiguousTablesForLocale provides the table of ambiguous characters for this locale. +func AmbiguousTablesForLocale(locale translation.Locale) []*AmbiguousTable { + key := locale.Language() + var table *AmbiguousTable + var ok bool + for len(key) > 0 { + if table, ok = AmbiguousCharacters[key]; ok { + break + } + idx := strings.LastIndexAny(key, "-_") + if idx < 0 { + key = "" + } else { + key = key[:idx] + } + } + if table == nil { + table = AmbiguousCharacters["_default"] + } + + return []*AmbiguousTable{ + table, + AmbiguousCharacters["_common"], + } +} + +func isAmbiguous(r rune, confusableTo *rune, tables ...*AmbiguousTable) bool { + for _, table := range tables { + if !unicode.Is(table.RangeTable, r) { + continue + } + i := sort.Search(len(table.Confusable), func(i int) bool { + return table.Confusable[i] >= r + }) + (*confusableTo) = table.With[i] + return true + } + return false +} diff --git a/modules/charset/ambiguous/ambiguous.json b/modules/charset/ambiguous/ambiguous.json new file mode 100644 index 0000000000..d0f69f6ae2 --- /dev/null +++ b/modules/charset/ambiguous/ambiguous.json @@ -0,0 +1 @@ +"{\"_common\":[8232,32,8233,32,5760,32,8192,32,8193,32,8194,32,8195,32,8196,32,8197,32,8198,32,8200,32,8201,32,8202,32,8287,32,8199,32,8239,32,2042,95,65101,95,65102,95,65103,95,8208,45,8209,45,8210,45,65112,45,1748,45,8259,45,727,45,8722,45,10134,45,11450,45,1549,44,1643,44,8218,44,184,44,42233,44,894,59,2307,58,2691,58,1417,58,1795,58,1796,58,5868,58,65072,58,6147,58,6153,58,8282,58,1475,58,760,58,42889,58,8758,58,720,58,42237,58,451,33,11601,33,660,63,577,63,2429,63,5038,63,42731,63,119149,46,8228,46,1793,46,1794,46,42510,46,68176,46,1632,46,1776,46,42232,46,1373,96,65287,96,8219,96,8242,96,1370,96,1523,96,8175,96,65344,96,900,96,8189,96,8125,96,8127,96,8190,96,697,96,884,96,712,96,714,96,715,96,756,96,699,96,701,96,700,96,702,96,42892,96,1497,96,2036,96,2037,96,5194,96,5836,96,94033,96,94034,96,65339,91,10088,40,10098,40,12308,40,64830,40,65341,93,10089,41,10099,41,12309,41,64831,41,10100,123,119060,123,10101,125,65342,94,8270,42,1645,42,8727,42,66335,42,5941,47,8257,47,8725,47,8260,47,9585,47,10187,47,10744,47,119354,47,12755,47,12339,47,11462,47,20031,47,12035,47,65340,92,65128,92,8726,92,10189,92,10741,92,10745,92,119311,92,119355,92,12756,92,20022,92,12034,92,42872,38,708,94,710,94,5869,43,10133,43,66203,43,8249,60,10094,60,706,60,119350,60,5176,60,5810,60,5120,61,11840,61,12448,61,42239,61,8250,62,10095,62,707,62,119351,62,5171,62,94015,62,8275,126,732,126,8128,126,8764,126,65372,124,65293,45,120784,50,120794,50,120804,50,120814,50,120824,50,130034,50,42842,50,423,50,1000,50,42564,50,5311,50,42735,50,119302,51,120785,51,120795,51,120805,51,120815,51,120825,51,130035,51,42923,51,540,51,439,51,42858,51,11468,51,1248,51,94011,51,71882,51,120786,52,120796,52,120806,52,120816,52,120826,52,130036,52,5070,52,71855,52,120787,53,120797,53,120807,53,120817,53,120827,53,130037,53,444,53,71867,53,120788,54,120798,54,120808,54,120818,54,120828,54,130038,54,11474,54,5102,54,71893,54,119314,55,120789,55,120799,55,120809,55,120819,55,120829,55,130039,55,66770,55,71878,55,2819,56,2538,56,2666,56,125131,56,120790,56,120800,56,120810,56,120820,56,120830,56,130040,56,547,56,546,56,66330,56,2663,57,2920,57,2541,57,3437,57,120791,57,120801,57,120811,57,120821,57,120831,57,130041,57,42862,57,11466,57,71884,57,71852,57,71894,57,9082,97,65345,97,119834,97,119886,97,119938,97,119990,97,120042,97,120094,97,120146,97,120198,97,120250,97,120302,97,120354,97,120406,97,120458,97,593,97,945,97,120514,97,120572,97,120630,97,120688,97,120746,97,65313,65,119808,65,119860,65,119912,65,119964,65,120016,65,120068,65,120120,65,120172,65,120224,65,120276,65,120328,65,120380,65,120432,65,913,65,120488,65,120546,65,120604,65,120662,65,120720,65,5034,65,5573,65,42222,65,94016,65,66208,65,119835,98,119887,98,119939,98,119991,98,120043,98,120095,98,120147,98,120199,98,120251,98,120303,98,120355,98,120407,98,120459,98,388,98,5071,98,5234,98,5551,98,65314,66,8492,66,119809,66,119861,66,119913,66,120017,66,120069,66,120121,66,120173,66,120225,66,120277,66,120329,66,120381,66,120433,66,42932,66,914,66,120489,66,120547,66,120605,66,120663,66,120721,66,5108,66,5623,66,42192,66,66178,66,66209,66,66305,66,65347,99,8573,99,119836,99,119888,99,119940,99,119992,99,120044,99,120096,99,120148,99,120200,99,120252,99,120304,99,120356,99,120408,99,120460,99,7428,99,1010,99,11429,99,43951,99,66621,99,128844,67,71922,67,71913,67,65315,67,8557,67,8450,67,8493,67,119810,67,119862,67,119914,67,119966,67,120018,67,120174,67,120226,67,120278,67,120330,67,120382,67,120434,67,1017,67,11428,67,5087,67,42202,67,66210,67,66306,67,66581,67,66844,67,8574,100,8518,100,119837,100,119889,100,119941,100,119993,100,120045,100,120097,100,120149,100,120201,100,120253,100,120305,100,120357,100,120409,100,120461,100,1281,100,5095,100,5231,100,42194,100,8558,68,8517,68,119811,68,119863,68,119915,68,119967,68,120019,68,120071,68,120123,68,120175,68,120227,68,120279,68,120331,68,120383,68,120435,68,5024,68,5598,68,5610,68,42195,68,8494,101,65349,101,8495,101,8519,101,119838,101,119890,101,119942,101,120046,101,120098,101,120150,101,120202,101,120254,101,120306,101,120358,101,120410,101,120462,101,43826,101,1213,101,8959,69,65317,69,8496,69,119812,69,119864,69,119916,69,120020,69,120072,69,120124,69,120176,69,120228,69,120280,69,120332,69,120384,69,120436,69,917,69,120492,69,120550,69,120608,69,120666,69,120724,69,11577,69,5036,69,42224,69,71846,69,71854,69,66182,69,119839,102,119891,102,119943,102,119995,102,120047,102,120099,102,120151,102,120203,102,120255,102,120307,102,120359,102,120411,102,120463,102,43829,102,42905,102,383,102,7837,102,1412,102,119315,70,8497,70,119813,70,119865,70,119917,70,120021,70,120073,70,120125,70,120177,70,120229,70,120281,70,120333,70,120385,70,120437,70,42904,70,988,70,120778,70,5556,70,42205,70,71874,70,71842,70,66183,70,66213,70,66853,70,65351,103,8458,103,119840,103,119892,103,119944,103,120048,103,120100,103,120152,103,120204,103,120256,103,120308,103,120360,103,120412,103,120464,103,609,103,7555,103,397,103,1409,103,119814,71,119866,71,119918,71,119970,71,120022,71,120074,71,120126,71,120178,71,120230,71,120282,71,120334,71,120386,71,120438,71,1292,71,5056,71,5107,71,42198,71,65352,104,8462,104,119841,104,119945,104,119997,104,120049,104,120101,104,120153,104,120205,104,120257,104,120309,104,120361,104,120413,104,120465,104,1211,104,1392,104,5058,104,65320,72,8459,72,8460,72,8461,72,119815,72,119867,72,119919,72,120023,72,120179,72,120231,72,120283,72,120335,72,120387,72,120439,72,919,72,120494,72,120552,72,120610,72,120668,72,120726,72,11406,72,5051,72,5500,72,42215,72,66255,72,731,105,9075,105,65353,105,8560,105,8505,105,8520,105,119842,105,119894,105,119946,105,119998,105,120050,105,120102,105,120154,105,120206,105,120258,105,120310,105,120362,105,120414,105,120466,105,120484,105,618,105,617,105,953,105,8126,105,890,105,120522,105,120580,105,120638,105,120696,105,120754,105,1110,105,42567,105,1231,105,43893,105,5029,105,71875,105,65354,106,8521,106,119843,106,119895,106,119947,106,119999,106,120051,106,120103,106,120155,106,120207,106,120259,106,120311,106,120363,106,120415,106,120467,106,1011,106,1112,106,65322,74,119817,74,119869,74,119921,74,119973,74,120025,74,120077,74,120129,74,120181,74,120233,74,120285,74,120337,74,120389,74,120441,74,42930,74,895,74,1032,74,5035,74,5261,74,42201,74,119844,107,119896,107,119948,107,120000,107,120052,107,120104,107,120156,107,120208,107,120260,107,120312,107,120364,107,120416,107,120468,107,8490,75,65323,75,119818,75,119870,75,119922,75,119974,75,120026,75,120078,75,120130,75,120182,75,120234,75,120286,75,120338,75,120390,75,120442,75,922,75,120497,75,120555,75,120613,75,120671,75,120729,75,11412,75,5094,75,5845,75,42199,75,66840,75,1472,108,8739,73,9213,73,65512,73,1633,108,1777,73,66336,108,125127,108,120783,73,120793,73,120803,73,120813,73,120823,73,130033,73,65321,73,8544,73,8464,73,8465,73,119816,73,119868,73,119920,73,120024,73,120128,73,120180,73,120232,73,120284,73,120336,73,120388,73,120440,73,65356,108,8572,73,8467,108,119845,108,119897,108,119949,108,120001,108,120053,108,120105,73,120157,73,120209,73,120261,73,120313,73,120365,73,120417,73,120469,73,448,73,120496,73,120554,73,120612,73,120670,73,120728,73,11410,73,1030,73,1216,73,1493,108,1503,108,1575,108,126464,108,126592,108,65166,108,65165,108,1994,108,11599,73,5825,73,42226,73,93992,73,66186,124,66313,124,119338,76,8556,76,8466,76,119819,76,119871,76,119923,76,120027,76,120079,76,120131,76,120183,76,120235,76,120287,76,120339,76,120391,76,120443,76,11472,76,5086,76,5290,76,42209,76,93974,76,71843,76,71858,76,66587,76,66854,76,65325,77,8559,77,8499,77,119820,77,119872,77,119924,77,120028,77,120080,77,120132,77,120184,77,120236,77,120288,77,120340,77,120392,77,120444,77,924,77,120499,77,120557,77,120615,77,120673,77,120731,77,1018,77,11416,77,5047,77,5616,77,5846,77,42207,77,66224,77,66321,77,119847,110,119899,110,119951,110,120003,110,120055,110,120107,110,120159,110,120211,110,120263,110,120315,110,120367,110,120419,110,120471,110,1400,110,1404,110,65326,78,8469,78,119821,78,119873,78,119925,78,119977,78,120029,78,120081,78,120185,78,120237,78,120289,78,120341,78,120393,78,120445,78,925,78,120500,78,120558,78,120616,78,120674,78,120732,78,11418,78,42208,78,66835,78,3074,111,3202,111,3330,111,3458,111,2406,111,2662,111,2790,111,3046,111,3174,111,3302,111,3430,111,3664,111,3792,111,4160,111,1637,111,1781,111,65359,111,8500,111,119848,111,119900,111,119952,111,120056,111,120108,111,120160,111,120212,111,120264,111,120316,111,120368,111,120420,111,120472,111,7439,111,7441,111,43837,111,959,111,120528,111,120586,111,120644,111,120702,111,120760,111,963,111,120532,111,120590,111,120648,111,120706,111,120764,111,11423,111,4351,111,1413,111,1505,111,1607,111,126500,111,126564,111,126596,111,65259,111,65260,111,65258,111,65257,111,1726,111,64428,111,64429,111,64427,111,64426,111,1729,111,64424,111,64425,111,64423,111,64422,111,1749,111,3360,111,4125,111,66794,111,71880,111,71895,111,66604,111,1984,79,2534,79,2918,79,12295,79,70864,79,71904,79,120782,79,120792,79,120802,79,120812,79,120822,79,130032,79,65327,79,119822,79,119874,79,119926,79,119978,79,120030,79,120082,79,120134,79,120186,79,120238,79,120290,79,120342,79,120394,79,120446,79,927,79,120502,79,120560,79,120618,79,120676,79,120734,79,11422,79,1365,79,11604,79,4816,79,2848,79,66754,79,42227,79,71861,79,66194,79,66219,79,66564,79,66838,79,9076,112,65360,112,119849,112,119901,112,119953,112,120005,112,120057,112,120109,112,120161,112,120213,112,120265,112,120317,112,120369,112,120421,112,120473,112,961,112,120530,112,120544,112,120588,112,120602,112,120646,112,120660,112,120704,112,120718,112,120762,112,120776,112,11427,112,65328,80,8473,80,119823,80,119875,80,119927,80,119979,80,120031,80,120083,80,120187,80,120239,80,120291,80,120343,80,120395,80,120447,80,929,80,120504,80,120562,80,120620,80,120678,80,120736,80,11426,80,5090,80,5229,80,42193,80,66197,80,119850,113,119902,113,119954,113,120006,113,120058,113,120110,113,120162,113,120214,113,120266,113,120318,113,120370,113,120422,113,120474,113,1307,113,1379,113,1382,113,8474,81,119824,81,119876,81,119928,81,119980,81,120032,81,120084,81,120188,81,120240,81,120292,81,120344,81,120396,81,120448,81,11605,81,119851,114,119903,114,119955,114,120007,114,120059,114,120111,114,120163,114,120215,114,120267,114,120319,114,120371,114,120423,114,120475,114,43847,114,43848,114,7462,114,11397,114,43905,114,119318,82,8475,82,8476,82,8477,82,119825,82,119877,82,119929,82,120033,82,120189,82,120241,82,120293,82,120345,82,120397,82,120449,82,422,82,5025,82,5074,82,66740,82,5511,82,42211,82,94005,82,65363,115,119852,115,119904,115,119956,115,120008,115,120060,115,120112,115,120164,115,120216,115,120268,115,120320,115,120372,115,120424,115,120476,115,42801,115,445,115,1109,115,43946,115,71873,115,66632,115,65331,83,119826,83,119878,83,119930,83,119982,83,120034,83,120086,83,120138,83,120190,83,120242,83,120294,83,120346,83,120398,83,120450,83,1029,83,1359,83,5077,83,5082,83,42210,83,94010,83,66198,83,66592,83,119853,116,119905,116,119957,116,120009,116,120061,116,120113,116,120165,116,120217,116,120269,116,120321,116,120373,116,120425,116,120477,116,8868,84,10201,84,128872,84,65332,84,119827,84,119879,84,119931,84,119983,84,120035,84,120087,84,120139,84,120191,84,120243,84,120295,84,120347,84,120399,84,120451,84,932,84,120507,84,120565,84,120623,84,120681,84,120739,84,11430,84,5026,84,42196,84,93962,84,71868,84,66199,84,66225,84,66325,84,119854,117,119906,117,119958,117,120010,117,120062,117,120114,117,120166,117,120218,117,120270,117,120322,117,120374,117,120426,117,120478,117,42911,117,7452,117,43854,117,43858,117,651,117,965,117,120534,117,120592,117,120650,117,120708,117,120766,117,1405,117,66806,117,71896,117,8746,85,8899,85,119828,85,119880,85,119932,85,119984,85,120036,85,120088,85,120140,85,120192,85,120244,85,120296,85,120348,85,120400,85,120452,85,1357,85,4608,85,66766,85,5196,85,42228,85,94018,85,71864,85,8744,118,8897,118,65366,118,8564,118,119855,118,119907,118,119959,118,120011,118,120063,118,120115,118,120167,118,120219,118,120271,118,120323,118,120375,118,120427,118,120479,118,7456,118,957,118,120526,118,120584,118,120642,118,120700,118,120758,118,1141,118,1496,118,71430,118,43945,118,71872,118,119309,86,1639,86,1783,86,8548,86,119829,86,119881,86,119933,86,119985,86,120037,86,120089,86,120141,86,120193,86,120245,86,120297,86,120349,86,120401,86,120453,86,1140,86,11576,86,5081,86,5167,86,42719,86,42214,86,93960,86,71840,86,66845,86,623,119,119856,119,119908,119,119960,119,120012,119,120064,119,120116,119,120168,119,120220,119,120272,119,120324,119,120376,119,120428,119,120480,119,7457,119,1121,119,1309,119,1377,119,71434,119,71438,119,71439,119,43907,119,71919,87,71910,87,119830,87,119882,87,119934,87,119986,87,120038,87,120090,87,120142,87,120194,87,120246,87,120298,87,120350,87,120402,87,120454,87,1308,87,5043,87,5076,87,42218,87,5742,120,10539,120,10540,120,10799,120,65368,120,8569,120,119857,120,119909,120,119961,120,120013,120,120065,120,120117,120,120169,120,120221,120,120273,120,120325,120,120377,120,120429,120,120481,120,5441,120,5501,120,5741,88,9587,88,66338,88,71916,88,65336,88,8553,88,119831,88,119883,88,119935,88,119987,88,120039,88,120091,88,120143,88,120195,88,120247,88,120299,88,120351,88,120403,88,120455,88,42931,88,935,88,120510,88,120568,88,120626,88,120684,88,120742,88,11436,88,11613,88,5815,88,42219,88,66192,88,66228,88,66327,88,66855,88,611,121,7564,121,65369,121,119858,121,119910,121,119962,121,120014,121,120066,121,120118,121,120170,121,120222,121,120274,121,120326,121,120378,121,120430,121,120482,121,655,121,7935,121,43866,121,947,121,8509,121,120516,121,120574,121,120632,121,120690,121,120748,121,1199,121,4327,121,71900,121,65337,89,119832,89,119884,89,119936,89,119988,89,120040,89,120092,89,120144,89,120196,89,120248,89,120300,89,120352,89,120404,89,120456,89,933,89,978,89,120508,89,120566,89,120624,89,120682,89,120740,89,11432,89,1198,89,5033,89,5053,89,42220,89,94019,89,71844,89,66226,89,119859,122,119911,122,119963,122,120015,122,120067,122,120119,122,120171,122,120223,122,120275,122,120327,122,120379,122,120431,122,120483,122,7458,122,43923,122,71876,122,66293,90,71909,90,65338,90,8484,90,8488,90,119833,90,119885,90,119937,90,119989,90,120041,90,120197,90,120249,90,120301,90,120353,90,120405,90,120457,90,918,90,120493,90,120551,90,120609,90,120667,90,120725,90,5059,90,42204,90,71849,90,65282,34,65284,36,65285,37,65286,38,65290,42,65291,43,65294,46,65295,47,65296,48,65297,49,65298,50,65299,51,65300,52,65301,53,65302,54,65303,55,65304,56,65305,57,65308,60,65309,61,65310,62,65312,64,65316,68,65318,70,65319,71,65324,76,65329,81,65330,82,65333,85,65334,86,65335,87,65343,95,65346,98,65348,100,65350,102,65355,107,65357,109,65358,110,65361,113,65362,114,65364,116,65365,117,65367,119,65370,122,65371,123,65373,125],\"_default\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"cs\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"de\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"es\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"fr\":[65374,126,65306,58,65281,33,8216,96,8245,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"it\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"ja\":[8211,45,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65292,44,65307,59],\"ko\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"pl\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"pt-BR\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"qps-ploc\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"ru\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,305,105,921,73,1009,112,215,120,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"tr\":[160,32,8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"zh-hans\":[65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65288,40,65289,41],\"zh-hant\":[8211,45,65374,126,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65307,59]}" \ No newline at end of file diff --git a/modules/charset/ambiguous/generate.go b/modules/charset/ambiguous/generate.go new file mode 100644 index 0000000000..43cdb217a7 --- /dev/null +++ b/modules/charset/ambiguous/generate.go @@ -0,0 +1,178 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "flag" + "fmt" + "go/format" + "os" + "sort" + "text/template" + "unicode" + + "code.gitea.io/gitea/modules/json" + + "golang.org/x/text/unicode/rangetable" +) + +// ambiguous.json provides a one to one mapping of ambiguous characters to other characters +// See https://github.com/hediet/vscode-unicode-data/blob/main/out/ambiguous.json + +type AmbiguousTable struct { + Confusable []rune + With []rune + Locale string + RangeTable *unicode.RangeTable +} + +type RunePair struct { + Confusable rune + With rune +} + +var verbose bool + +func main() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, `%s: Generate AmbiguousCharacter + +Usage: %[1]s [-v] [-o output.go] ambiguous.json +`, os.Args[0]) + flag.PrintDefaults() + } + + output := "" + flag.BoolVar(&verbose, "v", false, "verbose output") + flag.StringVar(&output, "o", "ambiguous_gen.go", "file to output to") + flag.Parse() + input := flag.Arg(0) + if input == "" { + input = "ambiguous.json" + } + + bs, err := os.ReadFile(input) + if err != nil { + fatalf("Unable to read: %s Err: %v", input, err) + } + + var unwrapped string + if err := json.Unmarshal(bs, &unwrapped); err != nil { + fatalf("Unable to unwrap content in: %s Err: %v", input, err) + } + + fromJSON := map[string][]uint32{} + if err := json.Unmarshal([]byte(unwrapped), &fromJSON); err != nil { + fatalf("Unable to unmarshal content in: %s Err: %v", input, err) + } + + tables := make([]*AmbiguousTable, 0, len(fromJSON)) + for locale, chars := range fromJSON { + table := &AmbiguousTable{Locale: locale} + table.Confusable = make([]rune, 0, len(chars)/2) + table.With = make([]rune, 0, len(chars)/2) + pairs := make([]RunePair, len(chars)/2) + for i := 0; i < len(chars); i += 2 { + pairs[i/2].Confusable, pairs[i/2].With = rune(chars[i]), rune(chars[i+1]) + } + sort.Slice(pairs, func(i, j int) bool { + return pairs[i].Confusable < pairs[j].Confusable + }) + for _, pair := range pairs { + table.Confusable = append(table.Confusable, pair.Confusable) + table.With = append(table.With, pair.With) + } + table.RangeTable = rangetable.New(table.Confusable...) + tables = append(tables, table) + } + sort.Slice(tables, func(i, j int) bool { + return tables[i].Locale < tables[j].Locale + }) + data := map[string]interface{}{ + "Tables": tables, + } + + if err := runTemplate(generatorTemplate, output, &data); err != nil { + fatalf("Unable to run template: %v", err) + } +} + +func runTemplate(t *template.Template, filename string, data interface{}) error { + buf := bytes.NewBuffer(nil) + if err := t.Execute(buf, data); err != nil { + return fmt.Errorf("unable to execute template: %w", err) + } + bs, err := format.Source(buf.Bytes()) + if err != nil { + verbosef("Bad source:\n%s", buf.String()) + return fmt.Errorf("unable to format source: %w", err) + } + file, err := os.Create(filename) + if err != nil { + return fmt.Errorf("failed to create file %s because %w", filename, err) + } + defer file.Close() + _, err = file.Write(bs) + if err != nil { + return fmt.Errorf("unable to write generated source: %w", err) + } + return nil +} + +var generatorTemplate = template.Must(template.New("ambiguousTemplate").Parse(`// This file is generated by modules/charset/ambiguous/generate.go DO NOT EDIT +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import "unicode" + +// This file is generated from https://github.com/hediet/vscode-unicode-data/blob/main/out/ambiguous.json + +// AmbiguousTable matches a confusable rune with its partner for the Locale +type AmbiguousTable struct { + Confusable []rune + With []rune + Locale string + RangeTable *unicode.RangeTable +} + +// AmbiguousCharacters provides a map by locale name to the confusable characters in that locale +var AmbiguousCharacters = map[string]*AmbiguousTable{ + {{range .Tables}}{{printf "%q:" .Locale}} { + Confusable: []rune{ {{range .Confusable}}{{.}},{{end}} }, + With: []rune{ {{range .With}}{{.}},{{end}} }, + Locale: {{printf "%q" .Locale}}, + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {{range .RangeTable.R16 }} {Lo:{{.Lo}}, Hi:{{.Hi}}, Stride: {{.Stride}}}, + {{end}} }, + R32: []unicode.Range32{ + {{range .RangeTable.R32}} {Lo:{{.Lo}}, Hi:{{.Hi}}, Stride: {{.Stride}}}, + {{end}} }, + LatinOffset: {{.RangeTable.LatinOffset}}, + }, + }, + {{end}} +} + +`)) + +func logf(format string, args ...interface{}) { + fmt.Fprintf(os.Stderr, format+"\n", args...) +} + +func verbosef(format string, args ...interface{}) { + if verbose { + logf(format, args...) + } +} + +func fatalf(format string, args ...interface{}) { + logf("fatal: "+format+"\n", args...) + os.Exit(1) +} diff --git a/modules/charset/ambiguous_gen.go b/modules/charset/ambiguous_gen.go new file mode 100644 index 0000000000..cc270affac --- /dev/null +++ b/modules/charset/ambiguous_gen.go @@ -0,0 +1,837 @@ +// This file is generated by modules/charset/ambiguous/generate.go DO NOT EDIT +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import "unicode" + +// This file is generated from https://github.com/hediet/vscode-unicode-data/blob/main/out/ambiguous.json + +// AmbiguousTable matches a confusable rune with its partner for the Locale +type AmbiguousTable struct { + Confusable []rune + With []rune + Locale string + RangeTable *unicode.RangeTable +} + +// AmbiguousCharacters provides a map by locale name to the confusable characters in that locale +var AmbiguousCharacters = map[string]*AmbiguousTable{ + "_common": { + Confusable: []rune{184, 383, 388, 397, 422, 423, 439, 444, 445, 448, 451, 540, 546, 547, 577, 593, 609, 611, 617, 618, 623, 651, 655, 660, 697, 699, 700, 701, 702, 706, 707, 708, 710, 712, 714, 715, 720, 727, 731, 732, 756, 760, 884, 890, 894, 895, 900, 913, 914, 917, 918, 919, 922, 924, 925, 927, 929, 932, 933, 935, 945, 947, 953, 957, 959, 961, 963, 965, 978, 988, 1000, 1010, 1011, 1017, 1018, 1029, 1030, 1032, 1109, 1110, 1112, 1121, 1140, 1141, 1198, 1199, 1211, 1213, 1216, 1231, 1248, 1281, 1292, 1307, 1308, 1309, 1357, 1359, 1365, 1370, 1373, 1377, 1379, 1382, 1392, 1400, 1404, 1405, 1409, 1412, 1413, 1417, 1472, 1475, 1493, 1496, 1497, 1503, 1505, 1523, 1549, 1575, 1607, 1632, 1633, 1637, 1639, 1643, 1645, 1726, 1729, 1748, 1749, 1776, 1777, 1781, 1783, 1793, 1794, 1795, 1796, 1984, 1994, 2036, 2037, 2042, 2307, 2406, 2429, 2534, 2538, 2541, 2662, 2663, 2666, 2691, 2790, 2819, 2848, 2918, 2920, 3046, 3074, 3174, 3202, 3302, 3330, 3360, 3430, 3437, 3458, 3664, 3792, 4125, 4160, 4327, 4351, 4608, 4816, 5024, 5025, 5026, 5029, 5033, 5034, 5035, 5036, 5038, 5043, 5047, 5051, 5053, 5056, 5058, 5059, 5070, 5071, 5074, 5076, 5077, 5081, 5082, 5086, 5087, 5090, 5094, 5095, 5102, 5107, 5108, 5120, 5167, 5171, 5176, 5194, 5196, 5229, 5231, 5234, 5261, 5290, 5311, 5441, 5500, 5501, 5511, 5551, 5556, 5573, 5598, 5610, 5616, 5623, 5741, 5742, 5760, 5810, 5815, 5825, 5836, 5845, 5846, 5868, 5869, 5941, 6147, 6153, 7428, 7439, 7441, 7452, 7456, 7457, 7458, 7462, 7555, 7564, 7837, 7935, 8125, 8126, 8127, 8128, 8175, 8189, 8190, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8208, 8209, 8210, 8218, 8219, 8228, 8232, 8233, 8239, 8242, 8249, 8250, 8257, 8259, 8260, 8270, 8275, 8282, 8287, 8450, 8458, 8459, 8460, 8461, 8462, 8464, 8465, 8466, 8467, 8469, 8473, 8474, 8475, 8476, 8477, 8484, 8488, 8490, 8492, 8493, 8494, 8495, 8496, 8497, 8499, 8500, 8505, 8509, 8517, 8518, 8519, 8520, 8521, 8544, 8548, 8553, 8556, 8557, 8558, 8559, 8560, 8564, 8569, 8572, 8573, 8574, 8722, 8725, 8726, 8727, 8739, 8744, 8746, 8758, 8764, 8868, 8897, 8899, 8959, 9075, 9076, 9082, 9213, 9585, 9587, 10088, 10089, 10094, 10095, 10098, 10099, 10100, 10101, 10133, 10134, 10187, 10189, 10201, 10539, 10540, 10741, 10744, 10745, 10799, 11397, 11406, 11410, 11412, 11416, 11418, 11422, 11423, 11426, 11427, 11428, 11429, 11430, 11432, 11436, 11450, 11462, 11466, 11468, 11472, 11474, 11576, 11577, 11599, 11601, 11604, 11605, 11613, 11840, 12034, 12035, 12295, 12308, 12309, 12339, 12448, 12755, 12756, 20022, 20031, 42192, 42193, 42194, 42195, 42196, 42198, 42199, 42201, 42202, 42204, 42205, 42207, 42208, 42209, 42210, 42211, 42214, 42215, 42218, 42219, 42220, 42222, 42224, 42226, 42227, 42228, 42232, 42233, 42237, 42239, 42510, 42564, 42567, 42719, 42731, 42735, 42801, 42842, 42858, 42862, 42872, 42889, 42892, 42904, 42905, 42911, 42923, 42930, 42931, 42932, 43826, 43829, 43837, 43847, 43848, 43854, 43858, 43866, 43893, 43905, 43907, 43923, 43945, 43946, 43951, 64422, 64423, 64424, 64425, 64426, 64427, 64428, 64429, 64830, 64831, 65072, 65101, 65102, 65103, 65112, 65128, 65165, 65166, 65257, 65258, 65259, 65260, 65282, 65284, 65285, 65286, 65287, 65290, 65291, 65293, 65294, 65295, 65296, 65297, 65298, 65299, 65300, 65301, 65302, 65303, 65304, 65305, 65308, 65309, 65310, 65312, 65313, 65314, 65315, 65316, 65317, 65318, 65319, 65320, 65321, 65322, 65323, 65324, 65325, 65326, 65327, 65328, 65329, 65330, 65331, 65332, 65333, 65334, 65335, 65336, 65337, 65338, 65339, 65340, 65341, 65342, 65343, 65344, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370, 65371, 65372, 65373, 65512, 66178, 66182, 66183, 66186, 66192, 66194, 66197, 66198, 66199, 66203, 66208, 66209, 66210, 66213, 66219, 66224, 66225, 66226, 66228, 66255, 66293, 66305, 66306, 66313, 66321, 66325, 66327, 66330, 66335, 66336, 66338, 66564, 66581, 66587, 66592, 66604, 66621, 66632, 66740, 66754, 66766, 66770, 66794, 66806, 66835, 66838, 66840, 66844, 66845, 66853, 66854, 66855, 68176, 70864, 71430, 71434, 71438, 71439, 71840, 71842, 71843, 71844, 71846, 71849, 71852, 71854, 71855, 71858, 71861, 71864, 71867, 71868, 71872, 71873, 71874, 71875, 71876, 71878, 71880, 71882, 71884, 71893, 71894, 71895, 71896, 71900, 71904, 71909, 71910, 71913, 71916, 71919, 71922, 93960, 93962, 93974, 93992, 94005, 94010, 94011, 94015, 94016, 94018, 94019, 94033, 94034, 119060, 119149, 119302, 119309, 119311, 119314, 119315, 119318, 119338, 119350, 119351, 119354, 119355, 119808, 119809, 119810, 119811, 119812, 119813, 119814, 119815, 119816, 119817, 119818, 119819, 119820, 119821, 119822, 119823, 119824, 119825, 119826, 119827, 119828, 119829, 119830, 119831, 119832, 119833, 119834, 119835, 119836, 119837, 119838, 119839, 119840, 119841, 119842, 119843, 119844, 119845, 119847, 119848, 119849, 119850, 119851, 119852, 119853, 119854, 119855, 119856, 119857, 119858, 119859, 119860, 119861, 119862, 119863, 119864, 119865, 119866, 119867, 119868, 119869, 119870, 119871, 119872, 119873, 119874, 119875, 119876, 119877, 119878, 119879, 119880, 119881, 119882, 119883, 119884, 119885, 119886, 119887, 119888, 119889, 119890, 119891, 119892, 119894, 119895, 119896, 119897, 119899, 119900, 119901, 119902, 119903, 119904, 119905, 119906, 119907, 119908, 119909, 119910, 119911, 119912, 119913, 119914, 119915, 119916, 119917, 119918, 119919, 119920, 119921, 119922, 119923, 119924, 119925, 119926, 119927, 119928, 119929, 119930, 119931, 119932, 119933, 119934, 119935, 119936, 119937, 119938, 119939, 119940, 119941, 119942, 119943, 119944, 119945, 119946, 119947, 119948, 119949, 119951, 119952, 119953, 119954, 119955, 119956, 119957, 119958, 119959, 119960, 119961, 119962, 119963, 119964, 119966, 119967, 119970, 119973, 119974, 119977, 119978, 119979, 119980, 119982, 119983, 119984, 119985, 119986, 119987, 119988, 119989, 119990, 119991, 119992, 119993, 119995, 119997, 119998, 119999, 120000, 120001, 120003, 120005, 120006, 120007, 120008, 120009, 120010, 120011, 120012, 120013, 120014, 120015, 120016, 120017, 120018, 120019, 120020, 120021, 120022, 120023, 120024, 120025, 120026, 120027, 120028, 120029, 120030, 120031, 120032, 120033, 120034, 120035, 120036, 120037, 120038, 120039, 120040, 120041, 120042, 120043, 120044, 120045, 120046, 120047, 120048, 120049, 120050, 120051, 120052, 120053, 120055, 120056, 120057, 120058, 120059, 120060, 120061, 120062, 120063, 120064, 120065, 120066, 120067, 120068, 120069, 120071, 120072, 120073, 120074, 120077, 120078, 120079, 120080, 120081, 120082, 120083, 120084, 120086, 120087, 120088, 120089, 120090, 120091, 120092, 120094, 120095, 120096, 120097, 120098, 120099, 120100, 120101, 120102, 120103, 120104, 120105, 120107, 120108, 120109, 120110, 120111, 120112, 120113, 120114, 120115, 120116, 120117, 120118, 120119, 120120, 120121, 120123, 120124, 120125, 120126, 120128, 120129, 120130, 120131, 120132, 120134, 120138, 120139, 120140, 120141, 120142, 120143, 120144, 120146, 120147, 120148, 120149, 120150, 120151, 120152, 120153, 120154, 120155, 120156, 120157, 120159, 120160, 120161, 120162, 120163, 120164, 120165, 120166, 120167, 120168, 120169, 120170, 120171, 120172, 120173, 120174, 120175, 120176, 120177, 120178, 120179, 120180, 120181, 120182, 120183, 120184, 120185, 120186, 120187, 120188, 120189, 120190, 120191, 120192, 120193, 120194, 120195, 120196, 120197, 120198, 120199, 120200, 120201, 120202, 120203, 120204, 120205, 120206, 120207, 120208, 120209, 120211, 120212, 120213, 120214, 120215, 120216, 120217, 120218, 120219, 120220, 120221, 120222, 120223, 120224, 120225, 120226, 120227, 120228, 120229, 120230, 120231, 120232, 120233, 120234, 120235, 120236, 120237, 120238, 120239, 120240, 120241, 120242, 120243, 120244, 120245, 120246, 120247, 120248, 120249, 120250, 120251, 120252, 120253, 120254, 120255, 120256, 120257, 120258, 120259, 120260, 120261, 120263, 120264, 120265, 120266, 120267, 120268, 120269, 120270, 120271, 120272, 120273, 120274, 120275, 120276, 120277, 120278, 120279, 120280, 120281, 120282, 120283, 120284, 120285, 120286, 120287, 120288, 120289, 120290, 120291, 120292, 120293, 120294, 120295, 120296, 120297, 120298, 120299, 120300, 120301, 120302, 120303, 120304, 120305, 120306, 120307, 120308, 120309, 120310, 120311, 120312, 120313, 120315, 120316, 120317, 120318, 120319, 120320, 120321, 120322, 120323, 120324, 120325, 120326, 120327, 120328, 120329, 120330, 120331, 120332, 120333, 120334, 120335, 120336, 120337, 120338, 120339, 120340, 120341, 120342, 120343, 120344, 120345, 120346, 120347, 120348, 120349, 120350, 120351, 120352, 120353, 120354, 120355, 120356, 120357, 120358, 120359, 120360, 120361, 120362, 120363, 120364, 120365, 120367, 120368, 120369, 120370, 120371, 120372, 120373, 120374, 120375, 120376, 120377, 120378, 120379, 120380, 120381, 120382, 120383, 120384, 120385, 120386, 120387, 120388, 120389, 120390, 120391, 120392, 120393, 120394, 120395, 120396, 120397, 120398, 120399, 120400, 120401, 120402, 120403, 120404, 120405, 120406, 120407, 120408, 120409, 120410, 120411, 120412, 120413, 120414, 120415, 120416, 120417, 120419, 120420, 120421, 120422, 120423, 120424, 120425, 120426, 120427, 120428, 120429, 120430, 120431, 120432, 120433, 120434, 120435, 120436, 120437, 120438, 120439, 120440, 120441, 120442, 120443, 120444, 120445, 120446, 120447, 120448, 120449, 120450, 120451, 120452, 120453, 120454, 120455, 120456, 120457, 120458, 120459, 120460, 120461, 120462, 120463, 120464, 120465, 120466, 120467, 120468, 120469, 120471, 120472, 120473, 120474, 120475, 120476, 120477, 120478, 120479, 120480, 120481, 120482, 120483, 120484, 120488, 120489, 120492, 120493, 120494, 120496, 120497, 120499, 120500, 120502, 120504, 120507, 120508, 120510, 120514, 120516, 120522, 120526, 120528, 120530, 120532, 120534, 120544, 120546, 120547, 120550, 120551, 120552, 120554, 120555, 120557, 120558, 120560, 120562, 120565, 120566, 120568, 120572, 120574, 120580, 120584, 120586, 120588, 120590, 120592, 120602, 120604, 120605, 120608, 120609, 120610, 120612, 120613, 120615, 120616, 120618, 120620, 120623, 120624, 120626, 120630, 120632, 120638, 120642, 120644, 120646, 120648, 120650, 120660, 120662, 120663, 120666, 120667, 120668, 120670, 120671, 120673, 120674, 120676, 120678, 120681, 120682, 120684, 120688, 120690, 120696, 120700, 120702, 120704, 120706, 120708, 120718, 120720, 120721, 120724, 120725, 120726, 120728, 120729, 120731, 120732, 120734, 120736, 120739, 120740, 120742, 120746, 120748, 120754, 120758, 120760, 120762, 120764, 120766, 120776, 120778, 120782, 120783, 120784, 120785, 120786, 120787, 120788, 120789, 120790, 120791, 120792, 120793, 120794, 120795, 120796, 120797, 120798, 120799, 120800, 120801, 120802, 120803, 120804, 120805, 120806, 120807, 120808, 120809, 120810, 120811, 120812, 120813, 120814, 120815, 120816, 120817, 120818, 120819, 120820, 120821, 120822, 120823, 120824, 120825, 120826, 120827, 120828, 120829, 120830, 120831, 125127, 125131, 126464, 126500, 126564, 126592, 126596, 128844, 128872, 130032, 130033, 130034, 130035, 130036, 130037, 130038, 130039, 130040, 130041}, + With: []rune{44, 102, 98, 103, 82, 50, 51, 53, 115, 73, 33, 51, 56, 56, 63, 97, 103, 121, 105, 105, 119, 117, 121, 63, 96, 96, 96, 96, 96, 60, 62, 94, 94, 96, 96, 96, 58, 45, 105, 126, 96, 58, 96, 105, 59, 74, 96, 65, 66, 69, 90, 72, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 89, 70, 50, 99, 106, 67, 77, 83, 73, 74, 115, 105, 106, 119, 86, 118, 89, 121, 104, 101, 73, 105, 51, 100, 71, 113, 87, 119, 85, 83, 79, 96, 96, 119, 113, 113, 104, 110, 110, 117, 103, 102, 111, 58, 108, 58, 108, 118, 96, 108, 111, 96, 44, 108, 111, 46, 108, 111, 86, 44, 42, 111, 111, 45, 111, 46, 73, 111, 86, 46, 46, 58, 58, 79, 108, 96, 96, 95, 58, 111, 63, 79, 56, 57, 111, 57, 56, 58, 111, 56, 79, 79, 57, 111, 111, 111, 111, 111, 111, 111, 111, 57, 111, 111, 111, 111, 111, 121, 111, 85, 79, 68, 82, 84, 105, 89, 65, 74, 69, 63, 87, 77, 72, 89, 71, 104, 90, 52, 98, 82, 87, 83, 86, 83, 76, 67, 80, 75, 100, 54, 71, 66, 61, 86, 62, 60, 96, 85, 80, 100, 98, 74, 76, 50, 120, 72, 120, 82, 98, 70, 65, 68, 68, 77, 66, 88, 120, 32, 60, 88, 73, 96, 75, 77, 58, 43, 47, 58, 58, 99, 111, 111, 117, 118, 119, 122, 114, 103, 121, 102, 121, 96, 105, 96, 126, 96, 96, 96, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 44, 96, 46, 32, 32, 32, 96, 60, 62, 47, 45, 47, 42, 126, 58, 32, 67, 103, 72, 72, 72, 104, 73, 73, 76, 108, 78, 80, 81, 82, 82, 82, 90, 90, 75, 66, 67, 101, 101, 69, 70, 77, 111, 105, 121, 68, 100, 101, 105, 106, 73, 86, 88, 76, 67, 68, 77, 105, 118, 120, 73, 99, 100, 45, 47, 92, 42, 73, 118, 85, 58, 126, 84, 118, 85, 69, 105, 112, 97, 73, 47, 88, 40, 41, 60, 62, 40, 41, 123, 125, 43, 45, 47, 92, 84, 120, 120, 92, 47, 92, 120, 114, 72, 73, 75, 77, 78, 79, 111, 80, 112, 67, 99, 84, 89, 88, 45, 47, 57, 51, 76, 54, 86, 69, 73, 33, 79, 81, 88, 61, 92, 47, 79, 40, 41, 47, 61, 47, 92, 92, 47, 66, 80, 100, 68, 84, 71, 75, 74, 67, 90, 70, 77, 78, 76, 83, 82, 86, 72, 87, 88, 89, 65, 69, 73, 79, 85, 46, 44, 58, 61, 46, 50, 105, 86, 63, 50, 115, 50, 51, 57, 38, 58, 96, 70, 102, 117, 51, 74, 88, 66, 101, 102, 111, 114, 114, 117, 117, 121, 105, 114, 119, 122, 118, 115, 99, 111, 111, 111, 111, 111, 111, 111, 111, 40, 41, 58, 95, 95, 95, 45, 92, 108, 108, 111, 111, 111, 111, 34, 36, 37, 38, 96, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 73, 66, 69, 70, 124, 88, 79, 80, 83, 84, 43, 65, 66, 67, 70, 79, 77, 84, 89, 88, 72, 90, 66, 67, 124, 77, 84, 88, 56, 42, 108, 88, 79, 67, 76, 83, 111, 99, 115, 82, 79, 85, 55, 111, 117, 78, 79, 75, 67, 86, 70, 76, 88, 46, 79, 118, 119, 119, 119, 86, 70, 76, 89, 69, 90, 57, 69, 52, 76, 79, 85, 53, 84, 118, 115, 70, 105, 122, 55, 111, 51, 57, 54, 57, 111, 117, 121, 79, 90, 87, 67, 88, 87, 67, 86, 84, 76, 73, 82, 83, 51, 62, 65, 85, 89, 96, 96, 123, 46, 51, 86, 92, 55, 70, 82, 76, 60, 62, 47, 92, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 67, 68, 71, 74, 75, 78, 79, 80, 81, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 102, 104, 105, 106, 107, 108, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 83, 84, 85, 86, 87, 88, 89, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 77, 79, 83, 84, 85, 86, 87, 88, 89, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 105, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 70, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 108, 56, 108, 111, 111, 108, 111, 67, 84, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57}, + Locale: "_common", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 184, Hi: 383, Stride: 199}, + {Lo: 388, Hi: 397, Stride: 9}, + {Lo: 422, Hi: 423, Stride: 1}, + {Lo: 439, Hi: 444, Stride: 5}, + {Lo: 445, Hi: 451, Stride: 3}, + {Lo: 540, Hi: 546, Stride: 6}, + {Lo: 547, Hi: 577, Stride: 30}, + {Lo: 593, Hi: 609, Stride: 16}, + {Lo: 611, Hi: 617, Stride: 6}, + {Lo: 618, Hi: 623, Stride: 5}, + {Lo: 651, Hi: 655, Stride: 4}, + {Lo: 660, Hi: 697, Stride: 37}, + {Lo: 699, Hi: 702, Stride: 1}, + {Lo: 706, Hi: 708, Stride: 1}, + {Lo: 710, Hi: 714, Stride: 2}, + {Lo: 715, Hi: 720, Stride: 5}, + {Lo: 727, Hi: 731, Stride: 4}, + {Lo: 732, Hi: 756, Stride: 24}, + {Lo: 760, Hi: 884, Stride: 124}, + {Lo: 890, Hi: 894, Stride: 4}, + {Lo: 895, Hi: 900, Stride: 5}, + {Lo: 913, Hi: 914, Stride: 1}, + {Lo: 917, Hi: 919, Stride: 1}, + {Lo: 922, Hi: 924, Stride: 2}, + {Lo: 925, Hi: 929, Stride: 2}, + {Lo: 932, Hi: 933, Stride: 1}, + {Lo: 935, Hi: 945, Stride: 10}, + {Lo: 947, Hi: 953, Stride: 6}, + {Lo: 957, Hi: 965, Stride: 2}, + {Lo: 978, Hi: 988, Stride: 10}, + {Lo: 1000, Hi: 1010, Stride: 10}, + {Lo: 1011, Hi: 1017, Stride: 6}, + {Lo: 1018, Hi: 1029, Stride: 11}, + {Lo: 1030, Hi: 1032, Stride: 2}, + {Lo: 1109, Hi: 1110, Stride: 1}, + {Lo: 1112, Hi: 1121, Stride: 9}, + {Lo: 1140, Hi: 1141, Stride: 1}, + {Lo: 1198, Hi: 1199, Stride: 1}, + {Lo: 1211, Hi: 1213, Stride: 2}, + {Lo: 1216, Hi: 1231, Stride: 15}, + {Lo: 1248, Hi: 1281, Stride: 33}, + {Lo: 1292, Hi: 1307, Stride: 15}, + {Lo: 1308, Hi: 1309, Stride: 1}, + {Lo: 1357, Hi: 1359, Stride: 2}, + {Lo: 1365, Hi: 1370, Stride: 5}, + {Lo: 1373, Hi: 1377, Stride: 4}, + {Lo: 1379, Hi: 1382, Stride: 3}, + {Lo: 1392, Hi: 1400, Stride: 8}, + {Lo: 1404, Hi: 1405, Stride: 1}, + {Lo: 1409, Hi: 1412, Stride: 3}, + {Lo: 1413, Hi: 1417, Stride: 4}, + {Lo: 1472, Hi: 1475, Stride: 3}, + {Lo: 1493, Hi: 1496, Stride: 3}, + {Lo: 1497, Hi: 1503, Stride: 6}, + {Lo: 1505, Hi: 1523, Stride: 18}, + {Lo: 1549, Hi: 1575, Stride: 26}, + {Lo: 1607, Hi: 1632, Stride: 25}, + {Lo: 1633, Hi: 1637, Stride: 4}, + {Lo: 1639, Hi: 1643, Stride: 4}, + {Lo: 1645, Hi: 1726, Stride: 81}, + {Lo: 1729, Hi: 1748, Stride: 19}, + {Lo: 1749, Hi: 1776, Stride: 27}, + {Lo: 1777, Hi: 1781, Stride: 4}, + {Lo: 1783, Hi: 1793, Stride: 10}, + {Lo: 1794, Hi: 1796, Stride: 1}, + {Lo: 1984, Hi: 1994, Stride: 10}, + {Lo: 2036, Hi: 2037, Stride: 1}, + {Lo: 2042, Hi: 2307, Stride: 265}, + {Lo: 2406, Hi: 2429, Stride: 23}, + {Lo: 2534, Hi: 2538, Stride: 4}, + {Lo: 2541, Hi: 2662, Stride: 121}, + {Lo: 2663, Hi: 2666, Stride: 3}, + {Lo: 2691, Hi: 2790, Stride: 99}, + {Lo: 2819, Hi: 2848, Stride: 29}, + {Lo: 2918, Hi: 2920, Stride: 2}, + {Lo: 3046, Hi: 3074, Stride: 28}, + {Lo: 3174, Hi: 3202, Stride: 28}, + {Lo: 3302, Hi: 3330, Stride: 28}, + {Lo: 3360, Hi: 3430, Stride: 70}, + {Lo: 3437, Hi: 3458, Stride: 21}, + {Lo: 3664, Hi: 3792, Stride: 128}, + {Lo: 4125, Hi: 4160, Stride: 35}, + {Lo: 4327, Hi: 4351, Stride: 24}, + {Lo: 4608, Hi: 5024, Stride: 208}, + {Lo: 5025, Hi: 5026, Stride: 1}, + {Lo: 5029, Hi: 5033, Stride: 4}, + {Lo: 5034, Hi: 5036, Stride: 1}, + {Lo: 5038, Hi: 5043, Stride: 5}, + {Lo: 5047, Hi: 5051, Stride: 4}, + {Lo: 5053, Hi: 5056, Stride: 3}, + {Lo: 5058, Hi: 5059, Stride: 1}, + {Lo: 5070, Hi: 5071, Stride: 1}, + {Lo: 5074, Hi: 5076, Stride: 2}, + {Lo: 5077, Hi: 5081, Stride: 4}, + {Lo: 5082, Hi: 5086, Stride: 4}, + {Lo: 5087, Hi: 5090, Stride: 3}, + {Lo: 5094, Hi: 5095, Stride: 1}, + {Lo: 5102, Hi: 5107, Stride: 5}, + {Lo: 5108, Hi: 5120, Stride: 12}, + {Lo: 5167, Hi: 5171, Stride: 4}, + {Lo: 5176, Hi: 5194, Stride: 18}, + {Lo: 5196, Hi: 5229, Stride: 33}, + {Lo: 5231, Hi: 5234, Stride: 3}, + {Lo: 5261, Hi: 5290, Stride: 29}, + {Lo: 5311, Hi: 5441, Stride: 130}, + {Lo: 5500, Hi: 5501, Stride: 1}, + {Lo: 5511, Hi: 5551, Stride: 40}, + {Lo: 5556, Hi: 5573, Stride: 17}, + {Lo: 5598, Hi: 5610, Stride: 12}, + {Lo: 5616, Hi: 5623, Stride: 7}, + {Lo: 5741, Hi: 5742, Stride: 1}, + {Lo: 5760, Hi: 5810, Stride: 50}, + {Lo: 5815, Hi: 5825, Stride: 10}, + {Lo: 5836, Hi: 5845, Stride: 9}, + {Lo: 5846, Hi: 5868, Stride: 22}, + {Lo: 5869, Hi: 5941, Stride: 72}, + {Lo: 6147, Hi: 6153, Stride: 6}, + {Lo: 7428, Hi: 7439, Stride: 11}, + {Lo: 7441, Hi: 7452, Stride: 11}, + {Lo: 7456, Hi: 7458, Stride: 1}, + {Lo: 7462, Hi: 7555, Stride: 93}, + {Lo: 7564, Hi: 7837, Stride: 273}, + {Lo: 7935, Hi: 8125, Stride: 190}, + {Lo: 8126, Hi: 8128, Stride: 1}, + {Lo: 8175, Hi: 8189, Stride: 14}, + {Lo: 8190, Hi: 8192, Stride: 2}, + {Lo: 8193, Hi: 8202, Stride: 1}, + {Lo: 8208, Hi: 8210, Stride: 1}, + {Lo: 8218, Hi: 8219, Stride: 1}, + {Lo: 8228, Hi: 8232, Stride: 4}, + {Lo: 8233, Hi: 8239, Stride: 6}, + {Lo: 8242, Hi: 8249, Stride: 7}, + {Lo: 8250, Hi: 8257, Stride: 7}, + {Lo: 8259, Hi: 8260, Stride: 1}, + {Lo: 8270, Hi: 8275, Stride: 5}, + {Lo: 8282, Hi: 8287, Stride: 5}, + {Lo: 8450, Hi: 8458, Stride: 8}, + {Lo: 8459, Hi: 8462, Stride: 1}, + {Lo: 8464, Hi: 8467, Stride: 1}, + {Lo: 8469, Hi: 8473, Stride: 4}, + {Lo: 8474, Hi: 8477, Stride: 1}, + {Lo: 8484, Hi: 8488, Stride: 4}, + {Lo: 8490, Hi: 8492, Stride: 2}, + {Lo: 8493, Hi: 8497, Stride: 1}, + {Lo: 8499, Hi: 8500, Stride: 1}, + {Lo: 8505, Hi: 8509, Stride: 4}, + {Lo: 8517, Hi: 8521, Stride: 1}, + {Lo: 8544, Hi: 8548, Stride: 4}, + {Lo: 8553, Hi: 8556, Stride: 3}, + {Lo: 8557, Hi: 8560, Stride: 1}, + {Lo: 8564, Hi: 8569, Stride: 5}, + {Lo: 8572, Hi: 8574, Stride: 1}, + {Lo: 8722, Hi: 8725, Stride: 3}, + {Lo: 8726, Hi: 8727, Stride: 1}, + {Lo: 8739, Hi: 8744, Stride: 5}, + {Lo: 8746, Hi: 8758, Stride: 12}, + {Lo: 8764, Hi: 8868, Stride: 104}, + {Lo: 8897, Hi: 8899, Stride: 2}, + {Lo: 8959, Hi: 9075, Stride: 116}, + {Lo: 9076, Hi: 9082, Stride: 6}, + {Lo: 9213, Hi: 9585, Stride: 372}, + {Lo: 9587, Hi: 10088, Stride: 501}, + {Lo: 10089, Hi: 10094, Stride: 5}, + {Lo: 10095, Hi: 10098, Stride: 3}, + {Lo: 10099, Hi: 10101, Stride: 1}, + {Lo: 10133, Hi: 10134, Stride: 1}, + {Lo: 10187, Hi: 10189, Stride: 2}, + {Lo: 10201, Hi: 10539, Stride: 338}, + {Lo: 10540, Hi: 10741, Stride: 201}, + {Lo: 10744, Hi: 10745, Stride: 1}, + {Lo: 10799, Hi: 11397, Stride: 598}, + {Lo: 11406, Hi: 11410, Stride: 4}, + {Lo: 11412, Hi: 11416, Stride: 4}, + {Lo: 11418, Hi: 11422, Stride: 4}, + {Lo: 11423, Hi: 11426, Stride: 3}, + {Lo: 11427, Hi: 11430, Stride: 1}, + {Lo: 11432, Hi: 11436, Stride: 4}, + {Lo: 11450, Hi: 11462, Stride: 12}, + {Lo: 11466, Hi: 11468, Stride: 2}, + {Lo: 11472, Hi: 11474, Stride: 2}, + {Lo: 11576, Hi: 11577, Stride: 1}, + {Lo: 11599, Hi: 11601, Stride: 2}, + {Lo: 11604, Hi: 11605, Stride: 1}, + {Lo: 11613, Hi: 11840, Stride: 227}, + {Lo: 12034, Hi: 12035, Stride: 1}, + {Lo: 12295, Hi: 12308, Stride: 13}, + {Lo: 12309, Hi: 12339, Stride: 30}, + {Lo: 12448, Hi: 12755, Stride: 307}, + {Lo: 12756, Hi: 20022, Stride: 7266}, + {Lo: 20031, Hi: 42192, Stride: 22161}, + {Lo: 42193, Hi: 42196, Stride: 1}, + {Lo: 42198, Hi: 42199, Stride: 1}, + {Lo: 42201, Hi: 42202, Stride: 1}, + {Lo: 42204, Hi: 42205, Stride: 1}, + {Lo: 42207, Hi: 42211, Stride: 1}, + {Lo: 42214, Hi: 42215, Stride: 1}, + {Lo: 42218, Hi: 42220, Stride: 1}, + {Lo: 42222, Hi: 42226, Stride: 2}, + {Lo: 42227, Hi: 42228, Stride: 1}, + {Lo: 42232, Hi: 42233, Stride: 1}, + {Lo: 42237, Hi: 42239, Stride: 2}, + {Lo: 42510, Hi: 42564, Stride: 54}, + {Lo: 42567, Hi: 42719, Stride: 152}, + {Lo: 42731, Hi: 42735, Stride: 4}, + {Lo: 42801, Hi: 42842, Stride: 41}, + {Lo: 42858, Hi: 42862, Stride: 4}, + {Lo: 42872, Hi: 42889, Stride: 17}, + {Lo: 42892, Hi: 42904, Stride: 12}, + {Lo: 42905, Hi: 42911, Stride: 6}, + {Lo: 42923, Hi: 42930, Stride: 7}, + {Lo: 42931, Hi: 42932, Stride: 1}, + {Lo: 43826, Hi: 43829, Stride: 3}, + {Lo: 43837, Hi: 43847, Stride: 10}, + {Lo: 43848, Hi: 43854, Stride: 6}, + {Lo: 43858, Hi: 43866, Stride: 8}, + {Lo: 43893, Hi: 43905, Stride: 12}, + {Lo: 43907, Hi: 43923, Stride: 16}, + {Lo: 43945, Hi: 43946, Stride: 1}, + {Lo: 43951, Hi: 64422, Stride: 20471}, + {Lo: 64423, Hi: 64429, Stride: 1}, + {Lo: 64830, Hi: 64831, Stride: 1}, + {Lo: 65072, Hi: 65101, Stride: 29}, + {Lo: 65102, Hi: 65103, Stride: 1}, + {Lo: 65112, Hi: 65128, Stride: 16}, + {Lo: 65165, Hi: 65166, Stride: 1}, + {Lo: 65257, Hi: 65260, Stride: 1}, + {Lo: 65282, Hi: 65284, Stride: 2}, + {Lo: 65285, Hi: 65287, Stride: 1}, + {Lo: 65290, Hi: 65291, Stride: 1}, + {Lo: 65293, Hi: 65305, Stride: 1}, + {Lo: 65308, Hi: 65310, Stride: 1}, + {Lo: 65312, Hi: 65373, Stride: 1}, + {Lo: 65512, Hi: 65512, Stride: 1}, + }, + R32: []unicode.Range32{ + {Lo: 66178, Hi: 66182, Stride: 4}, + {Lo: 66183, Hi: 66186, Stride: 3}, + {Lo: 66192, Hi: 66194, Stride: 2}, + {Lo: 66197, Hi: 66199, Stride: 1}, + {Lo: 66203, Hi: 66208, Stride: 5}, + {Lo: 66209, Hi: 66210, Stride: 1}, + {Lo: 66213, Hi: 66219, Stride: 6}, + {Lo: 66224, Hi: 66226, Stride: 1}, + {Lo: 66228, Hi: 66255, Stride: 27}, + {Lo: 66293, Hi: 66305, Stride: 12}, + {Lo: 66306, Hi: 66313, Stride: 7}, + {Lo: 66321, Hi: 66325, Stride: 4}, + {Lo: 66327, Hi: 66330, Stride: 3}, + {Lo: 66335, Hi: 66336, Stride: 1}, + {Lo: 66338, Hi: 66564, Stride: 226}, + {Lo: 66581, Hi: 66587, Stride: 6}, + {Lo: 66592, Hi: 66604, Stride: 12}, + {Lo: 66621, Hi: 66632, Stride: 11}, + {Lo: 66740, Hi: 66754, Stride: 14}, + {Lo: 66766, Hi: 66770, Stride: 4}, + {Lo: 66794, Hi: 66806, Stride: 12}, + {Lo: 66835, Hi: 66838, Stride: 3}, + {Lo: 66840, Hi: 66844, Stride: 4}, + {Lo: 66845, Hi: 66853, Stride: 8}, + {Lo: 66854, Hi: 66855, Stride: 1}, + {Lo: 68176, Hi: 70864, Stride: 2688}, + {Lo: 71430, Hi: 71438, Stride: 4}, + {Lo: 71439, Hi: 71840, Stride: 401}, + {Lo: 71842, Hi: 71844, Stride: 1}, + {Lo: 71846, Hi: 71852, Stride: 3}, + {Lo: 71854, Hi: 71855, Stride: 1}, + {Lo: 71858, Hi: 71867, Stride: 3}, + {Lo: 71868, Hi: 71872, Stride: 4}, + {Lo: 71873, Hi: 71876, Stride: 1}, + {Lo: 71878, Hi: 71884, Stride: 2}, + {Lo: 71893, Hi: 71896, Stride: 1}, + {Lo: 71900, Hi: 71904, Stride: 4}, + {Lo: 71909, Hi: 71910, Stride: 1}, + {Lo: 71913, Hi: 71922, Stride: 3}, + {Lo: 93960, Hi: 93962, Stride: 2}, + {Lo: 93974, Hi: 93992, Stride: 18}, + {Lo: 94005, Hi: 94010, Stride: 5}, + {Lo: 94011, Hi: 94015, Stride: 4}, + {Lo: 94016, Hi: 94018, Stride: 2}, + {Lo: 94019, Hi: 94033, Stride: 14}, + {Lo: 94034, Hi: 119060, Stride: 25026}, + {Lo: 119149, Hi: 119302, Stride: 153}, + {Lo: 119309, Hi: 119311, Stride: 2}, + {Lo: 119314, Hi: 119315, Stride: 1}, + {Lo: 119318, Hi: 119338, Stride: 20}, + {Lo: 119350, Hi: 119351, Stride: 1}, + {Lo: 119354, Hi: 119355, Stride: 1}, + {Lo: 119808, Hi: 119845, Stride: 1}, + {Lo: 119847, Hi: 119892, Stride: 1}, + {Lo: 119894, Hi: 119897, Stride: 1}, + {Lo: 119899, Hi: 119949, Stride: 1}, + {Lo: 119951, Hi: 119964, Stride: 1}, + {Lo: 119966, Hi: 119967, Stride: 1}, + {Lo: 119970, Hi: 119973, Stride: 3}, + {Lo: 119974, Hi: 119977, Stride: 3}, + {Lo: 119978, Hi: 119980, Stride: 1}, + {Lo: 119982, Hi: 119993, Stride: 1}, + {Lo: 119995, Hi: 119997, Stride: 2}, + {Lo: 119998, Hi: 120001, Stride: 1}, + {Lo: 120003, Hi: 120005, Stride: 2}, + {Lo: 120006, Hi: 120053, Stride: 1}, + {Lo: 120055, Hi: 120069, Stride: 1}, + {Lo: 120071, Hi: 120074, Stride: 1}, + {Lo: 120077, Hi: 120084, Stride: 1}, + {Lo: 120086, Hi: 120092, Stride: 1}, + {Lo: 120094, Hi: 120105, Stride: 1}, + {Lo: 120107, Hi: 120121, Stride: 1}, + {Lo: 120123, Hi: 120126, Stride: 1}, + {Lo: 120128, Hi: 120132, Stride: 1}, + {Lo: 120134, Hi: 120138, Stride: 4}, + {Lo: 120139, Hi: 120144, Stride: 1}, + {Lo: 120146, Hi: 120157, Stride: 1}, + {Lo: 120159, Hi: 120209, Stride: 1}, + {Lo: 120211, Hi: 120261, Stride: 1}, + {Lo: 120263, Hi: 120313, Stride: 1}, + {Lo: 120315, Hi: 120365, Stride: 1}, + {Lo: 120367, Hi: 120417, Stride: 1}, + {Lo: 120419, Hi: 120469, Stride: 1}, + {Lo: 120471, Hi: 120484, Stride: 1}, + {Lo: 120488, Hi: 120489, Stride: 1}, + {Lo: 120492, Hi: 120494, Stride: 1}, + {Lo: 120496, Hi: 120497, Stride: 1}, + {Lo: 120499, Hi: 120500, Stride: 1}, + {Lo: 120502, Hi: 120504, Stride: 2}, + {Lo: 120507, Hi: 120508, Stride: 1}, + {Lo: 120510, Hi: 120514, Stride: 4}, + {Lo: 120516, Hi: 120522, Stride: 6}, + {Lo: 120526, Hi: 120534, Stride: 2}, + {Lo: 120544, Hi: 120546, Stride: 2}, + {Lo: 120547, Hi: 120550, Stride: 3}, + {Lo: 120551, Hi: 120552, Stride: 1}, + {Lo: 120554, Hi: 120555, Stride: 1}, + {Lo: 120557, Hi: 120558, Stride: 1}, + {Lo: 120560, Hi: 120562, Stride: 2}, + {Lo: 120565, Hi: 120566, Stride: 1}, + {Lo: 120568, Hi: 120572, Stride: 4}, + {Lo: 120574, Hi: 120580, Stride: 6}, + {Lo: 120584, Hi: 120592, Stride: 2}, + {Lo: 120602, Hi: 120604, Stride: 2}, + {Lo: 120605, Hi: 120608, Stride: 3}, + {Lo: 120609, Hi: 120610, Stride: 1}, + {Lo: 120612, Hi: 120613, Stride: 1}, + {Lo: 120615, Hi: 120616, Stride: 1}, + {Lo: 120618, Hi: 120620, Stride: 2}, + {Lo: 120623, Hi: 120624, Stride: 1}, + {Lo: 120626, Hi: 120630, Stride: 4}, + {Lo: 120632, Hi: 120638, Stride: 6}, + {Lo: 120642, Hi: 120650, Stride: 2}, + {Lo: 120660, Hi: 120662, Stride: 2}, + {Lo: 120663, Hi: 120666, Stride: 3}, + {Lo: 120667, Hi: 120668, Stride: 1}, + {Lo: 120670, Hi: 120671, Stride: 1}, + {Lo: 120673, Hi: 120674, Stride: 1}, + {Lo: 120676, Hi: 120678, Stride: 2}, + {Lo: 120681, Hi: 120682, Stride: 1}, + {Lo: 120684, Hi: 120688, Stride: 4}, + {Lo: 120690, Hi: 120696, Stride: 6}, + {Lo: 120700, Hi: 120708, Stride: 2}, + {Lo: 120718, Hi: 120720, Stride: 2}, + {Lo: 120721, Hi: 120724, Stride: 3}, + {Lo: 120725, Hi: 120726, Stride: 1}, + {Lo: 120728, Hi: 120729, Stride: 1}, + {Lo: 120731, Hi: 120732, Stride: 1}, + {Lo: 120734, Hi: 120736, Stride: 2}, + {Lo: 120739, Hi: 120740, Stride: 1}, + {Lo: 120742, Hi: 120746, Stride: 4}, + {Lo: 120748, Hi: 120754, Stride: 6}, + {Lo: 120758, Hi: 120766, Stride: 2}, + {Lo: 120776, Hi: 120778, Stride: 2}, + {Lo: 120782, Hi: 120831, Stride: 1}, + {Lo: 125127, Hi: 125131, Stride: 4}, + {Lo: 126464, Hi: 126500, Stride: 36}, + {Lo: 126564, Hi: 126592, Stride: 28}, + {Lo: 126596, Hi: 128844, Stride: 2248}, + {Lo: 128872, Hi: 130032, Stride: 1160}, + {Lo: 130033, Hi: 130041, Stride: 1}, + }, + LatinOffset: 0, + }, + }, + "_default": { + Confusable: []rune{160, 180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{32, 96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "_default", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 160, Hi: 180, Stride: 20}, + {Lo: 215, Hi: 305, Stride: 90}, + {Lo: 921, Hi: 1009, Stride: 88}, + {Lo: 1040, Hi: 1042, Stride: 2}, + {Lo: 1045, Hi: 1047, Stride: 2}, + {Lo: 1050, Hi: 1052, Stride: 2}, + {Lo: 1053, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8211, Hi: 8216, Stride: 5}, + {Lo: 8217, Hi: 8245, Stride: 28}, + {Lo: 12494, Hi: 65281, Stride: 52787}, + {Lo: 65283, Hi: 65288, Stride: 5}, + {Lo: 65289, Hi: 65292, Stride: 3}, + {Lo: 65306, Hi: 65307, Stride: 1}, + {Lo: 65311, Hi: 65374, Stride: 63}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "cs": { + Confusable: []rune{180, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{96, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "cs", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 305, Stride: 125}, + {Lo: 921, Hi: 1009, Stride: 88}, + {Lo: 1040, Hi: 1042, Stride: 2}, + {Lo: 1045, Hi: 1047, Stride: 2}, + {Lo: 1050, Hi: 1052, Stride: 2}, + {Lo: 1053, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8216, Hi: 8217, Stride: 1}, + {Lo: 8245, Hi: 12494, Stride: 4249}, + {Lo: 65281, Hi: 65283, Stride: 2}, + {Lo: 65288, Hi: 65289, Stride: 1}, + {Lo: 65292, Hi: 65306, Stride: 14}, + {Lo: 65307, Hi: 65311, Stride: 4}, + {Lo: 65374, Hi: 65374, Stride: 1}, + }, + R32: []unicode.Range32{}, + LatinOffset: 0, + }, + }, + "de": { + Confusable: []rune{180, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{96, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "de", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 305, Stride: 125}, + {Lo: 921, Hi: 1009, Stride: 88}, + {Lo: 1040, Hi: 1042, Stride: 2}, + {Lo: 1045, Hi: 1047, Stride: 2}, + {Lo: 1050, Hi: 1052, Stride: 2}, + {Lo: 1053, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8216, Hi: 8217, Stride: 1}, + {Lo: 8245, Hi: 12494, Stride: 4249}, + {Lo: 65281, Hi: 65283, Stride: 2}, + {Lo: 65288, Hi: 65289, Stride: 1}, + {Lo: 65292, Hi: 65306, Stride: 14}, + {Lo: 65307, Hi: 65311, Stride: 4}, + {Lo: 65374, Hi: 65374, Stride: 1}, + }, + R32: []unicode.Range32{}, + LatinOffset: 0, + }, + }, + "es": { + Confusable: []rune{180, 215, 305, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{96, 120, 105, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "es", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 215, Stride: 35}, + {Lo: 305, Hi: 1009, Stride: 704}, + {Lo: 1040, Hi: 1042, Stride: 2}, + {Lo: 1045, Hi: 1047, Stride: 2}, + {Lo: 1050, Hi: 1052, Stride: 2}, + {Lo: 1053, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8211, Hi: 8245, Stride: 34}, + {Lo: 12494, Hi: 65281, Stride: 52787}, + {Lo: 65283, Hi: 65288, Stride: 5}, + {Lo: 65289, Hi: 65292, Stride: 3}, + {Lo: 65306, Hi: 65307, Stride: 1}, + {Lo: 65311, Hi: 65374, Stride: 63}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "fr": { + Confusable: []rune{215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "fr", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 215, Hi: 305, Stride: 90}, + {Lo: 921, Hi: 1009, Stride: 88}, + {Lo: 1040, Hi: 1042, Stride: 2}, + {Lo: 1045, Hi: 1047, Stride: 2}, + {Lo: 1050, Hi: 1052, Stride: 2}, + {Lo: 1053, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8216, Hi: 8245, Stride: 29}, + {Lo: 12494, Hi: 65281, Stride: 52787}, + {Lo: 65283, Hi: 65288, Stride: 5}, + {Lo: 65289, Hi: 65292, Stride: 3}, + {Lo: 65306, Hi: 65307, Stride: 1}, + {Lo: 65311, Hi: 65374, Stride: 63}, + }, + R32: []unicode.Range32{}, + LatinOffset: 0, + }, + }, + "it": { + Confusable: []rune{160, 180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8216, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{32, 96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "it", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 160, Hi: 180, Stride: 20}, + {Lo: 215, Hi: 305, Stride: 90}, + {Lo: 921, Hi: 1009, Stride: 88}, + {Lo: 1040, Hi: 1042, Stride: 2}, + {Lo: 1045, Hi: 1047, Stride: 2}, + {Lo: 1050, Hi: 1052, Stride: 2}, + {Lo: 1053, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8211, Hi: 8216, Stride: 5}, + {Lo: 8245, Hi: 12494, Stride: 4249}, + {Lo: 65281, Hi: 65283, Stride: 2}, + {Lo: 65288, Hi: 65289, Stride: 1}, + {Lo: 65292, Hi: 65306, Stride: 14}, + {Lo: 65307, Hi: 65311, Stride: 4}, + {Lo: 65374, Hi: 65374, Stride: 1}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "ja": { + Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8216, 8217, 8245, 65281, 65283, 65292, 65306, 65307}, + With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 96, 96, 33, 35, 44, 58, 59}, + Locale: "ja", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 215, Stride: 35}, + {Lo: 305, Hi: 921, Stride: 616}, + {Lo: 1009, Hi: 1040, Stride: 31}, + {Lo: 1042, Hi: 1045, Stride: 3}, + {Lo: 1047, Hi: 1050, Stride: 3}, + {Lo: 1052, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8211, Hi: 8216, Stride: 5}, + {Lo: 8217, Hi: 8245, Stride: 28}, + {Lo: 65281, Hi: 65283, Stride: 2}, + {Lo: 65292, Hi: 65306, Stride: 14}, + {Lo: 65307, Hi: 65307, Stride: 1}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "ko": { + Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "ko", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 215, Stride: 35}, + {Lo: 305, Hi: 921, Stride: 616}, + {Lo: 1009, Hi: 1040, Stride: 31}, + {Lo: 1042, Hi: 1045, Stride: 3}, + {Lo: 1047, Hi: 1050, Stride: 3}, + {Lo: 1052, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8211, Hi: 8245, Stride: 34}, + {Lo: 12494, Hi: 65281, Stride: 52787}, + {Lo: 65283, Hi: 65288, Stride: 5}, + {Lo: 65289, Hi: 65292, Stride: 3}, + {Lo: 65306, Hi: 65307, Stride: 1}, + {Lo: 65311, Hi: 65374, Stride: 63}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "pl": { + Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "pl", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 215, Stride: 35}, + {Lo: 305, Hi: 921, Stride: 616}, + {Lo: 1009, Hi: 1040, Stride: 31}, + {Lo: 1042, Hi: 1045, Stride: 3}, + {Lo: 1047, Hi: 1050, Stride: 3}, + {Lo: 1052, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8216, Hi: 8217, Stride: 1}, + {Lo: 8245, Hi: 12494, Stride: 4249}, + {Lo: 65281, Hi: 65283, Stride: 2}, + {Lo: 65288, Hi: 65289, Stride: 1}, + {Lo: 65292, Hi: 65306, Stride: 14}, + {Lo: 65307, Hi: 65311, Stride: 4}, + {Lo: 65374, Hi: 65374, Stride: 1}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "pt-BR": { + Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "pt-BR", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 215, Stride: 35}, + {Lo: 305, Hi: 921, Stride: 616}, + {Lo: 1009, Hi: 1040, Stride: 31}, + {Lo: 1042, Hi: 1045, Stride: 3}, + {Lo: 1047, Hi: 1050, Stride: 3}, + {Lo: 1052, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8216, Hi: 8217, Stride: 1}, + {Lo: 8245, Hi: 12494, Stride: 4249}, + {Lo: 65281, Hi: 65283, Stride: 2}, + {Lo: 65288, Hi: 65289, Stride: 1}, + {Lo: 65292, Hi: 65306, Stride: 14}, + {Lo: 65307, Hi: 65311, Stride: 4}, + {Lo: 65374, Hi: 65374, Stride: 1}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "qps-ploc": { + Confusable: []rune{160, 180, 215, 305, 921, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{32, 96, 120, 105, 73, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "qps-ploc", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 160, Hi: 180, Stride: 20}, + {Lo: 215, Hi: 305, Stride: 90}, + {Lo: 921, Hi: 1040, Stride: 119}, + {Lo: 1042, Hi: 1045, Stride: 3}, + {Lo: 1047, Hi: 1050, Stride: 3}, + {Lo: 1052, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8211, Hi: 8216, Stride: 5}, + {Lo: 8217, Hi: 8245, Stride: 28}, + {Lo: 12494, Hi: 65281, Stride: 52787}, + {Lo: 65283, Hi: 65288, Stride: 5}, + {Lo: 65289, Hi: 65292, Stride: 3}, + {Lo: 65306, Hi: 65307, Stride: 1}, + {Lo: 65311, Hi: 65374, Stride: 63}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "ru": { + Confusable: []rune{180, 215, 305, 921, 1009, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{96, 120, 105, 73, 112, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "ru", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 215, Stride: 35}, + {Lo: 305, Hi: 921, Stride: 616}, + {Lo: 1009, Hi: 8216, Stride: 7207}, + {Lo: 8217, Hi: 8245, Stride: 28}, + {Lo: 12494, Hi: 65281, Stride: 52787}, + {Lo: 65283, Hi: 65288, Stride: 5}, + {Lo: 65289, Hi: 65292, Stride: 3}, + {Lo: 65306, Hi: 65307, Stride: 1}, + {Lo: 65311, Hi: 65374, Stride: 63}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "tr": { + Confusable: []rune{160, 180, 215, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374}, + With: []rune{32, 96, 120, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126}, + Locale: "tr", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 160, Hi: 180, Stride: 20}, + {Lo: 215, Hi: 921, Stride: 706}, + {Lo: 1009, Hi: 1040, Stride: 31}, + {Lo: 1042, Hi: 1045, Stride: 3}, + {Lo: 1047, Hi: 1050, Stride: 3}, + {Lo: 1052, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8211, Hi: 8245, Stride: 34}, + {Lo: 12494, Hi: 65281, Stride: 52787}, + {Lo: 65283, Hi: 65288, Stride: 5}, + {Lo: 65289, Hi: 65292, Stride: 3}, + {Lo: 65306, Hi: 65307, Stride: 1}, + {Lo: 65311, Hi: 65374, Stride: 63}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "zh-hans": { + Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8245, 12494, 65281, 65288, 65289, 65306, 65374}, + With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 47, 33, 40, 41, 58, 126}, + Locale: "zh-hans", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 215, Stride: 35}, + {Lo: 305, Hi: 921, Stride: 616}, + {Lo: 1009, Hi: 1040, Stride: 31}, + {Lo: 1042, Hi: 1045, Stride: 3}, + {Lo: 1047, Hi: 1050, Stride: 3}, + {Lo: 1052, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8245, Hi: 12494, Stride: 4249}, + {Lo: 65281, Hi: 65288, Stride: 7}, + {Lo: 65289, Hi: 65306, Stride: 17}, + {Lo: 65374, Hi: 65374, Stride: 1}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, + "zh-hant": { + Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 12494, 65283, 65307, 65374}, + With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 47, 35, 59, 126}, + Locale: "zh-hant", + RangeTable: &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 180, Hi: 215, Stride: 35}, + {Lo: 305, Hi: 921, Stride: 616}, + {Lo: 1009, Hi: 1040, Stride: 31}, + {Lo: 1042, Hi: 1045, Stride: 3}, + {Lo: 1047, Hi: 1050, Stride: 3}, + {Lo: 1052, Hi: 1054, Stride: 1}, + {Lo: 1056, Hi: 1059, Stride: 1}, + {Lo: 1061, Hi: 1068, Stride: 7}, + {Lo: 1072, Hi: 1073, Stride: 1}, + {Lo: 1075, Hi: 1077, Stride: 2}, + {Lo: 1086, Hi: 1088, Stride: 2}, + {Lo: 1089, Hi: 1093, Stride: 2}, + {Lo: 8211, Hi: 12494, Stride: 4283}, + {Lo: 65283, Hi: 65307, Stride: 24}, + {Lo: 65374, Hi: 65374, Stride: 1}, + }, + R32: []unicode.Range32{}, + LatinOffset: 1, + }, + }, +} diff --git a/modules/charset/ambiguous_gen_test.go b/modules/charset/ambiguous_gen_test.go new file mode 100644 index 0000000000..bd64e1c5b1 --- /dev/null +++ b/modules/charset/ambiguous_gen_test.go @@ -0,0 +1,32 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import ( + "sort" + "testing" + "unicode" + + "github.com/stretchr/testify/assert" +) + +func TestAmbiguousCharacters(t *testing.T) { + for locale, ambiguous := range AmbiguousCharacters { + assert.Equal(t, locale, ambiguous.Locale) + assert.Equal(t, len(ambiguous.Confusable), len(ambiguous.With)) + assert.True(t, sort.SliceIsSorted(ambiguous.Confusable, func(i, j int) bool { + return ambiguous.Confusable[i] < ambiguous.Confusable[j] + })) + + for _, confusable := range ambiguous.Confusable { + assert.True(t, unicode.Is(ambiguous.RangeTable, confusable)) + i := sort.Search(len(ambiguous.Confusable), func(j int) bool { + return ambiguous.Confusable[j] >= confusable + }) + found := i < len(ambiguous.Confusable) && ambiguous.Confusable[i] == confusable + assert.True(t, found, "%c is not in %d", confusable, i) + } + } +} diff --git a/modules/charset/breakwriter.go b/modules/charset/breakwriter.go new file mode 100644 index 0000000000..619826ff21 --- /dev/null +++ b/modules/charset/breakwriter.go @@ -0,0 +1,44 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import ( + "bytes" + "io" +) + +// BreakWriter wraps an io.Writer to always write '\n' as '
' +type BreakWriter struct { + io.Writer +} + +// Write writes the provided byte slice transparently replacing '\n' with '
' +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("
")); err != nil { + return n, err + } + pos += idx + 1 + + n++ + } + + return n, err +} diff --git a/modules/charset/breakwriter_test.go b/modules/charset/breakwriter_test.go new file mode 100644 index 0000000000..6bbed42ea5 --- /dev/null +++ b/modules/charset/breakwriter_test.go @@ -0,0 +1,69 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package 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
", + }, + { + name: "startline", + kase: "\nabcdefghijklmnopqrstuvwxyz", + expect: "
abcdefghijklmnopqrstuvwxyz", + }, + { + name: "onlyline", + kase: "\n\n\n", + expect: "


", + }, + { + name: "empty", + kase: "", + expect: "", + }, + { + name: "midline", + kase: "\nabc\ndefghijkl\nmnopqrstuvwxy\nz", + expect: "
abc
defghijkl
mnopqrstuvwxy
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) + } + }) + } +} diff --git a/modules/charset/escape.go b/modules/charset/escape.go index 9c1baafba3..b264a569ff 100644 --- a/modules/charset/escape.go +++ b/modules/charset/escape.go @@ -1,236 +1,58 @@ -// Copyright 2021 The Gitea Authors. All rights reserved. +// Copyright 2022 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. +//go:generate go run invisible/generate.go -v -o ./invisible_gen.go + +//go:generate go run ambiguous/generate.go -v -o ./ambiguous_gen.go ambiguous/ambiguous.json + package charset import ( - "bytes" - "fmt" "io" "strings" - "unicode" - "unicode/utf8" - "golang.org/x/text/unicode/bidi" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/translation" ) -// EscapeStatus represents the findings of the unicode escaper -type EscapeStatus struct { - Escaped bool - HasError bool - HasBadRunes bool - HasControls bool - HasSpaces bool - HasMarks bool - HasBIDI bool - BadBIDI bool - HasRTLScript bool - HasLTRScript bool +// RuneNBSP is the codepoint for NBSP +const RuneNBSP = 0xa0 + +// EscapeControlHTML escapes the unicode control sequences in a provided html document +func EscapeControlHTML(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) { + sb := &strings.Builder{} + outputStream := &HTMLStreamerWriter{Writer: sb} + streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer) + + if err := StreamHTML(strings.NewReader(text), streamer); err != nil { + streamer.escaped.HasError = true + log.Error("Error whilst escaping: %v", err) + } + return streamer.escaped, sb.String() } -// Or combines two EscapeStatus structs into one representing the conjunction of the two -func (status EscapeStatus) Or(other EscapeStatus) EscapeStatus { - st := status - st.Escaped = st.Escaped || other.Escaped - st.HasError = st.HasError || other.HasError - st.HasBadRunes = st.HasBadRunes || other.HasBadRunes - st.HasControls = st.HasControls || other.HasControls - st.HasSpaces = st.HasSpaces || other.HasSpaces - st.HasMarks = st.HasMarks || other.HasMarks - st.HasBIDI = st.HasBIDI || other.HasBIDI - st.BadBIDI = st.BadBIDI || other.BadBIDI - st.HasRTLScript = st.HasRTLScript || other.HasRTLScript - st.HasLTRScript = st.HasLTRScript || other.HasLTRScript - return st +// EscapeControlReaders escapes the unicode control sequences in a provider reader and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte +func EscapeControlReader(reader io.Reader, writer io.Writer, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, err error) { + outputStream := &HTMLStreamerWriter{Writer: writer} + streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer) + + if err = StreamHTML(reader, streamer); err != nil { + streamer.escaped.HasError = true + log.Error("Error whilst escaping: %v", err) + } + return streamer.escaped, err } // EscapeControlString escapes the unicode control sequences in a provided string and returns the findings as an EscapeStatus and the escaped string -func EscapeControlString(text string) (EscapeStatus, string) { +func EscapeControlString(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) { sb := &strings.Builder{} - escaped, _ := EscapeControlReader(strings.NewReader(text), sb) - return escaped, sb.String() -} + outputStream := &HTMLStreamerWriter{Writer: sb} + streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer) -// EscapeControlBytes escapes the unicode control sequences a provided []byte and returns the findings as an EscapeStatus and the escaped []byte -func EscapeControlBytes(text []byte) (EscapeStatus, []byte) { - buf := &bytes.Buffer{} - escaped, _ := EscapeControlReader(bytes.NewReader(text), buf) - return escaped, buf.Bytes() -} - -// EscapeControlReader escapes the unicode control sequences a provided Reader writing the escaped output to the output and returns the findings as an EscapeStatus and an error -func EscapeControlReader(text io.Reader, output io.Writer) (escaped EscapeStatus, err error) { - buf := make([]byte, 4096) - readStart := 0 - runeCount := 0 - var n int - var writePos int - - lineHasBIDI := false - lineHasRTLScript := false - lineHasLTRScript := false - -readingloop: - for err == nil { - n, err = text.Read(buf[readStart:]) - bs := buf[:n+readStart] - n = len(bs) - i := 0 - - for i < len(bs) { - r, size := utf8.DecodeRune(bs[i:]) - runeCount++ - - // Now handle the codepoints - switch { - case r == utf8.RuneError: - if writePos < i { - if _, err = output.Write(bs[writePos:i]); err != nil { - escaped.HasError = true - return - } - writePos = i - } - // runes can be at most 4 bytes - so... - if len(bs)-i <= 3 { - // if not request more data - copy(buf, bs[i:]) - readStart = n - i - writePos = 0 - continue readingloop - } - // this is a real broken rune - escaped.HasBadRunes = true - escaped.Escaped = true - if err = writeBroken(output, bs[i:i+size]); err != nil { - escaped.HasError = true - return - } - writePos += size - case r == '\n': - if lineHasBIDI && !lineHasRTLScript && lineHasLTRScript { - escaped.BadBIDI = true - } - lineHasBIDI = false - lineHasRTLScript = false - lineHasLTRScript = false - - case runeCount == 1 && r == 0xFEFF: // UTF BOM - // the first BOM is safe - case r == '\r' || r == '\t' || r == ' ': - // These are acceptable control characters and space characters - case unicode.IsSpace(r): - escaped.HasSpaces = true - escaped.Escaped = true - if writePos < i { - if _, err = output.Write(bs[writePos:i]); err != nil { - escaped.HasError = true - return - } - } - if err = writeEscaped(output, r); err != nil { - escaped.HasError = true - return - } - writePos = i + size - case unicode.Is(unicode.Bidi_Control, r): - escaped.Escaped = true - escaped.HasBIDI = true - if writePos < i { - if _, err = output.Write(bs[writePos:i]); err != nil { - escaped.HasError = true - return - } - } - lineHasBIDI = true - if err = writeEscaped(output, r); err != nil { - escaped.HasError = true - return - } - writePos = i + size - case unicode.Is(unicode.C, r): - escaped.Escaped = true - escaped.HasControls = true - if writePos < i { - if _, err = output.Write(bs[writePos:i]); err != nil { - escaped.HasError = true - return - } - } - if err = writeEscaped(output, r); err != nil { - escaped.HasError = true - return - } - writePos = i + size - case unicode.Is(unicode.M, r): - escaped.Escaped = true - escaped.HasMarks = true - if writePos < i { - if _, err = output.Write(bs[writePos:i]); err != nil { - escaped.HasError = true - return - } - } - if err = writeEscaped(output, r); err != nil { - escaped.HasError = true - return - } - writePos = i + size - default: - p, _ := bidi.Lookup(bs[i : i+size]) - c := p.Class() - if c == bidi.R || c == bidi.AL { - lineHasRTLScript = true - escaped.HasRTLScript = true - } else if c == bidi.L { - lineHasLTRScript = true - escaped.HasLTRScript = true - } - } - i += size - } - if n > 0 { - // we read something... - // write everything unwritten - if writePos < i { - if _, err = output.Write(bs[writePos:i]); err != nil { - escaped.HasError = true - return - } - } - - // reset the starting positions for the next read - readStart = 0 - writePos = 0 - } + if err := streamer.Text(text); err != nil { + streamer.escaped.HasError = true + log.Error("Error whilst escaping: %v", err) } - if readStart > 0 { - // this means that there is an incomplete or broken rune at 0-readStart and we read nothing on the last go round - escaped.Escaped = true - escaped.HasBadRunes = true - if err = writeBroken(output, buf[:readStart]); err != nil { - escaped.HasError = true - return - } - } - if err == io.EOF { - if lineHasBIDI && !lineHasRTLScript && lineHasLTRScript { - escaped.BadBIDI = true - } - err = nil - return - } - escaped.HasError = true - return escaped, err -} - -func writeBroken(output io.Writer, bs []byte) (err error) { - _, err = fmt.Fprintf(output, `<%X>`, bs) - return err -} - -func writeEscaped(output io.Writer, r rune) (err error) { - _, err = fmt.Fprintf(output, `%c`, r, r) - return err + return streamer.escaped, sb.String() } diff --git a/modules/charset/escape_status.go b/modules/charset/escape_status.go new file mode 100644 index 0000000000..7ff0ef112b --- /dev/null +++ b/modules/charset/escape_status.go @@ -0,0 +1,28 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +// EscapeStatus represents the findings of the unicode escaper +type EscapeStatus struct { + Escaped bool + HasError bool + HasBadRunes bool + HasInvisible bool + HasAmbiguous bool +} + +// Or combines two EscapeStatus structs into one representing the conjunction of the two +func (status *EscapeStatus) Or(other *EscapeStatus) *EscapeStatus { + st := status + if status == nil { + st = &EscapeStatus{} + } + st.Escaped = st.Escaped || other.Escaped + st.HasError = st.HasError || other.HasError + st.HasBadRunes = st.HasBadRunes || other.HasBadRunes + st.HasAmbiguous = st.HasAmbiguous || other.HasAmbiguous + st.HasInvisible = st.HasInvisible || other.HasInvisible + return st +} diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go new file mode 100644 index 0000000000..8c17136c9d --- /dev/null +++ b/modules/charset/escape_stream.go @@ -0,0 +1,297 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import ( + "fmt" + "regexp" + "sort" + "strings" + "unicode" + "unicode/utf8" + + "code.gitea.io/gitea/modules/translation" + + "golang.org/x/net/html" +) + +// VScode defaultWordRegexp +var defaultWordRegexp = regexp.MustCompile(`(-?\d*\.\d\w*)|([^\` + "`" + `\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s\x00-\x1f]+)`) + +func NewEscapeStreamer(locale translation.Locale, next HTMLStreamer, allowed ...rune) HTMLStreamer { + return &escapeStreamer{ + escaped: &EscapeStatus{}, + PassthroughHTMLStreamer: *NewPassthroughStreamer(next), + locale: locale, + ambiguousTables: AmbiguousTablesForLocale(locale), + allowed: allowed, + } +} + +type escapeStreamer struct { + PassthroughHTMLStreamer + escaped *EscapeStatus + locale translation.Locale + ambiguousTables []*AmbiguousTable + allowed []rune +} + +func (e *escapeStreamer) EscapeStatus() *EscapeStatus { + return e.escaped +} + +// Text tells the next streamer there is a text +func (e *escapeStreamer) Text(data string) error { + sb := &strings.Builder{} + pos, until, next := 0, 0, 0 + if len(data) > len(UTF8BOM) && data[:len(UTF8BOM)] == string(UTF8BOM) { + _, _ = sb.WriteString(data[:len(UTF8BOM)]) + pos = len(UTF8BOM) + } + for pos < len(data) { + nextIdxs := defaultWordRegexp.FindStringIndex(data[pos:]) + if nextIdxs == nil { + until = len(data) + next = until + } else { + until, next = nextIdxs[0]+pos, nextIdxs[1]+pos + } + + // from pos until until we know that the runes are not \r\t\n or even ' ' + runes := make([]rune, 0, next-until) + positions := make([]int, 0, next-until+1) + + for pos < until { + r, sz := utf8.DecodeRune([]byte(data)[pos:]) + positions = positions[:0] + positions = append(positions, pos, pos+sz) + types, confusables, _ := e.runeTypes(r) + if err := e.handleRunes(data, []rune{r}, positions, types, confusables, sb); err != nil { + return err + } + pos += sz + } + + for i := pos; i < next; { + r, sz := utf8.DecodeRune([]byte(data)[i:]) + runes = append(runes, r) + positions = append(positions, i) + i += sz + } + positions = append(positions, next) + types, confusables, runeCounts := e.runeTypes(runes...) + if runeCounts.needsEscape() { + if err := e.handleRunes(data, runes, positions, types, confusables, sb); err != nil { + return err + } + } else { + _, _ = sb.Write([]byte(data)[pos:next]) + } + pos = next + } + if sb.Len() > 0 { + if err := e.PassthroughHTMLStreamer.Text(sb.String()); err != nil { + return err + } + } + return nil +} + +func (e *escapeStreamer) handleRunes(data string, runes []rune, positions []int, types []runeType, confusables []rune, sb *strings.Builder) error { + for i, r := range runes { + switch types[i] { + case brokenRuneType: + if sb.Len() > 0 { + if err := e.PassthroughHTMLStreamer.Text(sb.String()); err != nil { + return err + } + sb.Reset() + } + end := positions[i+1] + start := positions[i] + if err := e.brokenRune([]byte(data)[start:end]); err != nil { + return err + } + case ambiguousRuneType: + if sb.Len() > 0 { + if err := e.PassthroughHTMLStreamer.Text(sb.String()); err != nil { + return err + } + sb.Reset() + } + if err := e.ambiguousRune(r, confusables[0]); err != nil { + return err + } + confusables = confusables[1:] + case invisibleRuneType: + if sb.Len() > 0 { + if err := e.PassthroughHTMLStreamer.Text(sb.String()); err != nil { + return err + } + sb.Reset() + } + if err := e.invisibleRune(r); err != nil { + return err + } + default: + _, _ = sb.WriteRune(r) + } + } + return nil +} + +func (e *escapeStreamer) brokenRune(bs []byte) error { + e.escaped.Escaped = true + e.escaped.HasBadRunes = true + + if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{ + Key: "class", + Val: "broken-code-point", + }); err != nil { + return err + } + if err := e.PassthroughHTMLStreamer.Text(fmt.Sprintf("<%X>", bs)); err != nil { + return err + } + + return e.PassthroughHTMLStreamer.EndTag("span") +} + +func (e *escapeStreamer) ambiguousRune(r, c rune) error { + e.escaped.Escaped = true + e.escaped.HasAmbiguous = true + + if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{ + Key: "class", + Val: "ambiguous-code-point tooltip", + }, html.Attribute{ + Key: "data-content", + Val: e.locale.Tr("repo.ambiguous_character", r, c), + }); err != nil { + return err + } + if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{ + Key: "class", + Val: "char", + }); err != nil { + return err + } + if err := e.PassthroughHTMLStreamer.Text(string(r)); err != nil { + return err + } + if err := e.PassthroughHTMLStreamer.EndTag("span"); err != nil { + return err + } + + return e.PassthroughHTMLStreamer.EndTag("span") +} + +func (e *escapeStreamer) invisibleRune(r rune) error { + e.escaped.Escaped = true + e.escaped.HasInvisible = true + + if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{ + Key: "class", + Val: "escaped-code-point", + }, html.Attribute{ + Key: "data-escaped", + Val: fmt.Sprintf("[U+%04X]", r), + }); err != nil { + return err + } + if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{ + Key: "class", + Val: "char", + }); err != nil { + return err + } + if err := e.PassthroughHTMLStreamer.Text(string(r)); err != nil { + return err + } + if err := e.PassthroughHTMLStreamer.EndTag("span"); err != nil { + return err + } + + return e.PassthroughHTMLStreamer.EndTag("span") +} + +type runeCountType struct { + numBasicRunes int + numNonConfusingNonBasicRunes int + numAmbiguousRunes int + numInvisibleRunes int + numBrokenRunes int +} + +func (counts runeCountType) needsEscape() bool { + if counts.numBrokenRunes > 0 { + return true + } + if counts.numBasicRunes == 0 && + counts.numNonConfusingNonBasicRunes > 0 { + return false + } + return counts.numAmbiguousRunes > 0 || counts.numInvisibleRunes > 0 +} + +type runeType int + +const ( + basicASCIIRuneType runeType = iota //nolint // <- This is technically deadcode but its self-documenting so it should stay + brokenRuneType + nonBasicASCIIRuneType + ambiguousRuneType + invisibleRuneType +) + +func (e *escapeStreamer) runeTypes(runes ...rune) (types []runeType, confusables []rune, runeCounts runeCountType) { + types = make([]runeType, len(runes)) + for i, r := range runes { + var confusable rune + switch { + case r == utf8.RuneError: + types[i] = brokenRuneType + runeCounts.numBrokenRunes++ + case r == ' ' || r == '\t' || r == '\n': + runeCounts.numBasicRunes++ + case e.isAllowed(r): + if r > 0x7e || r < 0x20 { + types[i] = nonBasicASCIIRuneType + runeCounts.numNonConfusingNonBasicRunes++ + } else { + runeCounts.numBasicRunes++ + } + case unicode.Is(InvisibleRanges, r): + types[i] = invisibleRuneType + runeCounts.numInvisibleRunes++ + case unicode.IsControl(r): + types[i] = invisibleRuneType + runeCounts.numInvisibleRunes++ + case isAmbiguous(r, &confusable, e.ambiguousTables...): + confusables = append(confusables, confusable) + types[i] = ambiguousRuneType + runeCounts.numAmbiguousRunes++ + case r > 0x7e || r < 0x20: + types[i] = nonBasicASCIIRuneType + runeCounts.numNonConfusingNonBasicRunes++ + default: + runeCounts.numBasicRunes++ + } + } + return types, confusables, runeCounts +} + +func (e *escapeStreamer) isAllowed(r rune) bool { + if len(e.allowed) == 0 { + return false + } + if len(e.allowed) == 1 { + return e.allowed[0] == r + } + + return sort.Search(len(e.allowed), func(i int) bool { + return e.allowed[i] >= r + }) >= 0 +} diff --git a/modules/charset/escape_test.go b/modules/charset/escape_test.go index 01ccca7724..8063e11542 100644 --- a/modules/charset/escape_test.go +++ b/modules/charset/escape_test.go @@ -8,6 +8,8 @@ import ( "reflect" "strings" "testing" + + "code.gitea.io/gitea/modules/translation" ) type escapeControlTest struct { @@ -25,37 +27,37 @@ var escapeControlTests = []escapeControlTest{ name: "single line western", text: "single line western", result: "single line western", - status: EscapeStatus{HasLTRScript: true}, + status: EscapeStatus{}, }, { name: "multi line western", text: "single line western\nmulti line western\n", result: "single line western\nmulti line western\n", - status: EscapeStatus{HasLTRScript: true}, + status: EscapeStatus{}, }, { name: "multi line western non-breaking space", text: "single line western\nmulti line western\n", result: `single line western` + "\n" + `multi line western` + "\n", - status: EscapeStatus{Escaped: true, HasLTRScript: true, HasSpaces: true}, + status: EscapeStatus{Escaped: true, HasInvisible: true}, }, { name: "mixed scripts: western + japanese", text: "日属秘ぞしちゅ。Then some western.", result: "日属秘ぞしちゅ。Then some western.", - status: EscapeStatus{HasLTRScript: true}, + status: EscapeStatus{}, }, { name: "japanese", text: "日属秘ぞしちゅ。", result: "日属秘ぞしちゅ。", - status: EscapeStatus{HasLTRScript: true}, + status: EscapeStatus{}, }, { name: "hebrew", text: "עד תקופת יוון העתיקה היה העיסוק במתמטיקה תכליתי בלבד: היא שימשה כאוסף של נוסחאות לחישוב קרקע, אוכלוסין וכו'. פריצת הדרך של היוונים, פרט לתרומותיהם הגדולות לידע המתמטי, הייתה בלימוד המתמטיקה כשלעצמה, מתוקף ערכה הרוחני. יחסם של חלק מהיוונים הקדמונים למתמטיקה היה דתי - למשל, הכת שאסף סביבו פיתגורס האמינה כי המתמטיקה היא הבסיס לכל הדברים. היוונים נחשבים ליוצרי מושג ההוכחה המתמטית, וכן לראשונים שעסקו במתמטיקה לשם עצמה, כלומר כתחום מחקרי עיוני ומופשט ולא רק כעזר שימושי. עם זאת, לצדה", - result: "עד תקופת יוון העתיקה היה העיסוק במתמטיקה תכליתי בלבד: היא שימשה כאוסף של נוסחאות לחישוב קרקע, אוכלוסין וכו'. פריצת הדרך של היוונים, פרט לתרומותיהם הגדולות לידע המתמטי, הייתה בלימוד המתמטיקה כשלעצמה, מתוקף ערכה הרוחני. יחסם של חלק מהיוונים הקדמונים למתמטיקה היה דתי - למשל, הכת שאסף סביבו פיתגורס האמינה כי המתמטיקה היא הבסיס לכל הדברים. היוונים נחשבים ליוצרי מושג ההוכחה המתמטית, וכן לראשונים שעסקו במתמטיקה לשם עצמה, כלומר כתחום מחקרי עיוני ומופשט ולא רק כעזר שימושי. עם זאת, לצדה", - status: EscapeStatus{HasRTLScript: true}, + result: `עד תקופת יוון העתיקה היה העיסוק במתמטיקה תכליתי בלבד: היא שימשה כאוסף של נוסחאות לחישוב קרקע, אוכלוסין וכו'. פריצת הדרך של היוונים, פרט לתרומותיהם הגדולות לידע המתמטי, הייתה בלימוד המתמטיקה כשלעצמה, מתוקף ערכה הרוחני. יחסם של חלק מהיוונים הקדמונים למתמטיקה היה דתי - למשל, הכת שאסף סביבו פיתגורס האמינה כי המתמטיקה היא הבסיס לכל הדברים. היוונים נחשבים ליוצרי מושג ההוכחה המתמטית, וכן לראשונים שעסקו במתמטיקה לשם עצמה, כלומר כתחום מחקרי עיוני ומופשט ולא רק כעזר שימושי. עם זאת, לצדה`, + status: EscapeStatus{Escaped: true, HasAmbiguous: true}, }, { name: "more hebrew", @@ -64,12 +66,12 @@ var escapeControlTests = []escapeControlTest{ המתמטיקאי הבולט הראשון ביוון העתיקה, ויש האומרים בתולדות האנושות, הוא תאלס (624 לפנה"ס - 546 לפנה"ס בקירוב).[1] לא יהיה זה משולל יסוד להניח שהוא האדם הראשון שהוכיח משפט מתמטי, ולא רק גילה אותו. תאלס הוכיח שישרים מקבילים חותכים מצד אחד של שוקי זווית קטעים בעלי יחסים שווים (משפט תאלס הראשון), שהזווית המונחת על קוטר במעגל היא זווית ישרה (משפט תאלס השני), שהקוטר מחלק את המעגל לשני חלקים שווים, ושזוויות הבסיס במשולש שווה-שוקיים שוות זו לזו. מיוחסות לו גם שיטות למדידת גובהן של הפירמידות בעזרת מדידת צילן ולקביעת מיקומה של ספינה הנראית מן החוף. בשנים 582 לפנה"ס עד 496 לפנה"ס, בקירוב, חי מתמטיקאי חשוב במיוחד - פיתגורס. המקורות הראשוניים עליו מועטים, וההיסטוריונים מתקשים להפריד את העובדות משכבת המסתורין והאגדות שנקשרו בו. ידוע שסביבו התקבצה האסכולה הפיתגוראית מעין כת פסבדו-מתמטית שהאמינה ש"הכל מספר", או ליתר דיוק הכל ניתן לכימות, וייחסה למספרים משמעויות מיסטיות. ככל הנראה הפיתגוראים ידעו לבנות את הגופים האפלטוניים, הכירו את הממוצע האריתמטי, הממוצע הגאומטרי והממוצע ההרמוני והגיעו להישגים חשובים נוספים. ניתן לומר שהפיתגוראים גילו את היותו של השורש הריבועי של 2, שהוא גם האלכסון בריבוע שאורך צלעותיו 1, אי רציונלי, אך תגליתם הייתה למעשה רק שהקטעים "חסרי מידה משותפת", ומושג המספר האי רציונלי מאוחר יותר.[2] אזכור ראשון לקיומם של קטעים חסרי מידה משותפת מופיע בדיאלוג "תאיטיטוס" של אפלטון, אך רעיון זה היה מוכר עוד קודם לכן, במאה החמישית לפנה"ס להיפאסוס, בן האסכולה הפיתגוראית, ואולי לפיתגורס עצמו.[3]`, - result: `בתקופה מאוחרת יותר, השתמשו היוונים בשיטת סימון מתקדמת יותר, שבה הוצגו המספרים לפי 22 אותיות האלפבית היווני. לסימון המספרים בין 1 ל-9 נקבעו תשע האותיות הראשונות, בתוספת גרש ( ' ) בצד ימין של האות, למעלה; תשע האותיות הבאות ייצגו את העשרות מ-10 עד 90, והבאות את המאות. לסימון הספרות בין 1000 ל-900,000, השתמשו היוונים באותן אותיות, אך הוסיפו לאותיות את הגרש דווקא מצד שמאל של האותיות, למטה. ממיליון ומעלה, כנראה השתמשו היוונים בשני תגים במקום אחד. + result: `בתקופה מאוחרת יותר, השתמשו היוונים בשיטת סימון מתקדמת יותר, שבה הוצגו המספרים לפי 22 אותיות האלפבית היווני. לסימון המספרים בין 1 ל-9 נקבעו תשע האותיות הראשונות, בתוספת גרש ( ' ) בצד ימין של האות, למעלה; תשע האותיות הבאות ייצגו את העשרות מ-10 עד 90, והבאות את המאות. לסימון הספרות בין 1000 ל-900,000, השתמשו היוונים באותן אותיות, אך הוסיפו לאותיות את הגרש דווקא מצד שמאל של האותיות, למטה. ממיליון ומעלה, כנראה השתמשו היוונים בשני תגים במקום אחד. - המתמטיקאי הבולט הראשון ביוון העתיקה, ויש האומרים בתולדות האנושות, הוא תאלס (624 לפנה"ס - 546 לפנה"ס בקירוב).[1] לא יהיה זה משולל יסוד להניח שהוא האדם הראשון שהוכיח משפט מתמטי, ולא רק גילה אותו. תאלס הוכיח שישרים מקבילים חותכים מצד אחד של שוקי זווית קטעים בעלי יחסים שווים (משפט תאלס הראשון), שהזווית המונחת על קוטר במעגל היא זווית ישרה (משפט תאלס השני), שהקוטר מחלק את המעגל לשני חלקים שווים, ושזוויות הבסיס במשולש שווה-שוקיים שוות זו לזו. מיוחסות לו גם שיטות למדידת גובהן של הפירמידות בעזרת מדידת צילן ולקביעת מיקומה של ספינה הנראית מן החוף. + המתמטיקאי הבולט הראשון ביוון העתיקה, ויש האומרים בתולדות האנושות, הוא תאלס (624 לפנה"ס - 546 לפנה"ס בקירוב).[1] לא יהיה זה משולל יסוד להניח שהוא האדם הראשון שהוכיח משפט מתמטי, ולא רק גילה אותו. תאלס הוכיח שישרים מקבילים חותכים מצד אחד של שוקי זווית קטעים בעלי יחסים שווים (משפט תאלס הראשון), שהזווית המונחת על קוטר במעגל היא זווית ישרה (משפט תאלס השני), שהקוטר מחלק את המעגל לשני חלקים שווים, ושזוויות הבסיס במשולש שווה-שוקיים שוות זו לזו. מיוחסות לו גם שיטות למדידת גובהן של הפירמידות בעזרת מדידת צילן ולקביעת מיקומה של ספינה הנראית מן החוף. - בשנים 582 לפנה"ס עד 496 לפנה"ס, בקירוב, חי מתמטיקאי חשוב במיוחד - פיתגורס. המקורות הראשוניים עליו מועטים, וההיסטוריונים מתקשים להפריד את העובדות משכבת המסתורין והאגדות שנקשרו בו. ידוע שסביבו התקבצה האסכולה הפיתגוראית מעין כת פסבדו-מתמטית שהאמינה ש"הכל מספר", או ליתר דיוק הכל ניתן לכימות, וייחסה למספרים משמעויות מיסטיות. ככל הנראה הפיתגוראים ידעו לבנות את הגופים האפלטוניים, הכירו את הממוצע האריתמטי, הממוצע הגאומטרי והממוצע ההרמוני והגיעו להישגים חשובים נוספים. ניתן לומר שהפיתגוראים גילו את היותו של השורש הריבועי של 2, שהוא גם האלכסון בריבוע שאורך צלעותיו 1, אי רציונלי, אך תגליתם הייתה למעשה רק שהקטעים "חסרי מידה משותפת", ומושג המספר האי רציונלי מאוחר יותר.[2] אזכור ראשון לקיומם של קטעים חסרי מידה משותפת מופיע בדיאלוג "תאיטיטוס" של אפלטון, אך רעיון זה היה מוכר עוד קודם לכן, במאה החמישית לפנה"ס להיפאסוס, בן האסכולה הפיתגוראית, ואולי לפיתגורס עצמו.[3]`, - status: EscapeStatus{HasRTLScript: true}, + בשנים 582 לפנה"ס עד 496 לפנה"ס, בקירוב, חי מתמטיקאי חשוב במיוחד - פיתגורס. המקורות הראשוניים עליו מועטים, וההיסטוריונים מתקשים להפריד את העובדות משכבת המסתורין והאגדות שנקשרו בו. ידוע שסביבו התקבצה האסכולה הפיתגוראית מעין כת פסבדו-מתמטית שהאמינה ש"הכל מספר", או ליתר דיוק הכל ניתן לכימות, וייחסה למספרים משמעויות מיסטיות. ככל הנראה הפיתגוראים ידעו לבנות את הגופים האפלטוניים, הכירו את הממוצע האריתמטי, הממוצע הגאומטרי והממוצע ההרמוני והגיעו להישגים חשובים נוספים. ניתן לומר שהפיתגוראים גילו את היותו של השורש הריבועי של 2, שהוא גם האלכסון בריבוע שאורך צלעותיו 1, אי רציונלי, אך תגליתם הייתה למעשה רק שהקטעים "חסרי מידה משותפת", ומושג המספר האי רציונלי מאוחר יותר.[2] אזכור ראשון לקיומם של קטעים חסרי מידה משותפת מופיע בדיאלוג "תאיטיטוס" של אפלטון, אך רעיון זה היה מוכר עוד קודם לכן, במאה החמישית לפנה"ס להיפאסוס, בן האסכולה הפיתגוראית, ואולי לפיתגורס עצמו.[3]`, + status: EscapeStatus{Escaped: true, HasAmbiguous: true}, }, { name: "Mixed RTL+LTR", @@ -79,10 +81,7 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`, result: `Many computer programs fail to display bidirectional text correctly. For example, the Hebrew name Sarah (שרה) is spelled: sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).`, - status: EscapeStatus{ - HasRTLScript: true, - HasLTRScript: true, - }, + status: EscapeStatus{}, }, { name: "Mixed RTL+LTR+BIDI", @@ -90,32 +89,27 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`, For example, the Hebrew name Sarah ` + "\u2067" + `שרה` + "\u2066\n" + `sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).`, result: `Many computer programs fail to display bidirectional text correctly. - For example, the Hebrew name Sarah ` + "\u2067" + `שרה` + "\u2066" + `` + "\n" + + For example, the Hebrew name Sarah ` + "\u2067" + `שרה` + "\u2066\n" + `sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).`, - status: EscapeStatus{ - Escaped: true, - HasBIDI: true, - HasRTLScript: true, - HasLTRScript: true, - }, + status: EscapeStatus{}, }, { name: "Accented characters", text: string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}), result: string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}), - status: EscapeStatus{HasLTRScript: true}, + status: EscapeStatus{}, }, { name: "Program", text: "string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba})", result: "string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba})", - status: EscapeStatus{HasLTRScript: true}, + status: EscapeStatus{}, }, { name: "CVE testcase", text: "if access_level != \"user\u202E \u2066// Check if admin\u2069 \u2066\" {", - result: `if access_level != "user` + "\u202e" + ` ` + "\u2066" + `// Check if admin` + "\u2069" + ` ` + "\u2066" + `" {`, - status: EscapeStatus{Escaped: true, HasBIDI: true, BadBIDI: true, HasLTRScript: true}, + result: `if access_level != "user` + "\u202e" + ` ` + "\u2066" + `// Check if admin` + "\u2069" + ` ` + "\u2066" + `" {`, + status: EscapeStatus{Escaped: true, HasInvisible: true}, }, { name: "Mixed testcase with fail", @@ -124,10 +118,10 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`, `sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).` + "\nif access_level != \"user\u202E \u2066// Check if admin\u2069 \u2066\" {\n", result: `Many computer programs fail to display bidirectional text correctly. - For example, the Hebrew name Sarah ` + "\u2067" + `שרה` + "\u2066" + `` + "\n" + + For example, the Hebrew name Sarah ` + "\u2067" + `שרה` + "\u2066\n" + `sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).` + - "\n" + `if access_level != "user` + "\u202e" + ` ` + "\u2066" + `// Check if admin` + "\u2069" + ` ` + "\u2066" + `" {` + "\n", - status: EscapeStatus{Escaped: true, HasBIDI: true, BadBIDI: true, HasLTRScript: true, HasRTLScript: true}, + "\n" + `if access_level != "user` + "\u202e" + ` ` + "\u2066" + `// Check if admin` + "\u2069" + ` ` + "\u2066" + `" {` + "\n", + status: EscapeStatus{Escaped: true, HasInvisible: true}, }, { // UTF-8/16/32 all use the same codepoint for BOM @@ -135,15 +129,16 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`, name: "UTF BOM", text: "\xef\xbb\xbftest", result: "\xef\xbb\xbftest", - status: EscapeStatus{HasLTRScript: true}, + status: EscapeStatus{}, }, } func TestEscapeControlString(t *testing.T) { for _, tt := range escapeControlTests { t.Run(tt.name, func(t *testing.T) { - status, result := EscapeControlString(tt.text) - if !reflect.DeepEqual(status, tt.status) { + locale := translation.NewLocale("en_US") + status, result := EscapeControlString(tt.text, locale) + if !reflect.DeepEqual(*status, tt.status) { t.Errorf("EscapeControlString() status = %v, wanted= %v", status, tt.status) } if result != tt.result { @@ -153,20 +148,6 @@ func TestEscapeControlString(t *testing.T) { } } -func TestEscapeControlBytes(t *testing.T) { - for _, tt := range escapeControlTests { - t.Run(tt.name, func(t *testing.T) { - status, result := EscapeControlBytes([]byte(tt.text)) - if !reflect.DeepEqual(status, tt.status) { - t.Errorf("EscapeControlBytes() status = %v, wanted= %v", status, tt.status) - } - if string(result) != tt.result { - t.Errorf("EscapeControlBytes()\nresult= %v,\nwanted= %v", result, tt.result) - } - }) - } -} - func TestEscapeControlReader(t *testing.T) { // lets add some control characters to the tests tests := make([]escapeControlTest, 0, len(escapeControlTests)*3) @@ -184,16 +165,7 @@ func TestEscapeControlReader(t *testing.T) { test.text = addPrefix("\u001E", test.text) test.result = addPrefix(``+"\u001e"+``, test.result) test.status.Escaped = true - test.status.HasControls = true - tests = append(tests, test) - } - - for _, test := range escapeControlTests { - test.name += " (+Mark)" - test.text = addPrefix("\u0300", test.text) - test.result = addPrefix(``+"\u0300"+``, test.result) - test.status.Escaped = true - test.status.HasMarks = true + test.status.HasInvisible = true tests = append(tests, test) } @@ -201,13 +173,13 @@ func TestEscapeControlReader(t *testing.T) { t.Run(tt.name, func(t *testing.T) { input := strings.NewReader(tt.text) output := &strings.Builder{} - status, err := EscapeControlReader(input, output) + status, err := EscapeControlReader(input, output, translation.NewLocale("en_US")) result := output.String() if err != nil { t.Errorf("EscapeControlReader(): err = %v", err) } - if !reflect.DeepEqual(status, tt.status) { + if !reflect.DeepEqual(*status, tt.status) { t.Errorf("EscapeControlReader() status = %v, wanted= %v", status, tt.status) } if result != tt.result { @@ -223,5 +195,5 @@ func TestEscapeControlReader_panic(t *testing.T) { for i := 0; i < 6826; i++ { bs = append(bs, []byte("—")...) } - _, _ = EscapeControlBytes(bs) + _, _ = EscapeControlString(string(bs), translation.NewLocale("en_US")) } diff --git a/modules/charset/htmlstream.go b/modules/charset/htmlstream.go new file mode 100644 index 0000000000..b354ce6a48 --- /dev/null +++ b/modules/charset/htmlstream.go @@ -0,0 +1,201 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import ( + "fmt" + "io" + + "golang.org/x/net/html" +) + +// HTMLStreamer represents a SAX-like interface for HTML +type HTMLStreamer interface { + Error(err error) error + Doctype(data string) error + Comment(data string) error + StartTag(data string, attrs ...html.Attribute) error + SelfClosingTag(data string, attrs ...html.Attribute) error + EndTag(data string) error + Text(data string) error +} + +// PassthroughHTMLStreamer is a passthrough streamer +type PassthroughHTMLStreamer struct { + next HTMLStreamer +} + +func NewPassthroughStreamer(next HTMLStreamer) *PassthroughHTMLStreamer { + return &PassthroughHTMLStreamer{next: next} +} + +var _ (HTMLStreamer) = &PassthroughHTMLStreamer{} + +// Error tells the next streamer in line that there is an error +func (p *PassthroughHTMLStreamer) Error(err error) error { + return p.next.Error(err) +} + +// Doctype tells the next streamer what the doctype is +func (p *PassthroughHTMLStreamer) Doctype(data string) error { + return p.next.Doctype(data) +} + +// Comment tells the next streamer there is a comment +func (p *PassthroughHTMLStreamer) Comment(data string) error { + return p.next.Comment(data) +} + +// StartTag tells the next streamer there is a starting tag +func (p *PassthroughHTMLStreamer) StartTag(data string, attrs ...html.Attribute) error { + return p.next.StartTag(data, attrs...) +} + +// SelfClosingTag tells the next streamer there is a self-closing tag +func (p *PassthroughHTMLStreamer) SelfClosingTag(data string, attrs ...html.Attribute) error { + return p.next.SelfClosingTag(data, attrs...) +} + +// EndTag tells the next streamer there is a end tag +func (p *PassthroughHTMLStreamer) EndTag(data string) error { + return p.next.EndTag(data) +} + +// Text tells the next streamer there is a text +func (p *PassthroughHTMLStreamer) Text(data string) error { + return p.next.Text(data) +} + +// HTMLStreamWriter acts as a writing sink +type HTMLStreamerWriter struct { + io.Writer + err error +} + +// Write implements io.Writer +func (h *HTMLStreamerWriter) Write(data []byte) (int, error) { + if h.err != nil { + return 0, h.err + } + return h.Writer.Write(data) +} + +// Write implements io.StringWriter +func (h *HTMLStreamerWriter) WriteString(data string) (int, error) { + if h.err != nil { + return 0, h.err + } + return h.Writer.Write([]byte(data)) +} + +// Error tells the next streamer in line that there is an error +func (h *HTMLStreamerWriter) Error(err error) error { + if h.err == nil { + h.err = err + } + return h.err +} + +// Doctype tells the next streamer what the doctype is +func (h *HTMLStreamerWriter) Doctype(data string) error { + _, h.err = h.WriteString("") + return h.err +} + +// Comment tells the next streamer there is a comment +func (h *HTMLStreamerWriter) Comment(data string) error { + _, h.err = h.WriteString("") + return h.err +} + +// StartTag tells the next streamer there is a starting tag +func (h *HTMLStreamerWriter) StartTag(data string, attrs ...html.Attribute) error { + return h.startTag(data, attrs, false) +} + +// SelfClosingTag tells the next streamer there is a self-closing tag +func (h *HTMLStreamerWriter) SelfClosingTag(data string, attrs ...html.Attribute) error { + return h.startTag(data, attrs, true) +} + +func (h *HTMLStreamerWriter) startTag(data string, attrs []html.Attribute, selfclosing bool) error { + if _, h.err = h.WriteString("<" + data); h.err != nil { + return h.err + } + for _, attr := range attrs { + if _, h.err = h.WriteString(" " + attr.Key + "=\"" + html.EscapeString(attr.Val) + "\""); h.err != nil { + return h.err + } + } + if selfclosing { + if _, h.err = h.WriteString("/>"); h.err != nil { + return h.err + } + } else { + if _, h.err = h.WriteString(">"); h.err != nil { + return h.err + } + } + return h.err +} + +// EndTag tells the next streamer there is a end tag +func (h *HTMLStreamerWriter) EndTag(data string) error { + _, h.err = h.WriteString("") + return h.err +} + +// Text tells the next streamer there is a text +func (h *HTMLStreamerWriter) Text(data string) error { + _, h.err = h.WriteString(html.EscapeString(data)) + return h.err +} + +// StreamHTML streams an html to a provided streamer +func StreamHTML(source io.Reader, streamer HTMLStreamer) error { + tokenizer := html.NewTokenizer(source) + for { + tt := tokenizer.Next() + switch tt { + case html.ErrorToken: + if tokenizer.Err() != io.EOF { + return tokenizer.Err() + } + return nil + case html.DoctypeToken: + token := tokenizer.Token() + if err := streamer.Doctype(token.Data); err != nil { + return err + } + case html.CommentToken: + token := tokenizer.Token() + if err := streamer.Comment(token.Data); err != nil { + return err + } + case html.StartTagToken: + token := tokenizer.Token() + if err := streamer.StartTag(token.Data, token.Attr...); err != nil { + return err + } + case html.SelfClosingTagToken: + token := tokenizer.Token() + if err := streamer.StartTag(token.Data, token.Attr...); err != nil { + return err + } + case html.EndTagToken: + token := tokenizer.Token() + if err := streamer.EndTag(token.Data); err != nil { + return err + } + case html.TextToken: + token := tokenizer.Token() + if err := streamer.Text(token.Data); err != nil { + return err + } + default: + return fmt.Errorf("unknown type of token: %d", tt) + } + } +} diff --git a/modules/charset/invisible/generate.go b/modules/charset/invisible/generate.go new file mode 100644 index 0000000000..230ff0b832 --- /dev/null +++ b/modules/charset/invisible/generate.go @@ -0,0 +1,111 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "flag" + "fmt" + "go/format" + "os" + "text/template" + + "golang.org/x/text/unicode/rangetable" +) + +// InvisibleRunes these are runes that vscode has assigned to be invisible +// See https://github.com/hediet/vscode-unicode-data +var InvisibleRunes = []rune{ + 9, 10, 11, 12, 13, 32, 127, 160, 173, 847, 1564, 4447, 4448, 6068, 6069, 6155, 6156, 6157, 6158, 7355, 7356, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8203, 8204, 8205, 8206, 8207, 8234, 8235, 8236, 8237, 8238, 8239, 8287, 8288, 8289, 8290, 8291, 8292, 8293, 8294, 8295, 8296, 8297, 8298, 8299, 8300, 8301, 8302, 8303, 10240, 12288, 12644, 65024, 65025, 65026, 65027, 65028, 65029, 65030, 65031, 65032, 65033, 65034, 65035, 65036, 65037, 65038, 65039, 65279, 65440, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65532, 78844, 119155, 119156, 119157, 119158, 119159, 119160, 119161, 119162, 917504, 917505, 917506, 917507, 917508, 917509, 917510, 917511, 917512, 917513, 917514, 917515, 917516, 917517, 917518, 917519, 917520, 917521, 917522, 917523, 917524, 917525, 917526, 917527, 917528, 917529, 917530, 917531, 917532, 917533, 917534, 917535, 917536, 917537, 917538, 917539, 917540, 917541, 917542, 917543, 917544, 917545, 917546, 917547, 917548, 917549, 917550, 917551, 917552, 917553, 917554, 917555, 917556, 917557, 917558, 917559, 917560, 917561, 917562, 917563, 917564, 917565, 917566, 917567, 917568, 917569, 917570, 917571, 917572, 917573, 917574, 917575, 917576, 917577, 917578, 917579, 917580, 917581, 917582, 917583, 917584, 917585, 917586, 917587, 917588, 917589, 917590, 917591, 917592, 917593, 917594, 917595, 917596, 917597, 917598, 917599, 917600, 917601, 917602, 917603, 917604, 917605, 917606, 917607, 917608, 917609, 917610, 917611, 917612, 917613, 917614, 917615, 917616, 917617, 917618, 917619, 917620, 917621, 917622, 917623, 917624, 917625, 917626, 917627, 917628, 917629, 917630, 917631, 917760, 917761, 917762, 917763, 917764, 917765, 917766, 917767, 917768, 917769, 917770, 917771, 917772, 917773, 917774, 917775, 917776, 917777, 917778, 917779, 917780, 917781, 917782, 917783, 917784, 917785, 917786, 917787, 917788, 917789, 917790, 917791, 917792, 917793, 917794, 917795, 917796, 917797, 917798, 917799, 917800, 917801, 917802, 917803, 917804, 917805, 917806, 917807, 917808, 917809, 917810, 917811, 917812, 917813, 917814, 917815, 917816, 917817, 917818, 917819, 917820, 917821, 917822, 917823, 917824, 917825, 917826, 917827, 917828, 917829, 917830, 917831, 917832, 917833, 917834, 917835, 917836, 917837, 917838, 917839, 917840, 917841, 917842, 917843, 917844, 917845, 917846, 917847, 917848, 917849, 917850, 917851, 917852, 917853, 917854, 917855, 917856, 917857, 917858, 917859, 917860, 917861, 917862, 917863, 917864, 917865, 917866, 917867, 917868, 917869, 917870, 917871, 917872, 917873, 917874, 917875, 917876, 917877, 917878, 917879, 917880, 917881, 917882, 917883, 917884, 917885, 917886, 917887, 917888, 917889, 917890, 917891, 917892, 917893, 917894, 917895, 917896, 917897, 917898, 917899, 917900, 917901, 917902, 917903, 917904, 917905, 917906, 917907, 917908, 917909, 917910, 917911, 917912, 917913, 917914, 917915, 917916, 917917, 917918, 917919, 917920, 917921, 917922, 917923, 917924, 917925, 917926, 917927, 917928, 917929, 917930, 917931, 917932, 917933, 917934, 917935, 917936, 917937, 917938, 917939, 917940, 917941, 917942, 917943, 917944, 917945, 917946, 917947, 917948, 917949, 917950, 917951, 917952, 917953, 917954, 917955, 917956, 917957, 917958, 917959, 917960, 917961, 917962, 917963, 917964, 917965, 917966, 917967, 917968, 917969, 917970, 917971, 917972, 917973, 917974, 917975, 917976, 917977, 917978, 917979, 917980, 917981, 917982, 917983, 917984, 917985, 917986, 917987, 917988, 917989, 917990, 917991, 917992, 917993, 917994, 917995, 917996, 917997, 917998, 917999, +} + +var verbose bool + +func main() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, `%s: Generate InvisibleRunesRange + +Usage: %[1]s [-v] [-o output.go] +`, os.Args[0]) + flag.PrintDefaults() + } + + output := "" + flag.BoolVar(&verbose, "v", false, "verbose output") + flag.StringVar(&output, "o", "invisible_gen.go", "file to output to") + flag.Parse() + + // First we filter the runes to remove + // + filtered := make([]rune, 0, len(InvisibleRunes)) + for _, r := range InvisibleRunes { + if r == ' ' || r == '\t' || r == '\n' { + continue + } + filtered = append(filtered, r) + } + + table := rangetable.New(filtered...) + if err := runTemplate(generatorTemplate, output, table); err != nil { + fatalf("Unable to run template: %v", err) + } +} + +func runTemplate(t *template.Template, filename string, data interface{}) error { + buf := bytes.NewBuffer(nil) + if err := t.Execute(buf, data); err != nil { + return fmt.Errorf("unable to execute template: %w", err) + } + bs, err := format.Source(buf.Bytes()) + if err != nil { + verbosef("Bad source:\n%s", buf.String()) + return fmt.Errorf("unable to format source: %w", err) + } + file, err := os.Create(filename) + if err != nil { + return fmt.Errorf("failed to create file %s because %w", filename, err) + } + defer file.Close() + _, err = file.Write(bs) + if err != nil { + return fmt.Errorf("unable to write generated source: %w", err) + } + return nil +} + +var generatorTemplate = template.Must(template.New("invisibleTemplate").Parse(`// This file is generated by modules/charset/invisible/generate.go DO NOT EDIT +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import "unicode" + +var InvisibleRanges = &unicode.RangeTable{ + R16: []unicode.Range16{ +{{range .R16 }} {Lo:{{.Lo}}, Hi:{{.Hi}}, Stride: {{.Stride}}}, +{{end}} }, + R32: []unicode.Range32{ +{{range .R32}} {Lo:{{.Lo}}, Hi:{{.Hi}}, Stride: {{.Stride}}}, +{{end}} }, + LatinOffset: {{.LatinOffset}}, +} +`)) + +func logf(format string, args ...interface{}) { + fmt.Fprintf(os.Stderr, format+"\n", args...) +} + +func verbosef(format string, args ...interface{}) { + if verbose { + logf(format, args...) + } +} + +func fatalf(format string, args ...interface{}) { + logf("fatal: "+format+"\n", args...) + os.Exit(1) +} diff --git a/modules/charset/invisible_gen.go b/modules/charset/invisible_gen.go new file mode 100644 index 0000000000..b3bfebe0c0 --- /dev/null +++ b/modules/charset/invisible_gen.go @@ -0,0 +1,37 @@ +// This file is generated by modules/charset/invisible/generate.go DO NOT EDIT +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package charset + +import "unicode" + +var InvisibleRanges = &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 11, Hi: 13, Stride: 1}, + {Lo: 127, Hi: 160, Stride: 33}, + {Lo: 173, Hi: 847, Stride: 674}, + {Lo: 1564, Hi: 4447, Stride: 2883}, + {Lo: 4448, Hi: 6068, Stride: 1620}, + {Lo: 6069, Hi: 6155, Stride: 86}, + {Lo: 6156, Hi: 6158, Stride: 1}, + {Lo: 7355, Hi: 7356, Stride: 1}, + {Lo: 8192, Hi: 8207, Stride: 1}, + {Lo: 8234, Hi: 8239, Stride: 1}, + {Lo: 8287, Hi: 8303, Stride: 1}, + {Lo: 10240, Hi: 12288, Stride: 2048}, + {Lo: 12644, Hi: 65024, Stride: 52380}, + {Lo: 65025, Hi: 65039, Stride: 1}, + {Lo: 65279, Hi: 65440, Stride: 161}, + {Lo: 65520, Hi: 65528, Stride: 1}, + {Lo: 65532, Hi: 65532, Stride: 1}, + }, + R32: []unicode.Range32{ + {Lo: 78844, Hi: 119155, Stride: 40311}, + {Lo: 119156, Hi: 119162, Stride: 1}, + {Lo: 917504, Hi: 917631, Stride: 1}, + {Lo: 917760, Hi: 917999, Stride: 1}, + }, + LatinOffset: 2, +} diff --git a/modules/convert/git_commit_test.go b/modules/convert/git_commit_test.go index 118ba3a007..0bba0e502e 100644 --- a/modules/convert/git_commit_test.go +++ b/modules/convert/git_commit_test.go @@ -19,7 +19,7 @@ import ( func TestToCommitMeta(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) sha1, _ := git.NewIDFromString("0000000000000000000000000000000000000000") signature := &git.Signature{Name: "Test Signature", Email: "test@email.com", When: time.Unix(0, 0)} tag := &git.Tag{ diff --git a/modules/convert/issue_test.go b/modules/convert/issue_test.go index 5bf04bcb52..ec672abad2 100644 --- a/modules/convert/issue_test.go +++ b/modules/convert/issue_test.go @@ -21,8 +21,8 @@ import ( func TestLabel_ToLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID}).(*repo_model.Repository) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID}) assert.Equal(t, &api.Label{ ID: label.ID, Name: label.Name, diff --git a/modules/convert/pull_test.go b/modules/convert/pull_test.go index 10ef311399..a6ccbaca58 100644 --- a/modules/convert/pull_test.go +++ b/modules/convert/pull_test.go @@ -20,8 +20,8 @@ import ( func TestPullRequest_APIFormat(t *testing.T) { // with HeadRepo assert.NoError(t, unittest.PrepareTestDatabase()) - headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) + headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) assert.NoError(t, pr.LoadAttributes()) assert.NoError(t, pr.LoadIssue()) apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil) @@ -35,7 +35,7 @@ func TestPullRequest_APIFormat(t *testing.T) { }, apiPullRequest.Head) // withOut HeadRepo - pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) assert.NoError(t, pr.LoadIssue()) assert.NoError(t, pr.LoadAttributes()) // simulate fork deletion diff --git a/modules/convert/user_test.go b/modules/convert/user_test.go index 2ed962950f..89d912e460 100644 --- a/modules/convert/user_test.go +++ b/modules/convert/user_test.go @@ -17,13 +17,13 @@ import ( func TestUser_ToUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1, IsAdmin: true}).(*user_model.User) + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1, IsAdmin: true}) apiUser := toUser(user1, true, true) assert.True(t, apiUser.IsAdmin) assert.Contains(t, apiUser.AvatarURL, "://") - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2, IsAdmin: false}).(*user_model.User) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2, IsAdmin: false}) apiUser = toUser(user2, true, true) assert.False(t, apiUser.IsAdmin) @@ -32,7 +32,7 @@ func TestUser_ToUser(t *testing.T) { assert.False(t, apiUser.IsAdmin) assert.EqualValues(t, api.VisibleTypePublic.String(), apiUser.Visibility) - user31 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 31, IsAdmin: false, Visibility: api.VisibleTypePrivate}).(*user_model.User) + user31 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 31, IsAdmin: false, Visibility: api.VisibleTypePrivate}) apiUser = toUser(user31, true, true) assert.False(t, apiUser.IsAdmin) diff --git a/modules/doctor/doctor.go b/modules/doctor/doctor.go index c8975a788e..5d14cef55c 100644 --- a/modules/doctor/doctor.go +++ b/modules/doctor/doctor.go @@ -11,6 +11,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) @@ -49,7 +50,11 @@ func initDBDisableConsole(ctx context.Context, disableConsole bool) error { setting.NewXORMLogService(disableConsole) if err := db.InitEngine(ctx); err != nil { - return fmt.Errorf("models.SetEngine: %v", err) + return fmt.Errorf("db.InitEngine: %w", err) + } + // some doctor sub-commands need to use git command + if err := git.InitFull(ctx); err != nil { + return fmt.Errorf("git.InitFull: %w", err) } return nil } diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index 7ff23af42e..d3731cb928 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -7,6 +7,8 @@ package git import ( "bytes" + "encoding/hex" + "fmt" "io" "strconv" "strings" @@ -209,9 +211,9 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) ( }() go func() { stderr := strings.Builder{} - err := NewCommand(repo.Ctx, "log", revision, "--follow", + err := NewCommand(repo.Ctx, "rev-list", revision, "--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page), - prettyLogFormat, "--", file). + "--skip="+strconv.Itoa(skip), "--", file). Run(&RunOpts{ Dir: repo.Path, Stdout: stdoutWriter, @@ -224,32 +226,30 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) ( } }() - if skip > 0 { - _, err := io.CopyN(io.Discard, stdoutReader, int64(skip*41)) - if err != nil { + commits := []*Commit{} + shaline := [41]byte{} + var sha1 SHA1 + for { + n, err := io.ReadFull(stdoutReader, shaline[:]) + if err != nil || n < 40 { if err == io.EOF { - return []*Commit{}, nil + err = nil } - _ = stdoutReader.CloseWithError(err) + return commits, err + } + n, err = hex.Decode(sha1[:], shaline[0:40]) + if n != 20 { + err = fmt.Errorf("invalid sha %q", string(shaline[:40])) + } + if err != nil { return nil, err } + commit, err := repo.getCommit(sha1) + if err != nil { + return nil, err + } + commits = append(commits, commit) } - - stdout, err := io.ReadAll(stdoutReader) - if err != nil { - return nil, err - } - return repo.parsePrettyFormatLogToList(stdout) -} - -// CommitsByFileAndRangeNoFollow return the commits according revision file and the page -func (repo *Repository) CommitsByFileAndRangeNoFollow(revision, file string, page int) ([]*Commit, error) { - stdout, _, err := NewCommand(repo.Ctx, "log", revision, "--skip="+strconv.Itoa((page-1)*50), - "--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize), prettyLogFormat, "--", file).RunStdBytes(&RunOpts{Dir: repo.Path}) - if err != nil { - return nil, err - } - return repo.parsePrettyFormatLogToList(stdout) } // FilesCountBetween return the number of files changed between two commits diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go index 680ff529af..c7524a79db 100644 --- a/modules/graceful/net_unix.go +++ b/modules/graceful/net_unix.go @@ -23,6 +23,7 @@ import ( const ( listenFDs = "LISTEN_FDS" startFD = 3 + unlinkFDs = "GITEA_UNLINK_FDS" ) // In order to keep the working directory the same as when we started we record @@ -33,8 +34,10 @@ var ( once = sync.Once{} mutex = sync.Mutex{} - providedListeners = []net.Listener{} - activeListeners = []net.Listener{} + providedListenersToUnlink = []bool{} + activeListenersToUnlink = []bool{} + providedListeners = []net.Listener{} + activeListeners = []net.Listener{} ) func getProvidedFDs() (savedErr error) { @@ -53,6 +56,16 @@ func getProvidedFDs() (savedErr error) { return } + fdsToUnlinkStr := strings.Split(os.Getenv(unlinkFDs), ",") + providedListenersToUnlink = make([]bool, n) + for _, fdStr := range fdsToUnlinkStr { + i, err := strconv.Atoi(fdStr) + if err != nil || i < 0 || i >= n { + continue + } + providedListenersToUnlink[i] = true + } + for i := startFD; i < n+startFD; i++ { file := os.NewFile(uintptr(i), fmt.Sprintf("listener_FD%d", i)) @@ -136,8 +149,11 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err for i, l := range providedListeners { if isSameAddr(l.Addr(), address) { providedListeners = append(providedListeners[:i], providedListeners[i+1:]...) + needsUnlink := providedListenersToUnlink[i] + providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...) activeListeners = append(activeListeners, l) + activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink) return l.(*net.TCPListener), nil } } @@ -148,6 +164,7 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err return nil, err } activeListeners = append(activeListeners, l) + activeListenersToUnlink = append(activeListenersToUnlink, false) return l, nil } @@ -166,9 +183,15 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener, for i, l := range providedListeners { if isSameAddr(l.Addr(), address) { providedListeners = append(providedListeners[:i], providedListeners[i+1:]...) + needsUnlink := providedListenersToUnlink[i] + providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...) + + activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink) activeListeners = append(activeListeners, l) unixListener := l.(*net.UnixListener) - unixListener.SetUnlinkOnClose(true) + if needsUnlink { + unixListener.SetUnlinkOnClose(true) + } return unixListener, nil } } @@ -189,6 +212,7 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener, } activeListeners = append(activeListeners, l) + activeListenersToUnlink = append(activeListenersToUnlink, true) return l, nil } @@ -223,3 +247,11 @@ func getActiveListeners() []net.Listener { copy(listeners, activeListeners) return listeners } + +func getActiveListenersToUnlink() []bool { + mutex.Lock() + defer mutex.Unlock() + listenersToUnlink := make([]bool, len(activeListenersToUnlink)) + copy(listenersToUnlink, activeListenersToUnlink) + return listenersToUnlink +} diff --git a/modules/graceful/restart_unix.go b/modules/graceful/restart_unix.go index 2654ddfb94..1d0d1059e9 100644 --- a/modules/graceful/restart_unix.go +++ b/modules/graceful/restart_unix.go @@ -12,6 +12,7 @@ import ( "net" "os" "os/exec" + "strconv" "strings" "sync" "syscall" @@ -75,6 +76,20 @@ func RestartProcess() (int, error) { } env = append(env, fmt.Sprintf("%s=%d", listenFDs, len(listeners))) + sb := &strings.Builder{} + for i, unlink := range getActiveListenersToUnlink() { + if !unlink { + continue + } + _, _ = sb.WriteString(strconv.Itoa(i)) + _, _ = sb.WriteString(",") + } + unlinkStr := sb.String() + if len(unlinkStr) > 0 { + unlinkStr = unlinkStr[:len(unlinkStr)-1] + env = append(env, fmt.Sprintf("%s=%s", unlinkFDs, unlinkStr)) + } + allFiles := append([]*os.File{os.Stdin, os.Stdout, os.Stderr}, files...) process, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{ Dir: originalWD, diff --git a/modules/hostmatcher/hostmatcher.go b/modules/hostmatcher/hostmatcher.go index 81c4202fcd..a092e07f41 100644 --- a/modules/hostmatcher/hostmatcher.go +++ b/modules/hostmatcher/hostmatcher.go @@ -78,6 +78,11 @@ func (hl *HostMatchList) AppendBuiltin(builtin string) { hl.builtins = append(hl.builtins, builtin) } +// AppendPattern appends more pattern to match +func (hl *HostMatchList) AppendPattern(pattern string) { + hl.patterns = append(hl.patterns, pattern) +} + // IsEmpty checks if the checklist is empty func (hl *HostMatchList) IsEmpty() bool { return hl == nil || (len(hl.builtins) == 0 && len(hl.patterns) == 0 && len(hl.ipNets) == 0) diff --git a/modules/log/multichannel.go b/modules/log/multichannel.go index 273df81df1..519abf663d 100644 --- a/modules/log/multichannel.go +++ b/modules/log/multichannel.go @@ -33,7 +33,7 @@ func newLogger(name string, buffer int64) *MultiChannelledLogger { func (l *MultiChannelledLogger) SetLogger(name, provider, config string) error { eventLogger, err := NewChannelledLog(l.ctx, name, provider, config, l.bufferLength) if err != nil { - return fmt.Errorf("Failed to create sublogger (%s): %v", name, err) + return fmt.Errorf("failed to create sublogger (%s): %w", name, err) } l.MultiChannelledLog.DelLogger(name) @@ -41,9 +41,9 @@ func (l *MultiChannelledLogger) SetLogger(name, provider, config string) error { err = l.MultiChannelledLog.AddLogger(eventLogger) if err != nil { if IsErrDuplicateName(err) { - return fmt.Errorf("Duplicate named sublogger %s %v", name, l.MultiChannelledLog.GetEventLoggerNames()) + return fmt.Errorf("%w other names: %v", err, l.MultiChannelledLog.GetEventLoggerNames()) } - return fmt.Errorf("Failed to add sublogger (%s): %v", name, err) + return fmt.Errorf("failed to add sublogger (%s): %w", name, err) } return nil diff --git a/modules/notification/action/action_test.go b/modules/notification/action/action_test.go index 2898c8ec3d..f6de0d6759 100644 --- a/modules/notification/action/action_test.go +++ b/modules/notification/action/action_test.go @@ -26,8 +26,8 @@ func TestMain(m *testing.M) { func TestRenameRepoAction(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID}) repo.Owner = user oldRepoName := repo.Name diff --git a/modules/packages/content_store.go b/modules/packages/content_store.go index 64c3eedc23..a3a5d1a666 100644 --- a/modules/packages/content_store.go +++ b/modules/packages/content_store.go @@ -27,21 +27,21 @@ func NewContentStore() *ContentStore { // Get gets a package blob func (s *ContentStore) Get(key BlobHash256Key) (storage.Object, error) { - return s.store.Open(keyToRelativePath(key)) + return s.store.Open(KeyToRelativePath(key)) } // Save stores a package blob func (s *ContentStore) Save(key BlobHash256Key, r io.Reader, size int64) error { - _, err := s.store.Save(keyToRelativePath(key), r, size) + _, err := s.store.Save(KeyToRelativePath(key), r, size) return err } // Delete deletes a package blob func (s *ContentStore) Delete(key BlobHash256Key) error { - return s.store.Delete(keyToRelativePath(key)) + return s.store.Delete(KeyToRelativePath(key)) } -// keyToRelativePath converts the sha256 key aabb000000... to aa/bb/aabb000000... -func keyToRelativePath(key BlobHash256Key) string { +// KeyToRelativePath converts the sha256 key aabb000000... to aa/bb/aabb000000... +func KeyToRelativePath(key BlobHash256Key) string { return path.Join(string(key)[0:2], string(key)[2:4], string(key)) } diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 37181d2dcd..c62e324b66 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -49,7 +49,7 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { } pushCommits.HeadCommit = &PushCommit{Sha1: "69554a6"} - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(git.DefaultContext, repo.RepoPath(), "/user2/repo16") assert.NoError(t, err) assert.Len(t, payloadCommits, 3) diff --git a/modules/repository/create_test.go b/modules/repository/create_test.go index 2a47e93631..39f8b11356 100644 --- a/modules/repository/create_test.go +++ b/modules/repository/create_test.go @@ -24,7 +24,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testTeamRepositories := func(teamID int64, repoIds []int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team) + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, team.GetRepositoriesCtx(db.DefaultContext), "%s: GetRepositories", team.Name) assert.Len(t, team.Repos, team.NumRepos, "%s: len repo", team.Name) assert.Len(t, team.Repos, len(repoIds), "%s: repo count", team.Name) diff --git a/modules/setting/service.go b/modules/setting/service.go index af8a72cc6d..10e3899950 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -38,6 +38,7 @@ var Service = struct { EnableReverseProxyAuth bool EnableReverseProxyAutoRegister bool EnableReverseProxyEmail bool + EnableReverseProxyFullName bool EnableCaptcha bool RequireExternalRegistrationCaptcha bool RequireExternalRegistrationPassword bool @@ -127,6 +128,7 @@ func newService() { Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool() + Service.EnableReverseProxyFullName = sec.Key("ENABLE_REVERSE_PROXY_FULL_NAME").MustBool() Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false) Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha) Service.RequireExternalRegistrationPassword = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_PASSWORD").MustBool() diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 0af743dd97..3ab25fef6e 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -186,6 +186,7 @@ var ( CookieRememberName string ReverseProxyAuthUser string ReverseProxyAuthEmail string + ReverseProxyAuthFullName string ReverseProxyLimit int ReverseProxyTrustedProxies []string MinPasswordLength int @@ -909,6 +910,7 @@ func loadFromConf(allowEmpty bool, extraConfig string) { ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER") ReverseProxyAuthEmail = sec.Key("REVERSE_PROXY_AUTHENTICATION_EMAIL").MustString("X-WEBAUTH-EMAIL") + ReverseProxyAuthFullName = sec.Key("REVERSE_PROXY_AUTHENTICATION_FULL_NAME").MustString("X-WEBAUTH-FULLNAME") ReverseProxyLimit = sec.Key("REVERSE_PROXY_LIMIT").MustInt(1) ReverseProxyTrustedProxies = sec.Key("REVERSE_PROXY_TRUSTED_PROXIES").Strings(",") diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 8a15cec2c6..602afec413 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -972,11 +972,11 @@ type remoteAddress struct { Password string } -func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress { +func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string, ignoreOriginalURL bool) remoteAddress { a := remoteAddress{} remoteURL := m.OriginalURL - if remoteURL == "" { + if ignoreOriginalURL || remoteURL == "" { var err error remoteURL, err = git.GetRemoteAddress(ctx, m.RepoPath(), remoteName) if err != nil { diff --git a/modules/test/context_tests.go b/modules/test/context_tests.go index a08439e93f..963f79c3c6 100644 --- a/modules/test/context_tests.go +++ b/modules/test/context_tests.go @@ -56,7 +56,7 @@ func MockContext(t *testing.T, path string) *context.Context { // LoadRepo load a repo into a test context. func LoadRepo(t *testing.T, ctx *context.Context, repoID int64) { ctx.Repo = &context.Repository{} - ctx.Repo.Repository = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) + ctx.Repo.Repository = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) var err error ctx.Repo.Owner, err = user_model.GetUserByID(ctx.Repo.Repository.OwnerID) assert.NoError(t, err) @@ -81,7 +81,7 @@ func LoadRepoCommit(t *testing.T, ctx *context.Context) { // LoadUser load a user into a test context. func LoadUser(t *testing.T, ctx *context.Context, userID int64) { - ctx.Doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User) + ctx.Doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) } // LoadGitRepo load a git repo into a test context. Requires that ctx.Repo has diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go index 5e89b0faa2..8473d45051 100644 --- a/modules/timeutil/since.go +++ b/modules/timeutil/since.go @@ -234,7 +234,7 @@ func TimeSince(then time.Time, lang translation.Locale) template.HTML { } func htmlTimeSince(then, now time.Time, lang translation.Locale) template.HTML { - return template.HTML(fmt.Sprintf(`%s`, + return template.HTML(fmt.Sprintf(`%s`, then.In(setting.DefaultUILocation).Format(GetTimeFormat(lang.Language())), timeSince(then, now, lang))) } @@ -245,7 +245,7 @@ func TimeSinceUnix(then TimeStamp, lang translation.Locale) template.HTML { } func htmlTimeSinceUnix(then, now TimeStamp, lang translation.Locale) template.HTML { - return template.HTML(fmt.Sprintf(`%s`, + return template.HTML(fmt.Sprintf(`%s`, then.FormatInLocation(GetTimeFormat(lang.Language()), setting.DefaultUILocation), timeSinceUnix(int64(then), int64(now), lang))) } diff --git a/modules/timeutil/since_test.go b/modules/timeutil/since_test.go index 8bdb9d7546..dfcf9cb01d 100644 --- a/modules/timeutil/since_test.go +++ b/modules/timeutil/since_test.go @@ -119,7 +119,7 @@ func TestHtmlTimeSince(t *testing.T) { // test that `diff` yields a result containing `expected` test := func(expected string, diff time.Duration) { actual := htmlTimeSince(BaseDate, BaseDate.Add(diff), translation.NewLocale("en-US")) - assert.Contains(t, actual, `title="Sat Jan 1 00:00:00 UTC 2000"`) + assert.Contains(t, actual, `data-content="Sat Jan 1 00:00:00 UTC 2000"`) assert.Contains(t, actual, expected) } test("1 second", time.Second) diff --git a/modules/web/middleware/binding.go b/modules/web/middleware/binding.go index 88a3920f6e..636e655b9e 100644 --- a/modules/web/middleware/binding.go +++ b/modules/web/middleware/binding.go @@ -136,7 +136,16 @@ func Validate(errs binding.Errors, data map[string]interface{}, f Form, l transl case validation.ErrRegexPattern: data["ErrorMsg"] = trName + l.Tr("form.regex_pattern_error", errs[0].Message) default: - data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + errs[0].Classification + msg := errs[0].Classification + if msg != "" && errs[0].Message != "" { + msg += ": " + } + + msg += errs[0].Message + if msg == "" { + msg = l.Tr("form.unknown_error") + } + data["ErrorMsg"] = trName + ": " + msg } return errs } diff --git a/options/license/Python-2.0.1 b/options/license/Python-2.0.1 new file mode 100644 index 0000000000..2b90e0400c --- /dev/null +++ b/options/license/Python-2.0.1 @@ -0,0 +1,207 @@ +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Python Software Foundation; +All Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION +---------------------------------------------------------------------- + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/options/license/mpi-permissive b/options/license/mpi-permissive new file mode 100644 index 0000000000..2abcbe3ab0 --- /dev/null +++ b/options/license/mpi-permissive @@ -0,0 +1,15 @@ +* Copyright (C) 2000-2004 by Etnus, LLC + * + * Permission is hereby granted to use, reproduce, prepare derivative + * works, and to redistribute to others. + * + * DISCLAIMER + * + * Neither Etnus, nor any of their employees, makes any warranty + * express or implied, or assumes any legal liability or + * responsibility for the accuracy, completeness, or usefulness of any + * information, apparatus, product, or process disclosed, or + * represents that its use would not infringe privately owned rights. + * + * This code was written by + * James Cownie: Etnus, LLC. diff --git a/options/license/mpich2 b/options/license/mpich2 index 5c32b0ec1d..1fa4acbc62 100644 --- a/options/license/mpich2 +++ b/options/license/mpich2 @@ -3,11 +3,17 @@ COPYRIGHT The following is a notice of limited availability of the code, and disclaimer which must be included in the prologue of the code and in all source listings of the code. Copyright Notice -+ 2002 University of Chicago +1998--2020, Argonne National Laboratory Permission is hereby granted to use, reproduce, prepare derivative works, and to redistribute to others. This software was authored by: -Argonne National Laboratory Group W. Gropp: (630) 252-4318; FAX: (630) 252-5986; e-mail: gropp@mcs.anl.gov E. Lusk: (630) 252-7852; FAX: (630) 252-5986; e-mail: lusk@mcs.anl.gov Mathematics and Computer Science Division Argonne National Laboratory, Argonne IL 60439 +Mathematics and Computer Science Division +Argonne National Laboratory, Argonne IL 60439 + +(and) + +Department of Computer Science +University of Illinois at Urbana-Champaign GOVERNMENT LICENSE diff --git a/options/locale/locale_bg-BG.ini b/options/locale/locale_bg-BG.ini index 532bb4626f..497aab66c7 100644 --- a/options/locale/locale_bg-BG.ini +++ b/options/locale/locale_bg-BG.ini @@ -8,7 +8,6 @@ sign_out=Изход sign_up=Регистриране link_account=Свържи профил register=Регистрация -website=Уебсайт version=Версия powered_by=С подкрепата на %s page=Страница diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 389a259628..2b3ddeace3 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -8,7 +8,6 @@ sign_out=Odhlásit se sign_up=Registrovat se link_account=Propojit účet register=Registrovat se -website=Webové stránky version=Verze powered_by=Běží na %s page=Strana @@ -993,8 +992,6 @@ file_view_rendered=Zobrazit vykreslené file_view_raw=Zobrazit v surovém stavu file_permalink=Trvalý odkaz file_too_large=Soubor je příliš velký pro zobrazení. -bidi_bad_header=`Tento soubor obsahuje neočekávané obousměrné znaky Unicode!` -line_unicode=`Tento řádek má skryté unicode znaky` file_copy_permalink=Kopírovat trvalý odkaz video_not_supported_in_browser=Váš prohlížeč nepodporuje značku pro HTML5 video. diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index fa8b470a0f..84630dbc34 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -9,7 +9,6 @@ sign_out=Abmelden sign_up=Registrieren link_account=Account verbinden register=Registrieren -website=Webseite version=Version powered_by=Powered by %s page=Seite @@ -1032,13 +1031,7 @@ file_view_rendered=Ansicht rendern file_view_raw=Originalformat anzeigen file_permalink=Permalink file_too_large=Die Datei ist zu groß zum Anzeigen. -bidi_bad_header=`Diese Datei enthält unerwartete Bidirektionale Unicode-Zeichen!` -bidi_bad_description=`Diese Datei enthält unerwartete Bidirektionale Unicode-Zeichen, die anders verarbeitet werden können als nachstehend angezeigt. Wenn dein Anwendungsfall absichtlich und legitim ist, kannst du diese Warnung ignorieren. Benutze den "Escape" Button, um versteckte Zeichen anzuzeigen.` -bidi_bad_description_escaped=`Diese Datei enthält unerwartete Unicode-Zeichen. Versteckte Unicode-Zeichen werden unten escaped. Benutze den "Unescapen" Button, um zu sehen, wie sie ansonsten aussehen.` -unicode_header=`Diese Datei enthält versteckte Unicode-Zeichen!` -unicode_description=`Diese Datei enthält versteckte Unicode-Zeichen, die anders verarbeitet werden können als unten angezeigt. Wenn dein Anwendungsfall absichtlich und legitim ist, kannst du diese Warnung ignorieren. Benutze den Escape Button, um versteckte Zeichen anzuzeigen.` -unicode_description_escaped=`Diese Datei enthält versteckte Unicode-Zeichen. Versteckte Unicode-Zeichen werden unten escaped. Benutze den "Unescapen" Button, um zu sehen, wie sie ansonsten aussehen.` -line_unicode=`Diese Zeile hat versteckte Unicode-Zeichen` +ambiguous_character=`%[1]c [U+%04[1]X] kann mit %[2]c [U+%04[2]X] verwechselt werden` escape_control_characters=Escapen unescape_control_characters=Unescapen @@ -1059,6 +1052,7 @@ normal_view=Normale Ansicht line=zeile lines=Zeilen +editor.add_file=Datei hinzufügen editor.new_file=Neue Datei editor.upload_file=Datei hochladen editor.edit_file=Datei bearbeiten @@ -1264,6 +1258,8 @@ issues.filter_milestone=Meilenstein issues.filter_milestone_no_select=Alle Meilensteine issues.filter_assignee=Zuständig issues.filter_assginee_no_select=Alle Zuständigen +issues.filter_poster=Autor +issues.filter_poster_no_select=Alle Autoren issues.filter_type=Typ issues.filter_type.all_issues=Alle Issues issues.filter_type.assigned_to_you=Dir zugewiesen @@ -2790,7 +2786,9 @@ config.deliver_timeout=Zeitlimit für Zustellung config.skip_tls_verify=TLS-Verifikation überspringen config.mailer_enabled=Aktiviert +config.mailer_enable_helo=HELO aktivieren config.mailer_name=Name +config.mailer_protocol=Protokoll config.mailer_user=Benutzer config.mailer_use_sendmail=Sendmail benutzen config.mailer_sendmail_path=Sendmail-Pfad @@ -3097,6 +3095,7 @@ npm.dependencies.development=Entwicklungsabhängigkeiten npm.dependencies.peer=Peer Abhängigkeiten npm.dependencies.optional=Optionale Abhängigkeiten npm.details.tag=Tag +pub.install=Um das Paket mit Dart zu installieren, führe den folgenden Befehl aus: pypi.requires=Erfordert Python pypi.install=Nutze folgenden Befehl, um das Paket mit pip zu installieren: pypi.documentation=Weitere Informationen zur PyPI-Paketverwaltung findest du in der Dokumentation. diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 94b8eb9a15..e06a3e5392 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -9,7 +9,6 @@ sign_out=Έξοδος sign_up=Εγγραφή link_account=Σύνδεση λογαριασμού register=Εγγραφή -website=Ιστοσελίδα version=Έκδοση powered_by=Με τη δύναμη του %s page=Σελίδα @@ -1033,13 +1032,6 @@ file_view_rendered=Προβολή Απόδοσης file_view_raw=Προβολή Ακατέργαστου file_permalink=Permalink file_too_large=Το αρχείο είναι πολύ μεγάλο για να εμφανιστεί. -bidi_bad_header=`Αυτό το αρχείο περιέχει μη αναμενόμενους χαρακτήρες Unicode!` -bidi_bad_description=`Αυτό το αρχείο περιέχει μη αναμενόμενους χαρακτήρες Bidirectional Unicode που ίσως να επεξεργάζονται διαφορετικά από ότι εμφανίζεται παρακάτω. Αν η χρήση αυτή είναι σκόπιμη και νόμιμη, μπορείτε να αγνοήσετε με ασφάλεια αυτή την προειδοποίηση. Χρησιμοποιήστε το κουμπί Escape για να αποκαλύψετε κρυμμένους χαρακτήρες.` -bidi_bad_description_escaped=`Αυτό το αρχείο περιέχει μη αναμενόμενους χαρακτήρες Bidirectional Unicode. Οι κρυμμένοι χαρακτήρες unicode εμφανίζονται κωδικοποιημένοι παρακάτω. Χρησιμοποιήστε το κουμπί Unescape για να δείτε πώς αποδίδονται.` -unicode_header=`Αυτό το αρχείο περιέχει κρυφούς χαρακτήρες Unicode!` -unicode_description=`Αυτό το αρχείο περιέχει κρυφούς χαρακτήρες Unicode που μπορεί να επεξεργάζονται διαφορετικά από όπως εμφανίζονται παρακάτω. Αν η χρήση είναι σκόπιμη και νόμιμη, μπορείτε να αγνοήσετε με ασφάλεια αυτή την προειδοποίηση. Χρησιμοποιήστε το κουμπί Escape για να αποκαλύψετε τους κρυφούς χαρακτήρες.` -unicode_description_escaped=`Αυτό το αρχείο περιέχει κρυφούς χαρακτήρες Unicode. Οι κρυφοί χαρακτήρες unicode εμφανίζονται κωδικοποιημένοι παρακάτω. Χρησιμοποιήστε το κουμπί Unescape για να δείτε πώς αποδίδονται.` -line_unicode=`Αυτή η γραμμή έχει κρυφούς χαρακτήρες unicode` escape_control_characters=Escape unescape_control_characters=Unescape diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 426521e4ee..0e309279d2 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -9,7 +9,6 @@ sign_out = Sign Out sign_up = Register link_account = Link Account register = Register -website = Website version = Version powered_by = Powered by %s page = Page @@ -1036,13 +1035,13 @@ file_view_rendered = View Rendered file_view_raw = View Raw file_permalink = Permalink file_too_large = The file is too large to be shown. -bidi_bad_header = `This file contains unexpected Bidirectional Unicode characters!` -bidi_bad_description = `This file contains unexpected Bidirectional Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.` -bidi_bad_description_escaped = `This file contains unexpected Bidirectional Unicode characters. Hidden unicode characters are escaped below. Use the Unescape button to show how they render.` -unicode_header = `This file contains hidden Unicode characters!` -unicode_description = `This file contains hidden Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.` -unicode_description_escaped = `This file contains hidden Unicode characters. Hidden unicode characters are escaped below. Use the Unescape button to show how they render.` -line_unicode = `This line has hidden unicode characters` +invisible_runes_header = `This file contains invisible Unicode characters!` +invisible_runes_description = `This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.` +ambiguous_runes_header = `This file contains ambiguous Unicode characters!` +ambiguous_runes_description = `This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.` +invisible_runes_line = `This line has invisible unicode characters` +ambiguous_runes_line = `This line has ambiguous unicode characters` +ambiguous_character = `%[1]c [U+%04[1]X] is confusable with %[2]c [U+%04[2]X]` escape_control_characters = Escape unescape_control_characters = Unescape @@ -2896,6 +2895,7 @@ monitor.queue.nopool.title = No Worker Pool monitor.queue.nopool.desc = This queue wraps other queues and does not itself have a worker pool. monitor.queue.wrapped.desc = A wrapped queue wraps a slow starting queue, buffering queued requests in a channel. It does not have a worker pool itself. monitor.queue.persistable-channel.desc = A persistable-channel wraps two queues, a channel queue that has its own worker pool and a level queue for persisted requests from previous shutdowns. It does not have a worker pool itself. +monitor.queue.flush = Flush worker monitor.queue.pool.timeout = Timeout monitor.queue.pool.addworkers.title = Add Workers monitor.queue.pool.addworkers.submit = Add Workers diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index be3c2fbb34..ea1ce54749 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -9,7 +9,6 @@ sign_out=Cerrar sesión sign_up=Registrarse link_account=Vincular cuenta register=Registro -website=Página web version=Versión powered_by=Impulsado por %s page=Página @@ -979,7 +978,7 @@ migrate.migrating_topics=Migrando Temas migrate.migrating_milestones=Migrando Hitos migrate.migrating_labels=Migrando etiquetas migrate.migrating_releases=Migrando Lanzamientos -migrate.migrating_issues=Migrando Incidencías +migrate.migrating_issues=Migrando incidencias migrate.migrating_pulls=Migrando Pull Requests mirror_from=réplica de @@ -1036,13 +1035,13 @@ file_view_rendered=Ver procesado file_view_raw=Ver original file_permalink=Enlace permanente file_too_large=El archivo es demasiado grande para ser mostrado. -bidi_bad_header=`¡Este archivo contiene caracteres Unicode bidireccional inesperados!` -bidi_bad_description=`Este archivo contiene caracteres Bidirectional Unicode inesperados que pueden ser procesados de forma diferente a lo que aparece a continuación. Si su caso de uso es intencional y legítimo, puede ignorar esta advertencia. Use el botón de Escape para revelar caracteres ocultos.` -bidi_bad_description_escaped=`Este archivo contiene caracteres Unicode bidireccionales inesperados. Los caracteres unicode ocultos se escapan debajo. Utilice el botón Unescape para mostrar cómo se renderizan.` -unicode_header=`¡Este archivo contiene caracteres Unicode ocultos!` -unicode_description=`Este archivo contiene caracteres Unicode ocultos que pueden ser procesados de forma diferente a lo que aparece a continuación. Si su caso de uso es intencional y legítimo, puede ignorar esta advertencia. Use el botón de Escape para revelar caracteres ocultos.` -unicode_description_escaped=`Este archivo contiene caracteres Unicode ocultos. Los caracteres unicode ocultos se escapan debajo. Utilice el botón Unescape para mostrar cómo renderizan.` -line_unicode=`Esta línea tiene caracteres unicode ocultos` +invisible_runes_header=`¡Este archivo contiene caracteres Unicode invisibles!` +invisible_runes_description=`Este archivo contiene caracteres Unicode invisibles que pueden ser procesados de forma diferente a lo que aparece a continuación. Si su caso de uso es intencional y legítimo, puede ignorar esta advertencia. Use el botón de Escape para revelar caracteres ocultos.` +ambiguous_runes_header=`¡Este archivo contiene caracteres Unicode ambiguos!` +ambiguous_runes_description=`Este archivo contiene caracteres Unicode ambiguos que pueden confundirse con otros en tu idioma actual. Si tu caso de uso es intencional y legítimo, puedes ignorar esta advertencia. Usa el botón de Escape para resaltar estos caracteres.` +invisible_runes_line=`Esta línea tiene caracteres unicode invisibles` +ambiguous_runes_line=`Esta línea tiene caracteres unicode ambiguos` +ambiguous_character=`%[1]c [U+%04[1]X] es confusable con %[2]c [U+%04[2]X]` escape_control_characters=Escapar unescape_control_characters=No Escapar @@ -1269,6 +1268,8 @@ issues.filter_milestone=Milestone issues.filter_milestone_no_select=Todos los hitos issues.filter_assignee=Asignada a issues.filter_assginee_no_select=Todos los asignados +issues.filter_poster=Autor +issues.filter_poster_no_select=Todos los autores issues.filter_type=Tipo issues.filter_type.all_issues=Todas las incidencias issues.filter_type.assigned_to_you=Asignadas a ti @@ -2894,6 +2895,7 @@ monitor.queue.nopool.title=No existe un grupo de trabajadores monitor.queue.nopool.desc=Esta cola envuelve otras colas y no tiene grupos de trabajadores. monitor.queue.wrapped.desc=Una cola de tipo envuelto envuelve una cola de inicio lenta, búfer de peticiones en un canal. No tiene grupos de trabajadores en si misma. monitor.queue.persistable-channel.desc=Una cola de tipo canal persistente envuelve dos colas, una cola de canales que tiene sus propios grupos de trabajadores y una cola de niveles para peticiones persistentes de apagones anteriores. No tiene grupos de trabajadores en sí misma. +monitor.queue.flush=Vaciar trabajador monitor.queue.pool.timeout=Tiempo de espera monitor.queue.pool.addworkers.title=Añadir trabajadores monitor.queue.pool.addworkers.submit=Añadir trabajadores diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 5595de24c3..d60b6dceea 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -8,7 +8,6 @@ sign_out=خروج sign_up=ثبت نام link_account=پیوند به حساب register=ثبت نام -website=وب‌سایت version=نسخه powered_by=قدرت از %s page=صفحه diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index 0323854339..7c0cc31097 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -9,7 +9,6 @@ sign_out=Kirjaudu ulos sign_up=Rekisteröidy link_account=Yhdistä tili register=Rekisteröidy -website=Nettisivut version=Versio powered_by=Voimanlähteenä %s page=Sivu @@ -239,6 +238,7 @@ show_only_archived=Näytetään vain arkistoidut show_only_unarchived=Näytetään vain arkistoimattomat show_private=Yksityinen +show_both_private_public=Näytetään sekä julkiset että yksityiset show_only_private=Näytetään vain yksityiset show_only_public=Näytetään vain julkiset @@ -661,6 +661,7 @@ template_helper=Tee reposta mallipohja visibility=Näkyvyys visibility_description=Vain omistaja tai organisaation jäsenet, jos heillä on oikeudet, voivat nähdä sen. visibility_helper=Tee reposta yksityinen +visibility_helper_forced=Sivuston ylläpitäjä pakottaa uudet repot olemaan yksityisiä. fork_repo=Forkkaa repo fork_from=Forkkaa lähteestä fork_visibility_helper=Forkatun repon näkyvyyttä ei voi muuttaa. @@ -1087,6 +1088,7 @@ settings.danger_zone=Vaaravyöhyke settings.new_owner_has_same_repo=Uudella omistajalla on jo samanniminen repo. Ole hyvä ja valitse toinen nimi. settings.transfer=Siirrä omistajuus settings.transfer_form_title=Syötä repon nimi vahvistuksena: +settings.transfer_notices_3=- Jos arkisto on yksityinen ja se siirretään yksittäiselle käyttäjälle, tämä toiminto varmistaa, että käyttäjällä on ainakin lukuoikeudet (ja muuttaa käyttöoikeuksia tarvittaessa). settings.transfer_owner=Uusi omistaja settings.wiki_delete=Poista Wiki data settings.wiki_delete_desc=Repon wikin data poistaminen on pysyvä eikä voi peruuttaa. @@ -1140,14 +1142,24 @@ settings.web_hook_name_matrix=Matrix settings.web_hook_name_feishu=Feishu settings.web_hook_name_larksuite=Lark Suite settings.web_hook_name_packagist=Packagist -settings.deploy_keys=Deploy avaimet -settings.add_deploy_key=Lisää deploy avain +settings.deploy_keys=Julkaisuavaimet +settings.add_deploy_key=Lisää julkaisuavain +settings.deploy_key_desc=Julkaisuavaimilla on vain-luku oikeudet repoon. +settings.is_writable_info=Salli tämän julkaisuavaimen puskea repoon. +settings.no_deploy_keys=Julkaisuavaimia ei ole käytössä vielä. settings.title=Otsikko settings.deploy_key_content=Sisältö +settings.key_been_used=Julkaisuavain identtisellä sisällöllä on jo käytössä. +settings.key_name_used=Julkaisuavain samalla nimellä on jo olemassa. +settings.add_key_success=Julkaisuavain '%s' on lisätty. +settings.deploy_key_deletion=Poista julkaisuavain +settings.deploy_key_deletion_desc=Julkaisuavaimen poistaminen kumoaa sen pääsyn tähän repoon. Jatketaanko? +settings.deploy_key_deletion_success=Julkaisuavain on poistettu. settings.branches=Haarat settings.protected_branch=Haaran suojaus settings.branch_protection=Haaran '%s' suojaus settings.protect_this_branch=Ota haaran suojaus käyttöön +settings.protect_whitelist_deploy_keys=Lisää julkaisuavaimet sallittujen listalle mahdollistaaksesi repohin kirjoituksen. settings.protect_whitelist_users=Lista käyttäjistä joilla työntö oikeus: settings.protect_whitelist_search_users=Etsi käyttäjiä… settings.protect_merge_whitelist_committers_desc=Salli vain listaan merkittyjen käyttäjien ja tiimien yhdistää vetopyynnöt tähän haaraan. @@ -1171,7 +1183,28 @@ settings.matrix.access_token=Pääsymerkki settings.archive.button=Arkistoi repo settings.archive.header=Arkistoi tämä repo settings.lfs=LFS +settings.lfs_filelist=LFS-tiedostot tallennettu tähän repoon +settings.lfs_no_lfs_files=LFS-tiedostoja ei ole tallennettu tähän repoon. +settings.lfs_findcommits=Etsi commitit +settings.lfs_lfs_file_no_commits=LFS-tiedostolle ei löytynyt committeja +settings.lfs_noattribute=Tällä polulla ei ole lukittavaa attribuuttia oletushaarassa +settings.lfs_delete=Poista LFS-tiedosto OID:lla %s +settings.lfs_delete_warning=LFS-tiedoston poistaminen voi aiheuttaa 'object does not exists'-virheitä checkouttattaessa. Oletko varma? +settings.lfs_findpointerfiles=Etsi osoitintiedostoja +settings.lfs_locks=Lukot +settings.lfs_invalid_locking_path=Virheellinen polku: %s +settings.lfs_invalid_lock_directory=Hakemistoa ei voida lukita: %s +settings.lfs_lock_already_exists=Lukitus on jo olemassa: %s +settings.lfs_lock_path=Lukittavan tiedostopolku... +settings.lfs_locks_no_locks=Ei lukkoja +settings.lfs_lock_file_no_exist=Lukittua tiedostoa ei ole olemassa oletushaarassa +settings.lfs_force_unlock=Pakota lukituksen avaus +settings.lfs_pointers.found=Löytyi %d blob osoitinta - %d yhdistettyö, %d yhdistämätöntä (%d puuttuu varastosta) +settings.lfs_pointers.sha=Blob SHA settings.lfs_pointers.oid=OID +settings.lfs_pointers.inRepo=Repossa +settings.lfs_pointers.exists=Löytyy varastosta +settings.lfs_pointers.accessible=Saatavilla käyttäjälle diff.browse_source=Selaa lähdekoodia diff.parent=vanhempi @@ -1388,8 +1421,18 @@ users.allow_git_hook=Voi luoda Git koukkuja users.allow_create_organization=Voi luoda organisaatioita users.update_profile=Päivitä käyttäjän tili users.delete_account=Poista käyttäjän tili +users.list_status_filter.menu_text=Suodata +users.list_status_filter.reset=Tyhjennä +users.list_status_filter.is_active=Aktiivinen +users.list_status_filter.not_active=Ei-aktiivinen +users.list_status_filter.is_admin=Ylläpitäjä +users.list_status_filter.not_admin=Ei ylläpitäjä users.list_status_filter.is_restricted=Rajoitettu users.list_status_filter.not_restricted=Ei rajoitettu +users.list_status_filter.is_prohibit_login=Kirjautuminen estetty +users.list_status_filter.not_prohibit_login=Kirjautuminen sallittu +users.list_status_filter.is_2fa_enabled=2FA käytössä +users.list_status_filter.not_2fa_enabled=2FA ei käytössä emails.email_manage_panel=Käyttäjien sähköpostien hallinta emails.primary=Ensisijainen diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index ac1d950534..18eb44b16a 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -9,7 +9,6 @@ sign_out=Déconnexion sign_up=S'inscrire link_account=Lier un Compte register=S'inscrire -website=Site web version=Version powered_by=Propulsé par %s page=Page @@ -43,6 +42,11 @@ webauthn_error=Impossible de lire votre clé de sécurité. webauthn_unsupported_browser=Votre navigateur ne prend actuellement pas en charge WebAuthn. webauthn_error_unknown=Une erreur indéterminée s'est produite. Veuillez réessayer. webauthn_error_insecure=WebAuthn ne prend en charge que les connexions sécurisées. Pour les tests via HTTP, vous pouvez utiliser l'origine "localhost" ou "127.0.0.1" +webauthn_error_unable_to_process=Le serveur n'a pas pu traiter votre demande. +webauthn_error_duplicated=La clé de sécurité n'est pas autorisée pour cette demande. Veuillez vous assurer que la clé n'est pas déjà enregistrée. +webauthn_error_empty=Vous devez définir un nom pour cette clé. +webauthn_error_timeout=Le délai d'attente imparti a été atteint avant que votre clé ne puisse être lue. Veuillez recharger la page pour réessayer. +webauthn_reload=Recharger repository=Dépôt organization=Organisation @@ -103,7 +107,12 @@ never=Jamais rss_feed=Flux RSS [error] +occurred=Une erreur s’est produite +report_message=Si vous êtes sûr qu'il s'agit d'un bug de Gitea, cherchez s’il existe des tickets sur GitHub ou ouvrez-en un nouveau si nécessaire. missing_csrf=Requête incorrecte: aucun jeton CSRF présent +invalid_csrf=Requête incorrecte : jeton CSRF invalide +not_found=La cible n'a pu être trouvée. +network_error=Erreur réseau [startpage] app_desc=Un service Git auto-hébergé sans prise de tête @@ -169,6 +178,8 @@ log_root_path_helper=Les fichiers de journalisation seront écrits dans ce répe optional_title=Paramètres facultatifs email_title=Paramètres E-mail +smtp_addr=Hôte SMTP +smtp_port=Port SMTP smtp_from=Envoyer les e-mails en tant que smtp_from_helper=Adresse e-mail utilisée par Gitea. Veuillez entrer votre e-mail directement ou sous la forme . mailer_user=Utilisateur SMTP @@ -259,6 +270,7 @@ search=Rechercher code=Code search.fuzzy=Approximative search.match=Exacte +code_search_unavailable=Actuellement, la recherche de code n'est pas disponible. Veuillez contacter l'administrateur de votre site. repo_no_results=Aucun dépôt correspondant n'a été trouvé. user_no_results=Aucun utilisateur correspondant n'a été trouvé. org_no_results=Aucune organisation correspondante n'a été trouvée. @@ -272,6 +284,7 @@ register_helper_msg=Déjà enregistré ? Connectez-vous ! social_register_helper_msg=Déjà inscrit ? Connectez-vous ! disable_register_prompt=Les inscriptions sont désactivées. Veuillez contacter l'administrateur du site. disable_register_mail=La confirmation par e-mail à l'inscription est désactivée. +manual_activation_only=Contactez l'administrateur de votre site pour terminer l'activation. remember_me=Mémoriser cet appareil forgot_password_title=Mot de passe oublié forgot_password=Mot de passe oublié ? @@ -310,6 +323,9 @@ oauth_signup_submit=Finaliser la création du compte oauth_signin_tab=Lier à un compte existant oauth_signin_title=Connectez-vous pour autoriser le compte lié oauth_signin_submit=Lier un compte +oauth.signin.error=Une erreur s'est produite lors du traitement de la demande d'autorisation. Si cette erreur persiste, veuillez contacter l'administrateur du site. +oauth.signin.error.access_denied=La demande d'autorisation a été refusée. +oauth.signin.error.temporarily_unavailable=L'autorisation a échoué car le serveur d'authentification est temporairement indisponible. Veuillez réessayer plus tard. openid_connect_submit=Se connecter openid_connect_title=Se connecter à un compte existant openid_connect_desc=L'URI OpenID choisie est inconnue. Associez-le à un nouveau compte ici. @@ -356,6 +372,7 @@ reset_password.text=Veuillez cliquer sur le lien suivant pour récupérer votre register_success=Inscription réussie +issue_assigned.pull=@%[1]s vous a assigné à la demande d’ajout %[2]s dans le dépôt %[3]s. issue_assigned.issue=@%[1]s vous a assigné le ticket %[2]s dans le dépôt %[3]s. issue.x_mentioned_you=@%s vous a mentionné: @@ -971,6 +988,9 @@ file_view_rendered=Voir le rendu file_view_raw=Voir le Raw file_permalink=Lien permanent file_too_large=Le fichier est trop gros pour être affiché. +invisible_runes_line=`Cette ligne contient des caractères Unicode invisibles` +ambiguous_runes_line=`Cette ligne contient des caractères Unicode ambigus` +ambiguous_character=`%[1]c [U+%04[1]X] peut être confondu avec %[2]c [U+%04[2]X]` file_copy_permalink=Copier le lien permanent video_not_supported_in_browser=Votre navigateur ne supporte pas le tag HTML5 "video". @@ -988,6 +1008,7 @@ normal_view=Vue normale line=ligne lines=lignes +editor.add_file=Ajouter un fichier editor.new_file=Nouveau fichier editor.upload_file=Téléverser un fichier editor.edit_file=Modifier le fichier @@ -1011,6 +1032,10 @@ editor.add_tmpl=Ajouter '' editor.add=Ajouter '%s' editor.update=Mise à jour de '%s' editor.delete=Supprimer '%s' +editor.patch=Appliquer le correctif +editor.patching=Correction: +editor.fail_to_apply_patch=Impossible d'appliquer le correctif '%s' +editor.new_patch=Nouveau correctif editor.commit_message_desc=Ajouter une description détaillée facultative… editor.signoff_desc=Ajout d'un trailer Signed-off-by par le committeur à la fin du message du journal de commit. editor.commit_directly_to_this_branch=Soumettre directement dans la branche %s. @@ -1035,6 +1060,8 @@ editor.commit_empty_file_text=Le fichier que vous allez commiter est vide. Conti editor.no_changes_to_show=Il n’y a aucun changement à afficher. editor.fail_to_update_file=Impossible de mettre à jour/créer le fichier '%s'. editor.fail_to_update_file_summary=Message d'erreur : +editor.push_rejected_no_message=La modification a été rejetée par le serveur sans message. Veuillez vérifier les Git Hooks. +editor.push_rejected=La modification a été rejetée par le serveur. Veuillez vérifier vos Git Hooks. editor.push_rejected_summary=Message de rejet complet : editor.add_subdir=Ajouter un dossier… editor.unable_to_upload_files=Échec lors de l'envoie du fichier '%s' avec l’erreur : %v @@ -1044,6 +1071,7 @@ editor.cannot_commit_to_protected_branch=Impossible de créer une révision sur editor.no_commit_to_branch=Impossible d'enregistrer la révisions directement sur la branche parce que : editor.user_no_push_to_branch=L'utilisateur ne peut pas pousser vers la branche editor.require_signed_commit=Cette branche nécessite une révision signée +editor.cherry_pick=Picorer %s vers: editor.revert=Rétablir %s sur: commits.desc=Naviguer dans l'historique des modifications. @@ -1063,7 +1091,15 @@ commits.signed_by=Signé par commits.signed_by_untrusted_user=Signé par un utilisateur non approuvé commits.signed_by_untrusted_user_unmatched=Signé par un utilisateur non fiable qui ne correspond pas au validateur commits.gpg_key_id=ID de la clé GPG +commits.ssh_key_fingerprint=Empreinte numérique de la clé SSH +commit.actions=Actions +commit.revert=Rétablir +commit.revert-header=Rétablir : %s +commit.revert-content=Sélectionnez la branche sur laquelle revenir : +commit.cherry-pick=Picorer +commit.cherry-pick-header=Picorer : %s +commit.cherry-pick-content=Sélectionner la branche à picorer : ext_issues.desc=Lien vers un gestionnaire de tickets externe. @@ -1383,6 +1419,7 @@ compare.compare_head=comparer pulls.desc=Activer les demandes de fusion et la revue de code. pulls.new=Nouvelle demande d'ajout +pulls.view=Voir la demande d'ajout pulls.compare_changes=Nouvelle demande de fusion pulls.compare_changes_desc=Sélectionnez la branche dans laquelle fusionner et la branche depuis laquelle tirer les modifications. pulls.compare_base=fusionner dans @@ -1392,6 +1429,7 @@ pulls.filter_branch=Filtre de branche pulls.no_results=Aucun résultat trouvé. pulls.nothing_to_compare=Ces branches sont identiques. Il n'y a pas besoin de créer une demande de fusion. pulls.nothing_to_compare_and_allow_empty_pr=Ces branches sont égales. Cette demande d'ajout sera vide. +pulls.has_pull_request='Il existe déjà une demande d'ajout entre ces deux branches : %[2]s#%[3]d' pulls.create=Créer une demande d'ajout pulls.title_desc=veut fusionner %[1]d révision(s) depuis %[2]s vers %[3]s pulls.merged_title_desc=a fusionné %[1]d révision(s) à partir de %[2]s vers %[3]s %[4]s @@ -1420,7 +1458,6 @@ pulls.required_status_check_missing=Certains contrôles requis sont manquants. pulls.required_status_check_administrator=En tant qu'administrateur, vous pouvez toujours fusionner cette requête de pull. pulls.blocked_by_approvals=Cette demande d'ajout n'a pas assez d'approbation. %d sur %d approbations accordées. pulls.blocked_by_rejection=Cette demande de fusion a des modifications demandées par un réviseur officiel. -pulls.blocked_by_official_review_requests=Cette demande d'ajout a des demandes de revue officielles. pulls.blocked_by_outdated_branch=Cette demande d'ajout est bloquée car elle est obsolète. pulls.blocked_by_changed_protected_files_1=Cette demande d'ajout est bloquée car elle modifie un fichier protégé : pulls.blocked_by_changed_protected_files_n=Cette Pull Request est bloquée car elle modifie les fichiers protégés : @@ -1442,6 +1479,10 @@ pulls.no_merge_helper=Activez des options de fusion dans les paramètres du dép pulls.no_merge_wip=Cette demande d'ajout ne peut pas être fusionnée car elle est marquée comme en cours de chantier. pulls.no_merge_not_ready=Cette demande d'ajout n'est pas prête à être fusionnée, vérifiez l'état de la revue et les vérifications. pulls.no_merge_access=Vous n'êtes pas autorisé⋅e à fusionner cette demande d'ajout. +pulls.merge_pull_request=Créer une révision de fusion +pulls.rebase_merge_pull_request=Rebaser puis avancer rapidement +pulls.rebase_merge_commit_pull_request=Rebaser puis créer une révision de fusion +pulls.squash_merge_pull_request=Créer une révision de concaténation pulls.merge_manually=Fusionné manuellement pulls.merge_commit_id=L'ID de la révision de fusion pulls.require_signed_wont_sign=La branche nécessite des révisions signées mais cette fusion ne sera pas signée @@ -1472,9 +1513,17 @@ pulls.merge_instruction_hint=`Vous pouvez également voir %s rename_repo=a rebaptisé le dépôt de %[1]s vers %[3]s +create_pull_request=`a créé la demande d'ajout %[3]s#%[2]s` +close_pull_request=`a fermé la demande d'ajout %[3]s#%[2]s` +reopen_pull_request=`a réouvert la demande d'ajout %[3]s#%[2]s` +comment_pull=`a commenté la demande d'ajout %[3]s#%[2]s` +merge_pull_request=`a fusionné la demande d'ajout %[3]s#%[2]s` transfer_repo=a transféré le dépôt %s à %s delete_tag=étiquette supprimée %[2]s de %[3]s delete_branch=branche %[2]s supprimée de %[3]s @@ -2643,6 +2698,8 @@ compare_branch=Comparer compare_commits=Comparer %d révisions compare_commits_general=Comparer les révisions mirror_sync_delete=a synchronisé puis supprimé la nouvelle référence %[2]s vers %[3]s depuis le miroir +approve_pull_request=`a approuvé %[3]s#%[2]s` +reject_pull_request=`a suggérés des changements pour %[3]s#%[2]s` review_dismissed_reason=Raison : [tool] diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index b09ffdba11..c996aef385 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -8,7 +8,6 @@ sign_out=Kijelentkezés sign_up=Regisztrálás link_account=Fiók kapcsolása register=Regisztráció -website=Webhely version=Verzió powered_by=Biztosítja: %s page=Oldal diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index bfd7e6f31d..e7ddd418c6 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -8,7 +8,6 @@ sign_out=Keluar sign_up=Daftar link_account=Tautan Akun register=Daftar -website=Situs Web version=Versi powered_by=Diberdayakan oleh %s page=Halaman diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index f41fab0f52..90979837cb 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -8,7 +8,6 @@ sign_out=Skrá Út sign_up=Nýskráning link_account=Tengja Notanda register=Nýskráning -website=Vefsíða version=Útgáfa powered_by=Keyrt af %s page=Síða diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index 068891b779..ac29c5b841 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -9,7 +9,6 @@ sign_out=Esci sign_up=Registrati link_account=Collega account register=Registrati -website=Sito Web version=Versione powered_by=Gestito da %s page=Pagina @@ -1036,13 +1035,13 @@ file_view_rendered=Visualizza Renderizzato file_view_raw=Vedi originale file_permalink=Permalink file_too_large=Il file è troppo grande per essere visualizzato. -bidi_bad_header=`Questo file contiene caratteri Unicode Bidirezionali inattesi!` -bidi_bad_description=`Questo file contiene caratteri inaspettati Bidirezionali Unicode che possono essere elaborati in modo diverso da quello che appare di seguito. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per rivelare caratteri nascosti.` -bidi_bad_description_escaped=`Questo file contiene caratteri Unicode bidirezionali inattesi. I caratteri unicode nascosti sono sfuggiti qui sotto. Usa il pulsante Unescape per mostrare come render.` -unicode_header=`Questo file contiene caratteri Unicode nascosti!` -unicode_description=`Questo file contiene caratteri Unicode nascosti che possono essere elaborati in modo diverso da quello che appare di seguito. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per rivelare caratteri nascosti.` -unicode_description_escaped=`Questo file contiene caratteri Unicode nascosti. I caratteri unicode nascosti sono fuggiti qui sotto. Usa il pulsante Unescape per mostrare come render.` -line_unicode=`Questa riga ha caratteri unicode nascosti` +invisible_runes_header=`Questo file contiene caratteri Unicode invisibili!` +invisible_runes_description=`Questo file contiene caratteri Unicode invisibili che possono essere elaborati in modo diverso da quello che appare di seguito. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per rivelare caratteri nascosti.` +ambiguous_runes_header=`Questo file contiene caratteri Unicode ambigui!` +ambiguous_runes_description=`Questo file contiene caratteri Unicode ambigui che possono essere confusi con altri nella tua localizzazione attuale. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per evidenziare questi caratteri.` +invisible_runes_line=`Questa riga ha caratteri unicode invisibili` +ambiguous_runes_line=`Questa riga ha caratteri unicode ambigui` +ambiguous_character=`%[1]c [U+%04[1]X] è confondibile con %[2]c [U+%04[2]X]` escape_control_characters=Fuga unescape_control_characters=Unescape @@ -2896,6 +2895,7 @@ monitor.queue.nopool.title=Nessun pool di Workers monitor.queue.nopool.desc=Questa coda racchiude altre code al suo interno e non ha un proprio pool. monitor.queue.wrapped.desc=Una coda a capo avvolge una coda iniziale lenta, le richieste in coda di buffering in un canale. Non ha un pool di lavoratori stesso. monitor.queue.persistable-channel.desc=Un canale persistibile avvolge due code, una coda di canale che ha un proprio pool di operatori e una coda di livello per le richieste persistenti dagli arresti precedenti. Non ha un pool di operai. +monitor.queue.flush=Flush worker monitor.queue.pool.timeout=Timeout monitor.queue.pool.addworkers.title=Aggiungi Workers monitor.queue.pool.addworkers.submit=Aggiungi Workers diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 08edc0f034..efb41ddd84 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -9,7 +9,6 @@ sign_out=サインアウト sign_up=登録 link_account=アカウント連携 register=登録 -website=Webサイト version=バージョン powered_by=Powered by %s page=ページ @@ -179,6 +178,8 @@ log_root_path_helper=ログファイルがこのディレクトリに書き込 optional_title=オプション設定 email_title=メール設定 +smtp_addr=SMTPホスト +smtp_port=SMTPポート smtp_from=メール送信者 smtp_from_helper=Giteaが使用するメールアドレス。 メールアドレスのみ、または、 "名前" の形式で入力してください。 mailer_user=SMTPユーザー名 @@ -1034,13 +1035,6 @@ file_view_rendered=レンダリング表示 file_view_raw=Rawデータを見る file_permalink=パーマリンク file_too_large=このファイルは大きすぎるため、表示できません。 -bidi_bad_header=`このファイルには予期しない双方向Unicode文字が含まれています!` -bidi_bad_description=`このファイルには予期しない双方向Unicode文字が含まれており、下に見えているものとは異なる処理が行われる可能性があります。 あなたのユースケースが意図的かつ正当な場合はこの警告を無視して構いません。 不可視文字を表示するにはエスケープボタンを使用します。` -bidi_bad_description_escaped=`このファイルには予期しない双方向Unicode文字が含まれています。 下の表示では、不可視Unicode文字はエスケープされています。 どのようにレンダリングされるかを表示するにはエスケープ解除ボタンを使用します。` -unicode_header=`このファイルには不可視Unicode文字が含まれています!` -unicode_description=`このファイルには不可視Unicode文字が含まれており、下に見えているものとは異なる処理が行われる可能性があります。 あなたのユースケースが意図的かつ正当な場合はこの警告を無視して構いません。 不可視文字を表示するにはエスケープボタンを使用します。` -unicode_description_escaped=`このファイルには不可視Unicode文字が含まれています。 下の表示では、不可視Unicode文字はエスケープされています。 どのようにレンダリングされるかを表示するにはエスケープ解除ボタンを使用します。` -line_unicode=`この行には不可視Unicode文字があります` escape_control_characters=エスケープ unescape_control_characters=エスケープ解除 @@ -1061,6 +1055,7 @@ normal_view=通常表示 line=行 lines=行 +editor.add_file=ファイル追加 editor.new_file=新規ファイル editor.upload_file=ファイルをアップロード editor.edit_file=ファイルを編集 @@ -1266,6 +1261,8 @@ issues.filter_milestone=マイルストーン issues.filter_milestone_no_select=すべてのマイルストーン issues.filter_assignee=担当者 issues.filter_assginee_no_select=すべての担当者 +issues.filter_poster=作成者 +issues.filter_poster_no_select=すべての作成者 issues.filter_type=タイプ issues.filter_type.all_issues=すべてのイシュー issues.filter_type.assigned_to_you=自分が担当 @@ -3109,6 +3106,10 @@ npm.dependencies.development=開発用依存関係 npm.dependencies.peer=Peer依存関係 npm.dependencies.optional=オプションの依存関係 npm.details.tag=タグ +pub.install=Dart を使用してパッケージをインストールするには、次のコマンドを実行します: +pub.documentation=Pub レジストリの詳細については、ドキュメント を参照してください。 +pub.details.repository_site=リポジトリサイト +pub.details.documentation_site=ドキュメントサイト pypi.requires=必要なPython pypi.install=pip を使用してパッケージをインストールするには、次のコマンドを実行します: pypi.documentation=PyPI レジストリの詳細については、ドキュメント を参照してください。 diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index 002007508c..d4917f861a 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -8,7 +8,6 @@ sign_out=로그아웃 sign_up=가입하기 link_account=계정 연결 register=가입하기 -website=웹 사이트 version=버전 powered_by=%s 제공 page=페이지 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index acc2fad7e8..b826757620 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -9,7 +9,6 @@ sign_out=Izrakstīties sign_up=Reģistrēties link_account=Saistītie konti register=Reģistrēties -website=Mājas lapa version=Versija powered_by=Darbina %s page=Lapa @@ -1036,13 +1035,6 @@ file_view_rendered=Skatīt rezultātu file_view_raw=Rādīt neapstrādātu file_permalink=Patstāvīgā saite file_too_large=Šis fails ir par lielu, lai to parādītu. -bidi_bad_header=`Šis fails satur neparedzētus virzienmaiņas unikoda simbolus!` -bidi_bad_description=`Šis fails satur neparedzētus virzienmaiņas unikoda simbolus, kas var mainīt kā saturs tiek attēlots. Ja tie ir izmantoti ar pamatotu nodumu, tad varat ignorēt šo brīdinājumu. Izmantojiet Kodēt pogu, lai parādītu šos neredzamos simbolus.` -bidi_bad_description_escaped=`Šis fails satur neparedzētus virzienmaiņas unikoda simbolus. Neredzamie unikoda simboli ir kodēti, lai būtu redzami. Izmantojiet Atkodēt pogu, lai redzētu kā tie tiek attēloti.` -unicode_header=`Šis fails satur neredzamus unikoda simbolus!` -unicode_description=`Šis fails satur neredzamus unikoda simbolus, kas var mainīt kā saturs tiek attēlots. Ja tie ir izmantoti ar pamatotu nodumu, tad varat ignorēt šo brīdinājumu. Izmantojiet Kodēt pogu, lai parādītu šos neredzamos simbolus.` -unicode_description_escaped=`Šis fails satur neredzamus unikoda simbolus. Neredzamie unikoda simboli ir kodēti, lai būtu redzami. Izmantojiet Atkodēt pogu, lai redzētu kā tie tiek attēloti.` -line_unicode=`Šajā līnijā ir paslēpti unikoda simboli` escape_control_characters=Kodēt unescape_control_characters=Atkodēt diff --git a/options/locale/locale_ml-IN.ini b/options/locale/locale_ml-IN.ini index 5befd50bbf..7ee595bf4f 100644 --- a/options/locale/locale_ml-IN.ini +++ b/options/locale/locale_ml-IN.ini @@ -8,7 +8,6 @@ sign_out=പുറത്തുകടക്കുക sign_up=രജിസ്റ്റർ link_account=അക്കൌണ്ട് ബന്ധിപ്പിയ്ക്കുക register=രജിസ്റ്റർ -website=വെബ് സൈറ്റ് version=പതിപ്പ് page=പേജ് template=ടെംപ്ലേറ്റ് diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index e5b8ffefcd..5b18185fef 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -9,7 +9,6 @@ sign_out=Uitloggen sign_up=Registreren link_account=Account Koppelen register=Registreren -website=Website version=Versie powered_by=Powered by %s page=Pagina @@ -1036,13 +1035,13 @@ file_view_rendered=Weergave weergeven file_view_raw=Weergave ruw bestand file_permalink=Permalink file_too_large=Dit bestand is te groot om te tonen. -bidi_bad_header=`Dit bestand bevat onverwachte Bidirectionele Unicode karakters!` -bidi_bad_description=`Dit bestand bevat onverwachte Bidirectionele Unicode-tekens die anders verwerkt kunnen worden dan hieronder het geval is. Als uw gebruik ervan opzettelijk en legitiem is, kunt u deze waarschuwing veilig negeren. Gebruik de Escape knop om verborgen karakters te onthullen.` -bidi_bad_description_escaped=`Dit bestand bevat onverwachte Bidirectionele Unicode-tekens. Verborgen unicode tekens worden hieronder ge-escaped. Gebruik de knop Onescape om te laten zien hoe ze renderen.` -unicode_header=`Dit bestand bevat verborgen Unicode karakters!` -unicode_description=`Dit bestand bevat verborgen Unicode-tekens die anders verwerkt kunnen worden dan hieronder het geval is. Als uw gebruik ervan opzettelijk en legitiem is, kunt u deze waarschuwing veilig negeren. Gebruik de Escape knop om verborgen karakters te onthullen.` -unicode_description_escaped=`Dit bestand bevat verborgen Unicode-tekens. Verborgen unicode tekens zijn hieronder ge-escaped. Gebruik de knop Onescape om te laten zien hoe ze renderen.` -line_unicode=`Deze regel bevat verborgen Unicode karakters` +invisible_runes_header=`Dit bestand bevat onzichtbare Unicode-karakters!` +invisible_runes_description=`Dit bestand bevat onzichtbare Unicode karakters die mogelijk anders verwerkt worden dan wat hieronder staat. Als uw gebruik opzettelijk en legitiem is, kunt u deze waarschuwing veilig negeren. Gebruik de Escape knop om verborgen karakters te onthullen.` +ambiguous_runes_header=`Dit bestand bevat dubbelzinnige Unicode karakters!` +ambiguous_runes_description=`Dit bestand bevat dubbelzinnige Unicode karakters die verward kunnen worden met andere karakters in uw huidige taal. Als je het opzettelijk en legitiem gebruikt, kun je deze waarschuwing veilig negeren. Gebruik de Escape knop om deze karakters te markeren.` +invisible_runes_line=`Deze lijn heeft onzichtbare unicode karakters` +ambiguous_runes_line=`Deze lijn heeft dubbelzinnige unicode karakters` +ambiguous_character=`%[1]c [U+%04[1]X] is verwarrend met %[2]c [U+%04[2]X]` escape_control_characters=Escape unescape_control_characters=Onescape @@ -2739,6 +2738,7 @@ monitor.queue.review=Configuratie herzien monitor.queue.review_add=Beoordeel/Voeg workers toe monitor.queue.configuration=Initiële configuratie monitor.queue.nopool.title=Geen Worker-pool +monitor.queue.flush=Spoel werker monitor.queue.pool.timeout=Time-out monitor.queue.pool.addworkers.title=Voeg workers toe monitor.queue.pool.addworkers.submit=Voeg workers toe diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index f4a4521fb9..840f69d930 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -8,7 +8,6 @@ sign_out=Wyloguj sign_up=Zarejestruj link_account=Powiąż konto register=Zarejestruj się -website=Strona version=Wersja powered_by=Wspierane przez %s page=Strona diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 765c69b8d7..b5c81702dc 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -9,7 +9,6 @@ sign_out=Sair sign_up=Cadastrar link_account=Vincular conta register=Cadastrar -website=Site version=Versão powered_by=Desenvolvido por %s page=Página @@ -1036,13 +1035,6 @@ file_view_rendered=Ver Renderizado file_view_raw=Ver original file_permalink=Link permanente file_too_large=O arquivo é muito grande para ser mostrado. -bidi_bad_header=`Este arquivo contém caracteres Unicode Bidirecionais inesperados!` -bidi_bad_description=`Este arquivo contém caracteres Unicode bidirecionais inesperados que podem ser processados de forma diferente do que aparece abaixo. Se seu caso de uso for intencional e legítimo, você pode ignorar com segurança esse aviso. Use o botão Escapar para revelar caracteres ocultos.` -bidi_bad_description_escaped=`Este arquivo contém caracteres Unicode Bidirecionais inesperados. Caracteres unicode ocultos estão escapados abaixo. Use o botão Desescapar para mostrar como eles são mostrados.` -unicode_header=`Este arquivo contém caracteres Unicode ocultos!` -unicode_description=`Este arquivo contém caracteres Unicode ocultos que podem ser processados de forma diferente do que aparece abaixo. Se seu caso de uso for intencional e legítimo, você pode ignorar com segurança esse aviso. Use o botão Escapar para revelar caracteres ocultos.` -unicode_description_escaped=`Este arquivo contém caracteres Unicode ocultos. Caracteres unicode ocultos estão escapados abaixo. Utilize o botão Desescapar para mostrar como eles são mostrados.` -line_unicode=`Esta linha possui caracteres unicode ocultos` escape_control_characters=Escapar unescape_control_characters=Desescapar diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index a0446debee..de7935e78b 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -9,7 +9,6 @@ sign_out=Terminar sessão sign_up=Fazer inscrição link_account=Vincular conta register=Inscrição -website=Sítio web version=Versão powered_by=Implementado com %s page=Página @@ -1036,13 +1035,13 @@ file_view_rendered=Ver resultado processado file_view_raw=Ver em bruto file_permalink=Ligação permanente file_too_large=O ficheiro é demasiado grande para ser apresentado. -bidi_bad_header=`Este ficheiro contém caracteres Unicode Bidireccionais inesperados!` -bidi_bad_description=`Este ficheiro contém caracteres Unicode Bidireccionais inesperados que podem ser processados de forma diferente do que aparece abaixo. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para mostrar os caracteres escondidos.` -bidi_bad_description_escaped=`Este ficheiro contém caracteres Unicode Bidireccionais inesperados. Os caracteres escondidos unicode estão revelados abaixo. Use o botão Esconder para mostrar como é que eles são apresentados.` -unicode_header=`Este ficheiro contém caracteres Unicode escondidos!` -unicode_description=`Este ficheiro contém caracteres Unicode escondidos que podem ser processados de forma diferente do que aparece abaixo. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para mostrar os caracteres escondidos.` -unicode_description_escaped=`Este ficheiro contém caracteres Unicode escondidos. Os caracteres unicode escondidos estão revelados abaixo. Use o botão Esconder para mostrar como é que eles são apresentados.` -line_unicode=`Esta linha tem caracteres unicode escondidos` +invisible_runes_header=`Este ficheiro contém caracteres Unicode invisíveis!` +invisible_runes_description=`Este ficheiro contém caracteres Unicode invisíveis que podem ser processados de forma diferente do que aparece abaixo. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para mostrar os caracteres invisíveis.` +ambiguous_runes_header=`Este ficheiro contém caracteres Unicode ambíguos!` +ambiguous_runes_description=`Este ficheiro contém caracteres Unicode ambíguos que podem ser confundidos com outros da sua configuração regional vigente. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para realçar esses caracteres.` +invisible_runes_line=`Esta linha tem caracteres unicode invisíveis` +ambiguous_runes_line=`Esta linha tem caracteres unicode ambíguos` +ambiguous_character=`%[1]c [U+%04[1]X] pode confundir-se com %[2]c [U+%04[2]X]` escape_control_characters=Revelar unescape_control_characters=Esconder @@ -2894,20 +2893,21 @@ monitor.queue.review_add=Rever/Adicionar trabalhadores monitor.queue.configuration=Configuração inicial monitor.queue.nopool.title=Sem agregado de trabalhadores monitor.queue.nopool.desc=Esta fila engloba outras filas e ela própria não tem um agregado de trabalhadores. -monitor.queue.wrapped.desc=Uma fila envolvente envolve uma fila de início lento, armazenando pedidos em fila num canal. Ela própria não tem um conjunto de tarefas. +monitor.queue.wrapped.desc=Uma fila envolvente envolve uma fila de início lento, armazenando pedidos em fila num canal. Ela própria não tem um agregado de trabalhadores. monitor.queue.persistable-channel.desc=Um canal persistente engloba duas filas, uma fila de canal que tem o seu próprio agregado de trabalhadores e uma fila de nível para pedidos persistentes de encerramentos anteriores. Ele próprio não tem um agregado de trabalhadores. +monitor.queue.flush=Trabalhador descartável monitor.queue.pool.timeout=Prazo monitor.queue.pool.addworkers.title=Adicionar trabalhadores monitor.queue.pool.addworkers.submit=Adicionar trabalhadores -monitor.queue.pool.addworkers.desc=Adicione trabalhadores a este agregado com, ou sem, prazo. Se definir um prazo, estes trabalhadores serão removidos do agregado, após o fim do prazo. +monitor.queue.pool.addworkers.desc=Adicione trabalhadores a este agregado com, ou sem, um prazo. Se definir um prazo, estes trabalhadores serão removidos do agregado, quando terminar esse prazo. monitor.queue.pool.addworkers.numberworkers.placeholder=Número de trabalhadores monitor.queue.pool.addworkers.timeout.placeholder=Insira 0 para indicar que não tem prazo -monitor.queue.pool.addworkers.mustnumbergreaterzero=O número de trabalhadores a adicionar deve ser maior que zero +monitor.queue.pool.addworkers.mustnumbergreaterzero=O número de trabalhadores a adicionar deve ser maior do que zero monitor.queue.pool.addworkers.musttimeoutduration=O prazo tem que ser uma duração no formato golang (ex.: 5m) ou 0 monitor.queue.pool.flush.title=Despejar fila -monitor.queue.pool.flush.desc=O despejo irá adicionar um trabalhador que termina assim que a fila esteja vazia ou o prazo acabe. -monitor.queue.pool.flush.submit=Adicionar trabalhador de despejo -monitor.queue.pool.flush.added=Foi adicionado um trabalhador de despejo para %[1]s +monitor.queue.pool.flush.desc='Descartável' irá adicionar um trabalhador que termina assim que a fila esteja vazia ou o prazo acabe. +monitor.queue.pool.flush.submit=Adicionar trabalhador descartável +monitor.queue.pool.flush.added=Foi adicionado um trabalhador descartável para %[1]s monitor.queue.pool.pause.title=Pausar fila monitor.queue.pool.pause.desc=Pausar uma fila impede que ela processe dados monitor.queue.pool.pause.submit=Pausar fila @@ -2916,11 +2916,11 @@ monitor.queue.pool.resume.desc=Definir esta fila para continuar o trabalho monitor.queue.pool.resume.submit=Retomar fila monitor.queue.settings.title=Configurações do agregado -monitor.queue.settings.desc=Os agregados crescem dinamicamente com um impulso em resposta à ocorrência de bloqueios na sua fila de trabalhadores. Essas mudanças não irão influenciar os grupos de trabalhadores correntes. +monitor.queue.settings.desc=Os agregados crescem dinamicamente com um aumento em resposta à ocorrência de bloqueios na sua fila de trabalhadores. Essas mudanças não irão influenciar os grupos de trabalhadores correntes. monitor.queue.settings.timeout=Prazo do impulso monitor.queue.settings.timeout.placeholder=De momento %[1]v monitor.queue.settings.timeout.error=O prazo tem que ser uma duração no formato golang (ex: 5m) ou 0 -monitor.queue.settings.numberworkers=Número de trabalhadores do impulso +monitor.queue.settings.numberworkers=Aumentar o número de trabalhadores monitor.queue.settings.numberworkers.placeholder=De momento %[1]d monitor.queue.settings.numberworkers.error=O número de trabalhadores a adicionar tem que ser maior ou igual a zero monitor.queue.settings.maxnumberworkers=Número máximo de trabalhadores @@ -2932,14 +2932,14 @@ monitor.queue.settings.blocktimeout=Prazo do bloco corrente monitor.queue.settings.blocktimeout.value=%[1]v monitor.queue.pool.none=Esta fila não tem um agregado -monitor.queue.pool.added=Foi adicionado um agregado de trabalhadores +monitor.queue.pool.added=Foi adicionado um grupo de trabalhadores monitor.queue.pool.max_changed=O número máximo de trabalhadores mudou monitor.queue.pool.workers.title=Grupos de trabalhadores operantes -monitor.queue.pool.workers.none=Não há agregados de trabalhadores. -monitor.queue.pool.cancel=Desligar agregado de trabalhadores -monitor.queue.pool.cancelling=O agregado de trabalhadores está a encerrar -monitor.queue.pool.cancel_notices=Desligar este agregado de %s trabalhadores? -monitor.queue.pool.cancel_desc=Deixar uma fila sem quaisquer agregados de trabalhadores pode fazer com que os pedidos bloqueiem indefinidamente. +monitor.queue.pool.workers.none=Não há grupos de trabalhadores. +monitor.queue.pool.cancel=Desligar o grupo de trabalhadores +monitor.queue.pool.cancelling=O grupo de trabalhadores está a encerrar +monitor.queue.pool.cancel_notices=Desligar este grupo de %s trabalhadores? +monitor.queue.pool.cancel_desc=Deixar uma fila sem quaisquer grupos de trabalhadores pode fazer com que os pedidos sejam bloqueados indefinidamente. notices.system_notice_list=Notificações do sistema notices.view_detail_header=Ver os detalhes da notificação diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 35fc93d441..a185fe0cb0 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -9,7 +9,6 @@ sign_out=Выход sign_up=Регистрация link_account=Привязать аккаунт register=Регистрация -website=Веб-сайт version=Версия powered_by=Работает на %s page=Страница diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 17fbf54467..7e7b140f26 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -8,7 +8,6 @@ sign_out=නික්මෙන්න sign_up=ලියාපදිංචිය link_account=ගිණුම සබැඳින්න register=ලියාපදිංචිය -website=වියමන අඩවිය version=අනුවාදය powered_by=%s මගින් බලගන්වා ඇත page=පිටුව diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index 3adf6ce0ab..00d1034fc6 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -8,7 +8,6 @@ sign_out=Logga ut sign_up=Registrera link_account=Länka konto register=Registrera dig -website=Webbplats version=Version powered_by=Drivs av %s page=Sida @@ -60,7 +59,7 @@ forks=Forks activities=Aktiviteter pull_requests=Pull förfrågningar -issues=Problem +issues=Ärenden milestones=Milstolpar cancel=Avbryt @@ -643,15 +642,19 @@ generate_from=Generera från repo_desc=Beskrivning repo_lang=Språk repo_gitignore_helper=Välj .gitignore-mallar. +repo_gitignore_helper_desc=Välj vilka filer som inte ska spåras från en lista med mallar för vanliga språk. Typiska artefakter som genereras av varje språk byggverktyg ingår i .gitignore som standard. issue_labels=Ärendeetiketter issue_labels_helper=Välj en grupp av ärendeetiketter. license=Licens license_helper=Välj licensfil. +license_helper_desc=En licens styr vad andra kan och inte kan göra med din kod. Inte säker på vilken som är rätt för ditt projekt? Se Välj en licens. readme=README readme_helper=Välj en mall för README-filen. +readme_helper_desc=Här kan du skriva en fullständig beskrivning för ditt projekt. auto_init=Initiera utvecklingskatalog (Lägger till .gitignore, License and README) create_repo=Skapa utvecklingskatalog default_branch=Standardgren +default_branch_helper=Den förvalda grenen är bas-gren för pull requests och kod-commits. mirror_prune=Rensa mirror_prune_desc=Ta bort förlegade fjärrföljande referenser mirror_interval_invalid=Speglingsintervallen är inte giltig. @@ -720,6 +723,7 @@ migrated_from_fake=Migrerad från %[1]s migrate.migrate=Migrera från %s migrate.migrating=Migrerar från %s ... migrate.migrating_failed=Migrering från %s misslyckades. +migrate.migrating_issues=Migrerar Ärenden mirror_from=spegling av forked_from=forkad från @@ -906,7 +910,7 @@ issues.new.add_reviewer_title=Begär granskning issues.choose.get_started=Kom igång issues.choose.blank=Standard issues.choose.blank_about=Skapa ett ärende från standardmall. -issues.no_ref=Ingen branch/Tag specificerad +issues.no_ref=Ingen Branch/Tag specificerad issues.create=Skapa Ärende issues.new_label=Ny etikett issues.new_label_placeholder=Etikettsnamn @@ -972,6 +976,7 @@ issues.commented_at=`kommenterad %s` issues.delete_comment_confirm=Är du säker på att du vill ta bort den här kommentaren? issues.context.copy_link=Kopiera länk issues.context.quote_reply=Citerat svar +issues.context.reference_issue=Referens i nytt ärende issues.context.edit=Redigera issues.context.delete=Ta bort issues.no_content=Det finns inget innehåll än. @@ -981,6 +986,7 @@ issues.reopen_issue=Återöppna issues.reopen_comment_issue=Kommentera och återöppna issues.create_comment=Kommentera issues.closed_at=`stängde ärendet %[2]s` +issues.reopened_at=`återöppnade detta ärende %[2]s` issues.commit_ref_at=`refererade till detta ärende från en incheckning %[2]s` issues.ref_issue_from=`refererade till detta ärende %[4]s %[2]s` issues.ref_pull_from=`refererade till denna pull-förfrågan %[4]s %[2]s` @@ -1038,10 +1044,13 @@ issues.lock.reason=Anledningen till att låsa issues.lock.title=Lås konversationen för detta ärende. issues.unlock.title=Lås upp konversation för ärendet. issues.comment_on_locked=Du kan inte kommentera ett låst ärende. +issues.delete.title=Radera detta ärende? +issues.delete.text=Vill du verkligen ta bort detta ärende? (Detta kommer att permanent ta bort allt innehåll. Överväg att stänga det istället om du avser att hålla det arkiverat) issues.tracker=Tidsredovisning issues.start_tracking=Starta tidsredovisning issues.start_tracking_history=`började arbeta %s` issues.tracker_auto_close=Timern stoppas automatiskt när ärendet stängs +issues.tracking_already_started=`Du har redan påbörjat tidredovisning på ett annat ärende!` issues.stop_tracking_history=`slutade arbeta %s` issues.cancel_tracking_history=”avbröt tidredovisning %s' issues.add_time=Lägg till tid manuellt @@ -1114,6 +1123,7 @@ issues.review.hide_resolved=Dölj löst issues.review.resolve_conversation=Lös konversation issues.review.resolved_by=markerade denna konversation som löst issues.assignee.error=Inte alla tilldelade har lagts till på grund av ett oväntat fel. +issues.content_history.options=Alternativ pulls.desc=Aktivera pull-förfrågningar och kodgranskning. @@ -1157,6 +1167,7 @@ pulls.invalid_merge_option=Du kan inte använda detta mergealternativet för den ; %[2]s
%[3]s
pulls.open_unmerged_pull_exists=`Du kan inte återuppliva denna pull-request då det redan finns en identisk pull-request öppen (#%d).` pulls.update_branch_success=Uppdatering av branchen lyckades +pulls.update_not_allowed=Du är inte behörig att uppdatera grenen pulls.outdated_with_base_branch=Denna branch är föråldrad gentemot bas-branchen @@ -1269,6 +1280,7 @@ activity.git_stats_exclude_merges=Exkludera merger, activity.git_stats_author_1=%d författare activity.git_stats_author_n=%d författare activity.git_stats_push_to_all_branches=till alla brancher. +activity.git_stats_on_default_branch=På %s, activity.git_stats_file_1=%d fil activity.git_stats_file_n=%d filer activity.git_stats_files_changed_1=har ändrats @@ -1413,6 +1425,7 @@ settings.event_push=Pusha settings.event_push_desc=Git push till en utvecklingskatalog. settings.event_repository=Utvecklingskatalog settings.event_repository_desc=Utvecklingskatalogen skapad eller borttagen. +settings.event_header_issue=Ärendehändelser settings.event_issues=Ärenden settings.event_issue_comment=Kommentar settings.event_issue_comment_desc=Kommentar skapad, ändrad eller borttagen. @@ -1515,6 +1528,7 @@ settings.lfs_force_unlock=Tvinga upplåsning settings.lfs_pointers.sha=Blob SHA settings.lfs_pointers.oid=OID settings.lfs_pointers.inRepo=I utvecklingskatalogen +settings.rename_branch_failed_not_exist=Kan inte byta namn på branchen %s eftersom den inte finns. diff.browse_source=Bläddra i källkod diff.parent=förälder diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index c75a4f589a..d92c46eae4 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -9,7 +9,6 @@ sign_out=Çıkış Yap sign_up=Kaydol link_account=Bağlantı hesabı register=Üye Ol -website=Web sitesi version=Sürüm powered_by=%s tarafından desteklenen page=Sayfa @@ -1036,13 +1035,13 @@ file_view_rendered=Oluşturulanları Görüntüle file_view_raw=Ham Görünüm file_permalink=Kalıcı Bağlantı file_too_large=Bu dosya görüntülemek için çok büyük. -bidi_bad_header=`Bu dosya beklenmeyen tek yönlü evrensel kodlu karakter içeriyor!` -bidi_bad_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek beklenmeyen tek yönlü evrensel kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış Karakterli düğmesine tıklayın.` -bidi_bad_description_escaped=`Bu dosya beklenmeyen tek yönlü evrensel kodlu karakter içeriyor. Gizlenmiş evrensel kodlu karakterler aşağıda kaçış karakteri olarak gösteriliyor. Nasıl temsil edildiklerini görüntülemek için Kaçış Karaktersiz düğmesine tıklayın.` -unicode_header=`Bu dosya gizli evrensel kodlu karakter içeriyor!` -unicode_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek gizli evrensel kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış Karakterli düğmesine tıklayın.` -unicode_description_escaped=`Bu dosya gizli evrensel kodlu karakter içeriyor. Gizlenmiş evrensel kodlu karakterler aşağıda kaçış karakteri olarak gösteriliyor. Nasıl temsil edildiklerini görüntülemek için Kaçış Karaktersiz düğmesine tıklayın.` -line_unicode=`Bu satırda gizli evrensel kod karakterler var` +invisible_runes_header=`Bu dosya görünmez Evrensel Kodlu karakter içeriyor!` +invisible_runes_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek görünmez Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış düğmesine tıklayın.` +ambiguous_runes_header=`Bu dosya muğlak Evrensel Kodlu karakter içeriyor!` +ambiguous_runes_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek muğlak Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Bu karakterleri göstermek için Kaçış düğmesine tıklayın.` +invisible_runes_line=`Bu satırda görünmez evrensel kodlu karakter var` +ambiguous_runes_line=`Bu satırda muğlak evrensel kodlu karakter var` +ambiguous_character=`%[1]c [U+%04[1]X], %[2]c [U+%04[2]X] ile karıştırılabilir` escape_control_characters=Kaçış Karakterli unescape_control_characters=Kaçış Karaktersiz @@ -2896,6 +2895,7 @@ monitor.queue.nopool.title=Çalışan Havuzu Yok monitor.queue.nopool.desc=Bu kuyruk diğer kuyrukları sarar ve kendisinin bir işçi havuzu yoktur. monitor.queue.wrapped.desc=Sarılmış bir kuyruk, yavaş bir başlangıç kuyruğunu sararak kanaldaki kuyruk isteklerini arabelleğe alır. Bir işçi havuzu yoktur. monitor.queue.persistable-channel.desc=Kesintisiz bir kanal, kendi alt havuzuna sahip bir kanal kuyruğu ve önceki kapanmalardan gelen kalıcı istekler için bir seviye kuyruğu olan iki kuyruğu sarar. Bir işçi havuzu yoktur. +monitor.queue.flush=Çalışanı boşalt monitor.queue.pool.timeout=Zaman aşımı monitor.queue.pool.addworkers.title=Çalışan Ekle monitor.queue.pool.addworkers.submit=Çalışan Ekle diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index a5f26fd220..bed92be4fd 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -8,7 +8,6 @@ sign_out=Вийти sign_up=Реєстрація link_account=Прив'язати обліковий запис register=Реєстрація -website=Веб-сайт version=Версія powered_by=Працює на %s page=Сторінка diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index fc9b8ffc8a..fd0a6a8b4e 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -9,7 +9,6 @@ sign_out=退出 sign_up=注册 link_account=链接账户 register=注册 -website=网站 version=当前版本 powered_by=Powered by %s page=页面 @@ -182,7 +181,7 @@ email_title=电子邮箱设置 smtp_addr=SMTP 主机地址 smtp_port=SMTP 端口 smtp_from=电子邮件发件人 -smtp_from_helper=电子邮件地址 Gitea 将使用。输入一个普通的电子邮件地址或使用 "名称" 格式。 +smtp_from_helper=请输入一个用于 Gitea 的电子邮件地址,或者使用完整格式:"名称" mailer_user=SMTP 用户名 mailer_password=SMTP 密码 register_confirm=需要发电子邮件确认注册 @@ -1036,13 +1035,13 @@ file_view_rendered=渲染模式 file_view_raw=查看原始文件 file_permalink=永久链接 file_too_large=文件过大,无法显示。 -bidi_bad_header=`此文件包含意外的双向 Unicode 字符!` -bidi_bad_description=`此文件包含意外的双向 Unicode 字符,其处理方式可能与下面显示的不同。 如果您是有意且合法地使用它们,可以放心地忽略此警告。 使用 Escape 按钮显示隐藏的字符。` -bidi_bad_description_escaped=`此文件包含意外的双向 Unicode 字符。隐藏的 Unicode 字符在下面被转义。使用 Unescape 按钮来显示它们是如何渲染的。` -unicode_header=`此文件包含隐藏的 Unicode 字符!` -unicode_description=`该文件包含隐藏的 Unicode 字符,这些字符的处理方式可能与下面显示的不同。 如果您是有意且合法地使用它们,可以放心地忽略此警告。 使用 Escape 按钮显示隐藏的字符。` -unicode_description_escaped=`此文件包含隐藏的 Unicode 字符。隐藏的 unicode 字符在下面被转义。请使用 Unescape 按钮来显示它们是如何渲染的。` -line_unicode=`这一行有隐藏的 Unicode 字符` +invisible_runes_header=`此文件包含不可见的 Unicode 字符!` +invisible_runes_description=`这个文件包含不可见的 Unicode 字符,其处理方式可能不同于下面显示的字符。 如果您是有意且正当地使用它们,您可以安全地忽略这个警告。使用 Escape 按钮来显示隐藏的字符。 +ambiguous_runes_header=`此行包含模棱两可的 Unicode 字符!` +ambiguous_runes_description=`此文件包含模棱两可的 Unicode 字符,这些字符可能会与您当前语言环境的其他字符混淆。 如果您是有意且正当地使用它们,您可以安全地忽略这个警告。使用 Escape 按钮来高亮这些字符。` +invisible_runes_line=`此行含有不可见的 unicode 字符` +ambiguous_runes_line=`此行有模棱两可的 unicode 字符` +ambiguous_character=`%[1]c [U+%04[1]X] 容易和 %[2]c [U+%04[2]X] 混淆` escape_control_characters=Escape unescape_control_characters=Unescape @@ -2462,9 +2461,9 @@ dashboard.archive_cleanup=删除旧的仓库存档 dashboard.deleted_branches_cleanup=清理已删除的分支 dashboard.update_migration_poster_id=更新迁移的发表者ID dashboard.git_gc_repos=对仓库进行垃圾回收 -dashboard.resync_all_sshkeys=使用 Gitea SSH 密钥更新'.ssh/authorized_keys' 文件。 +dashboard.resync_all_sshkeys=使用 Gitea 的 SSH 密钥更新 '.ssh/authorized_keys' 文件。 dashboard.resync_all_sshkeys.desc=(内置的 SSH 服务器不需要。) -dashboard.resync_all_sshprincipals=使用 Gitea SSH 规则更新 '.ssh/authorized_principals' 文件。 +dashboard.resync_all_sshprincipals=使用 Gitea 的 SSH 规则更新 '.ssh/authorized_principals' 文件。 dashboard.resync_all_sshprincipals.desc=(内置的 SSH 服务器不需要。) dashboard.resync_all_hooks=重新同步所有仓库的 pre-receive、update 和 post-receive 钩子 dashboard.reinit_missing_repos=重新初始化所有丢失的 Git 仓库存在的记录 @@ -2896,6 +2895,7 @@ monitor.queue.nopool.title=没有工作者池 monitor.queue.nopool.desc=此队列包装其它队列,本身没有工作者池。 monitor.queue.wrapped.desc=一个包装队列包装一个启动缓慢队列,缓存队列请求到 channel 中。它本身没有一个工作者池。 monitor.queue.persistable-channel.desc=一个 persistable-channel 队列包装2个队列,一个 channel 队列拥有自己的工作者池,一个 level 队列用于永久存储。它没有自己的工作者池。 +monitor.queue.flush=Flush worker monitor.queue.pool.timeout=超时 monitor.queue.pool.addworkers.title=新增工作者 monitor.queue.pool.addworkers.submit=新增工作者 diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index 587ee5bb23..18168c1db9 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -6,7 +6,6 @@ sign_in=登入 sign_out=登出 link_account=連結帳戶 register=註冊 -website=網站 version=版本 page=頁面 template=樣板 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 0e0dc6d59f..47f8ffcdf6 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -9,7 +9,6 @@ sign_out=登出 sign_up=註冊 link_account=連結帳戶 register=註冊 -website=網站 version=版本 powered_by=技術提供: %s page=頁面 @@ -1032,13 +1031,6 @@ file_view_rendered=檢視渲染圖 file_view_raw=查看原始文件 file_permalink=永久連結 file_too_large=檔案太大,無法顯示。 -bidi_bad_header=`此檔案含有未預期的 Bidirectional Unicode 字元!` -bidi_bad_description=`此檔案含有未預期的 Bidirectional Unicode 字元,這些字元的處理方式可能和下面呈現的不同。若您是有意且合理的使用,您可以放心地忽略此警告。使用 Escape 按鈕顯示隱藏的字元。` -bidi_bad_description_escaped=`此檔案含有未預期的 Bidirectional Unicode 字元。隱藏的 Unicode 字元已在下面被跳脫 (Escaped)。使用 Unescape 按鈕以顯示它們呈現的樣子。` -unicode_header=`此檔案含有隱藏的 Unicode 字元!` -unicode_description=`此檔案含有隱藏的 Unicode 字元,這些字元的處理方式可能和下面呈現的不同。若您是有意且合理的使用,您可以放心地忽略此警告。使用 Escape 按鈕顯示隱藏的字元。` -unicode_description_escaped=`此檔案含有隱藏的 Unicode 字元。隱藏的 Unicode 字元已在下面被跳脫 (Escaped)。使用 Unescape 按鈕以顯示它們呈現的樣子。` -line_unicode=`這一行有隱藏的 Unicode 字元` escape_control_characters=Escape unescape_control_characters=Unescape diff --git a/public/img/svg/gitea-exclamation.svg b/public/img/svg/gitea-exclamation.svg index 22176010dc..d6c86136b3 100644 --- a/public/img/svg/gitea-exclamation.svg +++ b/public/img/svg/gitea-exclamation.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index f8c37303d6..db37bac57e 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -262,7 +262,7 @@ func EditTeam(ctx *context.APIContext) { } if form.CanCreateOrgRepo != nil { - team.CanCreateOrgRepo = *form.CanCreateOrgRepo + team.CanCreateOrgRepo = team.IsOwnerTeam() || *form.CanCreateOrgRepo } if len(form.Name) > 0 { diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index a3a5904925..d423bddbbd 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -427,9 +427,9 @@ func ListPageRevisions(ctx *context.APIContext) { } // get Commit Count - commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page) + commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page) if err != nil { - ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRangeNoFollow", err) + ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) return } diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index f0dc595ad5..ba008f587c 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -15,7 +15,6 @@ import ( "code.gitea.io/gitea/modules/json" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/routers/utils" webhook_service "code.gitea.io/gitea/services/webhook" ) @@ -141,14 +140,15 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID ctx.Error(http.StatusUnprocessableEntity, "", "Missing config option: channel") return nil, false } + channel = strings.TrimSpace(channel) - if !utils.IsValidSlackChannel(channel) { + if !webhook_service.IsValidSlackChannel(channel) { ctx.Error(http.StatusBadRequest, "", "Invalid slack channel name") return nil, false } meta, err := json.Marshal(&webhook_service.SlackMeta{ - Channel: strings.TrimSpace(channel), + Channel: channel, Username: form.Config["username"], IconURL: form.Config["icon_url"], Color: form.Config["color"], diff --git a/routers/private/mail.go b/routers/private/mail.go index 966a838168..e858992aee 100644 --- a/routers/private/mail.go +++ b/routers/private/mail.go @@ -9,6 +9,7 @@ import ( "net/http" "strconv" + "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" @@ -59,7 +60,7 @@ func SendEmail(ctx *context.PrivateContext) { } } } else { - err := user_model.IterateUser(func(user *user_model.User) error { + err := db.IterateObjects(ctx, func(user *user_model.User) error { if len(user.Email) > 0 && user.IsActive { emails = append(emails, user.Email) } diff --git a/routers/utils/utils.go b/routers/utils/utils.go index f15bc1e62e..66eaa1d9ce 100644 --- a/routers/utils/utils.go +++ b/routers/utils/utils.go @@ -20,25 +20,6 @@ func RemoveUsernameParameterSuffix(name string) string { return name } -// IsValidSlackChannel validates a channel name conforms to what slack expects. -// It makes sure a channel name cannot be empty and invalid ( only an # ) -func IsValidSlackChannel(channelName string) bool { - switch len(strings.TrimSpace(channelName)) { - case 0: - return false - case 1: - // Keep default behaviour where a channel name is still - // valid without an # - // But if it contains only an #, it should be regarded as - // invalid - if channelName[0] == '#' { - return false - } - } - - return true -} - // SanitizeFlashErrorString will sanitize a flash error string func SanitizeFlashErrorString(x string) string { return strings.ReplaceAll(html.EscapeString(x), "\n", "
") diff --git a/routers/utils/utils_test.go b/routers/utils/utils_test.go index f49ed77b6f..42cf948e30 100644 --- a/routers/utils/utils_test.go +++ b/routers/utils/utils_test.go @@ -18,23 +18,6 @@ func TestRemoveUsernameParameterSuffix(t *testing.T) { assert.Equal(t, "", RemoveUsernameParameterSuffix("")) } -func TestIsValidSlackChannel(t *testing.T) { - tt := []struct { - channelName string - expected bool - }{ - {"gitea", true}, - {" ", false}, - {"#", false}, - {"gitea ", true}, - {" gitea", true}, - } - - for _, v := range tt { - assert.Equal(t, v.expected, IsValidSlackChannel(v.channelName)) - } -} - func TestIsExternalURL(t *testing.T) { setting.AppURL = "https://try.gitea.io/" type test struct { diff --git a/routers/web/admin/admin.go b/routers/web/admin/admin.go index ebe5066d2c..c773034c53 100644 --- a/routers/web/admin/admin.go +++ b/routers/web/admin/admin.go @@ -257,6 +257,7 @@ func Config(ctx *context.Context) { ctx.Data["ScriptType"] = setting.ScriptType ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser ctx.Data["ReverseProxyAuthEmail"] = setting.ReverseProxyAuthEmail + ctx.Data["ReverseProxyAuthFullName"] = setting.ReverseProxyAuthFullName ctx.Data["SSH"] = setting.SSH ctx.Data["LFS"] = setting.LFS diff --git a/routers/web/admin/users_test.go b/routers/web/admin/users_test.go index e63367ccf2..da67cd5cb4 100644 --- a/routers/web/admin/users_test.go +++ b/routers/web/admin/users_test.go @@ -25,7 +25,7 @@ func TestNewUserPost_MustChangePassword(t *testing.T) { u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ IsAdmin: true, ID: 2, - }).(*user_model.User) + }) ctx.Doer = u @@ -62,7 +62,7 @@ func TestNewUserPost_MustChangePasswordFalse(t *testing.T) { u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ IsAdmin: true, ID: 2, - }).(*user_model.User) + }) ctx.Doer = u @@ -99,7 +99,7 @@ func TestNewUserPost_InvalidEmail(t *testing.T) { u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ IsAdmin: true, ID: 2, - }).(*user_model.User) + }) ctx.Doer = u @@ -129,7 +129,7 @@ func TestNewUserPost_VisibilityDefaultPublic(t *testing.T) { u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ IsAdmin: true, ID: 2, - }).(*user_model.User) + }) ctx.Doer = u @@ -167,7 +167,7 @@ func TestNewUserPost_VisibilityPrivate(t *testing.T) { u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ IsAdmin: true, ID: 2, - }).(*user_model.User) + }) ctx.Doer = u diff --git a/routers/web/auth/oauth_test.go b/routers/web/auth/oauth_test.go index 57f2477dba..48400846d2 100644 --- a/routers/web/auth/oauth_test.go +++ b/routers/web/auth/oauth_test.go @@ -60,7 +60,7 @@ func TestNewAccessTokenResponse_OIDCToken(t *testing.T) { assert.Empty(t, oidcToken.Email) assert.False(t, oidcToken.EmailVerified) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) grants, err = auth.GetOAuth2GrantsByUserID(db.DefaultContext, user.ID) assert.NoError(t, err) assert.Len(t, grants, 1) diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 284fb096f3..9ee66a1a3e 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -416,7 +416,11 @@ func EditTeamPost(ctx *context.Context) { isIncludeAllChanged = true t.IncludesAllRepositories = includesAllRepositories } + t.CanCreateOrgRepo = form.CanCreateOrgRepo + } else { + t.CanCreateOrgRepo = true } + t.Description = form.Description if t.AccessMode < perm.AccessModeAdmin { units := make([]organization.TeamUnit, 0, len(unitPerms)) @@ -433,7 +437,6 @@ func EditTeamPost(ctx *context.Context) { return } } - t.CanCreateOrgRepo = form.CanCreateOrgRepo if ctx.HasError() { ctx.HTML(http.StatusOK, tplTeamNew) diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index 06c43aec19..c53a53b471 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -40,7 +40,7 @@ type blameRow struct { CommitMessage string CommitSince gotemplate.HTML Code gotemplate.HTML - EscapeStatus charset.EscapeStatus + EscapeStatus *charset.EscapeStatus } // RefBlame render blame page @@ -235,7 +235,7 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m } lines := make([]string, 0) rows := make([]*blameRow, 0) - escapeStatus := charset.EscapeStatus{} + escapeStatus := &charset.EscapeStatus{} i := 0 commitCnt := 0 @@ -280,7 +280,7 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m fileName := fmt.Sprintf("%v", ctx.Data["FileName"]) line = highlight.Code(fileName, language, line) - br.EscapeStatus, line = charset.EscapeControlString(line) + br.EscapeStatus, line = charset.EscapeControlHTML(line, ctx.Locale) br.Code = gotemplate.HTML(line) rows = append(rows, br) escapeStatus = escapeStatus.Or(br.EscapeStatus) diff --git a/routers/web/repo/lfs.go b/routers/web/repo/lfs.go index 0e446f2de0..baec48bfea 100644 --- a/routers/web/repo/lfs.go +++ b/routers/web/repo/lfs.go @@ -309,7 +309,7 @@ func LFSFileGet(ctx *context.Context) { // Building code view blocks with line number on server side. escapedContent := &bytes.Buffer{} - ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, escapedContent) + ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, escapedContent, ctx.Locale) var output bytes.Buffer lines := strings.Split(escapedContent.String(), "\n") diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 6a9c6b9bba..72ffda7e01 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -328,35 +328,31 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin if markupType := markup.Type(readmeFile.name); markupType != "" { ctx.Data["IsMarkup"] = true ctx.Data["MarkupType"] = markupType - var result strings.Builder - err := markup.Render(&markup.RenderContext{ + + ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{ Ctx: ctx, RelativePath: path.Join(ctx.Repo.TreePath, readmeFile.name), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path). URLPrefix: readmeTreelink, Metas: ctx.Repo.Repository.ComposeDocumentMetas(), GitRepo: ctx.Repo.GitRepo, - }, rd, &result) + }, rd) if err != nil { - log.Error("Render failed: %v then fallback", err) + log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.name, ctx.Repo.Repository, err) buf := &bytes.Buffer{} - ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf) + ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf, ctx.Locale) ctx.Data["FileContent"] = strings.ReplaceAll( gotemplate.HTMLEscapeString(buf.String()), "\n", `
`, ) - } else { - ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String()) } } else { ctx.Data["IsRenderedHTML"] = true buf := &bytes.Buffer{} - ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, buf) + ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, &charset.BreakWriter{Writer: buf}, ctx.Locale, charset.RuneNBSP) if err != nil { log.Error("Read failed: %v", err) } - ctx.Data["FileContent"] = strings.ReplaceAll( - gotemplate.HTMLEscapeString(buf.String()), "\n", `
`, - ) + ctx.Data["FileContent"] = buf.String() } } @@ -498,32 +494,30 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st if markupType != "" && !shouldRenderSource { ctx.Data["IsMarkup"] = true ctx.Data["MarkupType"] = markupType - var result strings.Builder if !detected { markupType = "" } metas := ctx.Repo.Repository.ComposeDocumentMetas() metas["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL() - err := markup.Render(&markup.RenderContext{ + ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{ Ctx: ctx, Type: markupType, RelativePath: ctx.Repo.TreePath, URLPrefix: path.Dir(treeLink), Metas: metas, GitRepo: ctx.Repo.GitRepo, - }, rd, &result) + }, rd) if err != nil { ctx.ServerError("Render", err) return } // to prevent iframe load third-party url ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'") - ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String()) } else if readmeExist && !shouldRenderSource { buf := &bytes.Buffer{} ctx.Data["IsRenderedHTML"] = true - ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf) + ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf, ctx.Locale) ctx.Data["FileContent"] = strings.ReplaceAll( gotemplate.HTMLEscapeString(buf.String()), "\n", `
`, @@ -570,12 +564,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st log.Error("highlight.File failed, fallback to plain text: %v", err) fileContent = highlight.PlainText(buf) } - status, _ := charset.EscapeControlReader(bytes.NewReader(buf), io.Discard) - ctx.Data["EscapeStatus"] = status - statuses := make([]charset.EscapeStatus, len(fileContent)) + status := &charset.EscapeStatus{} + statuses := make([]*charset.EscapeStatus, len(fileContent)) for i, line := range fileContent { - statuses[i], fileContent[i] = charset.EscapeControlString(line) + statuses[i], fileContent[i] = charset.EscapeControlHTML(line, ctx.Locale) + status = status.Or(statuses[i]) } + ctx.Data["EscapeStatus"] = status ctx.Data["FileContent"] = fileContent ctx.Data["LineEscapeStatus"] = statuses } @@ -613,20 +608,17 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st rd := io.MultiReader(bytes.NewReader(buf), dataRc) ctx.Data["IsMarkup"] = true ctx.Data["MarkupType"] = markupType - var result strings.Builder - err := markup.Render(&markup.RenderContext{ + ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{ Ctx: ctx, RelativePath: ctx.Repo.TreePath, URLPrefix: path.Dir(treeLink), Metas: ctx.Repo.Repository.ComposeDocumentMetas(), GitRepo: ctx.Repo.GitRepo, - }, rd, &result) + }, rd) if err != nil { ctx.ServerError("Render", err) return } - - ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String()) } } @@ -645,6 +637,23 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st } } +func markupRender(ctx *context.Context, renderCtx *markup.RenderContext, input io.Reader) (escaped *charset.EscapeStatus, output string, err error) { + markupRd, markupWr := io.Pipe() + defer markupWr.Close() + done := make(chan struct{}) + go func() { + sb := &strings.Builder{} + // We allow NBSP here this is rendered + escaped, _ = charset.EscapeControlReader(markupRd, sb, ctx.Locale, charset.RuneNBSP) + output = sb.String() + close(done) + }() + err = markup.Render(renderCtx, input, markupWr) + _ = markupWr.CloseWithError(err) + <-done + return escaped, output, err +} + func safeURL(address string) string { u, err := url.Parse(address) if err != nil { diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go index a9b14ee21f..d4419a1e10 100644 --- a/routers/web/repo/webhook.go +++ b/routers/web/repo/webhook.go @@ -185,14 +185,22 @@ func ParseHookEvent(form forms.WebhookForm) *webhook.HookEvent { } } -// GiteaHooksNewPost response for creating Gitea webhook -func GiteaHooksNewPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewWebhookForm) +type webhookCreationParams struct { + URL string + ContentType webhook.HookContentType + Secret string + HTTPMethod string + WebhookForm forms.WebhookForm + Type string + Meta interface{} +} + +func createWebhook(ctx *context.Context, params webhookCreationParams) { ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.GITEA + ctx.Data["HookType"] = params.Type orCtx, err := getOrgRepoCtx(ctx) if err != nil { @@ -206,20 +214,25 @@ func GiteaHooksNewPost(ctx *context.Context) { return } - contentType := webhook.ContentTypeJSON - if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm { - contentType = webhook.ContentTypeForm + var meta []byte + if params.Meta != nil { + meta, err = json.Marshal(params.Meta) + if err != nil { + ctx.ServerError("Marshal", err) + return + } } w := &webhook.Webhook{ RepoID: orCtx.RepoID, - URL: form.PayloadURL, - HTTPMethod: form.HTTPMethod, - ContentType: contentType, - Secret: form.Secret, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.GITEA, + URL: params.URL, + HTTPMethod: params.HTTPMethod, + ContentType: params.ContentType, + Secret: params.Secret, + HookEvent: ParseHookEvent(params.WebhookForm), + IsActive: params.WebhookForm.Active, + Type: params.Type, + Meta: string(meta), OrgID: orCtx.OrgID, IsSystemWebhook: orCtx.IsSystemWebhook, } @@ -235,503 +248,175 @@ func GiteaHooksNewPost(ctx *context.Context) { ctx.Redirect(orCtx.Link) } +// GiteaHooksNewPost response for creating Gitea webhook +func GiteaHooksNewPost(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.NewWebhookForm) + + contentType := webhook.ContentTypeJSON + if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm { + contentType = webhook.ContentTypeForm + } + + createWebhook(ctx, webhookCreationParams{ + URL: form.PayloadURL, + ContentType: contentType, + Secret: form.Secret, + HTTPMethod: form.HTTPMethod, + WebhookForm: form.WebhookForm, + Type: webhook.GITEA, + }) +} + // GogsHooksNewPost response for creating webhook func GogsHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewGogshookForm) - newGogsWebhookPost(ctx, *form, webhook.GOGS) -} - -// newGogsWebhookPost response for creating gogs hook -func newGogsWebhookPost(ctx *context.Context, form forms.NewGogshookForm, kind webhook.HookType) { - ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.GOGS - - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - ctx.Data["BaseLink"] = orCtx.LinkNew - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } contentType := webhook.ContentTypeJSON if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm { contentType = webhook.ContentTypeForm } - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: form.PayloadURL, - ContentType: contentType, - Secret: form.Secret, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: kind, - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) + createWebhook(ctx, webhookCreationParams{ + URL: form.PayloadURL, + ContentType: contentType, + Secret: form.Secret, + WebhookForm: form.WebhookForm, + Type: webhook.GOGS, + }) } // DiscordHooksNewPost response for creating discord hook func DiscordHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewDiscordHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.DISCORD - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.DiscordMeta{ - Username: form.Username, - IconURL: form.IconURL, + createWebhook(ctx, webhookCreationParams{ + URL: form.PayloadURL, + ContentType: webhook.ContentTypeJSON, + WebhookForm: form.WebhookForm, + Type: webhook.DISCORD, + Meta: &webhook_service.DiscordMeta{ + Username: form.Username, + IconURL: form.IconURL, + }, }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.DISCORD, - Meta: string(meta), - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) } // DingtalkHooksNewPost response for creating dingtalk hook func DingtalkHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewDingtalkHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.DINGTALK - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.DINGTALK, - Meta: "", - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) + createWebhook(ctx, webhookCreationParams{ + URL: form.PayloadURL, + ContentType: webhook.ContentTypeJSON, + WebhookForm: form.WebhookForm, + Type: webhook.DINGTALK, + }) } // TelegramHooksNewPost response for creating telegram hook func TelegramHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewTelegramHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.TELEGRAM - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.TelegramMeta{ - BotToken: form.BotToken, - ChatID: form.ChatID, + createWebhook(ctx, webhookCreationParams{ + URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)), + ContentType: webhook.ContentTypeJSON, + WebhookForm: form.WebhookForm, + Type: webhook.TELEGRAM, + Meta: &webhook_service.TelegramMeta{ + BotToken: form.BotToken, + ChatID: form.ChatID, + }, }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)), - ContentType: webhook.ContentTypeJSON, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.TELEGRAM, - Meta: string(meta), - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) } // MatrixHooksNewPost response for creating a Matrix hook func MatrixHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewMatrixHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.MATRIX - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.MatrixMeta{ - HomeserverURL: form.HomeserverURL, - Room: form.RoomID, - AccessToken: form.AccessToken, - MessageType: form.MessageType, + createWebhook(ctx, webhookCreationParams{ + URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)), + ContentType: webhook.ContentTypeJSON, + HTTPMethod: http.MethodPut, + WebhookForm: form.WebhookForm, + Type: webhook.MATRIX, + Meta: &webhook_service.MatrixMeta{ + HomeserverURL: form.HomeserverURL, + Room: form.RoomID, + AccessToken: form.AccessToken, + MessageType: form.MessageType, + }, }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)), - ContentType: webhook.ContentTypeJSON, - HTTPMethod: "PUT", - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.MATRIX, - Meta: string(meta), - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) } // MSTeamsHooksNewPost response for creating MS Teams hook func MSTeamsHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewMSTeamsHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.MSTEAMS - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.MSTEAMS, - Meta: "", - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) + createWebhook(ctx, webhookCreationParams{ + URL: form.PayloadURL, + ContentType: webhook.ContentTypeJSON, + WebhookForm: form.WebhookForm, + Type: webhook.MSTEAMS, + }) } // SlackHooksNewPost response for creating slack hook func SlackHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewSlackHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.SLACK - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - if form.HasInvalidChannel() { - ctx.Flash.Error(ctx.Tr("repo.settings.add_webhook.invalid_channel_name")) - ctx.Redirect(orCtx.LinkNew + "/slack/new") - return - } - - meta, err := json.Marshal(&webhook_service.SlackMeta{ - Channel: strings.TrimSpace(form.Channel), - Username: form.Username, - IconURL: form.IconURL, - Color: form.Color, + createWebhook(ctx, webhookCreationParams{ + URL: form.PayloadURL, + ContentType: webhook.ContentTypeJSON, + WebhookForm: form.WebhookForm, + Type: webhook.SLACK, + Meta: &webhook_service.SlackMeta{ + Channel: strings.TrimSpace(form.Channel), + Username: form.Username, + IconURL: form.IconURL, + Color: form.Color, + }, }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.SLACK, - Meta: string(meta), - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) } // FeishuHooksNewPost response for creating feishu hook func FeishuHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewFeishuHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.FEISHU - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.FEISHU, - Meta: "", - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) + createWebhook(ctx, webhookCreationParams{ + URL: form.PayloadURL, + ContentType: webhook.ContentTypeJSON, + WebhookForm: form.WebhookForm, + Type: webhook.FEISHU, + }) } // WechatworkHooksNewPost response for creating wechatwork hook func WechatworkHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.WECHATWORK - - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.WECHATWORK, - Meta: "", - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) + createWebhook(ctx, webhookCreationParams{ + URL: form.PayloadURL, + ContentType: webhook.ContentTypeJSON, + WebhookForm: form.WebhookForm, + Type: webhook.WECHATWORK, + }) } // PackagistHooksNewPost response for creating packagist hook func PackagistHooksNewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewPackagistHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksNew"] = true - ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} - ctx.Data["HookType"] = webhook.PACKAGIST - orCtx, err := getOrgRepoCtx(ctx) - if err != nil { - ctx.ServerError("getOrgRepoCtx", err) - return - } - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.PackagistMeta{ - Username: form.Username, - APIToken: form.APIToken, - PackageURL: form.PackageURL, + createWebhook(ctx, webhookCreationParams{ + URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)), + ContentType: webhook.ContentTypeJSON, + WebhookForm: form.WebhookForm, + Type: webhook.PACKAGIST, + Meta: &webhook_service.PackagistMeta{ + Username: form.Username, + APIToken: form.APIToken, + PackageURL: form.PackageURL, + }, }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - - w := &webhook.Webhook{ - RepoID: orCtx.RepoID, - URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)), - ContentType: webhook.ContentTypeJSON, - HookEvent: ParseHookEvent(form.WebhookForm), - IsActive: form.Active, - Type: webhook.PACKAGIST, - Meta: string(meta), - OrgID: orCtx.OrgID, - IsSystemWebhook: orCtx.IsSystemWebhook, - } - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.ServerError("CreateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) - ctx.Redirect(orCtx.Link) } func checkWebhook(ctx *context.Context) (*orgRepoCtx, *webhook.Webhook) { @@ -894,12 +579,6 @@ func SlackHooksEditPost(ctx *context.Context) { return } - if form.HasInvalidChannel() { - ctx.Flash.Error(ctx.Tr("repo.settings.add_webhook.invalid_channel_name")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) - return - } - meta, err := json.Marshal(&webhook_service.SlackMeta{ Channel: strings.TrimSpace(form.Channel), Username: form.Username, diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index e4134028aa..4cd5856ea6 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -239,9 +239,28 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { Metas: ctx.Repo.Repository.ComposeDocumentMetas(), IsWiki: true, } + buf := &strings.Builder{} - var buf strings.Builder - if err := markdown.Render(rctx, bytes.NewReader(data), &buf); err != nil { + renderFn := func(data []byte) (escaped *charset.EscapeStatus, output string, err error) { + markupRd, markupWr := io.Pipe() + defer markupWr.Close() + done := make(chan struct{}) + go func() { + // We allow NBSP here this is rendered + escaped, _ = charset.EscapeControlReader(markupRd, buf, ctx.Locale, charset.RuneNBSP) + output = buf.String() + buf.Reset() + close(done) + }() + + err = markdown.Render(rctx, bytes.NewReader(data), markupWr) + _ = markupWr.CloseWithError(err) + <-done + return escaped, output, err + } + + ctx.Data["EscapeStatus"], ctx.Data["content"], err = renderFn(data) + if err != nil { if wikiRepo != nil { wikiRepo.Close() } @@ -249,11 +268,10 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { return nil, nil } - ctx.Data["EscapeStatus"], ctx.Data["content"] = charset.EscapeControlString(buf.String()) - if !isSideBar { buf.Reset() - if err := markdown.Render(rctx, bytes.NewReader(sidebarContent), &buf); err != nil { + ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"], err = renderFn(sidebarContent) + if err != nil { if wikiRepo != nil { wikiRepo.Close() } @@ -261,14 +279,14 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { return nil, nil } ctx.Data["sidebarPresent"] = sidebarContent != nil - ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"] = charset.EscapeControlString(buf.String()) } else { ctx.Data["sidebarPresent"] = false } if !isFooter { buf.Reset() - if err := markdown.Render(rctx, bytes.NewReader(footerContent), &buf); err != nil { + ctx.Data["footerEscapeStatus"], ctx.Data["footerContent"], err = renderFn(footerContent) + if err != nil { if wikiRepo != nil { wikiRepo.Close() } @@ -276,7 +294,6 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { return nil, nil } ctx.Data["footerPresent"] = footerContent != nil - ctx.Data["footerEscapeStatus"], ctx.Data["footerContent"] = charset.EscapeControlString(buf.String()) } else { ctx.Data["footerPresent"] = false } @@ -343,12 +360,12 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) } // get Commit Count - commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page) + commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page) if err != nil { if wikiRepo != nil { wikiRepo.Close() } - ctx.ServerError("CommitsByFileAndRangeNoFollow", err) + ctx.ServerError("CommitsByFileAndRange", err) return nil, nil } ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commitsHistory, ctx.Repo.Repository) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index f338c525b4..f28a684054 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -100,39 +100,6 @@ func Dashboard(ctx *context.Context) { } var err error - var mirrors []*repo_model.Repository - if ctxUser.IsOrganization() { - var env organization.AccessibleReposEnvironment - if ctx.Org.Team != nil { - env = organization.OrgFromUser(ctxUser).AccessibleTeamReposEnv(ctx.Org.Team) - } else { - env, err = organization.AccessibleReposEnv(ctx, organization.OrgFromUser(ctxUser), ctx.Doer.ID) - if err != nil { - ctx.ServerError("AccessibleReposEnv", err) - return - } - } - mirrors, err = env.MirrorRepos() - if err != nil { - ctx.ServerError("env.MirrorRepos", err) - return - } - } else { - mirrors, err = repo_model.GetUserMirrorRepositories(ctxUser.ID) - if err != nil { - ctx.ServerError("GetUserMirrorRepositories", err) - return - } - } - ctx.Data["MaxShowRepoNum"] = setting.UI.User.RepoPagingNum - - if err := repo_model.MirrorRepositoryList(mirrors).LoadAttributes(); err != nil { - ctx.ServerError("MirrorRepositoryList.LoadAttributes", err) - return - } - ctx.Data["MirrorCount"] = len(mirrors) - ctx.Data["Mirrors"] = mirrors - ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{ RequestedUser: ctxUser, RequestedTeam: ctx.Org.Team, @@ -607,10 +574,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { var shownIssues int if !isShowClosed { shownIssues = int(issueStats.OpenCount) - ctx.Data["TotalIssueCount"] = shownIssues } else { shownIssues = int(issueStats.ClosedCount) - ctx.Data["TotalIssueCount"] = shownIssues } if len(repoIDs) != 0 { shownIssues = 0 @@ -618,6 +583,13 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { shownIssues += int(issueCountByRepo[repoID]) } } + + var allIssueCount int64 + for _, issueCount := range issueCountByRepo { + allIssueCount += issueCount + } + ctx.Data["TotalIssueCount"] = allIssueCount + if len(repoIDs) == 1 { repo := showReposMap[repoIDs[0]] if repo != nil { diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 6f23d239e2..c804be3c5f 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -105,6 +105,13 @@ func Profile(ctx *context.Context) { ctx.Data["Orgs"] = orgs ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer) + badges, _, err := user_model.GetUserBadges(ctx, ctx.ContextUser) + if err != nil { + ctx.ServerError("GetUserBadges", err) + return + } + ctx.Data["Badges"] = badges + tab := ctx.FormString("tab") ctx.Data["TabName"] = tab diff --git a/services/asymkey/ssh_key_test.go b/services/asymkey/ssh_key_test.go index 182371271a..9bc23a719c 100644 --- a/services/asymkey/ssh_key_test.go +++ b/services/asymkey/ssh_key_test.go @@ -18,7 +18,7 @@ import ( func TestAddLdapSSHPublicKeys(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) s := &auth.Source{ID: 1} testCases := []struct { diff --git a/services/attachment/attachment_test.go b/services/attachment/attachment_test.go index 889151d8f3..561792db2f 100644 --- a/services/attachment/attachment_test.go +++ b/services/attachment/attachment_test.go @@ -26,7 +26,7 @@ func TestMain(m *testing.M) { func TestUploadAttachment(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) fPath := "./attachment_test.go" f, err := os.Open(fPath) diff --git a/services/auth/reverseproxy.go b/services/auth/reverseproxy.go index 05d6af78f1..d9d1b63e8f 100644 --- a/services/auth/reverseproxy.go +++ b/services/auth/reverseproxy.go @@ -105,9 +105,15 @@ func (r *ReverseProxy) newUser(req *http.Request) *user_model.User { } } + var fullname string + if setting.Service.EnableReverseProxyFullName { + fullname = req.Header.Get(setting.ReverseProxyAuthFullName) + } + user := &user_model.User{ - Name: username, - Email: email, + Name: username, + Email: email, + FullName: fullname, } overwriteDefault := user_model.CreateUserOverwriteOptions{ diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index afecc205f3..7a4a2123eb 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -17,7 +17,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web/middleware" - "code.gitea.io/gitea/routers/utils" + "code.gitea.io/gitea/services/webhook" "gitea.com/go-chi/binding" ) @@ -305,14 +305,16 @@ type NewSlackHookForm struct { // Validate validates the fields func (f *NewSlackHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { ctx := context.GetContext(req) + if !webhook.IsValidSlackChannel(strings.TrimSpace(f.Channel)) { + errs = append(errs, binding.Error{ + FieldNames: []string{"Channel"}, + Classification: "", + Message: ctx.Tr("repo.settings.add_webhook.invalid_channel_name"), + }) + } return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// HasInvalidChannel validates the channel name is in the right format -func (f NewSlackHookForm) HasInvalidChannel() bool { - return !utils.IsValidSlackChannel(f.Channel) -} - // NewDiscordHookForm form for creating discord hook type NewDiscordHookForm struct { PayloadURL string `binding:"Required;ValidUrl"` diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 6dd237bbc8..9844992f5b 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -32,6 +32,7 @@ import ( "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/translation" "github.com/sergi/go-diff/diffmatchpatch" stdcharset "golang.org/x/net/html/charset" @@ -169,11 +170,11 @@ func getDiffLineSectionInfo(treePath, line string, lastLeftIdx, lastRightIdx int } // escape a line's content or return
needed for copy/paste purposes -func getLineContent(content string) DiffInline { +func getLineContent(content string, locale translation.Locale) DiffInline { if len(content) > 0 { - return DiffInlineWithUnicodeEscape(template.HTML(html.EscapeString(content))) + return DiffInlineWithUnicodeEscape(template.HTML(html.EscapeString(content)), locale) } - return DiffInline{Content: "
"} + return DiffInline{EscapeStatus: &charset.EscapeStatus{}, Content: "
"} } // DiffSection represents a section of a DiffFile. @@ -267,26 +268,26 @@ func init() { // DiffInline is a struct that has a content and escape status type DiffInline struct { - EscapeStatus charset.EscapeStatus + EscapeStatus *charset.EscapeStatus Content template.HTML } // DiffInlineWithUnicodeEscape makes a DiffInline with hidden unicode characters escaped -func DiffInlineWithUnicodeEscape(s template.HTML) DiffInline { - status, content := charset.EscapeControlString(string(s)) +func DiffInlineWithUnicodeEscape(s template.HTML, locale translation.Locale) DiffInline { + status, content := charset.EscapeControlHTML(string(s), locale) return DiffInline{EscapeStatus: status, Content: template.HTML(content)} } // DiffInlineWithHighlightCode makes a DiffInline with code highlight and hidden unicode characters escaped -func DiffInlineWithHighlightCode(fileName, language, code string) DiffInline { - status, content := charset.EscapeControlString(highlight.Code(fileName, language, code)) +func DiffInlineWithHighlightCode(fileName, language, code string, locale translation.Locale) DiffInline { + status, content := charset.EscapeControlHTML(highlight.Code(fileName, language, code), locale) return DiffInline{EscapeStatus: status, Content: template.HTML(content)} } // GetComputedInlineDiffFor computes inline diff for the given line. -func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) DiffInline { +func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine, locale translation.Locale) DiffInline { if setting.Git.DisableDiffHighlight { - return getLineContent(diffLine.Content[1:]) + return getLineContent(diffLine.Content[1:], locale) } var ( @@ -303,26 +304,26 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) Dif // try to find equivalent diff line. ignore, otherwise switch diffLine.Type { case DiffLineSection: - return getLineContent(diffLine.Content[1:]) + return getLineContent(diffLine.Content[1:], locale) case DiffLineAdd: compareDiffLine = diffSection.GetLine(DiffLineDel, diffLine.RightIdx) if compareDiffLine == nil { - return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:]) + return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:], locale) } diff1 = compareDiffLine.Content diff2 = diffLine.Content case DiffLineDel: compareDiffLine = diffSection.GetLine(DiffLineAdd, diffLine.LeftIdx) if compareDiffLine == nil { - return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:]) + return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:], locale) } diff1 = diffLine.Content diff2 = compareDiffLine.Content default: if strings.IndexByte(" +-", diffLine.Content[0]) > -1 { - return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:]) + return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:], locale) } - return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content) + return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content, locale) } hcd := newHighlightCodeDiff() @@ -330,7 +331,7 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) Dif // it seems that Gitea doesn't need the line wrapper of Chroma, so do not add them back // if the line wrappers are still needed in the future, it can be added back by "diffToHTML(hcd.lineWrapperTags. ...)" diffHTML := diffToHTML(nil, diffRecord, diffLine.Type) - return DiffInlineWithUnicodeEscape(template.HTML(diffHTML)) + return DiffInlineWithUnicodeEscape(template.HTML(diffHTML), locale) } // DiffFile represents a file diff. diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index e88d831759..dfdd4df9c4 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -601,8 +601,8 @@ func setupDefaultDiff() *Diff { func TestDiff_LoadComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) diff := setupDefaultDiff() assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user)) assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 2) diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go index ce3f913627..f9ad0302ff 100644 --- a/services/issue/commit_test.go +++ b/services/issue/commit_test.go @@ -47,8 +47,8 @@ func TestUpdateIssuesCommit(t *testing.T) { }, } - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo.Owner = user commentBean := &issues_model.Comment{ @@ -77,7 +77,7 @@ func TestUpdateIssuesCommit(t *testing.T) { Message: "close #1", }, } - repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) commentBean = &issues_model.Comment{ Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", @@ -103,7 +103,7 @@ func TestUpdateIssuesCommit(t *testing.T) { Message: "close " + setting.AppURL + repo.FullName() + "/pulls/1", }, } - repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) commentBean = &issues_model.Comment{ Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef3", @@ -133,8 +133,8 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) { }, } - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo.Owner = user issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4} @@ -147,7 +147,7 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) { func TestUpdateIssuesCommit_Issue5957(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Test that push to a non-default branch closes an issue. pushCommits := []*repository.PushCommit{ @@ -161,7 +161,7 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) { }, } - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) commentBean := &issues_model.Comment{ Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", @@ -181,7 +181,7 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) { func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Test that a push to default branch closes issue in another repo // If the user also has push permissions to that repo @@ -196,7 +196,7 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { }, } - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) commentBean := &issues_model.Comment{ Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", @@ -216,7 +216,7 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Test that a push to default branch closes issue in another repo // If the user also has push permissions to that repo @@ -231,7 +231,7 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) { }, } - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) commentBean := &issues_model.Comment{ Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", @@ -251,7 +251,7 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) { func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10}) // Test that a push with close reference *can not* close issue // If the committer doesn't have push rights in that repo @@ -274,7 +274,7 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { }, } - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6}) commentBean := &issues_model.Comment{ Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef3", diff --git a/services/issue/label_test.go b/services/issue/label_test.go index 120c9ea4f1..482db95139 100644 --- a/services/issue/label_test.go +++ b/services/issue/label_test.go @@ -27,12 +27,12 @@ func TestIssue_AddLabels(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}) labels := make([]*issues_model.Label, len(test.labelIDs)) for i, labelID := range test.labelIDs { - labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) + labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}) } - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}) assert.NoError(t, AddLabels(issue, doer, labels)) for _, labelID := range test.labelIDs { unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: labelID}) @@ -53,9 +53,9 @@ func TestIssue_AddLabel(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) - label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: test.labelID}).(*issues_model.Label) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: test.labelID}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}) assert.NoError(t, AddLabel(issue, doer, label)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: test.labelID}) } diff --git a/services/issue/milestone_test.go b/services/issue/milestone_test.go index d08b1ae8c7..087c256700 100644 --- a/services/issue/milestone_test.go +++ b/services/issue/milestone_test.go @@ -16,8 +16,8 @@ import ( func TestChangeMilestoneAssign(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: 1}).(*issues_model.Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: 1}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) assert.NotNil(t, issue) assert.NotNil(t, doer) diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go index 604efe37b6..4302b2c74b 100644 --- a/services/mailer/mail_test.go +++ b/services/mailer/mail_test.go @@ -56,11 +56,11 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re setting.MailService = &mailService setting.Domain = "localhost" - doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer}).(*repo_model.Repository) - issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1, Repo: repo, Poster: doer}).(*issues_model.Issue) + doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer}) + issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1, Repo: repo, Poster: doer}) assert.NoError(t, issue.LoadRepo(db.DefaultContext)) - comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2, Issue: issue}).(*issues_model.Comment) + comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2, Issue: issue}) return doer, repo, issue, comment } @@ -159,8 +159,8 @@ func TestTemplateSelection(t *testing.T) { }, recipients, false, "TestTemplateSelection") expect(t, msg, "issue/default/subject", "issue/default/body") - pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer}).(*issues_model.Issue) - comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull}).(*issues_model.Comment) + pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer}) + comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull}) msg = testComposeIssueCommentMessage(t, &mailCommentContext{ Context: context.TODO(), // TODO: use a correct context Issue: pull, Doer: doer, ActionType: models.ActionCommentPull, diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index 6ea1c20592..9fb3d6ffd6 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -37,7 +37,7 @@ func TestGiteaUploadRepo(t *testing.T) { unittest.PrepareTestEnv(t) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) var ( ctx = context.Background() @@ -63,7 +63,7 @@ func TestGiteaUploadRepo(t *testing.T) { }, nil) assert.NoError(t, err) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName}) assert.True(t, repo.HasWiki()) assert.EqualValues(t, repo_model.RepositoryReady, repo.Status) @@ -127,8 +127,8 @@ func TestGiteaUploadRepo(t *testing.T) { func TestGiteaUploadRemapLocalUser(t *testing.T) { unittest.PrepareTestEnv(t) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) repoName := "migrated" uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName) @@ -177,7 +177,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { func TestGiteaUploadRemapExternalUser(t *testing.T) { unittest.PrepareTestEnv(t) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) repoName := "migrated" uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName) @@ -205,7 +205,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { // // Link the external ID to an existing user // - linkedUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + linkedUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) externalLoginUser := &user_model.ExternalLoginUser{ ExternalID: strconv.FormatInt(externalID, 10), UserID: linkedUser.ID, @@ -232,7 +232,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { // // fromRepo master // - fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) baseRef := "master" assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false)) err := git.NewCommand(git.DefaultContext, "symbolic-ref", "HEAD", git.BranchPrefix+baseRef).Run(&git.RunOpts{Dir: fromRepo.RepoPath()}) @@ -273,13 +273,13 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { headSHA, err := fromGitRepo.GetBranchCommitID(headRef) assert.NoError(t, err) - fromRepoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: fromRepo.OwnerID}).(*user_model.User) + fromRepoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: fromRepo.OwnerID}) // // forkRepo branch2 // forkHeadRef := "branch2" - forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}).(*repo_model.Repository) + forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}) assert.NoError(t, git.CloneWithArgs(git.DefaultContext, fromRepo.RepoPath(), forkRepo.RepoPath(), []string{}, git.CloneRepoOptions{ Branch: headRef, })) diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go index f2542173a0..9460c66dbc 100644 --- a/services/migrations/migrate.go +++ b/services/migrations/migrate.go @@ -479,5 +479,10 @@ func Init() error { } // TODO: at the moment, if ALLOW_LOCALNETWORKS=false, ALLOWED_DOMAINS=domain.com, and domain.com has IP 127.0.0.1, then it's still allowed. // if we want to block such case, the private&loopback should be added to the blockList when ALLOW_LOCALNETWORKS=false + + if setting.Proxy.Enabled && setting.Proxy.ProxyURLFixed != nil { + allowList.AppendPattern(setting.Proxy.ProxyURLFixed.Host) + } + return nil } diff --git a/services/migrations/migrate_test.go b/services/migrations/migrate_test.go index 53cfe6d3eb..3fc4034777 100644 --- a/services/migrations/migrate_test.go +++ b/services/migrations/migrate_test.go @@ -19,8 +19,8 @@ import ( func TestMigrateWhiteBlocklist(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}).(*user_model.User) - nonAdminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}).(*user_model.User) + adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) + nonAdminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}) setting.Migrations.AllowedDomains = "github.com" setting.Migrations.AllowLocalNetworks = false diff --git a/services/org/org_test.go b/services/org/org_test.go index 7f90d85807..c4e6088a71 100644 --- a/services/org/org_test.go +++ b/services/org/org_test.go @@ -24,18 +24,18 @@ func TestMain(m *testing.M) { func TestDeleteOrganization(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 6}).(*organization.Organization) + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 6}) assert.NoError(t, DeleteOrganization(org)) unittest.AssertNotExistsBean(t, &organization.Organization{ID: 6}) unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: 6}) unittest.AssertNotExistsBean(t, &organization.Team{OrgID: 6}) - org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization) + org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) err := DeleteOrganization(org) assert.Error(t, err) assert.True(t, models.IsErrUserOwnRepos(err)) - user := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 5}).(*organization.Organization) + user := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 5}) assert.Error(t, DeleteOrganization(user)) unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{}) } diff --git a/services/pull/check_test.go b/services/pull/check_test.go index 21fe675bbc..b4de02b5e2 100644 --- a/services/pull/check_test.go +++ b/services/pull/check_test.go @@ -43,11 +43,11 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) { prPatchCheckerQueue = q.(queue.UniqueQueue) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) AddToTaskQueue(pr) assert.Eventually(t, func() bool { - pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) return pr.Status == issues_model.PullRequestStatusChecking }, 1*time.Second, 100*time.Millisecond) @@ -72,7 +72,7 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) { assert.False(t, has) assert.NoError(t, err) - pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) assert.Equal(t, issues_model.PullRequestStatusChecking, pr.Status) for _, callback := range queueShutdown { diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go index 9160c43460..769e3c72e9 100644 --- a/services/pull/pull_test.go +++ b/services/pull/pull_test.go @@ -38,7 +38,7 @@ func TestPullRequest_CommitMessageTrailersPattern(t *testing.T) { func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) assert.NoError(t, pr.LoadBaseRepo()) gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) @@ -65,10 +65,10 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { ExternalTrackerFormat: "https://someurl.com/{user}/{repo}/{issue}", }, } - baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) baseRepo.Units = []*repo_model.RepoUnit{&externalTracker} - pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo}).(*issues_model.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo}) assert.NoError(t, pr.LoadBaseRepo()) gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) diff --git a/services/pull/update.go b/services/pull/update.go index e5e26462e5..49258a9862 100644 --- a/services/pull/update.go +++ b/services/pull/update.go @@ -87,6 +87,9 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest, } headRepoPerm, err := access_model.GetUserRepoPermission(ctx, pull.HeadRepo, user) if err != nil { + if repo_model.IsErrUnitTypeNotExist(err) { + return false, false, nil + } return false, false, err } diff --git a/services/release/release_test.go b/services/release/release_test.go index 0f5b74f70d..d1a9298b69 100644 --- a/services/release/release_test.go +++ b/services/release/release_test.go @@ -30,8 +30,8 @@ func TestMain(m *testing.M) { func TestRelease_Create(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repoPath := repo_model.RepoPath(user.Name, repo.Name) gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath) @@ -134,8 +134,8 @@ func TestRelease_Create(t *testing.T) { func TestRelease_Update(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repoPath := repo_model.RepoPath(user.Name, repo.Name) gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath) @@ -276,8 +276,8 @@ func TestRelease_Update(t *testing.T) { func TestRelease_createTag(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repoPath := repo_model.RepoPath(user.Name, repo.Name) gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath) @@ -358,8 +358,8 @@ func TestRelease_createTag(t *testing.T) { func TestCreateNewTag(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.NoError(t, CreateNewTag(git.DefaultContext, user, repo, "master", "v2.0", "v2.0 is released \n\n BUGFIX: .... \n\n 123")) diff --git a/services/repository/avatar.go b/services/repository/avatar.go index dcf04c7e54..b9bd36ab66 100644 --- a/services/repository/avatar.go +++ b/services/repository/avatar.go @@ -96,7 +96,7 @@ func DeleteAvatar(repo *repo_model.Repository) error { // RemoveRandomAvatars removes the randomly generated avatars that were created for repositories func RemoveRandomAvatars(ctx context.Context) error { - return repo_model.IterateRepository(func(repository *repo_model.Repository) error { + return db.IterateObjects(ctx, func(repository *repo_model.Repository) error { select { case <-ctx.Done(): return db.ErrCancelledf("before random avatars removed for %s", repository.FullName()) diff --git a/services/repository/avatar_test.go b/services/repository/avatar_test.go index efad392a2d..e5d9ac9d53 100644 --- a/services/repository/avatar_test.go +++ b/services/repository/avatar_test.go @@ -25,7 +25,7 @@ func TestUploadAvatar(t *testing.T) { png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) err := UploadAvatar(repo, buff.Bytes()) assert.NoError(t, err) @@ -39,7 +39,7 @@ func TestUploadBigAvatar(t *testing.T) { png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) err := UploadAvatar(repo, buff.Bytes()) assert.Error(t, err) @@ -52,7 +52,7 @@ func TestDeleteAvatar(t *testing.T) { png.Encode(&buff, myImage) assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) err := UploadAvatar(repo, buff.Bytes()) assert.NoError(t, err) diff --git a/services/repository/fork_test.go b/services/repository/fork_test.go index 965887b5d1..376c5c06d9 100644 --- a/services/repository/fork_test.go +++ b/services/repository/fork_test.go @@ -20,8 +20,8 @@ func TestForkRepository(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // user 13 has already forked repo10 - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 13}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 13}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) fork, err := ForkRepository(git.DefaultContext, user, user, ForkRepoOptions{ BaseRepo: repo, diff --git a/services/repository/review_test.go b/services/repository/review_test.go index 640657d1dd..badacf39a6 100644 --- a/services/repository/review_test.go +++ b/services/repository/review_test.go @@ -16,12 +16,12 @@ import ( func TestRepoGetReviewerTeams(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) teams, err := GetReviewerTeams(repo2) assert.NoError(t, err) assert.Empty(t, teams) - repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) teams, err = GetReviewerTeams(repo3) assert.NoError(t, err) assert.Len(t, teams, 2) diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go index 8be8c5353d..3c929f2f7b 100644 --- a/services/repository/transfer_test.go +++ b/services/repository/transfer_test.go @@ -35,12 +35,12 @@ func TestTransferOwnership(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) - repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) + repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) assert.NoError(t, TransferOwnership(doer, doer, repo, nil)) - transferredRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) + transferredRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) assert.EqualValues(t, 2, transferredRepo.OwnerID) exist, err := util.IsExist(repo_model.RepoPath("user3", "repo3")) @@ -62,10 +62,10 @@ func TestTransferOwnership(t *testing.T) { func TestStartRepositoryTransferSetPermission(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) - recipient := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) - repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + recipient := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) + repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) hasAccess, err := access_model.HasAccess(db.DefaultContext, recipient.ID, repo) assert.NoError(t, err) diff --git a/services/user/user_test.go b/services/user/user_test.go index d8673593df..c07244e7e1 100644 --- a/services/user/user_test.go +++ b/services/user/user_test.go @@ -28,7 +28,7 @@ func TestMain(m *testing.M) { func TestDeleteUser(t *testing.T) { test := func(userID int64) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) ownedRepos := make([]*repo_model.Repository, 0, 10) assert.NoError(t, db.GetEngine(db.DefaultContext).Find(&ownedRepos, &repo_model.Repository{OwnerID: userID})) @@ -56,14 +56,14 @@ func TestDeleteUser(t *testing.T) { test(8) test(11) - org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) assert.Error(t, DeleteUser(db.DefaultContext, org, false)) } func TestPurgeUser(t *testing.T) { test := func(userID int64) { assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) err := DeleteUser(db.DefaultContext, user, true) assert.NoError(t, err) @@ -76,7 +76,7 @@ func TestPurgeUser(t *testing.T) { test(8) test(11) - org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) + org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) assert.Error(t, DeleteUser(db.DefaultContext, org, false)) } diff --git a/services/webhook/slack.go b/services/webhook/slack.go index 11e1d3c081..e3d0d406de 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -7,6 +7,7 @@ package webhook import ( "errors" "fmt" + "regexp" "strings" webhook_model "code.gitea.io/gitea/models/webhook" @@ -286,3 +287,13 @@ func GetSlackPayload(p api.Payloader, event webhook_model.HookEventType, meta st return convertPayloader(s, p, event) } + +var slackChannel = regexp.MustCompile(`^#?[a-z0-9_-]{1,80}$`) + +// IsValidSlackChannel validates a channel name conforms to what slack expects: +// https://api.slack.com/methods/conversations.rename#naming +// Conversation names can only contain lowercase letters, numbers, hyphens, and underscores, and must be 80 characters or less. +// Gitea accepts if it starts with a #. +func IsValidSlackChannel(name string) bool { + return slackChannel.MatchString(name) +} diff --git a/services/webhook/slack_test.go b/services/webhook/slack_test.go index 8278afb69a..0f08785d25 100644 --- a/services/webhook/slack_test.go +++ b/services/webhook/slack_test.go @@ -170,3 +170,22 @@ func TestSlackJSONPayload(t *testing.T) { require.NoError(t, err) assert.NotEmpty(t, json) } + +func TestIsValidSlackChannel(t *testing.T) { + tt := []struct { + channelName string + expected bool + }{ + {"gitea", true}, + {"#gitea", true}, + {" ", false}, + {"#", false}, + {" #", false}, + {"gitea ", false}, + {" gitea", false}, + } + + for _, v := range tt { + assert.Equal(t, v.expected, IsValidSlackChannel(v.channelName)) + } +} diff --git a/services/webhook/webhook_test.go b/services/webhook/webhook_test.go index 85fc39770e..1887cc71fe 100644 --- a/services/webhook/webhook_test.go +++ b/services/webhook/webhook_test.go @@ -30,7 +30,7 @@ func TestWebhook_GetSlackHook(t *testing.T) { func TestPrepareWebhooks(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) hookTasks := []*webhook_model.HookTask{ {RepoID: repo.ID, HookID: 1, EventType: webhook_model.HookEventPush}, } @@ -46,7 +46,7 @@ func TestPrepareWebhooks(t *testing.T) { func TestPrepareWebhooksBranchFilterMatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) hookTasks := []*webhook_model.HookTask{ {RepoID: repo.ID, HookID: 4, EventType: webhook_model.HookEventPush}, } @@ -63,7 +63,7 @@ func TestPrepareWebhooksBranchFilterMatch(t *testing.T) { func TestPrepareWebhooksBranchFilterNoMatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) hookTasks := []*webhook_model.HookTask{ {RepoID: repo.ID, HookID: 4, EventType: webhook_model.HookEventPush}, } diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go index 0c73074dbe..1852ddbcb3 100644 --- a/services/wiki/wiki_test.go +++ b/services/wiki/wiki_test.go @@ -116,11 +116,11 @@ func TestWikiNameToFilenameToName(t *testing.T) { func TestRepository_InitWiki(t *testing.T) { unittest.PrepareTestEnv(t) // repo1 already has a wiki - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.NoError(t, InitWiki(git.DefaultContext, repo1)) // repo2 does not already have a wiki - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) assert.NoError(t, InitWiki(git.DefaultContext, repo2)) assert.True(t, repo2.HasWiki()) } @@ -129,8 +129,8 @@ func TestRepository_AddWikiPage(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) const wikiContent = "This is the wiki content" const commitMsg = "Commit message" - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) for _, wikiName := range []string{ "Another page", "Here's a and a/slash", @@ -174,8 +174,8 @@ func TestRepository_EditWikiPage(t *testing.T) { const newWikiContent = "This is the new content" const commitMsg = "Commit message" - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) for _, newWikiName := range []string{ "Home", // same name as before "New home", @@ -204,8 +204,8 @@ func TestRepository_EditWikiPage(t *testing.T) { func TestRepository_DeleteWikiPage(t *testing.T) { unittest.PrepareTestEnv(t) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) assert.NoError(t, DeleteWikiPage(git.DefaultContext, doer, repo, "Home")) // Now need to show that the page has been added: @@ -221,7 +221,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) { func TestPrepareWikiFileName(t *testing.T) { unittest.PrepareTestEnv(t) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) gitRepo, err := git.OpenRepository(git.DefaultContext, repo.WikiPath()) defer gitRepo.Close() assert.NoError(t, err) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 2defba7be3..437bda87aa 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -44,8 +44,8 @@ parts: plugin: make source: . stage-packages: [ git, sqlite3, openssh-client ] - build-packages: [ git, libpam0g-dev, libsqlite3-dev] - build-snaps: [ go, node/14/stable ] + build-packages: [ git, libpam0g-dev, libsqlite3-dev, build-essential] + build-snaps: [ go, node/18/stable ] build-environment: - LDFLAGS: "" override-pull: | diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl index dfc0646610..88dec014f6 100644 --- a/templates/base/footer_content.tmpl +++ b/templates/base/footer_content.tmpl @@ -1,7 +1,7 @@