Skip to content

Commit 3798c07

Browse files
committed
make language persistent in .keymaster config file
1 parent f184eb8 commit 3798c07

3 files changed

Lines changed: 39 additions & 2 deletions

File tree

cmd/keymaster/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,17 @@ func init() {
8282
// Database flags
8383
rootCmd.PersistentFlags().String("db-type", "sqlite", "Database type (e.g., sqlite, postgres)")
8484
rootCmd.PersistentFlags().String("db-dsn", "./keymaster.db", "Database connection string (DSN)")
85+
rootCmd.PersistentFlags().String("lang", "en", `TUI language ("en", "de")`)
8586

8687
// Bind flags to viper
8788
viper.BindPFlag("database.type", rootCmd.PersistentFlags().Lookup("db-type"))
8889
viper.BindPFlag("database.dsn", rootCmd.PersistentFlags().Lookup("db-dsn"))
90+
viper.BindPFlag("language", rootCmd.PersistentFlags().Lookup("lang"))
8991

9092
// Set defaults in viper. These are used if not set in the config file or by flags.
9193
viper.SetDefault("database.type", "sqlite")
9294
viper.SetDefault("database.dsn", "./keymaster.db")
95+
viper.SetDefault("language", "en")
9396

9497
// Add commands
9598
rootCmd.AddCommand(deployCmd)
@@ -143,6 +146,9 @@ database:
143146
# For SQLite, this is the path to the database file.
144147
dsn: ./keymaster.db
145148
149+
# The default language for the TUI. Supported: "en", "de".
150+
language: en
151+
146152
# Example for future PostgreSQL configuration:
147153
# database:
148154
# type: postgres

internal/i18n/i18n.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,17 @@ var localeFS embed.FS
2525
// bundle stores all the loaded translation messages from the locale files.
2626
var bundle *i18n.Bundle
2727

28-
// localizer is used to translate messages into a specific language.
29-
var localizer *i18n.Localizer
28+
var (
29+
// localizer is used to translate messages into a specific language.
30+
localizer *i18n.Localizer
31+
// currentLang stores the tag of the currently active language.
32+
currentLang string
33+
)
3034

3135
// Init initializes the i18n bundle and sets up the localizer for a specific language.
3236
// It parses all embedded YAML files from the 'locales' directory.
3337
func Init(lang string) {
38+
currentLang = lang
3439
bundle = i18n.NewBundle(language.English)
3540
bundle.RegisterUnmarshalFunc("yaml", yaml.Unmarshal)
3641

@@ -66,3 +71,8 @@ func T(messageID string) string {
6671
func SetLang(lang string) {
6772
Init(lang)
6873
}
74+
75+
// GetLang returns the string tag of the currently active language.
76+
func GetLang() string {
77+
return currentLang
78+
}

internal/tui/tui.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/toeirei/keymaster/internal/model"
1818

1919
tea "github.com/charmbracelet/bubbletea"
20+
"github.com/spf13/viper"
2021
)
2122

2223
// viewState represents which part of the UI is currently active.
@@ -263,6 +264,23 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
263264
i18n.T("menu.view_audit_log"),
264265
i18n.T("menu.view_accounts_by_tag"),
265266
}
267+
// Save the new language setting
268+
viper.Set("language", i18n.GetLang())
269+
if err := viper.WriteConfig(); err != nil {
270+
// This is not a fatal error, so we just note it.
271+
// The language will still change for the current session.
272+
m.err = fmt.Errorf("could not save language setting: %w", err)
273+
}
274+
// Re-initialize models that depend on i18n strings
275+
m.menu.choices = []string{
276+
i18n.T("menu.manage_accounts"),
277+
i18n.T("menu.manage_public_keys"),
278+
i18n.T("menu.assign_keys"),
279+
i18n.T("menu.rotate_system_keys"),
280+
i18n.T("menu.deploy_to_fleet"),
281+
i18n.T("menu.view_audit_log"),
282+
i18n.T("menu.view_accounts_by_tag"),
283+
}
266284
return m, nil
267285
}
268286
}
@@ -394,6 +412,9 @@ func (m menuModel) View(data dashboardData, width int) string {
394412

395413
// Run is the main entrypoint for the TUI. It initializes and runs the Bubble Tea program.
396414
func Run() {
415+
// Initialize i18n with the language from config
416+
i18n.Init(viper.GetString("language"))
417+
397418
if _, err := tea.NewProgram(initialModel()).Run(); err != nil {
398419
fmt.Printf("Alas, there's been an error: %v", err)
399420
os.Exit(1)

0 commit comments

Comments
 (0)