coverband 6.1.2.rc.1 → 6.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -0
  3. data/.rubocop.yml +5 -0
  4. data/README.md +3 -16
  5. data/changes.md +20 -0
  6. data/coverband.gemspec +5 -4
  7. data/lib/coverband/adapters/base.rb +5 -22
  8. data/lib/coverband/adapters/file_store.rb +0 -4
  9. data/lib/coverband/adapters/hash_redis_store.rb +20 -106
  10. data/lib/coverband/adapters/memcached_store.rb +0 -4
  11. data/lib/coverband/adapters/null_store.rb +0 -4
  12. data/lib/coverband/adapters/redis_store.rb +9 -22
  13. data/lib/coverband/adapters/stdout_store.rb +0 -4
  14. data/lib/coverband/collectors/abstract_tracker.rb +7 -2
  15. data/lib/coverband/collectors/coverage.rb +7 -18
  16. data/lib/coverband/collectors/delta.rb +1 -1
  17. data/lib/coverband/collectors/view_tracker.rb +3 -2
  18. data/lib/coverband/configuration.rb +6 -20
  19. data/lib/coverband/integrations/background.rb +2 -0
  20. data/lib/coverband/integrations/sidekiq_swarm.rb +8 -0
  21. data/lib/coverband/reporters/base.rb +2 -2
  22. data/lib/coverband/reporters/console_report.rb +13 -3
  23. data/lib/coverband/reporters/json_report.rb +36 -2
  24. data/lib/coverband/utils/dead_methods.rb +1 -1
  25. data/lib/coverband/utils/html_formatter.rb +18 -1
  26. data/lib/coverband/utils/results.rb +13 -0
  27. data/lib/coverband/utils/source_file.rb +4 -3
  28. data/lib/coverband/utils/tasks.rb +97 -15
  29. data/lib/coverband/version.rb +1 -1
  30. data/lib/coverband.rb +3 -1
  31. data/test/benchmarks/benchmark.rake +0 -1
  32. data/test/coverband/adapters/base_test.rb +1 -4
  33. data/test/coverband/adapters/hash_redis_store_test.rb +0 -51
  34. data/test/coverband/adapters/memecached_store_test.rb +26 -0
  35. data/test/coverband/adapters/redis_store_test.rb +0 -8
  36. data/test/coverband/collectors/coverage_test.rb +0 -42
  37. data/test/coverband/collectors/delta_test.rb +24 -26
  38. data/test/coverband/collectors/route_tracker_test.rb +1 -1
  39. data/test/coverband/collectors/view_tracker_test.rb +15 -2
  40. data/test/coverband/configuration_test.rb +3 -21
  41. data/test/coverband/integrations/resque_worker_test.rb +3 -1
  42. data/test/coverband/reporters/base_test.rb +0 -1
  43. data/test/coverband/reporters/json_test.rb +11 -0
  44. data/test/coverband/reporters/web_test.rb +52 -54
  45. data/test/rails5_dummy/config/coverband.rb +0 -1
  46. data/test/rails5_dummy/config/coverband_missing_redis.rb +0 -1
  47. data/test/test_helper.rb +10 -3
  48. data/views/source_file.erb +1 -1
  49. metadata +37 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5432cf1cd61639c5d7cbf9e2821dd17ce3db882ef44694302b11b0c3f899a23d
4
- data.tar.gz: abfd4a6cd427e46656e7d8bd33e7e97a26617e19d7868c03a10e8612b7a41ff3
3
+ metadata.gz: 6190be3d23adde604c28f1450cc2b89591fc3ef96047595e449a13ed5d7faf90
4
+ data.tar.gz: bd7d353847111e14bdb4ef0970bfea22e1feefc268bbb3349b1447918022fd28
5
5
  SHA512:
