danger-compose_compiler_metrics 0.0.2 → 0.0.4

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: 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