parallel_tests 3.0.0 → 3.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c8f92fb8fb19ff4348080358222c4984bcc5721ddd4779433ad4b8beead46a0
4
- data.tar.gz: e3fb4beed5a5391401e8fcd729a5308c274ac2ddc61b3cd548e655a25009ba5d
3
+ metadata.gz: 296e1e8f85f982a03a1b03882cdb265518add4b7a426defa0e393248dab74c0c
4
+ data.tar.gz: '09ca0aaa70fbf4ad7d73ce91c83d1c16b69fdc1612931ee1e6f71dd87cb1bbb9'
5
5
  SHA512:
6
- metadata.gz: bff5dfd53ba1acc4bb654d17f49d9d9deb1c86eff894232fc698dd3100fd2fbb7dd15ad11c1ebdc501438003ce62b2f65a7befcbc970e15d2b3e340f47ebf928
7
- data.tar.gz: a5ded77e36a14a8bebea03777666e6de95f787edaf79dcf27b8d99d91c69b4779cb43e5ba5daf13f7940b2b262ad49eede907e8c9482749e30e2b272cf965245
6
+ metadata.gz: 5f627a0bf28e53045281f616cecdc57c70da160c525e62e2425ccd431f7ac1f0c70f54ca72661e84a2ace1a9bdbb59cd54f602ad71c0df178f00e01c275ef4fa
7
+ data.tar.gz: 28119c3ec31c49c22e01c6c737fd9cfb7fa922e5bbfbfc3e90260c5714a6a1cabfbcaff2e1e91377d33811362ee038d4bbee21027fb98208e44485aaa863e89d
data/Readme.md CHANGED
@@ -37,6 +37,9 @@ test:
37
37
  ### Copy development schema (repeat after migrations)
38
38
  rake parallel:prepare
39
39
 
40
+ ### Run migrations in additional database(s) (repeat after migrations)
41
+ rake parallel:migrate
42
+
40
43
  ### Setup environment from scratch (create db and loads schema, useful for CI)
41
44
  rake parallel:setup
42
45
 
@@ -82,6 +85,8 @@ Running things once
82
85
  ===================
83
86
 
84
87
  ```Ruby
88
+ require "parallel_tests"
89
+
85
90
  # preparation:
86
91
  # affected by race-condition: first process may boot slower than the second
87
92
  # either sleep a bit or use a lock for example File.lock
@@ -97,7 +102,6 @@ at_exit do
97
102
  undo_something
98
103
  end
99
104
  end
100
-
101
105
  ```
102
106
 
103
107
  Even test group run-times
@@ -141,17 +145,19 @@ Add the following to your `.rspec_parallel` (or `.rspec`) :
141
145
  RSpec: FailuresLogger
142
146
  -----------------------
143
147
 
144
- Produce pasteable command-line snippets for each failed example.
148
+ Produce pastable command-line snippets for each failed example. For example:
145
149
 
146
- E.g.
150
+ ```bash
151
+ rspec /path/to/my_spec.rb:123 # should do something
152
+ ```
147
153
 
148
- rspec /path/to/my_spec.rb:123 # should do something
149
-
150
- Add the following to your `.rspec_parallel` (or `.rspec`) :
154
+ Add to `.rspec_parallel` or use as CLI flag:
151
155
 
152
156
  --format progress
153
157
  --format ParallelTests::RSpec::FailuresLogger --out tmp/failing_specs.log
154
158
 
159
+ (Not needed to retry failures, for that pass [--only-failures](https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures) to rspec)
160
+
155
161
  Cucumber: FailuresLogger
156
162
  -----------------------
157
163
 
@@ -192,7 +198,6 @@ Setup for non-rails
192
198
 
193
199
  Options are:
194
200
  <!-- copy output from bundle exec ./bin/parallel_test -h -->
195
-
196
201
  -n [PROCESSES] How many processes to use, default: available CPUs
197
202
  -p, --pattern [PATTERN] run tests matching this regex pattern
198
203
  --exclude-pattern [PATTERN] exclude tests matching this regex pattern
@@ -205,8 +210,19 @@ Options are:
205
210
  default - runtime when runtime log is filled otherwise filesize
206
211
  -m, --multiply-processes [FLOAT] use given number as a multiplier of processes to run
207
212
  -s, --single [PATTERN] Run all matching files in the same process
