geordi 5.2.2 → 6.0.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,5 +10,5 @@ LONGDESC
10
10
 
11
11
  def commit(*git_args)
12
12
  require 'geordi/gitpt'
13
- Gitpt.new.run(git_args)
13
+ Gitpt.new.run_commit(git_args)
14
14
  end
@@ -14,9 +14,9 @@ option :select_server, type: :string, aliases: '-s', banner: '[SERVER_NUMBER]',
14
14
 
15
15
  def console(target = 'development', *_args)
16
16
  require 'geordi/remote'
17
- invoke_geordi 'bundle_install'
18
17
 
19
18
  if target == 'development'
19
+ invoke_geordi 'bundle_install'
20
20
  invoke_geordi 'yarn_install'
21
21
 
22
22
  Interaction.announce 'Opening a local Rails console'
@@ -2,12 +2,8 @@ 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, with a VNC session
6
- holding Selenium test browsers, support for using a dedicated testing browser
7
- and beta support for re-running failed scenarios.
8
-
9
- - *@solo:* Generally, features are run in parallel. However, scenarios tagged
10
- with @solo are excluded from the parallel run and executed sequentially instead.
5
+ Runs Cucumber with `bundle exec`, using parallel tests and with support for re-running
6
+ failed scenarios.
11
7
 
12
8
  - *Debugging:* In some cases, the dot-printing Cucumber formatter swallows
13
9
  errors. In case a feature fails without an error message, try running it with
@@ -17,9 +13,8 @@ errors. In case a feature fails without an error message, try running it with
17
13
  e.g. `--format=pretty`. Make sure to connect option and value with an equals
18
14
  sign, i.e. have each option a contiguous string.
19
15
 
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.
16
+ - In order to limit processes in a parallel run, you can set an environment
17
+ variable like this: `PARALLEL_TEST_PROCESSORS=6 geordi cucumber`
23
18
  LONGDESC
24
19
 
25
20
  option :modified, aliases: '-m', type: :boolean,
@@ -64,28 +59,6 @@ def cucumber(*args)
64
59
  cmd_opts, files = args.partition { |f| f.start_with? '-' }
65
60
  cmd_opts << '--format' << 'pretty' << '--backtrace' if options.debug
66
61
 
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
62
  # Parallel run of all given features + reruns ##############################
90
63
  Interaction.announce 'Running features'
91
64
  normal_run_successful = Geordi::Cucumber.new.run(files, cmd_opts, verbose: options.verbose)
@@ -1,43 +1,41 @@
1
1
  desc 'delete-dumps [DIRECTORY]', 'Delete database dump files (*.dump)'
2
2
  long_desc <<-LONGDESC
3
- Example: `geordi delete_dumps` or `geordi delete_dumps ~/tmp/dumps`
3
+ Example: `geordi delete-dumps` or `geordi delete-dumps ~/tmp/dumps`
4
4
 
5
- Recursively search for files ending in `*.dump` and offer to delete those. When
5
+ Recursively searches for files ending in `.dump` and offers to delete them. When
6
6
  no argument is given, two default directories are searched for dump files: the
7
7
  current working directory and `~/dumps` (for dumps created with geordi).
8
8
 
9
- Geordi will ask for confirmation before actually deleting files.
9
+ Will ask for confirmation before actually deleting files.
10
10
  LONGDESC
11
11
 
12
- def delete_dumps(dump_directory = nil)
13
- deletable_dumps = []
14
- dump_directories = if dump_directory.nil?
15
- [
16
- File.join(Dir.home, 'dumps'),
17
- Dir.pwd,
18
- ]
19
- else
20
- [dump_directory]
12
+ def delete_dumps(*locations)
13
+ Interaction.announce 'Retrieving dump files'
14
+
15
+ dump_files = []
16
+ if locations.empty?
17
+ locations = [ File.join(Dir.home, 'dumps'), Dir.pwd ]
21
18
  end
22
- Interaction.announce 'Looking for *.dump in ' << dump_directories.join(',')
23
- dump_directories.each do |d|
24
- d_2 = File.expand_path(d)
25
- unless File.directory? File.realdirpath(d_2)
26
- Interaction.warn "Directory #{d_2} does not exist"
19
+ locations.map! &File.method(:expand_path)
20
+
21
+ Interaction.note "Looking in #{locations.join(', ')}"
22
+ locations.each do |dir|
23
+ directory = File.expand_path(dir)
24
+ unless File.directory? File.realdirpath(directory)
25
+ Interaction.warn "Directory #{directory} does not exist. Skipping."
27
26
  next
28
27
  end
29
- deletable_dumps.concat(Dir.glob("#{d_2}/**/*.dump"))
28
+ dump_files.concat Dir.glob("#{directory}/**/*.dump")
30
29
  end
