dply 0.2.19 → 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.
- checksums.yaml +5 -5
- data/.rspec +4 -0
- data/Rakefile +0 -14
- data/TODO +0 -1
- data/code_dump/old_remote_task.rb +2 -0
- data/{dev_bin → dev_exe}/dplyr +0 -0
- data/{dev_bin → dev_exe}/drake +1 -1
- data/dply.gemspec +2 -2
- data/{bin → exe}/dplyr +0 -0
- data/{bin → exe}/drake +12 -14
- data/lib/dply/TEST_TODO +50 -0
- data/lib/dply/app_config.rb +108 -0
- data/lib/dply/base_config.rb +110 -0
- data/lib/dply/build.rb +17 -11
- data/lib/dply/build_config.rb +28 -96
- data/lib/dply/bundle.rb +7 -30
- data/lib/dply/cli/build.rb +5 -12
- data/lib/dply/cli/ctl.rb +7 -8
- data/lib/dply/cli/deploy.rb +6 -10
- data/lib/dply/cli/devbuild.rb +6 -10
- data/lib/dply/cli/install_pkgs.rb +2 -3
- data/lib/dply/cli/run.rb +27 -0
- data/lib/dply/cli/status.rb +1 -2
- data/lib/dply/cli/task.rb +6 -12
- data/lib/dply/code_archive.rb +123 -0
- data/lib/dply/command.rb +57 -0
- data/lib/dply/config_downloader.rb +3 -2
- data/lib/dply/curl.rb +1 -5
- data/lib/dply/custom_logger.rb +18 -1
- data/lib/dply/deplist.rb +16 -48
- data/lib/dply/deploy_config.rb +34 -0
- data/lib/dply/elf.rb +60 -0
- data/lib/dply/env.rb +9 -0
- data/lib/dply/git.rb +15 -8
- data/lib/dply/helper.rb +21 -33
- data/lib/dply/linker.rb +27 -27
- data/lib/dply/lock.rb +2 -9
- data/lib/dply/logger.rb +1 -1
- data/lib/dply/pkgs.rb +9 -11
- data/lib/dply/release.rb +2 -2
- data/lib/dply/{archive.rb → remote_archive.rb} +1 -1
- data/lib/dply/repo.rb +3 -3
- data/lib/dply/rpm.rb +12 -20
- data/lib/dply/scripts/depcheck.rb +4 -0
- data/lib/dply/shared_dirs.rb +1 -1
- data/lib/dply/strategy/archive.rb +15 -22
- data/lib/dply/strategy/base.rb +82 -0
- data/lib/dply/strategy/git.rb +18 -19
- data/lib/dply/task_dsl.rb +101 -0
- data/lib/dply/util.rb +75 -0
- data/lib/dply/venv.rb +53 -0
- data/lib/dply/version.rb +1 -1
- data/lib/dply/yum.rb +21 -31
- data/lib/dplyr/consul.rb +1 -1
- data/spec/dply/base_config_spec.rb +178 -0
- data/spec/dply/bundle_spec.rb +100 -0
- data/spec/dply/command_spec.rb +190 -0
- data/spec/dply/curl_spec.rb +41 -0
- data/spec/dply/deplist_spec.rb +48 -0
- data/spec/dply/elf_spec.rb +64 -0
- data/spec/dply/env_spec.rb +57 -0
- data/spec/dply/git_spec.rb +136 -0
- data/spec/dply/helper_spec.rb +168 -0
- data/spec/dply/linker_spec.rb +81 -0
- data/spec/dply/lock_spec.rb +24 -0
- data/spec/dply/pkgs_spec.rb +105 -0
- data/spec/dply/repo_spec.rb +58 -0
- data/spec/dply/rpm_spec.rb +32 -0
- data/spec/dply/yum_spec.rb +29 -0
- data/spec/integration/archive_flow_spec.rb +87 -0
- data/spec/integration/git_flow_spec.rb +63 -0
- data/spec/repo.rb +27 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/test_data/build.tar.gz +0 -0
- data/spec/test_data/build.tar.gz.md5 +1 -0
- data/spec/test_data/bundle/gems_installed/Gemfile +1 -0
- data/spec/test_data/bundle/gems_not_installed/Gemfile +2 -0
- data/spec/test_data/bundle/no_gemfile/.gitkeep +0 -0
- data/spec/test_data/command/test.rb +7 -0
- data/spec/test_data/elf/elf +0 -0
- data/spec/test_data/elf/libpgtypes.so.3 +0 -0
- data/spec/test_data/elf/not_elf +1 -0
- data/spec/test_data/sample_repo/.dply.lock +0 -0
- data/spec/test_data/sample_repo/Gemfile +2 -0
- data/spec/test_data/sample_repo/Rakefile +3 -0
- data/spec/test_data/sample_repo/app.rb +1 -0
- data/spec/test_data/sample_repo/dply/app.rb +33 -0
- data/spec/test_data/sample_repo/lib/libacl.so.1 +0 -0
- data/spec/test_data/sample_repo/pkgs.yml +2 -0
- data/spec/webserver.rb +21 -0
- metadata +96 -28
- data/lib/dply/cli/app_task.rb +0 -38
- data/lib/dply/config.rb +0 -120
- data/lib/dply/config_struct.rb +0 -52
- data/lib/dply/rakelib/drake.rake +0 -33
- data/lib/dply/tasks.rb +0 -136
data/lib/dplyr/consul.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Dplyr
|
|
|
15
15
|
metadata = metadata_tag ? JSON.parse(metadata_tag.partition(":")[2]) : {}
|
|
16
16
|
host[:user] = metadata["user"]
|
|
17
17
|
host[:dir] = metadata["dir"]
|
|
18
|
-
host[:addr] = i["Address"]
|
|
18
|
+
host[:addr] = i["Address"]
|
|
19
19
|
host[:id] = i["Node"]
|
|
20
20
|
hosts << host
|
|
21
21
|
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
require 'dply/base_config'
|
|
2
|
+
|
|
3
|
+
module Dply
|
|
4
|
+
describe BaseConfig do
|
|
5
|
+
|
|
6
|
+
before :all do
|
|
7
|
+
@work_dir = "tmp/base_config"
|
|
8
|
+
FileUtils.rm_rf @work_dir
|
|
9
|
+
FileUtils.mkdir_p @work_dir
|
|
10
|
+
|
|
11
|
+
conf_working
|
|
12
|
+
conf_invalid_type
|
|
13
|
+
conf_invalid_opt
|
|
14
|
+
conf_missing_opts
|
|
15
|
+
conf_override
|
|
16
|
+
conf_other
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class TestConfig < BaseConfig
|
|
20
|
+
define_opts do
|
|
21
|
+
opt :any
|
|
22
|
+
opt :int, type: Integer
|
|
23
|
+
opt :arr, type: Array
|
|
24
|
+
opt :str1, type: String
|
|
25
|
+
opt :str2, type: String
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def default_config
|
|
29
|
+
any "default_any"
|
|
30
|
+
arr [:default]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def conf_path(name)
|
|
35
|
+
"#{@work_dir}/#{name}.rb"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def write_conf(name, data)
|
|
39
|
+
File.write(conf_path(name), data)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def conf_working
|
|
43
|
+
write_conf "working", <<~'EOF'
|
|
44
|
+
any "1"
|
|
45
|
+
int 2
|
|
46
|
+
arr [:myval]
|
|
47
|
+
str1 { "#{any}#{int}#{str2}" }
|
|
48
|
+
str2 "s2"
|
|
49
|
+
EOF
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def conf_other
|
|
53
|
+
write_conf "other", <<~'EOF'
|
|
54
|
+
any "4"
|
|
55
|
+
any "3"
|
|
56
|
+
EOF
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def conf_invalid_type
|
|
60
|
+
write_conf "invalid_type", <<~'EOF'
|
|
61
|
+
any "1"
|
|
62
|
+
int "2"
|
|
63
|
+
EOF
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def conf_invalid_opt
|
|
67
|
+
write_conf "invalid_opt", <<~'EOF'
|
|
68
|
+
other_opt "2"
|
|
69
|
+
EOF
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def conf_missing_opts
|
|
73
|
+
write_conf "missing_opts", <<~'EOF'
|
|
74
|
+
any "m"
|
|
75
|
+
EOF
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def conf_override
|
|
79
|
+
write_conf "override", <<~'EOF'
|
|
80
|
+
any "1"
|
|
81
|
+
any { "override" }
|
|
82
|
+
EOF
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe ".build" do
|
|
86
|
+
|
|
87
|
+
it "parses the config and returns a struct" do
|
|
88
|
+
path = conf_path "working"
|
|
89
|
+
conf = TestConfig.build(path)
|
|
90
|
+
expect(conf.any).to eq("1")
|
|
91
|
+
expect(conf.int).to eq(2)
|
|
92
|
+
expect(conf.arr).to eq([:myval])
|
|
93
|
+
expect(conf.str1).to eq("12s2")
|
|
94
|
+
expect(conf.str2).to eq("s2")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "calls default_config on opts_struct to set default values" do
|
|
98
|
+
conf = TestConfig.build
|
|
99
|
+
expect(conf.any).to eq("default_any")
|
|
100
|
+
expect(conf.arr).to eq([:default])
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "reads config using block" do
|
|
104
|
+
path = conf_path "working"
|
|
105
|
+
conf1 = TestConfig.build do
|
|
106
|
+
read path
|
|
107
|
+
end
|
|
108
|
+
conf2 = TestConfig.build(path)
|
|
109
|
+
expect(conf1.any).to eq(conf2.any)
|
|
110
|
+
expect(conf2.str1).to eq(conf2.str1)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "reads multiple configs(some can be optional) using block" do
|
|
114
|
+
path = conf_path "working"
|
|
115
|
+
other_path = conf_path "other"
|
|
116
|
+
optional_path = "#{@work_dir}/missing.rb"
|
|
117
|
+
|
|
118
|
+
conf = TestConfig.build do
|
|
119
|
+
read optional_path, optional: true
|
|
120
|
+
read path
|
|
121
|
+
read other_path
|
|
122
|
+
end
|
|
123
|
+
expect(conf.any).to eq("3")
|
|
124
|
+
expect(conf.int).to eq(2)
|
|
125
|
+
expect(conf.arr).to eq([:myval])
|
|
126
|
+
expect(conf.str1).to eq("32s2")
|
|
127
|
+
expect(conf.str2).to eq("s2")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "raises error when config file is not readable" do
|
|
131
|
+
path = "#{@work_dir}/missing.rb"
|
|
132
|
+
expect { TestConfig.build(path) }.to raise_error(Error)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
specify "config methods are available inside block" do
|
|
136
|
+
path = conf_path "working"
|
|
137
|
+
conf = TestConfig.build do
|
|
138
|
+
read path
|
|
139
|
+
any "45"
|
|
140
|
+
str2 { "block_override" }
|
|
141
|
+
end
|
|
142
|
+
expect(conf.any).to eq("45")
|
|
143
|
+
expect(conf.str2).to eq("block_override")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "overrides values when using block setter" do
|
|
147
|
+
path = conf_path "override"
|
|
148
|
+
conf = TestConfig.build(path)
|
|
149
|
+
expect(conf.any).to eq("override")
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
specify "set method works" do
|
|
153
|
+
conf = TestConfig.build do
|
|
154
|
+
set :any, "setval"
|
|
155
|
+
end
|
|
156
|
+
expect(conf.any).to eq("setval")
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "raises an error on invalid type" do
|
|
160
|
+
path = conf_path "invalid_type"
|
|
161
|
+
expect { TestConfig.build(path) }.to raise_error(Error, /Expected: /)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "raises an error on invalid opt" do
|
|
165
|
+
path = conf_path "invalid_opt"
|
|
166
|
+
expect { TestConfig.build(path) }.to raise_error(Error, /invalid option/)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "ignores missing options" do
|
|
170
|
+
path = conf_path "missing_opts"
|
|
171
|
+
conf = TestConfig.build path
|
|
172
|
+
expect(conf.any).to eq("m")
|
|
173
|
+
expect(conf.str2).to eq(nil)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'dply/bundle'
|
|
2
|
+
|
|
3
|
+
module Dply
|
|
4
|
+
describe Bundle do
|
|
5
|
+
|
|
6
|
+
def config_content
|
|
7
|
+
{
|
|
8
|
+
"BUNDLE_PATH" => "vendor/bundle",
|
|
9
|
+
"BUNDLE_FROZEN" => "1",
|
|
10
|
+
"BUNDLE_DISABLE_SHARED_GEMS" => "1"
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def expect_config
|
|
15
|
+
content = YAML.load_file("#{Dir.pwd}/.bundle/config")
|
|
16
|
+
expect(content).to include(config_content)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def bundle_check(ret)
|
|
20
|
+
allow(bundle).to receive(:system).with("bundle check > /dev/null") do
|
|
21
|
+
expect_config
|
|
22
|
+
ret
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def expect_install
|
|
27
|
+
expect(bundle).to receive(:cmd).with(install_cmd) do
|
|
28
|
+
expect_config
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
subject(:bundle) { Bundle.new }
|
|
34
|
+
let(:install_cmd) { "bundle install -j5 --deployment" }
|
|
35
|
+
|
|
36
|
+
describe "#install" do
|
|
37
|
+
|
|
38
|
+
it "does nothing when gemfile not present" do
|
|
39
|
+
Dir.chdir("spec/test_data/bundle/no_gemfile") do
|
|
40
|
+
expect(File).not_to exist(".bundle/config")
|
|
41
|
+
expect(bundle).not_to receive(:cmd)
|
|
42
|
+
bundle.install
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "when gems not installed" do
|
|
47
|
+
let!(:app_dir) { "#{Dir.pwd}/spec/test_data/bundle/gems_not_installed" }
|
|
48
|
+
|
|
49
|
+
before(:each) do
|
|
50
|
+
FileUtils.rm_rf "#{app_dir}/.bundle"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "writes the bundle config and runs bundle install" do
|
|
54
|
+
Dir.chdir app_dir do
|
|
55
|
+
bundle_check false
|
|
56
|
+
expect_install
|
|
57
|
+
bundle.install
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "overwrites the bundle config and runs bundle install" do
|
|
62
|
+
Dir.chdir app_dir do
|
|
63
|
+
FileUtils.mkdir ".bundle"
|
|
64
|
+
IO.write ".bundle/config", "some_text"
|
|
65
|
+
bundle_check false
|
|
66
|
+
expect_install
|
|
67
|
+
bundle.install
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "when gems installed" do
|
|
73
|
+
let(:app_dir) { "spec/test_data/bundle/gems_installed" }
|
|
74
|
+
|
|
75
|
+
it "doesn't run bundle install" do
|
|
76
|
+
Dir.chdir app_dir do
|
|
77
|
+
bundle_check true
|
|
78
|
+
expect(bundle).not_to receive(:cmd).with(install_cmd)
|
|
79
|
+
bundle.install
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "#clean" do
|
|
86
|
+
it "doesn't run bundle clean when gemfile is not present" do
|
|
87
|
+
Dir.chdir("spec") do
|
|
88
|
+
expect(bundle).not_to receive(:cmd)
|
|
89
|
+
bundle.clean
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "writes the config and runs bundle clean" do
|
|
94
|
+
expect_config
|
|
95
|
+
expect(bundle).to receive(:cmd).with("bundle clean")
|
|
96
|
+
bundle.clean
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
require 'dply/command'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'tmpdir'
|
|
4
|
+
|
|
5
|
+
module Dply
|
|
6
|
+
describe Command do
|
|
7
|
+
|
|
8
|
+
before :all do
|
|
9
|
+
FileUtils.rm_rf "tmp/command"
|
|
10
|
+
FileUtils.mkdir_p "tmp/command"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
CMD = "ruby --disable-gems test.rb #{Process.pid} 'a b' | tee"
|
|
14
|
+
CMD_ARR = ["ruby", "--disable-gems", "test.rb", "#{Process.pid}", "a b", "|", "tee" ]
|
|
15
|
+
CMD_ENV = { "E1" => "1", "E2" => "2" }
|
|
16
|
+
|
|
17
|
+
def tmp_dir(&block)
|
|
18
|
+
cwd = Dir.pwd
|
|
19
|
+
d = Dir.mktmpdir nil, "#{cwd}/tmp/command"
|
|
20
|
+
FileUtils.cp "#{cwd}/spec/test_data/command/test.rb", "#{d}/test.rb"
|
|
21
|
+
Dir.chdir(d) { yield d }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def deserialize(file)
|
|
25
|
+
Marshal.load(IO.read file)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def expect_run
|
|
29
|
+
["env", "shell", "extra_args"].each do |i|
|
|
30
|
+
expect(File).to exist(i)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def expect_env(expected, shell:)
|
|
35
|
+
env = deserialize "env"
|
|
36
|
+
if shell
|
|
37
|
+
expect(env).to include(expected)
|
|
38
|
+
else
|
|
39
|
+
expect(env).to eq(expected)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def expect_args(list)
|
|
44
|
+
args = deserialize "extra_args"
|
|
45
|
+
expect(args).to eq list
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def expect_shell(expected)
|
|
49
|
+
content = IO.read("shell").chomp
|
|
50
|
+
expect(content).to eq expected.to_s
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
arg_values = {
|
|
54
|
+
command: [CMD, CMD_ARR],
|
|
55
|
+
env: [CMD_ENV],
|
|
56
|
+
shell: [true, false]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
hash_product = Proc.new do |h|
|
|
60
|
+
values = h.values
|
|
61
|
+
keys = h.keys
|
|
62
|
+
product = values[0].product(*values[1..-1])
|
|
63
|
+
product.map { |p| Hash[keys.zip p] }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
test_cases = hash_product[arg_values].reject { |i| i[:command] == CMD_ARR && i[:shell] }
|
|
67
|
+
|
|
68
|
+
result_proc = lambda do |args|
|
|
69
|
+
shell = args.fetch :shell
|
|
70
|
+
extra_args = shell ? ["a b"] : ["a b", "|", "tee"]
|
|
71
|
+
{extra_args: extra_args}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe '#run' do
|
|
75
|
+
|
|
76
|
+
test_cases.each do |i|
|
|
77
|
+
expected = result_proc.call i
|
|
78
|
+
command = i[:command]
|
|
79
|
+
shell = i[:shell]
|
|
80
|
+
env = i[:env]
|
|
81
|
+
|
|
82
|
+
context "cmd: #{i[:command].class}, shell: #{shell}, env: #{env}" do
|
|
83
|
+
it "runs as expected" do
|
|
84
|
+
tmp_dir do
|
|
85
|
+
c = Command.new command, shell: shell, env: env
|
|
86
|
+
retval = nil
|
|
87
|
+
expect { retval = c.run }.to output("outout").to_stdout_from_any_process
|
|
88
|
+
expect(retval).to eq(true)
|
|
89
|
+
expect_run
|
|
90
|
+
expect_env env, shell: shell
|
|
91
|
+
expect_args expected[:extra_args]
|
|
92
|
+
expect_shell shell
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context "when calling non existent command" do
|
|
99
|
+
let(:cmd) { "non_existent" }
|
|
100
|
+
let(:script) { "(non_existent | grep a ) 2>/dev/null >/dev/null" }
|
|
101
|
+
|
|
102
|
+
it "raises error when command is not a shell script" do
|
|
103
|
+
expect { (Command.new cmd, env: {}, shell: false).run }.to raise_error(Error)
|
|
104
|
+
expect { (Command.new cmd, env: {}, shell: true).run }.to raise_error(Error)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "raises error when command is a shell script" do
|
|
108
|
+
expect { (Command.new script, env: {}, shell: false).run }.to raise_error(Error)
|
|
109
|
+
expect { (Command.new script, env: {}, shell: true).run }.to raise_error(Error)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "when a command returns non-zero exit status" do
|
|
114
|
+
|
|
115
|
+
let(:cmd) { "false | grep some_var" }
|
|
116
|
+
|
|
117
|
+
it "raises error" do
|
|
118
|
+
expect { (Command.new cmd, env: {}, shell: false).run }.to raise_error(Error)
|
|
119
|
+
expect { (Command.new cmd, env: {}, shell: true).run }.to raise_error(Error)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
context "command contains shell characters with zero arguments and shell: false" do
|
|
124
|
+
let(:cmd) { "non_existent;ls" }
|
|
125
|
+
it "spawns a shell but escapes the command (no workaround for it)" do
|
|
126
|
+
expect { (Command.new cmd, env: {}, shell: false).run }.to raise_error(Error).and(
|
|
127
|
+
output("sh: #{cmd}: command not found\n").to_stdout_from_any_process)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
describe '#capture' do
|
|
133
|
+
|
|
134
|
+
test_cases.each do |i|
|
|
135
|
+
expected = result_proc.call i
|
|
136
|
+
command = i[:command]
|
|
137
|
+
shell = i[:shell]
|
|
138
|
+
env = i[:env]
|
|
139
|
+
|
|
140
|
+
context "cmd: #{i[:command].class}, shell: #{shell}, env: #{env}" do
|
|
141
|
+
it "runs as expected" do
|
|
142
|
+
tmp_dir do
|
|
143
|
+
c = Command.new command, shell: shell, env: env
|
|
144
|
+
retval = nil
|
|
145
|
+
expect { retval = c.capture }.to output("out").to_stderr_from_any_process
|
|
146
|
+
expect(retval).to eq('out')
|
|
147
|
+
expect_run
|
|
148
|
+
expect_env env, shell: shell
|
|
149
|
+
expect_args expected[:extra_args]
|
|
150
|
+
expect_shell shell
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
context "when calling non existent command" do
|
|
157
|
+
let(:cmd) { "non_existent" }
|
|
158
|
+
let(:script) { "(non_existent | grep a ) 2>/dev/null >/dev/null" }
|
|
159
|
+
|
|
160
|
+
it "raises error when command is not a shell script" do
|
|
161
|
+
expect { (Command.new cmd, env: {}, shell: false).capture }.to raise_error(Errno::ENOENT)
|
|
162
|
+
expect { (Command.new cmd, env: {}, shell: true).capture }.to raise_error(Errno::ENOENT)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "raises error when command is a shell script" do
|
|
166
|
+
expect { (Command.new script, env: {}, shell: false).capture }.to raise_error(Errno::ENOENT)
|
|
167
|
+
expect { (Command.new script, env: {}, shell: true).capture }.to raise_error(Error)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
context "when a command returns non-zero exit status" do
|
|
172
|
+
|
|
173
|
+
let(:cmd) { "false | grep some_var" }
|
|
174
|
+
|
|
175
|
+
it "raises error" do
|
|
176
|
+
expect { (Command.new cmd, env: {}, shell: false).capture }.to raise_error(Error)
|
|
177
|
+
expect { (Command.new cmd, env: {}, shell: true).capture }.to raise_error(Error)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context "command contains shell characters with zero arguments and shell: false" do
|
|
182
|
+
let(:cmd) { "non_existent;ls" }
|
|
183
|
+
it "doesn't spawn a shell" do
|
|
184
|
+
expect { (Command.new cmd, env: {}, shell: false).capture }.to raise_error(Errno::ENOENT)
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
end
|
|
190
|
+
end
|