specbandit 0.11.0 → 0.12.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: '0284e5da8c01b4c149f7dedf22165ba743acd715de01073c9dc5fda6dd35742b'
4
- data.tar.gz: 7181e9efdc91cdeb1a80675d147f12934685c73a192aad42897d080a945675d1
3
+ metadata.gz: 82b0e7cfc34d8564657fc313dc9f0e4432a8c7c88795690670da3f86a21acd64
4
+ data.tar.gz: 321f4437b8a265664b72f30cd38f03cdd5b03f5f7814d00f608096a6fa47b19c
5
5
  SHA512:
6
- metadata.gz: 7effa3ce71d27cf6cc9a4166d99529dea22ebaa488a9100369a4e2834471e5f59358812653ccf10f29872de31a35ea591c995c7ad0e4b666ef7d50c4a00494d9
7
- data.tar.gz: bf2dfea12cd23511f63ccfa811a035966f81a35c6a26a93352990872908fa6eebb899855e4e5c3b4c6019d466e6e3d12eccafa0a329f4ea7741004de84b6be91
6
+ metadata.gz: f3e05b5368da44a918d66432edd5985cfb461f9505f1a47ba56b4d7e599cdae48395a9e5b8da5bbd015c9d1540a567ea97d719ef40004fe36238c5afe013adc9
7
+ data.tar.gz: a5cc4f6d8844a31f9f98eb6caf5928424cccf2d4fa662d06f7a853a095ff6c8a1ef155169eaea659fb7c2e57a38d1e2c76f67dd9723260fca0bc6b410ea27eb3
@@ -65,10 +65,10 @@ module Specbandit
65
65
  ensure
66
66
  # Print RSpec output through our output stream
67
67
  rspec_output = out&.string
68
- output.print(rspec_output) if verbose && rspec_output && !rspec_output.empty?
68
+ output.print(rspec_output) if rspec_output && !rspec_output.empty?
69
69
 
70
70
  rspec_err = err&.string
71
- output.print(rspec_err) if verbose && rspec_err && !rspec_err.empty?
71
+ output.print(rspec_err) if rspec_err && !rspec_err.empty?
72
72
 
73
73
  # Don't unlink the tempfile here — the Worker needs to read it.
74
74
  # The Worker is responsible for cleanup after accumulation.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Specbandit
4
- VERSION = '0.11.0'
4
+ VERSION = '0.12.0'
5
5
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'stringio'
4
3
  require 'json'
5
4
 
6
5
  module Specbandit
@@ -67,8 +66,6 @@ module Specbandit
67
66
 
68
67
  print_summary if @batch_results.any?
69
68
  merge_json_results
70
- write_github_step_summary if ENV['GITHUB_STEP_SUMMARY']
71
-
72
69
  exit_code
73
70
  ensure
74
71
  adapter.teardown
@@ -80,29 +77,31 @@ module Specbandit
80
77
  # Used when re-running a failed CI job -- the rerun key already
81
78
  # contains the exact files this runner executed previously.
82
79
  def run_replay(files)
83
- output.puts "[specbandit] Replay mode: found #{files.size} files in rerun key '#{key_rerun}'."
84
- output.puts '[specbandit] Running previously recorded files (not touching shared queue).'
80
+ output.puts "[specbandit] Replay mode: found #{files.size} files in rerun key '#{key_rerun}'." if verbose
81
+ output.puts '[specbandit] Running previously recorded files (not touching shared queue).' if verbose
85
82
 
86
83
  failed = false
87
84
  batch_num = 0
88
85
 
89
86
  files.each_slice(batch_size) do |batch|
90
87
  batch_num += 1
91
- output.puts "[specbandit] Batch ##{batch_num}: running #{batch.size} files"
88
+ output.puts "[specbandit] Batch ##{batch_num}: running #{batch.size} files" if verbose
92
89
  batch.each { |f| output.puts " #{f}" } if verbose
93
90
 
