oneshot_coverage 0.2.2 → 0.3.0
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/README.md +28 -9
- data/lib/oneshot_coverage.rb +45 -34
- data/lib/oneshot_coverage/logger/file_logger.rb +35 -0
- data/lib/oneshot_coverage/logger/null_logger.rb +0 -1
- data/lib/oneshot_coverage/logger/stdout_logger.rb +6 -5
- data/lib/oneshot_coverage/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b39908101b69a0d652f8219df289b541f44dd763586f938f714da7990aa801e
|
4
|
+
data.tar.gz: 9f71dd33954f1cc1e8e88f46a71cd99800f41afea57197851a9d4e46a9c98c49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf5c1b77da9e902783c2d62b65fb20827b78e7601cf9322ee0ac2802444d08db108a793634ae50a4891e1bf5809acb9203cd22fe7ad29351717f8f92787be56d
|
7
|
+
data.tar.gz: 9bad05fb306ccdf11c4ef94e8838f2eb63d24f69444c614439d578a812f2fd8decea5d8e3882256750c17fe8ec9b07f3539385d1c6bb89b01488449f27933a52
|
data/README.md
CHANGED
@@ -35,7 +35,7 @@ Or install it yourself as:
|
|
35
35
|
OneshotCoverage.configure(
|
36
36
|
target_path: '/base/project/path',
|
37
37
|
logger: OneshotCoverage::Logger::NullLogger.new,
|
38
|
-
|
38
|
+
emit_term: nil, # emit per `emit_term` seconds. It tries to emit per request when `nil`.
|
39
39
|
)
|
40
40
|
OneshotCoverage.start
|
41
41
|
```
|
@@ -44,25 +44,44 @@ As default, OneshotCoverage supports 2 logger.
|
|
44
44
|
|
45
45
|
- OneshotCoverage::Logger::NullLogger (default)
|
46
46
|
- OneshotCoverage::Logger::StdoutLogger
|
47
|
+
- OneshotCoverage::Logger::FileLogger
|
47
48
|
|
48
49
|
Only required interface is `#post` instance method, so you could implement
|
49
50
|
by yourself easily.
|
50
51
|
|
51
52
|
```ruby
|
52
|
-
class
|
53
|
-
def initialize
|
54
|
-
@
|
53
|
+
class FileLogger
|
54
|
+
def initialize(log_path)
|
55
|
+
@log_path = log_path
|
55
56
|
end
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
# new_logs: Struct.new(:path, :md5_hash, :lines)
|
59
|
+
def post(new_logs)
|
60
|
+
current_coverage = fetch
|
61
|
+
|
62
|
+
new_logs.each do |new_log|
|
63
|
+
key = "#{new_log.path}-#{new_log.md5_hash}"
|
64
|
+
|
65
|
+
logged_lines = current_coverage.fetch(key, [])
|
66
|
+
current_coverage[key] = logged_lines | new_log.lines
|
67
|
+
end
|
68
|
+
save(current_coverage)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def fetch
|
74
|
+
JSON.load(File.read(@log_path))
|
75
|
+
rescue Errno::ENOENT
|
76
|
+
{}
|
77
|
+
end
|
78
|
+
|
79
|
+
def save(data)
|
80
|
+
File.write(@log_path, JSON.dump(data))
|
59
81
|
end
|
60
82
|
end
|
61
83
|
```
|
62
84
|
|
63
|
-
Please note that it will retry to send data if `#post` returns falsy value.
|
64
|
-
Hence, make sure to return `true` if you don't want to retry.
|
65
|
-
|
66
85
|
### Emit logs
|
67
86
|
|
68
87
|
#### With rack application
|
data/lib/oneshot_coverage.rb
CHANGED
@@ -19,29 +19,50 @@ module OneshotCoverage
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
OneshotLog = Struct.new(:path, :md5_hash, :lines)
|
23
|
+
|
22
24
|
class Reporter
|
23
|
-
def initialize(target_path:, logger:,
|
25
|
+
def initialize(target_path:, logger:, emit_term: nil)
|
24
26
|
@target_path = target_path
|
25
27
|
@logger = logger
|
26
|
-
@
|
27
|
-
@
|
28
|
+
@emit_term = emit_term
|
29
|
+
if @emit_term
|
30
|
+
@next_emit_time = Time.now.to_i + rand(@emit_term)
|
31
|
+
end
|
32
|
+
|
28
33
|
if defined?(Bundler)
|
29
34
|
@bundler_path = Bundler.bundle_path.to_s
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
33
|
-
def emit
|
34
|
-
|
38
|
+
def emit(force_emit)
|
39
|
+
if !force_emit
|
40
|
+
if !time_to_emit?
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
logs =
|
46
|
+
Coverage.result(clear: true, stop: false).
|
35
47
|
select { |k, v| is_target?(k, v) }.
|
36
|
-
|
37
|
-
|
48
|
+
map do |filepath, v|
|
49
|
+
OneshotLog.new(relative_path(filepath), md5_hash_for(filepath), v[:oneshot_lines])
|
50
|
+
end
|
51
|
+
|
52
|
+
@logger.post(logs)
|
53
|
+
end
|
38
54
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
55
|
+
private
|
56
|
+
|
57
|
+
def time_to_emit?
|
58
|
+
if @emit_term
|
59
|
+
if @next_emit_time > Time.now.to_i
|
60
|
+
return false # Do not emit until next_emit_time
|
61
|
+
else
|
62
|
+
@next_emit_time += @emit_term
|
43
63
|
end
|
44
64
|
end
|
65
|
+
true
|
45
66
|
end
|
46
67
|
|
47
68
|
def is_target?(filepath, value)
|
@@ -51,30 +72,20 @@ module OneshotCoverage
|
|
51
72
|
true
|
52
73
|
end
|
53
74
|
|
54
|
-
def
|
55
|
-
|
56
|
-
md5_hash =
|
57
|
-
if md5_hash_cache.key?(filepath)
|
58
|
-
md5_hash_cache[filepath]
|
59
|
-
else
|
60
|
-
md5_hash_cache[filepath] = Digest::MD5.file(filepath).hexdigest
|
61
|
-
end
|
62
|
-
|
63
|
-
value[:oneshot_lines].map do |line|
|
64
|
-
{
|
65
|
-
path: rel_path,
|
66
|
-
md5_hash: md5_hash,
|
67
|
-
lineno: line
|
68
|
-
}
|
69
|
-
end
|
75
|
+
def relative_path(filepath)
|
76
|
+
filepath[@target_path.size..-1]
|
70
77
|
end
|
71
78
|
|
72
79
|
def md5_hash_cache
|
73
80
|
@md5_hash_cache ||= {}
|
74
81
|
end
|
75
82
|
|
76
|
-
def
|
77
|
-
|
83
|
+
def md5_hash_for(filepath)
|
84
|
+
if md5_hash_cache.key? filepath
|
85
|
+
md5_hash_cache[filepath]
|
86
|
+
else
|
87
|
+
md5_hash_cache[filepath] = Digest::MD5.file(filepath).hexdigest
|
88
|
+
end
|
78
89
|
end
|
79
90
|
end
|
80
91
|
|
@@ -85,15 +96,15 @@ module OneshotCoverage
|
|
85
96
|
|
86
97
|
# To handle execution with exit immediatly
|
87
98
|
at_exit do
|
88
|
-
OneshotCoverage.emit
|
99
|
+
OneshotCoverage.emit(force_emit: true)
|
89
100
|
end
|
90
101
|
end
|
91
102
|
|
92
|
-
def emit
|
93
|
-
@reporter&.emit
|
103
|
+
def emit(force_emit: false)
|
104
|
+
@reporter&.emit(force_emit)
|
94
105
|
end
|
95
106
|
|
96
|
-
def configure(target_path:, logger: OneshotCoverage::Logger::NullLogger.new,
|
107
|
+
def configure(target_path:, logger: OneshotCoverage::Logger::NullLogger.new, emit_term: nil)
|
97
108
|
target_path_by_pathname =
|
98
109
|
if target_path.is_a? Pathname
|
99
110
|
target_path
|
@@ -103,7 +114,7 @@ module OneshotCoverage
|
|
103
114
|
@reporter = OneshotCoverage::Reporter.new(
|
104
115
|
target_path: target_path_by_pathname.cleanpath.to_s + "/",
|
105
116
|
logger: logger,
|
106
|
-
|
117
|
+
emit_term: emit_term,
|
107
118
|
)
|
108
119
|
end
|
109
120
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module OneshotCoverage
|
4
|
+
module Logger
|
5
|
+
class FileLogger
|
6
|
+
def initialize(log_path)
|
7
|
+
@log_path = log_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def post(new_logs)
|
11
|
+
current_coverage = fetch
|
12
|
+
|
13
|
+
new_logs.each do |new_log|
|
14
|
+
key = "#{new_log.path}-#{new_log.md5_hash}"
|
15
|
+
|
16
|
+
logged_lines = current_coverage.fetch(key, [])
|
17
|
+
current_coverage[key] = logged_lines | new_log.lines
|
18
|
+
end
|
19
|
+
save(current_coverage)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def fetch
|
25
|
+
JSON.load(File.read(@log_path))
|
26
|
+
rescue Errno::ENOENT
|
27
|
+
{}
|
28
|
+
end
|
29
|
+
|
30
|
+
def save(data)
|
31
|
+
File.write(@log_path, JSON.dump(data))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module OneshotCoverage
|
2
2
|
module Logger
|
3
3
|
class StdoutLogger
|
4
|
-
def post(
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
def post(logs)
|
5
|
+
logs.each do |log|
|
6
|
+
$stdout.puts(
|
7
|
+
"[OneshotCoverage] logged path: #{log.path}, md5_hash: #{log.md5_hash}, executed_lines: #{log.lines}"
|
8
|
+
)
|
9
|
+
end
|
9
10
|
end
|
10
11
|
end
|
11
12
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oneshot_coverage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- bin/console
|
56
56
|
- bin/setup
|
57
57
|
- lib/oneshot_coverage.rb
|
58
|
+
- lib/oneshot_coverage/logger/file_logger.rb
|
58
59
|
- lib/oneshot_coverage/logger/null_logger.rb
|
59
60
|
- lib/oneshot_coverage/logger/stdout_logger.rb
|
60
61
|
- lib/oneshot_coverage/railtie.rb
|