oneshot_coverage 0.2.0 → 0.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 031ca916bcee96033586ba0e1c6f7a93129b8b758a1c297c9555d9de91bb14af
4
- data.tar.gz: 0dd69d9959a49fc94518926d498cb3350ec1d952de2887853fa09b0497011c2d
3
+ metadata.gz: d6573e60b68c3d682f2199237df98af49b7d9bd79ff7d117bf6edc07a773b15b
4
+ data.tar.gz: 0ccbec0f4e0bdfc3a807caf80be8080fb3e26ace5b261751c71d893190c4fa05
5
5
  SHA512:
6
- metadata.gz: 548640eb62924ec9d465fa6521c57fdf9cf1b2e63075a171bb24128d3dfbf8793e5f0165dd233ab898e7a9f7c63af431591eac5645fb1ed574d5a7dc26b7584a
7
- data.tar.gz: 1017152226c61dd4e2d588f59c62cd2a9a6b4f9a126dece207b27e0fc11281b164cd7456b7a12a6146464092d2d58966d417d40f1910536c5a817b6cdf4bd25d
6
+ metadata.gz: c8003ea1b0a4c6f5b7c23e0f250735085feabbf0cf1ac61c1f82872d7ae5528ed596506ba343ea9f812e2ea63e1032cdef33c5e903319179880d1fca2bd5e617
7
+ data.tar.gz: 460dab03da64b57a86986e143520dc4521ac2ebd4457d4acb23ca59cff129c66c8ed856293609ff3310d54a0b47ff658da3cc47fb1d09d86f66b8bd5569586cf
data/.gitignore CHANGED
@@ -41,6 +41,7 @@ Temporary Items
41
41
  /test/tmp/
42
42
  /test/version_tmp/
43
43
  /tmp/
44
+ Gemfile.lock
44
45
 
45
46
  # Used by dotenv library to load environment variables.
46
47
  # .env
data/README.md CHANGED
@@ -35,6 +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
+ emit_term: nil, # emit per `emit_term` seconds. It tries to emit per request when `nil`.
38
39
  )
39
40
  OneshotCoverage.start
40
41
  ```
@@ -43,18 +44,40 @@ As default, OneshotCoverage supports 2 logger.
43
44
 
44
45
  - OneshotCoverage::Logger::NullLogger (default)
45
46
  - OneshotCoverage::Logger::StdoutLogger
47
+ - OneshotCoverage::Logger::FileLogger
46
48
 
47
49
  Only required interface is `#post` instance method, so you could implement
48
50
  by yourself easily.
49
51
 
50
52
  ```ruby
51
- class SampleFluentLogger
52
- def initialize
53
- @logger = Fluent::Logger::FluentLogger.new('tag_prefix')
53
+ class FileLogger
54
+ def initialize(log_path)
55
+ @log_path = log_path
54
56
  end
55
57
 
56
- def post(path:, md5_hash:, lineno:)
57
- @logger.post(nil, path: path, md5_hash: md5_hash, lineno: lineno)
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))
58
81
  end
59
82
  end
60
83
  ```
@@ -19,24 +19,52 @@ 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:, max_emit_per_request:)
25
+ def initialize(target_path:, logger:, emit_term: nil)
24
26
  @target_path = target_path
25
27
  @logger = logger
26
- @buffer = []
27
- @max_emit_per_request = max_emit_per_request
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
- Coverage.result(clear: true, stop: false).
38
+ def emit(force_emit)
39
+ if !force_emit
40
+ if !time_to_emit?
41
+ return
42
+ end
43
+ end
44
+
45
+ logs =
46
+ Coverage.result(clear: true, stop: false).
35
47
  select { |k, v| is_target?(k, v) }.
36
- flat_map { |k, v| transform(k, v) }.
37
- each { |row| @buffer << row }
48
+ map do |filepath, v|
49
+ OneshotLog.new(relative_path(filepath), md5_hash_for(filepath), v[:oneshot_lines])
50
+ end
38
51
 
39
- @buffer.shift(emit_per_request).each { |row| @logger.post(row) }
52
+ if logs.size > 0
53
+ @logger.post(logs)
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def time_to_emit?
60
+ if @emit_term
61
+ if @next_emit_time > Time.now.to_i
62
+ return false # Do not emit until next_emit_time
63
+ else
64
+ @next_emit_time += @emit_term
65
+ end
66
+ end
67
+ true
40
68
  end
41
69
 
42
70
  def is_target?(filepath, value)
@@ -46,30 +74,20 @@ module OneshotCoverage
46
74
  true
47
75
  end
48
76
 
