geordi 5.3.0 → 6.0.1
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 +4 -4
- data/.github/workflows/test.yml +6 -6
- data/.rspec +2 -0
- data/CHANGELOG.md +34 -1
- data/Gemfile +2 -2
- data/Gemfile.lock +17 -10
- data/README.md +28 -50
- data/exe/dumple +7 -0
- data/geordi.gemspec +3 -2
- data/lib/geordi/capistrano_config.rb +13 -4
- data/lib/geordi/chromedriver_updater.rb +7 -7
- data/lib/geordi/cli.rb +6 -6
- data/lib/geordi/commands/branch.rb +12 -0
- data/lib/geordi/commands/commit.rb +1 -1
- data/lib/geordi/commands/cucumber.rb +7 -38
- data/lib/geordi/commands/delete_dumps.rb +1 -1
- data/lib/geordi/commands/docker.rb +7 -1
- data/lib/geordi/commands/drop_databases.rb +0 -2
- data/lib/geordi/commands/dump.rb +3 -0
- data/lib/geordi/commands/remove_executable_flags.rb +2 -1
- data/lib/geordi/commands/rspec.rb +4 -1
- data/lib/geordi/commands/tests.rb +36 -12
- data/lib/geordi/cucumber.rb +4 -100
- data/lib/geordi/db_cleaner.rb +5 -5
- data/lib/geordi/docker.rb +71 -4
- data/lib/geordi/dump_loader.rb +1 -5
- data/lib/geordi/gitpt.rb +156 -70
- data/lib/geordi/interaction.rb +5 -3
- data/lib/geordi/remote.rb +1 -0
- data/lib/geordi/settings.rb +38 -38
- data/lib/geordi/version.rb +1 -1
- metadata +9 -10
- data/exe/launchy_browser +0 -15
- data/lib/geordi/commands/_setup_vnc.rb +0 -64
- data/lib/geordi/commands/firefox.rb +0 -32
- data/lib/geordi/commands/vnc.rb +0 -18
- data/lib/geordi/firefox_for_selenium.rb +0 -200
@@ -0,0 +1,12 @@
|
|
1
|
+
desc 'branch', 'Check out a feature branch based on a story from Pivotal Tracker'
|
2
|
+
long_desc <<-LONGDESC
|
3
|
+
Example: `geordi branch`
|
4
|
+
|
5
|
+
On the first execution we ask for your Pivotal Tracker API token. It will be
|
6
|
+
stored in `~/.config/geordi/global.yml`.
|
7
|
+
LONGDESC
|
8
|
+
|
9
|
+
def branch
|
10
|
+
require 'geordi/gitpt'
|
11
|
+
Gitpt.new.run_branch
|
12
|
+
end
|
@@ -2,24 +2,15 @@ desc 'cucumber [FILES and OPTIONS]', 'Run Cucumber features'
|
|
2
2
|
long_desc <<-LONGDESC
|
3
3
|
Example: `geordi cucumber features/authentication_feature:3`
|
4
4
|
|
5
|
-
Runs Cucumber with `bundle exec`, using parallel tests
|
6
|
-
|
7
|
-
and beta support for re-running failed scenarios.
|
5
|
+
Runs Cucumber with `bundle exec`, using parallel tests and with support for
|
6
|
+
re-running failed scenarios.
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
Any unknown option will be passed through to Cucumber, e.g. `--format=pretty`.
|
9
|
+
Make sure to connect option and value with an equals sign, i.e. have each option
|
10
|
+
a contiguous string.
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
`--debug` or `-d`.
|
15
|
-
|
16
|
-
- *Options:* Any unknown option will be passed through to Cucumber,
|
17
|
-
e.g. `--format=pretty`. Make sure to connect option and value with an equals
|
18
|
-
sign, i.e. have each option a contiguous string.
|
19
|
-
|
20
|
-
- *VNC:* By default, test browsers will run in a VNC session. When using a
|
21
|
-
headless test browser anyway, you can disable VNC by setting `use_vnc: false`
|
22
|
-
in `.geordi.yml` in the project root.
|
12
|
+
In order to limit processes in a parallel run, you can set an environment
|
13
|
+
variable like this: `PARALLEL_TEST_PROCESSORS=6 geordi cucumber`
|
23
14
|
LONGDESC
|
24
15
|
|
25
16
|
option :modified, aliases: '-m', type: :boolean,
|
@@ -64,28 +55,6 @@ def cucumber(*args)
|
|
64
55
|
cmd_opts, files = args.partition { |f| f.start_with? '-' }
|
65
56
|
cmd_opts << '--format' << 'pretty' << '--backtrace' if options.debug
|
66
57
|
|
67
|
-
# Serial run of @solo scenarios ############################################
|
68
|
-
if files.any? { |f| f.include? ':' }
|
69
|
-
Interaction.note '@solo run skipped when called with line numbers' if options.verbose
|
70
|
-
else
|
71
|
-
solo_files = if files.empty?
|
72
|
-
'features' # Proper grepping
|
73
|
-
else
|
74
|
-
files.join(' ')
|
75
|
-
end
|
76
|
-
|
77
|
-
solo_tag_usages = `grep -r '@solo' #{solo_files}`.split("\n")
|
78
|
-
|
79
|
-
if solo_tag_usages.any?
|
80
|
-
solo_cmd_opts = cmd_opts.dup
|
81
|
-
solo_cmd_opts << '--tags' << '@solo'
|
82
|
-
|
83
|
-
Interaction.announce 'Running @solo features'
|
84
|
-
solo_success = Geordi::Cucumber.new.run files, solo_cmd_opts, verbose: options.verbose, parallel: false
|
85
|
-
solo_success || Interaction.fail('Features failed.')
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
58
|
# Parallel run of all given features + reruns ##############################
|
90
59
|
Interaction.announce 'Running features'
|
91
60
|
normal_run_successful = Geordi::Cucumber.new.run(files, cmd_opts, verbose: options.verbose)
|
@@ -30,7 +30,7 @@ def delete_dumps(*locations)
|
|
30
30
|
deletable_dumps = dump_files.flatten.uniq.sort.select &File.method(:file?)
|
31
31
|
|
32
32
|
if deletable_dumps.empty?
|
33
|
-
Interaction.
|
33
|
+
Interaction.warn 'No dump files found.'
|
34
34
|
else
|
35
35
|
puts deletable_dumps
|
36
36
|
Interaction.prompt('Delete these files?', 'n', /y|yes/) || Interaction.fail('Cancelled.')
|
@@ -12,8 +12,13 @@ class DockerCLI < Thor
|
|
12
12
|
end
|
13
13
|
|
14
14
|
desc 'vnc', 'Open a vnc viewer connecting to the docker container'
|
15
|
+
option :setup, default: false, type: :boolean, desc: 'Guide through the setup of VNC'
|
15
16
|
def vnc
|
16
|
-
|
17
|
+
if options.setup
|
18
|
+
docker.setup_vnc
|
19
|
+
else
|
20
|
+
docker.vnc
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
private
|
@@ -42,5 +47,6 @@ There are three subcommands:
|
|
42
47
|
|
43
48
|
- `geordi docker vnc`
|
44
49
|
Opens a VNC viewer to connect to the VNC server in the container.
|
50
|
+
Append `--setup` to be guided through the setup of VNC viewer.
|
45
51
|
LONGDESC
|
46
52
|
subcommand 'docker', DockerCLI
|
data/lib/geordi/commands/dump.rb
CHANGED
@@ -57,6 +57,9 @@ def dump(target = nil, *_args)
|
|
57
57
|
Interaction.announce "Sourcing dump into the #{loader.config['database']} db"
|
58
58
|
loader.load
|
59
59
|
|
60
|
+
Util.run! "rm #{dump_path}"
|
61
|
+
Interaction.note "Dump file removed"
|
62
|
+
|
60
63
|
Interaction.success "Your #{loader.config['database']} database has now the data of #{target}#{database_label}."
|
61
64
|
end
|
62
65
|
end
|
@@ -2,7 +2,10 @@ desc 'rspec [FILES]', 'Run RSpec'
|
|
2
2
|
long_desc <<-LONGDESC
|
3
3
|
Example: `geordi rspec spec/models/user_spec.rb:13`
|
4
4
|
|
5
|
-
Runs RSpec with
|
5
|
+
Runs RSpec with version 1/2 support, parallel_tests detection and `bundle exec`.
|
6
|
+
|
7
|
+
In order to limit processes in a parallel run, you can set an environment
|
8
|
+
variable like this: `PARALLEL_TEST_PROCESSORS=6 geordi rspec`
|
6
9
|
LONGDESC
|
7
10
|
|
8
11
|
def rspec(*files)
|
@@ -1,14 +1,38 @@
|
|
1
|
-
desc 'tests', 'Run all employed tests'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
desc 'tests [FILES]', 'Run all employed tests'
|
2
|
+
long_desc <<-LONGDESC
|
3
|
+
When running `geordi tests` without any arguments, all unit tests, rspec specs
|
4
|
+
and cucumber features will be run.
|
5
|
+
|
6
|
+
When passing arguments, Geordi will forward them to either `rspec` or `cucumber`,
|
7
|
+
depending on what the first argument indicates.
|
8
|
+
LONGDESC
|
9
|
+
|
10
|
+
def tests(*args)
|
11
|
+
if args.any?
|
12
|
+
args, opts = Thor::Options.split(args)
|
13
|
+
error_message = "When passing arguments, the first argument must be either an RSpec or a Cucumber path."
|
14
|
+
|
15
|
+
if args.empty?
|
16
|
+
Interaction.fail error_message
|
17
|
+
elsif args.first.start_with? 'spec'
|
18
|
+
invoke 'rspec', args, opts
|
19
|
+
elsif args.first.start_with? 'features'
|
20
|
+
invoke 'cucumber', args, opts
|
21
|
+
else
|
22
|
+
Interaction.fail error_message
|
23
|
+
end
|
12
24
|
|
13
|
-
|
25
|
+
else
|
26
|
+
rake_result = invoke_geordi 'with_rake'
|
27
|
+
|
28
|
+
# Since `rake` usually is configured to run all tests, only run them if `rake`
|
29
|
+
# did not perform
|
30
|
+
if rake_result == :did_not_perform
|
31
|
+
invoke_geordi 'unit'
|
32
|
+
invoke_geordi 'rspec'
|
33
|
+
invoke_geordi 'cucumber'
|
34
|
+
end
|
35
|
+
|
36
|
+
Interaction.success 'Successfully ran tests.'
|
37
|
+
end
|
14
38
|
end
|
data/lib/geordi/cucumber.rb
CHANGED
@@ -4,67 +4,23 @@ require 'tempfile'
|
|
4
4
|
# This require-style is to prevent Ruby from loading files of a different
|
5
5
|
# version of Geordi.
|
6
6
|
require File.expand_path('interaction', __dir__)
|
7
|
-
require File.expand_path('firefox_for_selenium', __dir__)
|
8
7
|
require File.expand_path('settings', __dir__)
|
9
8
|
|
10
9
|
module Geordi
|
11
10
|
class Cucumber
|
12
11
|
|
13
|
-
VNC_DISPLAY = ':17'.freeze
|
14
|
-
VNC_PASSWORD_FILE = File.expand_path('~/.vnc/passwd').freeze # default for "vncpasswd"
|
15
|
-
VNC_SERVER_DEFAULT_OPTIONS = "-localhost -nolisten tcp -geometry 1280x1024 -rfbauth #{VNC_PASSWORD_FILE}".freeze
|
16
|
-
VNC_SERVER_COMMAND = "vncserver #{VNC_DISPLAY} #{ENV.fetch('GEORDI_VNC_OPTIONS', VNC_SERVER_DEFAULT_OPTIONS)}".freeze
|
17
|
-
VNC_VIEWER_COMMAND = "vncviewer -passwd #{VNC_PASSWORD_FILE}".freeze
|
18
|
-
VNC_ENV_VARIABLES = %w[DISPLAY BROWSER LAUNCHY_BROWSER].freeze
|
19
|
-
|
20
12
|
def run(files, cucumber_options, options = {})
|
21
13
|
self.argv = files + cucumber_options.map { |option| option.split('=') }.flatten
|
22
14
|
self.settings = Geordi::Settings.new
|
23
15
|
|
24
16
|
consolidate_rerun_txt_files
|
25
17
|
show_features_to_run
|
26
|
-
setup_vnc if settings.use_vnc?
|
27
18
|
|
28
19
|
command = use_parallel_tests?(options) ? parallel_execution_command : serial_execution_command
|
29
20
|
Interaction.note_cmd(command) if options[:verbose]
|
30
21
|
|
31
22
|
puts # Make newline
|
32
|
-
system command
|
33
|
-
end
|
34
|
-
|
35
|
-
def launch_vnc_viewer(source = VNC_DISPLAY)
|
36
|
-
fork do
|
37
|
-
error = capture_stderr do
|
38
|
-
system("#{VNC_VIEWER_COMMAND} #{source}")
|
39
|
-
end
|
40
|
-
unless $?.success?
|
41
|
-
if $?.exitstatus == 127
|
42
|
-
Interaction.fail 'VNC viewer not found. Install it with `geordi vnc --setup`.'
|
43
|
-
else
|
44
|
-
Interaction.note 'VNC viewer could not be opened:'
|
45
|
-
puts error
|
46
|
-
puts
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def restore_env
|
53
|
-
VNC_ENV_VARIABLES.each do |variable|
|
54
|
-
ENV[variable] = ENV["OUTER_#{variable}"]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def setup_vnc
|
59
|
-
if try_and_start_vnc
|
60
|
-
VNC_ENV_VARIABLES.each do |variable|
|
61
|
-
ENV["OUTER_#{variable}"] = ENV[variable] if ENV[variable]
|
62
|
-
end
|
63
|
-
ENV['BROWSER'] = ENV['LAUNCHY_BROWSER'] = File.expand_path('../../exe/launchy_browser', __dir__)
|
64
|
-
ENV['DISPLAY'] = VNC_DISPLAY
|
65
|
-
|
66
|
-
Interaction.note 'Run `geordi vnc` to view the Selenium test browsers'
|
67
|
-
end
|
23
|
+
system command
|
68
24
|
end
|
69
25
|
|
70
26
|
private
|
@@ -76,7 +32,7 @@ module Geordi
|
|
76
32
|
unless argv.include?('--format') || argv.include?('-f')
|
77
33
|
format_args = spinner_available? ? ['--format', 'CucumberSpinner::CuriousProgressBarFormatter'] : ['--format', 'progress']
|
78
34
|
end
|
79
|
-
[
|
35
|
+
[ Util.binstub_or_fallback('cucumber'), format_args, escape_shell_args(argv)].flatten.compact.join(' ')
|
80
36
|
end
|
81
37
|
|
82
38
|
def parallel_execution_command
|
@@ -88,28 +44,12 @@ module Geordi
|
|
88
44
|
features = find_all_features_recursively('features') if features.empty?
|
89
45
|
|
90
46
|
[
|
91
|
-
use_firefox_for_selenium,
|
92
47
|
'bundle exec parallel_test -t ' + type_arg,
|
93
|
-
%(-o '#{command_line_options.join(' ')}
|
48
|
+
%(-o '#{command_line_options.join(' ')}'),
|
94
49
|
"-- #{features.join(' ')}",
|
95
50
|
].compact.join(' ')
|
96
51
|
end
|
97
52
|
|
98
|
-
def not_tag(name)
|
99
|
-
if Util.gem_major_version('cucumber') < 3
|
100
|
-
"~#{name}"
|
101
|
-
else
|
102
|
-
"not #{name}"
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def use_firefox_for_selenium
|
107
|
-
path = Geordi::FirefoxForSelenium.path_from_config
|
108
|
-
if path
|
109
|
-
"PATH=#{path}:$PATH"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
53
|
def escape_shell_args(*args)
|
114
54
|
args.flatten.collect do |arg|
|
115
55
|
arg.gsub(/([\\ "])/) { |_match| "\\#{Regexp.last_match(1)}" }
|
@@ -117,9 +57,7 @@ module Geordi
|
|
117
57
|
end
|
118
58
|
|
119
59
|
def show_features_to_run
|
120
|
-
if command_line_options.include? '
|
121
|
-
Interaction.note 'All features tagged with @solo'
|
122
|
-
elsif command_line_options.include? 'rerun'
|
60
|
+
if command_line_options.include? 'rerun'
|
123
61
|
Interaction.note 'Rerunning failed scenarios'
|
124
62
|
elsif features_to_run.empty?
|
125
63
|
Interaction.note 'All features in features/'
|
@@ -210,39 +148,5 @@ module Geordi
|
|
210
148
|
features_to_run.none? { |f| f.include? ':' }
|
211
149
|
end
|
212
150
|
|
213
|
-
def try_and_start_vnc
|
214
|
-
# check if vnc is already running
|
215
|
-
# return true if vnc_server_running?
|
216
|
-
error = capture_stderr do
|
217
|
-
system(VNC_SERVER_COMMAND)
|
218
|
-
end
|
219
|
-
case $?.exitstatus
|
220
|
-
when 0,
|
221
|
-
98 # was already running after all
|
222
|
-
true
|
223
|
-
when 127 # not installed
|
224
|
-
Interaction.warn 'Could not launch VNC server. Install it with `geordi vnc --setup`.'
|
225
|
-
false
|
226
|
-
else
|
227
|
-
Interaction.warn 'Starting VNC failed:'
|
228
|
-
puts error
|
229
|
-
puts
|
230
|
-
false
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
def capture_stderr
|
235
|
-
old_stderr = $stderr.dup
|
236
|
-
io = Tempfile.new('cuc')
|
237
|
-
$stderr.reopen(io)
|
238
|
-
yield
|
239
|
-
io.rewind
|
240
|
-
io.read
|
241
|
-
ensure
|
242
|
-
io.close
|
243
|
-
io.unlink
|
244
|
-
$stderr.reopen(old_stderr)
|
245
|
-
end
|
246
|
-
|
247
151
|
end
|
248
152
|
end
|
data/lib/geordi/db_cleaner.rb
CHANGED
@@ -180,7 +180,7 @@ HEREDOC
|
|
180
180
|
if @mysql_command.include? '-p'
|
181
181
|
puts "Please enter your MySQL/MariaDB account 'root' for: DROP DATABASE #{db}"
|
182
182
|
else
|
183
|
-
|
183
|
+
puts "Dropping MySQL/MariaDB database #{db}"
|
184
184
|
end
|
185
185
|
`#{@mysql_command} -e 'DROP DATABASE \`#{db}\`;'`
|
186
186
|
end
|
@@ -206,7 +206,7 @@ HEREDOC
|
|
206
206
|
until %w[y n].include? proceed
|
207
207
|
deletable_dbs = filter_whitelisted(dbtype, database_list)
|
208
208
|
if deletable_dbs.empty?
|
209
|
-
Interaction.note "No #{dbtype} databases found that were not whitelisted"
|
209
|
+
Interaction.note "No #{dbtype} databases found that were not whitelisted."
|
210
210
|
if Interaction.prompt('Edit the whitelist? [y]es or [n]o') == 'y'
|
211
211
|
proceed = 'e'
|
212
212
|
else
|
@@ -214,11 +214,11 @@ HEREDOC
|
|
214
214
|
end
|
215
215
|
end
|
216
216
|
if proceed.empty?
|
217
|
-
Interaction.note "The following #{dbtype} databases are not whitelisted and
|
217
|
+
Interaction.note "The following #{dbtype} databases are not whitelisted and can be deleted:"
|
218
218
|
deletable_dbs.sort.each do |db|
|
219
219
|
puts db
|
220
220
|
end
|
221
|
-
Interaction.note "
|
221
|
+
Interaction.note "These #{dbtype} databases are not whitelisted and can be deleted."
|
222
222
|
proceed = Interaction.prompt('Proceed? [y]es, [n]o or [e]dit whitelist')
|
223
223
|
end
|
224
224
|
case proceed
|
@@ -226,7 +226,7 @@ HEREDOC
|
|
226
226
|
proceed = '' # reset user selection
|
227
227
|
edit_whitelist dbtype
|
228
228
|
when 'n'
|
229
|
-
Interaction.success '
|
229
|
+
Interaction.success 'Nothing deleted.'
|
230
230
|
return []
|
231
231
|
when 'y'
|
232
232
|
return deletable_dbs
|
data/lib/geordi/docker.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'geordi/interaction'
|
2
2
|
require 'geordi/cucumber'
|
3
3
|
require 'yaml'
|
4
|
+
require 'open3'
|
4
5
|
|
5
6
|
module Geordi
|
6
7
|
class Docker
|
@@ -28,13 +29,61 @@ module Geordi
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def vnc
|
31
|
-
|
32
|
+
check_installation_and_config
|
33
|
+
launch_vnc_viewer('::5967')
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup_vnc
|
37
|
+
`clear`
|
38
|
+
Interaction.note 'This script will help you install a VNC viewer.'
|
39
|
+
Interaction.note 'Please open a second shell to execute instructions.'
|
40
|
+
Interaction.prompt 'Continue ...'
|
41
|
+
|
42
|
+
Interaction.announce 'Setup VNC viewer'
|
43
|
+
vnc_viewer_installed = system('which vncviewer > /dev/null 2>&1')
|
44
|
+
if vnc_viewer_installed
|
45
|
+
Interaction.success 'It appears you already have a VNC viewer installed. Good job!'
|
46
|
+
else
|
47
|
+
puts 'Please run:'
|
48
|
+
Interaction.note_cmd 'sudo apt-get install xtightvncviewer'
|
49
|
+
Interaction.prompt 'Continue ...'
|
50
|
+
end
|
51
|
+
|
52
|
+
puts
|
53
|
+
puts Util.strip_heredoc <<-TEXT
|
54
|
+
Done. You can view the VNC window with `geordi docker vnc`.
|
55
|
+
TEXT
|
56
|
+
|
57
|
+
Interaction.success 'Happy cuking!'
|
32
58
|
end
|
33
59
|
|
34
60
|
private
|
35
61
|
|
62
|
+
def launch_vnc_viewer(source)
|
63
|
+
fail('VNC viewer not found. Install it with `geordi docker vnc --setup`.') unless command_exists?('vncviewer')
|
64
|
+
|
65
|
+
fork do
|
66
|
+
error = capture_stderr do
|
67
|
+
system("vncviewer #{source}")
|
68
|
+
end
|
69
|
+
unless $?.success?
|
70
|
+
if $?.exitstatus == 127
|
71
|
+
fail('VNC viewer not found. Install it with `geordi docker vnc --setup`.')
|
72
|
+
else
|
73
|
+
fail("VNC viewer could not be opened: #{error}")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
exit 0
|
78
|
+
end
|
79
|
+
|
36
80
|
def attach_to_running_shell
|
37
|
-
|
81
|
+
# The command line output of docker-compose ps changes depending on the container name length, this is
|
82
|
+
# caused by the varying terminal length and results in the longer outputs, e.g the container name and id
|
83
|
+
# to be cut after x characters and the rest being placed in the line below.
|
84
|
+
|
85
|
+
stdout_str, _error_str = execute(:capture, {'COLUMNS' => '400'}, 'docker-compose ps')
|
86
|
+
running_containers = stdout_str.split("\n")
|
38
87
|
if (main_container_line = running_containers.grep(/_main_run/).first)
|
39
88
|
container_name = main_container_line.split(' ').first
|
40
89
|
execute(:exec, 'docker', 'exec', '-it', container_name, 'bash')
|
@@ -54,13 +103,17 @@ module Geordi
|
|
54
103
|
def execute(kind, *args)
|
55
104
|
if ENV['GEORDI_TESTING']
|
56
105
|
puts "Stubbed run #{args.join(' ')}"
|
57
|
-
if kind == :`
|
106
|
+
if kind == :` || kind == :capture
|
58
107
|
mock_parse(*args)
|
59
108
|
else
|
60
109
|
mock_run(*args)
|
61
110
|
end
|
62
111
|
else
|
63
|
-
|
112
|
+
if kind == :capture
|
113
|
+
Open3.capture2(*args)
|
114
|
+
else
|
115
|
+
send(kind, *args)
|
116
|
+
end
|
64
117
|
end
|
65
118
|
end
|
66
119
|
|
@@ -112,5 +165,19 @@ module Geordi
|
|
112
165
|
[]
|
113
166
|
end
|
114
167
|
end
|
168
|
+
|
169
|
+
def capture_stderr
|
170
|
+
old_stderr = $stderr.dup
|
171
|
+
io = Tempfile.new('cuc')
|
172
|
+
$stderr.reopen(io)
|
173
|
+
yield
|
174
|
+
io.rewind
|
175
|
+
io.read
|
176
|
+
ensure
|
177
|
+
io.close
|
178
|
+
io.unlink
|
179
|
+
$stderr.reopen(old_stderr)
|
180
|
+
end
|
181
|
+
|
115
182
|
end
|
116
183
|
end
|