ridley 1.0.3 → 1.1.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/.ruby-version +1 -1
- data/lib/ridley/chef/cookbook/syntax_check.rb +2 -1
- data/lib/ridley/chef_object.rb +3 -1
- data/lib/ridley/chef_objects/node_object.rb +7 -4
- data/lib/ridley/errors.rb +3 -0
- data/lib/ridley/host_connector/winrm.rb +1 -5
- data/lib/ridley/sandbox_uploader.rb +31 -25
- data/lib/ridley/version.rb +1 -1
- data/ridley.gemspec +1 -0
- data/spec/acceptance/sandbox_resource_spec.rb +2 -2
- data/spec/unit/ridley/chef_object_spec.rb +12 -5
- data/spec/unit/ridley/chef_objects/node_object_spec.rb +49 -0
- data/spec/unit/ridley/sandbox_uploader_spec.rb +25 -28
- metadata +19 -6
- data/lib/ridley/mixin/shell_out.rb +0 -84
- data/spec/unit/ridley/mixin/shell_out_spec.rb +0 -37
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.9.3-
|
1
|
+
1.9.3-p429
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shellwords'
|
2
|
+
require 'buff/shell_out'
|
2
3
|
|
3
4
|
module Ridley::Chef
|
4
5
|
class Cookbook
|
@@ -67,8 +68,8 @@ module Ridley::Chef
|
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
71
|
+
include Buff::ShellOut
|
70
72
|
include Ridley::Logging
|
71
|
-
include Ridley::Mixin::ShellOut
|
72
73
|
include Ridley::Mixin::Checksum
|
73
74
|
|
74
75
|
attr_reader :cookbook_path
|
data/lib/ridley/chef_object.rb
CHANGED
@@ -30,10 +30,13 @@ module Ridley
|
|
30
30
|
alias_method :default_attributes, :default
|
31
31
|
alias_method :override_attributes, :override
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
# A merged hash containing a deep merge of all of the attributes respecting the node attribute
|
34
|
+
# precedence level.
|
35
|
+
#
|
36
|
+
# @return [hashie::Mash]
|
37
|
+
def chef_attributes
|
38
|
+
default.merge(normal.merge(override.merge(automatic)))
|
39
|
+
end
|
37
40
|
|
38
41
|
# Set a node level normal attribute given the dotted path representation of the Chef
|
39
42
|
# attribute and value.
|
data/lib/ridley/errors.rb
CHANGED
@@ -65,6 +65,9 @@ module Ridley
|
|
65
65
|
class SandboxCommitError < RidleyError; end
|
66
66
|
class PermissionDenied < RidleyError; end
|
67
67
|
|
68
|
+
class SandboxUploadError < RidleyError; end
|
69
|
+
class ChecksumMismatch < RidleyError; end
|
70
|
+
|
68
71
|
class HTTPError < RidleyError
|
69
72
|
class << self
|
70
73
|
def fabricate(env)
|
@@ -81,11 +81,7 @@ module Ridley
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
ensure
|
84
|
-
|
85
|
-
command_uploaders.map(&:cleanup)
|
86
|
-
rescue ::WinRM::WinRMHTTPTransportError => ex
|
87
|
-
log.info "Error cleaning up leftover Powershell scripts on some hosts"
|
88
|
-
end
|
84
|
+
command_uploaders.map(&:cleanup)
|
89
85
|
end
|
90
86
|
|
91
87
|
# Returns the command if it does not break the WinRM command length
|
@@ -4,35 +4,30 @@ module Ridley
|
|
4
4
|
class << self
|
5
5
|
# Return the checksum of the contents of the file at the given filepath
|
6
6
|
#
|
7
|
-
# @param [String]
|
8
|
-
#
|
7
|
+
# @param [String] io
|
8
|
+
# a filepath or an IO
|
9
|
+
# @param [Digest::Base] digest
|
9
10
|
#
|
10
11
|
# @return [String]
|
11
12
|
# the binary checksum of the contents of the file
|
12
|
-
def checksum(
|
13
|
-
|
13
|
+
def checksum(io, digest = Digest::MD5.new)
|
14
|
+
io = io.dup
|
15
|
+
while chunk = io.read(1024 * 8)
|
16
|
+
digest.update(chunk)
|
17
|
+
end
|
18
|
+
digest.hexdigest
|
14
19
|
end
|
15
20
|
|
16
21
|
# Return a base64 encoded checksum of the contents of the given file. This is the expected
|
17
22
|
# format of sandbox checksums given to the Chef Server.
|
18
23
|
#
|
19
|
-
# @param [String] path
|
20
|
-
#
|
21
|
-
# @return [String]
|
22
|
-
# a base64 encoded checksum
|
23
|
-
def checksum64(path)
|
24
|
-
Base64.encode64([checksum(path)].pack("H*")).strip
|
25
|
-
end
|
26
|
-
|
27
24
|
# @param [String] io
|
28
|
-
#
|
25
|
+
# a filepath or an IO
|
29
26
|
#
|
30
27
|
# @return [String]
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
digest.hexdigest
|
28
|
+
# a base64 encoded checksum
|
29
|
+
def checksum64(io)
|
30
|
+
Base64.encode64([checksum(io)].pack("H*")).strip
|
36
31
|
end
|
37
32
|
end
|
38
33
|
|
@@ -53,22 +48,33 @@ module Ridley
|
|
53
48
|
# @param [Ridley::SandboxObject] sandbox
|
54
49
|
# @param [String] chk_id
|
55
50
|
# checksum of the file being uploaded
|
56
|
-
# @param [String]
|
57
|
-
#
|
51
|
+
# @param [String, #read] file
|
52
|
+
# a filepath or an IO
|
53
|
+
#
|
54
|
+
# @raise [Errors::ChecksumMismatch]
|
55
|
+
# if the given file does not match the expected checksum
|
58
56
|
#
|
59
57
|
# @return [Hash, nil]
|
60
|
-
def upload(sandbox, chk_id,
|
58
|
+
def upload(sandbox, chk_id, file)
|
61
59
|
checksum = sandbox.checksum(chk_id)
|
62
60
|
|
63
61
|
unless checksum[:needs_upload]
|
64
62
|
return nil
|
65
63
|
end
|
66
64
|
|
67
|
-
|
65
|
+
io = file.respond_to?(:read) ? file : File.new(file, 'rb')
|
66
|
+
calculated_checksum = self.class.checksum64(io)
|
67
|
+
expected_checksum = Base64.encode64([chk_id].pack('H*')).strip
|
68
|
+
|
69
|
+
unless calculated_checksum == expected_checksum
|
70
|
+
raise Errors::ChecksumMismatch,
|
71
|
+
"Error uploading #{chk_id}. Expected #{expected_checksum} but got #{calculated_checksum}"
|
72
|
+
end
|
73
|
+
|
74
|
+
headers = {
|
68
75
|
'Content-Type' => 'application/x-binary',
|
69
|
-
'content-md5' =>
|
76
|
+
'content-md5' => calculated_checksum
|
70
77
|
}
|
71
|
-
contents = File.open(path, 'rb') { |f| f.read }
|
72
78
|
|
73
79
|
url = URI(checksum[:url])
|
74
80
|
upload_path = url.path
|
@@ -86,7 +92,7 @@ module Ridley
|
|
86
92
|
c.response :follow_redirects
|
87
93
|
c.request :chef_auth, self.client_name, self.client_key
|
88
94
|
c.adapter :net_http
|
89
|
-
end.put(upload_path,
|
95
|
+
end.put(upload_path, io.read, headers)
|
90
96
|
rescue Ridley::Errors::HTTPError => ex
|
91
97
|
abort(ex)
|
92
98
|
end
|
data/lib/ridley/version.rb
CHANGED
data/ridley.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.required_ruby_version = ">= 1.9.1"
|
19
19
|
|
20
20
|
s.add_runtime_dependency 'addressable'
|
21
|
+
s.add_runtime_dependency 'buff-shell_out', '~> 0.1'
|
21
22
|
s.add_runtime_dependency 'chozo', '>= 0.6.0'
|
22
23
|
s.add_runtime_dependency 'celluloid', '~> 0.14.0'
|
23
24
|
s.add_runtime_dependency 'celluloid-io', '~> 0.14.0'
|
@@ -8,8 +8,8 @@ describe "Sandbox API operations", type: "acceptance" do
|
|
8
8
|
|
9
9
|
let(:checksums) do
|
10
10
|
[
|
11
|
-
Ridley::SandboxUploader.checksum(fixtures_path.join("recipe_one.rb")),
|
12
|
-
Ridley::SandboxUploader.checksum(fixtures_path.join("recipe_two.rb"))
|
11
|
+
Ridley::SandboxUploader.checksum(File.open(fixtures_path.join("recipe_one.rb"))),
|
12
|
+
Ridley::SandboxUploader.checksum(File.open(fixtures_path.join("recipe_two.rb")))
|
13
13
|
]
|
14
14
|
end
|
15
15
|
|
@@ -142,21 +142,28 @@ describe Ridley::ChefObject do
|
|
142
142
|
end
|
143
143
|
|
144
144
|
describe "#reload" do
|
145
|
-
let(:updated_subject) { double('updated_subject', _attributes_: {
|
145
|
+
let(:updated_subject) { double('updated_subject', _attributes_: { one: "val" }) }
|
146
146
|
|
147
147
|
before(:each) do
|
148
|
-
subject.class.attribute(:
|
149
|
-
|
148
|
+
subject.class.attribute(:one)
|
149
|
+
subject.class.attribute(:two)
|
150
|
+
resource.stub(:find).with(subject).and_return(updated_subject)
|
150
151
|
end
|
151
152
|
|
152
153
|
it "returns itself" do
|
153
154
|
subject.reload.should eql(subject)
|
154
155
|
end
|
155
156
|
|
156
|
-
it "sets the attributes of self to
|
157
|
+
it "sets the attributes of self to equal those of the updated object" do
|
157
158
|
subject.reload
|
158
159
|
|
159
|
-
subject.get_attribute(:
|
160
|
+
subject.get_attribute(:one).should eql("val")
|
161
|
+
end
|
162
|
+
|
163
|
+
it "does not include attributes not set by the updated object" do
|
164
|
+
subject.two = "other"
|
165
|
+
subject.reload
|
166
|
+
expect(subject.two).to be_nil
|
160
167
|
end
|
161
168
|
end
|
162
169
|
|
@@ -5,6 +5,55 @@ describe Ridley::NodeObject do
|
|
5
5
|
let(:instance) { described_class.new(resource) }
|
6
6
|
subject { instance }
|
7
7
|
|
8
|
+
describe "#chef_attributes" do
|
9
|
+
subject { instance.chef_attributes }
|
10
|
+
|
11
|
+
it "returns a Hashie::Mash" do
|
12
|
+
expect(subject).to be_a(Hashie::Mash)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "includes default attributes" do
|
16
|
+
instance.default = default = { default: { one: "val", two: "val" } }
|
17
|
+
expect(subject.to_hash).to include(default)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "includes normal attributes" do
|
21
|
+
instance.normal = normal = { normal: { one: "new", two: "val" } }
|
22
|
+
expect(subject.to_hash).to include(normal)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "includes override attributes" do
|
26
|
+
instance.override = override = { override: { one: "new", two: "val" } }
|
27
|
+
expect(subject.to_hash).to include(override)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "includes automatic attributes" do
|
31
|
+
instance.automatic = automatic = { automatic: { one: "new", two: "val" } }
|
32
|
+
expect(subject.to_hash).to include(automatic)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "overrides default attributes with normal attributes" do
|
36
|
+
instance.default = default = { one: "old", two: "old" }
|
37
|
+
instance.normal = normal = { one: "new" }
|
38
|
+
expect(subject[:one]).to eql("new")
|
39
|
+
expect(subject[:two]).to eql("old")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "overrides normal attributes with override attributes" do
|
43
|
+
instance.normal = normal = { one: "old", two: "old" }
|
44
|
+
instance.override = override = { one: "new" }
|
45
|
+
expect(subject[:one]).to eql("new")
|
46
|
+
expect(subject[:two]).to eql("old")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "overrides override attributes with automatic attributes" do
|
50
|
+
instance.override = override = { one: "old", two: "old" }
|
51
|
+
instance.automatic = automatic = { one: "new" }
|
52
|
+
expect(subject[:one]).to eql("new")
|
53
|
+
expect(subject[:two]).to eql("old")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
8
57
|
describe "#set_chef_attribute" do
|
9
58
|
it "sets an normal node attribute at the nested path" do
|
10
59
|
subject.set_chef_attribute('deep.nested.item', true)
|
@@ -1,6 +1,24 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Ridley::SandboxUploader do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
describe "::checksum" do
|
8
|
+
let(:io) { StringIO.new("some long string") }
|
9
|
+
subject { described_class.checksum(io) }
|
10
|
+
|
11
|
+
it { should eq("2fb66bbfb88cdf9e07a3f1d1dfad71ab") }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "::checksum64" do
|
15
|
+
let(:io) { StringIO.new("some long string") }
|
16
|
+
subject { described_class.checksum64(io) }
|
17
|
+
|
18
|
+
it { should eq("L7Zrv7iM354Ho/HR361xqw==") }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
4
22
|
let(:client_name) { "reset" }
|
5
23
|
let(:client_key) { fixtures_path.join('reset.pem') }
|
6
24
|
let(:connection) do
|
@@ -22,35 +40,14 @@ describe Ridley::SandboxUploader do
|
|
22
40
|
|
23
41
|
let(:sandbox) { Ridley::SandboxObject.new(resource, checksums: checksums) }
|
24
42
|
|
25
|
-
describe "ClassMethods" do
|
26
|
-
subject { described_class }
|
27
|
-
|
28
|
-
describe "::checksum" do
|
29
|
-
subject { described_class.checksum(path) }
|
30
|
-
|
31
|
-
let(:path) { fixtures_path.join('reset.pem') }
|
32
|
-
|
33
|
-
it { should eq("a0608f1eb43ee4cca510bf95f8d209f7") }
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "::checksum64" do
|
37
|
-
subject { described_class.checksum64(path) }
|
38
|
-
|
39
|
-
let(:path) { fixtures_path.join('reset.pem') }
|
40
|
-
|
41
|
-
it { should eq("oGCPHrQ+5MylEL+V+NIJ9w==") }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
43
|
subject { described_class.new(client_name, client_key, {}) }
|
46
44
|
|
47
45
|
describe "#upload" do
|
48
|
-
let(:chk_id) { "
|
46
|
+
let(:chk_id) { "a0608f1eb43ee4cca510bf95f8d209f7" }
|
49
47
|
let(:path) { fixtures_path.join('reset.pem').to_s }
|
48
|
+
let(:different_path) { fixtures_path.join('recipe_one.rb').to_s }
|
50
49
|
|
51
|
-
before
|
52
|
-
connection.stub(foss?: false)
|
53
|
-
end
|
50
|
+
before { connection.stub(foss?: false) }
|
54
51
|
|
55
52
|
context "when the checksum needs uploading" do
|
56
53
|
let(:checksums) do
|
@@ -67,6 +64,10 @@ describe Ridley::SandboxUploader do
|
|
67
64
|
|
68
65
|
subject.upload(sandbox, chk_id, path)
|
69
66
|
end
|
67
|
+
|
68
|
+
it "raises an exception when the calcuated checksum does not match the expected checksum" do
|
69
|
+
expect { subject.upload(sandbox, chk_id, different_path) }.to raise_error(Ridley::Errors::ChecksumMismatch)
|
70
|
+
end
|
70
71
|
end
|
71
72
|
|
72
73
|
context "when the checksum doesn't need uploading" do
|
@@ -78,10 +79,6 @@ describe Ridley::SandboxUploader do
|
|
78
79
|
}
|
79
80
|
end
|
80
81
|
|
81
|
-
let(:sandbox) do
|
82
|
-
Ridley::SandboxObject.new(double, checksums: checksums)
|
83
|
-
end
|
84
|
-
|
85
82
|
it "returns nil" do
|
86
83
|
subject.upload(sandbox, chk_id, path).should be_nil
|
87
84
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ridley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-06-
|
13
|
+
date: 2013-06-12 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
@@ -28,6 +28,22 @@ dependencies:
|
|
28
28
|
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: buff-shell_out
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0.1'
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.1'
|
31
47
|
- !ruby/object:Gem::Dependency
|
32
48
|
name: chozo
|
33
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -280,7 +296,6 @@ files:
|
|
280
296
|
- lib/ridley/middleware/retry.rb
|
281
297
|
- lib/ridley/mixin.rb
|
282
298
|
- lib/ridley/mixin/checksum.rb
|
283
|
-
- lib/ridley/mixin/shell_out.rb
|
284
299
|
- lib/ridley/resource.rb
|
285
300
|
- lib/ridley/resources.rb
|
286
301
|
- lib/ridley/resources/client_resource.rb
|
@@ -356,7 +371,6 @@ files:
|
|
356
371
|
- spec/unit/ridley/middleware/chef_response_spec.rb
|
357
372
|
- spec/unit/ridley/middleware/gzip_spec.rb
|
358
373
|
- spec/unit/ridley/middleware/parse_json_spec.rb
|
359
|
-
- spec/unit/ridley/mixin/shell_out_spec.rb
|
360
374
|
- spec/unit/ridley/resource_spec.rb
|
361
375
|
- spec/unit/ridley/resources/client_resource_spec.rb
|
362
376
|
- spec/unit/ridley/resources/cookbook_resource_spec.rb
|
@@ -390,7 +404,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
390
404
|
version: '0'
|
391
405
|
segments:
|
392
406
|
- 0
|
393
|
-
hash: -
|
407
|
+
hash: -1556301606897048958
|
394
408
|
requirements: []
|
395
409
|
rubyforge_project:
|
396
410
|
rubygems_version: 1.8.23
|
@@ -457,7 +471,6 @@ test_files:
|
|
457
471
|
- spec/unit/ridley/middleware/chef_response_spec.rb
|
458
472
|
- spec/unit/ridley/middleware/gzip_spec.rb
|
459
473
|
- spec/unit/ridley/middleware/parse_json_spec.rb
|
460
|
-
- spec/unit/ridley/mixin/shell_out_spec.rb
|
461
474
|
- spec/unit/ridley/resource_spec.rb
|
462
475
|
- spec/unit/ridley/resources/client_resource_spec.rb
|
463
476
|
- spec/unit/ridley/resources/cookbook_resource_spec.rb
|
@@ -1,84 +0,0 @@
|
|
1
|
-
module Ridley
|
2
|
-
module Mixin
|
3
|
-
# A Ruby platform agnostic way of executing shell commands on the local system
|
4
|
-
module ShellOut
|
5
|
-
class Response
|
6
|
-
# @return [Fixnum]
|
7
|
-
attr_reader :exitstatus
|
8
|
-
# @return [String]
|
9
|
-
attr_reader :stdout
|
10
|
-
# @return [String]
|
11
|
-
attr_reader :stderr
|
12
|
-
|
13
|
-
# @param [Fixnum] exitstatus
|
14
|
-
# @param [String] stdout
|
15
|
-
# @param [String] stderr
|
16
|
-
def initialize(exitstatus, stdout, stderr)
|
17
|
-
@exitstatus = exitstatus
|
18
|
-
@stdout = stdout
|
19
|
-
@stderr = stderr
|
20
|
-
end
|
21
|
-
|
22
|
-
def success?
|
23
|
-
exitstatus == 0
|
24
|
-
end
|
25
|
-
|
26
|
-
def error?
|
27
|
-
!success?
|
28
|
-
end
|
29
|
-
alias_method :failure?, :error?
|
30
|
-
end
|
31
|
-
|
32
|
-
include Chozo::RubyEngine
|
33
|
-
extend self
|
34
|
-
|
35
|
-
# Executes the given shell command on the local system
|
36
|
-
#
|
37
|
-
# @param [String] command
|
38
|
-
# The command to execute
|
39
|
-
#
|
40
|
-
# @return [ShellOut::Response]
|
41
|
-
def shell_out(command)
|
42
|
-
process_status, out, err = jruby? ? jruby_out(command) : mri_out(command)
|
43
|
-
Response.new(process_status, out, err)
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
# @param [String] command
|
49
|
-
# The command to execute
|
50
|
-
def mri_out(command)
|
51
|
-
out, err = Tempfile.new('ridley.shell_out.stdout'), Tempfile.new('ridley.shell_out.stderr')
|
52
|
-
|
53
|
-
begin
|
54
|
-
pid = Process.spawn(command, out: out.to_i, err: err.to_i)
|
55
|
-
pid, status = Process.waitpid2(pid)
|
56
|
-
exitstatus = status.exitstatus
|
57
|
-
rescue Errno::ENOENT => ex
|
58
|
-
exitstatus = 127
|
59
|
-
out.write("")
|
60
|
-
err.write("command not found: #{command}")
|
61
|
-
end
|
62
|
-
|
63
|
-
out.close
|
64
|
-
err.close
|
65
|
-
|
66
|
-
[ exitstatus, File.read(out), File.read(err) ]
|
67
|
-
end
|
68
|
-
|
69
|
-
# @param [String] command
|
70
|
-
# The command to execute
|
71
|
-
def jruby_out(command)
|
72
|
-
out, err = StringIO.new, StringIO.new
|
73
|
-
$stdout, $stderr = out, err
|
74
|
-
system(command)
|
75
|
-
|
76
|
-
out.rewind
|
77
|
-
err.rewind
|
78
|
-
[ $?, out.read, err.read ]
|
79
|
-
ensure
|
80
|
-
$stdout, $stderr = STDOUT, STDERR
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Ridley::Mixin::ShellOut do
|
4
|
-
describe "shell_out" do
|
5
|
-
let(:command) { "ls" }
|
6
|
-
|
7
|
-
subject(:result) { described_class.shell_out(command) }
|
8
|
-
|
9
|
-
it "returns a ShellOut::Response" do
|
10
|
-
expect(result).to be_a(described_class::Response)
|
11
|
-
end
|
12
|
-
|
13
|
-
its(:stdout) { should be_a(String) }
|
14
|
-
its(:stderr) { should be_a(String) }
|
15
|
-
its(:exitstatus) { should be_a(Fixnum) }
|
16
|
-
its(:success?) { should be_true }
|
17
|
-
its(:error?) { should be_false }
|
18
|
-
|
19
|
-
context "when on MRI" do
|
20
|
-
before { described_class.stub(jruby?: false) }
|
21
|
-
|
22
|
-
it "delegates to #mri_out" do
|
23
|
-
described_class.should_receive(:mri_out).with(command)
|
24
|
-
result
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context "when on JRuby" do
|
29
|
-
before { described_class.stub(jruby?: true) }
|
30
|
-
|
31
|
-
it "delegates to #jruby_out" do
|
32
|
-
described_class.should_receive(:jruby_out).with(command)
|
33
|
-
result
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|