akainaa 0.1.2 → 0.1.6

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: 6451f71725cda32349ab87402b32e6e132d8185274ba55a930fa2389fdd12279
4
- data.tar.gz: 2b40049516aa512d8a89b607d327b1a5571b3c4221e351248d4ac13bbdc31dfd
3
+ metadata.gz: 423527610c1fbb25d01ddfb555e6ea40f8a943001b04dc399682937353529a23
4
+ data.tar.gz: 70aab5713abf80fc2dd41783fb56b6e223d2d2549438640ca4916bf2f413cba6
5
5
  SHA512:
6
- metadata.gz: f3199e1047c1295040cf043154128fcef145da13815f1cf8b69c84ec4a3237e44c525107ccb97abcc115d9d12f810e40623685843e190bb07cb99f95e35b104d
7
- data.tar.gz: 74c12cf59e645eef87f2811d95d584a32ed5ec54b6f75019114c8f595fa206e0121cf7413c87a3b53fb4523f62cc7b45ee004aab467594f4dffd2153af00d045
6
+ metadata.gz: 35978a5f110960e9c5f37e5d025efb6c40307fae6e4979a4e01f368802e230d8d3ae338f4dd1ef0370a8d69d66bbddd96d5860c65e559e49e0f56b52696cf14b
7
+ data.tar.gz: 92c0ac588743097d660462ee452438cbd3c98ae0933525689e4024b592c815dfc36e7696dffb4d3f33e44505d6d1ea291f7307b103013e29c6d70e066b9262b4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.6] - 2024-09-11
4
+
5
+ - Feature: Add `clear` flag on first emit
6
+ - Feature: Add `trap_at_exit` option to `Akainaa.start` method
7
+ - Feature: Do not emit regularly if interval is 0 or nil
8
+
9
+ ## [0.1.5] - 2024-09-10
10
+
11
+ - Bug fix: nested method call won't handled
12
+ - Bug fix: Empty 302 response body on /akainaa/reset
13
+ - Feature: Add `ignore_glob_patterns` option to `Akainaa.start` method
14
+ - Feature: Add `hide_not_executed_files` option to `Akainaa.start` method
15
+ - Feature: Add `online_emit` option to `Akainaa.start` method
16
+
3
17
  ## [0.1.2] - 2024-05-06
4
18
 
5
19
  - Coloring all line of the method which located on multiple lines
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Akainaa (赤いなぁ)
1
+ # Akainaa (赤いなぁ、 It's red...)
2
2
 
3
3
  ![page view](./img/webui-rev02.png)
4
4
 