208
- -i, --isolate Do not run any other tests in the group used by --single(-s)
209
- --only-group INT[, INT]
213
+ -i, --isolate Do not run any other tests in the group used by --single(-s).
214
+ Automatically turned on if --isolate-n is set above 0.
215
+ --isolate-n Number of processes for isolated groups. Default to 1 when --isolate is on.
216
+ --specify-groups [SPECS] Use 'specify-groups' if you want to specify multiple specs running in multiple
217
+ processes in a specific formation. Commas indicate specs in the same process,
218
+ pipes indicate specs in a new process. Cannot use with --single, --isolate, or
219
+ --isolate-n. Ex.
220
+ Ex.
221
+ $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
222
+ Process 1 will contain 1_spec.rb and 2_spec.rb
223
+ Process 2 will contain 3_spec.rb
224
+ Process 3 will contain all other specs
225
+ --only-group INT[,INT]
210
226
  -e, --exec [COMMAND] execute this code parallel and with ENV['TEST_ENV_NUMBER']
211
227
  -o, --test-options '[OPTIONS]' execute test commands with those options
212
228
  -t, --type [TYPE] test(default) / rspec / cucumber / spinach
@@ -222,12 +238,14 @@ Options are:
222
238
  --ignore-tags [PATTERN] When counting steps ignore scenarios with tags that match this pattern
223
239
  --nice execute test commands with low priority.
224
240
  --runtime-log [PATH] Location of previously recorded test runtimes
225
- --allowed-missing Allowed percentage of missing runtimes (default = 50)
241
+ --allowed-missing [INT] Allowed percentage of missing runtimes (default = 50)
226
242
  --unknown-runtime [FLOAT] Use given number as unknown runtime (otherwise use average time)
