[I18n] tooling and process
Before: * Translations were imported from Crowdin via Gitea * New strings were added by Forgejo in feature branches but never translated * The build/merge-forgejo-locales.go script in the forgejo-i18n branch added/replaced Forgejo specific strings in the translated files at build time * Conflicts arising from Gitea changes in locale_en-US.ini were resolved by moving around Forgejo strings Transition: * The build/merge-forgejo-locales.go is run once on the source * The result is commited to the forgejo-development branch After: * Translation are exported and imported from translate.codeberg.org * build/crowdin-to-weblate.sh run is run when rebasing (soft-fork) or cherry-picking (hard-fork) to collect new translations from Crowdin via Gitea * In case of a conflict Forgejo translations are authoritative * In the absence of a conflict Crowdin translations are uploaded to Weblate
This commit is contained in:
parent
77716e7cd4
commit
9b5b714048
2 changed files with 136 additions and 0 deletions
27
build/crowdin-to-weblate.sh
Executable file
27
build/crowdin-to-weblate.sh
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2024 The Forgejo Authors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
D=/tmp/crowdin-to-weblate
|
||||||
|
mkdir -p $D
|
||||||
|
|
||||||
|
function checkout() {
|
||||||
|
if test -d $D/gitea ; then
|
||||||
|
git -C $D/gitea reset --hard
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
git clone --depth 1 https://github.com/go-gitea/gitea $D/gitea
|
||||||
|
}
|
||||||
|
|
||||||
|
function replace() {
|
||||||
|
go run build/merge-forgejo-locales.go $D/gitea/options/locale
|
||||||
|
cp -a $D/gitea/options/locale/* options/locale
|
||||||
|
}
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
checkout
|
||||||
|
replace
|
||||||
|
}
|
||||||
|
|
||||||
|
"$@"
|
109
build/merge-forgejo-locales.go
Normal file
109
build/merge-forgejo-locales.go
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright 2022 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
trimPrefix = "gitea_"
|
||||||
|
sourceFolder = "options/locales/"
|
||||||
|
)
|
||||||
|
|
||||||
|
// returns list of locales, still containing the file extension!
|
||||||
|
func generate_locale_list() []string {
|
||||||
|
localeFiles, _ := os.ReadDir(sourceFolder)
|
||||||
|
locales := []string{}
|
||||||
|
for _, localeFile := range localeFiles {
|
||||||
|
if !localeFile.IsDir() && strings.HasPrefix(localeFile.Name(), trimPrefix) {
|
||||||
|
locales = append(locales, strings.TrimPrefix(localeFile.Name(), trimPrefix))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return locales
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace all occurrences of Gitea with Forgejo
|
||||||
|
func renameGiteaForgejo(filename string) []byte {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
replacements := []string{
|
||||||
|
"Gitea", "Forgejo",
|
||||||
|
"https://docs.gitea.com/installation/install-from-binary", "https://forgejo.org/download/#installation-from-binary",
|
||||||
|
"https://github.com/go-gitea/gitea/tree/master/docker", "https://forgejo.org/download/#container-image",
|
||||||
|
"https://docs.gitea.com/installation/install-from-package", "https://forgejo.org/download",
|
||||||
|
"https://code.gitea.io/gitea", "https://forgejo.org/download",
|
||||||
|
"code.gitea.io/gitea", "Forgejo",
|
||||||
|
`<a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHub</a>`, `<a href="https://codeberg.org/forgejo/forgejo/issues" target="_blank">Codeberg</a>`,
|
||||||
|
"https://github.com/go-gitea/gitea", "https://codeberg.org/forgejo/forgejo",
|
||||||
|
"https://blog.gitea.io", "https://forgejo.org/news",
|
||||||
|
"https://docs.gitea.com/usage/protected-tags", "https://forgejo.org/docs/latest/user/protection/#protected-tags",
|
||||||
|
"https://docs.gitea.com/usage/webhooks", "https://forgejo.org/docs/latest/user/webhooks/",
|
||||||
|
}
|
||||||
|
replacer := strings.NewReplacer(replacements...)
|
||||||
|
replaced := make(map[string]bool, len(replacements)/2)
|
||||||
|
count_replaced := func(original string) {
|
||||||
|
for i := 0; i < len(replacements); i += 2 {
|
||||||
|
if strings.Contains(original, replacements[i]) {
|
||||||
|
replaced[replacements[i]] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]byte, 0, 1024)
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
scanner.Split(bufio.ScanLines)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "license_desc=") {
|
||||||
|
line = strings.Replace(line, "GitHub", "Forgejo", 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
|
||||||
|
out = append(out, []byte(line+"\n")...)
|
||||||
|
} else if strings.HasPrefix(line, "settings.web_hook_name_gitea") {
|
||||||
|
out = append(out, []byte(line+"\n")...)
|
||||||
|
out = append(out, []byte("settings.web_hook_name_forgejo = Forgejo\n")...)
|
||||||
|
} else if strings.HasPrefix(line, "migrate.gitea.description") {
|
||||||
|
re := regexp.MustCompile(`(.*Gitea)`)
|
||||||
|
out = append(out, []byte(re.ReplaceAllString(line, "${1}/Forgejo")+"\n")...)
|
||||||
|
} else {
|
||||||
|
count_replaced(line)
|
||||||
|
out = append(out, []byte(replacer.Replace(line)+"\n")...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.Close()
|
||||||
|
if strings.HasSuffix(filename, "gitea_en-US.ini") {
|
||||||
|
for i := 0; i < len(replacements); i += 2 {
|
||||||
|
if replaced[replacements[i]] == false {
|
||||||
|
log.Fatalf("%s was never used to replace something in %s, it is obsolete and must be updated", replacements[i], filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
d := os.Args[1]
|
||||||
|
files, err := os.ReadDir(d)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
p := d + "/" + f.Name()
|
||||||
|
os.WriteFile(p, renameGiteaForgejo(p), 0o644)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue