Permalink
Browse files

Allow the :runner option to take a lambda. Closes #4.

Also includes better documentation around providing your own runner.
  • Loading branch information...
1 parent 2854c5a commit 29b80e7503cc6cb9619955cd66282f2ba8567f08 @rsutphin committed Sep 6, 2011
Showing with 79 additions and 11 deletions.
  1. +5 −1 CHANGELOG.md
  2. +41 −9 lib/handbrake/cli.rb
  3. +1 −1 lib/handbrake/version.rb
  4. +32 −0 spec/handbrake/cli_spec.rb
View
@@ -1,6 +1,10 @@
-0.3.2
+0.4.0
=====
+- Allow the `:runner` option for {HandBrake::CLI} to take a lambda
+ that returns the runner. (#4)
+- Document the default runner to make the runner protocol
+ explicit. (#4)
- Ensure that arguments that contain quotes are properly escaped
during execution. (#2; reported by bmatsuo)
View
@@ -26,6 +26,14 @@ class CLI
attr_writer :dry_run
##
+ # The runner to use to actually invoke HandBrakeCLI. This should
+ # be an object following the protocol laid out in the
+ # documentation for {PopenRunner}.
+ #
+ # @return [#run]
+ attr_accessor :runner
+
+ ##
# @param [Hash] options
# @option options [String] :bin_path ('HandBrakeCLI') the full
# path to the executable to use
@@ -34,18 +42,35 @@ class CLI
# @option options [Boolean] :dry_run (false) if true, nothing will
# actually be executed. The commands that would have been
# executed will be printed to standard out.
- # @option options [#run] :runner (a PopenRunner instance) the object
- # encapsulating the execution method for HandBrakeCLI. You
- # shouldn't usually need to replace this.
+ # @option options [#run, #call] :runner (a PopenRunner instance)
+ # the object encapsulating the execution method for HandBrakeCLI
+ # or a lambda which may be invoked to create the runner. A lambda will
+ # receive the {CLI} instance that's being constructed as its
+ # sole argument. You shouldn't usually need to replace this. If
+ # you do, look at {#runner} for more details.
def initialize(options={})
@bin_path = options[:bin_path] || 'HandBrakeCLI'
@trace = options[:trace].nil? ? false : options[:trace]
@dry_run = options[:dry_run] || false
- @runner = options[:runner] || PopenRunner.new(self)
+ @runner = build_runner(options[:runner])
@args = []
end
+ def build_runner(selected)
+ default_runner_creator = lambda { |cli| PopenRunner.new(cli) }
+
+ case
+ when selected.nil?
+ default_runner_creator.call(self)
+ when selected.respond_to?(:call)
+ selected.call(self) || default_runner_creator.call(self)
+ else
+ selected
+ end
+ end
+ private :build_runner
+
##
# Ensures that `#dup` produces a separate copy.
#
@@ -253,7 +278,7 @@ def arguments
def run(*more_args)
@runner.run(arguments.push(*more_args)).tap do |result|
- unless result.status == 0
+ unless result.status.to_i == 0
unless trace?
$stderr.write result.output
end
@@ -282,13 +307,19 @@ def method_missing(name, *args)
end
##
- # @private
# The default runner. Uses `IO.popen` to spawn
# HandBrakeCLI. General use of this library does not require
# monkeying with this class.
+ #
+ # If you have non-general use case, a replacement runner must have
+ # a method matching the signature of {#run}.
+ #
+ # @see CLI#initialize the HandBrake::CLI constructor
+ # @see CLI#runner HandBrake::CLI#runner
class PopenRunner
##
- # @param [CLI] cli_instance the {CLI} instance whose configuration to share
+ # @param [CLI] cli_instance the {CLI} instance for which this
+ # runner will execute.
def initialize(cli_instance)
@cli = cli_instance
end
@@ -334,10 +365,11 @@ def command(arguments)
end
##
- # @private
# The raw result of one execution of HandBrakeCLI.
#
- # General use of the library will not require use of this class.
+ # General use of the library will not require use of this
+ # class. If you create your own {CLI#runner runner} its `run`
+ # method should return an instance of this class.
#
# @attr [String] output a string containing the combined output
# and error streams from the run
View
@@ -1,5 +1,5 @@
module HandBrake
##
# The current version
- VERSION = '0.3.2.pre'
+ VERSION = '0.4.0.pre'
end
View
@@ -23,6 +23,38 @@ module HandBrake
end
end
+ describe '#runner' do
+ let(:default_runner_class) { HandBrake::CLI::PopenRunner }
+
+ it 'is a PopenRunner by default' do
+ HandBrake::CLI.new.runner.should be_a default_runner_class
+ end
+
+ it 'can be set with a static value' do
+ HandBrake::CLI.new(:runner => HandBrake::Spec::StaticRunner.new).runner.
+ should be_a HandBrake::Spec::StaticRunner
+ end
+
+ describe 'set from a lambda' do
+ let(:recorder_class) { Struct.new(:input) }
+ let(:runner_constructor) { lambda { |cli| recorder_class.new(cli) } }
+ let(:cli) { HandBrake::CLI.new(:runner => runner_constructor) }
+
+ it 'calls the lambda' do
+ cli.runner.should be_a recorder_class
+ end
+
+ it 'yields the CLI instance' do
+ cli.runner.input.should be cli
+ end
+
+ it 'uses the default if the lambda returns nil' do
+ HandBrake::CLI.new(:runner => lambda { |cli| nil }).runner.
+ should be_a default_runner_class
+ end
+ end
+ end
+
describe "building a command" do
let(:cli) { HandBrake::CLI.new }

0 comments on commit 29b80e7

Please sign in to comment.