danger-compose_compiler_metrics 0.0.1 → 0.0.3

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: 0a4e4fdbd974ca9e26bf31a9d9d458a24701fba13e2cf50294ae0787573931f4
4
- data.tar.gz: 88b1ab8dacfa22cb954b930ffa589e8a3066e949d66c2275f93391a1bf829b44
3
+ metadata.gz: 2cc60271478af15e0a283d10f7d2b5e1cd1ecc5d899496b6ee3e0ed9b1f58da5
4
+ data.tar.gz: dc17d7971fae2598ef76c779cd120f3a87bcb943fbd2e9645717c20654885bdd
5
5
  SHA512:
6
- metadata.gz: bba795ff85c82cd20464458c407375dfbeeca2bcdc0f42b54cdf1842d3fb6b60507ff24e8b1ae796d753a83eab882b90d7f5e742bddd3d65187675099484c63f
7
- data.tar.gz: 53b535436b8654a60e2cbb43a42fa4aec95bae0a8cf684627e6ef40b8a063b14145e18d1560b22ef05e350efa99291a4af2d9e0f5bfb14ba7a5f4d050d00e9e3
6
+ metadata.gz: 9c5bc88d19bf7f84dc09a03f14d8ebc1f211afc6036646f9a6f1a5b469260036fce31d5c4e306d0f2033399d07bd38a5c81804dbfd89b071a3ee47d2a071fe6e
7
+ data.tar.gz: '085f7761b5f940d85af421a44877a0cd5db43b263412b17f822019189b86bd6ea044c080ed7048f8e0c599da8e9e1ed3985b0bd628d32f122e266854adb9d61f'
@@ -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.3)
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.1"
4
+ VERSION = "0.0.3"
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
 
@@ -45,4 +47,8 @@ module Helper
45
47
  </details>
46
48
  HTML
47
49
  end
50
+
51
+ def installed?(command)
52
+ system("which #{command} > /dev/null")
53
+ end
48
54
  end
@@ -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,113 +1,137 @@
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
- markdown('# Compose Compiler Metrics Difference Report')
13
+ def report_difference(metrics_dir, reference_metrics_dir)
14
+ unless installed?("diff")
15
+ failure "diff command not found. Please install diff command."
16
+ return
17
+ end
18
+
19
+ markdown("# Compose Compiler Metrics Difference Report")
14
20
  build_variants(metrics_dir).each do |module_name, build_variant|
15
21
  markdown("## #{module_name} - #{build_variant}")
16
22
 
17
23
  # Metrics Report
18
24
  metrics_path = File.join(metrics_dir, metrics_filename(module_name, build_variant))
19
- base_metrics_path = File.join(base_metrics_dir, metrics_filename(module_name, build_variant))
20
- report = `diff -u #{base_metrics_path} #{metrics_path}`
25
+ reference_metrics_path = File.join(reference_metrics_dir, metrics_filename(module_name, build_variant))
21
26
 
22
- markdown(
23
- folding(
24
- '### Metrics',
25
- if report.empty?
26
- 'No difference found.'
27
- else
28
- <<~MARKDOWN
29
- ```diff
30
- #{report}
31
- ```
32
- MARKDOWN
33
- end
34
- )
35
- )
27
+ report_metrics_report("Metrics Summary", metrics_path, reference_metrics_path)
28
+ report_file_difference("Metrics", metrics_path, reference_metrics_path)
36
29
 
37
30
  # Composable Stats Report
38
31
  composable_stats_report_path = File.join(metrics_dir, composable_stats_report_path(module_name, build_variant))
39
- base_composable_stats_report_path = File.join(base_metrics_dir, composable_stats_report_path(module_name, build_variant))
40
- report = `diff -u #{base_composable_stats_report_path} #{composable_stats_report_path}`
41
-
42
- markdown(
43
- folding(
44
- '### Composable Stats Report',
45
- if report.empty?
46
- 'No difference found.'
47
- else
48
- <<~MARKDOWN
49
- ```diff
50
- #{report}
51
- ```
52
- MARKDOWN
53
- end
54
- )
55
- )
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)
56
34
 
57
35
  # Composable Report
58
36
  composable_report_path = File.join(metrics_dir, composable_report_path(module_name, build_variant))
59
- base_composable_report_path = File.join(base_metrics_dir, composable_report_path(module_name, build_variant))
60
- report = `diff -u #{base_composable_report_path} #{composable_report_path}`
61
-
62
- markdown(
63
- folding(
64
- '### Composable Report',
65
- if report.empty?
66
- 'No difference found.'
67
- else
68
- <<~MARKDOWN
69
- ```diff
70
- #{report}
71
- ```
72
- MARKDOWN
73
- end
74
- )
75
- )
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)
76
39
 
77
40
  # Class Report
78
41
  class_report_path = File.join(metrics_dir, class_report_path(module_name, build_variant))
