danger-compose_compiler_metrics 0.0.1 → 0.0.3

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