cocaine 0.2.1 → 0.3.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/.gitignore CHANGED
@@ -1,3 +1,7 @@
1
1
  *.rbc
2
+ .rbx
2
3
  *.gem
3
4
  Gemfile.lock
5
+ *.swp
6
+ *.swo
7
+ .bundle
@@ -2,7 +2,7 @@ rvm:
2
2
  - 1.8.7
3
3
  - 1.9.2
4
4
  - 1.9.3
5
- - rbx
6
- - rbx-2.0
5
+ - rbx-18mode
6
+ - rbx-19mode
7
7
  - ree
8
8
  - jruby
data/GOALS ADDED
@@ -0,0 +1,8 @@
1
+ Cocaine hits 1.0.0 when:
2
+
3
+ [*] It can run command lines across all major unix platforms.
4
+ [*] It can run command lines on Windows.
5
+ [*] It handles quoting.
6
+ [*] It takes advantage of OS-specific functionality to be thread-safe,
7
+ when possible.
8
+ [ ] It has a consistent and functioning API that pleases us.
data/NEWS.md ADDED
@@ -0,0 +1,10 @@
1
+ New for 0.3.0:
2
+
3
+ * Support blank arguments.
4
+ * Add `CommandLine#unix?`.
5
+ * Add `CommandLine#exit_status`.
6
+ * Automatically use `POSIX::Spawn` if available.
7
+ * Add `CommandLine#environment` as a hash of extra `ENV` data..
8
+ * Add `CommandLine#environment=` to set that hash.
9
+ * Add `CommandLine#runner` which produces an object that responds to `#call`.
10
+ * Fix a race condition but only on Ruby 1.9.
data/README.md CHANGED
@@ -1,24 +1,20 @@
1
- # Cocaine
1
+ # Cocaine [![Build Status](https://secure.travis-ci.org/thoughtbot/cocaine.png)](http://travis-ci.org/thoughtbot/cocaine)
2
2
 
3
3
  A small library for doing (command) lines.
4
4
 
5
- ## Feedback
6
-
7
- Question? Idea? Problem? Bug? Something else? Comment? Concern? Like use question marks?
8
-
9
- [GitHub Issues For All!](https://github.com/thoughtbot/cocaine/issues)
5
+ [API reference](http://rubydoc.info/gems/cocaine/)
10
6
 
11
7
  ## Usage
12
8
 
13
- The basic, normal stuff.
9
+ The basic, normal stuff:
14
10
 
15
11
  ```ruby
16
- line = Cocaine::CommandLine.new("command", "some 'crazy' options")
17
- line.command # => "command some 'crazy' options"
18
- output = line.run # => Get you some output!
12
+ line = Cocaine::CommandLine.new("echo", "hello 'world'")
13
+ line.command # => "echo hello 'world'"
14
+ line.run # => "hello world\n"
19
15
  ```
20
16
 
21
- Allowing arguments to be dynamic:
17
+ Interpolated arguments:
22
18
 
23
19
  ```ruby
24
20
  line = Cocaine::CommandLine.new("convert", ":in -scale :resolution :out",
@@ -59,6 +55,17 @@ rescue Cocaine::ExitStatusError => e
59
55
  end
60
56
  ```
61
57
 
58
+ If your command might return something non-zero, and you expect that, it's cool:
59
+
60
+ ```ruby
61
+ line = Cocaine::CommandLine.new("/usr/bin/false", "", :expected_outcodes => [0, 1])
62
+ begin
63
+ line.run
64
+ rescue Cocaine::ExitStatusError => e
65
+ # => You never get here!
66
+ end
67
+ ```
68
+
62
69
  You don't have the command? You get an exception:
63
70
 
64
71
  ```ruby
@@ -82,7 +89,7 @@ You can even give it a bunch of places to look:
82
89
 
83
90
  ```ruby
84
91
  FileUtils.rm("/opt/bin/lolwut")
85
- `echo 'echo Hello' > /usr/local/bin/lolwut`
92
+ File.open('/usr/local/bin/lolwut') {|f| f.write('echo Hello') }
86
93
  Cocaine::CommandLine.path = ["/opt/bin", "/usr/local/bin"]
87
94
  line = Cocaine::CommandLine.new("lolwut")
88
95
  line.run # => prints 'Hello', because it searches the path
@@ -95,17 +102,6 @@ line = Cocaine::CommandLine.new("/opt/bin/lolwut")
95
102
  line.command # => "/opt/bin/lolwut"
96
103
  ```
97
104
 
98
- If your command might return something non-zero, and you expect that, it's cool:
99
-
100
- ```ruby
101
- line = Cocaine::CommandLine.new("/usr/bin/false", "", :expected_outcodes => [0, 1])
102
- begin
103
- line.run
104
- rescue Cocaine::ExitStatusError => e
105
- # => You never get here!
106
- end
107
- ```
108
-
109
105
  You can see what's getting run. The 'Command' part it logs is in green for visibility!
110
106
 
111
107
  ```ruby
@@ -113,13 +109,34 @@ line = Cocaine::CommandLine.new("echo", ":var", :var => "LOL!", :logger => Logge
113
109
  line.run # => Logs this with #info -> Command :: echo 'LOL!'
114
110
  ```
115
111
 
116
- But you don't have to, as you saw above where it doesn't use this. But you CAN log every command!
112
+ Or log every command:
117
113
 
118
114
  ```ruby
119
115
  Cocaine::CommandLine.logger = Logger.new(STDOUT)
120
116
  Cocaine::CommandLine.new("date").run # => Logs this -> Command :: date
121
117
  ```
122
118
 
119
+ ## POSIX Spawn
120
+
121
+ You can potentially increase performance by installing [the posix-spawn
122
+ gem](https://rubygems.org/gems/posix-spawn). This gem can keep your
123
+ application's heap from being copied when forking command line
124
+ processes. For applications with large heaps the gain can be
125
+ significant. To include `posix-spawn`, simply add it to your `Gemfile` or,
126
+ if you don't use bundler, install the gem.
127
+
128
+ ## Feedback
129
+
130
+ *Security* concerns must be privately emailed to
131
+ [security@thoughtbot.com](security@thoughtbot.com).
132
+
133
+ Question? Idea? Problem? Bug? Comment? Concern? Like using question marks?
134
+
135
+ [GitHub Issues For All!](https://github.com/thoughtbot/cocaine/issues)
136
+
123
137
  ## License
124
138
 
125
- Copyright 2011 Jon Yurek and thoughtbot, inc. This is free software, and may be redistributed under the terms specified in the LICENSE file.
139
+ Copyright 2011 Jon Yurek and thoughtbot, inc. This is free software, and
140
+ may be redistributed under the terms specified in the
141
+ [LICENSE](https://github.com/thoughtbot/cocaine/blob/master/LICENSE)
142
+ file.
@@ -20,5 +20,6 @@ Gem::Specification.new do |s|
20
20
  s.add_development_dependency('bourne')
21
21
  s.add_development_dependency('mocha')
22
22
  s.add_development_dependency('rake')
23
+ s.add_development_dependency('posix-spawn')
23
24
  end
24
25
 
@@ -1,5 +1,6 @@
1
1
  require 'rbconfig'
2
2
  require 'cocaine/command_line'
3
+ require 'cocaine/command_line/runners'
3
4
  require 'cocaine/exceptions'
4
5
 
5
6
  module Cocaine
@@ -1,8 +1,33 @@
1
1
  module Cocaine
2
2
  class CommandLine
3
3
  class << self
4
- attr_accessor :path, :logger
4
+ attr_accessor :logger
5
+
6
+ def path
7
+ @supplemental_path
8
+ end
9
+ def path=(supplemental_path)
10
+ @supplemental_path = supplemental_path
11
+ @supplemental_environment ||= {}
12
+ @supplemental_environment['PATH'] = [ENV['PATH'], *supplemental_path].join(File::PATH_SEPARATOR)
13
+ end
14
+
15
+ def posix_spawn_available?
16
+ @posix_spawn_available ||= begin
17
+ require 'posix/spawn'
18
+ true
19
+ rescue LoadError => e
20
+ false
21
+ end
22
+ end
23
+
24
+ def environment
25
+ @supplemental_environment ||= {}
26
+ end
5
27
  end
28
+ @environment = {}
29
+
30
+ attr_reader :exit_status, :runner
6
31
 
7
32
  def initialize(binary, params = "", options = {})
8
33
  @binary = binary.dup
@@ -12,6 +37,7 @@ module Cocaine
12
37
  @swallow_stderr = @options.delete(:swallow_stderr)
13
38
  @expected_outcodes = @options.delete(:expected_outcodes)
14
39
  @expected_outcodes ||= [0]
40
+ @runner = best_runner
15
41
  end
16
42
 
17
43
  def command
@@ -25,12 +51,12 @@ module Cocaine
25
51
  def run
26
52
  output = ''
27
53
  begin
28
- with_modified_path do
29
- @logger.info("\e[32mCommand\e[0m :: #{command}") if @logger
30
- output = self.class.send(:'`', command)
31
- end
54
+ @logger.info("\e[32mCommand\e[0m :: #{command}") if @logger
55
+ output = execute(command)
32
56
  rescue Errno::ENOENT
33
57
  raise Cocaine::CommandNotFoundError
58
+ ensure
59
+ @exit_status = $?.exitstatus
34
60
  end
35
61
  if $?.exitstatus == 127
36
62
  raise Cocaine::CommandNotFoundError
@@ -41,17 +67,20 @@ module Cocaine
41
67
  output
42
68
  end
43
69
 
70
+ def unix?
71
+ (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/).nil?
72
+ end
73
+
44
74
  private
45
75
 
46
- def with_modified_path
47
- begin
48
- saved_path = ENV['PATH']
49
- extra_path = [self.class.path].flatten
50
- ENV['PATH'] = [ENV['PATH'], *extra_path].join(File::PATH_SEPARATOR)
51
- yield
52
- ensure
53
- ENV['PATH'] = saved_path
54
- end
76
+ def execute(command)
77
+ runner.call(command, self.class.environment)
78
+ end
79
+
80
+ def best_runner
81
+ return PosixRunner.new if self.class.posix_spawn_available?
82
+ return ProcessRunner.new if Process.respond_to?(:spawn)
83
+ BackticksRunner.new
55
84
  end
56
85
 
57
86
  def interpolate(pattern, vars)
@@ -78,20 +107,20 @@ module Cocaine
78
107
  end
79
108
 
80
109
  def shell_quote(string)
81
- return "" if string.nil? or string.empty?
82
- if self.class.unix?
83
- string.split("'").map{|m| "'#{m}'" }.join("\\'")
110
+ return "" if string.nil?
111
+ if unix?
112
+ if string.empty?
113
+ "''"
114
+ else
115
+ string.split("'").map{|m| "'#{m}'" }.join("\\'")
116
+ end
84
117
  else
85
118
  %{"#{string}"}
86
119
  end
87
120
  end
88
121
 
89
122
  def bit_bucket
90
- self.class.unix? ? "2>/dev/null" : "2>NUL"
91
- end
92
-
93
- def self.unix?
94
- (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/).nil?
123
+ unix? ? "2>/dev/null" : "2>NUL"
95
124
  end
96
125
  end
97
126
  end
@@ -0,0 +1,3 @@
1
+ require 'cocaine/command_line/runners/backticks_runner'
2
+ require 'cocaine/command_line/runners/process_runner'
3
+ require 'cocaine/command_line/runners/posix_runner'
@@ -0,0 +1,25 @@
1
+ module Cocaine
2
+ class CommandLine
3
+ class BackticksRunner
4
+
5
+ def call(command, env = {})
6
+ with_modified_environment(env) do
7
+ `#{command}`
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def with_modified_environment(env)
14
+ begin
15
+ saved_env = ENV.to_hash
16
+ ENV.update(env)
17
+ yield
18
+ ensure
19
+ ENV.update(saved_env)
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ module Cocaine
2
+ class CommandLine
3
+ class PosixRunner
4
+ if Cocaine::CommandLine.posix_spawn_available?
5
+
6
+ def call(command, env = {})
7
+ input, output = IO.pipe
8
+ pid = spawn(env, command, :out => output)
9
+ waitpid(pid)
10
+ output.close
11
+ input.read
12
+ end
13
+
14
+ private
15
+
16
+ def spawn(*args)
17
+ POSIX::Spawn.spawn(*args)
18
+ end
19
+
20
+ def waitpid(pid)
21
+ Process.waitpid(pid)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ module Cocaine
2
+ class CommandLine
3
+ class ProcessRunner
4
+ if Process.respond_to?(:spawn)
5
+
6
+ def call(command, env = {})
7
+ input, output = IO.pipe
8
+ pid = spawn(env, command, :out => output)
9
+ waitpid(pid)
10
+ output.close
11
+ input.read
12
+ end
13
+
14
+ private
15
+
16
+ def spawn(*args)
17
+ Process.spawn(*args)
18
+ end
19
+
20
+ def waitpid(pid)
21
+ Process.waitpid(pid)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -1,3 +1,3 @@
1
1
  module Cocaine
2
- VERSION = "0.2.1".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cocaine::CommandLine::BackticksRunner do
4
+ it 'runs the command given' do
5
+ subject.call("echo hello").should == "hello\n"
6
+ end
7
+
8
+ it 'modifies the environment and runs the command given' do
9
+ subject.call("echo $yes", {"yes" => "no"}).should == "no\n"
10
+ end
11
+
12
+ it 'sets the exitstatus when a command completes' do
13
+ subject.call("ruby -e 'exit 0'")
14
+ $?.exitstatus.should == 0
15
+ subject.call("ruby -e 'exit 5'")
16
+ $?.exitstatus.should == 5
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cocaine::CommandLine::PosixRunner do
4
+ if Cocaine::CommandLine::posix_spawn_available?
5
+ it 'runs the command given' do
6
+ subject.call("echo hello").should == "hello\n"
7
+ end
8
+
9
+ it 'modifies the environment and runs the command given' do
10
+ subject.call("echo $yes", {"yes" => "no"}).should == "no\n"
11
+ end
12
+
13
+ it 'sets the exitstatus when a command completes' do
14
+ subject.call("ruby -e 'exit 0'")
15
+ $?.exitstatus.should == 0
16
+ subject.call("ruby -e 'exit 5'")
17
+ $?.exitstatus.should == 5
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cocaine::CommandLine::ProcessRunner do
4
+ if Process.respond_to?(:spawn)
5
+ it 'runs the command given' do
6
+ subject.call("echo hello").should == "hello\n"
7
+ end
8
+
9
+ it 'modifies the environment and runs the command given' do
10
+ subject.call("echo $yes", {"yes" => "no"}).should == "no\n"
11
+ end
12
+
13
+ it 'sets the exitstatus when a command completes' do
14
+ subject.call("ruby -e 'exit 0'")
15
+ $?.exitstatus.should == 0
16
+ subject.call("ruby -e 'exit 5'")
17
+ $?.exitstatus.should == 5
18
+ end
19
+ end
20
+ end
@@ -26,6 +26,13 @@ describe Cocaine::CommandLine do
26
26
  output.should match(%r{/path/to/command/dir})
27
27
  output.should match(%r{/some/other/path})
28
28
  end
29
+
30
+ it "temporarily changes specified environment variables" do
31
+ Cocaine::CommandLine.environment['TEST'] = 'Hello, world!'
32
+ cmd = Cocaine::CommandLine.new("ruby", "-e 'puts ENV[%{TEST}]'")
33
+ output = cmd.run
34
+ output.should match(%r{Hello, world!})
35
+ end
29
36
 
30
37
  it "can interpolate quoted variables into the command line's parameters" do
31
38
  cmd = Cocaine::CommandLine.new("convert",
@@ -65,6 +72,15 @@ describe Cocaine::CommandLine do
65
72
  cmd.command.should == %{convert "`rm -rf`.jpg" "ha'ha.png"}
66
73
  end
67
74
 
75
+ it "quotes blank values into the command line's parameters" do
76
+ cmd = Cocaine::CommandLine.new("curl",
77
+ "-X POST -d :data :url",
78
+ :data => "",
79
+ :url => "http://localhost:9000",
80
+ :swallow_stderr => false)
81
+ cmd.command.should == "curl -X POST -d '' 'http://localhost:9000'"
82
+ end
83
+
68
84
  it "allows colons in parameters" do
69
85
  cmd = Cocaine::CommandLine.new("convert", "'a.jpg' xc:black 'b.jpg'", :swallow_stderr => false)
70
86
  cmd.command.should == "convert 'a.jpg' xc:black 'b.jpg'"
@@ -104,7 +120,7 @@ describe Cocaine::CommandLine do
104
120
 
105
121
  it "runs the command it's given and return the output" do
106
122
  cmd = Cocaine::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
107
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
123
+ cmd.stubs(:execute).with("convert a.jpg b.png").returns(:correct_value)
108
124
  with_exitstatus_returning(0) do
109
125
  cmd.run.should == :correct_value
110
126
  end
@@ -112,7 +128,7 @@ describe Cocaine::CommandLine do
112
128
 
113
129
  it "raises a CommandLineError if the result code from the command isn't expected" do
114
130
  cmd = Cocaine::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
115
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
131
+ cmd.stubs(:execute).with("convert a.jpg b.png").returns(:correct_value)
116
132
  with_exitstatus_returning(1) do
117
133
  lambda do
118
134
  cmd.run
@@ -125,7 +141,7 @@ describe Cocaine::CommandLine do
125
141
  "a.jpg b.png",
126
142
  :expected_outcodes => [0, 1],
127
143
  :swallow_stderr => false)
128
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
144
+ cmd.stubs(:execute).with("convert a.jpg b.png").returns(:correct_value)
129
145
  with_exitstatus_returning(1) do
130
146
  lambda do
131
147
  cmd.run
@@ -133,18 +149,27 @@ describe Cocaine::CommandLine do
133
149
  end
134
150
  end
135
151
 
152
+ it "should keep result code in #exitstatus" do
153
+ cmd = Cocaine::CommandLine.new("convert")
154
+ cmd.stubs(:execute).with("convert").returns(:correct_value)
155
+ with_exitstatus_returning(1) do
156
+ cmd.run rescue nil
157
+ end
158
+ cmd.exit_status.should == 1
159
+ end
160
+
136
161
  it "detects that the system is unix" do
137
- Cocaine::CommandLine.unix?.should be_true
162
+ Cocaine::CommandLine.new("convert").unix?.should be_true
138
163
  end
139
164
 
140
165
  it "detects that the system is windows" do
141
166
  on_windows!
142
- Cocaine::CommandLine.unix?.should be_false
167
+ Cocaine::CommandLine.new("convert").unix?.should be_false
143
168
  end
144
169
 
145
170
  it "detects that the system is windows (mingw)" do
146
- on_windows!("mingw")
147
- Cocaine::CommandLine.unix?.should be_false
171
+ on_mingw!
172
+ Cocaine::CommandLine.new("convert").unix?.should be_false
148
173
  end
149
174
 
150
175
  it "logs the command to a supplied logger" do
@@ -166,4 +191,29 @@ describe Cocaine::CommandLine do
166
191
  cmd = Cocaine::CommandLine.new("echo", "'Logging!'", :logger => nil)
167
192
  lambda { cmd.run }.should_not raise_error
168
193
  end
194
+
195
+ describe "command execution" do
196
+ it "uses the BackticksRunner by default" do
197
+ Process.stubs(:respond_to?).with(:spawn).returns(false)
198
+ Cocaine::CommandLine.stubs(:posix_spawn_available?).returns(false)
199
+
200
+ cmd = Cocaine::CommandLine.new("echo", "hello")
201
+ cmd.runner.class.should == Cocaine::CommandLine::BackticksRunner
202
+ end
203
+
204
+ it "uses the ProcessRunner on 1.9 and it's available" do
205
+ Process.stubs(:respond_to?).with(:spawn).returns(true)
206
+ Cocaine::CommandLine.stubs(:posix_spawn_available?).returns(false)
207
+
208
+ cmd = Cocaine::CommandLine.new("echo", "hello")
209
+ cmd.runner.class.should == Cocaine::CommandLine::ProcessRunner
210
+ end
211
+
212
+ it "uses the PosixRunner if the posix-spawn gem is available" do
213
+ Cocaine::CommandLine.stubs(:posix_spawn_available?).returns(true)
214
+
215
+ cmd = Cocaine::CommandLine.new("echo", "hello")
216
+ cmd.runner.class.should == Cocaine::CommandLine::PosixRunner
217
+ end
218
+ end
169
219
  end
@@ -1,10 +1,14 @@
1
1
  module StubOS
2
- def on_windows!(host_string = 'mswin')
3
- stub_os(host_string)
2
+ def on_windows!
3
+ stub_os('mswin')
4
4
  end
5
5
 
6
- def on_unix!(host_string = 'darwin11.0.0')
7
- stub_os(host_string)
6
+ def on_unix!
7
+ stub_os('darwin11.0.0')
8
+ end
9
+
10
+ def on_mingw!
11
+ stub_os('mingw')
8
12
  end
9
13
 
10
14
  def stub_os(host_string)
metadata CHANGED
@@ -1,137 +1,154 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: cocaine
3
- version: !ruby/object:Gem::Version
4
- hash: 21
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Jon Yurek
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-12-13 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-08-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rspec
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
32
22
  type: :development
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: bourne
36
23
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
38
25
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 3
43
- segments:
44
- - 0
45
- version: "0"
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bourne
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
46
38
  type: :development
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
49
- name: mocha
50
39
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
52
41
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- hash: 3
57
- segments:
58
- - 0
59
- version: "0"
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: mocha
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
60
54
  type: :development
61
- version_requirements: *id003
62
- - !ruby/object:Gem::Dependency
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
63
  name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
64
71
  prerelease: false
65
- requirement: &id004 !ruby/object:Gem::Requirement
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: posix-spawn
80
+ requirement: !ruby/object:Gem::Requirement
66
81
  none: false
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 3
71
- segments:
72
- - 0
73
- version: "0"
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
74
86
  type: :development
75
- version_requirements: *id004
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
76
94
  description: A small library for doing (command) lines
77
95
  email: jyurek@thoughtbot.com
78
96
  executables: []
79
-
80
97
  extensions: []
81
-
82
98
  extra_rdoc_files: []
83
-
84
- files:
99
+ files:
85
100
  - .gitignore
86
101
  - .travis.yml
102
+ - GOALS
87
103
  - Gemfile
88
104
  - LICENSE
105
+ - NEWS.md
89
106
  - README.md
90
107
  - Rakefile
91
108
  - cocaine.gemspec
92
109
  - lib/cocaine.rb
93
110
  - lib/cocaine/command_line.rb
111
+ - lib/cocaine/command_line/runners.rb
112
+ - lib/cocaine/command_line/runners/backticks_runner.rb
113
+ - lib/cocaine/command_line/runners/posix_runner.rb
114
+ - lib/cocaine/command_line/runners/process_runner.rb
94
115
  - lib/cocaine/exceptions.rb
95
116
  - lib/cocaine/version.rb
117
+ - spec/cocaine/command_line/runners/backticks_runner_spec.rb
118
+ - spec/cocaine/command_line/runners/posix_runner_spec.rb
119
+ - spec/cocaine/command_line/runners/process_runner_spec.rb
96
120
  - spec/cocaine/command_line_spec.rb
97
121
  - spec/spec_helper.rb
98
122
  - spec/support/stub_os.rb
99
123
  - spec/support/with_exitstatus.rb
100
124
  homepage: http://www.thoughtbot.com/projects/cocaine
101
125
  licenses: []
102
-
103
126
  post_install_message:
104
127
  rdoc_options: []
105
-
106
- require_paths:
128
+ require_paths:
107
129
  - lib
108
- required_ruby_version: !ruby/object:Gem::Requirement
130
+ required_ruby_version: !ruby/object:Gem::Requirement
109
131
  none: false
110
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- hash: 3
114
- segments:
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ segments:
115
137
  - 0
116
- version: "0"
117
- required_rubygems_version: !ruby/object:Gem::Requirement
138
+ hash: 2124621343266974199
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
140
  none: false
119
- requirements:
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- hash: 3
123
- segments:
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ segments:
124
146
  - 0
125
- version: "0"
147
+ hash: 2124621343266974199
126
148
  requirements: []
127
-
128
149
  rubyforge_project:
129
- rubygems_version: 1.8.6
150
+ rubygems_version: 1.8.24
130
151
  signing_key:
131
152
  specification_version: 3
132
153
  summary: A small library for doing (command) lines
133
- test_files:
134
- - spec/cocaine/command_line_spec.rb
135
- - spec/spec_helper.rb
136
- - spec/support/stub_os.rb
137
- - spec/support/with_exitstatus.rb
154
+ test_files: []