rspec-tracer 0.6.0 → 0.8.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 +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +198 -227
- data/lib/rspec_tracer/cache.rb +1 -1
- data/lib/rspec_tracer/configuration.rb +15 -20
- data/lib/rspec_tracer/coverage_reporter.rb +7 -3
- data/lib/rspec_tracer/html_reporter/Rakefile +18 -0
- data/lib/rspec_tracer/remote_cache/Rakefile +38 -0
- data/lib/rspec_tracer/remote_cache/aws.rb +178 -0
- data/lib/rspec_tracer/remote_cache/cache.rb +36 -144
- data/lib/rspec_tracer/remote_cache/repo.rb +175 -0
- data/lib/rspec_tracer/remote_cache/validator.rb +52 -0
- data/lib/rspec_tracer/reporter.rb +9 -9
- data/lib/rspec_tracer/runner.rb +18 -8
- data/lib/rspec_tracer/time_formatter.rb +8 -5
- data/lib/rspec_tracer/version.rb +1 -1
- data/lib/rspec_tracer.rb +3 -3
- metadata +21 -17
- data/lib/rspec_tracer/remote_cache/git.rb +0 -113
@@ -0,0 +1,175 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecTracer
|
4
|
+
module RemoteCache
|
5
|
+
class Repo
|
6
|
+
class RepoError < StandardError; end
|
7
|
+
|
8
|
+
attr_reader :branch_name, :branch_ref, :branch_refs, :ancestry_refs, :cache_refs
|
9
|
+
|
10
|
+
def initialize(aws)
|
11
|
+
@aws = aws
|
12
|
+
@branch_name = ENV['GIT_BRANCH'].chomp
|
13
|
+
|
14
|
+
raise RepoError, 'GIT_BRANCH environment variable is not set' if @branch_name.nil?
|
15
|
+
|
16
|
+
fetch_head_ref
|
17
|
+
fetch_branch_ref
|
18
|
+
fetch_ancestry_refs
|
19
|
+
fetch_branch_refs
|
20
|
+
generate_cache_refs
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def fetch_head_ref
|
26
|
+
@head_ref = `git rev-parse HEAD`.chomp
|
27
|
+
|
28
|
+
raise RepoError, 'Could not find HEAD commit sha' unless $CHILD_STATUS.success?
|
29
|
+
end
|
30
|
+
|
31
|
+
def fetch_branch_ref
|
32
|
+
@merged_parents = []
|
33
|
+
@ignored_refs = []
|
34
|
+
|
35
|
+
unless merged?
|
36
|
+
@branch_ref = @head_ref
|
37
|
+
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
@ignored_refs << @head_ref
|
42
|
+
|
43
|
+
fetch_merged_parents
|
44
|
+
fetch_merged_branch_ref
|
45
|
+
end
|
46
|
+
|
47
|
+
def fetch_ancestry_refs
|
48
|
+
ref_list = `git rev-list --max-count=25 #{@branch_ref}`.chomp.split
|
49
|
+
|
50
|
+
raise RepoError, 'Could not find ancestry refs' unless $CHILD_STATUS.success?
|
51
|
+
|
52
|
+
ref_list = ref_list.to_set - @ignored_refs
|
53
|
+
@ancestry_refs = refs_committer_timestamp(ref_list.to_a)
|
54
|
+
|
55
|
+
return if @ancestry_refs.empty?
|
56
|
+
|
57
|
+
print_refs(@ancestry_refs, 'ancestry')
|
58
|
+
end
|
59
|
+
|
60
|
+
def fetch_branch_refs
|
61
|
+
unless @aws.branch_refs?(@branch_name)
|
62
|
+
puts "No branch refs for #{@branch_name} branch found in S3"
|
63
|
+
|
64
|
+
@branch_refs = {}
|
65
|
+
|
66
|
+
return
|
67
|
+
end
|
68
|
+
|
69
|
+
download_branch_refs
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_cache_refs
|
73
|
+
ref_list = @ancestry_refs.merge(@branch_refs)
|
74
|
+
|
75
|
+
if ref_list.empty?
|
76
|
+
@cache_refs = {}
|
77
|
+
|
78
|
+
return
|
79
|
+
end
|
80
|
+
|
81
|
+
@cache_refs = ref_list.sort_by { |_, timestamp| -timestamp }.to_h
|
82
|
+
|
83
|
+
print_refs(@cache_refs, 'cache')
|
84
|
+
end
|
85
|
+
|
86
|
+
def merged?
|
87
|
+
system('git', 'rev-parse', 'HEAD^2', out: File::NULL, err: File::NULL)
|
88
|
+
end
|
89
|
+
|
90
|
+
def fetch_merged_parents
|
91
|
+
first_parent = `git rev-parse HEAD^1`.chomp
|
92
|
+
@merged_parents << first_parent if $CHILD_STATUS.success?
|
93
|
+
|
94
|
+
second_parent = `git rev-parse HEAD^2`.chomp
|
95
|
+
@merged_parents << second_parent if $CHILD_STATUS.success?
|
96
|
+
|
97
|
+
raise RepoError, 'Could not find merged commit parents' if @merged_parents.length != 2
|
98
|
+
end
|
99
|
+
|
100
|
+
def fetch_merged_branch_ref
|
101
|
+
@origin_head_ref = `git rev-parse origin/HEAD`.chomp
|
102
|
+
@branch_ref = nil
|
103
|
+
|
104
|
+
if @merged_parents.first != @origin_head_ref
|
105
|
+
@branch_ref = @head_ref
|
106
|
+
@ignored_refs = []
|
107
|
+
|
108
|
+
return
|
109
|
+
end
|
110
|
+
|
111
|
+
@branch_ref = @merged_parents.last
|
112
|
+
@ignored_refs = @ignored_refs.to_set | `git rev-list #{@branch_ref}..origin/HEAD`.chomp.split
|
113
|
+
|
114
|
+
raise RepoError, 'Could not find ignored refs' unless $CHILD_STATUS.success?
|
115
|
+
end
|
116
|
+
|
117
|
+
def refs_committer_timestamp(ref_list)
|
118
|
+
return {} if ref_list.empty?
|
119
|
+
|
120
|
+
command = <<-COMMAND.strip.gsub(/\s+/, ' ')
|
121
|
+
git show
|
122
|
+
--no-patch
|
123
|
+
--format="%H %ct"
|
124
|
+
#{ref_list.join(' ')}
|
125
|
+
COMMAND
|
126
|
+
|
127
|
+
ref_list = `#{command}`.chomp
|
128
|
+
|
129
|
+
raise RepoError, 'Could not find ancestry refs' unless $CHILD_STATUS.success?
|
130
|
+
|
131
|
+
ref_list.split("\n").map(&:split).to_h.transform_values(&:to_i)
|
132
|
+
end
|
133
|
+
|
134
|
+
def download_branch_refs
|
135
|
+
file_name = File.join(RSpecTracer.cache_path, 'branch_refs.json')
|
136
|
+
|
137
|
+
if @aws.download_branch_refs(branch_name, file_name)
|
138
|
+
@branch_refs = JSON.parse(File.read(file_name)).transform_values(&:to_i)
|
139
|
+
|
140
|
+
return if @branch_refs.empty?
|
141
|
+
|
142
|
+
filter_branch_refs
|
143
|
+
print_refs(@branch_refs, 'branch')
|
144
|
+
else
|
145
|
+
@branch_refs = {}
|
146
|
+
|
147
|
+
File.rm_f(file_name)
|
148
|
+
|
149
|
+
puts "Failed to fetch branch refs for #{@branch_name} branch"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def filter_branch_refs
|
154
|
+
if @ancestry_refs.empty?
|
155
|
+
@branch_refs = @branch_refs.sort_by { |_, timestamp| -timestamp }.first(25).to_h
|
156
|
+
|
157
|
+
return
|
158
|
+
end
|
159
|
+
|
160
|
+
oldest_ancestry_time = @ancestry_refs.values.min
|
161
|
+
|
162
|
+
@branch_refs = @branch_refs
|
163
|
+
.select { |_, timestamp| timestamp >= oldest_ancestry_time }
|
164
|
+
.sort_by { |_, timestamp| -timestamp }
|
165
|
+
.first(25)
|
166
|
+
.to_h
|
167
|
+
end
|
168
|
+
|
169
|
+
def print_refs(refs, type)
|
170
|
+
puts "Fetched the following #{type} refs for #{@branch_name} branch:"
|
171
|
+
puts refs.map { |ref, timestamp| " * #{ref} (commit timestamp: #{timestamp})" }.join("\n")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpecTracer
|
4
|
+
module RemoteCache
|
5
|
+
class Validator
|
6
|
+
CACHE_FILES_PER_TEST_SUITE = 8
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@test_suite_id = ENV['TEST_SUITE_ID']
|
10
|
+
@test_suites = ENV['TEST_SUITES']
|
11
|
+
|
12
|
+
if @test_suite_id.nil? ^ @test_suites.nil?
|
13
|
+
raise(
|
14
|
+
ValidationError,
|
15
|
+
'Both the enviornment variables TEST_SUITE_ID and TEST_SUITES are not set'
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
setup
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid?(ref, cache_files)
|
23
|
+
last_run_regex = Regexp.new(format(@last_run_files_regex, ref: ref))
|
24
|
+
|
25
|
+
return false if cache_files.count { |file| file.match?(last_run_regex) } != @last_run_files_count
|
26
|
+
|
27
|
+
cache_regex = Regexp.new(format(@cached_files_regex, ref: ref))
|
28
|
+
|
29
|
+
cache_files.count { |file| file.match?(cache_regex) } == @cached_files_count
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def setup
|
35
|
+
if @test_suites.nil?
|
36
|
+
@last_run_files_count = 1
|
37
|
+
@last_run_files_regex = '/%<ref>s/last_run.json$'
|
38
|
+
@cached_files_count = CACHE_FILES_PER_TEST_SUITE
|
39
|
+
@cached_files_regex = '/%<ref>s/[0-9a-f]{32}/.+.json'
|
40
|
+
else
|
41
|
+
@test_suites = @test_suites.to_i
|
42
|
+
@test_suites_regex = (1..@test_suites).to_a.join('|')
|
43
|
+
|
44
|
+
@last_run_files_count = @test_suites
|
45
|
+
@last_run_files_regex = "/%<ref>s/(#{@test_suites_regex})/last_run.json$"
|
46
|
+
@cached_files_count = CACHE_FILES_PER_TEST_SUITE * @test_suites
|
47
|
+
@cached_files_regex = "/%<ref>s/(#{@test_suites_regex})/[0-9a-f]{32}/.+.json$"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -229,56 +229,56 @@ module RSpecTracer
|
|
229
229
|
def write_all_examples_report
|
230
230
|
file_name = File.join(@cache_dir, 'all_examples.json')
|
231
231
|
|
232
|
-
File.write(file_name, JSON.
|
232
|
+
File.write(file_name, JSON.pretty_generate(@all_examples))
|
233
233
|
end
|
234
234
|
|
235
235
|
def write_flaky_examples_report
|
236
236
|
file_name = File.join(@cache_dir, 'flaky_examples.json')
|
237
237
|
|
238
|
-
File.write(file_name, JSON.
|
238
|
+
File.write(file_name, JSON.pretty_generate(@flaky_examples.to_a))
|
239
239
|
end
|
240
240
|
|
241
241
|
def write_failed_examples_report
|
242
242
|
file_name = File.join(@cache_dir, 'failed_examples.json')
|
243
243
|
|
244
|
-
File.write(file_name, JSON.
|
244
|
+
File.write(file_name, JSON.pretty_generate(@failed_examples.to_a))
|
245
245
|
end
|
246
246
|
|
247
247
|
def write_pending_examples_report
|
248
248
|
file_name = File.join(@cache_dir, 'pending_examples.json')
|
249
249
|
|
250
|
-
File.write(file_name, JSON.
|
250
|
+
File.write(file_name, JSON.pretty_generate(@pending_examples.to_a))
|
251
251
|
end
|
252
252
|
|
253
253
|
def write_all_files_report
|
254
254
|
file_name = File.join(@cache_dir, 'all_files.json')
|
255
255
|
|
256
|
-
File.write(file_name, JSON.
|
256
|
+
File.write(file_name, JSON.pretty_generate(@all_files))
|
257
257
|
end
|
258
258
|
|
259
259
|
def write_dependency_report
|
260
260
|
file_name = File.join(@cache_dir, 'dependency.json')
|
261
261
|
|
262
|
-
File.write(file_name, JSON.
|
262
|
+
File.write(file_name, JSON.pretty_generate(@dependency))
|
263
263
|
end
|
264
264
|
|
265
265
|
def write_reverse_dependency_report
|
266
266
|
file_name = File.join(@cache_dir, 'reverse_dependency.json')
|
267
267
|
|
268
|
-
File.write(file_name, JSON.
|
268
|
+
File.write(file_name, JSON.pretty_generate(@reverse_dependency))
|
269
269
|
end
|
270
270
|
|
271
271
|
def write_examples_coverage_report
|
272
272
|
file_name = File.join(@cache_dir, 'examples_coverage.json')
|
273
273
|
|
274
|
-
File.write(file_name, JSON.
|
274
|
+
File.write(file_name, JSON.pretty_generate(@examples_coverage))
|
275
275
|
end
|
276
276
|
|
277
277
|
def write_last_run_report
|
278
278
|
file_name = File.join(RSpecTracer.cache_path, 'last_run.json')
|
279
279
|
last_run_data = @last_run.merge(run_id: @run_id, timestamp: Time.now.utc)
|
280
280
|
|
281
|
-
File.write(file_name, JSON.
|
281
|
+
File.write(file_name, JSON.pretty_generate(last_run_data))
|
282
282
|
end
|
283
283
|
end
|
284
284
|
end
|
data/lib/rspec_tracer/runner.rb
CHANGED
@@ -90,16 +90,15 @@ module RSpecTracer
|
|
90
90
|
# rubocop:enable Metrics/AbcSize
|
91
91
|
|
92
92
|
def register_dependency(examples_coverage)
|
93
|
+
filtered_files = Set.new
|
94
|
+
|
93
95
|
examples_coverage.each_pair do |example_id, example_coverage|
|
94
96
|
register_example_files_dependency(example_id)
|
95
97
|
|
96
98
|
example_coverage.each_key do |file_path|
|
97
|
-
|
98
|
-
|
99
|
-
next if RSpecTracer.filters.any? { |filter| filter.match?(source_file) }
|
99
|
+
next if filtered_files.include?(file_path)
|
100
100
|
|
101
|
-
|
102
|
-
@reporter.register_dependency(example_id, source_file[:file_name])
|
101
|
+
filtered_files << file_path unless register_file_dependency(example_id, file_path)
|
103
102
|
end
|
104
103
|
end
|
105
104
|
|
@@ -140,7 +139,7 @@ module RSpecTracer
|
|
140
139
|
ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
141
140
|
elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
|
142
141
|
|
143
|
-
puts "RSpec tracer generated #{report_type.to_s.tr('_', ' ')} report (took #{elpased})"
|
142
|
+
puts "RSpec tracer generated #{report_type.to_s.tr('_', ' ')} report (took #{elpased})" if RSpecTracer.verbose?
|
144
143
|
end
|
145
144
|
|
146
145
|
@reporter.write_reports
|
@@ -162,7 +161,7 @@ module RSpecTracer
|
|
162
161
|
ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
163
162
|
elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
|
164
163
|
|
165
|
-
puts "RSpec tracer processed cache (took #{elpased})"
|
164
|
+
puts "RSpec tracer processed cache (took #{elpased})" if RSpecTracer.verbose?
|
166
165
|
end
|
167
166
|
|
168
167
|
def filter_by_example_status
|
@@ -260,6 +259,17 @@ module RSpecTracer
|
|
260
259
|
@reporter.register_dependency(example_id, file_name)
|
261
260
|
end
|
262
261
|
|
262
|
+
def register_file_dependency(example_id, file_path)
|
263
|
+
source_file = RSpecTracer::SourceFile.from_path(file_path)
|
264
|
+
|
265
|
+
return false if RSpecTracer.filters.any? { |filter| filter.match?(source_file) }
|
266
|
+
|
267
|
+
@reporter.register_source_file(source_file)
|
268
|
+
@reporter.register_dependency(example_id, source_file[:file_name])
|
269
|
+
|
270
|
+
true
|
271
|
+
end
|
272
|
+
|
263
273
|
def generate_examples_status_report
|
264
274
|
starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
265
275
|
|
@@ -270,7 +280,7 @@ module RSpecTracer
|
|
270
280
|
ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
271
281
|
elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
|
272
282
|
|
273
|
-
puts "RSpec tracer generated flaky, failed, and pending examples report (took #{elpased})"
|
283
|
+
puts "RSpec tracer generated flaky, failed, and pending examples report (took #{elpased})" if RSpecTracer.verbose?
|
274
284
|
end
|
275
285
|
|
276
286
|
def generate_all_files_report
|
@@ -21,11 +21,10 @@ module RSpecTracer
|
|
21
21
|
next unless seconds.positive?
|
22
22
|
|
23
23
|
seconds, remainder = seconds.divmod(count)
|
24
|
-
remainder = format_duration(remainder)
|
25
24
|
|
26
25
|
next if remainder.zero?
|
27
26
|
|
28
|
-
duration << pluralize(remainder, unit)
|
27
|
+
duration << pluralize(format_duration(remainder), unit)
|
29
28
|
end
|
30
29
|
|
31
30
|
formatted_duration.reverse.join(' ')
|
@@ -36,17 +35,21 @@ module RSpecTracer
|
|
36
35
|
|
37
36
|
precision = duration < 1 ? SECONDS_PRECISION : DEFAULT_PRECISION
|
38
37
|
|
39
|
-
format("%<duration>0.#{precision}f", duration: duration)
|
38
|
+
strip_trailing_zeroes(format("%<duration>0.#{precision}f", duration: duration))
|
39
|
+
end
|
40
|
+
|
41
|
+
def strip_trailing_zeroes(formatted_duration)
|
42
|
+
formatted_duration.sub(/(?:(\..*[^0])0+|\.0+)$/, '\1')
|
40
43
|
end
|
41
44
|
|
42
45
|
def pluralize(duration, unit)
|
43
|
-
if duration
|
46
|
+
if (duration.to_f - 1).abs < Float::EPSILON
|
44
47
|
"#{duration} #{unit}"
|
45
48
|
else
|
46
49
|
"#{duration} #{unit}s"
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
50
|
-
private_class_method :format_duration, :pluralize
|
53
|
+
private_class_method :format_duration, :strip_trailing_zeroes, :pluralize
|
51
54
|
end
|
52
55
|
end
|
data/lib/rspec_tracer/version.rb
CHANGED
data/lib/rspec_tracer.rb
CHANGED
@@ -201,7 +201,7 @@ module RSpecTracer
|
|
201
201
|
ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
202
202
|
elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
|
203
203
|
|
204
|
-
puts "RSpec tracer processed dependency (took #{elpased})"
|
204
|
+
puts "RSpec tracer processed dependency (took #{elpased})" if RSpecTracer.verbose?
|
205
205
|
end
|
206
206
|
|
207
207
|
def process_coverage
|
@@ -214,7 +214,7 @@ module RSpecTracer
|
|
214
214
|
ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
215
215
|
elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
|
216
216
|
|
217
|
-
puts "RSpec tracer processed coverage (took #{elpased})"
|
217
|
+
puts "RSpec tracer processed coverage (took #{elpased})" if RSpecTracer.verbose?
|
218
218
|
end
|
219
219
|
|
220
220
|
def run_simplecov_exit_task
|
@@ -250,7 +250,7 @@ module RSpecTracer
|
|
250
250
|
}
|
251
251
|
}
|
252
252
|
|
253
|
-
File.write(file_name, JSON.
|
253
|
+
File.write(file_name, JSON.pretty_generate(report))
|
254
254
|
end
|
255
255
|
|
256
256
|
def print_coverage_stats(file_name, elpased)
|
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-tracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abhimanyu Singh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docile
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 1.1.0
|
20
17
|
- - "~>"
|
21
18
|
- !ruby/object:Gem::Version
|
22
19
|
version: '1.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.1.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 1.1.0
|
30
27
|
- - "~>"
|
31
28
|
- !ruby/object:Gem::Version
|
32
29
|
version: '1.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rspec-core
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- - ">="
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: 3.6.0
|
40
37
|
- - "~>"
|
41
38
|
- !ruby/object:Gem::Version
|
42
39
|
version: '3.6'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 3.6.0
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: 3.6.0
|
50
47
|
- - "~>"
|
51
48
|
- !ruby/object:Gem::Version
|
52
49
|
version: '3.6'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 3.6.0
|
53
53
|
description: RSpec Tracer is a specs dependency analysis tool and a test skipper for
|
54
54
|
RSpec. It maintains a list of files for each test, enabling itself to skip tests
|
55
55
|
in the subsequent runs if none of the dependent files are changed.
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- lib/rspec_tracer/defaults.rb
|
70
70
|
- lib/rspec_tracer/example.rb
|
71
71
|
- lib/rspec_tracer/filter.rb
|
72
|
+
- lib/rspec_tracer/html_reporter/Rakefile
|
72
73
|
- lib/rspec_tracer/html_reporter/assets/javascripts/application.js
|
73
74
|
- lib/rspec_tracer/html_reporter/assets/javascripts/libraries/jquery.js
|
74
75
|
- lib/rspec_tracer/html_reporter/assets/javascripts/plugins/datatables.js
|
@@ -92,8 +93,11 @@ files:
|
|
92
93
|
- lib/rspec_tracer/html_reporter/views/files_dependency.erb
|
93
94
|
- lib/rspec_tracer/html_reporter/views/flaky_examples.erb
|
94
95
|
- lib/rspec_tracer/html_reporter/views/layout.erb
|
96
|
+
- lib/rspec_tracer/remote_cache/Rakefile
|
97
|
+
- lib/rspec_tracer/remote_cache/aws.rb
|
95
98
|
- lib/rspec_tracer/remote_cache/cache.rb
|
96
|
-
- lib/rspec_tracer/remote_cache/
|
99
|
+
- lib/rspec_tracer/remote_cache/repo.rb
|
100
|
+
- lib/rspec_tracer/remote_cache/validator.rb
|
97
101
|
- lib/rspec_tracer/reporter.rb
|
98
102
|
- lib/rspec_tracer/rspec_reporter.rb
|
99
103
|
- lib/rspec_tracer/rspec_runner.rb
|
@@ -107,7 +111,7 @@ licenses:
|
|
107
111
|
- MIT
|
108
112
|
metadata:
|
109
113
|
homepage_uri: https://github.com/avmnu-sng/rspec-tracer
|
110
|
-
source_code_uri: https://github.com/avmnu-sng/rspec-tracer/tree/v0.
|
114
|
+
source_code_uri: https://github.com/avmnu-sng/rspec-tracer/tree/v0.8.0
|
111
115
|
changelog_uri: https://github.com/avmnu-sng/rspec-tracer/blob/main/CHANGELOG.md
|
112
116
|
bug_tracker_uri: https://github.com/avmnu-sng/rspec-tracer/issues
|
113
117
|
post_install_message:
|
@@ -125,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
129
|
- !ruby/object:Gem::Version
|
126
130
|
version: '0'
|
127
131
|
requirements: []
|
128
|
-
rubygems_version: 3.
|
132
|
+
rubygems_version: 3.2.26
|
129
133
|
signing_key:
|
130
134
|
specification_version: 4
|
131
135
|
summary: RSpec Tracer is a specs dependency analysis tool and a test skipper for RSpec
|