rspec-sharder 0.0.2 → 0.0.3

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: defc38fdaa55ddfeb271282a3ca2a992b0391fed1eb4be8d552fcd41caafc551
4
- data.tar.gz: 22fa847d430e3bc20069803710a0e3429eede4a58b4cd56d28eb3f9492c95f2c
3
+ metadata.gz: 7abffffb75542211fc36495edeca3b96f32f59b6975686568b3532d2df6ff9c6
4
+ data.tar.gz: 64bccf923c9897fa23205ade6af164ca10eb60dfc3c89b760b9a73be35d382bb
5
5
  SHA512:
6
- metadata.gz: 507e697bece492b62a5310f761c923e3956e328c014e6aa610fd2106c57c55662a84c23c1e91fca3ee8b3a2028d96832d1a7e790716f21c786d93bdf408c6342
7
- data.tar.gz: 443c1586f14b36142790ea916f3864e797481d8729e16b418e1fb123361d9f7263115cbe9ba7f710c2052d13547b9e1150799c9e80a2198613cb178d0fe1893c
6
+ metadata.gz: 3cbba17bc9116dbe0a8e3f6aef9d7865f57e40c6393d2e3d3243afacfc5dee658d33fe2c729734fb43ad291280a67f124913807f0b5d69eb28f13671d194309f
7
+ data.tar.gz: 809210eec8b32c39a87c6f64dbe6e9f699c1f1242b8edb1c0a9ea8120c7945801461744ad17065913f981a81bdfe1b5e1a031a2ce68a746871db995504e39ff1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-sharder (0.0.1)
4
+ rspec-sharder (0.0.2)
5
5
  rspec-core
6
6
 
7
7
  GEM
data/bin/rspec-sharder CHANGED
@@ -1,75 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'optparse'
4
- require 'rspec-sharder'
5
-
6
- def fail(message)
7
- warn message
8
- puts
9
- puts @parser.help
10
- exit 1
11
- end
12
-
13
- @total_shards = 1
14
- @shard_num = 1
15
- @persist = false
16
-
17
- @parser = OptionParser.new do |opts|
18
- opts.banner = <<~EOF
19
- Groups specs into shards, ensuring that each shard has a similar size, and runs
20
- the specified shard.
21
-
22
- Shard size is determined by summing the saved durations for each spec file in
23
- the shard. Durations are saved in .spec_durations. If a spec file is not found
24
- in .spec_durations, the duration is estimated based on the number of examples in
25
- the spec file.
26
-
27
- .spec_durations is generate/updated after a successful run when --persist is
28
- specified, but only for the shard which was actually executed. To generate
29
- durations for all shards simultaneously, run with the default options of 1 total
30
- shards and --persist:
31
-
32
- bundle exec rspec-sharder --persist -- [<rspec-args...>]
33
-
34
- Usage: bundle exec rspec-sharder [--total-shards <num> [--shard <num>]] [--persist] -- [<rspec-args...>]
35
-
36
- Options:
37
- EOF
38
-
39
- opts.on('-h', '--help', "Print this message.") do
40
- puts opts
41
- exit
42
- end
43
-
44
- opts.on('-t', '--total-shards <num>', 'The total number of shards. Defaults to 1.') do |total_shards|
45
- begin
46
- @total_shards = Integer(total_shards)
47
- rescue ArgumentError
48
- fail('fatal: invalid value for --total-shards')
49
- end
50
- end
51
-
52
- opts.on('-s', '--shard <num>', 'The shard to run. Defaults to 1.') do |shard|
53
- begin
54
- @shard = Integer(shard)
55
- rescue ArgumentError
56
- fail('fatal: invalid value for --shard')
57
- end
58
- end
59
-
60
- opts.on('-p', '--persist', 'Save durations to .spec_durations.') do
61
- @persist = true
62
- end
63
- end
64
-
65
- begin
66
- @parser.parse!
67
- rescue StandardError => e
68
- fail("fatal: #{e.message}")
69
- end
70
-
71
- fail('fatal: invalid value for --total-shards') unless @total_shards > 0
72
- fail('fatal: invalid value for --shard') unless @shard > 0
73
- fail('fatal: --shard may not be greater than --total-shards') unless @shard <= @total_shards
74
-
75
- RSpec::Sharder.run(total_shards: @total_shards, shard_num: @shard, persist: @persist, rspec_args: ARGV)
3
+ require 'rspec-sharder/command'
@@ -0,0 +1,73 @@
1
+ require 'optparse'
2
+ require 'rspec-sharder'
3
+
4
+ def fail(message)
5
+ warn message
6
+ puts
7
+ puts @parser.help
8
+ exit 1
9
+ end
10
+
11
+ @total_shards = 1
12
+ @shard = 1
13
+ @persist = false
14
+
15
+ @parser = OptionParser.new do |opts|
16
+ opts.banner = <<~EOF
17
+ Groups specs into shards, ensuring that each shard has a similar size, and runs
18
+ the specified shard.
19
+
20
+ Shard size is determined by summing the saved durations for each spec file in
21
+ the shard. Durations are saved in .spec_durations. If a spec file is not found
22
+ in .spec_durations, the duration is estimated based on the number of examples in
23
+ the spec file.
24
+
25
+ .spec_durations is generate/updated after a successful run when --persist is
26
+ specified, but only for the shard which was actually executed. To generate
27
+ durations for all shards simultaneously, run with the default options of 1 total
28
+ shards and --persist:
29
+
30
+ bundle exec rspec-sharder --persist -- [<rspec-args...>]
31
+
32
+ Usage: bundle exec rspec-sharder [--total-shards <num> [--shard <num>]] [--persist] -- [<rspec-args...>]
33
+
34
+ Options:
35
+ EOF
36
+
37
+ opts.on('-h', '--help', "Print this message.") do
38
+ puts opts
39
+ exit
40
+ end
41
+
42
+ opts.on('-t', '--total-shards <num>', 'The total number of shards. Defaults to 1.') do |total_shards|
43
+ begin
44
+ @total_shards = Integer(total_shards)
45
+ rescue ArgumentError
46
+ fail('fatal: invalid value for --total-shards')
47
+ end
48
+ end
49
+
50
+ opts.on('-s', '--shard <num>', 'The shard to run. Defaults to 1.') do |shard|
51
+ begin
52
+ @shard = Integer(shard)
53
+ rescue ArgumentError
54
+ fail('fatal: invalid value for --shard')
55
+ end
56
+ end
57
+
58
+ opts.on('-p', '--persist', 'Save durations to .spec_durations.') do
59
+ @persist = true
60
+ end
61
+ end
62
+
63
+ begin
64
+ @parser.parse!
65
+ rescue StandardError => e
66
+ fail("fatal: #{e.message}")
67
+ end
68
+
69
+ fail('fatal: invalid value for --total-shards') unless @total_shards > 0
70
+ fail('fatal: invalid value for --shard') unless @shard > 0
71
+ fail('fatal: --shard may not be greater than --total-shards') unless @shard <= @total_shards
72
+
73
+ RSpec::Sharder.run(total_shards: @total_shards, shard_num: @shard, persist: @persist, rspec_args: ARGV)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module Sharder
5
- VERSION = "0.0.2"
5
+ VERSION = "0.0.3"
6
6
  end