49
- def transform(filepath, value)
50
- rel_path = filepath[@target_path.size..]
51
- md5_hash =
52
- if md5_hash_cache.key?(filepath)
53
- md5_hash_cache[filepath]
54
- else
55
- md5_hash_cache[filepath] = Digest::MD5.file(filepath).hexdigest
56
- end
57
-
58
- value[:oneshot_lines].map do |line|
59
- {
60
- path: rel_path,
61
- md5_hash: md5_hash,
62
- lineno: line
63
- }
64
- end
77
+ def relative_path(filepath)
78
+ filepath[@target_path.size..-1]
65
79
  end
66
80
 
67
81
  def md5_hash_cache
68
82
  @md5_hash_cache ||= {}
69
83
  end
70
84
 
71
- def emit_per_request
72
- @max_emit_per_request || @buffer.size
85
+ def md5_hash_for(filepath)
86
+ if md5_hash_cache.key? filepath
87
+ md5_hash_cache[filepath]
88
+ else
89
+ md5_hash_cache[filepath] = Digest::MD5.file(filepath).hexdigest
90
+ end
73
91
  end
74
92
  end
75
93
 
@@ -80,15 +98,15 @@ module OneshotCoverage
80
98
 
81
99
  # To handle execution with exit immediatly
82
100
  at_exit do
83
- OneshotCoverage.emit
101
+ OneshotCoverage.emit(force_emit: true)
84
102
  end
85
103
  end
86
104
 
87
- def emit
88
- @reporter&.emit
105
+ def emit(force_emit: false)
106
+ @reporter&.emit(force_emit)
89
107
  end
90
108
 
91
- def configure(target_path:, logger: OneshotCoverage::Logger::NullLogger.new, max_emit_per_request: nil)
109
+ def configure(target_path:, logger: OneshotCoverage::Logger::NullLogger.new, emit_term: nil)
92
110
  target_path_by_pathname =
93
111
  if target_path.is_a? Pathname
94
112
  target_path
@@ -98,7 +116,7 @@ module OneshotCoverage
98
116
  @reporter = OneshotCoverage::Reporter.new(
99
117
  target_path: target_path_by_pathname.cleanpath.to_s + "/",
100
118
  logger: logger,
101
- max_emit_per_request: max_emit_per_request
119
+ emit_term: emit_term,
102
120
  )
103
121
  end
104
122
  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,10 +1,12 @@
1
1
  module OneshotCoverage
2
2
  module Logger
3
3
  class StdoutLogger
4
- def post(path:, md5_hash:, lineno:)
5
- $stdout.puts(
6
- "[OneshotCoverage] logged path: #{path}, md5_hash: #{md5_hash}, lineno: #{lineno}"
7
- )
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
8
10
  end
9
11
  end
10
12
  end
@@ -1,3 +1,3 @@
1
1
  module OneshotCoverage
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -37,6 +37,6 @@ Gem::Specification.new do |spec|
37
37
  # Release ruby version lock temperary
38
38
  # spec.required_ruby_version = '>= 2.6'
39
39
 
40
- spec.add_development_dependency "bundler", "~> 1.17"
41
- spec.add_development_dependency "rake", "~> 10.0"
40
+ spec.add_development_dependency "bundler", "~> 2.1"
41
+ spec.add_development_dependency "rake", "~> 13.0"
42
42
  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.2.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-20 00:00:00.000000000 Z
11
+ date: 2020-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '2.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '13.0'
41
41
  description: OneshotCoverage will help you to measure oneshot coverage on production
42
42
  email:
43
43
  - rise.shia@gmail.com
@@ -48,13 +48,13 @@ files:
48
48
  - ".gitignore"
49
49
  - CODE_OF_CONDUCT.md
50
50
  - Gemfile
51
- - Gemfile.lock
52
51
  - LICENSE.txt
53
52
  - README.md
54
53
  - Rakefile
55
54
  - bin/console
56
55
  - bin/setup
57
56
  - lib/oneshot_coverage.rb
57
+ - lib/oneshot_coverage/logger/file_logger.rb
58
58
  - lib/oneshot_coverage/logger/null_logger.rb
59
59
  - lib/oneshot_coverage/logger/stdout_logger.rb
60
60
  - lib/oneshot_coverage/railtie.rb
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  requirements: []
85
- rubygems_version: 3.0.3
85
+ rubygems_version: 3.1.2
86
86
  signing_key:
87
87
  specification_version: 4
88
88
  summary: Simple toolbox for oneshot coverage
@@ -1,20 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- oneshot_coverage (0.1.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- rake (10.5.0)
10
-
11
- PLATFORMS
12
- ruby
13
-
14
- DEPENDENCIES
15
- bundler (~> 1.17)
16
- oneshot_coverage!
17
- rake (~> 10.0)
18
-
19
- BUNDLED WITH
20
- 1.17.2