From 4e6e1f524a6eb1a2e2ad5c7bf92e51b4eeb19f5d Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Thu, 27 Feb 2025 11:18:13 +0300 Subject: [PATCH 1/3] chore: make the application more internationalized --- Makefile | 1 + README.md | 2 +- .../coverage-badge.svg | 0 assets/i18n-ru-badge.svg | 18 ++++ internal/cliutils/template.go | 102 ++++++++++++++++++ internal/translations/default.pot | 62 ++++++++++- internal/translations/po/ru/default.po | 68 ++++++++++-- main.go | 6 ++ scripts/coverage-badge.sh | 2 +- scripts/i18n-badge.sh | 74 +++++++++++++ 10 files changed, 320 insertions(+), 15 deletions(-) rename coverage-badge.svg => assets/coverage-badge.svg (100%) create mode 100644 assets/i18n-ru-badge.svg create mode 100644 internal/cliutils/template.go create mode 100755 scripts/i18n-badge.sh diff --git a/Makefile b/Makefile index 157b882..6af9352 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,7 @@ i18n: $(XGOTEXT_BIN) --output ./internal/translations/default.pot msguniq --use-first -o ./internal/translations/default.pot ./internal/translations/default.pot msgmerge --backup=off -U ./internal/translations/po/ru/default.po ./internal/translations/default.pot + bash scripts/i18n-badge.sh test-coverage: go test ./... -v -coverpkg=./... -coverprofile=coverage.out diff --git a/README.md b/README.md index 6ae4871..1378b28 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

