Skip to content

Commit cb8c9d5

Browse files
committed
[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 (cherry picked from commit 9b5b7140480a75edb070d4151f585c20d3a08f64) (cherry picked from commit 6c7b5e322d1dc736f2e2d9725f77f09bbdb5ffa1)
1 parent 9e54952 commit cb8c9d5

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

build/crowdin-to-weblate.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
# Copyright 2024 The Forgejo Authors
3+
# SPDX-License-Identifier: MIT
4+
5+
D=/tmp/crowdin-to-weblate
6+
mkdir -p $D
7+
8+
function checkout() {
9+
if test -d $D/gitea ; then
10+
git -C $D/gitea reset --hard
11+
return
12+
fi
13+
14+
git clone --depth 1 https://github.com/go-gitea/gitea $D/gitea
15+
}
16+
17+
function replace() {
18+
go run build/merge-forgejo-locales.go $D/gitea/options/locale
19+
cp -a $D/gitea/options/locale/* options/locale
20+
}
21+
22+
function run() {
23+
checkout
24+
replace
25+
}
26+
27+
"$@"

build/merge-forgejo-locales.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright 2022 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build ignore
6+
7+
package main
8+
9+
import (
10+
"bufio"
11+
"log"
12+
"os"
13+
"regexp"
14+
"strings"
15+
)
16+
17+
const (
18+
trimPrefix = "gitea_"
19+
sourceFolder = "options/locales/"
20+
)
21+
22+
// returns list of locales, still containing the file extension!
23+
func generate_locale_list() []string {
24+
localeFiles, _ := os.ReadDir(sourceFolder)
25+
locales := []string{}
26+
for _, localeFile := range localeFiles {
27+
if !localeFile.IsDir() && strings.HasPrefix(localeFile.Name(), trimPrefix) {
28+
locales = append(locales, strings.TrimPrefix(localeFile.Name(), trimPrefix))
29+
}
30+
}
31+
return locales
32+
}
33+
34+
// replace all occurrences of Gitea with Forgejo
35+
func renameGiteaForgejo(filename string) []byte {
36+
file, err := os.Open(filename)
37+
if err != nil {
38+
panic(err)
39+
}
40+
41+
replacements := []string{
42+
"Gitea", "Forgejo",
43+
"https://docs.gitea.com/installation/install-from-binary", "https://forgejo.org/download/#installation-from-binary",
44+
"https://github.com/go-gitea/gitea/tree/master/docker", "https://forgejo.org/download/#container-image",
45+
"https://docs.gitea.com/installation/install-from-package", "https://forgejo.org/download",
46+
"https://code.gitea.io/gitea", "https://forgejo.org/download",
47+
"code.gitea.io/gitea", "Forgejo",
48+
`<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>`,
49+
"https://github.com/go-gitea/gitea", "https://codeberg.org/forgejo/forgejo",
50+
"https://blog.gitea.io", "https://forgejo.org/news",
51+
"https://docs.gitea.com/usage/protected-tags", "https://forgejo.org/docs/latest/user/protection/#protected-tags",
52+
"https://docs.gitea.com/usage/webhooks", "https://forgejo.org/docs/latest/user/webhooks/",
53+
}
54+
replacer := strings.NewReplacer(replacements...)
55+
replaced := make(map[string]bool, len(replacements)/2)
56+
count_replaced := func(original string) {
57+
for i := 0; i < len(replacements); i += 2 {
58+
if strings.Contains(original, replacements[i]) {
59+
replaced[replacements[i]] = true
60+
}
61+
}
62+
}
63+
64+
out := make([]byte, 0, 1024)
65+
scanner := bufio.NewScanner(file)
66+
scanner.Split(bufio.ScanLines)
67+
for scanner.Scan() {
68+
line := scanner.Text()
69+
70+
if strings.HasPrefix(line, "license_desc=") {
71+
line = strings.Replace(line, "GitHub", "Forgejo", 1)
72+
}
73+
74+
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
75+
out = append(out, []byte(line+"\n")...)
76+
} else if strings.HasPrefix(line, "settings.web_hook_name_gitea") {
77+
out = append(out, []byte(line+"\n")...)
78+
out = append(out, []byte("settings.web_hook_name_forgejo = Forgejo\n")...)
79+
} else if strings.HasPrefix(line, "migrate.gitea.description") {
80+
re := regexp.MustCompile(`(.*Gitea)`)
81+
out = append(out, []byte(re.ReplaceAllString(line, "${1}/Forgejo")+"\n")...)
82+
} else {
83+
count_replaced(line)
84+
out = append(out, []byte(replacer.Replace(line)+"\n")...)
85+
}
86+
}
87+
file.Close()
88+
if strings.HasSuffix(filename, "gitea_en-US.ini") {
89+
for i := 0; i < len(replacements); i += 2 {
90+
if replaced[replacements[i]] == false {
91+
log.Fatalf("%s was never used to replace something in %s, it is obsolete and must be updated", replacements[i], filename)
92+
}
93+
}
94+
}
95+
return out
96+
}
97+
98+
func main() {
99+
d := os.Args[1]
100+
files, err := os.ReadDir(d)
101+
if err != nil {
102+
log.Fatal(err)
103+
}
104+
105+
for _, f := range files {
106+
p := d + "/" + f.Name()
107+
os.WriteFile(p, renameGiteaForgejo(p), 0o644)
108+
}
109+
}

0 commit comments

Comments
 (0)