feat: translation support
All checks were successful
continuous-integration/drone/push Build is passing

See #483
This commit is contained in:
2025-08-19 11:22:52 +02:00
parent 5cf6048ecb
commit 4e205cf13e
108 changed files with 11217 additions and 1645 deletions

View File

@ -2,6 +2,7 @@ package app
import (
"bufio"
"errors"
"fmt"
"os"
"path"
@ -13,6 +14,7 @@ import (
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/envfile"
"coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/i18n"
"coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/upstream/convert"
"coopcloud.tech/abra/pkg/upstream/stack"
@ -36,7 +38,7 @@ func Get(appName string) (App, error) {
return App{}, err
}
log.Debugf("loaded app %s: %s", appName, app)
log.Debug(i18n.G("loaded app %s: %s", appName, app))
return app, nil
}
@ -47,7 +49,7 @@ func Get(appName string) (App, error) {
func GetApp(apps AppFiles, name AppName) (App, error) {
appFile, exists := apps[name]
if !exists {
return App{}, fmt.Errorf("cannot find app with name %s", name)
return App{}, errors.New(i18n.G("cannot find app with name %s", name))
}
app, err := ReadAppEnvFile(appFile, name)
@ -136,7 +138,7 @@ func StackName(appName string) string {
stackName := SanitiseAppName(appName)
if len(stackName) > config.MAX_SANITISED_APP_NAME_LENGTH {
log.Debugf("trimming %s to %s to avoid runtime limits", stackName, stackName[:config.MAX_SANITISED_APP_NAME_LENGTH])
log.Debug(i18n.G("trimming %s to %s to avoid runtime limits", stackName, stackName[:config.MAX_SANITISED_APP_NAME_LENGTH]))
stackName = stackName[:config.MAX_SANITISED_APP_NAME_LENGTH]
}
@ -243,12 +245,12 @@ func (a ByName) Less(i, j int) bool {
func ReadAppEnvFile(appFile AppFile, name AppName) (App, error) {
env, err := envfile.ReadEnv(appFile.Path)
if err != nil {
return App{}, fmt.Errorf("env file for %s couldn't be read: %s", name, err.Error())
return App{}, errors.New(i18n.G("env file for %s couldn't be read: %s", name, err.Error()))
}
app, err := NewApp(env, name, appFile)
if err != nil {
return App{}, fmt.Errorf("env file for %s has issues: %s", name, err.Error())
return App{}, errors.New(i18n.G("env file for %s has issues: %s", name, err.Error()))
}
return app, nil
@ -262,7 +264,7 @@ func NewApp(env envfile.AppEnv, name string, appFile AppFile) (App, error) {
if !exists {
recipeName, exists = env["TYPE"]
if !exists {
return App{}, fmt.Errorf("%s is missing the TYPE env var?", name)
return App{}, errors.New(i18n.G("%s is missing the TYPE env var?", name))
}
}
@ -290,13 +292,13 @@ func LoadAppFiles(servers ...string) (AppFiles, error) {
}
}
log.Debugf("collecting metadata from %v servers: %s", len(servers), strings.Join(servers, ", "))
log.Debug(i18n.G("collecting metadata from %v servers: %s", len(servers), strings.Join(servers, ", ")))
for _, server := range servers {
serverDir := path.Join(config.SERVERS_DIR, server)
files, err := config.GetAllFilesInDirectory(serverDir)
if err != nil {
return appFiles, fmt.Errorf("server %s doesn't exist? Run \"abra server ls\" to check", server)
return appFiles, errors.New(i18n.G("server %s doesn't exist? Run \"abra server ls\" to check", server))
}
for _, file := range files {
@ -375,7 +377,7 @@ func TemplateAppEnvSample(r recipe.Recipe, appName, server, domain string) error
appEnvPath := path.Join(config.ABRA_DIR, "servers", server, fmt.Sprintf("%s.env", appName))
if _, err := os.Stat(appEnvPath); !os.IsNotExist(err) {
return fmt.Errorf("%s already exists?", appEnvPath)
return errors.New(i18n.G("%s already exists?", appEnvPath))
}
err = os.WriteFile(appEnvPath, envSample, 0o664)
@ -395,7 +397,7 @@ func TemplateAppEnvSample(r recipe.Recipe, appName, server, domain string) error
return err
}
log.Debugf("copied & templated %s to %s", r.SampleEnvPath, appEnvPath)
log.Debug(i18n.G("copied & templated %s to %s", r.SampleEnvPath, appEnvPath))
return nil
}
@ -419,7 +421,7 @@ func GetAppStatuses(apps []App, MachineReadable bool) (map[string]map[string]str
var bar *progressbar.ProgressBar
if !MachineReadable {
bar = formatter.CreateProgressbar(len(servers), "querying remote servers...")
bar = formatter.CreateProgressbar(len(servers), i18n.G("querying remote servers..."))
}
ch := make(chan stack.StackStatus, len(servers))
@ -482,7 +484,7 @@ func GetAppStatuses(apps []App, MachineReadable bool) (map[string]map[string]str
}
}
log.Debugf("retrieved app statuses: %s", statuses)
log.Debug(i18n.G("retrieved app statuses: %s", statuses))
return statuses, nil
}
@ -496,7 +498,7 @@ func GetAppComposeConfig(recipe string, opts stack.Deploy, appEnv envfile.AppEnv
return &composetypes.Config{}, err
}
log.Debugf("retrieved %s for %s", compose.Filename, recipe)
log.Debug(i18n.G("retrieved %s for %s", compose.Filename, recipe))
return compose, nil
}
@ -505,13 +507,13 @@ func GetAppComposeConfig(recipe string, opts stack.Deploy, appEnv envfile.AppEnv
func ExposeAllEnv(stackName string, compose *composetypes.Config, appEnv envfile.AppEnv) {
for _, service := range compose.Services {
if service.Name == "app" {
log.Debugf("adding env vars to %s service config", stackName)
log.Debug(i18n.G("adding env vars to %s service config", stackName))
for k, v := range appEnv {
_, exists := service.Environment[k]
if !exists {
value := v
service.Environment[k] = &value
log.Debugf("%s: %s: %s", stackName, k, value)
log.Debug(i18n.G("%s: %s: %s", stackName, k, value))
}
}
}
@ -572,9 +574,9 @@ func ReadAbraShCmdNames(abraSh string) ([]string, error) {
}
if len(cmdNames) > 0 {
log.Debugf("read %s from %s", strings.Join(cmdNames, " "), abraSh)
log.Debug(i18n.G("read %s from %s", strings.Join(cmdNames, " "), abraSh))
} else {
log.Debugf("read 0 command names from %s", abraSh)
log.Debug(i18n.G("read 0 command names from %s", abraSh))
}
return cmdNames, nil
@ -617,7 +619,7 @@ func (a App) WipeRecipeVersion() error {
log.Fatal(err)
}
log.Debugf("version wiped from %s.env", a.Domain)
log.Debug(i18n.G("version wiped from %s.env", a.Domain))
return nil
}
@ -674,13 +676,13 @@ func (a App) WriteRecipeVersion(version string, dryRun bool) error {
log.Fatal(err)
}
} else {
log.Debugf("skipping writing version %s because dry run", version)
log.Debug(i18n.G("skipping writing version %s because dry run", version))
}
if !skipped {
log.Debugf("version %s saved to %s.env", version, a.Domain)
log.Debug(i18n.G("version %s saved to %s.env", version, a.Domain))
} else {
log.Debugf("skipping version %s write as already exists in %s.env", version, a.Domain)
log.Debug(i18n.G("skipping version %s write as already exists in %s.env", version, a.Domain))
}
return nil

View File

@ -5,6 +5,7 @@ import (
"strconv"
"coopcloud.tech/abra/pkg/envfile"
"coopcloud.tech/abra/pkg/i18n"
"coopcloud.tech/abra/pkg/log"
composetypes "github.com/docker/cli/cli/compose/types"
)
@ -14,7 +15,7 @@ import (
func SetRecipeLabel(compose *composetypes.Config, stackName string, recipe string) {
for _, service := range compose.Services {
if service.Name == "app" {
log.Debugf("set recipe label 'coop-cloud.%s.recipe' to %s for %s", stackName, recipe, stackName)
log.Debug(i18n.G("set recipe label 'coop-cloud.%s.recipe' to %s for %s", stackName, recipe, stackName))
labelKey := fmt.Sprintf("coop-cloud.%s.recipe", stackName)
service.Deploy.Labels[labelKey] = recipe
}
@ -26,7 +27,7 @@ func SetRecipeLabel(compose *composetypes.Config, stackName string, recipe strin
func SetChaosLabel(compose *composetypes.Config, stackName string, chaos bool) {
for _, service := range compose.Services {
if service.Name == "app" {
log.Debugf("set label 'coop-cloud.%s.chaos' to %v for %s", stackName, chaos, stackName)
log.Debug(i18n.G("set label 'coop-cloud.%s.chaos' to %v for %s", stackName, chaos, stackName))
labelKey := fmt.Sprintf("coop-cloud.%s.chaos", stackName)
service.Deploy.Labels[labelKey] = strconv.FormatBool(chaos)
}
@ -37,7 +38,7 @@ func SetChaosLabel(compose *composetypes.Config, stackName string, chaos bool) {
func SetChaosVersionLabel(compose *composetypes.Config, stackName string, chaosVersion string) {
for _, service := range compose.Services {
if service.Name == "app" {
log.Debugf("set label 'coop-cloud.%s.chaos-version' to %v for %s", stackName, chaosVersion, stackName)
log.Debug(i18n.G("set label 'coop-cloud.%s.chaos-version' to %v for %s", stackName, chaosVersion, stackName))
labelKey := fmt.Sprintf("coop-cloud.%s.chaos-version", stackName)
service.Deploy.Labels[labelKey] = chaosVersion
}
@ -47,7 +48,7 @@ func SetChaosVersionLabel(compose *composetypes.Config, stackName string, chaosV
func SetVersionLabel(compose *composetypes.Config, stackName string, version string) {
for _, service := range compose.Services {
if service.Name == "app" {
log.Debugf("set label 'coop-cloud.%s.version' to %v for %s", stackName, version, stackName)
log.Debug(i18n.G("set label 'coop-cloud.%s.version' to %v for %s", stackName, version, stackName))
labelKey := fmt.Sprintf("coop-cloud.%s.version", stackName)
service.Deploy.Labels[labelKey] = version
}
@ -64,7 +65,7 @@ func SetUpdateLabel(compose *composetypes.Config, stackName string, appEnv envfi
if !exists {
enable_auto_update = "false"
}
log.Debugf("set label 'coop-cloud.%s.autoupdate' to %s for %s", stackName, enable_auto_update, stackName)
log.Debug(i18n.G("set label 'coop-cloud.%s.autoupdate' to %s for %s", stackName, enable_auto_update, stackName))
labelKey := fmt.Sprintf("coop-cloud.%s.autoupdate", stackName)
service.Deploy.Labels[labelKey] = enable_auto_update
}
@ -76,13 +77,13 @@ func GetLabel(compose *composetypes.Config, stackName string, label string) stri
for _, service := range compose.Services {
if service.Name == "app" {
labelKey := fmt.Sprintf("coop-cloud.%s.%s", stackName, label)
log.Debugf("get label '%s'", labelKey)
log.Debug(i18n.G("get label '%s'", labelKey))
if labelValue, ok := service.Deploy.Labels[labelKey]; ok {
return labelValue
}
}
}
log.Debugf("no %s label found for %s", label, stackName)
log.Debug(i18n.G("no %s label found for %s", label, stackName))
return ""
}
@ -91,7 +92,7 @@ func GetTimeoutFromLabel(compose *composetypes.Config, stackName string) (int, e
timeout := 50 // Default Timeout
var err error = nil
if timeoutLabel := GetLabel(compose, stackName, "timeout"); timeoutLabel != "" {
log.Debugf("timeout label: %s", timeoutLabel)
log.Debug(i18n.G("timeout label: %s", timeoutLabel))
timeout, err = strconv.Atoi(timeoutLabel)
}
return timeout, err