-[![Go Report Card](https://goreportcard.com/badge/gitea.plemya-x.ru/Plemya-x/ALR)](https://goreportcard.com/report/gitea.plemya-x.ru/Plemya-x/ALR) ![Test coverage](./coverage-badge.svg) +[![Go Report Card](https://goreportcard.com/badge/gitea.plemya-x.ru/Plemya-x/ALR)](https://goreportcard.com/report/gitea.plemya-x.ru/Plemya-x/ALR) ![Test coverage](./assets/coverage-badge.svg) ![ru translate](./assets/i18n-ru-badge.svg) # ALR (Any Linux Repository) diff --git a/coverage-badge.svg b/assets/coverage-badge.svg similarity index 100% rename from coverage-badge.svg rename to assets/coverage-badge.svg diff --git a/assets/i18n-ru-badge.svg b/assets/i18n-ru-badge.svg new file mode 100644 index 0000000..6deb013 --- /dev/null +++ b/assets/i18n-ru-badge.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + ru translate + ru translate + 79.00% + 79.00% + + diff --git a/internal/cliutils/template.go b/internal/cliutils/template.go new file mode 100644 index 0000000..101a461 --- /dev/null +++ b/internal/cliutils/template.go @@ -0,0 +1,102 @@ +// ALR - Any Linux Repository +// Copyright (C) 2025 Евгений Храмов +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package cliutils + +import ( + "fmt" + + "github.com/leonelquinteros/gotext" +) + +// Templates are based on https://github.com/urfave/cli/blob/3b17080d70a630feadadd23dd036cad121dd9a50/template.go + +//nolint:unused +var ( + helpNameTemplate = `{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}` + descriptionTemplate = `{{wrap .Description 3}}` + authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: + {{range $index, $author := .Authors}}{{if $index}} + {{end}}{{$author}}{{end}}` + visibleCommandTemplate = `{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}} + {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}` + visibleCommandCategoryTemplate = `{{range .VisibleCategories}}{{if .Name}} + {{.Name}}:{{range .VisibleCommands}} + {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{template "visibleCommandTemplate" .}}{{end}}{{end}}` + visibleFlagCategoryTemplate = `{{range .VisibleFlagCategories}} + {{if .Name}}{{.Name}} + + {{end}}{{$flglen := len .Flags}}{{range $i, $e := .Flags}}{{if eq (subtract $flglen $i) 1}}{{$e}} +{{else}}{{$e}} + {{end}}{{end}}{{end}}` + visibleFlagTemplate = `{{range $i, $e := .VisibleFlags}} + {{wrap $e.String 6}}{{end}}` + copyrightTemplate = `{{wrap .Copyright 3}}` +) + +func GetAppCliTemplate() string { + return fmt.Sprintf(`%s: + {{template "helpNameTemplate" .}} + +%s: + {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} + +%s: + {{.Version}}{{end}}{{end}}{{if .Description}} + +%s: + {{template "descriptionTemplate" .}}{{end}} +{{- if len .Authors}} + +%s{{template "authorsTemplate" .}}{{end}}{{if .VisibleCommands}} + +%s:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}} + +%s:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} + +%s:{{template "visibleFlagTemplate" .}}{{end}}{{if .Copyright}} + +%s: + {{template "copyrightTemplate" .}}{{end}} +`, gotext.Get("NAME"), gotext.Get("USAGE"), gotext.Get("VERSION"), gotext.Get("DESCRIPTION"), gotext.Get("AUTHOR"), gotext.Get("COMMANDS"), gotext.Get("GLOBAL OPTIONS"), gotext.Get("GLOBAL OPTIONS"), gotext.Get("COPYRIGHT")) +} + +func GetCommandHelpTemplate() string { + return fmt.Sprintf(`%s: + {{template "helpNameTemplate" .}} + +%s: + {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [%s]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[%s]{{end}}{{end}}{{if .Category}} + +%s: + {{.Category}}{{end}}{{if .Description}} + +%s: + {{template "descriptionTemplate" .}}{{end}}{{if .VisibleFlagCategories}} + +%s:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} + +%s:{{template "visibleFlagTemplate" .}}{{end}} +`, gotext.Get("NAME"), + gotext.Get("USAGE"), + gotext.Get("command options"), + gotext.Get("arguments..."), + gotext.Get("CATEGORY"), + gotext.Get("DESCRIPTION"), + gotext.Get("OPTIONS"), + gotext.Get("OPTIONS"), + ) +} diff --git a/internal/translations/default.pot b/internal/translations/default.pot index 6739f13..c132ac0 100644 --- a/internal/translations/default.pot +++ b/internal/translations/default.pot @@ -194,6 +194,54 @@ msgstr "" msgid "Choose which optional package(s) to install" msgstr "" +#: internal/cliutils/template.go:74 internal/cliutils/template.go:93 +msgid "NAME" +msgstr "" + +#: internal/cliutils/template.go:74 internal/cliutils/template.go:94 +msgid "USAGE" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "VERSION" +msgstr "" + +#: internal/cliutils/template.go:74 internal/cliutils/template.go:98 +msgid "DESCRIPTION" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "AUTHOR" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "COMMANDS" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "GLOBAL OPTIONS" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "COPYRIGHT" +msgstr "" + +#: internal/cliutils/template.go:95 +msgid "command options" +msgstr "" + +#: internal/cliutils/template.go:96 +msgid "arguments..." +msgstr "" + +#: internal/cliutils/template.go:97 +msgid "CATEGORY" +msgstr "" + +#: internal/cliutils/template.go:99 internal/cliutils/template.go:100 +msgid "OPTIONS" +msgstr "" + #: internal/config/config.go:59 msgid "Error opening config file, using defaults" msgstr "" @@ -275,25 +323,29 @@ msgstr "" msgid "Error listing installed packages" msgstr "" -#: main.go:44 +#: main.go:45 msgid "Print the current ALR version and exit" msgstr "" -#: main.go:60 +#: main.go:61 msgid "Arguments to be passed on to the package manager" msgstr "" -#: main.go:66 +#: main.go:67 msgid "Enable interactive questions and prompts" msgstr "" -#: main.go:91 +#: main.go:92 msgid "" "Running ALR as root is forbidden as it may cause catastrophic damage to your " "system" msgstr "" -#: main.go:123 +#: main.go:125 +msgid "Show help" +msgstr "" + +#: main.go:129 msgid "Error while running app" msgstr "" diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po index cb9e07a..0c95890 100644 --- a/internal/translations/po/ru/default.po +++ b/internal/translations/po/ru/default.po @@ -1,12 +1,12 @@ # -# Maxim Slipenko , 2025. # x1z53 , 2025. +# Maxim Slipenko , 2025. # msgid "" msgstr "" "Project-Id-Version: unnamed project\n" -"PO-Revision-Date: 2025-01-24 21:20+0300\n" -"Last-Translator: x1z53 \n" +"PO-Revision-Date: 2025-02-27 10:10+0300\n" +"Last-Translator: Maxim Slipenko \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -202,6 +202,54 @@ msgstr "Выберите, какой пакет использовать для msgid "Choose which optional package(s) to install" msgstr "Выберите, какой дополнительный пакет(ы) следует установить" +#: internal/cliutils/template.go:74 internal/cliutils/template.go:93 +msgid "NAME" +msgstr "НАЗВАНИЕ" + +#: internal/cliutils/template.go:74 internal/cliutils/template.go:94 +msgid "USAGE" +msgstr "ИСПОЛЬЗОВАНИЕ" + +#: internal/cliutils/template.go:74 +msgid "VERSION" +msgstr "ВЕРСИЯ" + +#: internal/cliutils/template.go:74 internal/cliutils/template.go:98 +msgid "DESCRIPTION" +msgstr "ОПИСАНИЕ" + +#: internal/cliutils/template.go:74 +msgid "AUTHOR" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "COMMANDS" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "GLOBAL OPTIONS" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "COPYRIGHT" +msgstr "" + +#: internal/cliutils/template.go:95 +msgid "command options" +msgstr "" + +#: internal/cliutils/template.go:96 +msgid "arguments..." +msgstr "" + +#: internal/cliutils/template.go:97 +msgid "CATEGORY" +msgstr "" + +#: internal/cliutils/template.go:99 internal/cliutils/template.go:100 +msgid "OPTIONS" +msgstr "" + #: internal/config/config.go:59 msgid "Error opening config file, using defaults" msgstr "" @@ -288,19 +336,19 @@ msgstr "Список пакетов репозитория ALR" msgid "Error listing installed packages" msgstr "Ошибка при составлении списка установленных пакетов" -#: main.go:44 +#: main.go:45 msgid "Print the current ALR version and exit" msgstr "Показать текущую версию ALR и выйти" -#: main.go:60 +#: main.go:61 msgid "Arguments to be passed on to the package manager" msgstr "Аргументы, которые будут переданы менеджеру пакетов" -#: main.go:66 +#: main.go:67 msgid "Enable interactive questions and prompts" msgstr "Включение интерактивных вопросов и запросов" -#: main.go:91 +#: main.go:92 msgid "" "Running ALR as root is forbidden as it may cause catastrophic damage to your " "system" @@ -308,7 +356,11 @@ msgstr "" "Запуск ALR от имени root запрещён, так как это может привести к " "катастрофическому повреждению вашей системы" -#: main.go:123 +#: main.go:125 +msgid "Show help" +msgstr "" + +#: main.go:129 msgid "Error while running app" msgstr "Ошибка при запуске приложения" diff --git a/main.go b/main.go index 2bb286a..1d4ce30 100644 --- a/main.go +++ b/main.go @@ -31,6 +31,7 @@ import ( "github.com/mattn/go-isatty" "github.com/urfave/cli/v2" + "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/translations" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager" @@ -118,6 +119,11 @@ func main() { ctx, cancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM) defer cancel() + // Make the application more internationalized + cli.AppHelpTemplate = cliutils.GetAppCliTemplate() + cli.CommandHelpTemplate = cliutils.GetCommandHelpTemplate() + cli.HelpFlag.(*cli.BoolFlag).Usage = gotext.Get("Show help") + err := app.RunContext(ctx, os.Args) if err != nil { slog.Error(gotext.Get("Error while running app"), "err", err) diff --git a/scripts/coverage-badge.sh b/scripts/coverage-badge.sh index 935aa0c..b6c575d 100755 --- a/scripts/coverage-badge.sh +++ b/scripts/coverage-badge.sh @@ -25,7 +25,7 @@ elif (( $(echo "$COVERAGE < 80" | bc -l) )); then COLOR="#dfb317" fi -cat < coverage-badge.svg +cat < assets/coverage-badge.svg diff --git a/scripts/i18n-badge.sh b/scripts/i18n-badge.sh new file mode 100755 index 0000000..7282281 --- /dev/null +++ b/scripts/i18n-badge.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# ALR - Any Linux Repository +# Copyright (C) 2025 Евгений Храмов +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +TRANSLATIONS_DIR="internal/translations/po" + +if [ ! -d "$TRANSLATIONS_DIR" ]; then + echo "Ошибка: директория '$TRANSLATIONS_DIR' не найдена" + exit 1 +fi + +declare -A TOTAL_STRINGS_MAP +declare -A TRANSLATED_STRINGS_MAP + +for PO_FILE in $(find "$TRANSLATIONS_DIR" -type f -name "*.po"); do + LANG_DIR=$(dirname "$PO_FILE") + LANG=$(basename "$LANG_DIR") + + TOTAL_STRINGS=$(grep -c "^msgid " "$PO_FILE") + TRANSLATED_STRINGS=$(grep -c "^msgstr \"[^\"]\+\"" "$PO_FILE") + + TOTAL_STRINGS_MAP[$LANG]=$((TOTAL_STRINGS_MAP[$LANG] + TOTAL_STRINGS)) + TRANSLATED_STRINGS_MAP[$LANG]=$((TRANSLATED_STRINGS_MAP[$LANG] + TRANSLATED_STRINGS)) +done + +for LANG in "${!TOTAL_STRINGS_MAP[@]}"; do + TOTAL=${TOTAL_STRINGS_MAP[$LANG]} + TRANSLATED=${TRANSLATED_STRINGS_MAP[$LANG]} + if [ "$TOTAL" -eq 0 ]; then + PERCENTAGE="0.00" + else + PERCENTAGE=$(echo "scale=2; ($TRANSLATED / $TOTAL) * 100" | bc) + fi + COLOR="#4c1" + if (( $(echo "$PERCENTAGE < 50" | bc -l) )); then + COLOR="#e05d44" + elif (( $(echo "$PERCENTAGE < 80" | bc -l) )); then + COLOR="#dfb317" + fi +cat < assets/i18n-$LANG-badge.svg + + + + + + + + + + + + + $LANG translate + $LANG translate + ${PERCENTAGE}% + ${PERCENTAGE}% + + +EOF +done From dcac0b9ee5aa73705536abc944be21b91a9945c4 Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Thu, 27 Feb 2025 11:43:20 +0300 Subject: [PATCH 2/3] i18n: translate all strings --- assets/i18n-ru-badge.svg | 6 +-- install.go | 2 +- internal/translations/po/ru/default.po | 51 ++++++++++++-------------- scripts/i18n-badge.sh | 20 +++++++--- 4 files changed, 42 insertions(+), 37 deletions(-) diff --git a/assets/i18n-ru-badge.svg b/assets/i18n-ru-badge.svg index 6deb013..2a5d418 100644 --- a/assets/i18n-ru-badge.svg +++ b/assets/i18n-ru-badge.svg @@ -6,13 +6,13 @@ - + ru translate ru translate - 79.00% - 79.00% + 100.00% + 100.00% diff --git a/install.go b/install.go index 046c170..ab59e40 100644 --- a/install.go +++ b/install.go @@ -46,7 +46,7 @@ func InstallCmd() *cli.Command { &cli.BoolFlag{ Name: "clean", Aliases: []string{"c"}, - Usage: "Build package from scratch even if there's an already built package available", + Usage: gotext.Get("Build package from scratch even if there's an already built package available"), }, }, Action: func(c *cli.Context) error { diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po index 0c95890..f9179c3 100644 --- a/internal/translations/po/ru/default.po +++ b/internal/translations/po/ru/default.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: unnamed project\n" -"PO-Revision-Date: 2025-02-27 10:10+0300\n" +"PO-Revision-Date: 2025-02-27 11:33+0300\n" "Last-Translator: Maxim Slipenko \n" "Language-Team: Russian\n" "Language: ru\n" @@ -26,7 +26,7 @@ msgstr "Путь к скрипту сборки" #: build.go:55 msgid "Specify package in script (for multi package script only)" -msgstr "" +msgstr "Укажите пакет в скрипте (только для многопакетного скрипта)" #: build.go:60 msgid "Name of the package to build and its repo (example: default/go-bin)" @@ -43,7 +43,7 @@ msgstr "Ошибка инициализации базы данных" #: build.go:105 msgid "Package not found" -msgstr "" +msgstr "Пакет не найден" #: build.go:123 msgid "Error pulling repositories" @@ -54,7 +54,6 @@ msgid "Unable to detect a supported package manager on the system" msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе" #: build.go:137 -#, fuzzy msgid "Error parsing os release" msgstr "Ошибка при разборе файла выпуска операционной системы" @@ -220,35 +219,35 @@ msgstr "ОПИСАНИЕ" #: internal/cliutils/template.go:74 msgid "AUTHOR" -msgstr "" +msgstr "АВТОР" #: internal/cliutils/template.go:74 msgid "COMMANDS" -msgstr "" +msgstr "КОМАНДЫ" #: internal/cliutils/template.go:74 msgid "GLOBAL OPTIONS" -msgstr "" +msgstr "ГЛОБАЛЬНЫЕ ОПЦИИ" #: internal/cliutils/template.go:74 msgid "COPYRIGHT" -msgstr "" +msgstr "АВТОРСКОЕ ПРАВО" #: internal/cliutils/template.go:95 msgid "command options" -msgstr "" +msgstr "опции команды" #: internal/cliutils/template.go:96 msgid "arguments..." -msgstr "" +msgstr "аргументы..." #: internal/cliutils/template.go:97 msgid "CATEGORY" -msgstr "" +msgstr "КАТЕГОРИЯ" #: internal/cliutils/template.go:99 internal/cliutils/template.go:100 msgid "OPTIONS" -msgstr "" +msgstr "ПАРАМЕТРЫ" #: internal/config/config.go:59 msgid "Error opening config file, using defaults" @@ -318,11 +317,11 @@ msgstr "Скачивание источника" #: internal/dl/progress_tui.go:100 msgid "%s: done!\n" -msgstr "" +msgstr "%s: выполнено!\n" #: internal/dl/progress_tui.go:104 msgid "%s %s downloading at %s/s\n" -msgstr "" +msgstr "%s %s загружается — %s/с\n" #: internal/logger/log.go:47 msgid "ERROR" @@ -358,7 +357,7 @@ msgstr "" #: main.go:125 msgid "Show help" -msgstr "" +msgstr "Показать справку" #: main.go:129 msgid "Error while running app" @@ -421,9 +420,8 @@ msgid "Executing build()" msgstr "Исполнение build()" #: pkg/build/build.go:689 pkg/build/build.go:709 -#, fuzzy msgid "Executing %s()" -msgstr "Исполнение files()" +msgstr "Исполнение %s()" #: pkg/build/build.go:768 msgid "Error installing native packages" @@ -521,38 +519,35 @@ msgstr "Скачать все изменённые репозитории" #: search.go:36 msgid "Search packages" -msgstr "" +msgstr "Поиск пакетов" #: search.go:42 msgid "Search by name" -msgstr "" +msgstr "Искать по имени" #: search.go:47 msgid "Search by description" -msgstr "" +msgstr "Искать по описанию" #: search.go:52 -#, fuzzy msgid "Search by repository" -msgstr "Добавить новый репозиторий" +msgstr "Искать по репозиторию" #: search.go:57 msgid "Search by provides" -msgstr "" +msgstr "Иcкать по provides" #: search.go:62 msgid "Format output using a Go template" -msgstr "" +msgstr "Формат выходных данных с использованием шаблона Go" #: search.go:82 search.go:99 -#, fuzzy msgid "Error parsing format template" -msgstr "Ошибка при разборе файла выпуска операционной системы" +msgstr "Ошибка при разборе шаблона" #: search.go:107 -#, fuzzy msgid "Error executing template" -msgstr "Ошибка при получении пакетов" +msgstr "Ошибка при выполнении шаблона" #: upgrade.go:47 msgid "Upgrade all installed packages" diff --git a/scripts/i18n-badge.sh b/scripts/i18n-badge.sh index 7282281..7e452a4 100755 --- a/scripts/i18n-badge.sh +++ b/scripts/i18n-badge.sh @@ -19,7 +19,7 @@ TRANSLATIONS_DIR="internal/translations/po" if [ ! -d "$TRANSLATIONS_DIR" ]; then - echo "Ошибка: директория '$TRANSLATIONS_DIR' не найдена" + echo "Error: directory '$TRANSLATIONS_DIR' not found" exit 1 fi @@ -29,10 +29,20 @@ declare -A TRANSLATED_STRINGS_MAP for PO_FILE in $(find "$TRANSLATIONS_DIR" -type f -name "*.po"); do LANG_DIR=$(dirname "$PO_FILE") LANG=$(basename "$LANG_DIR") - - TOTAL_STRINGS=$(grep -c "^msgid " "$PO_FILE") - TRANSLATED_STRINGS=$(grep -c "^msgstr \"[^\"]\+\"" "$PO_FILE") - + + STATS=$(LC_ALL=C msgfmt --statistics -o /dev/null "$PO_FILE" 2>&1) + + NUMBERS=($(echo "$STATS" | grep -o '[0-9]\+')) + + case ${#NUMBERS[@]} in + 1) TRANSLATED_STRINGS=${NUMBERS[0]}; UNTRANSLATED_STRINGS=0 ;; # all translated + 2) TRANSLATED_STRINGS=${NUMBERS[0]}; UNTRANSLATED_STRINGS=${NUMBERS[1]} ;; # no fuzzy + 3) TRANSLATED_STRINGS=${NUMBERS[0]}; UNTRANSLATED_STRINGS=${NUMBERS[2]} ;; # with fuzzy + *) TRANSLATED_STRINGS=0; UNTRANSLATED_STRINGS=0 ;; + esac + + TOTAL_STRINGS=$((TRANSLATED_STRINGS + UNTRANSLATED_STRINGS)) + TOTAL_STRINGS_MAP[$LANG]=$((TOTAL_STRINGS_MAP[$LANG] + TOTAL_STRINGS)) TRANSLATED_STRINGS_MAP[$LANG]=$((TRANSLATED_STRINGS_MAP[$LANG] + TRANSLATED_STRINGS)) done From 0fa288b8a2de8e652c87f6f1977ad3577bbc8fbf Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Thu, 27 Feb 2025 16:41:18 +0300 Subject: [PATCH 3/3] chore: make the application more internationalized --- internal/cliutils/template.go | 8 +++---- internal/translations/default.pot | 24 ++++++++++++++------- internal/translations/po/ru/default.po | 30 ++++++++++++++++---------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/internal/cliutils/template.go b/internal/cliutils/template.go index 101a461..da8bb2e 100644 --- a/internal/cliutils/template.go +++ b/internal/cliutils/template.go @@ -52,7 +52,7 @@ func GetAppCliTemplate() string { {{template "helpNameTemplate" .}} %s: - {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} + {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[%s]{{end}}{{if .Commands}} %s [%s]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[%s...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} %s: {{.Version}}{{end}}{{end}}{{if .Description}} @@ -71,7 +71,7 @@ func GetAppCliTemplate() string { %s: {{template "copyrightTemplate" .}}{{end}} -`, gotext.Get("NAME"), gotext.Get("USAGE"), gotext.Get("VERSION"), gotext.Get("DESCRIPTION"), gotext.Get("AUTHOR"), gotext.Get("COMMANDS"), gotext.Get("GLOBAL OPTIONS"), gotext.Get("GLOBAL OPTIONS"), gotext.Get("COPYRIGHT")) +`, gotext.Get("NAME"), gotext.Get("USAGE"), gotext.Get("global options"), gotext.Get("command"), gotext.Get("command options"), gotext.Get("arguments"), gotext.Get("VERSION"), gotext.Get("DESCRIPTION"), gotext.Get("AUTHOR"), gotext.Get("COMMANDS"), gotext.Get("GLOBAL OPTIONS"), gotext.Get("GLOBAL OPTIONS"), gotext.Get("COPYRIGHT")) } func GetCommandHelpTemplate() string { @@ -79,7 +79,7 @@ func GetCommandHelpTemplate() string { {{template "helpNameTemplate" .}} %s: - {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [%s]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[%s]{{end}}{{end}}{{if .Category}} + {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [%s]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[%s...]{{end}}{{end}}{{if .Category}} %s: {{.Category}}{{end}}{{if .Description}} @@ -93,7 +93,7 @@ func GetCommandHelpTemplate() string { `, gotext.Get("NAME"), gotext.Get("USAGE"), gotext.Get("command options"), - gotext.Get("arguments..."), + gotext.Get("arguments"), gotext.Get("CATEGORY"), gotext.Get("DESCRIPTION"), gotext.Get("OPTIONS"), diff --git a/internal/translations/default.pot b/internal/translations/default.pot index c132ac0..8e2ee3c 100644 --- a/internal/translations/default.pot +++ b/internal/translations/default.pot @@ -202,6 +202,22 @@ msgstr "" msgid "USAGE" msgstr "" +#: internal/cliutils/template.go:74 +msgid "global options" +msgstr "" + +#: internal/cliutils/template.go:74 +msgid "command" +msgstr "" + +#: internal/cliutils/template.go:74 internal/cliutils/template.go:95 +msgid "command options" +msgstr "" + +#: internal/cliutils/template.go:74 internal/cliutils/template.go:96 +msgid "arguments" +msgstr "" + #: internal/cliutils/template.go:74 msgid "VERSION" msgstr "" @@ -226,14 +242,6 @@ msgstr "" msgid "COPYRIGHT" msgstr "" -#: internal/cliutils/template.go:95 -msgid "command options" -msgstr "" - -#: internal/cliutils/template.go:96 -msgid "arguments..." -msgstr "" - #: internal/cliutils/template.go:97 msgid "CATEGORY" msgstr "" diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po index f9179c3..4420300 100644 --- a/internal/translations/po/ru/default.po +++ b/internal/translations/po/ru/default.po @@ -5,15 +5,15 @@ msgid "" msgstr "" "Project-Id-Version: unnamed project\n" -"PO-Revision-Date: 2025-02-27 11:33+0300\n" +"PO-Revision-Date: 2025-02-27 14:27+0300\n" "Last-Translator: Maxim Slipenko \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Gtranslator 47.1\n" #: build.go:44 @@ -209,6 +209,22 @@ msgstr "НАЗВАНИЕ" msgid "USAGE" msgstr "ИСПОЛЬЗОВАНИЕ" +#: internal/cliutils/template.go:74 +msgid "global options" +msgstr "глобальные опции" + +#: internal/cliutils/template.go:74 +msgid "command" +msgstr "команда" + +#: internal/cliutils/template.go:74 internal/cliutils/template.go:95 +msgid "command options" +msgstr "опции команды" + +#: internal/cliutils/template.go:74 internal/cliutils/template.go:96 +msgid "arguments" +msgstr "аргументы" + #: internal/cliutils/template.go:74 msgid "VERSION" msgstr "ВЕРСИЯ" @@ -233,14 +249,6 @@ msgstr "ГЛОБАЛЬНЫЕ ОПЦИИ" msgid "COPYRIGHT" msgstr "АВТОРСКОЕ ПРАВО" -#: internal/cliutils/template.go:95 -msgid "command options" -msgstr "опции команды" - -#: internal/cliutils/template.go:96 -msgid "arguments..." -msgstr "аргументы..." - #: internal/cliutils/template.go:97 msgid "CATEGORY" msgstr "КАТЕГОРИЯ"