Skip to content

Conversation

@warpfork
Copy link

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.

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.

By allowing these to be user-controlled, it becomes possible for users
to write tests of their CLI behavior, _without_ needing to invoke
their entire program as a subprocess (which would carry 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 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.)
@warpfork warpfork force-pushed the controllable-exit-and-output branch from 69d0e65 to 52e8e8e Compare November 27, 2022 06:05
@dnagir
Copy link

dnagir commented Jun 15, 2023

Agree that it is very useful (and much needed) addition.

I did another PR before I noticed this one (which is a bit light touch): #130

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.

2 participants