Skip to content

refactor: separate template resource spec from runtime state #603

@abtreece

Description

@abtreece

Problem

TemplateResource mixes parsed TOML configuration, derived values, mutable runtime state, backend dependencies, rendering helpers, command execution, file staging, and watch state in a single struct.

Verified in pkg/template/resource.go:55-106. The struct includes:

  • Parsed resource fields such as CheckCmd, Dest, Keys, Mode, Src, ReloadCmd.
  • Derived values such as prefixedKeys, parsed durations, and resolved ownership.
  • Runtime state such as StageFile, lastIndex, lastReloadTime, and store.
  • Dependencies such as storeClient, cmdExecutor, fmtValidator, bkndFetcher, tmplRenderer, and fileStgr.

Additional evidence:

  • NewTemplateResource performs parsing, dependency selection, prefix normalization, ownership resolution, duration parsing, and helper construction in one path (pkg/template/resource.go:184-309).
  • sync(), check(), and reload() contain lazy helper initialization "for backward compatibility with tests" (pkg/template/resource.go:344, pkg/template/resource.go:406, pkg/template/resource.go:437), which indicates tests can construct partially initialized resources.

Why this is a problem

Mixing config and runtime state makes the resource lifecycle harder to reason about. It also allows invalid partial states: callers/tests can create a TemplateResource that has some fields but not required helpers, and production methods then compensate with lazy initialization.

This increases maintenance cost when changing rendering, staging, command execution, or watch behavior because all of those concerns meet on the same struct.

Suggested refactor

Separate the concepts:

  • ResourceSpec: parsed TOML plus validated, derived immutable values.
  • ResourceRuntime or ResourceProcessor: dependencies and mutable processing state.
  • Constructors should fully validate/build runtime dependencies; production methods should not need lazy "if nil, initialize" fallbacks.

Acceptance criteria

  • Parsed resource configuration can be tested separately from processing.
  • Processing methods operate on a fully initialized runtime object.
  • Lazy helper initialization in sync(), check(), and reload() is removed or confined to test helpers.
  • Watch state and reload state have clear ownership.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions