danger-compose_compiler_metrics 0.0.2 → 0.0.4

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: 5174bc2092a2c48fa3a84c6cb7006b0836fc9ccdc55f647efad88cc3fbd52e65
4
- data.tar.gz: de4c9958f624409b65e36aa49d5b001de6f474e79c43afe51a42011f1150ac91
3
+ metadata.gz: 8b9f0973e51bb4416bad39bb523c7d0b9e81828aa750c435fbdfe2b471857a48
4
+ data.tar.gz: cffa918441edcfa7bbd58e0d994a508c32abb22679194af550836e5edd5cb294
5
5
  SHA512:
6
- metadata.gz: 4543a2ecc312efe6d7357acaf70e19bf84d4f2938cc525b9c33db740f04aee929acc7c2cdd17a98c5cb112bb3d3595654ac92498d3bf5de665e246608ea7e3b3
7
- data.tar.gz: 77d0f263a40a8286b3b36cc6a3dc2bf6b3dff3370e91717d5bdefd4ed824ddecb067c8f14a9c70c1e8d000a35867817e66895f16701d9f653cef050f86fb251b
6
+ metadata.gz: c171857c7292b8b335c143721da0bc3cf8b38dd28de677b33bf210d49346908ebde5ae5e073151c7c47f1016d5d79f34c799aa1a077ee476312033a2d2b08862
7
+ data.tar.gz: 2b4451fb0c7150296ab5c71ead7711584816412349afc8195631016121a2c2cab87bc6eb423b3ee8f681a19d3064492420f13a91578888cff648059ae4ff6ddc
@@ -0,0 +1,47 @@
1
+ name: test
2
+ on: [push]
3
+ jobs:
4
+ run:
5
+ runs-on: ubuntu-latest
6
+ timeout-minutes: 5
7
+
8
+ container:
9
+ image: ruby:3.0
10
+ options: --user 1001
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Restore gem cache
20
+ uses: actions/cache/restore@v4
21
+ with:
22
+ key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
23
+ path: |
24
+ vendor/bundle
25
+ restore-keys: |
26
+ ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
27
+ ${{ runner.os }}-gem-
28
+ ${{ runner.os }}-
29
+
30
+ - name: Bundle install
31
+ run: |
32
+ bundle config set path 'vendor/bundle'
33
+ bundle config set clean 'true'
34
+ bundle install --jobs 4 --retry 3
35
+
36
+ - name: Save gem cache
37
+ uses: actions/cache/save@v4
38
+ with:
39
+ path: |
40
+ vendor/bundle
41
+ key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
42
+
43
+ - name: Run rubocop
44
+ run: bundle exec rubocop
45
+
46
+ - name: Run rspec
47
+ run: bundle exec rspec
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@
3
3
  # If you don't like these settings, just delete this file :)
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.7
6
+ TargetRubyVersion: 3.0
7
7
 
8
8
  Style/StringLiterals:
9
9
  EnforcedStyle: double_quotes
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.0.6
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- danger-compose_compiler_metrics (0.0.1)
4
+ danger-compose_compiler_metrics (0.0.4)
5
5
  csv
6
6
  danger-plugin-api (~> 1.0)
7
7
  json
@@ -98,7 +98,7 @@ GEM
98
98
  public_suffix (5.0.4)
99
99
  racc (1.7.3)
100
100
  rainbow (3.1.1)
101
- rake (10.5.0)
101
+ rake (13.1.0)
102
102
  rb-fsevent (0.11.2)
103
103
  rb-inotify (0.10.1)
104
104
  ffi (~> 1.0)
@@ -154,7 +154,7 @@ DEPENDENCIES
154
154
  guard-rspec (~> 4.7)
155
155
  listen (= 3.0.7)
156
156
  pry
157
- rake (~> 10.0)
157
+ rake
158
158
  rspec (~> 3.4)
159
159
  rubocop
160
160
  yard
@@ -19,13 +19,15 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ["lib"]
21
21
 
22
+ spec.required_ruby_version = "~> 3.0"
23
+
24
+ spec.add_runtime_dependency "csv"
22
25
  spec.add_runtime_dependency "danger-plugin-api", "~> 1.0"
23
26
  spec.add_runtime_dependency "json"
24
- spec.add_runtime_dependency "csv"
25
27
 
26
28
  # General ruby development
27
29
  spec.add_development_dependency "bundler", "~> 2.0"
