loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

wxiaoguang
delvh
and committed by
GitHub
95818adb 378d6b84

+107 -19
+89
build/backport-locales.go
··· 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 + }
+18 -19
options/locale/locale_en-US.ini
··· 219 219 enable_captcha = Enable registration CAPTCHA 220 220 enable_captcha_popup = Require a CAPTCHA for user self-registration. 221 221 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. 223 223 admin_setting_desc = Creating an administrator account is optional. The first registered user will automatically become an administrator. 224 224 admin_title = Administrator Account Settings 225 225 admin_name = Administrator Username ··· 249 249 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'. 250 250 password_algorithm = Password Hash Algorithm 251 251 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. 253 253 enable_update_checker = Enable Update Checker 254 254 enable_update_checker_helper = Checks for new version releases periodically by connecting to gitea.io. 255 255 ··· 521 521 invalid_gpg_key = Cannot verify your GPG key: %s 522 522 invalid_ssh_principal = Invalid principal: %s 523 523 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." 525 525 auth_failed = Authentication failed: %v 526 526 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." 532 532 533 533 target_branch_not_exist = Target branch does not exist. 534 534 ··· 993 993 migrate.clone_local_path = or a local server path 994 994 migrate.permission_denied = You are not allowed to import local repositories. 995 995 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." 997 997 migrate.invalid_lfs_endpoint = The LFS endpoint is not valid. 998 998 migrate.failed = Migration failed: %v 999 999 migrate.migrate_items_options = Access Token is required to migrate additional items ··· 1175 1175 commits.no_commits = No commits in common. '%s' and '%s' have entirely different histories. 1176 1176 commits.nothing_to_compare = These branches are equal. 1177 1177 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". 1179 1179 commits.find = Search 1180 1180 commits.search_all = All Branches 1181 1181 commits.author = Author ··· 1635 1635 pulls.merge_conflict_summary = Error Message 1636 1636 pulls.rebase_conflict = Merge Failed: There was a conflict whilst rebasing commit: %[1]s. Hint: Try a different strategy 1637 1637 pulls.rebase_conflict_summary = Error Message 1638 - ; </summary><code>%[2]s<br>%[3]s</code></details> 1639 1638 pulls.unrelated_histories = Merge Failed: The merge head and base do not share a common history. Hint: Try a different strategy 1640 1639 pulls.merge_out_of_date = Merge Failed: Whilst generating the merge, the base was updated. Hint: Try again. 1641 1640 pulls.head_out_of_date = Merge Failed: Whilst generating the merge, the head was updated. Hint: Try again. ··· 1935 1934 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. 1936 1935 settings.trust_model.committer = Committer 1937 1936 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. 1939 1938 settings.trust_model.collaboratorcommitter = Collaborator+Committer 1940 1939 settings.trust_model.collaboratorcommitter.long = Collaborator+Committer: Trust signatures by collaborators which match the committer 1941 1940 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 2134 settings.require_signed_commits = Require Signed Commits 2136 2135 settings.require_signed_commits_desc = Reject pushes to this branch if they are unsigned or unverifiable. 2137 2136 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>.` 2142 2141 settings.add_protected_branch = Enable protection 2143 2142 settings.delete_protected_branch = Disable protection 2144 2143 settings.update_protect_branch_success = Branch protection for rule '%s' has been updated. ··· 2481 2480 teams.remove_all_repos_desc = This will remove all repositories from the team. 2482 2481 teams.add_all_repos_title = Add all repositories 2483 2482 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." 2485 2484 teams.add_duplicate_users = User is already a team member. 2486 2485 teams.repos.none = No repositories could be accessed by this team. 2487 2486 teams.members.none = No members on this team. ··· 2511 2510 last_page = Last 2512 2511 total = Total: %d 2513 2512 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. 2515 2514 dashboard.statistic = Summary 2516 2515 dashboard.operations = Maintenance Operations 2517 2516 dashboard.system_status = System Status ··· 2631 2630 users.still_has_org = This user is a member of an organization. Remove the user from any organizations first. 2632 2631 users.purge = Purge User 2633 2632 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. 2635 2634 users.deletion_success = The user account has been deleted. 2636 2635 users.reset_2fa = Reset 2FA 2637 2636 users.list_status_filter.menu_text = Filter