Skip to content

refactor(internal): improve encapsulation, separation of concerns, and test coverage#48

Merged
seanseannery merged 1 commit intomainfrom
refactor/internal-encapsulation
Mar 19, 2026
Merged

refactor(internal): improve encapsulation, separation of concerns, and test coverage#48
seanseannery merged 1 commit intomainfrom
refactor/internal-encapsulation

Conversation

@seanseannery
Copy link
Copy Markdown
Owner

Key Changes

  • ParsedOpsfile structParseOpsFile now returns a single struct instead of 5 values, eliminating the multi-return anti-pattern across all call sites
  • ShellLine struct — parse-time type carrying Text, Silent (@ prefix), and IgnoreError (- prefix); prefix stripping moved from resolver to parser where it belongs
  • envLookup injectionResolve now accepts func(string)(string, bool) instead of hardcoding os.LookupEnv, enabling proper unit testing without os.Setenv
  • CommandArgs passthrough (bug fix)Args.CommandArgs was populated but never passed through to Execute; fixed via POSIX sh -c "script" ops arg1 arg2 so $1, $2, $@, and $0 work correctly in Opsfile shell lines
  • dryRun in executorExecute now owns dry-run logic (previously in main.go); prints lines without executing, respecting per-line Silent flag
  • DefaultShell() in executor — shell detection moved from main.go into the executor package that uses it
  • formatCommandList moved to cmd/ops — presentation concern removed from internal; lister.go/lister_test.go relocated and made unexported
  • examples/Opsfile_maclocal — new macOS local dev example covering resource checks, port management, log tailing, DNS flush, and network diagnostics

Why do we need this?

The internal package had accumulated presentation logic (lister.go), mixed responsibilities in the executor (shell detection, dry-run), and a fragile 5-return-value API from ParseOpsFile. The CommandArgs bug meant ops deploy myapp never actually passed myapp as $1 to the shell. This PR addresses all of these as identified in an architecture review.

New modules or other dependencies introduced

None.

How was this tested?

  • All existing tests updated for the new APIs — no tests weakened or removed
  • New test groups added: ShellLine prefix parsing, dry-run executor behavior, CommandArgs passthrough ($1/$2/$@/$0/spaces-in-args), DefaultShell edge cases, nil-safety for envFileVars and lister slices
  • A QA agent review was performed post-implementation; all identified gaps addressed
  • make lint and make test pass (also verified by pre-push hook)

…d test coverage

- ParseOpsFile returns ParsedOpsfile struct instead of 5 values
- ShellLine struct carries Silent/IgnoreError flags; @ and - prefix stripping moved from resolver to parser
- Resolve accepts envLookup func injection instead of hardcoding os.LookupEnv
- Execute gains dryRun bool and commandArgs []string; POSIX sh -c passthrough makes $1/$@/$0 work in Opsfile lines
- DefaultShell() moved to executor; formatCommandList moved from internal to cmd/ops (presentation concern)
- Add examples/Opsfile_maclocal for macOS local dev operations
- Expand test coverage: dry-run, CommandArgs, ShellLine prefix parsing, nil-safety, $0 behavior, DefaultShell edge cases
@seanseannery seanseannery merged commit 0fc9e7c into main Mar 19, 2026
4 checks passed
@seanseannery seanseannery deleted the refactor/internal-encapsulation branch March 19, 2026 20:41
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