Skip to content

refactor: remove config global state#51

Open
dgerlanc wants to merge 15 commits into
mainfrom
worktree-config-global-state
Open

refactor: remove config global state#51
dgerlanc wants to merge 15 commits into
mainfrom
worktree-config-global-state

Conversation

@dgerlanc

Copy link
Copy Markdown
Owner

Summary

  • Replace config.Init() / config.Get() / Reset() singleton pattern with a pure config.Load() constructor that returns (*Config, string, error)
  • Thread config explicitly through hook.ProcessWithResult and cmd layer via function parameters and closures
  • Replace cmd package init() functions and global flags with a buildRootCmd() builder pattern
  • Enable t.Parallel() on 43 tests now that global config state is eliminated

Test plan

  • go test ./... -race -count=1 passes (all 7 packages)
  • go vet ./... clean
  • No remaining references to removed functions (config.Get, config.Init, config.Reset, config.InitError, config.GetConfigPath)
  • No remaining global config variables (globalConfig, configInitialized, globalInitError, globalConfigPath)
  • Benchmarks and fuzz tests updated and working

dgerlanc added 15 commits March 16, 2026 19:00
Covers the plan to replace the config singleton pattern with a pure
constructor + closure-based wiring, enabling parallel tests and
explicit dependency passing.
Fix signature mismatches (GetConfigDir returns error, logger.Init
takes Options struct, audit.Init signature), address logAudit
dependency on config globals, add completion.go restructuring,
cover benchmark_test.go and fuzz_test.go, preserve io.Reader
parameter on ProcessWithResult, and clarify root command Run wiring.
Resolve logAudit design (pass cfgPath/cfgErr through ProcessWithResult),
add Process() wrapper signature, inline runHook into root Run closure,
fix audit.Init to be called unconditionally, note IsVerbose/IsDryRun
removal, add EnsureConfigFiles/GetDefaultConfig to unchanged list,
address cmd test rewrites for package-level vars, and add mmi init
first-run note.
Return loadEmbeddedDefaults() instead of nil on parse errors to match
current Init() behavior and prevent nil pointer dereferences. Keep
Execute() as the public entry point wrapping buildRootCmd().
Ensures Load() never returns nil config, matching current Init()
behavior where callers always get a usable (deny-all) config.
10 tasks covering config.Load(), hook signature changes, cmd builder
pattern, and comprehensive test updates across all packages.
Address validate missing-config behavioral change, note intermediate
commit ordering, fix init.go configureClaudeSettings/getClaudeSettingsPath
param threading, expand hook_test.go coverage, enumerate validate_test
and init_test direct function calls.
Remove global variables (globalConfig, configInitialized, globalInitError,
globalConfigPath) and functions (Init, Get, InitError, GetConfigPath, Reset)
from the config package. Replace with a pure Load() function that returns
(*Config, string, error) and always provides a non-nil Config with embedded
defaults on any error path.
Replace SetupTestConfig (which used global config state) with
LoadTestConfig that parses TOML and returns a *Config for testing.
- Rewrite all cmd tests to use buildRootCmd() with SetArgs/SetIn/SetOut
- Update root.go Run to use cmd.InOrStdin/OutOrStdout/ErrOrStderr
- Update validate.go to use cmd.OutOrStdout for testability
- Remove all global state references (resetGlobalState, initForce, etc.)
- Remove TestMain that set up global config state
- Add loadTestConfig helper using config.LoadConfig directly
- Update TestProcess to pass cfg explicitly to hook.Process
- Update TestStripWrappers, TestCheckSafe, TestCheckSafeUnsafe
- Update TestInitConfig and TestConfigCustomization to use config.Load
- Update runMmi integration helper to create its own temp config
- Update benchmarks and fuzz tests for explicit config parameter
- Replace setupTestConfig with loadTestConfig returning (*Config, string)
- Update all ProcessWithResult calls to pass cfg, cfgPath, cfgErr
- Replace config.Reset/Init patterns with config.Load or empty Config
- Update audit config path/error tests to use config.Load
Add t.Parallel() to tests that don't rely on global state (t.Setenv
or audit.Init/Close/Reset). Tests using the global audit logger in
hook_test.go are excluded since audit.Init is not safe for concurrent use.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant