Support rerouting output and exit code handlers. #128
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.
Adds support for setting output writers and the exit code handler at the scope of the application.
While a CLI application most commonly does want to call os.Exit to handle exit codes, and print errors or usage information to the stderr file descriptor... it's also useful to be able to control these. In this PR, that ability is introduced.
The main motivation for this (at least for me!) is for testing. By allowing these to be user-controlled, it becomes possible for users to write tests of their CLI behavior. (This is a big win, in my book! IMO, it's very important to be able to write end-to-end tests of CLIs, because UX bugs in the last mile are otherwise very easy to accumulate. To try to do this without the ability to control exit behavior and where messages are written, the next nearest fallback option is to invoke the whole program as a subprocess... but this is a fairly awful fallback, and carries considerable complexity burdens; invoking go-install in the middle of go-test... well, let's say it "does not spark joy".)
Previously, within this library, the needs for the library's own self-testing were satisfied by using package-scope variables, which aside from being global, were also unexported. This is no longer necessary. The internal tests now use the same mechanisms that will be available to users. (As a bonus, the tests could now be parallelized without issue, though I haven't taken that step in this commit.)
I've tried to implement this change in a minimally invasive way, and I think it's pretty safe. Tests all still pass :) There are a couple requests for review embedded in the comments in the diff (mostly for stylistic things).
I'm not sure if there were open issues for all of this, but at least #112 is addressed by this.