Skip to content

Add stderr, stdin, and stdout support for Dry::CLI #151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

aaronmallen
Copy link
Contributor

Introduce stderr, stdin, and stdout streams to Dry::CLI and its components to better handle I/O. This allows commands to utilize specific input/output streams, improving flexibility and testability. Refactor existing methods to use the new stream parameters consistently.

As an alternative to #150

cc @timriley

@aaronmallen aaronmallen force-pushed the expose-stderr-stdout-breaking branch from 46410e6 to ef66718 Compare July 25, 2025 05:07
Introduce `stderr`, `stdin`, and `stdout` streams to `Dry::CLI`
and its components to better handle I/O. This allows commands
to utilize specific input/output streams, improving flexibility
and testability. Refactor existing methods to use the new stream
parameters consistently.
@aaronmallen aaronmallen force-pushed the expose-stderr-stdout-breaking branch from ef66718 to 075a7c6 Compare July 25, 2025 05:08
@timriley
Copy link
Member

Per my comments here (#150 (comment)), this is a change that I think is worth breaking API compatibility over, and releasing as 2.0 if needed.

Why is it breaking compatibility? Previously Dry::CLI made no claim over the structure of a command's #initialize method. With this change, we now expect it to receive kwargs and reserve stdin:, stdout: and stderr: as required keywords that we manage internally.

I think this is a good change because it sets the expectation with users that they should use the streams that are given to them, rather than handle IO themselves. This ensures we're using the same streams as given to Dry::CLI#call, and improves command testing, since it's clear that streams are injected, and in tests, fake IO objects can be given instead.

This arrangement matches what we already do internally within Hanami::CLI::Command, which is our own primary in-ecosystem consumer of Dry CLI.

@flash-gordon @cllns @alassek — what do you think about this? Worth the change, in your opinion? And do you actually consider it "breaking?"

exit(1)
end

# @since 1.1.1
def spell_checker(result, arguments)
spell_checker = SpellChecker.call(result, arguments)
err.puts spell_checker if spell_checker
stderr.puts spell_checker if spell_checker
puts
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timriley is this a bug? Should this be stderr.puts and if so would you like me to fix it in this PR?

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