6
- metadata.gz: 8c85138cc11053800b739780e69ea459473683f114b76319d3334ddbf6732287458948817e6f650a1dece4be57022f5b30385b24422c6de8d9bbb45077029de2
7
- data.tar.gz: d9f8829248d15dd0159824c45eab9ffc3c286f2e357ef76665305db2dfca434c6f6c9184808dd9b8d421fd98c4ada3c6ee3ac5a1afba69d9f10f46608b42d61e
6
+ metadata.gz: ad51883929ced53534259cab4192f7b6aadf141e64219daf6bf0387b9e76b2530fd4ab04fb6739344723f659ba3eb7d51e21da683f529d51907bedf09720f2ca
7
+ data.tar.gz: 152e98163c8c6083b3902318c1485cc3c3d88201332b032ba13a8039da96a751f06efa6a53e90a0733feea3c7e27e0159aa576c259525856ef089420af841623
@@ -35,3 +35,4 @@ jobs:
35
35
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
36
36
  - run: bundle exec standardrb
37
37
  - run: bundle exec rake
38
+ - run: "RUBYOPT='--enable=frozen-string-literal --debug=frozen-string-literal' bundle exec rake"
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ require: standard
2
+
3
+ inherit_gem:
4
+ standard:
5
+ - config/ruby-2.7.yml
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#note-on-load-order
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-rails', require: 'dotenv/load'
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 = false`
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,14 +307,6 @@ 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
- ### Coverage Data Migration
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`
320
-
321
- - We will be working to support migrations going forward, when possible
322
-
323
310
  ### Adding Rake Tasks outside of Rails
324
311
 
325
312
  Rails apps should automatically include the tasks via the Railtie.
data/changes.md CHANGED
@@ -1,3 +1,23 @@
1
+ ### Coverband 6.1.3
2
+
3
+ * memory optimizations thx @fatkodima
4
+ * drop support for Ruby less than 2.7 thx @fatkodima
5
+ * improved 0 missed styles thx @fatkodima
6
+ * improved sidekiq swarm support thx @fatkodima
7
+ * default include memcached adapter thx @colemanja91
8
+ * improved long filename web admin views thx @fatkodima
9
+ * reduce logging noise thx @jamiecobbett
10
+ * improved readme thx @hotoolong
11
+ * fix for ignoring views @thijsnado
12
+ * improved documentation @jjb
13
+ * add back static output summary @bessey
14
+
15
+ other cleanup, small fixes, and updated mostly basic maintence, by me.
16
+
17
+ ### Coverband 6.1.2
18
+
19
+ * Fix for paging that would pull empty pages after getting all the data.
20
+
1
21
  ### Coverband 6.1.1
2
22
 
3
23
  * Performance fix making paged report loading 10X faster
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", "= 5.18.1"
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", "~> 1.7.0"
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", "= 1.34.0"
49
+ spec.add_development_dependency "standard", ">= 1.35.1"
50
50
  # breaking changes in various rubocop versions
51
- spec.add_development_dependency "rubocop", "= 1.60.0"
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
- if type == Coverband::RUNTIME_TYPE && Coverband.configuration.simulate_oneshot_lines_coverage
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 only be 2 cases get our dup / not dups aligned
128
+ # TODO: This should have cases reduced
146
129
  def array_add(latest, original)
147
- if Coverband.configuration.use_oneshot_lines_coverage
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
@@ -48,10 +48,6 @@ module Coverband
48
48
  File.size?(path).to_i
49
49
  end
50
50
 
51
- def migrate!
52
- raise NotImplementedError, "FileStore doesn't support migrations"
53
- end
54
-
55
51
  def coverage(_local_type = nil, opts = {})
56
52
  if merge_mode
57
53
  data = {}
@@ -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, :get_coverage_cache
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
- cached_results = @get_coverage_cache.fetch(local_type || type) do |sleep_time|
180
- files_set = if opts[:page]
181
- raise "call coverage_for_types with paging"
182
- elsif opts[:filename]
183
- type_key_prefix = key_prefix(local_type)
184
- # NOTE: a better way to extract filename from key would be better
185
- files_set(local_type).select do |cache_key|
186
- cache_key.sub(type_key_prefix, "").match(short_name(opts[:filename]))
187
- end || {}
188
- else
189
- files_set(local_type)
190
- end
191
- # below uses batches with a sleep in between to avoid overloading redis
192
- files_set.each_slice(page_size).flat_map do |key_batch|
193
- sleep sleep_time
194
- @redis.pipelined do |pipeline|
195
- key_batch.each do |key|
196
- pipeline.hgetall(key)
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
- cached_results.each_with_object({}) do |data_from_redis, hash|
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
@@ -36,10 +36,6 @@ module Coverband
36
36
  @memcached.read(base_key) ? @memcached.read(base_key).bytesize : "N/A"
