diff --git a/cmd/migrate_storage.go b/cmd/migrate_storage.go index a283f91401839..b6af5b96e87fc 100644 --- a/cmd/migrate_storage.go +++ b/cmd/migrate_storage.go @@ -83,35 +83,35 @@ var CmdMigrateStorage = cli.Command{ } func migrateAttachments(ctx context.Context, dstStorage storage.ObjectStorage) error { - return db.IterateObjects(ctx, func(attach *repo_model.Attachment) error { + return db.Iterate(ctx, nil, func(ctx context.Context, attach *repo_model.Attachment) error { _, err := storage.Copy(dstStorage, attach.RelativePath(), storage.Attachments, attach.RelativePath()) return err }) } func migrateLFS(ctx context.Context, dstStorage storage.ObjectStorage) error { - return db.IterateObjects(ctx, func(mo *git_model.LFSMetaObject) error { + return db.Iterate(ctx, nil, func(ctx context.Context, mo *git_model.LFSMetaObject) error { _, err := storage.Copy(dstStorage, mo.RelativePath(), storage.LFS, mo.RelativePath()) return err }) } func migrateAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error { - return db.IterateObjects(ctx, func(user *user_model.User) error { + return db.Iterate(ctx, nil, func(ctx context.Context, user *user_model.User) error { _, err := storage.Copy(dstStorage, user.CustomAvatarRelativePath(), storage.Avatars, user.CustomAvatarRelativePath()) return err }) } func migrateRepoAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error { - return db.IterateObjects(ctx, func(repo *repo_model.Repository) error { + return db.Iterate(ctx, nil, func(ctx context.Context, 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 { + return db.Iterate(ctx, nil, func(ctx context.Context, archiver *repo_model.RepoArchiver) error { p := archiver.RelativePath() _, err := storage.Copy(dstStorage, p, storage.RepoArchives, p) return err @@ -119,7 +119,7 @@ func migrateRepoArchivers(ctx context.Context, dstStorage storage.ObjectStorage) } func migratePackages(ctx context.Context, dstStorage storage.ObjectStorage) error { - return db.IterateObjects(ctx, func(pb *packages_model.PackageBlob) error { + return db.Iterate(ctx, nil, func(ctx context.Context, pb *packages_model.PackageBlob) error { p := packages_module.KeyToRelativePath(packages_module.BlobHash256Key(pb.HashSHA256)) _, err := storage.Copy(dstStorage, p, storage.Packages, p) return err diff --git a/docs/content/doc/advanced/hacking-on-gitea.zh-cn.md b/docs/content/doc/advanced/hacking-on-gitea.zh-cn.md deleted file mode 100644 index 7ad8019c5e6a3..0000000000000 --- a/docs/content/doc/advanced/hacking-on-gitea.zh-cn.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -date: "2016-12-01T16:00:00+02:00" -title: "加入 Gitea 开源" -slug: "hacking-on-gitea" -weight: 10 -toc: false -draft: false -menu: - sidebar: - parent: "advanced" - name: "加入 Gitea 开源" - weight: 10 - identifier: "hacking-on-gitea" ---- - -# Hacking on Gitea - -首先你需要一些运行环境,这和 [从源代码安装]({{< relref "from-source.zh-cn.md" >}}) 相同,如果你还没有设置好,可以先阅读那个章节。 - -如果你想为 Gitea 贡献代码,你需要 Fork 这个项目并且以 `master` 为开发分支。Gitea 使用 Govendor -来管理依赖,因此所有依赖项都被工具自动 copy 在 vendor 子目录下。用下面的命令来下载源码: - -``` -go get -d code.gitea.io/gitea -``` - -然后你可以在 Github 上 fork [Gitea 项目](https://github.com/go-gitea/gitea),之后可以通过下面的命令进入源码目录: - -``` -cd $GOPATH/src/code.gitea.io/gitea -``` - -要创建 pull requests 你还需要在源码中新增一个 remote 指向你 Fork 的地址,直接推送到 origin 的话会告诉你没有写权限: - -``` -git remote rename origin upstream -git remote add origin git@github.com:/gitea.git -git fetch --all --prune -``` - -然后你就可以开始开发了。你可以看一下 `Makefile` 的内容。`make test` 可以运行测试程序, `make build` 将生成一个 `gitea` 可运行文件在根目录。如果你的提交比较复杂,尽量多写一些单元测试代码。 - -好了,到这里你已经设置好了所有的开发 Gitea 所需的环境。欢迎成为 Gitea 的 Contributor。 diff --git a/docs/content/doc/advanced/mail-templates-us.md b/docs/content/doc/advanced/mail-templates.en-us.md similarity index 100% rename from docs/content/doc/advanced/mail-templates-us.md rename to docs/content/doc/advanced/mail-templates.en-us.md diff --git a/docs/content/doc/advanced/make.fr-fr.md b/docs/content/doc/advanced/make.fr-fr.md deleted file mode 100644 index f30b709f0ef61..0000000000000 --- a/docs/content/doc/advanced/make.fr-fr.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -date: "2017-08-23T09:00:00+02:00" -title: "Make" -slug: "make" -weight: 10 -toc: false -draft: false -menu: - sidebar: - parent: "advanced" - name: "Make" - weight: 30 - identifier: "make" ---- - -# Make - -Gitea fait largement usage de Make pour automatiser les tâches et avoir un développement plus rapide. Ce guide explique comment installer Make. - -### Linux - -Vous pouvez installer Make avec votre gestionnaire de paquetages - -Depuis Ubuntu/Debian: - -```bash -sudo apt-get install build-essential -``` - -Depuis Fedora/RHEL/CentOS: - -```bash -sudo yum install make -``` - -### Windows - -Si vous utilisez Windows, vous pouvez télécharger une des versions suivantes de Make: - -- [Simple binaire](http://www.equation.com/servlet/equation.cmd?fa=make). Copiez-le quelque part et mettez à jour `PATH`. - - [32-bits version](ftp://ftp.equation.com/make/32/make.exe) - - [64-bits version](ftp://ftp.equation.com/make/64/make.exe) -- [MinGW](http://www.mingw.org/) inclut un _build_. Le fichier binaire est nommé `mingw32-make.exe` plutôt que `make.exe`. Ajoutez le dossier `bin` à votre `PATH`. -- [Chocolatey package](https://chocolatey.org/packages/make). Exécutez `choco install make`. diff --git a/docs/content/doc/advanced/make.zh-cn.md b/docs/content/doc/advanced/make.zh-cn.md deleted file mode 100644 index 2491dbe2319c0..0000000000000 --- a/docs/content/doc/advanced/make.zh-cn.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -date: "2017-01-14T11:00:00-02:00" -title: "Make 安装" -slug: "make" -weight: 10 -toc: false -draft: false -menu: - sidebar: - parent: "advanced" - name: "Make 安装" - weight: 30 - identifier: "make" ---- - -# 安装 Make - -Gitea 大量使用了 Make 工具来自动执行任务并改进开发,本文将介绍如何安装 Make。 - -### 在 Linux 环境下 - -可以使用包管理工具来安装 Make。 - -Ubuntu/Debian 环境,执行以下命令: - -```bash -sudo apt-get install make -``` - -Fedora/RHEL/CentOS,执行以下命令: - -```bash -sudo yum install make -``` - -### 在 Windows 环境下 - -您可以参照以下三种方案在 Windows 环境安装 Make: - -- 直接使用 [exe文件](http://www.equation.com/servlet/equation.cmd?fa=make):将适合您系统的exe文件拷贝到某处并添加至环境变量 `PATH` 中。 - - [32 位版本](ftp://ftp.equation.com/make/32/make.exe) - - [64 位版本](ftp://ftp.equation.com/make/64/make.exe) -- 使用 [MinGW](http://www.mingw.org/) 工具: - - 此处使用二进制文件 `mingw32-make.exe` 替代前面提到的 `make.exe`文件。同样您需要将包含此exe文件的 `bin` 目录添加至环境变量 `PATH`中。 -- 通过 [Chocolatey](https://chocolatey.org/packages/make) 安装: 执行 `choco install make` 命令即可。 diff --git a/docs/content/doc/advanced/third-party-tools.zh-cn.md b/docs/content/doc/advanced/third-party-tools.zh-cn.md deleted file mode 100644 index e961e9ec1fa19..0000000000000 --- a/docs/content/doc/advanced/third-party-tools.zh-cn.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -date: "2019-03-11T21:45:00+00:00" -title: "高级: 第三方工具" -slug: "third-party-tools" -weight: 50 -toc: false -draft: false -menu: - sidebar: - parent: "advanced" - name: "第三方工具" - weight: 50 - identifier: "third-party-tools" ---- - -# 第三方工具列表 - -**注意:** 这些工具并没有经过Gitea的检验,在这里列出它们只是为了便捷. - -*此列表并不是完整的列表,可以随时咨询如何添加!* - -### 持续集成 - -[BuildKite 连接器](https://github.com/techknowlogick/gitea-buildkite-connector) -[Jenkins 插件](https://github.com/jenkinsci/gitea-plugin) -[Gitea搭配Drone](https://docs.drone.io/installation/gitea) - -### 迁移 - -[Gitea安装脚本](https://git.coolaj86.com/coolaj86/gitea-installer.sh) -[GitHub迁移](https://gitea.com/gitea/migrator) - -### 移动端 - -[安卓客户端GitNex](https://gitlab.com/mmarif4u/gitnex) - -### 编辑器扩展 - -- [Gitea的Visual Studio扩展](https://github.com/maikebing/Gitea.VisualStudio) 从 [Visual Studio 扩展市场](https://marketplace.visualstudio.com/items?itemName=MysticBoy.GiteaExtensionforVisualStudio) 下载 diff --git a/docs/content/doc/developers.zh-cn.md b/docs/content/doc/developers.zh-cn.md index 0a873102bc504..97fb3a97826fb 100644 --- a/docs/content/doc/developers.zh-cn.md +++ b/docs/content/doc/developers.zh-cn.md @@ -8,6 +8,6 @@ draft: false menu: sidebar: name: "开发者" - weight: 50 + weight: 55 identifier: "developers" --- diff --git a/docs/content/doc/developers/guidelines-backend.md b/docs/content/doc/developers/guidelines-backend.en-us.md similarity index 100% rename from docs/content/doc/developers/guidelines-backend.md rename to docs/content/doc/developers/guidelines-backend.en-us.md diff --git a/docs/content/doc/developers/oauth2-provider.md b/docs/content/doc/developers/oauth2-provider.en-us.md similarity index 100% rename from docs/content/doc/developers/oauth2-provider.md rename to docs/content/doc/developers/oauth2-provider.en-us.md diff --git a/docs/content/doc/installation/from-source.en-us.md b/docs/content/doc/installation/from-source.en-us.md index 660f996b1e707..0be5673be4795 100644 --- a/docs/content/doc/installation/from-source.en-us.md +++ b/docs/content/doc/installation/from-source.en-us.md @@ -87,7 +87,7 @@ To build from source, the following programs must be present on the system: - `go` {{< min-go-version >}} or higher, see [here](https://golang.org/dl/) - `node` {{< min-node-version >}} or higher with `npm`, see [here](https://nodejs.org/en/download/) -- `make`, see here +- `make`, see [here]({{< relref "doc/developers/hacking-on-gitea.en-us.md" >}}#installing-make) Various [make tasks](https://github.com/go-gitea/gitea/blob/main/Makefile) are provided to keep the build process as simple as possible. diff --git a/docs/content/doc/installation/from-source.fr-fr.md b/docs/content/doc/installation/from-source.fr-fr.md index 00f67eab55f2f..6ff4853a22c5f 100644 --- a/docs/content/doc/installation/from-source.fr-fr.md +++ b/docs/content/doc/installation/from-source.fr-fr.md @@ -53,7 +53,7 @@ git checkout pr-xyz ## Compilation -Comme nous regroupons déjà toutes les bibliothèques requises pour compiler Gitea, vous pouvez continuer avec le processus de compilation lui-même. Nous fournissons diverses [tâches Make](https://github.com/go-gitea/gitea/blob/master/Makefile) pour rendre le processus de construction aussi simple que possible. Voyez ici comment obtenir Make. Selon vos besoins, vous pourrez éventuellement ajouter diverses options de compilation, vous pouvez choisir entre ces options : +Comme nous regroupons déjà toutes les bibliothèques requises pour compiler Gitea, vous pouvez continuer avec le processus de compilation lui-même. Nous fournissons diverses [tâches Make](https://github.com/go-gitea/gitea/blob/master/Makefile) pour rendre le processus de construction aussi simple que possible. [Voyez ici comment obtenir Make]({{< relref "doc/developers/hacking-on-gitea.fr-fr.md" >}}#installing-make). Selon vos besoins, vous pourrez éventuellement ajouter diverses options de compilation, vous pouvez choisir entre ces options : * `bindata`: Intègre toutes les ressources nécessaires à l'exécution d'une instance de Gitea, ce qui rend un déploiement facile car il n'est pas nécessaire de se préoccuper des fichiers supplémentaires. * `sqlite sqlite_unlock_notify`: Active la prise en charge d'une base de données [SQLite3](https://sqlite.org/), ceci n'est recommandé que pour les petites installations de Gitea. diff --git a/docs/content/doc/installation/from-source.zh-cn.md b/docs/content/doc/installation/from-source.zh-cn.md index 008566e57db58..659c992346cd1 100644 --- a/docs/content/doc/installation/from-source.zh-cn.md +++ b/docs/content/doc/installation/from-source.zh-cn.md @@ -54,7 +54,7 @@ git checkout v{{< version >}} - `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`, 详见[这里]({{< relref "doc/developers/hacking-on-gitea.zh-cn.md" >}}) 各种可用的 [make 任务](https://github.com/go-gitea/gitea/blob/main/Makefile) 可以用来使编译过程更方便。 diff --git a/docs/content/doc/installation/on-cloud-provider.md b/docs/content/doc/installation/on-cloud-provider.en-us.md similarity index 100% rename from docs/content/doc/installation/on-cloud-provider.md rename to docs/content/doc/installation/on-cloud-provider.en-us.md diff --git a/docs/content/doc/usage/email-setup.en-us.md b/docs/content/doc/usage/email-setup.en-us.md index 533e0fe1a8f9c..05cc19c13452c 100644 --- a/docs/content/doc/usage/email-setup.en-us.md +++ b/docs/content/doc/usage/email-setup.en-us.md @@ -47,7 +47,8 @@ Directly use SMTP server as relay. This option is useful if you don't want to se ENABLED = true FROM = gitea@mydomain.com MAILER_TYPE = smtp -HOST = mail.mydomain.com:587 +SMTP_ADDR = mail.mydomain.com +SMTP_PORT = 587 IS_TLS_ENABLED = true USER = gitea@mydomain.com PASSWD = `password` @@ -75,7 +76,8 @@ The following configuration should work with GMail's SMTP server: ```ini [mailer] ENABLED = true -HOST = smtp.gmail.com:465 +SMTP_ADDR = smtp.gmail.com +SMTP_PORT = 465 FROM = example@gmail.com USER = example@gmail.com PASSWD = *** diff --git a/docs/content/doc/usage/git-lfs-support.md b/docs/content/doc/usage/git-lfs-support.en-us.md similarity index 100% rename from docs/content/doc/usage/git-lfs-support.md rename to docs/content/doc/usage/git-lfs-support.en-us.md diff --git a/docs/content/doc/usage/https-support.md b/docs/content/doc/usage/https-support.en-us.md similarity index 100% rename from docs/content/doc/usage/https-support.md rename to docs/content/doc/usage/https-support.en-us.md diff --git a/docs/content/doc/usage/template-repositories.md b/docs/content/doc/usage/template-repositories.en-us.md similarity index 100% rename from docs/content/doc/usage/template-repositories.md rename to docs/content/doc/usage/template-repositories.en-us.md diff --git a/docs/static/_redirects b/docs/static/_redirects index 676181b61f938..39bd09f9ba514 100644 --- a/docs/static/_redirects +++ b/docs/static/_redirects @@ -9,7 +9,10 @@ https://gitea-docs.netlify.com/* https://docs.gitea.io/:splat 302! /en-us/ci-cd/ /en-us/integrations/ 302! /en-us/third-party-tools/ /en-us/integrations/ 302! +/zh-cn/third-party-tools/ /zh-cn/integrations/ 302! /en-us/make/ /en-us/hacking-on-gitea/ 302! +/zh-cn/make/ /zh-cn/hacking-on-gitea/ 302! +/fr-fr/make/ /fr-fr/hacking-on-gitea/ 302! /en-us/upgrade/ /en-us/upgrade-from-gitea/ 302! /fr-fr/upgrade/ /fr-fr/upgrade-from-gitea/ 302! /zh-cn/upgrade/ /zh-cn/upgrade-from-gitea/ 302! diff --git a/models/db/context.go b/models/db/context.go index 4fd35200cf71c..e90780e4e93e9 100644 --- a/models/db/context.go +++ b/models/db/context.go @@ -8,9 +8,6 @@ import ( "context" "database/sql" - "code.gitea.io/gitea/modules/setting" - - "xorm.io/builder" "xorm.io/xorm/schemas" ) @@ -121,13 +118,6 @@ func WithTx(f func(ctx context.Context) error, stdCtx ...context.Context) error return sess.Commit() } -// Iterate iterates the databases and doing something -func Iterate(ctx context.Context, tableBean interface{}, cond builder.Cond, fun func(idx int, bean interface{}) error) error { - return GetEngine(ctx).Where(cond). - BufferSize(setting.Database.IterateBufferSize). - Iterate(tableBean, fun) -} - // Insert inserts records into database func Insert(ctx context.Context, beans ...interface{}) error { _, err := GetEngine(ctx).Insert(beans...) diff --git a/models/db/iterate.go b/models/db/iterate.go index 3d4fa06eeb96e..cbd2feed280e8 100644 --- a/models/db/iterate.go +++ b/models/db/iterate.go @@ -8,25 +8,30 @@ import ( "context" "code.gitea.io/gitea/modules/setting" + + "xorm.io/builder" ) -// IterateObjects iterate all the Bean object -func IterateObjects[Object any](ctx context.Context, f func(repo *Object) error) error { +// Iterate iterate all the Bean object +func Iterate[Bean any](ctx context.Context, cond builder.Cond, f func(ctx context.Context, bean *Bean) 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 { + beans := make([]*Bean, 0, batchSize) + if cond != nil { + sess = sess.Where(cond) + } + if err := sess.Limit(batchSize, start).Find(&beans); err != nil { return err } - if len(repos) == 0 { + if len(beans) == 0 { return nil } - start += len(repos) + start += len(beans) - for _, repo := range repos { - if err := f(repo); err != nil { + for _, bean := range beans { + if err := f(ctx, bean); err != nil { return err } } diff --git a/models/db/iterate_test.go b/models/db/iterate_test.go new file mode 100644 index 0000000000000..5d03a6e9ceab8 --- /dev/null +++ b/models/db/iterate_test.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 db_test + +import ( + "context" + "testing" + + "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + + "github.com/stretchr/testify/assert" +) + +func TestIterate(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + xe := unittest.GetXORMEngine() + assert.NoError(t, xe.Sync(&repo_model.RepoUnit{})) + + var repoCnt int + err := db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repo *repo_model.RepoUnit) error { + repoCnt++ + return nil + }) + assert.NoError(t, err) + assert.EqualValues(t, 79, repoCnt) + + err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error { + reopUnit2 := repo_model.RepoUnit{ID: repoUnit.ID} + has, err := db.GetByBean(ctx, &reopUnit2) + if err != nil { + return err + } else if !has { + return db.ErrNotExist{Resource: "repo_unit", ID: repoUnit.ID} + } + assert.EqualValues(t, repoUnit.RepoID, repoUnit.RepoID) + assert.EqualValues(t, repoUnit.CreatedUnix, repoUnit.CreatedUnix) + return nil + }) + assert.NoError(t, err) +} diff --git a/modules/doctor/breaking.go b/modules/doctor/breaking.go index 51122d9a61a5c..474997acd855f 100644 --- a/modules/doctor/breaking.go +++ b/modules/doctor/breaking.go @@ -18,10 +18,9 @@ import ( func iterateUserAccounts(ctx context.Context, each func(*user.User) error) error { err := db.Iterate( ctx, - new(user.User), builder.Gt{"id": 0}, - func(idx int, bean interface{}) error { - return each(bean.(*user.User)) + func(ctx context.Context, bean *user.User) error { + return each(bean) }, ) return err diff --git a/modules/doctor/fix16961.go b/modules/doctor/fix16961.go index 307cfcd9ff877..d9f895739f2e7 100644 --- a/modules/doctor/fix16961.go +++ b/modules/doctor/fix16961.go @@ -269,13 +269,10 @@ func fixBrokenRepoUnits16961(ctx context.Context, logger log.Logger, autofix boo err := db.Iterate( ctx, - new(RepoUnit), builder.Gt{ "id": 0, }, - func(idx int, bean interface{}) error { - unit := bean.(*RepoUnit) - + func(ctx context.Context, unit *RepoUnit) error { bs := unit.Config repoUnit := &repo_model.RepoUnit{ ID: unit.ID, diff --git a/modules/doctor/mergebase.go b/modules/doctor/mergebase.go index b279c453f7995..9f5e336461a07 100644 --- a/modules/doctor/mergebase.go +++ b/modules/doctor/mergebase.go @@ -21,10 +21,9 @@ import ( func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*repo_model.Repository, *issues_model.PullRequest) error) error { return db.Iterate( ctx, - new(issues_model.PullRequest), builder.Eq{"base_repo_id": repo.ID}, - func(idx int, bean interface{}) error { - return each(repo, bean.(*issues_model.PullRequest)) + func(ctx context.Context, bean *issues_model.PullRequest) error { + return each(repo, bean) }, ) } diff --git a/modules/doctor/misc.go b/modules/doctor/misc.go index 277d66a177725..6f0e066f54d13 100644 --- a/modules/doctor/misc.go +++ b/modules/doctor/misc.go @@ -30,10 +30,9 @@ import ( func iterateRepositories(ctx context.Context, each func(*repo_model.Repository) error) error { err := db.Iterate( ctx, - new(repo_model.Repository), builder.Gt{"id": 0}, - func(idx int, bean interface{}) error { - return each(bean.(*repo_model.Repository)) + func(ctx context.Context, bean *repo_model.Repository) error { + return each(bean) }, ) return err diff --git a/modules/issue/template/unmarshal.go b/modules/issue/template/unmarshal.go index e695d1e1cc664..24587b0fed2b1 100644 --- a/modules/issue/template/unmarshal.go +++ b/modules/issue/template/unmarshal.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" "gopkg.in/yaml.v2" ) @@ -95,14 +96,27 @@ func unmarshal(filename string, content []byte) (*api.IssueTemplate, error) { }{} if typ := it.Type(); typ == api.IssueTemplateTypeMarkdown { - templateBody, err := markdown.ExtractMetadata(string(content), it) - if err != nil { - return nil, err - } - it.Content = templateBody - if it.About == "" { - if _, err := markdown.ExtractMetadata(string(content), compatibleTemplate); err == nil && compatibleTemplate.About != "" { - it.About = compatibleTemplate.About + if templateBody, err := markdown.ExtractMetadata(string(content), it); err != nil { + // The only thing we know here is that we can't extract metadata from the content, + // it's hard to tell if metadata doesn't exist or metadata isn't valid. + // There's an example template: + // + // --- + // # Title + // --- + // Content + // + // It could be a valid markdown with two horizontal lines, or an invalid markdown with wrong metadata. + + it.Content = string(content) + it.Name = filepath.Base(it.FileName) + it.About, _ = util.SplitStringAtByteN(it.Content, 80) + } else { + it.Content = templateBody + if it.About == "" { + if _, err := markdown.ExtractMetadata(string(content), compatibleTemplate); err == nil && compatibleTemplate.About != "" { + it.About = compatibleTemplate.About + } } } } else if typ == api.IssueTemplateTypeYaml { diff --git a/modules/structs/issue.go b/modules/structs/issue.go index 27ec81f7283f7..70f5e1ba8eaa1 100644 --- a/modules/structs/issue.go +++ b/modules/structs/issue.go @@ -170,7 +170,7 @@ func (it IssueTemplate) Type() IssueTemplateType { if ext := filepath.Ext(it.FileName); ext == ".md" { return IssueTemplateTypeMarkdown } else if ext == ".yaml" || ext == ".yml" { - return "yaml" + return IssueTemplateTypeYaml } - return IssueTemplateTypeYaml + return "" } diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 11adea6555cd5..abb58a4f2576c 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -107,6 +107,8 @@ never=無し rss_feed=RSSフィード [filter] +string.asc=A - Z +string.desc=Z - A [error] occurred=エラーが発生しました. @@ -414,6 +416,10 @@ repo.transfer.body=承認または拒否するには %s を開きます。 も repo.collaborator.added.subject=%s が %s にあなたを追加しました repo.collaborator.added.text=あなたは次のリポジトリの共同作業者に追加されました: +team_invite.subject=%[1]s さんが %[2]s への参加にあなたを招待しました +team_invite.text_1=%[1]s さんが、組織 %[3]s 内のチーム %[2]s への参加に、あなたを招待しました。 +team_invite.text_2=下のリンクをクリックしてチームに参加してください。 +team_invite.text_3=注: この招待は %[1]s 宛です。 招待に心当たりがなければ、このメールを無視してかまいません。 [modal] yes=はい @@ -490,6 +496,7 @@ user_not_exist=指定されたユーザーは存在しません。 team_not_exist=チームが存在していません。 last_org_owner='Owners'チームから最後のユーザーを削除することはできません。ひとつの組織には少なくとも一人のオーナーが必要です。 cannot_add_org_to_team=組織はチームメンバーとして追加できません。 +duplicate_invite_to_team=指定したユーザーはすでにチームメンバーに招待されています。 invalid_ssh_key=SSHキーが確認できません: %s invalid_gpg_key=GPGキーが確認できません: %s @@ -742,6 +749,7 @@ create_oauth2_application_button=アプリケーション作成 create_oauth2_application_success=新しいOAuth2アプリケーションを作成しました。 update_oauth2_application_success=OAuth2アプリケーションを更新しました。 oauth2_application_name=アプリケーション名 +oauth2_confidential_client=コンフィデンシャルクライアント。 ウェブアプリのように秘密情報を機密にできるアプリの場合に選択します。 デスクトップアプリやモバイルアプリなどのネイティブアプリには選択しないでください。 oauth2_redirect_uri=リダイレクトURI save_application=保存 oauth2_client_id=クライアントID @@ -2402,6 +2410,8 @@ teams.members=チームメンバー teams.update_settings=設定の更新 teams.delete_team=チームを削除 teams.add_team_member=チームメンバーを追加 +teams.invite_team_member=%s への招待 +teams.invite_team_member.list=保留中の招待 teams.delete_team_title=チームの削除 teams.delete_team_desc=チームを削除すると、メンバーはこのリポジトリへのアクセス権を失います。 続行しますか? teams.delete_team_success=チームを削除しました。 @@ -2426,6 +2436,9 @@ teams.all_repositories_helper=チームはすべてのリポジトリにアク teams.all_repositories_read_permission_desc=このチームはすべてのリポジトリ読み取りアクセス権を持ちます: メンバーはリポジトリの閲覧とクローンが可能です。 teams.all_repositories_write_permission_desc=このチームはすべてのリポジトリ書き込みアクセス権を持ちます: メンバーはリポジトリの読み取りとプッシュが可能です。 teams.all_repositories_admin_permission_desc=このチームはすべてのリポジトリ管理者アクセス権を持ちます: メンバーはリポジトリの読み取り、プッシュ、共同作業者の追加が可能です。 +teams.invite.title=あなたは組織 %[2]s 内のチーム %[1]s への参加に招待されました。 +teams.invite.by=%s からの招待 +teams.invite.description=下のボタンをクリックしてチームに参加してください。 [admin] dashboard=ダッシュボード @@ -2879,6 +2892,8 @@ config.access_log_template=テンプレート config.xorm_log_mode=XORMログのモード config.xorm_log_sql=SQLのログ出力 +config.get_setting_failed=%s の取得に失敗しました +config.set_setting_failed=%s の設定に失敗しました monitor.cron=Cronタスク monitor.name=名称 diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 6d8f03edf4c13..3d164f005edb9 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -2490,9 +2490,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 仓库存在的记录 diff --git a/routers/private/mail.go b/routers/private/mail.go index e858992aee13b..255e1d901dfe7 100644 --- a/routers/private/mail.go +++ b/routers/private/mail.go @@ -5,6 +5,7 @@ package private import ( + stdCtx "context" "fmt" "net/http" "strconv" @@ -60,7 +61,7 @@ func SendEmail(ctx *context.PrivateContext) { } } } else { - err := db.IterateObjects(ctx, func(user *user_model.User) error { + err := db.Iterate(ctx, nil, func(ctx stdCtx.Context, user *user_model.User) error { if len(user.Email) > 0 && user.IsActive { emails = append(emails, user.Email) } diff --git a/services/repository/adopt.go b/services/repository/adopt.go index 3b986c66c6138..a9a063954800d 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -8,6 +8,7 @@ import ( "context" "fmt" "os" + "path" "path/filepath" "strings" @@ -218,21 +219,21 @@ func DeleteUnadoptedRepository(doer, u *user_model.User, repoName string) error return util.RemoveAll(repoPath) } -type unadoptedRrepositories struct { +type unadoptedRepositories struct { repositories []string index int start int end int } -func (unadopted *unadoptedRrepositories) add(repository string) { +func (unadopted *unadoptedRepositories) add(repository string) { if unadopted.index >= unadopted.start && unadopted.index < unadopted.end { unadopted.repositories = append(unadopted.repositories, repository) } unadopted.index++ } -func checkUnadoptedRepositories(userName string, repoNamesToCheck []string, unadopted *unadoptedRrepositories) error { +func checkUnadoptedRepositories(userName string, repoNamesToCheck []string, unadopted *unadoptedRepositories) error { if len(repoNamesToCheck) == 0 { return nil } @@ -264,7 +265,7 @@ func checkUnadoptedRepositories(userName string, repoNamesToCheck []string, unad } for _, repoName := range repoNamesToCheck { if !repoNames.Contains(repoName) { - unadopted.add(filepath.Join(userName, repoName)) + unadopted.add(path.Join(userName, repoName)) // These are not used as filepaths - but as reponames - therefore use path.Join not filepath.Join } } return nil @@ -292,7 +293,7 @@ func ListUnadoptedRepositories(query string, opts *db.ListOptions) ([]string, in var repoNamesToCheck []string start := (opts.Page - 1) * opts.PageSize - unadopted := &unadoptedRrepositories{ + unadopted := &unadoptedRepositories{ repositories: make([]string, 0, opts.PageSize), start: start, end: start + opts.PageSize, diff --git a/services/repository/adopt_test.go b/services/repository/adopt_test.go index 685bfe9bc4824..b450005f344bc 100644 --- a/services/repository/adopt_test.go +++ b/services/repository/adopt_test.go @@ -19,7 +19,7 @@ import ( func TestCheckUnadoptedRepositories_Add(t *testing.T) { start := 10 end := 20 - unadopted := &unadoptedRrepositories{ + unadopted := &unadoptedRepositories{ start: start, end: end, index: 0, @@ -39,7 +39,7 @@ func TestCheckUnadoptedRepositories(t *testing.T) { // // Non existent user // - unadopted := &unadoptedRrepositories{start: 0, end: 100} + unadopted := &unadoptedRepositories{start: 0, end: 100} err := checkUnadoptedRepositories("notauser", []string{"repo"}, unadopted) assert.NoError(t, err) assert.Equal(t, 0, len(unadopted.repositories)) @@ -50,14 +50,14 @@ func TestCheckUnadoptedRepositories(t *testing.T) { userName := "user2" repoName := "repo2" unadoptedRepoName := "unadopted" - unadopted = &unadoptedRrepositories{start: 0, end: 100} + unadopted = &unadoptedRepositories{start: 0, end: 100} err = checkUnadoptedRepositories(userName, []string{repoName, unadoptedRepoName}, unadopted) assert.NoError(t, err) assert.Equal(t, []string{path.Join(userName, unadoptedRepoName)}, unadopted.repositories) // // Existing (adopted) repository is not returned // - unadopted = &unadoptedRrepositories{start: 0, end: 100} + unadopted = &unadoptedRepositories{start: 0, end: 100} err = checkUnadoptedRepositories(userName, []string{repoName}, unadopted) assert.NoError(t, err) assert.Equal(t, 0, len(unadopted.repositories)) diff --git a/services/repository/avatar.go b/services/repository/avatar.go index b80a8fb77588e..1cf9e869c0747 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 db.IterateObjects(ctx, func(repository *repo_model.Repository) error { + return db.Iterate(ctx, nil, func(ctx context.Context, 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/check.go b/services/repository/check.go index 5529a61b396f4..5725f540b0cca 100644 --- a/services/repository/check.go +++ b/services/repository/check.go @@ -29,10 +29,8 @@ func GitFsck(ctx context.Context, timeout time.Duration, args []git.CmdArg) erro if err := db.Iterate( ctx, - new(repo_model.Repository), builder.Expr("id>0 AND is_fsck_enabled=?", true), - func(idx int, bean interface{}) error { - repo := bean.(*repo_model.Repository) + func(ctx context.Context, repo *repo_model.Repository) error { select { case <-ctx.Done(): return db.ErrCancelledf("before fsck of %s", repo.FullName()) @@ -64,10 +62,8 @@ func GitGcRepos(ctx context.Context, timeout time.Duration, args ...git.CmdArg) if err := db.Iterate( ctx, - new(repo_model.Repository), builder.Gt{"id": 0}, - func(idx int, bean interface{}) error { - repo := bean.(*repo_model.Repository) + func(ctx context.Context, repo *repo_model.Repository) error { select { case <-ctx.Done(): return db.ErrCancelledf("before GC of %s", repo.FullName()) @@ -113,10 +109,8 @@ func gatherMissingRepoRecords(ctx context.Context) ([]*repo_model.Repository, er repos := make([]*repo_model.Repository, 0, 10) if err := db.Iterate( ctx, - new(repo_model.Repository), builder.Gt{"id": 0}, - func(idx int, bean interface{}) error { - repo := bean.(*repo_model.Repository) + func(ctx context.Context, repo *repo_model.Repository) error { select { case <-ctx.Done(): return db.ErrCancelledf("during gathering missing repo records before checking %s", repo.FullName()) diff --git a/services/repository/hooks.go b/services/repository/hooks.go index d326cd26b168f..d29384e012486 100644 --- a/services/repository/hooks.go +++ b/services/repository/hooks.go @@ -25,10 +25,8 @@ func SyncRepositoryHooks(ctx context.Context) error { if err := db.Iterate( ctx, - new(repo_model.Repository), builder.Gt{"id": 0}, - func(idx int, bean interface{}) error { - repo := bean.(*repo_model.Repository) + func(ctx context.Context, repo *repo_model.Repository) error { select { case <-ctx.Done(): return db.ErrCancelledf("before sync repository hooks for %s", repo.FullName()) diff --git a/web_src/js/markup/mermaid.js b/web_src/js/markup/mermaid.js index 62de9a3aae053..984946045d4f0 100644 --- a/web_src/js/markup/mermaid.js +++ b/web_src/js/markup/mermaid.js @@ -2,6 +2,7 @@ import {isDarkTheme} from '../utils.js'; const {mermaidMaxSourceCharacters} = window.config; const iframeCss = ` + :root {color-scheme: normal} body {margin: 0; padding: 0} #mermaid {display: block; margin: 0 auto} `; diff --git a/web_src/less/markup/content.less b/web_src/less/markup/content.less index 7ee55ea7f800a..80c6267af880c 100644 --- a/web_src/less/markup/content.less +++ b/web_src/less/markup/content.less @@ -537,6 +537,7 @@ width: 100%; height: var(--height-loading); // actual height is set in JS after loading overflow: hidden; + color-scheme: normal; // match the value inside the iframe to allow it to become transparent } .markup-block-error {