coverband 6.1.2 → 6.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -0
- data/.rubocop.yml +5 -0
- data/README.md +6 -14
- data/changes.md +21 -0
- data/coverband.gemspec +5 -4
- data/lib/coverband/adapters/base.rb +5 -22
- data/lib/coverband/adapters/file_store.rb +0 -4
- data/lib/coverband/adapters/hash_redis_store.rb +20 -106
- data/lib/coverband/adapters/memcached_store.rb +0 -4
- data/lib/coverband/adapters/null_store.rb +0 -4
- data/lib/coverband/adapters/redis_store.rb +9 -22
- data/lib/coverband/adapters/stdout_store.rb +0 -4
- data/lib/coverband/collectors/abstract_tracker.rb +7 -2
- data/lib/coverband/collectors/coverage.rb +7 -18
- data/lib/coverband/collectors/delta.rb +1 -1
- data/lib/coverband/collectors/view_tracker.rb +6 -2
- data/lib/coverband/configuration.rb +7 -21
- data/lib/coverband/integrations/background.rb +2 -0
- data/lib/coverband/integrations/sidekiq_swarm.rb +8 -0
- data/lib/coverband/reporters/base.rb +2 -2
- data/lib/coverband/reporters/console_report.rb +13 -3
- data/lib/coverband/reporters/json_report.rb +36 -2
- data/lib/coverband/utils/dead_methods.rb +1 -1
- data/lib/coverband/utils/html_formatter.rb +18 -1
- data/lib/coverband/utils/results.rb +13 -0
- data/lib/coverband/utils/source_file.rb +4 -3
- data/lib/coverband/utils/tasks.rb +97 -15
- data/lib/coverband/version.rb +1 -1
- data/lib/coverband.rb +4 -2
- data/test/benchmarks/benchmark.rake +0 -1
- data/test/coverband/adapters/base_test.rb +1 -4
- data/test/coverband/adapters/hash_redis_store_test.rb +0 -51
- data/test/coverband/adapters/memecached_store_test.rb +26 -0
- data/test/coverband/adapters/redis_store_test.rb +0 -8
- data/test/coverband/collectors/coverage_test.rb +0 -42
- data/test/coverband/collectors/delta_test.rb +24 -26
- data/test/coverband/collectors/route_tracker_test.rb +1 -1
- data/test/coverband/collectors/view_tracker_test.rb +17 -4
- data/test/coverband/configuration_test.rb +6 -23
- data/test/coverband/integrations/resque_worker_test.rb +3 -1
- data/test/coverband/reporters/base_test.rb +0 -1
- data/test/coverband/reporters/json_test.rb +11 -0
- data/test/coverband/reporters/web_test.rb +52 -54
- data/test/rails5_dummy/config/coverband.rb +0 -1
- data/test/rails5_dummy/config/coverband_missing_redis.rb +0 -1
- data/test/test_helper.rb +10 -3
- data/views/source_file.erb +1 -1
- metadata +35 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3ffdf0c9a4cefbcbc728967f36ed20a90755074864a2fe858859b739e6912bb
|
4
|
+
data.tar.gz: e853e687820d45bbf414f51efd3a51f996b05f5eff0dcecac95351b076b3300d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f2f69c9de574808771f002af9fc4903fed8ec9af0d52288457759ff21b1c8a3c0e42111a6ea59c8830893fc57acf05e300f8520903dda920a894419710ad386
|
7
|
+
data.tar.gz: 20073041f076062cefeeeb8bcec74d703086d70c86c6f7b0b2511474f5c0cd2b9cb61510245cca49104dff53a8979249a2b4dae2bfad85b09682c9dd56ce5628
|
data/.github/workflows/main.yml
CHANGED
data/.rubocop.yml
ADDED
data/README.md
CHANGED
@@ -204,10 +204,10 @@ end
|
|
204
204
|
|
205
205
|
Do you use figaro, mc-settings, dotenv or something else to inject environment variables into your app? If so ensure you have that done BEFORE Coverband is required.
|
206
206
|
|
207
|
-
For example if you use dotenv, you need to do this, see https://github.com/bkeepers/dotenv#
|
207
|
+
For example if you use dotenv, you need to do this, see https://github.com/bkeepers/dotenv#load-order
|
208
208
|
|
209
209
|
```
|
210
|
-
gem 'dotenv
|
210
|
+
gem 'dotenv', require: 'dotenv/load'
|
211
211
|
gem 'coverband'
|
212
212
|
gem 'other-gem-that-requires-env-variables'
|
213
213
|
```
|
@@ -244,7 +244,7 @@ Coverband provides a view of all of its current settings. Sometimes you might wa
|
|
244
244
|
such as when sharing coverband data with a large number of developers of varying trust levels.
|
245
245
|
You can disable the settings view like so:
|
246
246
|
|
247
|
-
`config.hide_settings =
|
247
|
+
`config.hide_settings = true`
|
248
248
|
|
249
249
|
### Fixing Coverage Only Shows Loading Hits
|
250
250
|
|
@@ -299,11 +299,6 @@ Coverband on very high volume sites with many server processes reporting can hav
|
|
299
299
|
|
300
300
|
See more discussion [here](https://github.com/danmayer/coverband/issues/384).
|
301
301
|
|
302
|
-
Please note that with the Redis Hash Store, everytime you load the full report, Coverband will execute `HGETALL` queries in your Redis server twice for every file in the project (once for runtime coverage and once for eager loading coverage). This shouldn't have a big impact in small to medium projects, but can be quite a hassle if your project has a few thousand files.
|
303
|
-
To help reduce the extra redis load when getting the coverage report, you can enable `get_coverage_cache` (but note that when doing that, you will always get a previous version of the report, while a cache is re-populated with a newer version).
|
304
|
-
|
305
|
-
- Use Hash Redis Store with _get coverage cache_: `config.store = Coverband::Adapters::HashRedisStore.new(redis, get_coverage_cache: true)`
|
306
|
-
|
307
302
|
### Clear Coverage
|
308
303
|
|
309
304
|
Now that Coverband uses MD5 hashes there should be no reason to manually clear coverage unless one is testing, changing versions, or possibly debugging Coverband itself.
|
@@ -312,13 +307,10 @@ Now that Coverband uses MD5 hashes there should be no reason to manually clear c
|
|
312
307
|
|
313
308
|
This can also be done through the web if `config.web_enable_clear` is enabled.
|
314
309
|
|
315
|
-
|
316
|
-
|
317
|
-
Between the release of 4.0 and 4.1 our data format changed. This resets all your coverage data. If you want to restore your previous coverage data, feel free to migrate.
|
318
|
-
|
319
|
-
`rake coverband:migrate`
|
310
|
+
**NOTE**: The previous task does not clear the trackers data (views, routes, translations, etc).
|
311
|
+
To clear trackers data, run
|
320
312
|
|
321
|
-
|
313
|
+
`rake coverband:clear_tracker`
|
322
314
|
|
323
315
|
### Adding Rake Tasks outside of Rails
|
324
316
|
|
data/changes.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
### Coverband 6.1.4
|
2
|
+
|
3
|
+
* fix on ignoring to many view files thx @fatkodima
|
4
|
+
* improve docs on clear
|
5
|
+
|
6
|
+
### Coverband 6.1.3
|
7
|
+
|
8
|
+
* memory optimizations thx @fatkodima
|
9
|
+
* drop support for Ruby less than 2.7 thx @fatkodima
|
10
|
+
* improved 0 missed styles thx @fatkodima
|
11
|
+
* improved sidekiq swarm support thx @fatkodima
|
12
|
+
* default include memcached adapter thx @colemanja91
|
13
|
+
* improved long filename web admin views thx @fatkodima
|
14
|
+
* reduce logging noise thx @jamiecobbett
|
15
|
+
* improved readme thx @hotoolong
|
16
|
+
* fix for ignoring views @thijsnado
|
17
|
+
* improved documentation @jjb
|
18
|
+
* add back static output summary @bessey
|
19
|
+
|
20
|
+
other cleanup, small fixes, and updated mostly basic maintence, by me.
|
21
|
+
|
1
22
|
### Coverband 6.1.2
|
2
23
|
|
3
24
|
* Fix for paging that would pull empty pages after getting all the data.
|
data/coverband.gemspec
CHANGED
@@ -38,22 +38,23 @@ Gem::Specification.new do |spec|
|
|
38
38
|
# note: we are also adding 'spy' as mocha doesn't want us to spy on redis calls...
|
39
39
|
spec.add_development_dependency "spy"
|
40
40
|
# ^^^ probably need a large test cleanup refactor
|
41
|
-
spec.add_development_dependency "minitest"
|
41
|
+
spec.add_development_dependency "minitest"
|
42
42
|
spec.add_development_dependency "minitest-fork_executor"
|
43
43
|
spec.add_development_dependency "minitest-stub-const"
|
44
|
-
spec.add_development_dependency "mocha"
|
44
|
+
spec.add_development_dependency "mocha"
|
45
45
|
spec.add_development_dependency "rack"
|
46
46
|
spec.add_development_dependency "rack-test"
|
47
47
|
spec.add_development_dependency "rake"
|
48
48
|
spec.add_development_dependency "resque"
|
49
|
-
spec.add_development_dependency "standard", "
|
49
|
+
spec.add_development_dependency "standard", ">= 1.35.1"
|
50
50
|
# breaking changes in various rubocop versions
|
51
|
-
spec.add_development_dependency "rubocop"
|
51
|
+
spec.add_development_dependency "rubocop"
|
52
52
|
|
53
53
|
spec.add_development_dependency "coveralls"
|
54
54
|
# minitest-profile is not compatible with Rails 7.1.0 setup... dropping it for now
|
55
55
|
# spec.add_development_dependency "minitest-profile"
|
56
56
|
spec.add_development_dependency "webmock"
|
57
|
+
spec.add_development_dependency "dalli" # Default memcached adapter
|
57
58
|
|
58
59
|
# TODO: Remove when other production adapters exist
|
59
60
|
# because the default configuration of redis store, we really do require
|
@@ -23,10 +23,6 @@ module Coverband
|
|
23
23
|
raise ABSTRACT_KEY
|
24
24
|
end
|
25
25
|
|
26
|
-
def migrate!
|
27
|
-
raise ABSTRACT_KEY
|
28
|
-
end
|
29
|
-
|
30
26
|
def size
|
31
27
|
raise ABSTRACT_KEY
|
32
28
|
end
|
@@ -69,21 +65,8 @@ module Coverband
|
|
69
65
|
|
70
66
|
def split_coverage(types, coverage_cache, options = {})
|
71
67
|
types.reduce({}) do |data, type|
|
72
|
-
|
73
|
-
data.update(type => coverage_cache[type] ||= simulated_runtime_coverage)
|
74
|
-
else
|
75
|
-
data.update(type => coverage_cache[type] ||= coverage(type, options))
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def simulated_runtime_coverage
|
81
|
-
runtime_data = coverage(Coverband::RUNTIME_TYPE)
|
82
|
-
eager_data = coverage(Coverband::EAGER_TYPE)
|
83
|
-
eager_data.values do |vals|
|
84
|
-
vals["data"].map! { |line_coverage| line_coverage ? (0 - line_coverage) : line_coverage }
|
68
|
+
data.update(type => coverage_cache[type] ||= coverage(type, options))
|
85
69
|
end
|
86
|
-
merge_reports(runtime_data, eager_data, skip_expansion: true)
|
87
70
|
end
|
88
71
|
|
89
72
|
def merged_coverage(types, coverage_cache)
|
@@ -142,12 +125,12 @@ module Coverband
|
|
142
125
|
}
|
143
126
|
end
|
144
127
|
|
145
|
-
# TODO: This should
|
128
|
+
# TODO: This should have cases reduced
|
146
129
|
def array_add(latest, original)
|
147
|
-
if
|
130
|
+
if latest.empty? && original.empty?
|
131
|
+
[]
|
132
|
+
elsif Coverband.configuration.use_oneshot_lines_coverage
|
148
133
|
latest.map!.with_index { |v, i| ((v + original[i] >= 1) ? 1 : 0) if v && original[i] }
|
149
|
-
elsif Coverband.configuration.simulate_oneshot_lines_coverage
|
150
|
-
latest.map.with_index { |v, i| ((v + original[i] >= 1) ? 1 : 0) if v && original[i] }
|
151
134
|
else
|
152
135
|
latest.map.with_index { |v, i| (v && original[i]) ? v + original[i] : nil }
|
153
136
|
end
|
@@ -5,82 +5,6 @@ require "securerandom"
|
|
5
5
|
module Coverband
|
6
6
|
module Adapters
|
7
7
|
class HashRedisStore < Base
|
8
|
-
class GetCoverageNullCacheStore
|
9
|
-
def self.clear!(*_local_types)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.fetch(_local_type)
|
13
|
-
yield(0)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class GetCoverageRedisCacheStore
|
18
|
-
LOCK_LIMIT = 60 * 30 # 30 minutes
|
19
|
-
|
20
|
-
def initialize(redis, key_prefix)
|
21
|
-
@redis = redis
|
22
|
-
@key_prefix = [key_prefix, "get-coverage"].join(".")
|
23
|
-
end
|
24
|
-
|
25
|
-
def fetch(local_type)
|
26
|
-
cached_result = get(local_type)
|
27
|
-
|
28
|
-
# if no cache available, block the call and populate the cache
|
29
|
-
# if cache is available, return it and start re-populating it (with a lock)
|
30
|
-
if cached_result.nil?
|
31
|
-
value = yield(0)
|
32
|
-
result = set(local_type, JSON.generate(value))
|
33
|
-
value
|
34
|
-
else
|
35
|
-
if lock!(local_type)
|
36
|
-
Thread.new do
|
37
|
-
result = yield(deferred_time)
|
38
|
-
set(local_type, JSON.generate(result))
|
39
|
-
ensure
|
40
|
-
unlock!(local_type)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
JSON.parse(cached_result)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def clear!(local_types = Coverband::TYPES)
|
48
|
-
Array(local_types).each do |local_type|
|
49
|
-
del(local_type)
|
50
|
-
unlock!(local_type)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
# sleep in between to avoid holding other redis commands..
|
57
|
-
# with a small random offset so runtime and eager types can be processed "at the same time"
|
58
|
-
def deferred_time
|
59
|
-
rand(2.0..3.0)
|
60
|
-
end
|
61
|
-
|
62
|
-
def del(local_type)
|
63
|
-
@redis.del("#{@key_prefix}.cache.#{local_type}")
|
64
|
-
end
|
65
|
-
|
66
|
-
def get(local_type)
|
67
|
-
@redis.get("#{@key_prefix}.cache.#{local_type}")
|
68
|
-
end
|
69
|
-
|
70
|
-
def set(local_type, value)
|
71
|
-
@redis.set("#{@key_prefix}.cache.#{local_type}", value)
|
72
|
-
end
|
73
|
-
|
74
|
-
# lock for at most 60 minutes
|
75
|
-
def lock!(local_type)
|
76
|
-
@redis.set("#{@key_prefix}.lock.#{local_type}", "1", nx: true, ex: LOCK_LIMIT)
|
77
|
-
end
|
78
|
-
|
79
|
-
def unlock!(local_type)
|
80
|
-
@redis.del("#{@key_prefix}.lock.#{local_type}")
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
8
|
FILE_KEY = "file"
|
85
9
|
FILE_LENGTH_KEY = "file_length"
|
86
10
|
META_DATA_KEYS = [DATA_KEY, FIRST_UPDATED_KEY, LAST_UPDATED_KEY, FILE_HASH].freeze
|
@@ -93,7 +17,7 @@ module Coverband
|
|
93
17
|
|
94
18
|
JSON_PAYLOAD_EXPIRATION = 5 * 60
|
95
19
|
|
96
|
-
attr_reader :redis_namespace
|
20
|
+
attr_reader :redis_namespace
|
97
21
|
|
98
22
|
def initialize(redis, opts = {})
|
99
23
|
super()
|
@@ -105,13 +29,6 @@ module Coverband
|
|
105
29
|
|
106
30
|
@ttl = opts[:ttl]
|
107
31
|
@relative_file_converter = opts[:relative_file_converter] || Utils::RelativeFileConverter
|
108
|
-
|
109
|
-
@get_coverage_cache = if opts[:get_coverage_cache]
|
110
|
-
key_prefix = [REDIS_STORAGE_FORMAT_VERSION, @redis_namespace].compact.join(".")
|
111
|
-
GetCoverageRedisCacheStore.new(redis, key_prefix)
|
112
|
-
else
|
113
|
-
GetCoverageNullCacheStore
|
114
|
-
end
|
115
32
|
end
|
116
33
|
|
117
34
|
def supported?
|
@@ -129,7 +46,6 @@ module Coverband
|
|
129
46
|
@redis.del(*file_keys) if file_keys.any?
|
130
47
|
@redis.del(files_key)
|
131
48
|
@redis.del(files_key(type))
|
132
|
-
@get_coverage_cache.clear!(type)
|
133
49
|
end
|
134
50
|
self.type = old_type
|
135
51
|
end
|
@@ -139,7 +55,6 @@ module Coverband
|
|
139
55
|
relative_path_file = @relative_file_converter.convert(file)
|
140
56
|
Coverband::TYPES.each do |type|
|
141
57
|
@redis.del(key(relative_path_file, type, file_hash: file_hash))
|
142
|
-
@get_coverage_cache.clear!(type)
|
143
58
|
end
|
144
59
|
@redis.srem(files_key, relative_path_file)
|
145
60
|
end
|
@@ -176,30 +91,29 @@ module Coverband
|
|
176
91
|
# When paging code should use coverage_for_types and pull eager and runtime together as matched pairs
|
177
92
|
def coverage(local_type = nil, opts = {})
|
178
93
|
page_size = opts[:page_size] || 250
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
end
|
94
|
+
files_set = if opts[:page]
|
95
|
+
raise "call coverage_for_types with paging"
|
96
|
+
elsif opts[:filename]
|
97
|
+
type_key_prefix = key_prefix(local_type)
|
98
|
+
# NOTE: a better way to extract filename from key would be better
|
99
|
+
files_set(local_type).select do |cache_key|
|
100
|
+
cache_key.sub(type_key_prefix, "").match(short_name(opts[:filename]))
|
101
|
+
end || {}
|
102
|
+
else
|
103
|
+
files_set(local_type)
|
104
|
+
end
|
105
|
+
|
106
|
+
# below uses batches with a sleep in between to avoid overloading redis
|
107
|
+
files_set = files_set.each_slice(page_size).flat_map do |key_batch|
|
108
|
+
sleep(0.01 * rand(1..10))
|
109
|
+
@redis.pipelined do |pipeline|
|
110
|
+
key_batch.each do |key|
|
111
|
+
pipeline.hgetall(key)
|
198
112
|
end
|
199
113
|
end
|
200
114
|
end
|
201
115
|
|
202
|
-
|
116
|
+
files_set.each_with_object({}) do |data_from_redis, hash|
|
203
117
|
add_coverage_for_file(data_from_redis, hash)
|
204
118
|
end
|
205
119
|
end
|
@@ -45,28 +45,6 @@ module Coverband
|
|
45
45
|
@redis.get(base_key) ? @redis.get(base_key).bytesize : "N/A"
|
46
46
|
end
|
47
47
|
|
48
|
-
###
|
49
|
-
# Current implementation moves from coverband3_1 to coverband_3_2
|
50
|
-
# In the future this can be made more general and support a more specific
|
51
|
-
# version format.
|
52
|
-
###
|
53
|
-
def migrate!
|
54
|
-
reset_base_key
|
55
|
-
@format_version = "coverband3_1"
|
56
|
-
previous_data = coverage
|
57
|
-
if previous_data.empty?
|
58
|
-
puts "no previous data to migrate found"
|
59
|
-
exit 0
|
60
|
-
end
|
61
|
-
relative_path_report = previous_data.each_with_object({}) { |(key, vals), fixed_report|
|
62
|
-
fixed_report[Utils::RelativeFileConverter.convert(key)] = vals
|
63
|
-
}
|
64
|
-
clear!
|
65
|
-
reset_base_key
|
66
|
-
@format_version = REDIS_STORAGE_FORMAT_VERSION
|
67
|
-
save_coverage(merge_reports(coverage, relative_path_report, skip_expansion: true))
|
68
|
-
end
|
69
|
-
|
70
48
|
def type=(type)
|
71
49
|
super
|
72
50
|
reset_base_key
|
@@ -94,6 +72,15 @@ module Coverband
|
|
94
72
|
@redis
|
95
73
|
end
|
96
74
|
|
75
|
+
def file_count
|
76
|
+
data = redis.get type_base_key(Coverband::RUNTIME_TYPE)
|
77
|
+
JSON.parse(data).keys.length
|
78
|
+
end
|
79
|
+
|
80
|
+
def cached_file_count
|
81
|
+
@cached_file_count ||= file_count
|
82
|
+
end
|
83
|
+
|
97
84
|
private
|
98
85
|
|
99
86
|
attr_reader :redis
|
@@ -127,7 +127,8 @@ module Coverband
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def track_key?(key, options = {})
|
130
|
-
|
130
|
+
key = key.to_s
|
131
|
+
@ignore_patterns.none? { |pattern| key.match?(pattern) }
|
131
132
|
end
|
132
133
|
|
133
134
|
private
|
@@ -157,7 +158,11 @@ module Coverband
|
|
157
158
|
end
|
158
159
|
|
159
160
|
def class_key
|
160
|
-
@class_key ||=
|
161
|
+
@class_key ||= if Coverband.configuration.redis_namespace
|
162
|
+
"#{Coverband.configuration.redis_namespace}_#{self.class.name.split("::").last}"
|
163
|
+
else
|
164
|
+
self.class.name.split("::").last
|
165
|
+
end
|
161
166
|
end
|
162
167
|
end
|
163
168
|
end
|
@@ -14,10 +14,6 @@ module Coverband
|
|
14
14
|
class Coverage
|
15
15
|
include Singleton
|
16
16
|
|
17
|
-
def self.ruby_version_greater_than_or_equal_to?(version)
|
18
|
-
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(version)
|
19
|
-
end
|
20
|
-
|
21
17
|
def reset_instance
|
22
18
|
@project_directory = File.expand_path(Coverband.configuration.root)
|
23
19
|
@ignore_patterns = Coverband.configuration.ignore
|
@@ -87,7 +83,6 @@ module Coverband
|
|
87
83
|
|
88
84
|
def initialize
|
89
85
|
@semaphore = Mutex.new
|
90
|
-
raise NotImplementedError, "Coverage needs Ruby > 2.3.0" if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.3.0")
|
91
86
|
|
92
87
|
require "coverage"
|
93
88
|
if RUBY_PLATFORM == "java"
|
@@ -98,20 +93,14 @@ module Coverband
|
|
98
93
|
if defined?(SimpleCov) && defined?(Rails) && defined?(Rails.env) && Rails.env.test?
|
99
94
|
puts "Coverband: detected SimpleCov in test Env, allowing it to start Coverage"
|
100
95
|
puts "Coverband: to ensure no error logs or missing Coverage call `SimpleCov.start` prior to requiring Coverband"
|
101
|
-
|
102
|
-
if ::Coverage.
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
::Coverage.resume
|
107
|
-
end
|
108
|
-
elsif Coverage.ruby_version_greater_than_or_equal_to?("2.6.0")
|
109
|
-
::Coverage.start(oneshot_lines: Coverband.configuration.use_oneshot_lines_coverage) unless ::Coverage.running?
|
110
|
-
elsif Coverage.ruby_version_greater_than_or_equal_to?("2.5.0")
|
111
|
-
::Coverage.start unless ::Coverage.running?
|
112
|
-
else
|
113
|
-
::Coverage.start
|
96
|
+
elsif ::Coverage.respond_to?(:state)
|
97
|
+
if ::Coverage.state == :idle
|
98
|
+
::Coverage.start(oneshot_lines: Coverband.configuration.use_oneshot_lines_coverage)
|
99
|
+
elsif ::Coverage.state == :suspended
|
100
|
+
::Coverage.resume
|
114
101
|
end
|
102
|
+
else
|
103
|
+
::Coverage.start(oneshot_lines: Coverband.configuration.use_oneshot_lines_coverage) unless ::Coverage.running?
|
115
104
|
end
|
116
105
|
reset_instance
|
117
106
|
end
|
@@ -32,7 +32,7 @@ module Coverband
|
|
32
32
|
transform_oneshot_lines_results(current_coverage)
|
33
33
|
else
|
34
34
|
new_results = generate
|
35
|
-
@@previous_coverage = current_coverage
|
35
|
+
@@previous_coverage = current_coverage
|
36
36
|
new_results
|
37
37
|
end
|
38
38
|
end
|
@@ -17,6 +17,7 @@ module Coverband
|
|
17
17
|
|
18
18
|
REPORT_ROUTE = "views_tracker"
|
19
19
|
TITLE = "Views"
|
20
|
+
VIEWS_PATTERNS = %w[.erb$ .haml$ .slim$]
|
20
21
|
|
21
22
|
def initialize(options = {})
|
22
23
|
@project_directory = File.expand_path(Coverband.configuration.root)
|
@@ -24,6 +25,8 @@ module Coverband
|
|
24
25
|
@roots = @roots.split(",") if @roots.is_a?(String)
|
25
26
|
|
26
27
|
super
|
28
|
+
|
29
|
+
@ignore_patterns -= VIEWS_PATTERNS.map { |ignore_str| Regexp.new(ignore_str) }
|
27
30
|
end
|
28
31
|
|
29
32
|
def railtie!
|
@@ -84,7 +87,8 @@ module Coverband
|
|
84
87
|
recently_used_views = used_keys.keys
|
85
88
|
unused_views = all_keys - recently_used_views
|
86
89
|
# since layouts don't include format we count them used if they match with ANY formats
|
87
|
-
unused_views.reject { |view| view.
|
90
|
+
unused_views = unused_views.reject { |view| view.include?("/layouts/") && recently_used_views.any? { |used_view| view.include?(used_view) } }
|
91
|
+
unused_views.reject { |view| @ignore_patterns.any? { |pattern| view.match?(pattern) } }
|
88
92
|
end
|
89
93
|
|
90
94
|
def clear_key!(filename)
|
@@ -99,7 +103,7 @@ module Coverband
|
|
99
103
|
|
100
104
|
def track_file?(file, options = {})
|
101
105
|
(file.start_with?(@project_directory) || options[:layout]) &&
|
102
|
-
@ignore_patterns.none? { |pattern| file.
|
106
|
+
@ignore_patterns.none? { |pattern| file.match?(pattern) }
|
103
107
|
end
|
104
108
|
|
105
109
|
def concrete_target
|
@@ -10,7 +10,7 @@ module Coverband
|
|
10
10
|
:reporter, :redis_namespace, :redis_ttl,
|
11
11
|
:background_reporting_enabled,
|
12
12
|
:test_env, :web_enable_clear, :gem_details, :web_debug, :report_on_exit,
|
13
|
-
:simulate_oneshot_lines_coverage,
|
13
|
+
:use_oneshot_lines_coverage, :simulate_oneshot_lines_coverage,
|
14
14
|
:view_tracker, :defer_eager_loading_data,
|
15
15
|
:track_routes, :track_redirect_routes, :route_tracker,
|
16
16
|
:track_translations, :translations_tracker,
|
@@ -22,7 +22,7 @@ module Coverband
|
|
22
22
|
:background_reporting_sleep_seconds, :reporting_wiggle,
|
23
23
|
:send_deferred_eager_loading_data, :paged_reporting
|
24
24
|
|
25
|
-
attr_reader :track_gems, :ignore
|
25
|
+
attr_reader :track_gems, :ignore
|
26
26
|
|
27
27
|
#####
|
28
28
|
# TODO: This is is brittle and not a great solution to avoid deploy time
|
@@ -33,7 +33,6 @@ module Coverband
|
|
33
33
|
IGNORE_TASKS = ["coverband:clear",
|
34
34
|
"coverband:coverage",
|
35
35
|
"coverband:coverage_server",
|
36
|
-
"coverband:migrate",
|
37
36
|
"assets:precompile",
|
38
37
|
"webpacker:compile",
|
39
38
|
"db:version",
|
@@ -49,7 +48,7 @@ module Coverband
|
|
49
48
|
# Heroku when building assets runs code from a dynamic directory
|
50
49
|
# /tmp was added to avoid coverage from /tmp/build directories during
|
51
50
|
# heroku asset compilation
|
52
|
-
IGNORE_DEFAULTS = %w[vendor/
|
51
|
+
IGNORE_DEFAULTS = %w[vendor/ /tmp internal:prelude db/schema.rb] + Collectors::ViewTracker::VIEWS_PATTERNS
|
53
52
|
|
54
53
|
# Add in missing files which were never loaded
|
55
54
|
# we need to know what all paths to check for unloaded files
|
@@ -62,7 +61,7 @@ module Coverband
|
|
62
61
|
def reset
|
63
62
|
@root = Dir.pwd
|
64
63
|
@root_paths = []
|
65
|
-
@ignore = IGNORE_DEFAULTS.
|
64
|
+
@ignore = IGNORE_DEFAULTS.map { |ignore_str| Regexp.new(ignore_str) }
|
66
65
|
@search_paths = TRACKED_DEFAULT_PATHS.dup
|
67
66
|
@verbose = false
|
68
67
|
@reporter = "scov"
|
@@ -84,7 +83,7 @@ module Coverband
|
|
84
83
|
@web_debug = false
|
85
84
|
@report_on_exit = true
|
86
85
|
@use_oneshot_lines_coverage = ENV["ONESHOT"] || false
|
87
|
-
@simulate_oneshot_lines_coverage =
|
86
|
+
@simulate_oneshot_lines_coverage = false # this is being deprecated
|
88
87
|
@current_root = nil
|
89
88
|
@all_root_paths = nil
|
90
89
|
@all_root_patterns = nil
|
@@ -223,8 +222,8 @@ module Coverband
|
|
223
222
|
# Don't allow the ignore to override things like gem tracking
|
224
223
|
###
|
225
224
|
def ignore=(ignored_array)
|
226
|
-
ignored_array.map { |ignore_str| Regexp.new(ignore_str) }
|
227
|
-
@ignore
|
225
|
+
ignored_array = ignored_array.map { |ignore_str| Regexp.new(ignore_str) }
|
226
|
+
@ignore |= ignored_array
|
228
227
|
rescue RegexpError
|
229
228
|
logger.error "an invalid regular expression was passed in, ensure string are valid regex patterns #{ignored_array.join(",")}"
|
230
229
|
end
|
@@ -253,19 +252,6 @@ module Coverband
|
|
253
252
|
end
|
254
253
|
end
|
255
254
|
|
256
|
-
def use_oneshot_lines_coverage=(value)
|
257
|
-
unless one_shot_coverage_implemented_in_ruby_version? || !value
|
258
|
-
raise(StandardError,
|
259
|
-
"One shot line coverage is only available in ruby >= 2.6")
|
260
|
-
end
|
261
|
-
|
262
|
-
@use_oneshot_lines_coverage = value
|
263
|
-
end
|
264
|
-
|
265
|
-
def one_shot_coverage_implemented_in_ruby_version?
|
266
|
-
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6.0")
|
267
|
-
end
|
268
|
-
|
269
255
|
def redis_url
|
270
256
|
@redis_url ||= ENV["COVERBAND_REDIS_URL"] || ENV["REDIS_URL"]
|
271
257
|
end
|
@@ -30,6 +30,8 @@ module Coverband
|
|
30
30
|
logger.debug("Coverband: Starting background reporting") if Coverband.configuration.verbose
|
31
31
|
sleep_seconds = Coverband.configuration.background_reporting_sleep_seconds.to_i
|
32
32
|
@thread = Thread.new {
|
33
|
+
Thread.current.name = "Coverband Background Reporter"
|
34
|
+
|
33
35
|
loop do
|
34
36
|
if Coverband.configuration.reporting_wiggle
|
35
37
|
sleep_seconds = Coverband.configuration.background_reporting_sleep_seconds.to_i + rand(Coverband.configuration.reporting_wiggle.to_i)
|