diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-03 23:53:25 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-03 23:53:25 +0200 |
| commit | 09b8aa9d74df0ef7d50858cd398efc8a952a1aad (patch) | |
| tree | 66b77086b1f55c349d7edb32635a52566ca70c8d /internal/cli | |
| parent | e785973bc3a0add31a7ff68a94b9ea5d43413b59 (diff) | |
cli: thread config via command context
Diffstat (limited to 'internal/cli')
| -rw-r--r-- | internal/cli/root.go | 31 | ||||
| -rw-r--r-- | internal/cli/root_test.go | 6 | ||||
| -rw-r--r-- | internal/cli/timer.go | 12 | ||||
| -rw-r--r-- | internal/cli/tui.go | 2 | ||||
| -rw-r--r-- | internal/cli/work.go | 22 |
5 files changed, 46 insertions, 27 deletions
diff --git a/internal/cli/root.go b/internal/cli/root.go index 11dabc5..faba592 100644 --- a/internal/cli/root.go +++ b/internal/cli/root.go @@ -1,6 +1,7 @@ package cli import ( + "context" "fmt" timr "codeberg.org/snonux/timr/internal" @@ -8,7 +9,7 @@ import ( "github.com/spf13/cobra" ) -var loadedConfig = config.Default() +type configContextKey struct{} // Execute runs the root command. func Execute() error { @@ -34,7 +35,7 @@ func NewRootCmd() *cobra.Command { return fmt.Errorf("load config: %w", err) } - loadedConfig = cfg + setConfig(cmd, cfg) return nil }, RunE: func(cmd *cobra.Command, args []string) error { @@ -56,7 +57,27 @@ func NewRootCmd() *cobra.Command { return cmd } -// CurrentConfig returns the config loaded in PersistentPreRunE. -func CurrentConfig() config.Config { - return loadedConfig +func setConfig(cmd *cobra.Command, cfg config.Config) { + baseContext := cmd.Context() + if baseContext == nil { + baseContext = context.Background() + } + cmd.SetContext(context.WithValue(baseContext, configContextKey{}, cfg)) +} + +func currentConfig(cmd *cobra.Command) config.Config { + if cmd == nil { + return config.Default() + } + + commandContext := cmd.Context() + if commandContext == nil { + return config.Default() + } + + cfg, ok := commandContext.Value(configContextKey{}).(config.Config) + if !ok { + return config.Default() + } + return cfg } diff --git a/internal/cli/root_test.go b/internal/cli/root_test.go index c900027..2b12514 100644 --- a/internal/cli/root_test.go +++ b/internal/cli/root_test.go @@ -12,8 +12,6 @@ import ( ) func TestRootVersionFlag(t *testing.T) { - loadedConfig = CurrentConfig() - var out bytes.Buffer cmd := NewRootCmd() cmd.SetOut(&out) @@ -51,7 +49,7 @@ func TestRootLoadsConfigInPersistentPreRun(t *testing.T) { t.Fatalf("Execute() error = %v", err) } - cfg := CurrentConfig() + cfg := currentConfig(cmd) if cfg.Hostname != "from-config" { t.Fatalf("Hostname = %q, want %q", cfg.Hostname, "from-config") } @@ -116,7 +114,7 @@ func TestRootUsesDefaultConfigWhenNoFileExists(t *testing.T) { t.Fatalf("Execute() error = %v", err) } - cfg := CurrentConfig() + cfg := currentConfig(cmd) if cfg.WeekWorkHours != 40 { t.Fatalf("WeekWorkHours = %v, want 40", cfg.WeekWorkHours) } diff --git a/internal/cli/timer.go b/internal/cli/timer.go index 46292ad..22f1ce8 100644 --- a/internal/cli/timer.go +++ b/internal/cli/timer.go @@ -52,7 +52,7 @@ func newTimerStartCmd() *cobra.Command { if err != nil { return err } - if err := syncWorktimeWithTimer(true); err != nil { + if err := syncWorktimeWithTimer(cmd, true); err != nil { return err } return printOutput(cmd, output) @@ -69,7 +69,7 @@ func newTimerStopCmd() *cobra.Command { if err != nil { return fmt.Errorf("stop timer: %w", err) } - if err := syncWorktimeWithTimer(false); err != nil { + if err := syncWorktimeWithTimer(cmd, false); err != nil { return err } return printOutput(cmd, output) @@ -198,7 +198,7 @@ func newTimerLiveCmd() *cobra.Command { selectedFont = ascii.AllFonts[rand.IntN(len(ascii.AllFonts))] } - model, err := tuiapp.NewTimerModel(selectedFont, CurrentConfig()) + model, err := tuiapp.NewTimerModel(selectedFont, currentConfig(cmd)) if err != nil { return err } @@ -220,13 +220,13 @@ func printOutput(cmd *cobra.Command, output string) error { return err } -func syncWorktimeWithTimer(start bool) error { - cfg := CurrentConfig() +func syncWorktimeWithTimer(cmd *cobra.Command, start bool) error { + cfg := currentConfig(cmd) if !cfg.AutoWorktimeLogin { return nil } - ctx, err := resolveWorkContext() + ctx, err := resolveWorkContext(cmd) if err != nil { return err } diff --git a/internal/cli/tui.go b/internal/cli/tui.go index c65b988..ff4f2aa 100644 --- a/internal/cli/tui.go +++ b/internal/cli/tui.go @@ -11,7 +11,7 @@ func newTUICmd() *cobra.Command { Use: "tui", Short: "Launch full-screen TUI", RunE: func(cmd *cobra.Command, args []string) error { - model, err := tuiapp.NewModelWithConfig(CurrentConfig()) + model, err := tuiapp.NewModelWithConfig(currentConfig(cmd)) if err != nil { return err } diff --git a/internal/cli/work.go b/internal/cli/work.go index e70587f..ce96115 100644 --- a/internal/cli/work.go +++ b/internal/cli/work.go @@ -53,7 +53,7 @@ func newWorkLoginCmd() *cobra.Command { Use: "login", Short: "Start work-time tracking", RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := resolveWorkContext() + ctx, err := resolveWorkContext(cmd) if err != nil { return err } @@ -98,7 +98,7 @@ func newWorkLogoutCmd() *cobra.Command { Use: "logout", Short: "Stop work-time tracking", RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := resolveWorkContext() + ctx, err := resolveWorkContext(cmd) if err != nil { return err } @@ -143,7 +143,7 @@ func newWorkAddCmd() *cobra.Command { Short: "Add manual work-time duration", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := resolveWorkContext() + ctx, err := resolveWorkContext(cmd) if err != nil { return err } @@ -183,7 +183,7 @@ func newWorkSubCmd() *cobra.Command { Short: "Subtract manual work-time duration", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := resolveWorkContext() + ctx, err := resolveWorkContext(cmd) if err != nil { return err } @@ -222,7 +222,7 @@ func newWorkUseBufferCmd() *cobra.Command { Short: "Transfer selfdevelopment buffer time into work", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := resolveWorkContext() + ctx, err := resolveWorkContext(cmd) if err != nil { return err } @@ -259,7 +259,7 @@ func newWorkReportCmd() *cobra.Command { Use: "report", Short: "Print weekly work-time report", RunE: func(cmd *cobra.Command, args []string) error { - cfg := CurrentConfig() + cfg := currentConfig(cmd) entries, err := worktime.LoadAll(cfg.WorktimeDBDir) if err != nil { @@ -290,7 +290,7 @@ func newWorkStatusCmd() *cobra.Command { Use: "status", Short: "Show current login status", RunE: func(cmd *cobra.Command, args []string) error { - cfg := CurrentConfig() + cfg := currentConfig(cmd) entries, err := worktime.LoadAll(cfg.WorktimeDBDir) if err != nil { return err @@ -311,7 +311,7 @@ func newWorkEditCmd() *cobra.Command { Use: "edit", Short: "Open host DB JSON in $EDITOR", RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := resolveWorkContext() + ctx, err := resolveWorkContext(cmd) if err != nil { return err } @@ -345,7 +345,7 @@ func newWorkImportCmd() *cobra.Command { Short: "Import report-format text file", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := resolveWorkContext() + ctx, err := resolveWorkContext(cmd) if err != nil { return err } @@ -360,8 +360,8 @@ func newWorkImportCmd() *cobra.Command { } } -func resolveWorkContext() (workContext, error) { - cfg := CurrentConfig() +func resolveWorkContext(cmd *cobra.Command) (workContext, error) { + cfg := currentConfig(cmd) if strings.TrimSpace(cfg.WorktimeDBDir) == "" { return workContext{}, errors.New("worktime_db_dir is empty in config") } |
