coverband 4.2.5.rc.2 → 5.0.0.rc.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.standard.yml +25 -0
- data/.travis.yml +2 -1
- data/Gemfile +5 -7
- data/Gemfile.rails4 +0 -3
- data/Gemfile.rails6 +0 -3
- data/README.md +24 -77
- data/Rakefile +17 -17
- data/changes.md +26 -30
- data/config.ru +1 -1
- data/coverband.gemspec +29 -34
- data/lib/alternative_coverband_patch.rb +5 -0
- data/lib/coverband.rb +55 -43
- data/lib/coverband/adapters/base.rb +17 -17
- data/lib/coverband/adapters/file_store.rb +2 -2
- data/lib/coverband/adapters/hash_redis_store.rb +24 -21
- data/lib/coverband/adapters/redis_store.rb +12 -12
- data/lib/coverband/at_exit.rb +1 -1
- data/lib/coverband/collectors/coverage.rb +15 -27
- data/lib/coverband/collectors/delta.rb +19 -9
- data/lib/coverband/collectors/view_tracker.rb +19 -11
- data/lib/coverband/configuration.rb +48 -84
- data/lib/coverband/integrations/background.rb +3 -3
- data/lib/coverband/integrations/rack_server_check.rb +3 -3
- data/lib/coverband/integrations/resque.rb +13 -1
- data/lib/coverband/reporters/base.rb +10 -10
- data/lib/coverband/reporters/console_report.rb +1 -1
- data/lib/coverband/reporters/html_report.rb +10 -30
- data/lib/coverband/reporters/web.rb +56 -49
- data/lib/coverband/utils/absolute_file_converter.rb +6 -6
- data/lib/coverband/utils/html_formatter.rb +32 -61
- data/lib/coverband/utils/railtie.rb +16 -4
- data/lib/coverband/utils/relative_file_converter.rb +2 -2
- data/lib/coverband/utils/result.rb +6 -11
- data/lib/coverband/utils/results.rb +0 -10
- data/lib/coverband/utils/source_file.rb +21 -30
- data/lib/coverband/utils/tasks.rb +7 -11
- data/lib/coverband/version.rb +1 -1
- data/public/application.js +0 -30
- data/test/benchmarks/benchmark.rake +97 -92
- data/test/benchmarks/dog.rb +1 -1
- data/test/benchmarks/init_rails.rake +4 -4
- data/test/coverband/adapters/base_test.rb +29 -30
- data/test/coverband/adapters/file_store_test.rb +15 -16
- data/test/coverband/adapters/hash_redis_store_test.rb +57 -57
- data/test/coverband/adapters/redis_store_test.rb +26 -26
- data/test/coverband/at_exit_test.rb +2 -2
- data/test/coverband/collectors/coverage_test.rb +33 -47
- data/test/coverband/collectors/delta_test.rb +51 -23
- data/test/coverband/collectors/view_tracker_test.rb +35 -35
- data/test/coverband/configuration_test.rb +27 -53
- data/test/coverband/coverband_test.rb +11 -11
- data/test/coverband/integrations/background_middleware_test.rb +10 -10
- data/test/coverband/integrations/background_test.rb +3 -2
- data/test/coverband/integrations/rack_server_check_test.rb +7 -7
- data/test/coverband/integrations/report_middleware_test.rb +9 -9
- data/test/coverband/integrations/resque_worker_test.rb +9 -9
- data/test/coverband/integrations/test_resque_job.rb +1 -1
- data/test/coverband/reporters/base_test.rb +9 -9
- data/test/coverband/reporters/console_test.rb +6 -6
- data/test/coverband/reporters/html_test.rb +36 -48
- data/test/coverband/reporters/web_test.rb +16 -18
- data/test/coverband/utils/absolute_file_converter_test.rb +22 -22
- data/test/coverband/utils/file_hasher_test.rb +6 -12
- data/test/coverband/utils/file_list_test.rb +13 -13
- data/test/coverband/utils/html_formatter_test.rb +9 -23
- data/test/coverband/utils/lines_classifier_test.rb +29 -29
- data/test/coverband/utils/relative_file_converter_test.rb +13 -13
- data/test/coverband/utils/result_test.rb +18 -18
- data/test/coverband/utils/results_test.rb +17 -17
- data/test/coverband/utils/source_file_line_test.rb +46 -46
- data/test/coverband/utils/source_file_test.rb +38 -88
- data/test/dog.rb +1 -1
- data/test/fake_app/basic_rack.rb +2 -2
- data/test/fixtures/app/controllers/sample_controller.rb +1 -1
- data/test/fixtures/app/models/user.rb +1 -1
- data/test/fixtures/sample.rb +1 -1
- data/test/fixtures/utf-8.rb +0 -2
- data/test/forked/rails_full_stack_test.rb +24 -27
- data/test/forked/rails_rake_full_stack_test.rb +7 -26
- data/test/integration/full_stack_test.rb +11 -22
- data/test/jruby_check.rb +2 -3
- data/test/rails4_dummy/Rakefile +1 -1
- data/test/rails4_dummy/config.ru +1 -1
- data/test/rails4_dummy/config/application.rb +4 -4
- data/test/rails4_dummy/config/boot.rb +2 -2
- data/test/rails4_dummy/config/coverband.rb +1 -1
- data/test/rails4_dummy/config/coverband_missing_redis.rb +1 -1
- data/test/rails4_dummy/config/environment.rb +1 -1
- data/test/rails4_dummy/config/routes.rb +2 -2
- data/test/rails5_dummy/Rakefile +1 -1
- data/test/rails5_dummy/config.ru +1 -1
- data/test/rails5_dummy/config/application.rb +3 -3
- data/test/rails5_dummy/config/coverband.rb +8 -8
- data/test/rails5_dummy/config/coverband_missing_redis.rb +8 -8
- data/test/rails5_dummy/config/environment.rb +1 -1
- data/test/rails5_dummy/config/routes.rb +2 -2
- data/test/rails6_dummy/Rakefile +1 -1
- data/test/rails6_dummy/config.ru +1 -1
- data/test/rails6_dummy/config/application.rb +4 -4
- data/test/rails6_dummy/config/boot.rb +2 -2
- data/test/rails6_dummy/config/coverband.rb +1 -1
- data/test/rails6_dummy/config/coverband_missing_redis.rb +1 -1
- data/test/rails6_dummy/config/environment.rb +1 -1
- data/test/rails6_dummy/config/routes.rb +2 -2
- data/test/rails_test_helper.rb +11 -11
- data/test/test_helper.rb +41 -34
- data/test/unique_files.rb +10 -10
- data/views/layout.erb +2 -12
- metadata +5 -43
- data/.rubocop.yml +0 -84
- data/lib/coverband/integrations/bundler.rb +0 -8
- data/lib/coverband/utils/file_groups.rb +0 -53
- data/lib/coverband/utils/gem_list.rb +0 -31
- data/lib/coverband/utils/s3_report.rb +0 -105
- data/test/coverband/utils/file_groups_test.rb +0 -61
- data/test/coverband/utils/gem_list_test.rb +0 -48
- data/test/coverband/utils/s3_report_test.rb +0 -44
- data/views/gem_list.erb +0 -63
data/lib/coverband.rb
CHANGED
@@ -1,42 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require 'coverband/utils/lines_classifier'
|
24
|
-
require 'coverband/utils/results'
|
25
|
-
require 'coverband/collectors/coverage'
|
26
|
-
require 'coverband/collectors/view_tracker'
|
27
|
-
require 'coverband/reporters/base'
|
28
|
-
require 'coverband/reporters/html_report'
|
29
|
-
require 'coverband/reporters/console_report'
|
30
|
-
require 'coverband/reporters/web'
|
31
|
-
require 'coverband/integrations/background'
|
32
|
-
require 'coverband/integrations/background_middleware'
|
33
|
-
require 'coverband/integrations/rack_server_check'
|
3
|
+
require "logger"
|
4
|
+
require "json"
|
5
|
+
require "redis"
|
6
|
+
require "coverband/version"
|
7
|
+
require "coverband/at_exit"
|
8
|
+
require "coverband/configuration"
|
9
|
+
require "coverband/utils/relative_file_converter"
|
10
|
+
require "coverband/utils/absolute_file_converter"
|
11
|
+
require "coverband/adapters/base"
|
12
|
+
require "coverband/adapters/redis_store"
|
13
|
+
require "coverband/adapters/hash_redis_store"
|
14
|
+
require "coverband/adapters/file_store"
|
15
|
+
require "coverband/utils/file_hasher"
|
16
|
+
require "coverband/collectors/coverage"
|
17
|
+
require "coverband/collectors/view_tracker"
|
18
|
+
require "coverband/reporters/base"
|
19
|
+
require "coverband/reporters/console_report"
|
20
|
+
require "coverband/integrations/background"
|
21
|
+
require "coverband/integrations/background_middleware"
|
22
|
+
require "coverband/integrations/rack_server_check"
|
34
23
|
|
35
|
-
Coverband::Adapters::RedisStore = Coverband::Adapters::HashRedisStore if ENV[
|
24
|
+
Coverband::Adapters::RedisStore = Coverband::Adapters::HashRedisStore if ENV["COVERBAND_HASH_REDIS_STORE"]
|
36
25
|
|
37
26
|
module Coverband
|
38
27
|
@@configured = false
|
39
|
-
CONFIG_FILE =
|
28
|
+
CONFIG_FILE = "./config/coverband.rb"
|
40
29
|
RUNTIME_TYPE = :runtime
|
41
30
|
EAGER_TYPE = :eager_loading
|
42
31
|
MERGED_TYPE = :merged
|
@@ -44,14 +33,14 @@ module Coverband
|
|
44
33
|
ALL_TYPES = TYPES + [:merged]
|
45
34
|
|
46
35
|
def self.configure(file = nil)
|
47
|
-
configuration_file = file || ENV.fetch(
|
36
|
+
configuration_file = file || ENV.fetch("COVERBAND_CONFIG", CONFIG_FILE)
|
48
37
|
configuration
|
49
38
|
if block_given?
|
50
39
|
yield(configuration)
|
51
40
|
elsif File.exist?(configuration_file)
|
52
41
|
load configuration_file
|
53
42
|
else
|
54
|
-
configuration.logger.debug(
|
43
|
+
configuration.logger.debug("using default configuration")
|
55
44
|
end
|
56
45
|
@@configured = true
|
57
46
|
coverage_instance.reset_instance
|
@@ -98,19 +87,42 @@ module Coverband
|
|
98
87
|
private_class_method def self.coverage_instance
|
99
88
|
Coverband::Collectors::Coverage.instance
|
100
89
|
end
|
101
|
-
unless ENV[
|
90
|
+
unless ENV["COVERBAND_DISABLE_AUTO_START"]
|
102
91
|
begin
|
103
|
-
require 'coverband/utils/jruby_ext' if RUBY_PLATFORM == 'java'
|
104
92
|
# Coverband should be setup as early as possible
|
105
93
|
# to capture usage of things loaded by initializers or other Rails engines
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
94
|
+
# but after gems are loaded to avoid slowing down gem usage
|
95
|
+
# best is in application.rb after the bundler line but we get close with Railtie
|
96
|
+
if defined? ::Rails::Railtie
|
97
|
+
require "coverband/utils/railtie"
|
98
|
+
else
|
99
|
+
configure
|
100
|
+
start
|
101
|
+
end
|
102
|
+
require "coverband/integrations/resque" if defined? ::Resque
|
111
103
|
rescue Redis::CannotConnectError => error
|
112
104
|
Coverband.configuration.logger.info "Redis is not available (#{error}), Coverband not configured"
|
113
|
-
Coverband.configuration.logger.info
|
105
|
+
Coverband.configuration.logger.info "If this is a setup task like assets:precompile feel free to ignore"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
module Reporters
|
110
|
+
class Web
|
111
|
+
###
|
112
|
+
# NOTE: if the user doesn't setup the webreporter
|
113
|
+
# we don't need any of the below files loaded or using memory
|
114
|
+
###
|
115
|
+
def initialize
|
116
|
+
require "coverband/reporters/web"
|
117
|
+
require "coverband/utils/html_formatter"
|
118
|
+
require "coverband/utils/result"
|
119
|
+
require "coverband/utils/file_list"
|
120
|
+
require "coverband/utils/source_file"
|
121
|
+
require "coverband/utils/lines_classifier"
|
122
|
+
require "coverband/utils/results"
|
123
|
+
require "coverband/reporters/html_report"
|
124
|
+
init_web
|
125
|
+
end
|
114
126
|
end
|
115
127
|
end
|
116
128
|
end
|
@@ -3,11 +3,11 @@
|
|
3
3
|
module Coverband
|
4
4
|
module Adapters
|
5
5
|
class Base
|
6
|
-
DATA_KEY =
|
7
|
-
FIRST_UPDATED_KEY =
|
8
|
-
LAST_UPDATED_KEY =
|
9
|
-
FILE_HASH =
|
10
|
-
ABSTRACT_KEY =
|
6
|
+
DATA_KEY = "data"
|
7
|
+
FIRST_UPDATED_KEY = "first_updated_at"
|
8
|
+
LAST_UPDATED_KEY = "last_updated_at"
|
9
|
+
FILE_HASH = "file_hash"
|
10
|
+
ABSTRACT_KEY = "abstract"
|
11
11
|
|
12
12
|
attr_accessor :type
|
13
13
|
|
@@ -40,11 +40,11 @@ module Coverband
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def size_in_mib
|
43
|
-
format(
|
43
|
+
format("%<size>.2f", size: (size.to_f / 2**20))
|
44
44
|
end
|
45
45
|
|
46
46
|
def save_report(_report)
|
47
|
-
raise
|
47
|
+
raise "abstract"
|
48
48
|
end
|
49
49
|
|
50
50
|
def get_coverage_report
|
@@ -76,7 +76,7 @@ module Coverband
|
|
76
76
|
runtime_data = coverage(Coverband::RUNTIME_TYPE)
|
77
77
|
eager_data = coverage(Coverband::EAGER_TYPE)
|
78
78
|
eager_data.values do |vals|
|
79
|
-
vals[
|
79
|
+
vals["data"].map! { |line_coverage| line_coverage ? (0 - line_coverage) : line_coverage }
|
80
80
|
end
|
81
81
|
merge_reports(runtime_data, eager_data, skip_expansion: true)
|
82
82
|
end
|
@@ -117,14 +117,14 @@ module Coverband
|
|
117
117
|
keys = (new_report.keys + old_report.keys).uniq
|
118
118
|
keys.each do |file|
|
119
119
|
new_report[file] = if new_report[file] &&
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
120
|
+
old_report[file] &&
|
121
|
+
new_report[file][FILE_HASH] == old_report[file][FILE_HASH]
|
122
|
+
merge_expanded_data(new_report[file], old_report[file])
|
123
|
+
elsif new_report[file]
|
124
|
+
new_report[file]
|
125
|
+
else
|
126
|
+
old_report[file]
|
127
|
+
end
|
128
128
|
end
|
129
129
|
new_report
|
130
130
|
end
|
@@ -145,7 +145,7 @@ module Coverband
|
|
145
145
|
elsif Coverband.configuration.simulate_oneshot_lines_coverage
|
146
146
|
latest.map.with_index { |v, i| (v + original[i] >= 1 ? 1 : 0) if v && original[i] }
|
147
147
|
else
|
148
|
-
latest.map.with_index { |v, i|
|
148
|
+
latest.map.with_index { |v, i| v && original[i] ? v + original[i] : nil }
|
149
149
|
end
|
150
150
|
end
|
151
151
|
end
|
@@ -5,7 +5,7 @@ module Coverband
|
|
5
5
|
###
|
6
6
|
# FilesStore store a merged coverage file to local disk
|
7
7
|
# Generally this is for testing and development
|
8
|
-
# Not recommended for production deployment
|
8
|
+
# Not recommended for production deployment, as it doesn't handle concurrency
|
9
9
|
###
|
10
10
|
class FileStore < Base
|
11
11
|
def initialize(path, _opts = {})
|
@@ -39,7 +39,7 @@ module Coverband
|
|
39
39
|
def save_report(report)
|
40
40
|
data = report.dup
|
41
41
|
data = merge_reports(data, coverage)
|
42
|
-
File.open(path,
|
42
|
+
File.open(path, "w") { |f| f.write(data.to_json) }
|
43
43
|
end
|
44
44
|
|
45
45
|
def raw_store
|
@@ -1,19 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "securerandom"
|
4
4
|
|
5
5
|
module Coverband
|
6
6
|
module Adapters
|
7
7
|
class HashRedisStore < Base
|
8
|
-
FILE_KEY =
|
9
|
-
FILE_LENGTH_KEY =
|
8
|
+
FILE_KEY = "file"
|
9
|
+
FILE_LENGTH_KEY = "file_length"
|
10
10
|
META_DATA_KEYS = [DATA_KEY, FIRST_UPDATED_KEY, LAST_UPDATED_KEY, FILE_HASH].freeze
|
11
11
|
###
|
12
12
|
# This key isn't related to the coverband version, but to the interal format
|
13
13
|
# used to store data to redis. It is changed only when breaking changes to our
|
14
14
|
# redis format are required.
|
15
15
|
###
|
16
|
-
REDIS_STORAGE_FORMAT_VERSION =
|
16
|
+
REDIS_STORAGE_FORMAT_VERSION = "coverband_hash_3_3"
|
17
17
|
|
18
18
|
JSON_PAYLOAD_EXPIRATION = 5 * 60
|
19
19
|
|
@@ -25,14 +25,17 @@ module Coverband
|
|
25
25
|
@save_report_batch_size = opts[:save_report_batch_size] || 100
|
26
26
|
@format_version = REDIS_STORAGE_FORMAT_VERSION
|
27
27
|
@redis = redis
|
28
|
-
raise
|
28
|
+
raise "HashRedisStore requires redis >= 2.6.0" unless supported?
|
29
29
|
|
30
30
|
@ttl = opts[:ttl]
|
31
31
|
@relative_file_converter = opts[:relative_file_converter] || Utils::RelativeFileConverter
|
32
32
|
end
|
33
33
|
|
34
34
|
def supported?
|
35
|
-
Gem::Version.new(@redis.info[
|
35
|
+
Gem::Version.new(@redis.info["redis_version"]) >= Gem::Version.new("2.6.0")
|
36
|
+
rescue Redis::CannotConnectError => error
|
37
|
+
Coverband.configuration.logger.info "Redis is not available (#{error}), Coverband not configured"
|
38
|
+
Coverband.configuration.logger.info "If this is a setup task like assets:precompile feel free to ignore"
|
36
39
|
end
|
37
40
|
|
38
41
|
def clear!
|
@@ -60,7 +63,7 @@ module Coverband
|
|
60
63
|
updated_time = type == Coverband::EAGER_TYPE ? nil : report_time
|
61
64
|
keys = []
|
62
65
|
report.each_slice(@save_report_batch_size) do |slice|
|
63
|
-
files_data = slice.map
|
66
|
+
files_data = slice.map { |(file, data)|
|
64
67
|
relative_file = @relative_file_converter.convert(file)
|
65
68
|
file_hash = file_hash(relative_file)
|
66
69
|
key = key(relative_file, file_hash: file_hash)
|
@@ -73,11 +76,11 @@ module Coverband
|
|
73
76
|
report_time: report_time,
|
74
77
|
updated_time: updated_time
|
75
78
|
)
|
76
|
-
|
79
|
+
}
|
77
80
|
next unless files_data.any?
|
78
81
|
|
79
|
-
arguments_key = [@redis_namespace, SecureRandom.uuid].compact.join(
|
80
|
-
@redis.set(arguments_key, {
|
82
|
+
arguments_key = [@redis_namespace, SecureRandom.uuid].compact.join(".")
|
83
|
+
@redis.set(arguments_key, {ttl: @ttl, files_data: files_data}.to_json, ex: JSON_PAYLOAD_EXPIRATION)
|
81
84
|
@redis.evalsha(hash_incr_script, [arguments_key])
|
82
85
|
end
|
83
86
|
@redis.sadd(files_key, keys) if keys.any?
|
@@ -85,11 +88,11 @@ module Coverband
|
|
85
88
|
|
86
89
|
def coverage(local_type = nil)
|
87
90
|
files_set = files_set(local_type)
|
88
|
-
@redis.pipelined
|
91
|
+
@redis.pipelined {
|
89
92
|
files_set.map do |key|
|
90
93
|
@redis.hgetall(key)
|
91
94
|
end
|
92
|
-
|
95
|
+
}.each_with_object({}) do |data_from_redis, hash|
|
93
96
|
add_coverage_for_file(data_from_redis, hash)
|
94
97
|
end
|
95
98
|
end
|
@@ -99,11 +102,11 @@ module Coverband
|
|
99
102
|
end
|
100
103
|
|
101
104
|
def size
|
102
|
-
|
105
|
+
"not available"
|
103
106
|
end
|
104
107
|
|
105
108
|
def size_in_mib
|
106
|
-
|
109
|
+
"not available"
|
107
110
|
end
|
108
111
|
|
109
112
|
private
|
@@ -115,7 +118,7 @@ module Coverband
|
|
115
118
|
return unless file_hash(file) == data_from_redis[FILE_HASH]
|
116
119
|
|
117
120
|
data = coverage_data_from_redis(data_from_redis)
|
118
|
-
hash[file] = data_from_redis.select { |meta_data_key, _value| META_DATA_KEYS.include?(meta_data_key) }.merge!(
|
121
|
+
hash[file] = data_from_redis.select { |meta_data_key, _value| META_DATA_KEYS.include?(meta_data_key) }.merge!("data" => data)
|
119
122
|
hash[file][LAST_UPDATED_KEY] = hash[file][LAST_UPDATED_KEY].blank? ? nil : hash[file][LAST_UPDATED_KEY].to_i
|
120
123
|
hash[file].merge!(LAST_UPDATED_KEY => hash[file][LAST_UPDATED_KEY], FIRST_UPDATED_KEY => hash[file][FIRST_UPDATED_KEY].to_i)
|
121
124
|
end
|
@@ -129,9 +132,9 @@ module Coverband
|
|
129
132
|
end
|
130
133
|
|
131
134
|
def script_input(key:, file:, file_hash:, data:, report_time:, updated_time:)
|
132
|
-
coverage_data = data.each_with_index.each_with_object({})
|
135
|
+
coverage_data = data.each_with_index.each_with_object({}) { |(coverage, index), hash|
|
133
136
|
hash[index] = coverage if coverage
|
134
|
-
|
137
|
+
}
|
135
138
|
meta = {
|
136
139
|
first_updated_at: report_time,
|
137
140
|
file: file,
|
@@ -153,8 +156,8 @@ module Coverband
|
|
153
156
|
|
154
157
|
def lua_script_content
|
155
158
|
File.read(File.join(
|
156
|
-
|
157
|
-
|
159
|
+
File.dirname(__FILE__), "../../../lua/lib/persist-coverage.lua"
|
160
|
+
))
|
158
161
|
end
|
159
162
|
|
160
163
|
def values_from_redis(local_type, files)
|
@@ -178,12 +181,12 @@ module Coverband
|
|
178
181
|
end
|
179
182
|
|
180
183
|
def key(file, local_type = nil, file_hash:)
|
181
|
-
[key_prefix(local_type), file, file_hash].join(
|
184
|
+
[key_prefix(local_type), file, file_hash].join(".")
|
182
185
|
end
|
183
186
|
|
184
187
|
def key_prefix(local_type = nil)
|
185
188
|
local_type ||= type
|
186
|
-
[@format_version, @redis_namespace, local_type].compact.join(
|
189
|
+
[@format_version, @redis_namespace, local_type].compact.join(".")
|
187
190
|
end
|
188
191
|
end
|
189
192
|
end
|
@@ -11,19 +11,19 @@ module Coverband
|
|
11
11
|
# used to store data to redis. It is changed only when breaking changes to our
|
12
12
|
# redis format are required.
|
13
13
|
###
|
14
|
-
REDIS_STORAGE_FORMAT_VERSION =
|
14
|
+
REDIS_STORAGE_FORMAT_VERSION = "coverband_3_2"
|
15
15
|
|
16
16
|
attr_reader :redis_namespace
|
17
17
|
|
18
18
|
def initialize(redis, opts = {})
|
19
19
|
super()
|
20
|
-
@redis
|
21
|
-
@ttl
|
20
|
+
@redis = redis
|
21
|
+
@ttl = opts[:ttl]
|
22
22
|
@redis_namespace = opts[:redis_namespace]
|
23
|
-
@format_version
|
24
|
-
@keys
|
23
|
+
@format_version = REDIS_STORAGE_FORMAT_VERSION
|
24
|
+
@keys = {}
|
25
25
|
Coverband::TYPES.each do |type|
|
26
|
-
@keys[type] = [@format_version, @redis_namespace, type].compact.join(
|
26
|
+
@keys[type] = [@format_version, @redis_namespace, type].compact.join(".")
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -54,15 +54,15 @@ module Coverband
|
|
54
54
|
###
|
55
55
|
def migrate!
|
56
56
|
reset_base_key
|
57
|
-
@format_version =
|
57
|
+
@format_version = "coverband3_1"
|
58
58
|
previous_data = coverage
|
59
59
|
if previous_data.empty?
|
60
|
-
puts
|
60
|
+
puts "no previous data to migrate found"
|
61
61
|
exit 0
|
62
62
|
end
|
63
|
-
relative_path_report = previous_data.each_with_object({})
|
63
|
+
relative_path_report = previous_data.each_with_object({}) { |(key, vals), fixed_report|
|
64
64
|
fixed_report[Utils::RelativeFileConverter.convert(key)] = vals
|
65
|
-
|
65
|
+
}
|
66
66
|
clear!
|
67
67
|
reset_base_key
|
68
68
|
@format_version = REDIS_STORAGE_FORMAT_VERSION
|
@@ -78,7 +78,7 @@ module Coverband
|
|
78
78
|
local_type ||= opts.key?(:override_type) ? opts[:override_type] : type
|
79
79
|
data = redis.get type_base_key(local_type)
|
80
80
|
data = data ? JSON.parse(data) : {}
|
81
|
-
data.delete_if { |file_path, file_data| file_hash(file_path) != file_data[
|
81
|
+
data.delete_if { |file_path, file_data| file_hash(file_path) != file_data["file_hash"] } unless opts[:skip_hash_check]
|
82
82
|
data
|
83
83
|
end
|
84
84
|
|
@@ -105,7 +105,7 @@ module Coverband
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def base_key
|
108
|
-
@base_key ||= [@format_version, @redis_namespace, type].compact.join(
|
108
|
+
@base_key ||= [@format_version, @redis_namespace, type].compact.join(".")
|
109
109
|
end
|
110
110
|
|
111
111
|
def type_base_key(local_type)
|
data/lib/coverband/at_exit.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require_relative
|
3
|
+
require "singleton"
|
4
|
+
require_relative "delta"
|
5
5
|
|
6
6
|
module Coverband
|
7
7
|
module Collectors
|
@@ -25,7 +25,6 @@ module Coverband
|
|
25
25
|
@verbose = Coverband.configuration.verbose
|
26
26
|
@logger = Coverband.configuration.logger
|
27
27
|
@test_env = Coverband.configuration.test_env
|
28
|
-
@track_gems = Coverband.configuration.track_gems
|
29
28
|
Delta.reset
|
30
29
|
self
|
31
30
|
end
|
@@ -49,53 +48,42 @@ module Coverband
|
|
49
48
|
|
50
49
|
def report_coverage
|
51
50
|
@semaphore.synchronize do
|
52
|
-
raise
|
51
|
+
raise "no Coverband store set" unless @store
|
53
52
|
|
54
53
|
files_with_line_usage = filtered_files(Delta.results)
|
55
54
|
@store.save_report(files_with_line_usage)
|
56
55
|
end
|
57
|
-
rescue
|
58
|
-
@logger&.error
|
56
|
+
rescue => e
|
57
|
+
@logger&.error "coverage failed to store"
|
59
58
|
@logger&.error "Coverband Error: #{e.inspect} #{e.message}"
|
60
59
|
e.backtrace.each { |line| @logger&.error line } if @verbose
|
61
60
|
raise e if @test_env
|
62
61
|
end
|
63
62
|
|
64
|
-
protected
|
65
|
-
|
66
|
-
###
|
67
|
-
# Normally I would break this out into additional methods
|
68
|
-
# and improve the readability but this is in a tight loop
|
69
|
-
# on the critical performance path, and any refactoring I come up with
|
70
|
-
# would slow down the performance.
|
71
|
-
###
|
72
|
-
def track_file?(file)
|
73
|
-
@ignore_patterns.none? do |pattern|
|
74
|
-
file.match(pattern)
|
75
|
-
end && (file.start_with?(@project_directory) ||
|
76
|
-
(@track_gems &&
|
77
|
-
Coverband.configuration.gem_paths.any? { |path| file.start_with?(path) }))
|
78
|
-
end
|
79
|
-
|
80
63
|
private
|
81
64
|
|
82
65
|
def filtered_files(new_results)
|
83
|
-
new_results.select! { |
|
66
|
+
new_results.select! { |_file, coverage| coverage.any? { |value| value&.nonzero? } }
|
84
67
|
new_results
|
85
68
|
end
|
86
69
|
|
87
70
|
def initialize
|
88
71
|
@semaphore = Mutex.new
|
89
|
-
raise NotImplementedError,
|
72
|
+
raise NotImplementedError, "Coverage needs Ruby > 2.3.0" if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.3.0")
|
90
73
|
|
91
|
-
require
|
74
|
+
require "coverage"
|
75
|
+
if RUBY_PLATFORM == "java"
|
76
|
+
unless ::Coverage.respond_to?(:line_stub)
|
77
|
+
require "coverband/utils/jruby_ext"
|
78
|
+
end
|
79
|
+
end
|
92
80
|
if defined?(SimpleCov) && defined?(Rails) && defined?(Rails.env) && Rails.env.test?
|
93
81
|
puts "Coverband: detected SimpleCov in test Env, allowing it to start Coverage"
|
94
82
|
puts "Coverband: to ensure no error logs or missing Coverage call `SimpleCov.start` prior to requiring Coverband"
|
95
83
|
else
|
96
|
-
if Coverage.ruby_version_greater_than_or_equal_to?(
|
84
|
+
if Coverage.ruby_version_greater_than_or_equal_to?("2.6.0")
|
97
85
|
::Coverage.start(oneshot_lines: Coverband.configuration.use_oneshot_lines_coverage) unless ::Coverage.running?
|
98
|
-
elsif Coverage.ruby_version_greater_than_or_equal_to?(
|
86
|
+
elsif Coverage.ruby_version_greater_than_or_equal_to?("2.5.0")
|
99
87
|
::Coverage.start unless ::Coverage.running?
|
100
88
|
else
|
101
89
|
::Coverage.start
|