Skip to content

Commit 95818ad

Browse files
wxiaoguangdelvh
andauthored
A tool to help to backport locales, changes source strings to fix other broken translations (#23633)
It use old en-US locales as reference, fill the old other locales with new locales. ---- ## More broken translations Many translations are still broken. The reason is: at the last time restoring the ini to crowdin, many semicolon are treated as comments. Two kinds of broken strings: ### Some translations can be re-translated <details> ``` skipping options/locale/locale_si-LK.ini org teams.add_nonexistent_repo skipping options/locale/locale_tr-TR.ini repo commits.search.tooltip skipping options/locale/locale_es-ES.ini repo settings.trust_model.committer.desc skipping options/locale/locale_es-ES.ini admin dashboard.new_version_hint skipping options/locale/locale_pt-PT.ini org teams.add_nonexistent_repo skipping options/locale/locale_hu-HU.ini install require_sign_in_view_popup skipping options/locale/locale_hu-HU.ini repo migrate.invalid_local_path skipping options/locale/locale_id-ID.ini repo migrate.invalid_local_path skipping options/locale/locale_id-ID.ini org teams.add_nonexistent_repo skipping options/locale/locale_de-DE.ini repo settings.protect_protected_file_patterns_desc ``` </details> So this PR also does some small changes on them, to trigger the re-translation. ### The `locale_el-GR.ini` contains many broken tranlsations I guess we should reset them from crowdin side, then translators can re-translate them. ---- Update: in latest main, the strings have been fixed. ## TODO Update: the el-GR translators have done great job and fixes these broken translations. <details> Merge this PR ASAP and upload `locale_el-GR.ini` to crowdin to remove broken strings. Out-dated, fixed in main. ![image](https://user-images.githubusercontent.com/2114189/226954531-36e14527-278a-41a1-8ddb-2b2b27bfc746.png) </details> --------- Co-authored-by: delvh <dev.lh@web.de>
1 parent 378d6b8 commit 95818ad

File tree

2 files changed

+107
-19
lines changed

2 files changed

+107
-19
lines changed

build/backport-locales.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//go:build ignore
2+
3+
package main
4+
5+
import (
6+
"fmt"
7+
"os"
8+
"os/exec"
9+
"path/filepath"
10+
"strings"
11+
12+
"gopkg.in/ini.v1"
13+
)
14+
15+
func main() {
16+
if len(os.Args) != 2 {
17+
println("usage: backport-locales <to-ref>")
18+
println("eg: backport-locales release/v1.19")
19+
os.Exit(1)
20+
}
21+
22+
ini.PrettyFormat = false
23+
mustNoErr := func(err error) {
24+
if err != nil {
25+
panic(err)
26+
}
27+
}
28+
collectInis := func(ref string) map[string]*ini.File {
29+
inis := map[string]*ini.File{}
30+
err := filepath.WalkDir("options/locale", func(path string, d os.DirEntry, err error) error {
31+
if err != nil {
32+
return err
33+
}
34+
if d.IsDir() || !strings.HasSuffix(d.Name(), ".ini") {
35+
return nil
36+
}
37+
cfg, err := ini.LoadSources(ini.LoadOptions{
38+
IgnoreInlineComment: true,
39+
UnescapeValueCommentSymbols: true,
40+
}, path)
41+
mustNoErr(err)
42+
inis[path] = cfg
43+
fmt.Printf("collecting: %s @ %s\n", path, ref)
44+
return nil
45+
})
46+
mustNoErr(err)
47+
return inis
48+
}
49+
50+
// collect new locales from current working directory
51+
inisNew := collectInis("HEAD")
52+
53+
// switch to the target ref, and collect the old locales
54+
cmd := exec.Command("git", "checkout", os.Args[1])
55+
cmd.Stdout = os.Stdout
56+
cmd.Stderr = os.Stderr
57+
mustNoErr(cmd.Run())
58+
inisOld := collectInis(os.Args[1])
59+
60+
// use old en-US as the base, and copy the new translations to the old locales
61+
enUsOld := inisOld["options/locale/locale_en-US.ini"]
62+
for path, iniOld := range inisOld {
63+
if iniOld == enUsOld {
64+
continue
65+
}
66+
iniNew := inisNew[path]
67+
if iniNew == nil {
68+
continue
69+
}
70+
for _, secEnUS := range enUsOld.Sections() {
71+
secOld := iniOld.Section(secEnUS.Name())
72+
secNew := iniNew.Section(secEnUS.Name())
73+
for _, keyEnUs := range secEnUS.Keys() {
74+
if secNew.HasKey(keyEnUs.Name()) {
75+
oldStr := secOld.Key(keyEnUs.Name()).String()
76+
newStr := secNew.Key(keyEnUs.Name()).String()
77+
// A bug: many of new translations with ";" are broken in Crowdin (due to last messy restoring)
78+
// As the broken strings are gradually fixed, this workaround check could be removed (in a few months?)
79+
if strings.Contains(oldStr, ";") && !strings.Contains(newStr, ";") {
80+
println("skip potential broken string", path, secEnUS.Name(), keyEnUs.Name())
81+
continue
82+
}
83+
secOld.Key(keyEnUs.Name()).SetValue(newStr)
84+
}
85+
}
86+
}
87+
mustNoErr(iniOld.SaveTo(path))
88+
}
89+
}

options/locale/locale_en-US.ini

+18-19
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ openid_signup_popup = Enable OpenID-based user self-registration.
219219
enable_captcha = Enable registration CAPTCHA
220220
enable_captcha_popup = Require a CAPTCHA for user self-registration.
221221
require_sign_in_view = Require Sign-In to View Pages
222-
require_sign_in_view_popup = Limit page access to signed-in users. Visitors will only see the 'sign in' and registration pages.
222+
require_sign_in_view_popup = Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.
223223
admin_setting_desc = Creating an administrator account is optional. The first registered user will automatically become an administrator.
224224
admin_title = Administrator Account Settings
225225
admin_name = Administrator Username
@@ -249,7 +249,7 @@ no_reply_address = Hidden Email Domain
249249
no_reply_address_helper = Domain name for users with a hidden email address. For example, the username 'joe' will be logged in Git as 'joe@noreply.example.org' if the hidden email domain is set to 'noreply.example.org'.
250250
password_algorithm = Password Hash Algorithm
251251
invalid_password_algorithm = Invalid password hash algorithm
252-
password_algorithm_helper = Set the password hashing algorithm. Algorithms have differing requirements and strength. `argon2` whilst having good characteristics uses a lot of memory and may be inappropriate for small systems.
252+
password_algorithm_helper = Set the password hashing algorithm. Algorithms have differing requirements and strength. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.
253253
enable_update_checker = Enable Update Checker
254254
enable_update_checker_helper = Checks for new version releases periodically by connecting to gitea.io.
255255

@@ -521,14 +521,14 @@ invalid_ssh_key = Cannot verify your SSH key: %s
521521
invalid_gpg_key = Cannot verify your GPG key: %s
522522
invalid_ssh_principal = Invalid principal: %s
523523
must_use_public_key = The key you provided is a private key. Please do not upload your private key anywhere. Use your public key instead.
524-
unable_verify_ssh_key = "Cannot verify the SSH key; double-check it for mistakes."
524+
unable_verify_ssh_key = "Cannot verify the SSH key, double-check it for mistakes."
525525
auth_failed = Authentication failed: %v
526526

527-
still_own_repo = "Your account owns one or more repositories; delete or transfer them first."
528-
still_has_org = "Your account is a member of one or more organizations; leave them first."
529-
still_own_packages = "Your account owns one or more packages; delete them first."
530-
org_still_own_repo = "This organization still owns one or more repositories; delete or transfer them first."
531-
org_still_own_packages = "This organization still owns one or more packages; delete them first."
527+
still_own_repo = "Your account owns one or more repositories, delete or transfer them first."
528+
still_has_org = "Your account is a member of one or more organizations, leave them first."
529+
still_own_packages = "Your account owns one or more packages, delete them first."
530+
org_still_own_repo = "This organization still owns one or more repositories, delete or transfer them first."
531+
org_still_own_packages = "This organization still owns one or more packages, delete them first."
532532

533533
target_branch_not_exist = Target branch does not exist.
534534

@@ -993,7 +993,7 @@ migrate.github_token_desc = You can put one or more tokens with comma separated
993993
migrate.clone_local_path = or a local server path
994994
migrate.permission_denied = You are not allowed to import local repositories.
995995
migrate.permission_denied_blocked = You cannot import from disallowed hosts, please ask the admin to check ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS settings.
996-
migrate.invalid_local_path = "The local path is invalid. It does not exist or is not a directory."
996+
migrate.invalid_local_path = "The local path is invalid. It doesn't exist or is not a directory."
997997
migrate.invalid_lfs_endpoint = The LFS endpoint is not valid.
998998
migrate.failed = Migration failed: %v
999999
migrate.migrate_items_options = Access Token is required to migrate additional items
@@ -1175,7 +1175,7 @@ commits.commits = Commits
11751175
commits.no_commits = No commits in common. '%s' and '%s' have entirely different histories.
11761176
commits.nothing_to_compare = These branches are equal.
11771177
commits.search = Search commits…
1178-
commits.search.tooltip = You can prefix keywords with "author:", "committer:", "after:", or "before:", e.g. "revert author:Alice before:2019-04-01".
1178+
commits.search.tooltip = You can prefix keywords with "author:", "committer:", "after:", or "before:", e.g. "revert author:Alice before:2019-01-13".
11791179
commits.find = Search
11801180
commits.search_all = All Branches
11811181
commits.author = Author
@@ -1635,7 +1635,6 @@ pulls.merge_conflict = Merge Failed: There was a conflict whilst merging. Hint:
16351635
pulls.merge_conflict_summary = Error Message
16361636
pulls.rebase_conflict = Merge Failed: There was a conflict whilst rebasing commit: %[1]s. Hint: Try a different strategy
16371637
pulls.rebase_conflict_summary = Error Message
1638-
; </summary><code>%[2]s<br>%[3]s</code></details>
16391638
pulls.unrelated_histories = Merge Failed: The merge head and base do not share a common history. Hint: Try a different strategy
16401639
pulls.merge_out_of_date = Merge Failed: Whilst generating the merge, the base was updated. Hint: Try again.
16411640
pulls.head_out_of_date = Merge Failed: Whilst generating the merge, the head was updated. Hint: Try again.
@@ -1935,7 +1934,7 @@ settings.trust_model.collaborator.long = Collaborator: Trust signatures by colla
19351934
settings.trust_model.collaborator.desc = Valid signatures by collaborators of this repository will be marked "trusted" - (whether they match the committer or not). Otherwise, valid signatures will be marked "untrusted" if the signature matches the committer and "unmatched" if not.
19361935
settings.trust_model.committer = Committer
19371936
settings.trust_model.committer.long = Committer: Trust signatures that match committers (This matches GitHub and will force Gitea signed commits to have Gitea as the committer)
1938-
settings.trust_model.committer.desc = Valid signatures will only be marked "trusted" if they match the committer, otherwise they will be marked "unmatched". This will force Gitea to be the committer on signed commits with the actual committer marked as Co-authored-by: and Co-committed-by: trailer in the commit. The default Gitea key must match a User in the database.
1937+
settings.trust_model.committer.desc = Valid signatures will only be marked "trusted" if they match the committer, otherwise they will be marked "unmatched". This forces Gitea to be the committer on signed commits with the actual committer marked as Co-authored-by: and Co-committed-by: trailer in the commit. The default Gitea key must match a User in the database.
19391938
settings.trust_model.collaboratorcommitter = Collaborator+Committer
19401939
settings.trust_model.collaboratorcommitter.long = Collaborator+Committer: Trust signatures by collaborators which match the committer
19411940
settings.trust_model.collaboratorcommitter.desc = Valid signatures by collaborators of this repository will be marked "trusted" if they match the committer. Otherwise, valid signatures will be marked "untrusted" if the signature matches the committer and "unmatched" otherwise. This will force Gitea to be marked as the committer on signed commits with the actual committer marked as Co-Authored-By: and Co-Committed-By: trailer in the commit. The default Gitea key must match a User in the database.
@@ -2135,10 +2134,10 @@ settings.dismiss_stale_approvals_desc = When new commits that change the content
21352134
settings.require_signed_commits = Require Signed Commits
21362135
settings.require_signed_commits_desc = Reject pushes to this branch if they are unsigned or unverifiable.
21372136
settings.protect_branch_name_pattern = Protected Branch Name Pattern
2138-
settings.protect_protected_file_patterns = Protected file patterns (separated using semicolon '\;'):
2139-
settings.protect_protected_file_patterns_desc = Protected files that are not allowed to be changed directly even if user has rights to add, edit, or delete files in this branch. Multiple patterns can be separated using semicolon ('\;'). See <a href="https://pkg.go.dev/github.com/gobwas/glob#Compile">github.com/gobwas/glob</a> documentation for pattern syntax. Examples: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.
2140-
settings.protect_unprotected_file_patterns = Unprotected file patterns (separated using semicolon '\;'):
2141-
settings.protect_unprotected_file_patterns_desc = Unprotected files that are allowed to be changed directly if user has write access, bypassing push restriction. Multiple patterns can be separated using semicolon ('\;'). See <a href="https://pkg.go.dev/github.com/gobwas/glob#Compile">github.com/gobwas/glob</a> documentation for pattern syntax. Examples: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.
2137+
settings.protect_protected_file_patterns = `Protected file patterns (separated using semicolon ';'):`
2138+
settings.protect_protected_file_patterns_desc = `Protected files are not allowed to be changed directly even if user has rights to add, edit, or delete files in this branch. Multiple patterns can be separated using semicolon (';'). See <a href="https://pkg.go.dev/github.com/gobwas/glob#Compile">github.com/gobwas/glob</a> documentation for pattern syntax. Examples: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.`
2139+
settings.protect_unprotected_file_patterns = `Unprotected file patterns (separated using semicolon ';'):`
2140+
settings.protect_unprotected_file_patterns_desc = `Unprotected files that are allowed to be changed directly if user has write access, bypassing push restriction. Multiple patterns can be separated using semicolon (';'). See <a href="https://pkg.go.dev/github.com/gobwas/glob#Compile">github.com/gobwas/glob</a> documentation for pattern syntax. Examples: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.`
21422141
settings.add_protected_branch = Enable protection
21432142
settings.delete_protected_branch = Disable protection
21442143
settings.update_protect_branch_success = Branch protection for rule '%s' has been updated.
@@ -2481,7 +2480,7 @@ teams.remove_all_repos_title = Remove all team repositories
24812480
teams.remove_all_repos_desc = This will remove all repositories from the team.
24822481
teams.add_all_repos_title = Add all repositories
24832482
teams.add_all_repos_desc = This will add all the organization's repositories to the team.
2484-
teams.add_nonexistent_repo = "The repository you're trying to add does not exist; please create it first."
2483+
teams.add_nonexistent_repo = "The repository you're trying to add doesn't exist, please create it first."
24852484
teams.add_duplicate_users = User is already a team member.
24862485
teams.repos.none = No repositories could be accessed by this team.
24872486
teams.members.none = No members on this team.
@@ -2511,7 +2510,7 @@ first_page = First
25112510
last_page = Last
25122511
total = Total: %d
25132512
2514-
dashboard.new_version_hint = Gitea %s is now available, you are running %s. Check the <a target="_blank" rel="noreferrer" href="https://blog.gitea.io">blog</a> for more details.
2513+
dashboard.new_version_hint = Gitea %s is now available, you are running %s. Check <a target="_blank" rel="noreferrer" href="https://blog.gitea.io">the blog</a> for more details.
25152514
dashboard.statistic = Summary
25162515
dashboard.operations = Maintenance Operations
25172516
dashboard.system_status = System Status
@@ -2631,7 +2630,7 @@ users.still_own_repo = This user still owns one or more repositories. Delete or
26312630
users.still_has_org = This user is a member of an organization. Remove the user from any organizations first.
26322631
users.purge = Purge User
26332632
users.purge_help = Forcibly delete user and any repositories, organizations, and packages owned by the user. All comments will be deleted too.
2634-
users.still_own_packages = This user still owns one or more packages. Delete these packages first.
2633+
users.still_own_packages = This user still owns one or more packages, delete these packages first.
26352634
users.deletion_success = The user account has been deleted.
26362635
users.reset_2fa = Reset 2FA
26372636
users.list_status_filter.menu_text = Filter

0 commit comments

Comments
 (0)