94
91
  result = adapter.run_batch(batch, batch_num)
95
92
  process_batch_result(result)
96
93
 
97
94
  if result.exit_code != 0
98
- output.puts "[specbandit] Batch ##{batch_num} FAILED (exit code: #{result.exit_code})"
95
+ output.puts "[specbandit] Batch ##{batch_num} FAILED (exit code: #{result.exit_code})" if verbose
99
96
  failed = true
100
- else
97
+ elsif verbose
101
98
  output.puts "[specbandit] Batch ##{batch_num} passed."
102
99
  end
103
100
  end
104
101
 
105
- output.puts "[specbandit] Replay finished: #{batch_num} batches. #{failed ? 'SOME FAILED' : 'All passed.'}"
102
+ if verbose
103
+ output.puts "[specbandit] Replay finished: #{batch_num} batches. #{failed ? 'SOME FAILED' : 'All passed.'}"
104
+ end
106
105
  failed ? 1 : 0
107
106
  end
108
107
 
@@ -111,8 +110,8 @@ module Specbandit
111
110
  # rerun key so this runner can replay them on a re-run.
112
111
  def run_steal(record:)
113
112
  mode_label = record ? 'Record' : 'Steal'
114
- output.puts "[specbandit] #{mode_label} mode: stealing batches from '#{key}'."
115
- output.puts "[specbandit] Recording stolen files to rerun key '#{key_rerun}'." if record
113
+ output.puts "[specbandit] #{mode_label} mode: stealing batches from '#{key}'." if verbose
114
+ output.puts "[specbandit] Recording stolen files to rerun key '#{key_rerun}'." if verbose && record
116
115
 
117
116
  failed = false
118
117
  batch_num = 0
@@ -121,7 +120,7 @@ module Specbandit
121
120
  files = queue.steal(key, batch_size)
122
121
 
123
122
  if files.empty?
124
- output.puts '[specbandit] Queue exhausted. No more files to run.'
123
+ output.puts '[specbandit] Queue exhausted. No more files to run.' if verbose
125
124
  break
126
125
  end
127
126
 
@@ -129,23 +128,23 @@ module Specbandit
129
128
  queue.push(key_rerun, files, ttl: key_rerun_ttl) if record
130
129
 
131
130
  batch_num += 1
132
- output.puts "[specbandit] Batch ##{batch_num}: running #{files.size} files"
131
+ output.puts "[specbandit] Batch ##{batch_num}: running #{files.size} files" if verbose
133
132
  files.each { |f| output.puts " #{f}" } if verbose
134
133
 
135
134
  result = adapter.run_batch(files, batch_num)
136
135
  process_batch_result(result)
137
136
 
138
137
  if result.exit_code != 0
139
- output.puts "[specbandit] Batch ##{batch_num} FAILED (exit code: #{result.exit_code})"
138
+ output.puts "[specbandit] Batch ##{batch_num} FAILED (exit code: #{result.exit_code})" if verbose
140
139
  failed = true
141
- else
140
+ elsif verbose
142
141
  output.puts "[specbandit] Batch ##{batch_num} passed."
143
142
  end
144
143
  end
145
144
 
146
145
  if batch_num.zero?
147
- output.puts '[specbandit] Nothing to do (queue was empty).'
148
- else
146
+ output.puts '[specbandit] Nothing to do (queue was empty).' if verbose
147
+ elsif verbose
149
148
  output.puts "[specbandit] Finished #{batch_num} batches. #{failed ? 'SOME FAILED' : 'All passed.'}"
150
149
  end
151
150
 
@@ -310,92 +309,5 @@ module Specbandit
310
309
  parts << "#{@accumulated_summary[:pending_count]} pending" if @accumulated_summary[:pending_count] > 0
311
310
  parts.join(', ')
312
311
  end
