summaryrefslogtreecommitdiff
path: root/internal/ior.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-12 22:53:15 +0300
committerPaul Buetow <paul@buetow.org>2026-05-12 22:53:15 +0300
commit9f8096551ecf7184693b786a8e0b77d290086eac (patch)
tree3e7e1294655202c7339b3bd62cbcbefdfb4ea397 /internal/ior.go
parent35df301fceabfadc8b8a4ae221cc0c2391e233cd (diff)
refactor dispatchRun/validateRunConfig into ModeRegistry for OCP compliance
Introduce a ModeRegistry pattern so new execution modes can be added without modifying the dispatch or validation switch/if chains. Each mode is a self-contained modeHandler (match + validate + run); the ordered defaultRegistry replaces the open if-chains in dispatchRun and validateRunConfig, which become thin wrappers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/ior.go')
-rw-r--r--internal/ior.go68
1 files changed, 11 insertions, 57 deletions
diff --git a/internal/ior.go b/internal/ior.go
index aff1355..f1b159d 100644
--- a/internal/ior.go
+++ b/internal/ior.go
@@ -69,67 +69,18 @@ func Run(cfg flags.Config) error {
return dispatchRun(cfg)
}
+// dispatchRun delegates to the defaultRegistry, which validates all
+// mode-combination constraints and then runs the first matching handler.
func dispatchRun(cfg flags.Config) error {
- if err := validateRunConfig(cfg); err != nil {
- return err
- }
- if cfg.TestFlames {
- return runTUITestFlamesFn(cfg, tuiTestFlamesStarter(cfg))
- }
- if cfg.TestLiveFlames {
- return runTUITestLiveFlamesFn(cfg, tuiTestLiveFlamesStarter(cfg))
- }
- // All remaining modes require tracing, which needs root. Fail fast here so
- // the TUI never starts (and hangs) when we already know it cannot trace.
- if getEUID() != 0 {
- return errRootPrivilegesRequired
- }
- if isHeadlessParquetMode(cfg) {
- return runParquetFn(cfg)
- }
- if shouldRunTraceMode(cfg) {
- return runTraceFn(cfg)
- }
- return runTUIFn(cfg, tuiTraceStarterFromRunTrace(cfg, runTraceWithContextFn))
+ return defaultRegistry.dispatch(cfg)
}
+// validateRunConfig runs all cross-mode constraint checks without running
+// any mode. It is a thin wrapper around defaultRegistry.validate so that
+// callers (and tests) that only want validation do not need to know about
+// the registry.
func validateRunConfig(cfg flags.Config) error {
- if isHeadlessParquetMode(cfg) {
- if cfg.TestFlames {
- return errors.New("--testflames cannot be combined with -parquet")
- }
- if cfg.TestLiveFlames {
- return errors.New("--testliveflames cannot be combined with -parquet")
- }
- if cfg.PlainMode {
- return errors.New("-parquet and -plain are mutually exclusive")
- }
- if cfg.FlamegraphOutput {
- return errors.New("-parquet and -flamegraph are mutually exclusive")
- }
- if hasHeadlessParquetContentFilters(cfg) {
- return errors.New("-parquet cannot be combined with content filters (-comm, -path, -pid, -tid)")
- }
- }
- if cfg.TestFlames && cfg.PlainMode {
- return errors.New("--testflames cannot be combined with -plain")
- }
- if cfg.TestFlames && cfg.FlamegraphOutput {
- return errors.New("--testflames cannot be combined with -flamegraph")
- }
- if cfg.TestLiveFlames && cfg.PlainMode {
- return errors.New("--testliveflames cannot be combined with -plain")
- }
- if cfg.TestLiveFlames && cfg.FlamegraphOutput {
- return errors.New("--testliveflames cannot be combined with -flamegraph")
- }
- if cfg.PlainMode && cfg.FlamegraphOutput {
- return errors.New("-plain and -flamegraph are mutually exclusive")
- }
- if cfg.TestFlames && cfg.TestLiveFlames {
- return errors.New("--testflames and --testliveflames are mutually exclusive")
- }
- return nil
+ return defaultRegistry.validate(cfg)
}
// tuiTestFlamesStarter returns a TraceStarter that seeds static test flame data
@@ -208,6 +159,9 @@ func runSyntheticLiveFlames(ctx context.Context, liveTrie *flamegraph.LiveTrie,
}
}
+// shouldRunTraceMode reports whether cfg selects a headless trace path
+// (plain CSV, flamegraph output, or headless Parquet). It is retained for
+// use by the test suite; the dispatch path uses modeRegistry instead.
func shouldRunTraceMode(cfg flags.Config) bool {
return cfg.PlainMode || cfg.FlamegraphOutput || isHeadlessParquetMode(cfg)
}