Conversation
lib/dry/cli.rb
Outdated
| def perform_command(arguments) | ||
| command, args = parse(kommand, arguments, []) | ||
|
|
||
| command.instance_variable_set(:@stderr, err) |
There was a problem hiding this comment.
The idea here is to not have to change the signature of Command#initialize causing a breaking change
There was a problem hiding this comment.
How about initializing a pair of StringIO in the command, and then
def perform_command(arguments)
command, args = parse(kommand, arguments, [])
command.call(**args)
IO.copy_stream(command.out, out)
IO.copy_stream(command.err, err)
endThis would make testing the stdout and stderr of commands much simpler.
There was a problem hiding this comment.
The intention is to utilize the out/err passed to the CLI in the first place. dry-cil uses them to print help and errors and "inline" commands. We should also allow the commands to use the user specified out/err. Testing is already trivial as the values are DI
There was a problem hiding this comment.
My belated thoughts on this idea. I think it's kind of cool that we can use copy_stream to allow for a dedicated stdout/stderr per-command, but I think this would still surprise a user. We accept injected stdout/stderr objects from the top-level CLI, and if we are going to expose things of the same name inside commands, then I think the expectation would be that they're the same objects.
85eb546 to
8d8c51d
Compare
|
@aaronmallen I like the idea of this. We already do similar in Hanami CLI, which I think represents good and typical usage of dry-cli: # in hanami/cli/command.rb
def initialize(out:, err:, fs:, inflector:)
super()
@out = out
@err = err
@fs = fs
@inflector = inflector
endI'd love to pull this down into the core library so it's there for everyone who uses it. Since we already make In your change here you're conscious to avoid API breakage, but I wonder, perhaps this is worth breaking API for? This feels like a valuable enough thing to move to 2.0 for. And if we did that, is there anything else you'd like to see change with the command interface? |
@timriley The only other thing I modify about Dry::CLI locally would actually be a small breaking change. I typically change the class MyCommand < Dry::CLI::Command
example "--with-option", "Do a thing with an option"
example "--without-option", "Do a thing without an option"
endvia def example(example, description)
@examples += [example, description].freeze
endI then implement: def examples
indent = @examples.map { |example, _| example.length }.max + 5
@examples.map { |example, description| "#{example.ljust(indent)}# #{description}" }
endThe idea being I always have a aligned example/description print out: Examples:
foo --with-option # Do a thing with an option
foo --without-option # Do a thing without an option |
|
I would even go so far as to say, it would be cool if |
|
@aaronmallen This change looks good to me. I'd like to merge this and then release it as v1.4.0. Then we'll use #151 as the beginnings of 2.0, which can also include #152. How does that sound to you? This will probably mean you need to adjust #151 so it's based off this change, rather than off the current main. Would you mind doing that? Thank you! I'll open a convo with our maintainers just to raise awareness of this change. |
|
Before I merge this, I want to test it with hanami and hanami-cli just to see if there's any breakage with our current internal approach of setting up stderr/stdout. |
|
@aaronmallen Actually, one change request: can you please rename these to These are the names of the args we currently expose to |
8d8c51d to
9427502
Compare
✅ Done @timriley |
9427502 to
cccc052
Compare
Introduce `@stderr` and `@stdout` instance variables to make error and output streams accessible within commands. This enables more flexible error handling and message output customization.
cccc052 to
6ffdea2
Compare
|
@aaronmallen Thanks for tweaking the names. FYI, I just pushed two changes:
|
|
Will merge this now. Whatever is in the main branch from this merge we'll use as the basis for the next 1.x release. Future commits to main we can use for 2.0. |
stderr and stdout for commandsout and err for commands
Introduce
@stderrand@stdoutinstance variables to make error and output streams accessible within commands. This enables more flexible error handling and message output customization.