handbrake 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,13 @@
1
+ 0.4.0
2
+ =====
3
+
4
+ - Allow the `:runner` option for {HandBrake::CLI} to take a lambda
5
+ that returns the runner. (#4)
6
+ - Document the default runner to make the runner protocol
7
+ explicit. (#4)
8
+ - Ensure that arguments that contain quotes are properly escaped
9
+ during execution. (#2; reported by bmatsuo)
10
+
1
11
  0.3.1
2
12
  =====
3
13
 
@@ -25,6 +25,14 @@ module HandBrake
25
25
  # @return [Boolean]
26
26
  attr_writer :dry_run
27
27
 
28
+ ##
29
+ # The runner to use to actually invoke HandBrakeCLI. This should
30
+ # be an object following the protocol laid out in the
31
+ # documentation for {PopenRunner}.
32
+ #
33
+ # @return [#run]
34
+ attr_accessor :runner
35
+
28
36
  ##
29
37
  # @param [Hash] options
30
38
  # @option options [String] :bin_path ('HandBrakeCLI') the full
@@ -34,18 +42,35 @@ module HandBrake
34
42
  # @option options [Boolean] :dry_run (false) if true, nothing will
35
43
  # actually be executed. The commands that would have been
36
44
  # executed will be printed to standard out.
37
- # @option options [#run] :runner (a PopenRunner instance) the class
38
- # encapsulating the execution method for HandBrakeCLI. You
39
- # shouldn't usually need to replace this.
45
+ # @option options [#run, #call] :runner (a PopenRunner instance)
46
+ # the object encapsulating the execution method for HandBrakeCLI
47
+ # or a lambda which may be invoked to create the runner. A lambda will
48
+ # receive the {CLI} instance that's being constructed as its
49
+ # sole argument. You shouldn't usually need to replace this. If
50
+ # you do, look at {#runner} for more details.
40
51
  def initialize(options={})
41
52
  @bin_path = options[:bin_path] || 'HandBrakeCLI'
42
53
  @trace = options[:trace].nil? ? false : options[:trace]
43
54
  @dry_run = options[:dry_run] || false
44
- @runner = options[:runner] || PopenRunner.new(self)
55
+ @runner = build_runner(options[:runner])
45
56
 
46
57
  @args = []
47
58
  end
48
59
 
60
+ def build_runner(selected)
61
+ default_runner_creator = lambda { |cli| PopenRunner.new(cli) }
62
+
63
+ case
64
+ when selected.nil?
65
+ default_runner_creator.call(self)
66
+ when selected.respond_to?(:call)
67
+ selected.call(self) || default_runner_creator.call(self)
68
+ else
69
+ selected
70
+ end
71
+ end
72
+ private :build_runner
73
+
49
74
  ##
50
75
  # Ensures that `#dup` produces a separate copy.
51
76
  #
@@ -253,7 +278,7 @@ module HandBrake
253
278
 
254
279
  def run(*more_args)
255
280
  @runner.run(arguments.push(*more_args)).tap do |result|
256
- unless result.status == 0
281
+ unless result.status.to_i == 0
257
282
  unless trace?
258
283
  $stderr.write result.output
259
284
  end
@@ -282,13 +307,19 @@ module HandBrake
282
307
  end
283
308
 
284
309
  ##
285
- # @private
286
310
  # The default runner. Uses `IO.popen` to spawn
287
311
  # HandBrakeCLI. General use of this library does not require
288
312
  # monkeying with this class.
313
+ #
314
+ # If you have non-general use case, a replacement runner must have
315
+ # a method matching the signature of {#run}.
316
+ #
317
+ # @see CLI#initialize the HandBrake::CLI constructor
318
+ # @see CLI#runner HandBrake::CLI#runner
289
319
  class PopenRunner
290
320
  ##
291
- # @param [CLI] cli_instance the {CLI} instance whose configuration to share
321
+ # @param [CLI] cli_instance the {CLI} instance for which this
322
+ # runner will execute.
292
323
  def initialize(cli_instance)
293
324
  @cli = cli_instance
294
325
  end
@@ -309,7 +340,7 @@ module HandBrake
309
340
  def run(arguments)
310
341
  output = ''
311
342
 
312
- cmd = "'" + arguments.unshift(@cli.bin_path).join("' '") + "' 2>&1"
343
+ cmd = command(arguments)
313
344
 
314
345
  $stderr.puts "Spawning HandBrakeCLI using #{cmd.inspect}" if @cli.trace?
315
346
  if @cli.dry_run?
@@ -325,13 +356,20 @@ module HandBrake
325
356
  RunnerResult.new(output, $?)
326
357
  end
327
358
  end
359
+
360
+ ##
361
+ # @return [String] the concatentated command string to pass to IO.popen.
362
+ def command(arguments)
363
+ "'#{arguments.unshift(@cli.bin_path).collect { |a| a.gsub(%r(')) { %('\\\'') } }.join("' '")}' 2>&1"
364
+ end
328
365
  end
329
366
 
330
367
  ##
331
- # @private
332
368
  # The raw result of one execution of HandBrakeCLI.
333
369
  #
334
- # General use of the library will not require use of this class.
370
+ # General use of the library will not require use of this
371
+ # class. If you create your own {CLI#runner runner} its `run`
372
+ # method should return an instance of this class.
335
373
  #
336
374
  # @attr [String] output a string containing the combined output
337
375
  # and error streams from the run
@@ -1,5 +1,5 @@
1
1
  module HandBrake
2
2
  ##
3
3
  # The current version
4
- VERSION = '0.3.1'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -23,6 +23,38 @@ module HandBrake
23
23
  end
24
24
  end
25
25
 
26
+ describe '#runner' do
27
+ let(:default_runner_class) { HandBrake::CLI::PopenRunner }
28
+
29
+ it 'is a PopenRunner by default' do
30
+ HandBrake::CLI.new.runner.should be_a default_runner_class
31
+ end
32
+
33
+ it 'can be set with a static value' do
34
+ HandBrake::CLI.new(:runner => HandBrake::Spec::StaticRunner.new).runner.
35
+ should be_a HandBrake::Spec::StaticRunner
36
+ end
37
+
38
+ describe 'set from a lambda' do
39
+ let(:recorder_class) { Struct.new(:input) }
40
+ let(:runner_constructor) { lambda { |cli| recorder_class.new(cli) } }
41
+ let(:cli) { HandBrake::CLI.new(:runner => runner_constructor) }
42
+
43
+ it 'calls the lambda' do
44
+ cli.runner.should be_a recorder_class
45
+ end
46
+
47
+ it 'yields the CLI instance' do
48
+ cli.runner.input.should be cli
49
+ end
50
+
51
+ it 'uses the default if the lambda returns nil' do
52
+ HandBrake::CLI.new(:runner => lambda { |cli| nil }).runner.
53
+ should be_a default_runner_class
54
+ end
55
+ end
56
+ end
57
+
26
58
  describe "building a command" do
27
59
  let(:cli) { HandBrake::CLI.new }
28
60
 
@@ -356,4 +388,27 @@ module HandBrake
356
388
  end
357
389
  end
358
390
  end
391
+
392
+ describe CLI::PopenRunner do
393
+ describe '#command' do
394
+ subject { CLI::PopenRunner.new(CLI.new(:bin_path => '/foo/hbcli')) }
395
+
396
+ it 'starts with the bin path' do
397
+ subject.command(%w(--bar)).should =~ %r{^'/foo/hbcli'}
398
+ end
399
+
400
+ it 'quotes the arguments' do
401
+ subject.command(%w(--bar)).should =~ %r{'--bar'}
402
+ end
403
+
404
+ it 'redirects stderr to stdout' do
405
+ subject.command([]).should =~ %r{2>&1$}
406
+ end
407
+
408
+ it 'escapes single quotes in the arguments' do
409
+ subject.command(["--output", "/quux/boo's.m4v"]).
410
+ should == %('/foo/hbcli' '--output' '/quux/boo'\\''s.m4v' 2>&1)
411
+ end
412
+ end
413
+ end
359
414
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: handbrake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-21 00:00:00.000000000Z
12
+ date: 2011-09-06 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rubytree
16
- requirement: &2152476560 !ruby/object:Gem::Requirement
16
+ requirement: &2157010300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.8.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152476560
24
+ version_requirements: *2157010300
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2152476060 !ruby/object:Gem::Requirement
27
+ requirement: &2157009800 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.5'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2152476060
35
+ version_requirements: *2157009800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &2152475600 !ruby/object:Gem::Requirement
38
+ requirement: &2157009340 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.9.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2152475600
46
+ version_requirements: *2157009340
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: yard
49
- requirement: &2152475140 !ruby/object:Gem::Requirement
49
+ requirement: &2157008880 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 0.7.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2152475140
57
+ version_requirements: *2157008880
58
58
  description: A lightweight literate ruby wrapper for HandBrakeCLI, the command-line
59
59
  interface for the HandBrake video transcoder.
60
60
  email: