summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-03 23:53:25 +0200
committerPaul Buetow <paul@buetow.org>2026-03-03 23:53:25 +0200
commit09b8aa9d74df0ef7d50858cd398efc8a952a1aad (patch)
tree66b77086b1f55c349d7edb32635a52566ca70c8d
parente785973bc3a0add31a7ff68a94b9ea5d43413b59 (diff)
cli: thread config via command context
-rw-r--r--internal/cli/root.go31
-rw-r--r--internal/cli/root_test.go6
-rw-r--r--internal/cli/timer.go12
-rw-r--r--internal/cli/tui.go2
-rw-r--r--internal/cli/work.go22
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")
}