oneshot_coverage 0.2.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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