coverband 2.0.3 → 3.0.0.alpha
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/.gitignore +0 -1
- data/.rubocop.yml +73 -0
- data/.travis.yml +0 -3
- data/README.md +3 -3
- data/changes.md +65 -49
- data/coverband.gemspec +1 -1
- data/lib/coverband.rb +9 -6
- data/lib/coverband/adapters/base.rb +22 -2
- data/lib/coverband/adapters/file_store.rb +11 -11
- data/lib/coverband/adapters/redis_store.rb +22 -57
- data/lib/coverband/collectors/coverage.rb +57 -53
- data/lib/coverband/configuration.rb +6 -14
- data/lib/coverband/integrations/background.rb +7 -0
- data/lib/coverband/{middleware.rb → integrations/middleware.rb} +1 -3
- data/lib/coverband/reporters/base.rb +37 -82
- data/lib/coverband/reporters/console_report.rb +3 -0
- data/lib/coverband/reporters/simple_cov_report.rb +4 -3
- data/lib/coverband/reporters/web.rb +38 -35
- data/lib/coverband/utils/s3_report_writer.rb +59 -0
- data/lib/coverband/{tasks.rb → utils/tasks.rb} +0 -0
- data/lib/coverband/version.rb +1 -1
- data/test/benchmarks/benchmark.rake +3 -3
- data/test/test_helper.rb +18 -17
- data/test/unit/adapters_base_test.rb +29 -0
- data/test/unit/adapters_file_store_test.rb +2 -2
- data/test/unit/adapters_redis_store_test.rb +14 -51
- data/test/unit/collectors_coverage_test.rb +3 -107
- data/test/unit/configuration_test.rb +2 -9
- data/test/unit/full_stack_test.rb +47 -0
- data/test/unit/middleware_test.rb +21 -57
- data/test/unit/reports_base_test.rb +12 -71
- data/test/unit/reports_console_test.rb +9 -22
- data/test/unit/reports_simple_cov_test.rb +3 -37
- data/test/unit/reports_web_test.rb +4 -0
- data/test/unit/{s3_report_writer_test.rb → utils_s3_report_writer_test.rb} +1 -1
- metadata +29 -18
- data/lib/coverband/adapters/memory_cache_store.rb +0 -53
- data/lib/coverband/collectors/base.rb +0 -126
- data/lib/coverband/collectors/trace.rb +0 -122
- data/lib/coverband/s3_report_writer.rb +0 -49
- data/test/unit/adapters_memory_cache_store_test.rb +0 -66
- data/test/unit/collectors_base_test.rb +0 -104
- data/test/unit/collectors_trace_test.rb +0 -106
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff8f54b9c75fc882bc548834903c232af3ff9e74
|
4
|
+
data.tar.gz: 72cbf124e7484c096bc8316f8940a5d1128ba4de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f964fca6d95868d170694bb4dfb5a064b9d8df717e63a5d79b941dda8beaa6e6acbc3b149f98891030538da8c5b88d46a89edfbd9d97e668230e802fa222102e
|
7
|
+
data.tar.gz: de616d37895b9446425e2947d435db919776019f8658d45183430de3c95675e40591e49bcf0539a5306389f1ee52f5ae15372fa2521b13a71ead5a738ff79340
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.4
|
3
|
+
Exclude:
|
4
|
+
- docs/**/*
|
5
|
+
Documentation:
|
6
|
+
Enabled: false
|
7
|
+
Metrics/MethodLength:
|
8
|
+
Enabled: false
|
9
|
+
Metrics/LineLength:
|
10
|
+
Max: 120
|
11
|
+
Metrics/BlockNesting:
|
12
|
+
Max: 5
|
13
|
+
Bundler/OrderedGems:
|
14
|
+
Enabled: false
|
15
|
+
Metrics/CyclomaticComplexity:
|
16
|
+
Enabled: false
|
17
|
+
Metrics/PerceivedComplexity:
|
18
|
+
Enabled: false
|
19
|
+
Metrics/AbcSize:
|
20
|
+
Enabled: false
|
21
|
+
Metrics/ClassLength:
|
22
|
+
Enabled: false
|
23
|
+
Metrics/BlockLength:
|
24
|
+
Enabled: false
|
25
|
+
Metrics/BlockNesting:
|
26
|
+
Max: 10
|
27
|
+
Metrics/ModuleLength:
|
28
|
+
Enabled: false
|
29
|
+
Metrics/ParameterLists:
|
30
|
+
Max: 10
|
31
|
+
Naming/AccessorMethodName:
|
32
|
+
Enabled: false
|
33
|
+
Naming/PredicateName:
|
34
|
+
Enabled: false
|
35
|
+
Style/FormatStringToken:
|
36
|
+
Enabled: false
|
37
|
+
Style/TernaryParentheses:
|
38
|
+
Enabled: false
|
39
|
+
Style/MutableConstant:
|
40
|
+
Enabled: false
|
41
|
+
Style/FrozenStringLiteralComment:
|
42
|
+
Enabled: true
|
43
|
+
Style/GuardClause:
|
44
|
+
Enabled: true
|
45
|
+
Style/NumericPredicate:
|
46
|
+
Enabled: false
|
47
|
+
Style/NumericLiterals:
|
48
|
+
Enabled: false
|
49
|
+
Style/NumericLiteralPrefix:
|
50
|
+
Enabled: false
|
51
|
+
Style/ClassAndModuleChildren:
|
52
|
+
Enabled: false
|
53
|
+
Style/MethodMissingSuper:
|
54
|
+
Enabled: true
|
55
|
+
Style/MissingRespondToMissing:
|
56
|
+
Enabled: false
|
57
|
+
Performance/Casecmp:
|
58
|
+
Enabled: false
|
59
|
+
Layout/EmptyLinesAroundArguments:
|
60
|
+
Enabled: true
|
61
|
+
Layout/MultilineMethodCallIndentation:
|
62
|
+
Enabled: true
|
63
|
+
Layout/MultilineOperationIndentation:
|
64
|
+
Enabled: true
|
65
|
+
Lint/RescueException:
|
66
|
+
Enabled: true
|
67
|
+
Lint/ShadowingOuterLocalVariable:
|
68
|
+
Enabled: true
|
69
|
+
Style/FormatString:
|
70
|
+
Enabled: true
|
71
|
+
Security/Eval:
|
72
|
+
Enabled: true
|
73
|
+
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -179,7 +179,7 @@ module MyApplication
|
|
179
179
|
# any files that get loaded as part of railties will have no coverage
|
180
180
|
config.before_initialize do
|
181
181
|
require 'coverage'
|
182
|
-
Coverband::Collectors::
|
182
|
+
Coverband::Collectors::Coverage.instance.start
|
183
183
|
end
|
184
184
|
|
185
185
|
end
|
@@ -380,9 +380,9 @@ require 'rails'
|
|
380
380
|
# Capture code coverage during our cron jobs
|
381
381
|
class CoverageRunner < ::Rails::Railtie
|
382
382
|
runner do
|
383
|
-
Coverband::Collectors::
|
383
|
+
Coverband::Collectors::Coverage.instance.start
|
384
384
|
at_exit do
|
385
|
-
Coverband::Collectors::
|
385
|
+
Coverband::Collectors::Coverage.instance.report_coverage
|
386
386
|
end
|
387
387
|
end
|
388
388
|
end
|
data/changes.md
CHANGED
@@ -4,22 +4,41 @@
|
|
4
4
|
|
5
5
|
Will be the fully modern release that drops maintenance legacy support in favor of increased performance, ease of use, and maintainability.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
- expects to drop Tracepoint collection engine
|
8
|
+
- expects to drop anything below Ruby 2.3
|
9
|
+
- Release will be aimed as significantly simplifying ease of use
|
10
|
+
- near zero config setup for Rails apps
|
11
|
+
- add built-in support for easy loading via Railties
|
12
|
+
- built in support for activejob, sidekiq, and other common frameworks
|
13
|
+
- reduced configuration options
|
14
|
+
- options on reporting
|
15
|
+
- background reporting
|
16
|
+
- or middleware reporting
|
17
|
+
- improved web reporting
|
18
|
+
- no longer relying directly on HTML in S3 but dynamically generated from any adapter
|
19
|
+
- additional adapters including Memcache, S3, and ActiveRecord
|
20
|
+
|
21
|
+
### Coverband_jam_session
|
22
|
+
|
23
|
+
This is a possible gem to host experimental or more complex features, which would require tuning, configuration, and performance trade offs
|
24
|
+
|
25
|
+
- additional adapters (tracepoint, ruby-profiler, etc)
|
26
|
+
- code route tracing (entry point to all code executed for example /some_path -> code coverage of that path)
|
27
|
+
- tagging of reported Coverage
|
28
|
+
- allow only to collect coverage based on route (limiting or scoped coverage)
|
29
|
+
- coverage over some other variable like a set of alpha users
|
16
30
|
|
17
31
|
# Alpha
|
18
32
|
|
19
|
-
### 3.0
|
33
|
+
### Coverband 3.0
|
34
|
+
|
35
|
+
* drops Tracepoint
|
36
|
+
* drops Ruby <= 2.3.0
|
37
|
+
* rewrites redis store, for 60X perf
|
38
|
+
* drops various other features not needed without Tracepoint
|
39
|
+
* standardizes on Coverage array format vs sparse hash
|
20
40
|
|
21
|
-
|
22
|
-
* background thread reporter
|
41
|
+
# Released
|
23
42
|
|
24
43
|
# 2.0.3
|
25
44
|
|
@@ -28,9 +47,6 @@ Will be the fully modern release that drops maintenance legacy support in favor
|
|
28
47
|
* various additional benchmarks @danmayer
|
29
48
|
* Filter out files with no coverage thanks @kbaum
|
30
49
|
|
31
|
-
|
32
|
-
# Released
|
33
|
-
|
34
50
|
### 2.0.2
|
35
51
|
|
36
52
|
* fix possible nil error on files that changed since initial recording @viktor-silakov
|
@@ -45,50 +61,50 @@ Will be the fully modern release that drops maintenance legacy support in favor
|
|
45
61
|
|
46
62
|
### 2.0.1
|
47
63
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
64
|
+
- add support for fine grained S3 configuration via Coverband config, thanks @a0s
|
65
|
+
- https://github.com/danmayer/coverband/pull/98
|
66
|
+
- Using the file argument to self.configure in lib/coverband.rb, thanks @ThomasOwens
|
67
|
+
- https://github.com/danmayer/coverband/pull/100
|
68
|
+
- added redis improvements allowing namespace and TTL thx @oded-zahavi
|
69
|
+
- fix warnings about duplicate method definition
|
70
|
+
- Add support for safe_reload_files based on full file path
|
71
|
+
- Add support for Sinatra admin control endpoints
|
72
|
+
- improved documentation
|
57
73
|
|
58
74
|
### 2.0.0
|
59
75
|
|
60
76
|
Major release with various backwards compatibility breaking changes (generally related to the configuration). The 2.0 lifecycle will act as a mostly easy upgrade that supports past users looking to move to the much faster new Coverage Adapter.
|
61
77
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
78
|
+
- Continues to support Ruby 2.0 and up
|
79
|
+
- supports multiple collect engines, introducing the concept of multiple collector adapters
|
80
|
+
- extends the concepts of multiple storage adapters, enabling additional authors to help support Kafka, graphite, other adapters
|
81
|
+
- old require based loading, but working towards deprecating the entire baseline concept
|
82
|
+
- Introduces massive performance enhancements by moving to Ruby `Coverage` based collection
|
83
|
+
- Opposed to sampling this is now a reporting frequency, when using `Coverage` collector
|
84
|
+
- Reduced configuration complexity
|
85
|
+
- Refactoring the code preparing for more varied storage and reporting options
|
86
|
+
- Drop Redis as a gem runtime_dependency
|
71
87
|
|
72
88
|
### 1.5.0
|
73
89
|
|
74
90
|
This is a significant release with significant refactoring a stepping stone for a 2.0 release.
|
75
91
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
92
|
+
- staging a changes.md document!
|
93
|
+
- refactored out full abstraction for stores
|
94
|
+
- supports hit counts vs binary covered / not covered for lines
|
95
|
+
- this will let you find density of code usage just not if it was used
|
96
|
+
- this is a slight performance hit, so you can fall back to the old system if you want `redisstore.new(@redis, array: true)`
|
97
|
+
- this is the primary new feature in 1.5.0
|
98
|
+
- Redis has configurable base name, so I can safely change storage formats between releases
|
99
|
+
- improved documentation
|
100
|
+
- supports `SimpleCov.root`
|
101
|
+
- show files that were never touched
|
102
|
+
- apply coverband filters to ignore files in report not just collection
|
103
|
+
- improved test coverage
|
104
|
+
- improved benchmarks including support for multiple stores ;)
|
89
105
|
|
90
106
|
### 1.3.1
|
91
107
|
|
92
|
-
|
93
|
-
|
94
|
-
|
108
|
+
- This was a small fix release addressing some issues
|
109
|
+
- mostly readme updates
|
110
|
+
- last release prior to having a changes document!
|
data/coverband.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency 'benchmark-ips'
|
32
32
|
# add when debugging
|
33
33
|
# require 'byebug'; byebug
|
34
|
-
|
34
|
+
spec.add_development_dependency 'byebug'
|
35
35
|
# deprecate when dropping support for older ruby
|
36
36
|
spec.add_runtime_dependency 'json'
|
37
37
|
# todo make an optional dependency for simplecov reports
|
data/lib/coverband.rb
CHANGED
@@ -7,17 +7,15 @@ require 'coverband/version'
|
|
7
7
|
require 'coverband/configuration'
|
8
8
|
require 'coverband/adapters/base'
|
9
9
|
require 'coverband/adapters/redis_store'
|
10
|
-
require 'coverband/adapters/memory_cache_store'
|
11
10
|
require 'coverband/adapters/file_store'
|
12
|
-
require 'coverband/
|
13
|
-
require 'coverband/collectors/trace'
|
11
|
+
require 'coverband/utils/s3_report_writer'
|
14
12
|
require 'coverband/collectors/coverage'
|
15
13
|
require 'coverband/reporters/base'
|
16
14
|
require 'coverband/reporters/simple_cov_report'
|
17
15
|
require 'coverband/reporters/console_report'
|
18
16
|
require 'coverband/reporters/web'
|
19
|
-
require 'coverband/middleware'
|
20
|
-
require 'coverband/
|
17
|
+
require 'coverband/integrations/middleware'
|
18
|
+
require 'coverband/integrations/background'
|
21
19
|
|
22
20
|
module Coverband
|
23
21
|
CONFIG_FILE = './config/coverband.rb'
|
@@ -35,11 +33,16 @@ module Coverband
|
|
35
33
|
elsif File.exist?(configuration_file)
|
36
34
|
require configuration_file
|
37
35
|
else
|
38
|
-
|
36
|
+
msg = "configure requires a block, #{CONFIG_FILE} in project, or file path passed in configure"
|
37
|
+
raise ArgumentError, msg
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
42
41
|
def self.configuration
|
43
42
|
self.configuration_data ||= Configuration.new
|
44
43
|
end
|
44
|
+
|
45
|
+
def self.start
|
46
|
+
Coverband::Collectors::Coverage.instance
|
47
|
+
end
|
45
48
|
end
|
@@ -11,7 +11,7 @@ module Coverband
|
|
11
11
|
raise 'abstract'
|
12
12
|
end
|
13
13
|
|
14
|
-
def save_report(
|
14
|
+
def save_report(_report)
|
15
15
|
raise 'abstract'
|
16
16
|
end
|
17
17
|
|
@@ -23,9 +23,29 @@ module Coverband
|
|
23
23
|
raise 'abstract'
|
24
24
|
end
|
25
25
|
|
26
|
-
def covered_lines_for_file(
|
26
|
+
def covered_lines_for_file(_file)
|
27
27
|
raise 'abstract'
|
28
28
|
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def merge_reports(new_report, old_report)
|
33
|
+
keys = (new_report.keys + old_report.keys).uniq
|
34
|
+
keys.each do |file|
|
35
|
+
new_report[file] = if new_report[file] && old_report[file]
|
36
|
+
array_add(new_report[file], old_report[file])
|
37
|
+
elsif new_report[file]
|
38
|
+
new_report[file]
|
39
|
+
else
|
40
|
+
old_report[file]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
new_report
|
44
|
+
end
|
45
|
+
|
46
|
+
def array_add(latest, original)
|
47
|
+
latest.map.with_index { |v, i| (v && original[i]) ? v + original[i] : nil }
|
48
|
+
end
|
29
49
|
end
|
30
50
|
end
|
31
51
|
end
|
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
module Coverband
|
4
4
|
module Adapters
|
5
|
+
###
|
6
|
+
# FilesStore store a merged coverage file to local disk
|
7
|
+
# Generally this is for testing and development
|
8
|
+
# Not recommended for production deployment
|
9
|
+
###
|
5
10
|
class FileStore < Base
|
6
11
|
attr_accessor :path
|
7
12
|
|
@@ -17,17 +22,8 @@ module Coverband
|
|
17
22
|
end
|
18
23
|
|
19
24
|
def save_report(report)
|
20
|
-
|
21
|
-
report
|
22
|
-
if results.key?(file)
|
23
|
-
# convert the keys to "3" opposed to 3
|
24
|
-
values = JSON.parse(values.to_json)
|
25
|
-
results[file].merge!(values) { |_k, old_v, new_v| old_v.to_i + new_v.to_i }
|
26
|
-
else
|
27
|
-
results[file] = values
|
28
|
-
end
|
29
|
-
end
|
30
|
-
File.open(path, 'w') { |f| f.write(results.to_json) }
|
25
|
+
merge_reports(report, coverage)
|
26
|
+
save_coverage(report)
|
31
27
|
end
|
32
28
|
|
33
29
|
def coverage
|
@@ -46,6 +42,10 @@ module Coverband
|
|
46
42
|
|
47
43
|
private
|
48
44
|
|
45
|
+
def save_coverage(report)
|
46
|
+
File.open(path, 'w') { |f| f.write(report.to_json) }
|
47
|
+
end
|
48
|
+
|
49
49
|
def existing_data(path)
|
50
50
|
if File.exist?(path)
|
51
51
|
JSON.parse(File.read(path))
|
@@ -2,94 +2,59 @@
|
|
2
2
|
|
3
3
|
module Coverband
|
4
4
|
module Adapters
|
5
|
+
###
|
6
|
+
# RedisStore store a merged coverage file to redis
|
7
|
+
###
|
5
8
|
class RedisStore < Base
|
6
|
-
BASE_KEY = '
|
9
|
+
BASE_KEY = 'coverband3'
|
7
10
|
|
8
11
|
def initialize(redis, opts = {})
|
9
|
-
@redis
|
12
|
+
@redis = redis
|
10
13
|
@ttl = opts[:ttl]
|
11
14
|
@redis_namespace = opts[:redis_namespace]
|
12
15
|
end
|
13
16
|
|
14
17
|
def clear!
|
15
|
-
@redis.smembers(base_key).each { |key| @redis.del("#{base_key}.#{key}") }
|
16
18
|
@redis.del(base_key)
|
17
19
|
end
|
18
20
|
|
19
|
-
def base_key
|
20
|
-
@base_key ||= [BASE_KEY, @redis_namespace].compact.join('.')
|
21
|
-
end
|
22
|
-
|
23
21
|
def save_report(report)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
# Note: This could lead to slight races
|
23
|
+
# where multiple processes pull the old coverage and add to it then push
|
24
|
+
# the Coverband 2 had the same issue,
|
25
|
+
# and the tradeoff has always been acceptable
|
26
|
+
merge_reports(report, coverage)
|
27
|
+
save_coverage(base_key, report)
|
30
28
|
end
|
31
29
|
|
32
30
|
def coverage
|
33
|
-
|
34
|
-
redis.smembers(base_key).each do |key|
|
35
|
-
data[key] = covered_lines_for_file(key)
|
36
|
-
end
|
37
|
-
data
|
31
|
+
get_report(base_key)
|
38
32
|
end
|
39
33
|
|
40
34
|
def covered_files
|
41
|
-
|
35
|
+
coverage.keys
|
42
36
|
end
|
43
37
|
|
44
38
|
def covered_lines_for_file(file)
|
45
|
-
|
39
|
+
coverage[file]
|
46
40
|
end
|
47
41
|
|
48
42
|
private
|
49
43
|
|
50
44
|
attr_reader :redis
|
51
|
-
|
52
|
-
def pipelined_save(combined_report)
|
53
|
-
redis.pipelined do
|
54
|
-
combined_report.each do |file, values|
|
55
|
-
existing = values[:existing]
|
56
|
-
new = values[:new]
|
57
|
-
unless values.empty?
|
58
|
-
# in redis all file_keys are strings
|
59
|
-
new_string_values = Hash[new.map {|k, val| [k.to_s, val]}]
|
60
|
-
new_string_values.merge!(existing) {|_k, old_v, new_v| old_v.to_i + new_v.to_i}
|
61
|
-
redis.mapped_hmset(file, new_string_values)
|
62
|
-
redis.expire(file, @ttl) if @ttl
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
45
|
|
68
|
-
def
|
69
|
-
|
70
|
-
file_keys.each do |key|
|
71
|
-
redis.hgetall(key)
|
72
|
-
end
|
73
|
-
end
|
46
|
+
def base_key
|
47
|
+
@base_key ||= [BASE_KEY, @redis_namespace].compact.join('.')
|
74
48
|
end
|
75
49
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
file_keys.each_with_index do |key, i|
|
80
|
-
combined_report[key] = {
|
81
|
-
new: report.values[i],
|
82
|
-
existing: existing_records[i]
|
83
|
-
}
|
84
|
-
end
|
85
|
-
|
86
|
-
return combined_report
|
50
|
+
def save_coverage(key, data)
|
51
|
+
redis.set key, data.to_json
|
52
|
+
redis.expire(key, @ttl) if @ttl
|
87
53
|
end
|
88
54
|
|
89
|
-
def
|
90
|
-
redis.
|
91
|
-
|
92
|
-
values
|
55
|
+
def get_report(key)
|
56
|
+
data = redis.get key
|
57
|
+
data ? JSON.parse(data) : {}
|
93
58
|
end
|
94
59
|
end
|
95
60
|
end
|