internal/cli/i18n.go (128 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package cli import ( "fmt" "github.com/apache/answer/i18n" "github.com/apache/answer/pkg/dir" "github.com/apache/answer/pkg/writer" "gopkg.in/yaml.v3" "os" "path/filepath" "strings" ) type YamlPluginContent struct { Plugin map[string]any `yaml:"plugin"` } // ReplaceI18nFilesLocal replace i18n files func ReplaceI18nFilesLocal(i18nDir string) error { i18nList, err := i18n.I18n.ReadDir(".") if err != nil { fmt.Println(err.Error()) return err } fmt.Printf("[i18n] find i18n bundle %d\n", len(i18nList)) for _, item := range i18nList { path := filepath.Join(i18nDir, item.Name()) content, err := i18n.I18n.ReadFile(item.Name()) if err != nil { continue } exist := dir.CheckFileExist(path) if exist { fmt.Printf("[i18n] install %s file exist, try to replace it\n", item.Name()) if err = os.Remove(path); err != nil { fmt.Println(err) } } fmt.Printf("[i18n] install %s bundle...\n", item.Name()) err = writer.WriteFile(path, string(content)) if err != nil { fmt.Printf("[i18n] install %s bundle fail: %s\n", item.Name(), err.Error()) } else { fmt.Printf("[i18n] install %s bundle success\n", item.Name()) } } return nil } // MergeI18nFilesLocal merge i18n files func MergeI18nFilesLocal(originalI18nDir, targetI18nDir string) (err error) { pluginAllTranslations := make(map[string]*YamlPluginContent) err = findI18nFileInDir(pluginAllTranslations, targetI18nDir) if err != nil { return err } entries, err := os.ReadDir(originalI18nDir) if err != nil { return err } for _, file := range entries { // ignore directory if file.IsDir() { continue } // ignore non-YAML file filename := file.Name() if filepath.Ext(filename) != ".yaml" && filename != "i18n.yaml" { continue } // if plugin don't have this translation file, ignore it if pluginAllTranslations[filename] == nil { continue } out, _ := yaml.Marshal(pluginAllTranslations[filename]) buf, err := os.OpenFile(filepath.Join(originalI18nDir, filename), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Printf("[i18n] read translation file failed: %s %s\n", filename, err) continue } _, _ = buf.WriteString("\n") _, _ = buf.Write(out) _ = buf.Close() fmt.Printf("[i18n] merge i18n file: %s success\n", filename) } return nil } // find i18n file in dir func findI18nFileInDir(pluginAllTranslations map[string]*YamlPluginContent, i18nDir string) error { // if i18n dir is not i18n, find deeper dirBase := filepath.Base(i18nDir) if dirBase != "i18n" { if strings.HasPrefix(dirBase, ".") { return nil } // find all i18n dir in target dir targetDirs, err := os.ReadDir(i18nDir) if err != nil { return err } for _, targetDir := range targetDirs { if targetDir.IsDir() { if err := findI18nFileInDir(pluginAllTranslations, filepath.Join(i18nDir, targetDir.Name())); err != nil { fmt.Printf("[i18n] find i18n file in dir failed: %s %s\n", targetDir.Name(), err) } } } return nil } fmt.Printf("[i18n] find i18n file in dir: %s\n", i18nDir) // if i18nDir is i18n, find all yaml files entries, err := os.ReadDir(i18nDir) if err != nil { return err } for _, file := range entries { // ignore directory if file.IsDir() { continue } // ignore non-YAML file if filepath.Ext(file.Name()) != ".yaml" { continue } buf, err := os.ReadFile(filepath.Join(i18nDir, file.Name())) if err != nil { fmt.Printf("[i18n] read translation file failed: %s %s\n", file.Name(), err) continue } translation := &YamlPluginContent{} if err = yaml.Unmarshal(buf, translation); err != nil { fmt.Printf("[i18n] unmarshal translation file failed: %s %s\n", file.Name(), err) continue } if pluginAllTranslations[file.Name()] == nil { pluginAllTranslations[file.Name()] = &YamlPluginContent{Plugin: make(map[string]any)} } for k, v := range translation.Plugin { pluginAllTranslations[file.Name()].Plugin[k] = v } } return nil }