Stanislav N. aka pztrn 71c80799d2
Some checks failed
Linting and tests / Tests (push) Failing after 1m22s
Linting and tests / Linting (push) Failing after 1m32s
Linter configuration and linting.
2025-09-11 02:30:15 +05:00

130 lines
3.5 KiB
Go

//nolint:gosec
package main
import (
"encoding/json"
"flag"
"fmt"
"io/fs"
"log/slog"
"os"
"path/filepath"
"sort"
"strings"
)
const (
exitCodeFailedToReadEnglishFile = 3
exitCodeFailedToReadTranslationsFile = 6
exitCodeFailedToNormalizePath = 2
exitCodeFailedToUnmarshalEnglishFile = 4
exitCodeFailedToUnmarshalTranslationsFile = 7
exitCodeFailedToWalkTranslationsPath = 5
exitCodeNoTranslationsPath = 1
)
var translationsPath string
func main() {
flag.StringVar(&translationsPath, "translations-path", "", "Path to translations JSON files.")
flag.Parse()
if translationsPath == "" {
slog.Error("No -translations-path specified.")
os.Exit(exitCodeNoTranslationsPath)
}
slog.Info(
"Checking translations file for missing translations, using 'en.json' as original source...",
"path", translationsPath,
)
dirPath, err := filepath.Abs(translationsPath)
if err != nil {
slog.Error("Failed to normalize translations files path!", "error", err.Error())
os.Exit(exitCodeFailedToNormalizePath)
}
sourceDataAsBytes, err := os.ReadFile(filepath.Join(dirPath, "en.json"))
if err != nil {
slog.Error("Failed to read 'en.json' file!", "error", err.Error())
os.Exit(exitCodeFailedToReadEnglishFile)
}
sourceData := make(map[string]string)
if err := json.Unmarshal(sourceDataAsBytes, &sourceData); err != nil {
slog.Error("Failed to unmarshal 'en.json' file!", "error", err.Error())
os.Exit(exitCodeFailedToUnmarshalEnglishFile)
}
langFilesToCheck := make([]string, 0)
if err := filepath.WalkDir(dirPath, func(path string, _ fs.DirEntry, _ error) error {
if strings.Contains(path, ".json") && !strings.Contains(path, "en.json") {
langFilesToCheck = append(langFilesToCheck, path)
}
return nil
}); err != nil {
slog.Error("Failed to walk translations path!", "error", err.Error())
os.Exit(exitCodeFailedToWalkTranslationsPath)
}
slog.Info("Got langfiles to check", "count", len(langFilesToCheck))
missingTranslations := make(map[string][]string)
for _, langFile := range langFilesToCheck {
slog.Info("Checking language file...", "file", langFile)
langFileBytes, err := os.ReadFile(langFile)
if err != nil {
slog.Error("Failed to read language file!", "file", langFile, "error", err.Error())
os.Exit(exitCodeFailedToReadTranslationsFile)
}
langFileData := make(map[string]string)
if err := json.Unmarshal(langFileBytes, &langFileData); err != nil {
slog.Error("Failed to parse language file!", "file", langFile, "error", err.Error())
os.Exit(exitCodeFailedToUnmarshalTranslationsFile)
}
for originalTranslation := range sourceData {
if _, found := langFileData[originalTranslation]; !found {
if _, langFound := missingTranslations[langFile]; !langFound {
missingTranslations[langFile] = make([]string, 0)
}
missingTranslations[langFile] = append(missingTranslations[langFile], originalTranslation)
}
}
}
if len(missingTranslations) == 0 {
slog.Info("Yay, no missing translations!")
os.Exit(0)
}
for langFile, missing := range missingTranslations {
_, fileName := filepath.Split(langFile)
slog.Info("Found missing translations for file.", "file", fileName)
sort.Strings(missing)
//nolint:forbidigo
fmt.Println("============================== " + fileName + " MISSING START")
for _, name := range missing {
//nolint:forbidigo
fmt.Println(name)
}
//nolint:forbidigo
fmt.Println("============================== " + fileName + " MISSING END")
}
}