diff --git a/lib/dry/cli.rb b/lib/dry/cli.rb index 5f93860..4179275 100644 --- a/lib/dry/cli.rb +++ b/lib/dry/cli.rb @@ -57,12 +57,13 @@ def initialize(command_or_registry = nil, &block) # Invoke the CLI # # @param arguments [Array] the command line arguments (defaults to `ARGV`) - # @param out [IO] the standard output (defaults to `$stdout`) - # @param err [IO] the error output (defaults to `$stderr`) + # @param stderr [IO] the error output (defaults to `$stderr`) + # @param stdin [IO] the standard input (defaults to `$stdin`) + # @param stdout [IO] the standard output (defaults to `$stdout`) # # @since 0.1.0 - def call(arguments: ARGV, out: $stdout, err: $stderr) - @out, @err = out, err + def call(arguments: ARGV, stderr: $stderr, stdin: $stdin, stdout: $stdout) + @stderr, @stdin, @stdout = stderr, stdin, stdout kommand ? perform_command(arguments) : perform_registry(arguments) rescue SignalException => e signal_exception(e) @@ -82,11 +83,15 @@ def call(arguments: ARGV, out: $stdout, err: $stderr) # @since 0.6.0 # @api private - attr_reader :out + attr_reader :stderr + + # @since unreleased + # @api private + attr_reader :stdin # @since 0.6.0 # @api private - attr_reader :err + attr_reader :stdout # Invoke the CLI if singular command passed # @@ -145,29 +150,29 @@ def parse(command, arguments, names) # @since 0.6.0 # @api private def build_command(command) - command.is_a?(Class) ? command.new : command + command.is_a?(Class) ? command.new(stderr: stderr, stdin: stdin, stdout: stdout) : command end # @since 0.6.0 # @api private def help(command, prog_name) - out.puts Banner.call(command, prog_name) + stdout.puts Banner.call(command, prog_name) exit(0) # Successful exit end # @since 0.6.0 # @api private def error(result) - err.puts(result.error) + stderr.puts(result.error) 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 - err.puts Usage.call(result) + stderr.puts Usage.call(result) exit(1) end diff --git a/lib/dry/cli/command.rb b/lib/dry/cli/command.rb index 3e6a601..807f586 100644 --- a/lib/dry/cli/command.rb +++ b/lib/dry/cli/command.rb @@ -366,6 +366,14 @@ def self.superclass_options superclass_variable_dup(:@options) end + # @since unreleased + # @api private + def initialize(stderr: $stderr, stdin: $stdin, stdout: $stdout) + @stderr = stderr + @stdin = stdin + @stdout = stdout + end + extend Forwardable delegate %i[ @@ -379,6 +387,52 @@ def self.superclass_options optional_arguments subcommands ] => "self.class" + + protected + + # The error output used to print error messaging + # + # @example + # class MyCommand + # def call + # stdout.puts "Hello World!" + # exit(0) + # rescue StandardError => e + # stderr.puts "Uh oh: #{e.message}" + # exit(1) + # end + # end + # + # @since unreleased + # @return [IO] + attr_reader :stderr + + # The standard input stream used for reading input + # + # @example + # class MyCommand + # def call + # name = stdin.gets.chomp + # stdout.puts "Hello #{name}!" + # end + # end + # + # @since unreleased + # @return [IO] + attr_reader :stdin + + # The standard output stream used for normal output + # + # @example + # class MyCommand + # def call + # stdout.puts "Hello World!" + # end + # end + # + # @since unreleased + # @return [IO] + attr_reader :stdout end end end diff --git a/lib/dry/cli/inline.rb b/lib/dry/cli/inline.rb index 1dde7fa..e058bba 100644 --- a/lib/dry/cli/inline.rb +++ b/lib/dry/cli/inline.rb @@ -13,7 +13,7 @@ class CLI # methods below # # DSL consists of 5 methods: - # `desc`, `example`, `argument`, `option`  + # `desc`, `example`, `argument`, `option` # — are similar to methods from Command class # # `run` accepts a block to execute @@ -60,13 +60,13 @@ module Inline # end # # @since 0.6.0 - def run(arguments: ARGV, out: $stdout) + def run(arguments: ARGV, stdout: $stdout) command = AnonymousCommand command.define_method(:call) do |**args| yield(**args) end - Dry.CLI(command).call(arguments: arguments, out: out) + Dry.CLI(command).call(arguments: arguments, stdout: stdout) end end end