30
+ deletable_dumps = dump_files.flatten.uniq.sort.select &File.method(:file?)
31
+
31
32
  if deletable_dumps.empty?
32
- Interaction.success 'No dumps to delete' if deletable_dumps.empty?
33
- exit 0
34
- end
35
- deletable_dumps.uniq!.sort!
36
- Interaction.note 'The following dumps can be deleted:'
37
- puts
38
- puts deletable_dumps
39
- Interaction.prompt('Delete those dumps', 'n', /y|yes/) || raise('Cancelled.')
40
- deletable_dumps.each do |dump|
41
- File.delete dump unless File.directory? dump
33
+ Interaction.warn 'No dump files found.'
34
+ else
35
+ puts deletable_dumps
36
+ Interaction.prompt('Delete these files?', 'n', /y|yes/) || Interaction.fail('Cancelled.')
37
+
38
+ deletable_dumps.each &File.method(:delete)
39
+ Interaction.success 'Done.'
42
40
  end
43
41
  end
@@ -1,19 +1,24 @@
1
1
  class DockerCLI < Thor
2
- desc 'setup', 'Setup docker and fetch required docker-container for the current project.'
2
+ desc 'setup', 'Setup docker and fetch required docker-container for the current project'
3
3
  def setup
4
4
  docker.setup
5
5
  end
6
6
 
7
- desc 'shell', 'Open a shell in the main docker container for the current project.'
7
+ desc 'shell', 'Open a shell in the main docker container for the current project'
8
8
  option :secondary, default: false, type: :boolean
9
9
  map 'shell' => '_shell'
10
10
  def _shell
11
11
  docker.shell(:secondary => options[:secondary])
12
12
  end
13
13
 
14
- desc 'vnc', 'Open a vnc viewer connecting to the docker container.'
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
- docker.vnc
17
+ if options.setup
18
+ docker.setup_vnc
19
+ else
20
+ docker.vnc
21
+ end
17
22
  end
18
23
 
19
24
  private
@@ -24,7 +29,7 @@ class DockerCLI < Thor
24
29
  end
25
30
  end
26
31
 
27
- desc 'docker', 'Manage docker containers for the current project.'
32
+ desc 'docker', 'Manage docker containers for the current project'
28
33
  long_desc <<-LONGDESC
29
34
  Manage docker containers to run your project dockerized.
30
35
 
@@ -35,10 +40,13 @@ There are three subcommands:
35
40
 
36
41
  - `geordi docker setup`
37
42
  Fetches all docker containers.
43
+
38
44
  - `geordi docker shell`
39
45
  Runs the docker service named 'main'.
46
+ Append `--secondary` to open a second shell in an already running container.
47
+
40
48
  - `geordi docker vnc`
41
49
  Opens a VNC viewer to connect to the VNC server in the container.
42
-
50
+ Append `--setup` to be guided through the setup of VNC viewer.
43
51
  LONGDESC
44
52
  subcommand 'docker', DockerCLI
@@ -47,6 +47,4 @@ def drop_databases
47
47
  cleaner = DBCleaner.new(extra_flags)
48
48
  cleaner.clean_mysql unless options.postgres_only
49
49
  cleaner.clean_postgres unless options.mysql_only
50
-
51
- Interaction.success 'Done.'
52
50
  end
@@ -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
@@ -10,5 +10,6 @@ def remove_executable_flags
10
10
  Interaction.note pattern
11
11
  `find . -name "#{pattern}" -exec chmod -x {} ';'`
12
12
  end
13
- puts 'Done.'
13
+
14
+ Interaction.success 'Done.'
14
15
  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 RSpec 1/2 support, parallel_tests detection and `bundle exec`.
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)
@@ -15,8 +15,6 @@ option :select_server, type: :string, aliases: '-s', banner: '[SERVER_NUMBER]',
15
15
  def shelll(target, *_args)
16
16
  require 'geordi/remote'
17
17
 
18
- invoke_geordi 'bundle_install'
19
-
20
18
  Interaction.announce 'Opening a shell on ' + target
21
19
  Geordi::Remote.new(target).shell(options)
22
20
  end
@@ -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 # Util.run! would reset the Firefox PATH
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('../../bin/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
- [use_firefox_for_selenium, Util.binstub_or_fallback('cucumber'), format_args, escape_shell_args(argv)].flatten.compact.join(' ')
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(' ')} --tags "#{not_tag('@solo')}"'),
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? '@solo'
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
@@ -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
- Interaction.note "Dropping MySQL/MariaDB database #{db}"
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 could be deleted:"
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 "Those #{dbtype} databases are not whitelisted and could be deleted."
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 'Not deleting anything'
229
+ Interaction.success 'Nothing deleted.'
230
230
  return []
231
231
  when 'y'
232
232
  return deletable_dbs