28
- spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "rake"
29
31
 
30
32
  # Testing support
31
33
  spec.add_development_dependency "rspec", "~> 3.4"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ComposeCompilerMetrics
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.4"
5
5
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Helper
2
4
  def build_variants(dir)
3
5
  Dir.glob("#{dir}/*").
4
- map { |s| File.basename(s).split(/[_\-]/).take(2) }.
6
+ map { |s| File.basename(s).split(/[_-]/).take(2) }.
5
7
  uniq
6
8
  end
7
9
 
@@ -31,9 +33,11 @@ module Helper
31
33
  end.join("\n")
32
34
  end
33
35
 
34
- def folding(summary, details)
36
+ def folding(summary, details, open)
37
+ open_attribute = open == :open ? "open" : ""
38
+
35
39
  <<~HTML
36
- <details>
40
+ <details #{open_attribute}>
37
41
  <summary>
38
42
 
39
43
  #{summary}
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ class Metrics
6
+ attr_reader :hash
7
+
8
+ def initialize(hash)
9
+ @hash = hash
10
+ end
11
+
12
+ def keys
13
+ to_h.keys
14
+ end
15
+
16
+ def grouping_keys
17
+ keys.map { |key| grouping_key(key) }.uniq
18
+ end
19
+
20
+ def grouped_metrics
21
+ hash.
22
+ group_by { |k, _| grouping_key(k) }.
23
+ transform_values { |array| Metrics.new(array.to_h) }
24
+ end
25
+
26
+ def to_h
27
+ hash
28
+ end
29
+
30
+ def respond_to_missing?(method_name, include_private)
31
+ hash.key?(method_name.to_s) || hash.key?(convert_to_metrics_key(method_name)) || super
32
+ end
33
+
34
+ def method_missing(method_name)
35
+ return hash[method_name.to_s] if hash.key?(method_name.to_s)
36
+
37
+ key = convert_to_metrics_key(method_name)
38
+ return hash[key] if hash.key?(key)
39
+
40
+ super method_name
41
+ end
42
+
43
+ def self.load(path)
44
+ Loader.new(path).load
45
+ end
46
+
47
+ def ==(other)
48
+ hash == other.hash
49
+ end
50
+
51
+ class Loader
52
+ attr_reader :path
53
+
54
+ def initialize(path)
55
+ @path = path
56
+ end
57
+
58
+ def metrics_hash
59
+ @metrics_hash ||= JSON.parse(File.read(path))
60
+ end
61
+
62
+ def load
63
+ advanced_metrics_hash = metrics_hash.each.with_object({}) do |(k, v), h|
64
+ h[k] = v
65
+
66
+ case k
67
+ when "skippableComposables"
68
+ h["unskippableComposables"] = metrics_hash["totalComposables"] - metrics_hash["skippableComposables"]
69
+ when "restartableComposables"
70
+ h["unrestartableComposables"] = metrics_hash["totalComposables"] - metrics_hash["restartableComposables"]
71
+ end
72
+ end
73
+
74
+ Metrics.new(advanced_metrics_hash)
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def grouping_key(key)
81
+ to_snake_case(key).split("_").last.capitalize
82
+ end
83
+
84
+ def to_small_camel_case(str)
85
+ str.to_s.split("_").each_with_index.map { |s, i| i.zero? ? s : s.capitalize }.join
86
+ end
87
+ alias convert_to_metrics_key to_small_camel_case
88
+
89
+ def to_snake_case(str)
90
+ str.gsub(/::/, "/")
91
+ .gsub(/([A-Z]+)([A-Z][a-z])/, "\\1_\\2")
92
+ .gsub(/([a-z\d])([A-Z])/, "\\1_\\2")
93
+ .tr("-", "_")
94
+ .downcase
95
+ end
96
+ end
@@ -1,17 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'csv'
3
+ require "json"
4
+ require "csv"
5
5
 
6
- require_relative './helper'
6
+ require_relative "./helper"
7
+ require_relative "./metrics"
7
8
 
8
9
  module Danger
9
10
  class DangerComposeCompilerMetrics < Plugin
10
11
  include Helper
11
12
 
12
- def report_difference(metrics_dir, base_metrics_dir)
13
+ def report_difference(metrics_dir, reference_metrics_dir, options = {})
13
14
  unless installed?("diff")
14
- error "diff command not found. Please install diff command."
15
+ failure "diff command not found. Please install diff command."
15
16
  return
