Fingertips-executioner 0.1.0 → 0.2.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.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :minor: 1
2
+ :minor: 2
3
3
  :patch: 0
4
4
  :major: 0
data/lib/executioner.rb CHANGED
@@ -16,7 +16,7 @@ module Executioner
16
16
  end
17
17
 
18
18
  def execute(command, options={})
19
- options[:switch_stdout_and_stderr] = false if options[:switch_stdout_and_stderr].nil?
19
+ command = "#{options[:env].map { |k,v| "#{k}='#{v}'" }.join(' ')} #{command}" if options[:env]
20
20
 
21
21
  Executioner.logger.debug("Executing: `#{command}'") if Executioner.logger
22
22
 
@@ -56,8 +56,8 @@ module Executioner
56
56
 
57
57
  module ClassMethods
58
58
  def executable(executable, options={})
59
- options[:switch_stdout_and_stderr] = false if options[:switch_stdout_and_stderr].nil?
60
- options[:use_queue] = false if options[:use_queue].nil?
59
+ options[:switch_stdout_and_stderr] ||= false
60
+ options[:use_queue] ||= false
61
61
 
62
62
  executable = executable.to_s if executable.is_a? Symbol
63
63
  use_queue = options.delete(:use_queue)
@@ -76,13 +76,13 @@ module Executioner
76
76
  if use_queue
77
77
  body = "queue(\"#{executable_path} \#{args}\")"
78
78
  else
79
- body = "execute(\"#{executable_path} \#{args}\", #{options.inspect})"
79
+ body = "execute(\"#{executable_path} \#{args}\", #{options.inspect}.merge(options))"
80
80
  end
81
81
  else
82
82
  body = "raise Executioner::ExecutableNotFoundError, \"Unable to find the executable '#{executable}' in: #{Executioner::SEARCH_PATHS.join(', ')}\""
83
83
  end
84
84
 
85
- class_eval "def #{executable.gsub(/-/, '_')}(args); #{body}; end", __FILE__, __LINE__
85
+ class_eval "def #{executable.gsub(/-/, '_')}(args, options = {}); #{body}; end", __FILE__, __LINE__
86
86
  end
87
87
 
88
88
  def find_executable(executable, advance_from = nil)
@@ -6,18 +6,64 @@ class AClassThatUsesSubshells
6
6
  executable :doesnotexistforsure
7
7
  executable 'executable-with-dash'
8
8
  executable :with_path, :path => '/path/to/executable'
9
+ executable :with_env, :path => '/path/to/executable', :env => { :foo => 'bar' }
10
+
11
+ public :execute
9
12
  end
10
13
 
11
- describe "Executioner, the module" do
12
- it "should assign an optional logger" do
14
+ describe "Executioner, when executing" do
15
+ before do
16
+ @object = AClassThatUsesSubshells.new
17
+ end
18
+
19
+ it "should open a pipe with the given command" do
20
+ Open3.expects(:popen3).with('/the/command')
21
+ @object.execute('/the/command')
22
+ end
23
+
24
+ it "should return the output received from stdout" do
25
+ stub_popen3 'stdout output', ''
26
+ @object.execute('/the/command').should == 'stdout output'
27
+ end
28
+
29
+ it "should return the output received from stderr if they should be reversed" do
30
+ stub_popen3 '', 'stderr output'
31
+ @object.execute('/the/command', :switch_stdout_and_stderr => true).should == 'stderr output'
32
+ end
33
+
34
+ it "should raise a Executioner::ProcessError if stdout is empty and stderr is not" do
35
+ stub_popen3 '', 'stderr output'
36
+ lambda { @object.execute('foo') }.should.raise Executioner::ProcessError
37
+ end
38
+
39
+ it "should raise a Executioner::ProcessError if stderr is empty and stdout is not and the streams are reversed" do
40
+ stub_popen3 'stdout output', ''
41
+ lambda { @object.execute('foo', :switch_stdout_and_stderr => true) }.should.raise Executioner::ProcessError
42
+ end
43
+
44
+ it "should prepend the given env variables" do
45
+ Open3.expects(:popen3).with("foo='bar' /the/command")
46
+ @object.execute('/the/command', :env => { :foo => :bar })
47
+ end
48
+
49
+ it "should log the command that's going to be executed if a logger is available" do
13
50
  begin
14
- logger = Object.new
51
+ logger = mock('Logger')
15
52
  Executioner.logger = logger
16
- Executioner.logger.should.be logger
53
+
54
+ logger.expects(:debug).with("Executing: `foo'")
55
+ stub_popen3
56
+ @object.execute('foo')
17
57
  ensure
18
58
  Executioner.logger = nil
19
59
  end
20
60
  end
61
+
62
+ private
63
+
64
+ def stub_popen3(stdout = '', stderr = '')
65
+ Open3.stubs(:popen3).yields(*['stdin', stdout, stderr].map { |s| StringIO.new(s) })
66
+ end
21
67
  end
22
68
 
23
69
  describe "Executioner, instance methods" do
@@ -76,7 +122,7 @@ describe "Executioner, class methods" do
76
122
  end
77
123
 
78
124
  it "should define an instance method which calls #execute with the correct path to the executable" do
79
- @object.expects(:execute).with('/bin/sh with some args', {:switch_stdout_and_stderr => false})
125
+ @object.expects(:execute).with('/bin/sh with some args', { :switch_stdout_and_stderr => false })
80
126
  @object.sh 'with some args'
81
127
  end
82
128
 
@@ -85,13 +131,13 @@ describe "Executioner, class methods" do
85
131
  end
86
132
 
87
133
  it "should be possible to switch stdin and stderr" do
88
- AClassThatUsesSubshells.class_eval { executable(:sh, {:switch_stdout_and_stderr => true}) }
89
- @object.expects(:execute).with('/bin/sh with some args', {:switch_stdout_and_stderr => true})
134
+ AClassThatUsesSubshells.class_eval { executable(:sh, { :switch_stdout_and_stderr => true }) }
135
+ @object.expects(:execute).with('/bin/sh with some args', { :switch_stdout_and_stderr => true })
90
136
  @object.sh 'with some args'
91
137
  end
92
138
 
93
139
  it "should be possible to use the queue by default" do
94
- AClassThatUsesSubshells.class_eval { executable(:sh, {:use_queue => true}) }
140
+ AClassThatUsesSubshells.class_eval { executable(:sh, { :use_queue => true }) }
95
141
  @object.expects(:execute).with('/bin/sh arg1 && /bin/sh arg2', {})
96
142
  @object.sh 'arg1'
97
143
  @object.sh 'arg2'
@@ -103,6 +149,16 @@ describe "Executioner, class methods" do
103
149
  @object.with_path 'arg1'
104
150
  end
105
151
 
152
+ it "should be possible to specify the env that's to be prepended to the command" do
153
+ @object.expects(:execute).with { |command, options| options[:env] == { :foo => 'bar' } }
154
+ @object.with_env 'arg1'
155
+ end
156
+
157
+ it "should merge options onto the default options" do
158
+ @object.expects(:execute).with { |command, options| options[:env] == { :foo => 'foo' } }
159
+ @object.with_env 'arg1', :env => { :foo => 'foo' }
160
+ end
161
+
106
162
  it "should be possible to find an executable" do
107
163
  File.stubs(:exist?).with('/bin/sh').returns(true)
108
164
  Executioner::ClassMethods.find_executable('sh').should == '/bin/sh'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Fingertips-executioner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eloy Duran