coverband 6.1.2 → 6.1.4
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/.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)
|