coverband 5.2.6.rc.1 → 5.2.6.rc.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/diagram.yml +2 -1
- data/.github/workflows/main.yml +2 -2
- data/README.md +4 -4
- data/changes.md +4 -0
- data/lib/coverband/at_exit.rb +2 -1
- data/lib/coverband/collectors/abstract_tracker.rb +164 -0
- data/lib/coverband/collectors/route_tracker.rb +35 -114
- data/lib/coverband/collectors/translation_tracker.rb +15 -138
- data/lib/coverband/collectors/view_tracker.rb +29 -96
- data/lib/coverband/collectors/view_tracker_service.rb +1 -1
- data/lib/coverband/configuration.rb +34 -1
- data/lib/coverband/integrations/background.rb +1 -3
- data/lib/coverband/reporters/web.rb +75 -116
- data/lib/coverband/utils/html_formatter.rb +4 -23
- data/lib/coverband/utils/railtie.rb +1 -45
- data/lib/coverband/version.rb +1 -1
- data/lib/coverband.rb +1 -0
- data/roadmap.md +23 -23
- data/test/coverband/collectors/route_tracker_test.rb +22 -22
- data/test/coverband/collectors/view_tracker_test.rb +29 -29
- data/test/coverband/configuration_test.rb +10 -0
- data/test/forked/rails_full_stack_views_test.rb +13 -13
- data/test/forked/rails_route_tracker_stack_test.rb +1 -1
- data/test/forked/rails_view_tracker_stack_test.rb +1 -1
- data/views/{translations_tracker.erb → abstract_tracker.erb} +7 -8
- data/views/nav.erb +4 -4
- metadata +4 -5
- data/views/route_tracker.erb +0 -49
- data/views/view_tracker.erb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '039bd98899c0794752cb3244029b3bce0d9d6ebda8ddf449423e94e44741acb5'
|
4
|
+
data.tar.gz: 5b19acc65170a2f2c6d66a750a7e958759e90caca808943426481828c26dedfa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51e2ef52b7bd14f677845d6d565872ab9a607990ff28e89ba020f5fe8f8a65d728400f241ea2d70647580f2387e2115f9d033e450704d821d9a1664be5457f76
|
7
|
+
data.tar.gz: 62dc029eb498529c31e81a297db3afb5a1d95a716d0802ed0b99128b8405f937b6d90c61eb3d0dc49df4f2faf9b9c2545ae5f54dbda9db2d04e3b6465001a75d
|
data/.github/workflows/main.yml
CHANGED
@@ -21,11 +21,11 @@ jobs:
|
|
21
21
|
# removing jruby again to flaky
|
22
22
|
# ruby: [2.3, 2.4, 2.5, 2.6, 2.7, "3.0", "3.1", jruby]
|
23
23
|
# need to add support for multiple gemfiles
|
24
|
-
ruby: ["2.7", "3.0", "3.1"]
|
24
|
+
ruby: ["2.7", "3.0", "3.1", "3.2"]
|
25
25
|
redis-version: [4, 5, 6]
|
26
26
|
runs-on: ${{ matrix.os }}-latest
|
27
27
|
steps:
|
28
|
-
- uses: actions/checkout@
|
28
|
+
- uses: actions/checkout@v3
|
29
29
|
- uses: supercharge/redis-github-action@1.2.0
|
30
30
|
- uses: ruby/setup-ruby@v1
|
31
31
|
with:
|
data/README.md
CHANGED
@@ -207,9 +207,9 @@ config.ignore += ['config/application.rb',
|
|
207
207
|
'config/boot.rb',
|
208
208
|
'config/puma.rb',
|
209
209
|
'config/schedule.rb',
|
210
|
-
'bin
|
211
|
-
'config/environments
|
212
|
-
'lib/tasks
|
210
|
+
'bin/.*',
|
211
|
+
'config/environments/.*',
|
212
|
+
'lib/tasks/.*']
|
213
213
|
```
|
214
214
|
|
215
215
|
**Ignoring Custom Gem Locations:** Note, if you have your gems in a custom location under your app folder you likely want to add them to `config.ignore`. For example, if you have your gems not in a default ignored location of `app/vendor` but have them in `app/gems` you would need to add `gems/*` to your ignore list.
|
@@ -437,7 +437,7 @@ What is the coverage data in Redis?
|
|
437
437
|
|
438
438
|
A diagram of the code.
|
439
439
|
|
440
|
-
![Visualization of this repo](
|
440
|
+
![Visualization of this repo](https://raw.githubusercontent.com/danmayer/coverband/diagram/diagram.svg)
|
441
441
|
|
442
442
|
## Logo
|
443
443
|
|
data/changes.md
CHANGED
data/lib/coverband/at_exit.rb
CHANGED
@@ -22,7 +22,8 @@ module Coverband
|
|
22
22
|
Coverband.report_coverage
|
23
23
|
# to ensure we track mailer views we now need to report views tracking
|
24
24
|
# at exit as well for rake tasks and background tasks that can trigger email
|
25
|
-
Coverband.configuration.view_tracker&.
|
25
|
+
Coverband.configuration.view_tracker&.save_report
|
26
|
+
Coverband.configuration.translations_tracker&.save_report
|
26
27
|
end
|
27
28
|
end
|
28
29
|
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
require "singleton"
|
5
|
+
|
6
|
+
module Coverband
|
7
|
+
module Collectors
|
8
|
+
###
|
9
|
+
# This abstract class makes it easy to track any used/unused with timestamp set of usage
|
10
|
+
###
|
11
|
+
class AbstractTracker
|
12
|
+
REPORT_ROUTE = "/"
|
13
|
+
TITLE = "abstract"
|
14
|
+
|
15
|
+
attr_accessor :target
|
16
|
+
attr_reader :logger, :store, :ignore_patterns
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
raise NotImplementedError, "#{self.class.name} requires a newer version of Rails" unless self.class.supported_version?
|
20
|
+
raise "Coverband: #{self.class.name} initialized before configuration!" if !Coverband.configured? && ENV["COVERBAND_TEST"] == "test"
|
21
|
+
|
22
|
+
@ignore_patterns = Coverband.configuration.ignore
|
23
|
+
@store = options.fetch(:store) { Coverband.configuration.store }
|
24
|
+
@logger = options.fetch(:logger) { Coverband.configuration.logger }
|
25
|
+
@target = options.fetch(:target) do
|
26
|
+
concrete_target
|
27
|
+
end
|
28
|
+
|
29
|
+
@one_time_timestamp = false
|
30
|
+
|
31
|
+
@logged_keys = Set.new
|
32
|
+
@keys_to_record = Set.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def logged_keys
|
36
|
+
@logged_keys.to_a
|
37
|
+
end
|
38
|
+
|
39
|
+
def keys_to_record
|
40
|
+
@keys_to_record.to_a
|
41
|
+
end
|
42
|
+
|
43
|
+
###
|
44
|
+
# This method is called on every translation usage
|
45
|
+
###
|
46
|
+
def track_key(key)
|
47
|
+
if key
|
48
|
+
if newly_seen_key?(key)
|
49
|
+
@logged_keys << key
|
50
|
+
@keys_to_record << key if track_key?(key)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def used_keys
|
56
|
+
redis_store.hgetall(tracker_key)
|
57
|
+
end
|
58
|
+
|
59
|
+
def all_keys
|
60
|
+
target.uniq
|
61
|
+
end
|
62
|
+
|
63
|
+
def unused_keys(used_keys = nil)
|
64
|
+
recently_used_keys = (used_keys || self.used_keys).keys
|
65
|
+
all_keys.reject { |k| recently_used_keys.include?(k.to_s) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def as_json
|
69
|
+
used_keys = self.used_keys
|
70
|
+
{
|
71
|
+
unused_keys: unused_keys(used_keys),
|
72
|
+
used_keys: used_keys
|
73
|
+
}.to_json
|
74
|
+
end
|
75
|
+
|
76
|
+
def tracking_since
|
77
|
+
if (tracking_time = redis_store.get(tracker_time_key))
|
78
|
+
Time.at(tracking_time.to_i).iso8601
|
79
|
+
else
|
80
|
+
"N/A"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def reset_recordings
|
85
|
+
redis_store.del(tracker_key)
|
86
|
+
redis_store.del(tracker_time_key)
|
87
|
+
end
|
88
|
+
|
89
|
+
def clear_key!(key)
|
90
|
+
return unless key
|
91
|
+
puts "#{tracker_key} key #{key}"
|
92
|
+
redis_store.hdel(tracker_key, key)
|
93
|
+
@logged_keys.delete(key)
|
94
|
+
end
|
95
|
+
|
96
|
+
def save_report
|
97
|
+
redis_store.set(tracker_time_key, Time.now.to_i) unless @one_time_timestamp || tracker_time_key_exists?
|
98
|
+
@one_time_timestamp = true
|
99
|
+
reported_time = Time.now.to_i
|
100
|
+
@keys_to_record.to_a.each do |key|
|
101
|
+
redis_store.hset(tracker_key, key.to_s, reported_time)
|
102
|
+
end
|
103
|
+
@keys_to_record.clear
|
104
|
+
rescue => e
|
105
|
+
# we don't want to raise errors if Coverband can't reach redis.
|
106
|
+
# This is a nice to have not a bring the system down
|
107
|
+
logger&.error "Coverband: #{self.class.name} failed to store, error #{e.class.name} info #{e.message}"
|
108
|
+
end
|
109
|
+
|
110
|
+
# This is the basic rails version supported, if there is something more unique over ride in subclass
|
111
|
+
def self.supported_version?
|
112
|
+
defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 5
|
113
|
+
end
|
114
|
+
|
115
|
+
def route
|
116
|
+
self.class::REPORT_ROUTE
|
117
|
+
end
|
118
|
+
|
119
|
+
def title
|
120
|
+
self.class::TITLE
|
121
|
+
end
|
122
|
+
|
123
|
+
protected
|
124
|
+
|
125
|
+
def newly_seen_key?(key)
|
126
|
+
!@logged_keys.include?(key)
|
127
|
+
end
|
128
|
+
|
129
|
+
def track_key?(key, options = {})
|
130
|
+
@ignore_patterns.none? { |pattern| key.to_s.include?(pattern) }
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def concrete_target
|
136
|
+
raise "subclass must implement"
|
137
|
+
end
|
138
|
+
|
139
|
+
def redis_store
|
140
|
+
store.raw_store
|
141
|
+
end
|
142
|
+
|
143
|
+
def tracker_time_key_exists?
|
144
|
+
if defined?(redis_store.exists?)
|
145
|
+
redis_store.exists?(tracker_time_key)
|
146
|
+
else
|
147
|
+
redis_store.exists(tracker_time_key)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def tracker_key
|
152
|
+
"#{class_key}_tracker"
|
153
|
+
end
|
154
|
+
|
155
|
+
def tracker_time_key
|
156
|
+
"#{class_key}_tracker_time"
|
157
|
+
end
|
158
|
+
|
159
|
+
def class_key
|
160
|
+
@class_key ||= self.class.name.split("::").last
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -8,51 +8,23 @@ module Coverband
|
|
8
8
|
###
|
9
9
|
# This class tracks route usage via ActiveSupport::Notifications
|
10
10
|
###
|
11
|
-
class RouteTracker
|
12
|
-
|
13
|
-
|
11
|
+
class RouteTracker < AbstractTracker
|
12
|
+
REPORT_ROUTE = "routes_tracker"
|
13
|
+
TITLE = "Routes"
|
14
14
|
|
15
15
|
def initialize(options = {})
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
@ignore_patterns = Coverband.configuration.ignore
|
20
|
-
@store = options.fetch(:store) { Coverband.configuration.store }
|
21
|
-
@logger = options.fetch(:logger) { Coverband.configuration.logger }
|
22
|
-
@target = options.fetch(:target) do
|
23
|
-
if defined?(Rails.application)
|
24
|
-
Rails.application.routes.routes.map do |route|
|
25
|
-
{
|
26
|
-
controller: route.defaults[:controller],
|
27
|
-
action: route.defaults[:action],
|
28
|
-
url_path: route.path.spec.to_s.gsub("(.:format)", ""),
|
29
|
-
verb: route.verb
|
30
|
-
}
|
31
|
-
end
|
32
|
-
else
|
33
|
-
[]
|
34
|
-
end
|
16
|
+
if Rails&.respond_to?(:version) && Gem::Version.new(Rails.version) >= Gem::Version.new("6.0.0") && Gem::Version.new(Rails.version) < Gem::Version.new("7.1.0")
|
17
|
+
require_relative "../utils/rails6_ext"
|
35
18
|
end
|
36
19
|
|
37
|
-
|
38
|
-
|
39
|
-
@logged_routes = Set.new
|
40
|
-
@routes_to_record = Set.new
|
41
|
-
end
|
42
|
-
|
43
|
-
def logged_routes
|
44
|
-
@logged_routes.to_a
|
45
|
-
end
|
46
|
-
|
47
|
-
def routes_to_record
|
48
|
-
@routes_to_record.to_a
|
20
|
+
super
|
49
21
|
end
|
50
22
|
|
51
23
|
###
|
52
24
|
# This method is called on every routing call, so we try to reduce method calls
|
53
25
|
# and ensure high performance
|
54
26
|
###
|
55
|
-
def
|
27
|
+
def track_key(payload)
|
56
28
|
route = if payload[:request]
|
57
29
|
{
|
58
30
|
controller: nil,
|
@@ -69,104 +41,53 @@ module Coverband
|
|
69
41
|
}
|
70
42
|
end
|
71
43
|
if route
|
72
|
-
if
|
73
|
-
@
|
74
|
-
@
|
44
|
+
if newly_seen_key?(route)
|
45
|
+
@logged_keys << route
|
46
|
+
@keys_to_record << route if track_key?(route)
|
75
47
|
end
|
76
48
|
end
|
77
49
|
end
|
78
50
|
|
79
|
-
def
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
def all_routes
|
84
|
-
target.uniq
|
51
|
+
def self.supported_version?
|
52
|
+
defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 6
|
85
53
|
end
|
86
54
|
|
87
|
-
def
|
88
|
-
recently_used_routes = (
|
55
|
+
def unused_keys(used_keys = nil)
|
56
|
+
recently_used_routes = (used_keys || self.used_keys).keys
|
89
57
|
# NOTE: we match with or without path to handle paths with named params like `/user/:user_id` to used routes filling with all the variable named paths
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
def as_json
|
94
|
-
used_routes = self.used_routes
|
95
|
-
{
|
96
|
-
unused_routes: unused_routes(used_routes),
|
97
|
-
used_routes: used_routes
|
98
|
-
}.to_json
|
58
|
+
all_keys.reject { |r| recently_used_routes.include?(r.to_s) || recently_used_routes.include?(r.merge(url_path: nil).to_s) }
|
99
59
|
end
|
100
60
|
|
101
|
-
def
|
102
|
-
|
103
|
-
|
104
|
-
else
|
105
|
-
"N/A"
|
61
|
+
def railtie!
|
62
|
+
ActiveSupport::Notifications.subscribe("start_processing.action_controller") do |name, start, finish, id, payload|
|
63
|
+
Coverband.configuration.route_tracker.track_key(payload)
|
106
64
|
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def reset_recordings
|
110
|
-
redis_store.del(tracker_key)
|
111
|
-
redis_store.del(tracker_time_key)
|
112
|
-
end
|
113
|
-
|
114
|
-
def clear_route!(route)
|
115
|
-
return unless route
|
116
65
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
@one_time_timestamp = true
|
124
|
-
reported_time = Time.now.to_i
|
125
|
-
@routes_to_record.to_a.each do |route|
|
126
|
-
redis_store.hset(tracker_key, route.to_s, reported_time)
|
66
|
+
# NOTE: This event was instrumented in Aug 10th 2022, but didn't make the 7.0.4 release and should be in the next release
|
67
|
+
# https://github.com/rails/rails/pull/43755
|
68
|
+
# Automatic tracking of redirects isn't avaible before Rails 7.1.0 (currently tested against the 7.1.0.alpha)
|
69
|
+
# We could consider back porting or patching a solution that works on previous Rails versions
|
70
|
+
ActiveSupport::Notifications.subscribe("redirect.action_dispatch") do |name, start, finish, id, payload|
|
71
|
+
Coverband.configuration.route_tracker.track_key(payload)
|
127
72
|
end
|
128
|
-
@routes_to_record.clear
|
129
|
-
rescue => e
|
130
|
-
# we don't want to raise errors if Coverband can't reach redis.
|
131
|
-
# This is a nice to have not a bring the system down
|
132
|
-
logger&.error "Coverband: route_tracker failed to store, error #{e.class.name} info #{e.message}"
|
133
|
-
end
|
134
|
-
|
135
|
-
def self.supported_version?
|
136
|
-
defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 4
|
137
|
-
end
|
138
|
-
|
139
|
-
protected
|
140
|
-
|
141
|
-
def newly_seen_route?(route)
|
142
|
-
!@logged_routes.include?(route)
|
143
|
-
end
|
144
|
-
|
145
|
-
def track_route?(route, options = {})
|
146
|
-
@ignore_patterns.none? { |pattern| route.to_s.include?(pattern) }
|
147
73
|
end
|
148
74
|
|
149
75
|
private
|
150
76
|
|
151
|
-
def
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
77
|
+
def concrete_target
|
78
|
+
if defined?(Rails.application)
|
79
|
+
Rails.application.routes.routes.map do |route|
|
80
|
+
{
|
81
|
+
controller: route.defaults[:controller],
|
82
|
+
action: route.defaults[:action],
|
83
|
+
url_path: route.path.spec.to_s.gsub("(.:format)", ""),
|
84
|
+
verb: route.verb
|
85
|
+
}
|
86
|
+
end
|
158
87
|
else
|
159
|
-
|
88
|
+
[]
|
160
89
|
end
|
161
90
|
end
|
162
|
-
|
163
|
-
def tracker_key
|
164
|
-
"route_tracker_2"
|
165
|
-
end
|
166
|
-
|
167
|
-
def tracker_time_key
|
168
|
-
"route_tracker_time"
|
169
|
-
end
|
170
91
|
end
|
171
92
|
end
|
172
93
|
end
|
@@ -20,129 +20,30 @@ module Coverband
|
|
20
20
|
###
|
21
21
|
# This class tracks translation usage via I18n::Backend
|
22
22
|
###
|
23
|
-
class TranslationTracker
|
24
|
-
|
25
|
-
|
23
|
+
class TranslationTracker < AbstractTracker
|
24
|
+
REPORT_ROUTE = "translations_tracker"
|
25
|
+
TITLE = "Translations"
|
26
26
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
@ignore_patterns = Coverband.configuration.ignore
|
32
|
-
@store = options.fetch(:store) { Coverband.configuration.store }
|
33
|
-
@logger = options.fetch(:logger) { Coverband.configuration.logger }
|
34
|
-
@target = options.fetch(:target) do
|
35
|
-
if defined?(Rails.application)
|
36
|
-
# I18n.eager_load!
|
37
|
-
# I18n.backend.send(:translations)
|
38
|
-
app_translation_keys = []
|
39
|
-
app_translation_files = ::I18n.load_path.select { |f| f.match(/config\/locales/) }
|
40
|
-
app_translation_files.each do |file|
|
41
|
-
app_translation_keys += flatten_hash(YAML.load_file(file)).keys
|
42
|
-
end
|
43
|
-
app_translation_keys.uniq
|
44
|
-
else
|
45
|
-
[]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
@one_time_timestamp = false
|
50
|
-
|
51
|
-
@logged_keys = Set.new
|
52
|
-
@keys_to_record = Set.new
|
27
|
+
def railtie!
|
28
|
+
# plugin to i18n
|
29
|
+
::I18n::Backend::Simple.send :include, ::Coverband::Collectors::I18n::KeyRegistry
|
53
30
|
end
|
54
31
|
|
55
|
-
|
56
|
-
@logged_keys.to_a
|
57
|
-
end
|
58
|
-
|
59
|
-
def keys_to_record
|
60
|
-
@keys_to_record.to_a
|
61
|
-
end
|
32
|
+
private
|
62
33
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@logged_keys << key
|
70
|
-
@keys_to_record << key if track_key?(key)
|
34
|
+
def concrete_target
|
35
|
+
if defined?(Rails.application)
|
36
|
+
app_translation_keys = []
|
37
|
+
app_translation_files = ::I18n.load_path.select { |f| f.match(/config\/locales/) }
|
38
|
+
app_translation_files.each do |file|
|
39
|
+
app_translation_keys += flatten_hash(YAML.load_file(file)).keys
|
71
40
|
end
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
def used_keys
|
76
|
-
redis_store.hgetall(tracker_key)
|
77
|
-
end
|
78
|
-
|
79
|
-
def all_keys
|
80
|
-
target.uniq
|
81
|
-
end
|
82
|
-
|
83
|
-
def unused_keys(used_keys = nil)
|
84
|
-
recently_used_keys = (used_keys || self.used_keys).keys
|
85
|
-
all_keys.reject { |k| recently_used_keys.include?(k.to_s) }
|
86
|
-
end
|
87
|
-
|
88
|
-
def as_json
|
89
|
-
used_keys = self.used_keys
|
90
|
-
{
|
91
|
-
unused_keys: unused_keys(used_keys),
|
92
|
-
used_keys: used_keys
|
93
|
-
}.to_json
|
94
|
-
end
|
95
|
-
|
96
|
-
def tracking_since
|
97
|
-
if (tracking_time = redis_store.get(tracker_time_key))
|
98
|
-
Time.at(tracking_time.to_i).iso8601
|
41
|
+
app_translation_keys.uniq
|
99
42
|
else
|
100
|
-
|
43
|
+
[]
|
101
44
|
end
|
102
45
|
end
|
103
46
|
|
104
|
-
def reset_recordings
|
105
|
-
redis_store.del(tracker_key)
|
106
|
-
redis_store.del(tracker_time_key)
|
107
|
-
end
|
108
|
-
|
109
|
-
def clear_key!(key)
|
110
|
-
return unless key
|
111
|
-
|
112
|
-
redis_store.hdel(tracker_key, key)
|
113
|
-
@logged_keys.delete(key)
|
114
|
-
end
|
115
|
-
|
116
|
-
def save_report
|
117
|
-
redis_store.set(tracker_time_key, Time.now.to_i) unless @one_time_timestamp || tracker_time_key_exists?
|
118
|
-
@one_time_timestamp = true
|
119
|
-
reported_time = Time.now.to_i
|
120
|
-
@keys_to_record.to_a.each do |key|
|
121
|
-
redis_store.hset(tracker_key, key.to_s, reported_time)
|
122
|
-
end
|
123
|
-
@keys_to_record.clear
|
124
|
-
rescue => e
|
125
|
-
# we don't want to raise errors if Coverband can't reach redis.
|
126
|
-
# This is a nice to have not a bring the system down
|
127
|
-
logger&.error "Coverband: #{self.class.name} failed to store, error #{e.class.name} info #{e.message}"
|
128
|
-
end
|
129
|
-
|
130
|
-
def self.supported_version?
|
131
|
-
defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 4
|
132
|
-
end
|
133
|
-
|
134
|
-
protected
|
135
|
-
|
136
|
-
def newly_seen_key?(key)
|
137
|
-
!@logged_keys.include?(key)
|
138
|
-
end
|
139
|
-
|
140
|
-
def track_key?(key, options = {})
|
141
|
-
@ignore_patterns.none? { |pattern| key.to_s.include?(pattern) }
|
142
|
-
end
|
143
|
-
|
144
|
-
private
|
145
|
-
|
146
47
|
def flatten_hash(hash)
|
147
48
|
hash.each_with_object({}) do |(k, v), h|
|
148
49
|
if v.is_a? Hash
|
@@ -154,30 +55,6 @@ module Coverband
|
|
154
55
|
end
|
155
56
|
end
|
156
57
|
end
|
157
|
-
|
158
|
-
def redis_store
|
159
|
-
store.raw_store
|
160
|
-
end
|
161
|
-
|
162
|
-
def tracker_time_key_exists?
|
163
|
-
if defined?(redis_store.exists?)
|
164
|
-
redis_store.exists?(tracker_time_key)
|
165
|
-
else
|
166
|
-
redis_store.exists(tracker_time_key)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def tracker_key
|
171
|
-
"#{class_key}_tracker"
|
172
|
-
end
|
173
|
-
|
174
|
-
def tracker_time_key
|
175
|
-
"#{class_key}_tracker_time"
|
176
|
-
end
|
177
|
-
|
178
|
-
def class_key
|
179
|
-
@class_key ||= self.class.name.split("::").last
|
180
|
-
end
|
181
58
|
end
|
182
59
|
end
|
183
60
|
end
|