7
7
  end
data/lib/rspec-sharder.rb CHANGED
@@ -50,12 +50,9 @@ module RSpec
50
50
  end
51
51
 
52
52
  group_results = example_groups.map do |example_group|
53
- start_time = current_time_millis
54
- result = example_group.run(reporter)
55
- end_time = current_time_millis
53
+ result, duration = run_example_group(example_group, reporter)
56
54
 
57
55
  file_path = example_group.metadata[:file_path]
58
- duration = (end_time - start_time).to_i
59
56
  actual_total_duration += duration
60
57
  new_durations[file_path] ||= 0
61
58
  new_durations[file_path] += duration
@@ -88,10 +85,7 @@ module RSpec
88
85
  else
89
86
  if exit_code == 0
90
87
  # Print recorded durations and summary.
91
- ::RSpec.configuration.output_stream.puts <<~EOF
92
-
93
- Durations:
94
- EOF
88
+ ::RSpec.configuration.output_stream.puts 'Durations'
95
89
 
96
90
  new_durations.sort_by { |file_path, duration| file_path }.each do |file_path, duration|
97
91
  ::RSpec.configuration.output_stream.puts "#{file_path},#{duration}"
@@ -177,7 +171,7 @@ module RSpec
177
171
  if durations[file_path]
178
172
  files[file_path] = durations[file_path]
179
173
  else
180
- ::RSpec.configuration.error_stream.puts "warning: recorded duration not found for #{file_path}"
174
+ ::RSpec.configuration.output_stream.puts "warning: recorded duration not found for #{file_path}"
181
175
 
182
176
  # Assume 1000 milliseconds per example.
183
177
  files[file_path] += ::RSpec.world.example_count([example_group]) * 1000
@@ -209,7 +203,7 @@ module RSpec
209
203
  end
210
204
  ::RSpec::Core::ExampleStatusPersister.persist(examples, path)
211
205
  rescue SystemCallError => e
212
- ::RSpec.configuration.error_stream.puts "warning: failed to write results to #{path}"
206
+ ::RSpec.configuration.output_stream.puts "warning: failed to write results to #{path}"
213
207
  end
214
208
 
215
209
  def self.pretty_duration(duration_millis)
@@ -236,7 +230,7 @@ module RSpec
236
230
  shard[:file_paths].each do |file_path|
237
231
  ::RSpec.configuration.output_stream.puts file_path
238
232
  end
239
- ::RSpec.configuration.output_stream.puts
233
+ ::RSpec.configuration.output_stream.puts unless i == shards.size - 1
240
234
  end
241
235
  end
242
236
 
@@ -255,5 +249,11 @@ module RSpec
255
249
  def self.current_time_millis
256
250
  (Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000).to_i
257
251
  end
252
+
253
+ def self.run_example_group(example_group, reporter)
254
+ start_time = current_time_millis
255
+ result = example_group.run(reporter)
256
+ [result, (current_time_millis - start_time).to_i]
257
+ end
258
258
  end
259
259
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-sharder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Dower
@@ -39,6 +39,7 @@ files:
39
39
  - README.md
40
40
  - bin/rspec-sharder
41
41
  - lib/rspec-sharder.rb
42
+ - lib/rspec-sharder/command.rb
42
43
  - lib/rspec-sharder/version.rb
43
44
  - rspec-sharder.gemspec
44
45
  - scripts/release.sh