handbrake 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: