cocaine 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of cocaine might be problematic. Click here for more details.
- data/.travis.yml +0 -1
- data/README.md +24 -11
- data/lib/cocaine/command_line.rb +7 -24
- data/lib/cocaine/version.rb +1 -1
- data/spec/cocaine/command_line_spec.rb +19 -33
- data/spec/support/nonblocking_examples.rb +1 -1
- metadata +85 -92
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -17,21 +17,21 @@ line.run # => "hello world\n"
|
|
17
17
|
Interpolated arguments:
|
18
18
|
|
19
19
|
```ruby
|
20
|
-
line = Cocaine::CommandLine.new("convert", ":in -scale :resolution :out"
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
line = Cocaine::CommandLine.new("convert", ":in -scale :resolution :out")
|
21
|
+
line.command(:in => "omg.jpg",
|
22
|
+
:resolution => "32x32",
|
23
|
+
:out => "omg_thumb.jpg")
|
24
|
+
# => "convert 'omg.jpg' -scale '32x32' 'omg_thumb.jpg'"
|
25
25
|
```
|
26
26
|
|
27
27
|
It prevents attempts at being bad:
|
28
28
|
|
29
29
|
```ruby
|
30
|
-
line = Cocaine::CommandLine.new("cat", ":file"
|
31
|
-
line.command # => "cat 'haha`rm -rf /`.txt'"
|
30
|
+
line = Cocaine::CommandLine.new("cat", ":file")
|
31
|
+
line.command(:file => "haha`rm -rf /`.txt") # => "cat 'haha`rm -rf /`.txt'"
|
32
32
|
|
33
|
-
line = Cocaine::CommandLine.new("cat", ":file"
|
34
|
-
line.command # => "cat 'ohyeah?'\\''`rm -rf /`.ha!'"
|
33
|
+
line = Cocaine::CommandLine.new("cat", ":file")
|
34
|
+
line.command(:file => "ohyeah?'`rm -rf /`.ha!") # => "cat 'ohyeah?'\\''`rm -rf /`.ha!'"
|
35
35
|
```
|
36
36
|
|
37
37
|
You can ignore the result:
|
@@ -105,8 +105,8 @@ line.command # => "/opt/bin/lolwut"
|
|
105
105
|
You can see what's getting run. The 'Command' part it logs is in green for visibility!
|
106
106
|
|
107
107
|
```ruby
|
108
|
-
line = Cocaine::CommandLine.new("echo", ":var", :
|
109
|
-
line.run # => Logs this with #info -> Command :: echo 'LOL!'
|
108
|
+
line = Cocaine::CommandLine.new("echo", ":var", :logger => Logger.new(STDOUT))
|
109
|
+
line.run(:var => "LOL!") # => Logs this with #info -> Command :: echo 'LOL!'
|
110
110
|
```
|
111
111
|
|
112
112
|
Or log every command:
|
@@ -149,6 +149,19 @@ in https://github.com/thoughtbot/cocaine/issues/24 and probably fixed in
|
|
149
149
|
http://jira.codehaus.org/browse/JRUBY-6162. You *will* want to use the
|
150
150
|
`BackticksRunner` if you are unable to update JRuby.
|
151
151
|
|
152
|
+
## REE
|
153
|
+
|
154
|
+
So, here's the thing about REE: The specs that involve timeouts don't work
|
155
|
+
there. Not because the logic is unsound, but because the command runs really
|
156
|
+
slowly. The test passes -- eventually. This was verified using an external
|
157
|
+
debugger: the process that REE kicks off in the tests reads and writes
|
158
|
+
surprisingly slowly. For this reason, we cannot recommend using Cocaine with
|
159
|
+
REE anymore.
|
160
|
+
|
161
|
+
It's not something we like, so if anyone has any insight into this problem,
|
162
|
+
we'd love to hear about it. But, for the time being, we'll consider it more
|
163
|
+
appropriate to just not use it anymore. Upgrade to 1.9.3, people.
|
164
|
+
|
152
165
|
## Feedback
|
153
166
|
|
154
167
|
*Security* concerns must be privately emailed to
|
data/lib/cocaine/command_line.rb
CHANGED
@@ -52,19 +52,19 @@ module Cocaine
|
|
52
52
|
@environment = @options.delete(:environment) || {}
|
53
53
|
end
|
54
54
|
|
55
|
-
def command
|
55
|
+
def command(interpolations = {})
|
56
56
|
cmd = []
|
57
57
|
cmd << @binary
|
58
|
-
cmd << interpolate(@params,
|
58
|
+
cmd << interpolate(@params, interpolations)
|
59
59
|
cmd << bit_bucket if @swallow_stderr
|
60
60
|
cmd.join(" ").strip
|
61
61
|
end
|
62
62
|
|
63
|
-
def run
|
63
|
+
def run(interpolations = {})
|
64
64
|
output = ''
|
65
65
|
begin
|
66
66
|
@logger.info("\e[32mCommand\e[0m :: #{command}") if @logger
|
67
|
-
output = execute(command)
|
67
|
+
output = execute(command(interpolations))
|
68
68
|
rescue Errno::ENOENT
|
69
69
|
raise Cocaine::CommandNotFoundError
|
70
70
|
ensure
|
@@ -93,26 +93,9 @@ module Cocaine
|
|
93
93
|
self.class.environment.merge(@environment)
|
94
94
|
end
|
95
95
|
|
96
|
-
def interpolate(pattern,
|
97
|
-
|
98
|
-
|
99
|
-
key = match[1..-1]
|
100
|
-
key = key[1..-2] if key[0,1] == '{'
|
101
|
-
if invalid_variables.include?(key)
|
102
|
-
raise InterpolationError,
|
103
|
-
"Interpolation of #{key} isn't allowed."
|
104
|
-
end
|
105
|
-
interpolation(vars, key) || match
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def invalid_variables
|
110
|
-
%w(expected_outcodes swallow_stderr logger environment)
|
111
|
-
end
|
112
|
-
|
113
|
-
def interpolation(vars, key)
|
114
|
-
if vars.key?(key.to_sym)
|
115
|
-
shell_quote(vars[key.to_sym])
|
96
|
+
def interpolate(pattern, interpolations)
|
97
|
+
interpolations.inject(pattern) do |command_string, (key, value)|
|
98
|
+
command_string.gsub(/:\{?#{key}\}?/) { shell_quote(value) }
|
116
99
|
end
|
117
100
|
end
|
118
101
|
|
data/lib/cocaine/version.rb
CHANGED
@@ -52,48 +52,49 @@ describe Cocaine::CommandLine do
|
|
52
52
|
it "can interpolate quoted variables into the command line's parameters" do
|
53
53
|
cmd = Cocaine::CommandLine.new("convert",
|
54
54
|
":one :{two}",
|
55
|
-
:one => "a.jpg",
|
56
|
-
:two => "b.png",
|
57
55
|
:swallow_stderr => false)
|
58
|
-
|
56
|
+
|
57
|
+
command_string = cmd.command(:one => "a.jpg", :two => "b.png")
|
58
|
+
command_string.should == "convert 'a.jpg' 'b.png'"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "interpolates when running a command" do
|
62
|
+
command = Cocaine::CommandLine.new("echo", ":hello_world")
|
63
|
+
command.run(:hello_world => "Hello, world").should match(/Hello, world/)
|
59
64
|
end
|
60
65
|
|
61
66
|
it "quotes command line options differently if we're on windows" do
|
62
67
|
on_windows!
|
63
68
|
cmd = Cocaine::CommandLine.new("convert",
|
64
69
|
":one :{two}",
|
65
|
-
:one => "a.jpg",
|
66
|
-
:two => "b.png",
|
67
70
|
:swallow_stderr => false)
|
68
|
-
cmd.command
|
71
|
+
command_string = cmd.command(:one => "a.jpg", :two => "b.png")
|
72
|
+
command_string.should == 'convert "a.jpg" "b.png"'
|
69
73
|
end
|
70
74
|
|
71
75
|
it "can quote and interpolate dangerous variables" do
|
72
76
|
cmd = Cocaine::CommandLine.new("convert",
|
73
77
|
":one :two",
|
74
|
-
:one => "`rm -rf`.jpg",
|
75
|
-
:two => "ha'ha.png",
|
76
78
|
:swallow_stderr => false)
|
77
|
-
cmd.command
|
79
|
+
command_string = cmd.command(:one => "`rm -rf`.jpg", :two => "ha'ha.png")
|
80
|
+
command_string.should == "convert '`rm -rf`.jpg' 'ha'\\''ha.png'"
|
78
81
|
end
|
79
82
|
|
80
83
|
it "can quote and interpolate dangerous variables even on windows" do
|
81
84
|
on_windows!
|
82
85
|
cmd = Cocaine::CommandLine.new("convert",
|
83
86
|
":one :two",
|
84
|
-
:one => "`rm -rf`.jpg",
|
85
|
-
:two => "ha'ha.png",
|
86
87
|
:swallow_stderr => false)
|
87
|
-
cmd.command
|
88
|
+
command_string = cmd.command(:one => "`rm -rf`.jpg", :two => "ha'ha.png")
|
89
|
+
command_string.should == %{convert "`rm -rf`.jpg" "ha'ha.png"}
|
88
90
|
end
|
89
91
|
|
90
92
|
it "quotes blank values into the command line's parameters" do
|
91
93
|
cmd = Cocaine::CommandLine.new("curl",
|
92
94
|
"-X POST -d :data :url",
|
93
|
-
:data => "",
|
94
|
-
:url => "http://localhost:9000",
|
95
95
|
:swallow_stderr => false)
|
96
|
-
cmd.command
|
96
|
+
command_string = cmd.command(:data => "", :url => "http://localhost:9000")
|
97
|
+
command_string.should == "curl -X POST -d '' 'http://localhost:9000'"
|
97
98
|
end
|
98
99
|
|
99
100
|
it "allows colons in parameters" do
|
@@ -118,21 +119,6 @@ describe Cocaine::CommandLine do
|
|
118
119
|
cmd.command.should == "convert a.jpg b.png 2>NUL"
|
119
120
|
end
|
120
121
|
|
121
|
-
it "raises if trying to interpolate :swallow_stderr" do
|
122
|
-
cmd = Cocaine::CommandLine.new("convert", ":swallow_stderr", :swallow_stderr => false)
|
123
|
-
lambda { cmd.command }.should raise_error(Cocaine::CommandLineError)
|
124
|
-
end
|
125
|
-
|
126
|
-
it "raises if trying to interpolate :expected_outcodes" do
|
127
|
-
cmd = Cocaine::CommandLine.new("convert", ":expected_outcodes", :expected_outcodes => [0])
|
128
|
-
lambda { cmd.command }.should raise_error(Cocaine::CommandLineError)
|
129
|
-
end
|
130
|
-
|
131
|
-
it "raises if trying to interpolate :logger" do
|
132
|
-
cmd = Cocaine::CommandLine.new("convert", ":logger", :logger => stub)
|
133
|
-
lambda { cmd.command }.should raise_error(Cocaine::CommandLineError)
|
134
|
-
end
|
135
|
-
|
136
122
|
it "runs the command it's given and return the output" do
|
137
123
|
cmd = Cocaine::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
|
138
124
|
cmd.stubs(:execute).with("convert a.jpg b.png").returns(:correct_value)
|
@@ -174,17 +160,17 @@ describe Cocaine::CommandLine do
|
|
174
160
|
end
|
175
161
|
|
176
162
|
it "detects that the system is unix" do
|
177
|
-
Cocaine::CommandLine.new("convert").
|
163
|
+
Cocaine::CommandLine.new("convert").should be_unix
|
178
164
|
end
|
179
165
|
|
180
166
|
it "detects that the system is windows" do
|
181
167
|
on_windows!
|
182
|
-
Cocaine::CommandLine.new("convert").
|
168
|
+
Cocaine::CommandLine.new("convert").should_not be_unix
|
183
169
|
end
|
184
170
|
|
185
171
|
it "detects that the system is windows (mingw)" do
|
186
172
|
on_mingw!
|
187
|
-
Cocaine::CommandLine.new("convert").
|
173
|
+
Cocaine::CommandLine.new("convert").should_not be_unix
|
188
174
|
end
|
189
175
|
|
190
176
|
it "logs the command to a supplied logger" do
|
@@ -3,7 +3,7 @@ shared_examples_for "a command that does not block" do
|
|
3
3
|
garbage_file = Tempfile.new("garbage")
|
4
4
|
10.times{ garbage_file.write("A" * 1024 * 1024) }
|
5
5
|
|
6
|
-
Timeout
|
6
|
+
Timeout.timeout(5) do
|
7
7
|
output = subject.call("cat '#{garbage_file.path}'")
|
8
8
|
$?.exitstatus.should == 0
|
9
9
|
output.length.should == 10 * 1024 * 1024
|
metadata
CHANGED
@@ -1,101 +1,102 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocaine
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 3
|
9
|
-
- 2
|
10
|
-
version: 0.3.2
|
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
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-10-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: rspec
|
22
|
-
|
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
|
-
|
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
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
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
|
38
33
|
none: false
|
39
|
-
requirements:
|
40
|
-
- -
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
segments:
|
44
|
-
- 0
|
45
|
-
version: "0"
|
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
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
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
|
52
49
|
none: false
|
53
|
-
requirements:
|
54
|
-
- -
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
|
57
|
-
segments:
|
58
|
-
- 0
|
59
|
-
version: "0"
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
60
54
|
type: :development
|
61
|
-
version_requirements: *id003
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: rake
|
64
55
|
prerelease: false
|
65
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
57
|
none: false
|
67
|
-
requirements:
|
68
|
-
- -
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
74
70
|
type: :development
|
75
|
-
version_requirements: *id004
|
76
|
-
- !ruby/object:Gem::Dependency
|
77
|
-
name: posix-spawn
|
78
71
|
prerelease: false
|
79
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
73
|
none: false
|
81
|
-
requirements:
|
82
|
-
- -
|
83
|
-
- !ruby/object:Gem::Version
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
88
86
|
type: :development
|
89
|
-
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
90
94
|
description: A small library for doing (command) lines
|
91
95
|
email: jyurek@thoughtbot.com
|
92
96
|
executables: []
|
93
|
-
|
94
97
|
extensions: []
|
95
|
-
|
96
98
|
extra_rdoc_files: []
|
97
|
-
|
98
|
-
files:
|
99
|
+
files:
|
99
100
|
- .gitignore
|
100
101
|
- .travis.yml
|
101
102
|
- GOALS
|
@@ -123,38 +124,29 @@ files:
|
|
123
124
|
- spec/support/with_exitstatus.rb
|
124
125
|
homepage: http://github.com/thoughtbot/cocaine
|
125
126
|
licenses: []
|
126
|
-
|
127
127
|
post_install_message:
|
128
128
|
rdoc_options: []
|
129
|
-
|
130
|
-
require_paths:
|
129
|
+
require_paths:
|
131
130
|
- lib
|
132
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
132
|
none: false
|
134
|
-
requirements:
|
135
|
-
- -
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
|
138
|
-
|
139
|
-
- 0
|
140
|
-
version: "0"
|
141
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
138
|
none: false
|
143
|
-
requirements:
|
144
|
-
- -
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
|
147
|
-
segments:
|
148
|
-
- 0
|
149
|
-
version: "0"
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
150
143
|
requirements: []
|
151
|
-
|
152
144
|
rubyforge_project:
|
153
145
|
rubygems_version: 1.8.24
|
154
146
|
signing_key:
|
155
147
|
specification_version: 3
|
156
148
|
summary: A small library for doing (command) lines
|
157
|
-
test_files:
|
149
|
+
test_files:
|
158
150
|
- spec/cocaine/command_line/runners/backticks_runner_spec.rb
|
159
151
|
- spec/cocaine/command_line/runners/posix_runner_spec.rb
|
160
152
|
- spec/cocaine/command_line/runners/process_runner_spec.rb
|
@@ -163,3 +155,4 @@ test_files:
|
|
163
155
|
- spec/support/nonblocking_examples.rb
|
164
156
|
- spec/support/stub_os.rb
|
165
157
|
- spec/support/with_exitstatus.rb
|
158
|
+
has_rdoc:
|