@@ -28,7 +28,13 @@ Here is example:
28
28
  ```ruby
29
29
  require 'akainaa'
30
30
 
31
- Akainaa.start(project_dir: File.expand_path(__dir__))
31
+ Akainaa.start(
32
+ project_dir: File.expand_path(__dir__),
33
+ ignore_glob_patterns: %w[
34
+ config/application.rb
35
+ config/initializers/*_initializer.rb
36
+ ],
37
+ )
32
38
 
33
39
  require_relative 'app'
34
40
 
@@ -39,6 +45,27 @@ run App
39
45
  Boot up application, do something, and access `/akainaa`.
40
46
  It will show Web UI what and how many executed.
41
47
 
48
+ ### Enable online emit mode
49
+
50
+ Akainaa can emit coverage data which recorded in interval to the file.
51
+ This feature is intended to be used with vscode-akainaa extension.
52
+
53
+ ```ruby
54
+ Akainaa.start(
55
+ project_dir: File.expand_path(__dir__),
56
+ ignore_glob_patterns: %w[
57
+ config/application.rb
58
+ config/initializers/*_initializer.rb
59
+ ],
60
+ online_emit: {
61
+ mode: :file,
62
+ interval: 1, # seconds
63
+ output_path: '/tmp/akainaa.json',
64
+ trap_at_exit: true,
65
+ },
66
+ )
67
+ ```
68
+
42
69
  ## Development
43
70
 
44
71
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/akainaa/util.rb CHANGED
@@ -19,6 +19,7 @@ module Akainaa
19
19
 
20
20
  visitor.multiline_method_calls.each do |method_range|
21
21
  call_count = lines[method_range.start_line_as_idx]
22
+ next if call_count.nil?
22
23
 
23
24
  method_range.method_row_range_as_idx.each do |idx|
24
25
  if fullfilled_lines[idx].nil?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Akainaa
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.6"
5
5
  end
data/lib/akainaa.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'coverage'
4
+ require 'fileutils'
4
5
 
5
6
  require_relative 'akainaa/version'
6
7
  require_relative 'akainaa/call_node_visitor'
@@ -10,24 +11,111 @@ module Akainaa
10
11
  class Error < StandardError; end
11
12
 
12
13
  class << self
13
- attr_accessor :project_dir
14
-
15
- def start(project_dir:)
14
+ attr_accessor :project_dir, :ignore_files, :hide_not_executed_files
15
+
16
+ def start(
17
+ project_dir:,
18
+ ignore_glob_patterns: [],
19
+ hide_not_executed_files: false,
20
+ online_emit: nil
21
+ )
16
22
  @project_dir = project_dir
17
23
  @project_dir += '/' unless @project_dir.end_with?('/')
24
+ ignore_files = ignore_glob_patterns.flat_map do |pattern|
25
+ Dir["#{@project_dir}#{pattern}"].to_a
26
+ end
27
+ @ignore_files = Set.new(ignore_files)
28
+ @hide_not_executed_files = hide_not_executed_files
29
+ @monitor = Monitor.new
30
+ @first_emitted = false
18
31
 
19
32
  Coverage.start(lines: true)
33
+
34
+ if online_emit.is_a?(Hash)
35
+ option = default_online_emit.merge(online_emit)
36
+ FileUtils.mkdir_p(File.dirname(option[:path]))
37
+ start_multipart_emit(option)
38
+
39
+ if option[:trap_at_exit]
40
+ at_exit do
41
+ write_result(peek_result, option[:path])
42
+ end
43
+ end
44
+ end
20
45
  end
21
46
 
22
47
  def peek_result
23
48
  Coverage
24
49
  .peek_result
25
50
  .select { |k, _v| k.start_with?(project_dir) }
51
+ .reject { |k, _v| ignore_files.member?(k) }
26
52
  .transform_keys { |k| k.sub(project_dir, '') }
27
53
  end
28
54
 
29
55
  def reset
30
- Coverage.result(stop: false, clear: true)
56
+ @monitor.synchronize do
57
+ Coverage.result(stop: false, clear: true)
58
+ @previous_result = {}
59
+ end
60
+ end
61
+
62
+ private def write_result(result, path)
63
+ puts "Writing coverage result to #{path}"
64
+ unless @first_emitted
65
+ puts "with clear flag"
66
+ result['clear'] = true
67
+ end
68
+ File.write(path, result.to_json)
69
+ @first_emitted = true
70
+ end
71
+
72
+ private def default_online_emit
73
+ {
74
+ mode: :file,
75
+ interval: 1,
76
+ path: 'tmp/coverage.json',
77
+ trap_at_exit: true,
78
+ }
79
+ end
80
+
81
+ private def start_multipart_emit(option)
82
+ return if option[:interval].nil? || option[:interval] <= 0
83
+
84
+ Thread.new do
85
+ @monitor.synchronize do
86
+ @previous_result = {}
87
+ end
88
+
89
+ loop do
90
+ sleep option[:interval]
91
+ current_result = peek_result
92
+
93
+ diff = {}
94
+ current_result.each do |path, path_coverage|
95
+ previous_path_coverage = @previous_result[path]
96
+
97
+ if previous_path_coverage.nil?
98
+ diff[path] = path_coverage
99
+ elsif previous_path_coverage[:lines].size != path_coverage[:lines].size
100
+ diff[path] = path_coverage
101
+ else
102
+ diff[path] = { lines: [] }
103
+
104
+ path_coverage[:lines].each_with_index do |count, index|
105
+ val = count ? count - previous_path_coverage[:lines][index] : nil
106
+
107
+ diff[path][:lines] << val
108
+ end
109
+ end
110
+ end
111
+
112
+ @monitor.synchronize do
113
+ @previous_result = current_result
114
+ end
115
+
116
+ write_result(diff, option[:path])
117
+ end
118
+ end
31
119
  end
32
120
  end
33
121
 
@@ -48,7 +136,7 @@ module Akainaa
48
136
  path = extract_path_from_query(env)
49
137
  Akainaa.reset
50
138
 
51
- [302, { 'Location' => "/akainaa?path=#{path}" }, [html]]
139
+ [302, { 'Location' => "/akainaa?path=#{path}" }, []]
52
140
  else
53
141
  @app.call(env)
54
142
  end
@@ -83,6 +171,8 @@ module Akainaa
83
171
 
84
172
  li_elements = files.sort.map do |file|
85
173
  total_count_on_file = coverage_result[file][:lines].reject(&:nil?).sum
174
+ next '' if Akainaa.hide_not_executed_files && total_count_on_file == 0
175
+
86
176
  count_top = (total_count_on_file * 10 / max_count_on_proj).to_i * 10
87
177
 
88
178
  class_suffix = file == current_path ? ' current' : ''
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: akainaa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shia
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-06 00:00:00.000000000 Z
11
+ date: 2024-09-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Minimum rack middleware for coverage
14
14
  email:
@@ -47,7 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  - !ruby/object:Gem::Version
48
48
  version: '0'
49
49
  requirements: []
50
- rubygems_version: 3.6.0.dev
50
+ rubygems_version: 3.5.11
51
51
  signing_key:
52
52
  specification_version: 4
53
53
  summary: Minimum rack middleware for coverage