16
17
  end
17
18
 
@@ -21,38 +22,93 @@ module Danger
21
22
 
22
23
  # Metrics Report
23
24
  metrics_path = File.join(metrics_dir, metrics_filename(module_name, build_variant))
24
- base_metrics_path = File.join(base_metrics_dir, metrics_filename(module_name, build_variant))
25
- report_file_difference("Metrics", metrics_path, base_metrics_path)
25
+ reference_metrics_path = File.join(reference_metrics_dir, metrics_filename(module_name, build_variant))
26
+
27
+ report_metrics_report("Metrics Summary", metrics_path, reference_metrics_path, options[:metrics_summary])
28
+ report_file_difference("Metrics", metrics_path, reference_metrics_path, options[:metrics])
26
29
 
27
30
  # Composable Stats Report
28
31
  composable_stats_report_path = File.join(metrics_dir, composable_stats_report_path(module_name, build_variant))
29
- base_composable_stats_report_path = File.join(base_metrics_dir, composable_stats_report_path(module_name, build_variant))
30
- report_file_difference("Composable Stats Report", composable_stats_report_path, base_composable_stats_report_path)
32
+ reference_composable_stats_report_path = File.join(reference_metrics_dir, composable_stats_report_path(module_name, build_variant))
33
+ report_file_difference("Composable Stats Report", composable_stats_report_path, reference_composable_stats_report_path, options[:composable_stats])
31
34
 
32
35
  # Composable Report
33
36
  composable_report_path = File.join(metrics_dir, composable_report_path(module_name, build_variant))
34
- base_composable_report_path = File.join(base_metrics_dir, composable_report_path(module_name, build_variant))
35
- report_file_difference("Composable Report", composable_report_path, base_composable_report_path)
37
+ reference_composable_report_path = File.join(reference_metrics_dir, composable_report_path(module_name, build_variant))
38
+ report_file_difference("Composable Report", composable_report_path, reference_composable_report_path, options[:composable_report])
36
39
 
37
40
  # Class Report
38
41
  class_report_path = File.join(metrics_dir, class_report_path(module_name, build_variant))
39
- base_class_report_path = File.join(base_metrics_dir, class_report_path(module_name, build_variant))
40
- report_file_difference("Composable Report", class_report_path, base_class_report_path)
42
+ reference_class_report_path = File.join(reference_metrics_dir, class_report_path(module_name, build_variant))
43
+ report_file_difference("Class Report", class_report_path, reference_class_report_path, options[:class_report])
44
+ end
45
+ end
46
+
47
+ def report_metrics_report(title, metrics_path, reference_metrics_path, open)
48
+ open ||= :close
49
+ return if open == :disabled
50
+
51
+ unless File.exist?(metrics_path)
52
+ warn "DangerComposeCompilerMetrics: new file not found at #{metrics_path}. Skipping file difference report."
53
+ return
54
+ end
55
+
56
+ unless File.exist?(reference_metrics_path)
57
+ warn "DangerComposeCompilerMetrics: reference file not found at #{reference_metrics_path}. Skipping file difference report."
58
+ return
59
+ end
60
+
61
+ metrics = Metrics.load(metrics_path)
62
+ reference_metrics = Metrics.load(reference_metrics_path)
63
+
64
+ tables = reference_metrics.grouped_metrics.map do |group_key, grouped_reference_metrics|
65
+ grouped_metrics = metrics.grouped_metrics[group_key]
66
+
67
+ table_headers = %w(name reference new diff)
68
+ table_rows = grouped_reference_metrics.keys.map do |key|
69
+ new_value = grouped_metrics.send(key.to_sym)
70
+ reference_value = grouped_reference_metrics.send(key.to_sym)
71
+ diff_value = (new_value - reference_value).then do |v|
72
+ next "+#{v}" if v.positive?
73
+
74
+ next v.to_s if v.negative?
75
+
76
+ ""
77
+ end
78
+
79
+ [key, reference_value, new_value, diff_value]
80
+ end
81
+
82
+ [
83
+ "#### #{group_key}",
84
+ build_markdown_table(table_headers, table_rows)
85
+ ].join("\n\n")
41
86
  end
87
+
88
+ markdown(
89
+ folding(
90
+ "### #{title}",
91
+ tables.join("\n\n"),
92
+ open
93
+ )
94
+ )
42
95
  end
43
96
 
