refactor(internal): improve encapsulation, separation of concerns, and test coverage#48
Merged
seanseannery merged 1 commit intomainfrom Mar 19, 2026
Merged
Conversation
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Key Changes
ParsedOpsfilestruct —ParseOpsFilenow returns a single struct instead of 5 values, eliminating the multi-return anti-pattern across all call sitesShellLinestruct — parse-time type carryingText,Silent(@prefix), andIgnoreError(-prefix); prefix stripping moved from resolver to parser where it belongsenvLookupinjection —Resolvenow acceptsfunc(string)(string, bool)instead of hardcodingos.LookupEnv, enabling proper unit testing withoutos.SetenvArgs.CommandArgswas populated but never passed through toExecute; fixed via POSIXsh -c "script" ops arg1 arg2so$1,$2,$@, and$0work correctly in Opsfile shell linesdryRunin executor —Executenow owns dry-run logic (previously inmain.go); prints lines without executing, respecting per-lineSilentflagDefaultShell()in executor — shell detection moved frommain.gointo the executor package that uses itformatCommandListmoved tocmd/ops— presentation concern removed frominternal;lister.go/lister_test.gorelocated and made unexportedexamples/Opsfile_maclocal— new macOS local dev example covering resource checks, port management, log tailing, DNS flush, and network diagnosticsWhy do we need this?
The
internalpackage had accumulated presentation logic (lister.go), mixed responsibilities in the executor (shell detection, dry-run), and a fragile 5-return-value API fromParseOpsFile. The CommandArgs bug meantops deploy myappnever actually passedmyappas$1to 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?
ShellLineprefix parsing, dry-run executor behavior, CommandArgs passthrough ($1/$2/$@/$0/spaces-in-args),DefaultShelledge cases,nil-safety forenvFileVarsand lister slicesmake lintandmake testpass (also verified by pre-push hook)