37
37
  end
38
38
 
39
- def migrate!
40
- raise NotImplementedError, "MemcachedStore doesn't support migrations"
41
- end
42
-
43
39
  def type=(type)
44
40
  super
45
41
  reset_base_key
@@ -22,10 +22,6 @@ module Coverband
22
22
  0
23
23
  end
24
24
 
25
- def migrate!
26
- raise NotImplementedError, "NullStore doesn't support migrations"
27
- end
28
-
29
25
  def coverage(_local_type = nil, opts = {})
30
26
  {}
31
27
  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
@@ -21,10 +21,6 @@ module Coverband
21
21
  0
22
22
  end
23
23
 
24
- def migrate!
25
- raise NotImplementedError, "StdoutStore doesn't support migrations"
26
- end
27
-
28
24
  def coverage(_local_type = nil, opts = {})
29
25
  {}
30
26
  end
@@ -127,7 +127,8 @@ module Coverband
127
127
  end
128
128
 
129
129
  def track_key?(key, options = {})
130
- @ignore_patterns.none? { |pattern| key.to_s.include?(pattern) }
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 ||= self.class.name.split("::").last
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
- else
102
- if ::Coverage.respond_to?(:state)
103
- if ::Coverage.state == :idle
104
- ::Coverage.start(oneshot_lines: Coverband.configuration.use_oneshot_lines_coverage)
105
- elsif ::Coverage.state == :suspended
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 unless Coverband.configuration.simulate_oneshot_lines_coverage
35
+ @@previous_coverage = current_coverage
36
36
  new_results
37
37
  end
38
38
  end
@@ -84,7 +84,8 @@ module Coverband
84
84
  recently_used_views = used_keys.keys
85
85
  unused_views = all_keys - recently_used_views
86
86
  # since layouts don't include format we count them used if they match with ANY formats
87
- unused_views.reject { |view| view.match(/\/layouts\//) && recently_used_views.any? { |used_view| view.include?(used_view) } }
87
+ unused_views.reject { |view| view.include?("/layouts/") && recently_used_views.any? { |used_view| view.include?(used_view) } }
88
+ unused_views.reject { |view| @ignore_patterns.any? { |pattern| view.match?(pattern) } }
88
89
  end
89
90
 
90
91
  def clear_key!(filename)
@@ -99,7 +100,7 @@ module Coverband
99
100
 
100
101
  def track_file?(file, options = {})
101
102
  (file.start_with?(@project_directory) || options[:layout]) &&
102
- @ignore_patterns.none? { |pattern| file.include?(pattern) }
103
+ @ignore_patterns.none? { |pattern| file.match?(pattern) }
103
104
  end
104
105
 
105
106
  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, :use_oneshot_lines_coverage
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",
@@ -62,7 +61,7 @@ module Coverband
62
61
  def reset
63
62
  @root = Dir.pwd
64
63
  @root_paths = []
65
- @ignore = IGNORE_DEFAULTS.dup
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 = ENV["SIMULATE_ONESHOT"] || false
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 = (@ignore + ignored_array).uniq
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)
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ Sidekiq.configure_server do |config|
4
+ config.on(:fork) do
5
+ Coverband.start
6
+ Coverband.runtime_coverage!
7
+ end
8
+ end
@@ -37,7 +37,7 @@ module Coverband
37
37
 
38
38
  # apply coverband filters
39
39
  report_files.each_pair do |file, data|
40
- next if Coverband.configuration.ignore.any? { |i| file.match(i) }
40
+ next if Coverband.configuration.ignore.any? { |i| file.match?(i) }
41
41
 
42
42
  filtered_report_files[report_name][file] = data
43
43
  end
@@ -93,7 +93,7 @@ module Coverband
93
93
  scov_style_report = {}
94
94
  store.get_coverage_report(options).each_pair do |name, data|
95
95
  data.each_pair do |key, line_data|
96
- next if Coverband.configuration.ignore.any? { |i| key.match(i) }
96
+ next if Coverband.configuration.ignore.any? { |i| key.match?(i) }
97
97
  next unless line_data
98
98
 
99
99
  scov_style_report[name] = {} unless scov_style_report.key?(name)