79
- base_class_report_path = File.join(base_metrics_dir, class_report_path(module_name, build_variant))
80
- report = `diff -u #{base_class_report_path} #{class_report_path}`
81
- markdown(
82
- folding(
83
- '### Class Report',
84
- if report.empty?
85
- 'No difference found.'
86
- else
87
- <<~MARKDOWN
88
- ```diff
89
- #{report}
90
- ```
91
- MARKDOWN
92
- end
93
- )
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)
44
+ end
45
+ end
46
+
47
+ def report_metrics_report(title, metrics_path, reference_metrics_path)
48
+ unless File.exist?(metrics_path)
49
+ warn "DangerComposeCompilerMetrics: new file not found at #{metrics_path}. Skipping file difference report."
50
+ return
51
+ end
52
+
53
+ unless File.exist?(reference_metrics_path)
54
+ warn "DangerComposeCompilerMetrics: reference file not found at #{reference_metrics_path}. Skipping file difference report."
55
+ return
56
+ end
57
+
58
+ metrics = Metrics.load(metrics_path)
59
+ reference_metrics = Metrics.load(reference_metrics_path)
60
+
61
+ tables = reference_metrics.grouped_metrics.map do |group_key, grouped_reference_metrics|
62
+ grouped_metrics = metrics.grouped_metrics[group_key]
63
+
64
+ table_headers = %w(name reference new diff)
65
+ table_rows = grouped_reference_metrics.keys.map do |key|
66
+ new_value = grouped_metrics.send(key.to_sym)
67
+ reference_value = grouped_reference_metrics.send(key.to_sym)
68
+ diff_value = (new_value - reference_value).then do |v|
69
+ next "+#{v}" if v.positive?
70
+
71
+ next v.to_s if v.negative?
72
+
73
+ ""
74
+ end
75
+
76
+ [key, reference_value, new_value, diff_value]
77
+ end
78
+
79
+ [
80
+ "#### #{group_key}",
81
+ build_markdown_table(table_headers, table_rows)
82
+ ].join("\n\n")
83
+ end
84
+
85
+ markdown(
86
+ folding(
87
+ "### #{title}",
88
+ tables.join("\n\n")
94
89
  )
90
+ )
91
+ end
92
+
93
+ def report_file_difference(title, metrics_path, reference_metrics_path)
94
+ unless File.exist?(metrics_path)
95
+ warn "DangerComposeCompilerMetrics: new file not found at #{metrics_path}. Skipping file difference report."
96
+ return
95
97
  end
98
+
99
+ unless File.exist?(reference_metrics_path)
100
+ warn "DangerComposeCompilerMetrics: reference file not found at #{reference_metrics_path}. Skipping file difference report."
101
+ return
102
+ end
103
+
104
+ report = `diff -u #{reference_metrics_path} #{metrics_path}`
105
+
106
+ markdown(
107
+ folding(
108
+ "### #{title}",
109
+ if report.empty?
110
+ "No difference found."
111
+ else
112
+ <<~MARKDOWN
113
+ ```diff
114
+ #{report}
115
+ ```
116
+ MARKDOWN
117
+ end
118
+ )
119
+ )
96
120
  end
97
121
 
98
122
  def report(metrics_dir)
99
- markdown('# Compose Compiler Metrics Report')
123
+ markdown("# Compose Compiler Metrics Report")
100
124
  build_variants(metrics_dir).each do |module_name, build_variant|
101
125
  markdown("## #{module_name} - #{build_variant}")
102
126
 
103
127
  # Metrics Report
104
128
  metrics_path = File.join(metrics_dir, metrics_filename(module_name, build_variant))
105
- table_headers = %w[name value]
129
+ table_headers = %w(name value)
106
130
  table_rows = JSON.load_file(metrics_path).to_a
107
131
 
108
132
  markdown(
109
133
  folding(
110
- '### Metrics',
134
+ "### Metrics",
111
135
  build_markdown_table(table_headers, table_rows)
112
136
  )
113
137
  )
@@ -118,7 +142,7 @@ module Danger
118
142
 
119
143
  markdown(
120
144
  folding(
121
- '### Composable Stats Report',
145
+ "### Composable Stats Report",
122
146
  build_markdown_table(csv.headers, csv.map(&:fields))
123
147
  )
124
148
  )
@@ -127,7 +151,7 @@ module Danger
127
151
  composable_report_path = File.join(metrics_dir, composable_report_path(module_name, build_variant))
128
152
  markdown(
129
153
  folding(
130
- '### Composable Report',
154
+ "### Composable Report",
131
155
  <<~MARKDOWN
132
156
  ```kotlin
133
157
  #{File.read(composable_report_path)}
@@ -140,7 +164,7 @@ module Danger
140
164
  class_report_path = File.join(metrics_dir, class_report_path(module_name, build_variant))
141
165
  markdown(
142
166
  folding(
143
- '### Class Report',
167
+ "### Class Report",
144
168
  <<~MARKDOWN
145
169
  ```kotlin
146
170
  #{File.read(class_report_path)}