313
-
314
- # Write a markdown summary to $GITHUB_STEP_SUMMARY for GitHub Actions.
315
- def write_github_step_summary
316
- path = ENV['GITHUB_STEP_SUMMARY']
317
- return unless path
318
-
319
- md = StringIO.new
320
-
321
- if has_rspec_results?
322
- write_rspec_github_summary(md)
323
- else
324
- write_generic_github_summary(md)
325
- end
326
-
327
- File.open(path, 'a') { |f| f.write(md.string) }
328
- rescue StandardError
329
- # Never fail the build because of summary writing
330
- nil
331
- end
332
-
333
- def write_rspec_github_summary(md)
334
- md.puts '### Specbandit Results'
335
- md.puts ''
336
- md.puts '| Metric | Value |'
337
- md.puts '|--------|-------|'
338
- md.puts "| Batches | #{batch_durations.size} |"
339
- md.puts "| Examples | #{@accumulated_summary[:example_count]} |"
340
- md.puts "| Failures | #{@accumulated_summary[:failure_count]} |"
341
- md.puts "| Pending | #{@accumulated_summary[:pending_count]} |"
342
-
343
- md.puts format('| Batch time (min) | %.1fs |', batch_durations.min || 0)
344
- md.puts format('| Batch time (avg) | %.1fs |',
345
- batch_durations.empty? ? 0 : batch_durations.sum / batch_durations.size)
346
- md.puts format('| Batch time (max) | %.1fs |', batch_durations.max || 0)
347
- md.puts ''
348
-
349
- failed_examples = @accumulated_examples.select { |e| e['status'] == 'failed' }
350
- return unless failed_examples.any?
351
-
352
- md.puts "<details><summary>#{failed_examples.size} failed specs</summary>"
353
- md.puts ''
354
- md.puts '| Location | Description | Error |'
355
- md.puts '|----------|-------------|-------|'
356
- failed_examples.each do |ex|
357
- location = ex['file_path'] || 'unknown'
358
- line = ex['line_number']
359
- location = "#{location}:#{line}" if line
360
- desc = (ex['full_description'] || ex['description'] || '').gsub('|', '\\|')
361
- message = (ex.dig('exception', 'message') || '').gsub('|', '\\|').gsub("\n", ' ')
362
- message = "#{message[0, 100]}..." if message.length > 100
363
- md.puts "| `#{location}` | #{desc} | #{message} |"
364
- end
365
- md.puts ''
366
- md.puts '</details>'
367
- end
368
-
369
- def write_generic_github_summary(md)
370
- total_files = @batch_results.sum { |r| r.files.size }
371
- failed_batch_results = @batch_results.select { |r| r.exit_code != 0 }
372
-
373
- md.puts '### Specbandit Results'
374
- md.puts ''
375
- md.puts '| Metric | Value |'
376
- md.puts '|--------|-------|'
377
- md.puts "| Batches | #{batch_durations.size} |"
378
- md.puts "| Files | #{total_files} |"
379
- md.puts "| Failed batches | #{failed_batch_results.size} |"
380
-
381
- md.puts format('| Batch time (min) | %.1fs |', batch_durations.min || 0)
382
- md.puts format('| Batch time (avg) | %.1fs |',
383
- batch_durations.empty? ? 0 : batch_durations.sum / batch_durations.size)
384
- md.puts format('| Batch time (max) | %.1fs |', batch_durations.max || 0)
385
- md.puts ''
386
-
387
- return unless failed_batch_results.any?
388
-
389
- md.puts "<details><summary>#{failed_batch_results.size} failed batches</summary>"
390
- md.puts ''
391
- md.puts '| Batch | Exit Code | Files |'
392
- md.puts '|-------|-----------|-------|'
393
- failed_batch_results.each do |r|
394
- files_str = r.files.map { |f| "`#{f}`" }.join(', ')
395
- md.puts "| ##{r.batch_num} | #{r.exit_code} | #{files_str} |"
396
- end
397
- md.puts ''
398
- md.puts '</details>'
399
- end
400
312
  end
401
313
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: specbandit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ferran Basora