44
- def report_file_difference(title, metrics_path, base_metrics_path)
97
+ def report_file_difference(title, metrics_path, reference_metrics_path, open)
98
+ open ||= :close
99
+ return if open == :disabled
100
+
45
101
  unless File.exist?(metrics_path)
46
102
  warn "DangerComposeCompilerMetrics: new file not found at #{metrics_path}. Skipping file difference report."
47
103
  return
48
104
  end
49
105
 
50
- unless File.exist?(base_metrics_path)
51
- warn "DangerComposeCompilerMetrics: reference file not found at #{base_metrics_path}. Skipping file difference report."
106
+ unless File.exist?(reference_metrics_path)
107
+ warn "DangerComposeCompilerMetrics: reference file not found at #{reference_metrics_path}. Skipping file difference report."
52
108
  return
53
109
  end
54
110
 
55
- report = `diff -u #{base_metrics_path} #{metrics_path}`
111
+ report = `diff -u #{reference_metrics_path} #{metrics_path}`
56
112
 
57
113
  markdown(
58
114
  folding(
@@ -65,65 +121,64 @@ module Danger
65
121
  #{report}
66
122
  ```
67
123
  MARKDOWN
68
- end
124
+ end,
125
+ open
69
126
  )
70
127
  )
71
128
  end
72
129
 
73
- def report(metrics_dir)
74
- markdown('# Compose Compiler Metrics Report')
130
+ def report(metrics_dir, options = {})
131
+ markdown("# Compose Compiler Metrics Report")
75
132
  build_variants(metrics_dir).each do |module_name, build_variant|
76
133
  markdown("## #{module_name} - #{build_variant}")
77
134
 
78
135
  # Metrics Report
79
136
  metrics_path = File.join(metrics_dir, metrics_filename(module_name, build_variant))
80
- table_headers = %w[name value]
137
+ table_headers = %w(name value)
81
138
  table_rows = JSON.load_file(metrics_path).to_a
82
-
83
- markdown(
84
- folding(
85
- '### Metrics',
86
- build_markdown_table(table_headers, table_rows)
87
- )
88
- )
139
+ report_table("Metrics", table_headers, table_rows, options[:metrics])
89
140
 
90
141
  # Composable Stats Report
91
142
  composable_stats_report_path = File.join(metrics_dir, composable_stats_report_path(module_name, build_variant))
92
143
  csv = CSV.read(composable_stats_report_path, headers: true)
93
-
94
- markdown(
95
- folding(
96
- '### Composable Stats Report',
97
- build_markdown_table(csv.headers, csv.map(&:fields))
98
- )
99
- )
144
+ report_table("Composable Stats Report", csv.headers, csv.map(&:fields), options[:composable_stats])
100
145
 
101
146
  # Composable Report
102
147
  composable_report_path = File.join(metrics_dir, composable_report_path(module_name, build_variant))
103
- markdown(
104
- folding(
105
- '### Composable Report',
106
- <<~MARKDOWN
107
- ```kotlin
108
- #{File.read(composable_report_path)}
109
- ```
110
- MARKDOWN
111
- )
112
- )
148
+ report_code_block("Composable Report", "kotlin", File.read(composable_report_path), options[:composable_report])
113
149
 
114
150
  # Class Report
115
151
  class_report_path = File.join(metrics_dir, class_report_path(module_name, build_variant))
116
- markdown(
117
- folding(
118
- '### Class Report',
119
- <<~MARKDOWN
120
- ```kotlin
121
- #{File.read(class_report_path)}
122
- ```
123
- MARKDOWN
124
- )
125
- )
152
+ report_code_block("Class Report", "kotlin", File.read(class_report_path), options[:class_report])
126
153
  end
127
154
  end
155
+
156
+ def report_table(title, headers, rows, open)
157
+ return if open == :disabled
158
+
159
+ markdown(
160
+ folding(
161
+ "### #{title}",
162
+ build_markdown_table(headers, rows),
163
+ open
164
+ )
165
+ )
166
+ end
167
+
168
+ def report_code_block(title, language, code, open)
169
+ return if open == :disabled
170
+
171
+ markdown(
172
+ folding(
173
+ "### #{title}",
174
+ <<~MARKDOWN,
175
+ ```#{language}
176
+ #{code}
177
+ ```
178
+ MARKDOWN
179
+ open
180
+ )
181
+ )
182
+ end
128
183
  end
129
184
  end