scmd 3.0.1 → 3.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -7
- data/Gemfile +14 -6
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +1 -1
- data/bench/results.txt +32 -32
- data/bench/runner.rb +16 -13
- data/lib/scmd/command.rb +59 -43
- data/lib/scmd/command_spy.rb +22 -24
- data/lib/scmd/stored_commands.rb +10 -14
- data/lib/scmd/version.rb +3 -1
- data/lib/scmd.rb +17 -16
- data/scmd.gemspec +13 -6
- data/script/bench.rb +6 -7
- data/test/helper.rb +13 -2
- data/test/support/factory.rb +3 -2
- data/test/system/command_tests.rb +22 -27
- data/test/unit/command_spy_tests.rb +30 -16
- data/test/unit/command_tests.rb +8 -9
- data/test/unit/scmd_tests.rb +17 -22
- data/test/unit/stored_commands_tests.rb +7 -9
- metadata +62 -49
- data/.gitignore +0 -19
- data/Rakefile +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
SHA512:
|
6
|
-
|
7
|
-
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f93aa47368dbe362f4e21f275f29e463e1be3ac7a4eec07b5ce2d18b77155543
|
4
|
+
data.tar.gz: 3d9daf1670226711e0852c079276823f211088eb306e7b147b8bba140d5aee74
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6aab5d881aa873b1f95309ecd760a2e04e349df5821b3ac8814e5a4aba0fbe95e38aa6638cd3f9b5b70e0fea410b93a1aba65c78bf82ac8223b33514f9740616
|
7
|
+
data.tar.gz: 4a167c35519b264b3c33c93c72315af1f73f50c8b0b3373fb59946dcd95dbd5d93046d4978560ee1568a9cedd241487df27d986607ae6cc31373136fc179fd88
|
data/Gemfile
CHANGED
@@ -1,11 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
5
|
+
ruby ">= 2.5"
|
6
|
+
|
3
7
|
gemspec
|
4
8
|
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
|
9
|
+
gem "pry"
|
10
|
+
gem "whysoslow"
|
11
|
+
|
12
|
+
# to release, uncomment this and run `bundle exec ggem r -f`
|
13
|
+
gem 'ggem'
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
15
|
+
gem "assert", path: "/Users/kellyredding/projects/tmp/assert"
|
16
|
+
gem "much-style-guide", path: "/Users/kellyredding/projects/tmp/much-style-guide"
|
17
|
+
gem "much-factory", path: "/Users/kellyredding/projects/tmp/much-factory"
|
18
|
+
gem "much-not-given", path: "/Users/kellyredding/projects/tmp/much-not-given"
|
19
|
+
gem "much-stub", path: "/Users/kellyredding/projects/tmp/much-stub"
|
data/{LICENSE.txt → LICENSE}
RENAMED
File without changes
|
data/README.md
CHANGED
data/bench/results.txt
CHANGED
@@ -2,79 +2,79 @@ echo hi: 1 times
|
|
2
2
|
----------------
|
3
3
|
whysoslow? ..
|
4
4
|
|
5
|
-
mem @ start
|
6
|
-
mem @ finish
|
5
|
+
mem @ start 17 MB ??
|
6
|
+
mem @ finish 17 MB [31m+ 0 MB, 0%[0m
|
7
7
|
|
8
|
-
|
9
|
-
time
|
8
|
+
user system total real
|
9
|
+
time 0.5820000000000001 ms 0.5519999999999999 ms 3.786 ms 3.7030000000000003 ms
|
10
10
|
|
11
11
|
echo hi: 10 times
|
12
12
|
-----------------
|
13
13
|
whysoslow? ..
|
14
14
|
|
15
|
-
mem @ start
|
16
|
-
mem @ finish
|
15
|
+
mem @ start 17 MB ??
|
16
|
+
mem @ finish 17 MB [31m+ 0 MB, 0%[0m
|
17
17
|
|
18
|
-
|
19
|
-
time
|
18
|
+
user system total real
|
19
|
+
time 2.475 ms 3.822 ms 32.675999999999995 ms 34.702 ms
|
20
20
|
|
21
21
|
echo hi: 100 times
|
22
22
|
------------------
|
23
23
|
whysoslow? ..
|
24
24
|
|
25
|
-
mem @ start
|
26
|
-
mem @ finish
|
25
|
+
mem @ start 17 MB ??
|
26
|
+
mem @ finish 18 MB [31m+ 0 MB, 2%[0m
|
27
27
|
|
28
|
-
|
29
|
-
time
|
28
|
+
user system total real
|
29
|
+
time 19.75 ms 31.77 ms 281.766 ms 306.74899999999997 ms
|
30
30
|
|
31
31
|
echo hi: 1000 times
|
32
32
|
-------------------
|
33
33
|
whysoslow? ..
|
34
34
|
|
35
|
-
mem @ start
|
36
|
-
mem @ finish
|
35
|
+
mem @ start 18 MB ??
|
36
|
+
mem @ finish 29 MB [31m+ 11 MB, 61%[0m
|
37
37
|
|
38
|
-
|
39
|
-
time
|
38
|
+
user system total real
|
39
|
+
time 161.98399999999998 ms 271.296 ms 2432.76 ms 2662.98 ms
|
40
40
|
|
41
41
|
cat test/support/bigger-than-64k.txt: 1 times
|
42
42
|
---------------------------------------------
|
43
43
|
whysoslow? ..
|
44
44
|
|
45
|
-
mem @ start
|
46
|
-
mem @ finish
|
45
|
+
mem @ start 31 MB ??
|
46
|
+
mem @ finish 31 MB [31m+ 0 MB, 1%[0m
|
47
47
|
|
48
|
-
|
49
|
-
time
|
48
|
+
user system total real
|
49
|
+
time 0.412 ms 0.504 ms 4.343999999999999 ms 4.654 ms
|
50
50
|
|
51
51
|
cat test/support/bigger-than-64k.txt: 10 times
|
52
52
|
----------------------------------------------
|
53
53
|
whysoslow? ..
|
54
54
|
|
55
|
-
mem @ start
|
56
|
-
mem @ finish
|
55
|
+
mem @ start 31 MB ??
|
56
|
+
mem @ finish 34 MB [31m+ 2 MB, 7%[0m
|
57
57
|
|
58
|
-
|
59
|
-
time
|
58
|
+
user system total real
|
59
|
+
time 3.2880000000000003 ms 4.386 ms 43.447 ms 46.552 ms
|
60
60
|
|
61
61
|
cat test/support/bigger-than-64k.txt: 100 times
|
62
62
|
-----------------------------------------------
|
63
63
|
whysoslow? ..
|
64
64
|
|
65
|
-
mem @ start
|
66
|
-
mem @ finish
|
65
|
+
mem @ start 33 MB ??
|
66
|
+
mem @ finish 56 MB [31m+ 23 MB, 68%[0m
|
67
67
|
|
68
|
-
|
69
|
-
time
|
68
|
+
user system total real
|
69
|
+
time 28.892999999999997 ms 40.599000000000004 ms 407.804 ms 440.11 ms
|
70
70
|
|
71
71
|
cat test/support/bigger-than-64k.txt: 1000 times
|
72
72
|
------------------------------------------------
|
73
73
|
whysoslow? ..
|
74
74
|
|
75
|
-
mem @ start
|
76
|
-
mem @ finish
|
75
|
+
mem @ start 44 MB ??
|
76
|
+
mem @ finish 297 MB [31m+ 254 MB, 582%[0m
|
77
77
|
|
78
|
-
|
79
|
-
time
|
78
|
+
user system total real
|
79
|
+
time 285.236 ms 408.677 ms 4097.647 ms 4428.276999999999 ms
|
80
80
|
|
data/bench/runner.rb
CHANGED
@@ -1,29 +1,32 @@
|
|
1
|
-
|
2
|
-
require 'scmd'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require "whysoslow"
|
4
|
+
require "scmd"
|
5
5
|
|
6
|
+
class ScmdBenchRunner
|
6
7
|
attr_reader :result
|
7
8
|
|
8
9
|
def self.run(*args)
|
9
|
-
|
10
|
+
new(*args).run
|
10
11
|
end
|
11
12
|
|
12
13
|
def initialize(printer_io, cmd, num_times = 10)
|
13
14
|
@cmd = cmd
|
14
|
-
@proc =
|
15
|
-
|
16
|
-
|
15
|
+
@proc =
|
16
|
+
proc do
|
17
|
+
num_times.times{ cmd.run! }
|
18
|
+
end
|
17
19
|
|
18
|
-
@printer =
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
@printer =
|
21
|
+
Whysoslow::DefaultPrinter.new(
|
22
|
+
printer_io,
|
23
|
+
title: "#{@cmd.cmd_str}: #{num_times} times",
|
24
|
+
verbose: true,
|
25
|
+
)
|
22
26
|
@runner = Whysoslow::Runner.new(@printer)
|
23
27
|
end
|
24
28
|
|
25
29
|
def run
|
26
|
-
@runner.run
|
30
|
+
@runner.run(&@proc)
|
27
31
|
end
|
28
|
-
|
29
32
|
end
|
data/lib/scmd/command.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thread"
|
4
|
+
require "posix-spawn"
|
5
|
+
require "scmd"
|
4
6
|
|
5
7
|
# Scmd::Command is a base wrapper for handling system commands. Initialize it
|
6
8
|
# with with a string specifying the command to execute. You can then run the
|
@@ -8,7 +10,6 @@ require 'scmd'
|
|
8
10
|
# create a more custom command wrapper.
|
9
11
|
|
10
12
|
module Scmd
|
11
|
-
|
12
13
|
class Command
|
13
14
|
READ_SIZE = 10240 # bytes
|
14
15
|
READ_CHECK_TIMEOUT = 0.001 # seconds
|
@@ -26,7 +27,11 @@ module Scmd
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def run(input = nil)
|
29
|
-
|
30
|
+
begin
|
31
|
+
run!(input)
|
32
|
+
rescue
|
33
|
+
RunError
|
34
|
+
end
|
30
35
|
self
|
31
36
|
end
|
32
37
|
|
@@ -34,11 +39,13 @@ module Scmd
|
|
34
39
|
start_err_msg, start_err_bt = nil, nil
|
35
40
|
begin
|
36
41
|
start(input)
|
37
|
-
rescue
|
38
|
-
start_err_msg, start_err_bt =
|
42
|
+
rescue => ex
|
43
|
+
start_err_msg, start_err_bt = ex.message, ex.backtrace
|
39
44
|
ensure
|
40
45
|
wait # indefinitely until cmd is done running
|
41
|
-
|
46
|
+
unless success?
|
47
|
+
raise RunError.new(start_err_msg || @stderr, start_err_bt || caller)
|
48
|
+
end
|
42
49
|
end
|
43
50
|
|
44
51
|
self
|
@@ -49,19 +56,20 @@ module Scmd
|
|
49
56
|
|
50
57
|
@pid = @child_process.pid.to_i
|
51
58
|
@child_process.write(input)
|
52
|
-
@read_output_thread =
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
@read_output_thread =
|
60
|
+
Thread.new do
|
61
|
+
while @child_process.check_for_exit
|
62
|
+
begin
|
63
|
+
read_output
|
64
|
+
rescue EOFError # rubocop:disable Lint/SuppressedException
|
65
|
+
end
|
57
66
|
end
|
67
|
+
@stop_w.write_nonblock(".")
|
58
68
|
end
|
59
|
-
@stop_w.write_nonblock('.')
|
60
|
-
end
|
61
69
|
end
|
62
70
|
|
63
71
|
def wait(timeout = nil)
|
64
|
-
return
|
72
|
+
return unless running?
|
65
73
|
|
66
74
|
wait_for_exit(timeout)
|
67
75
|
if @child_process.running?
|
@@ -78,18 +86,18 @@ module Scmd
|
|
78
86
|
end
|
79
87
|
|
80
88
|
def stop(timeout = nil)
|
81
|
-
return
|
89
|
+
return unless running?
|
82
90
|
|
83
91
|
send_term
|
84
92
|
begin
|
85
93
|
wait(timeout || DEFAULT_STOP_TIMEOUT)
|
86
|
-
rescue TimeoutError
|
94
|
+
rescue TimeoutError
|
87
95
|
kill
|
88
96
|
end
|
89
97
|
end
|
90
98
|
|
91
99
|
def kill(signal = nil)
|
92
|
-
return
|
100
|
+
return unless running?
|
93
101
|
|
94
102
|
send_kill(signal)
|
95
103
|
wait # indefinitely until cmd is killed
|
@@ -108,25 +116,28 @@ module Scmd
|
|
108
116
|
end
|
109
117
|
|
110
118
|
def inspect
|
111
|
-
reference =
|
119
|
+
reference = "0x0%x" % (object_id << 1)
|
112
120
|
"#<#{self.class}:#{reference}"\
|
113
|
-
" @cmd_str=#{
|
121
|
+
" @cmd_str=#{cmd_str.inspect}"\
|
114
122
|
" @exitstatus=#{@exitstatus.inspect}>"
|
115
123
|
end
|
116
124
|
|
117
125
|
private
|
118
126
|
|
119
127
|
def read_output
|
120
|
-
@child_process.read(READ_SIZE)
|
128
|
+
@child_process.read(READ_SIZE) do |out, err|
|
129
|
+
@stdout += out
|
130
|
+
@stderr += err
|
131
|
+
end
|
121
132
|
end
|
122
133
|
|
123
134
|
def wait_for_exit(timeout)
|
124
|
-
ios, _, _ = IO.select([
|
125
|
-
@stop_r.read_nonblock(1) if ios
|
135
|
+
ios, _, _ = IO.select([@stop_r], nil, nil, timeout)
|
136
|
+
@stop_r.read_nonblock(1) if ios&.include?(@stop_r)
|
126
137
|
end
|
127
138
|
|
128
139
|
def reset_attrs
|
129
|
-
@stdout, @stderr, @pid, @exitstatus =
|
140
|
+
@stdout, @stderr, @pid, @exitstatus = +"", +"", nil, nil
|
130
141
|
end
|
131
142
|
|
132
143
|
def setup_run
|
@@ -145,33 +156,32 @@ module Scmd
|
|
145
156
|
end
|
146
157
|
|
147
158
|
def send_term
|
148
|
-
send_signal
|
159
|
+
send_signal "TERM"
|
149
160
|
end
|
150
161
|
|
151
162
|
def send_kill(signal = nil)
|
152
|
-
send_signal(signal ||
|
163
|
+
send_signal(signal || "KILL")
|
153
164
|
end
|
154
165
|
|
155
166
|
def send_signal(sig)
|
156
|
-
return
|
167
|
+
return unless running?
|
157
168
|
@child_process.send_signal(sig)
|
158
169
|
end
|
159
170
|
|
160
171
|
def stringify_hash(hash)
|
161
|
-
hash.
|
172
|
+
hash.reduce({}) do |h, (k, v)|
|
162
173
|
h.merge(k.to_s => v.to_s)
|
163
174
|
end
|
164
175
|
end
|
165
176
|
|
166
177
|
class ChildProcess
|
167
|
-
|
168
178
|
attr_reader :pid, :stdin, :stdout, :stderr
|
169
179
|
|
170
180
|
def initialize(cmd_str, env, options)
|
171
|
-
@pid, @stdin, @stdout, @stderr = *::POSIX::Spawn
|
181
|
+
@pid, @stdin, @stdout, @stderr = *::POSIX::Spawn.popen4(
|
172
182
|
env,
|
173
183
|
cmd_str,
|
174
|
-
options
|
184
|
+
options,
|
175
185
|
)
|
176
186
|
@wait_pid, @wait_status = nil, nil
|
177
187
|
end
|
@@ -194,25 +204,34 @@ module Scmd
|
|
194
204
|
end
|
195
205
|
|
196
206
|
def write(input)
|
197
|
-
|
207
|
+
unless input.nil?
|
198
208
|
[*input].each{ |line| @stdin.puts line.to_s }
|
199
209
|
@stdin.close
|
200
210
|
end
|
201
211
|
end
|
202
212
|
|
203
213
|
def read(size)
|
204
|
-
ios, _, _ =
|
214
|
+
ios, _, _ =
|
215
|
+
IO.select([@stdout, @stderr], nil, nil, READ_CHECK_TIMEOUT)
|
205
216
|
if ios && block_given?
|
206
|
-
yield
|
217
|
+
yield(
|
218
|
+
read_if_ready(ios, @stdout, size),
|
219
|
+
read_if_ready(ios, @stderr, size)
|
220
|
+
)
|
207
221
|
end
|
208
222
|
end
|
209
223
|
|
210
224
|
def send_signal(sig)
|
211
|
-
process_kill(sig,
|
225
|
+
process_kill(sig, pid)
|
226
|
+
end
|
227
|
+
|
228
|
+
def flush_stdout
|
229
|
+
@stdout.read
|
212
230
|
end
|
213
231
|
|
214
|
-
def
|
215
|
-
|
232
|
+
def flush_stderr
|
233
|
+
@stderr.read
|
234
|
+
end
|
216
235
|
|
217
236
|
def teardown
|
218
237
|
[@stdin, @stdout, @stderr].each{ |fd| fd.close if fd && !fd.closed? }
|
@@ -221,7 +240,7 @@ module Scmd
|
|
221
240
|
private
|
222
241
|
|
223
242
|
def read_if_ready(ready_ios, io, size)
|
224
|
-
ready_ios.include?(io) ? read_by_size(io, size) :
|
243
|
+
ready_ios.include?(io) ? read_by_size(io, size) : ""
|
225
244
|
end
|
226
245
|
|
227
246
|
def read_by_size(io, size)
|
@@ -238,11 +257,8 @@ module Scmd
|
|
238
257
|
end
|
239
258
|
|
240
259
|
def pgrep
|
241
|
-
@pgrep ||= Command.new(
|
260
|
+
@pgrep ||= Command.new("which pgrep").run.stdout.strip
|
242
261
|
end
|
243
|
-
|
244
262
|
end
|
245
|
-
|
246
263
|
end
|
247
|
-
|
248
264
|
end
|
data/lib/scmd/command_spy.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "scmd"
|
4
4
|
|
5
|
+
module Scmd
|
5
6
|
class CommandSpy
|
6
|
-
|
7
7
|
attr_reader :cmd_str, :env, :options
|
8
8
|
attr_reader :run_calls, :run_bang_calls, :start_calls
|
9
9
|
attr_reader :wait_calls, :stop_calls, :kill_calls
|
@@ -20,12 +20,12 @@ module Scmd
|
|
20
20
|
|
21
21
|
@running = false
|
22
22
|
|
23
|
-
@stdout, @stderr, @pid, @exitstatus =
|
23
|
+
@stdout, @stderr, @pid, @exitstatus = "", "", 1, 0
|
24
24
|
end
|
25
25
|
|
26
26
|
def run(input = nil)
|
27
27
|
@run_calls.push(InputCall.new(input))
|
28
|
-
Scmd.calls.push(Scmd::Call.new(self, input))
|
28
|
+
Scmd.calls.push(Scmd::Call.new(self, input)) if ENV["SCMD_TEST_MODE"]
|
29
29
|
self
|
30
30
|
end
|
31
31
|
|
@@ -35,7 +35,7 @@ module Scmd
|
|
35
35
|
|
36
36
|
def run!(input = nil)
|
37
37
|
@run_bang_calls.push(InputCall.new(input))
|
38
|
-
Scmd.calls.push(Scmd::Call.new(self, input))
|
38
|
+
Scmd.calls.push(Scmd::Call.new(self, input)) if ENV["SCMD_TEST_MODE"]
|
39
39
|
self
|
40
40
|
end
|
41
41
|
|
@@ -45,7 +45,7 @@ module Scmd
|
|
45
45
|
|
46
46
|
def start(input = nil)
|
47
47
|
@start_calls.push(InputCall.new(input))
|
48
|
-
Scmd.calls.push(Scmd::Call.new(self, input))
|
48
|
+
Scmd.calls.push(Scmd::Call.new(self, input)) if ENV["SCMD_TEST_MODE"]
|
49
49
|
@running = true
|
50
50
|
end
|
51
51
|
|
@@ -92,21 +92,21 @@ module Scmd
|
|
92
92
|
@cmd_str.to_s
|
93
93
|
end
|
94
94
|
|
95
|
-
def ==(
|
96
|
-
if
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
95
|
+
def ==(other)
|
96
|
+
if other.is_a?(CommandSpy)
|
97
|
+
cmd_str == other.cmd_str &&
|
98
|
+
env == other.env &&
|
99
|
+
options == other.options &&
|
100
|
+
run_calls == other.run_calls &&
|
101
|
+
run_bang_calls == other.run_bang_calls &&
|
102
|
+
start_calls == other.start_calls &&
|
103
|
+
wait_calls == other.wait_calls &&
|
104
|
+
stop_calls == other.stop_calls &&
|
105
|
+
kill_calls == other.kill_calls &&
|
106
|
+
pid == other.pid &&
|
107
|
+
exitstatus == other.exitstatus &&
|
108
|
+
stdout == other.stdout &&
|
109
|
+
stderr == other.stderr
|
110
110
|
else
|
111
111
|
super
|
112
112
|
end
|
@@ -115,7 +115,5 @@ module Scmd
|
|
115
115
|
InputCall = Struct.new(:input)
|
116
116
|
TimeoutCall = Struct.new(:timeout)
|
117
117
|
SignalCall = Struct.new(:signal)
|
118
|
-
|
119
118
|
end
|
120
|
-
|
121
119
|
end
|
data/lib/scmd/stored_commands.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "scmd/command_spy"
|
4
4
|
|
5
|
+
module Scmd
|
5
6
|
class StoredCommands
|
6
|
-
|
7
7
|
attr_reader :hash
|
8
8
|
|
9
9
|
def initialize
|
@@ -30,16 +30,15 @@ module Scmd
|
|
30
30
|
@hash.empty?
|
31
31
|
end
|
32
32
|
|
33
|
-
def ==(
|
34
|
-
if
|
35
|
-
|
33
|
+
def ==(other)
|
34
|
+
if other.is_a?(StoredCommands)
|
35
|
+
hash == other.hash
|
36
36
|
else
|
37
37
|
super
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
class Stub
|
42
|
-
|
43
42
|
attr_reader :cmd_str, :hash
|
44
43
|
|
45
44
|
def initialize(cmd_str)
|
@@ -62,17 +61,14 @@ module Scmd
|
|
62
61
|
CommandSpy.new(@cmd_str, opts).tap(&block)
|
63
62
|
end
|
64
63
|
|
65
|
-
def ==(
|
66
|
-
if
|
67
|
-
|
68
|
-
|
64
|
+
def ==(other)
|
65
|
+
if other.is_a?(Stub)
|
66
|
+
cmd_str == other.cmd_str &&
|
67
|
+
hash == other.hash
|
69
68
|
else
|
70
69
|
super
|
71
70
|
end
|
72
71
|
end
|
73
|
-
|
74
72
|
end
|
75
|
-
|
76
73
|
end
|
77
|
-
|
78
74
|
end
|
data/lib/scmd/version.rb
CHANGED
data/lib/scmd.rb
CHANGED
@@ -1,42 +1,44 @@
|
|
1
|
-
|
2
|
-
require 'scmd/command'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require "scmd/version"
|
4
|
+
require "scmd/command"
|
5
5
|
|
6
|
+
module Scmd
|
6
7
|
# Scmd can be run in "test mode". This means that command spies will be used
|
7
8
|
# in place of "live" commands, each time a command is run or started will be
|
8
9
|
# logged in a collection and option-specific spies can be added and used to
|
9
10
|
# "stub" spies with specific attributes in specific contexts.
|
10
11
|
|
11
12
|
def self.new(*args)
|
12
|
-
if !ENV[
|
13
|
+
if !ENV["SCMD_TEST_MODE"]
|
13
14
|
Command.new(*args)
|
14
15
|
else
|
15
|
-
|
16
|
+
commands.get(*args)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
20
|
def self.commands
|
20
|
-
raise NoMethodError
|
21
|
-
@commands ||=
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
raise NoMethodError unless ENV["SCMD_TEST_MODE"]
|
22
|
+
@commands ||=
|
23
|
+
begin
|
24
|
+
require "scmd/stored_commands"
|
25
|
+
StoredCommands.new
|
26
|
+
end
|
25
27
|
end
|
26
28
|
|
27
29
|
def self.calls
|
28
|
-
raise NoMethodError
|
30
|
+
raise NoMethodError unless ENV["SCMD_TEST_MODE"]
|
29
31
|
@calls ||= []
|
30
32
|
end
|
31
33
|
|
32
34
|
def self.reset
|
33
|
-
raise NoMethodError
|
34
|
-
|
35
|
-
|
35
|
+
raise NoMethodError unless ENV["SCMD_TEST_MODE"]
|
36
|
+
calls.clear
|
37
|
+
commands.remove_all
|
36
38
|
end
|
37
39
|
|
38
40
|
def self.add_command(cmd_str, &block)
|
39
|
-
|
41
|
+
commands.add(cmd_str, &block)
|
40
42
|
end
|
41
43
|
|
42
44
|
class Call < Struct.new(:cmd_str, :input, :cmd)
|
@@ -53,5 +55,4 @@ module Scmd
|
|
53
55
|
set_backtrace(called_from || caller)
|
54
56
|
end
|
55
57
|
end
|
56
|
-
|
57
58
|
end
|