243
+ --first-is-1 Use "1" as TEST_ENV_NUMBER to not reuse the default test environment
244
+ --fail-fast Stop all groups when one group fails (best used with --test-options '--fail-fast' if supported
227
245
  --verbose Print debug output
228
- --verbose-process-command Print the command that will be executed by each process before it begins
229
- --verbose-rerun-command After a process fails, print the command executed by that process
230
- --quiet Print only test output
246
+ --verbose-process-command Displays only the command that will be executed by each process
247
+ --verbose-rerun-command When there are failures, displays the command executed by each process that failed
248
+ --quiet Print only tests output
231
249
  -v, --version Show Version
232
250
  -h, --help Show this.
233
251
 
@@ -257,7 +275,7 @@ TIPS
257
275
  - Use [rspec-retry](https://github.com/NoRedInk/rspec-retry) (not rspec-rerun) to rerun failed tests.
258
276
  - [JUnit formatter configuration](https://github.com/grosser/parallel_tests/wiki#with-rspec_junit_formatter----by-jgarber)
259
277
  - Use [parallel_split_test](https://github.com/grosser/parallel_split_test) to run multiple scenarios in a single spec file, concurrently. (`parallel_tests` [works at the file-level and intends to stay that way](https://github.com/grosser/parallel_tests/issues/747#issuecomment-580216980))
260
-
278
+
261
279
  ### Cucumber
262
280
 
263
281
  - Add a `parallel: foo` profile to your `config/cucumber.yml` and it will be used to run parallel tests
@@ -278,7 +296,7 @@ TIPS
278
296
  `export PARALLEL_TEST_FIRST_IS_1=true` will provide the same result
279
297
  - [email_spec and/or action_mailer_cache_delivery](https://github.com/grosser/parallel_tests/wiki)
280
298
  - [zeus-parallel_tests](https://github.com/sevos/zeus-parallel_tests)
281
- - [Distributed parallel test (e.g. Travis Support)](https://github.com/grosser/parallel_tests/wiki/Distributed-Parallel-Tests-and-Travis-Support)
299
+ - [Distributed Parallel Tests on CI systems)](https://github.com/grosser/parallel_tests/wiki/Distributed-Parallel-Tests-on-CI-systems) learn how `parallel_tests` can run on distributed servers such as Travis and GitLab-CI. Also shows you how to use parallel_tests without adding `TEST_ENV_NUMBER`-backends
282
300
  - [Capybara setup](https://github.com/grosser/parallel_tests/wiki)
283
301
  - [Sphinx setup](https://github.com/grosser/parallel_tests/wiki)
284
302
  - [Capistrano setup](https://github.com/grosser/parallel_tests/wiki/Remotely-with-capistrano) let your tests run on a big box instead of your laptop
@@ -374,6 +392,8 @@ inspired by [pivotal labs](https://blog.pivotal.io/labs/labs/parallelize-your-rs
374
392
  - [Calaway](https://github.com/calaway)
375
393
  - [alboyadjian](https://github.com/alboyadjian)
376
394
  - [Nathan Broadbent](https://github.com/ndbroadbent)
395
+ - [Vikram B Kumar](https://github.com/v-kumar)
396
+ - [Joshua Pinter](https://github.com/joshuapinter)
377
397
 
378
398
  [Michael Grosser](http://grosser.it)<br/>
379
399
  michael@grosser.it<br/>
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # enable local usage from cloned repo
4
- root = File.expand_path("../..", __FILE__)
5
+ root = File.expand_path('..', __dir__)
5
6
  $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
7
 
7
8
  require "parallel_tests"
data/bin/parallel_rspec CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # enable local usage from cloned repo
4
- root = File.expand_path("../..", __FILE__)
5
+ root = File.expand_path('..', __dir__)
5
6
  $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
7
 
7
8
  require "parallel_tests"
data/bin/parallel_spinach CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # enable local usage from cloned repo
4
- root = File.expand_path("../..", __FILE__)
5
+ root = File.expand_path('..', __dir__)
5
6
  $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
7
 
7
8
  require "parallel_tests"
data/bin/parallel_test CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # enable local usage from cloned repo
4
- root = File.expand_path("../..", __FILE__)
5
+ root = File.expand_path('..', __dir__)
5
6
  $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
7
 
7
8
  require "parallel_tests"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "parallel"
2
3
  require "parallel_tests/railtie" if defined? Rails::Railtie
3
4
  require "rbconfig"
@@ -17,7 +18,7 @@ module ParallelTests
17
18
  count,
18
19
  ENV["PARALLEL_TEST_PROCESSORS"],
19
20
  Parallel.processor_count
20
- ].detect{|c| not c.to_s.strip.empty? }.to_i
21
+ ].detect { |c| !c.to_s.strip.empty? }.to_i
21
22
  end
22
23
 
23
24
  def with_pid_file
@@ -57,7 +58,8 @@ module ParallelTests
57
58
  until !File.directory?(current) || current == previous
58
59
  filename = File.join(current, "Gemfile")
59
60
  return true if File.exist?(filename)
60
- current, previous = File.expand_path("..", current), current
61
+ previous = current
62
+ current = File.expand_path("..", current)
61
63
  end
62
64
 
63
65
  false
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'optparse'
2
3
  require 'tempfile'
3
4
  require 'parallel_tests'
@@ -14,7 +15,7 @@ module ParallelTests
14
15
  ENV['DISABLE_SPRING'] ||= '1'
15
16
 
16
17
  num_processes = ParallelTests.determine_number_of_processes(options[:count])
17
- num_processes = num_processes * (options[:multiply] || 1)
18
+ num_processes *= (options[:multiply] || 1)
18
19
 
19
20
  options[:first_is_1] ||= first_is_1?
20
21
 
@@ -42,9 +43,10 @@ module ParallelTests
42
43
  Tempfile.open 'parallel_tests-lock' do |lock|
43
44
  ParallelTests.with_pid_file do
44
45
  simulate_output_for_ci options[:serialize_stdout] do
45
- Parallel.map(items, :in_threads => num_processes) do |item|
46
+ Parallel.map(items, in_threads: num_processes) do |item|
46
47
  result = yield(item)
47
48
  reprint_output(result, lock.path) if options[:serialize_stdout]
49
+ ParallelTests.stop_all_processes if options[:fail_fast] && result[:exit_status] != 0
48
50
  result
49
51
  end
50
52
  end
@@ -55,12 +57,12 @@ module ParallelTests
55
57
  def run_tests_in_parallel(num_processes, options)
56
58
  test_results = nil
57
59
 
58
- run_tests_proc = -> {
60
+ run_tests_proc = -> do
59
61
  groups = @runner.tests_in_groups(options[:files], num_processes, options)
60
- groups.reject! &:empty?
62
+ groups.reject!(&:empty?)
61
63
 
62
64
  test_results = if options[:only_group]
63
- groups_to_run = options[:only_group].collect{|i| groups[i - 1]}.compact
65
+ groups_to_run = options[:only_group].map { |i| groups[i - 1] }.compact
64
66
  report_number_of_tests(groups_to_run) unless options[:quiet]
65
67
  execute_in_parallel(groups_to_run, groups_to_run.size, options) do |group|
66
68
  run_tests(group, groups_to_run.index(group), 1, options)
@@ -74,7 +76,7 @@ module ParallelTests
74
76
  end
75
77
 
76
78
  report_results(test_results, options) unless options[:quiet]
77
- }
79
+ end
78
80
 
79
81
  if options[:quiet]
80
82
  run_tests_proc.call
@@ -87,7 +89,7 @@ module ParallelTests
87
89
 
88
90
  def run_tests(group, process_number, num_processes, options)
89
91
  if group.empty?
90
- {:stdout => '', :exit_status => 0, :command => '', :seed => nil}
92
+ { stdout: '', exit_status: 0, command: '', seed: nil }
91
93
  else
92
94
  @runner.run_tests(group, process_number, num_processes, options)
93
95
  end
@@ -114,7 +116,7 @@ module ParallelTests
114
116
  end
115
117
 
116
118
  def report_results(test_results, options)
117
- results = @runner.find_results(test_results.map { |result| result[:stdout] }*"")
119
+ results = @runner.find_results(test_results.map { |result| result[:stdout] } * "")
118
120
  puts ""
119
121
  puts @runner.summarize_results(results)
120
122
 
@@ -139,20 +141,31 @@ module ParallelTests
139
141
  def report_number_of_tests(groups)
140
142
  name = @runner.test_file_name
141
143
  num_processes = groups.size
142
- num_tests = groups.map(&:size).inject(0, :+)
144
+ num_tests = groups.map(&:size).sum
143
145
  tests_per_process = (num_processes == 0 ? 0 : num_tests / num_processes)
144
- puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{tests_per_process} #{name}s per process"
146
+ puts "#{pluralize(num_processes, 'process')} for #{pluralize(num_tests, name)}, ~ #{pluralize(tests_per_process, name)} per process"
147
+ end
148
+
149
+ def pluralize(n, singular)
150
+ if n == 1
151
+ "1 #{singular}"
152
+ elsif singular.end_with?('s', 'sh', 'ch', 'x', 'z')
153
+ "#{n} #{singular}es"
154
+ else
155
+ "#{n} #{singular}s"
156
+ end
145
157
  end
146
158
 
147
- #exit with correct status code so rake parallel:test && echo 123 works
159
+ # exit with correct status code so rake parallel:test && echo 123 works
148
160
  def any_test_failed?(test_results)
149
161
  test_results.any? { |result| result[:exit_status] != 0 }
150
162
  end
151
163
 
152
164
  def parse_options!(argv)
165
+ newline_padding = " " * 37
153
166
  options = {}
154
167
  OptionParser.new do |opts|
155
- opts.banner = <<-BANNER.gsub(/^ /, '')
168
+ opts.banner = <<~BANNER
156
169
  Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
157
170
 
158
171
  [optional] Only selected files & folders:
@@ -166,32 +179,51 @@ module ParallelTests
166
179
  opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n }
167
180
  opts.on("-p", "--pattern [PATTERN]", "run tests matching this regex pattern") { |pattern| options[:pattern] = /#{pattern}/ }
168
181
  opts.on("--exclude-pattern", "--exclude-pattern [PATTERN]", "exclude tests matching this regex pattern") { |pattern| options[:exclude_pattern] = /#{pattern}/ }
169
- opts.on("--group-by [TYPE]", <<-TEXT.gsub(/^ /, '')
170
- group tests by:
171
- found - order of finding files
172
- steps - number of cucumber/spinach steps
173
- scenarios - individual cucumber scenarios
174
- filesize - by size of the file
175
- runtime - info from runtime log
176
- default - runtime when runtime log is filled otherwise filesize
182
+ opts.on(
183
+ "--group-by [TYPE]",
184
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
185
+ group tests by:
186
+ found - order of finding files
187
+ steps - number of cucumber/spinach steps
188
+ scenarios - individual cucumber scenarios
189
+ filesize - by size of the file
190
+ runtime - info from runtime log
191
+ default - runtime when runtime log is filled otherwise filesize
177
192
  TEXT
178
- ) { |type| options[:group_by] = type.to_sym }
179
- opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run") { |multiply| options[:multiply] = multiply }
180
-
181
- opts.on("-s [PATTERN]", "--single [PATTERN]",
182
- "Run all matching files in the same process") do |pattern|
183
-
184
- options[:single_process] ||= []
185
- options[:single_process] << /#{pattern}/
193
+ ) { |type| options[:group_by] = type.to_sym }
194
+ opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run") do |multiply|
195
+ options[:multiply] = multiply
186
196
  end
187
197
 
188
- opts.on("-i", "--isolate",
189
- "Do not run any other tests in the group used by --single(-s)") do |pattern|
198
+ opts.on("-s [PATTERN]", "--single [PATTERN]", "Run all matching files in the same process") do |pattern|
199
+ (options[:single_process] ||= []) << /#{pattern}/
200
+ end
190
201
 
202
+ opts.on("-i", "--isolate", "Do not run any other tests in the group used by --single(-s)") do
191
203
  options[:isolate] = true
192
204
  end
193
205
 
194
- opts.on("--only-group INT[, INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
206
+ opts.on(
207
+ "--isolate-n [PROCESSES]",
208
+ Integer,
209
+ "Use 'isolate' singles with number of processes, default: 1."
210
+ ) { |n| options[:isolate_count] = n }
211
+
212
+ opts.on(
213
+ "--specify-groups [SPECS]",
214
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
215
+ Use 'specify-groups' if you want to specify multiple specs running in multiple
216
+ processes in a specific formation. Commas indicate specs in the same process,
217
+ pipes indicate specs in a new process. Cannot use with --single, --isolate, or
218
+ --isolate-n. Ex.
219
+ $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
220
+ Process 1 will contain 1_spec.rb and 2_spec.rb
221
+ Process 2 will contain 3_spec.rb
222
+ Process 3 will contain all other specs
223
+ TEXT
224
+ ) { |groups| options[:specify_groups] = groups }
225
+
226
+ opts.on("--only-group INT[,INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
195
227
 
196
228
  opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |path| options[:execute] = path }
197
229
  opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = arg.lstrip }
@@ -203,34 +235,41 @@ module ParallelTests
203
235
  abort
204
236
  end
205
237
  end
206
- opts.on("--suffix [PATTERN]", <<-TEXT.gsub(/^ /, '')
207
- override built in test file pattern (should match suffix):
208
- '_spec\.rb$' - matches rspec files
209
- '_(test|spec).rb$' - matches test or spec files
238
+ opts.on(
239
+ "--suffix [PATTERN]",
240
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
241
+ override built in test file pattern (should match suffix):
242
+ '_spec\.rb$' - matches rspec files
243
+ '_(test|spec).rb$' - matches test or spec files
210
244
  TEXT
211
- ) { |pattern| options[:suffix] = /#{pattern}/ }
245
+ ) { |pattern| options[:suffix] = /#{pattern}/ }
212
246
  opts.on("--serialize-stdout", "Serialize stdout output, nothing will be written until everything is done") { options[:serialize_stdout] = true }
213
247
  opts.on("--prefix-output-with-test-env-number", "Prefixes test env number to the output when not using --serialize-stdout") { options[:prefix_output_with_test_env_number] = true }
214
248
  opts.on("--combine-stderr", "Combine stderr into stdout, useful in conjunction with --serialize-stdout") { options[:combine_stderr] = true }
215
249
  opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec") { options[:non_parallel] = true }
216
250
  opts.on("--no-symlinks", "Do not traverse symbolic links to find test files") { options[:symlinks] = false }
217
- opts.on('--ignore-tags [PATTERN]', 'When counting steps ignore scenarios with tags that match this pattern') { |arg| options[:ignore_tag_pattern] = arg }
251
+ opts.on('--ignore-tags [PATTERN]', 'When counting steps ignore scenarios with tags that match this pattern') { |arg| options[:ignore_tag_pattern] = arg }
218
252
  opts.on("--nice", "execute test commands with low priority.") { options[:nice] = true }
219
253
  opts.on("--runtime-log [PATH]", "Location of previously recorded test runtimes") { |path| options[:runtime_log] = path }
220
254
  opts.on("--allowed-missing [INT]", Integer, "Allowed percentage of missing runtimes (default = 50)") { |percent| options[:allowed_missing_percent] = percent }
221
255
  opts.on("--unknown-runtime [FLOAT]", Float, "Use given number as unknown runtime (otherwise use average time)") { |time| options[:unknown_runtime] = time }
222
256
  opts.on("--first-is-1", "Use \"1\" as TEST_ENV_NUMBER to not reuse the default test environment") { options[:first_is_1] = true }
257
+ opts.on("--fail-fast", "Stop all groups when one group fails (best used with --test-options '--fail-fast' if supported") { options[:fail_fast] = true }
223
258
  opts.on("--verbose", "Print debug output") { options[:verbose] = true }
224
259
  opts.on("--verbose-process-command", "Displays only the command that will be executed by each process") { options[:verbose_process_command] = true }
225
260
  opts.on("--verbose-rerun-command", "When there are failures, displays the command executed by each process that failed") { options[:verbose_rerun_command] = true }
226
261
  opts.on("--quiet", "Print only tests output") { options[:quiet] = true }
227
- opts.on("-v", "--version", "Show Version") { puts ParallelTests::VERSION; exit }
228
- opts.on("-h", "--help", "Show this.") { puts opts; exit }
262
+ opts.on("-v", "--version", "Show Version") do
263
+ puts ParallelTests::VERSION
264
+ exit 0
265
+ end
266
+ opts.on("-h", "--help", "Show this.") do
267
+ puts opts
268
+ exit 0
269
+ end
229
270
  end.parse!(argv)
230
271
 
231
- if options[:verbose] && options[:quiet]
232
- raise "Both options are mutually exclusive: verbose & quiet"
233
- end
272
+ raise "Both options are mutually exclusive: verbose & quiet" if options[:verbose] && options[:quiet]
234
273
 
235
274
  if options[:count] == 0
236
275
  options.delete(:count)
@@ -247,12 +286,18 @@ module ParallelTests
247
286
 
248
287
  options[:group_by] ||= :filesize if options[:only_group]
249
288
 
250
- raise "--group-by found and --single-process are not supported" if options[:group_by] == :found and options[:single_process]
289
+ if options[:group_by] == :found && options[:single_process]
290
+ raise "--group-by found and --single-process are not supported"
291
+ end
251
292
  allowed = [:filesize, :runtime, :found]
252
293
  if !allowed.include?(options[:group_by]) && options[:only_group]
253
294
  raise "--group-by #{allowed.join(" or ")} is required for --only-group"
254
295
  end
255
296
 
297
+ if options[:specify_groups] && (options.keys & [:single_process, :isolate, :isolate_count]).any?
298
+ raise "Can't pass --specify-groups with any of these keys: --single, --isolate, or --isolate-n"
299
+ end
300
+
256
301
  options
257
302
  end
258
303
 
@@ -264,7 +309,7 @@ module ParallelTests
264
309
 
265
310
  def extract_test_options(argv)
266
311
  dash_index = argv.index("--") || -1
267
- argv[dash_index+1..-1]
312
+ argv[dash_index + 1..-1]
268
313
  end
269
314
 
270
315
  def append_test_options(options, argv)
@@ -284,7 +329,7 @@ module ParallelTests
284
329
 
285
330
  def execute_shell_command_in_parallel(command, num_processes, options)
286
331
  runs = if options[:only_group]
287
- options[:only_group].map{|g| g - 1}
332
+ options[:only_group].map { |g| g - 1 }
288
333
  else
289
334
  (0...num_processes).to_a
290
335
  end
@@ -303,13 +348,13 @@ module ParallelTests
303
348
  abort if results.any? { |r| r[:exit_status] != 0 }
304
349
  end
305
350
 
306
- def report_time_taken
307
- seconds = ParallelTests.delta { yield }.to_i
351
+ def report_time_taken(&block)
352
+ seconds = ParallelTests.delta(&block).to_i
308
353
  puts "\nTook #{seconds} seconds#{detailed_duration(seconds)}"
309
354
  end
310
355
 
311
356
  def detailed_duration(seconds)
312
- parts = [ seconds / 3600, seconds % 3600 / 60, seconds % 60 ].drop_while(&:zero?)
357
+ parts = [seconds / 3600, seconds % 3600 / 60, seconds % 60].drop_while(&:zero?)
313
358
  return if parts.size < 2
314
359
  parts = parts.map { |i| "%02d" % i }.join(':').sub(/^0/, '')
315
360
  " (#{parts})"