danger-compose_compiler_metrics 0.0.2 → 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: 5174bc2092a2c48fa3a84c6cb7006b0836fc9ccdc55f647efad88cc3fbd52e65
4
- data.tar.gz: de4c9958f624409b65e36aa49d5b001de6f474e79c43afe51a42011f1150ac91
3
+ metadata.gz: 2cc60271478af15e0a283d10f7d2b5e1cd1ecc5d899496b6ee3e0ed9b1f58da5
4
+ data.tar.gz: dc17d7971fae2598ef76c779cd120f3a87bcb943fbd2e9645717c20654885bdd
5
5
  SHA512:
6
- metadata.gz: 4543a2ecc312efe6d7357acaf70e19bf84d4f2938cc525b9c33db740f04aee929acc7c2cdd17a98c5cb112bb3d3595654ac92498d3bf5de665e246608ea7e3b3
7
- data.tar.gz: 77d0f263a40a8286b3b36cc6a3dc2bf6b3dff3370e91717d5bdefd4ed824ddecb067c8f14a9c70c1e8d000a35867817e66895f16701d9f653cef050f86fb251b
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.2"
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
 
@@ -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)
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,86 @@ 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)
28
+ report_file_difference("Metrics", metrics_path, reference_metrics_path)
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)
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)
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)
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
41
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")
89
+ )
90
+ )
42
91
  end
43
92
 
44
- def report_file_difference(title, metrics_path, base_metrics_path)
93
+ def report_file_difference(title, metrics_path, reference_metrics_path)
45
94
  unless File.exist?(metrics_path)
46
95
  warn "DangerComposeCompilerMetrics: new file not found at #{metrics_path}. Skipping file difference report."
47
96
  return
48
97
  end
49
98
 
50
- unless File.exist?(base_metrics_path)
51
- warn "DangerComposeCompilerMetrics: reference file not found at #{base_metrics_path}. Skipping file difference report."
99
+ unless File.exist?(reference_metrics_path)
100
+ warn "DangerComposeCompilerMetrics: reference file not found at #{reference_metrics_path}. Skipping file difference report."
52
101
  return
53
102
  end
54
103
 
55
- report = `diff -u #{base_metrics_path} #{metrics_path}`
104
+ report = `diff -u #{reference_metrics_path} #{metrics_path}`
56
105
 
57
106
  markdown(
58
107
  folding(
@@ -71,18 +120,18 @@ module Danger
71
120
  end
72
121
 
73
122
  def report(metrics_dir)
74
- markdown('# Compose Compiler Metrics Report')
123
+ markdown("# Compose Compiler Metrics Report")
75
124
  build_variants(metrics_dir).each do |module_name, build_variant|
76
125
  markdown("## #{module_name} - #{build_variant}")
77
126
 
78
127
  # Metrics Report
79
128
  metrics_path = File.join(metrics_dir, metrics_filename(module_name, build_variant))
80
- table_headers = %w[name value]
129
+ table_headers = %w(name value)
81
130
  table_rows = JSON.load_file(metrics_path).to_a
82
131
 
83
132
  markdown(
84
133
  folding(
85
- '### Metrics',
134
+ "### Metrics",
86
135
  build_markdown_table(table_headers, table_rows)
87
136
  )
88
137
  )
@@ -93,7 +142,7 @@ module Danger
93
142
 
94
143
  markdown(
95
144
  folding(
96
- '### Composable Stats Report',
145
+ "### Composable Stats Report",
97
146
  build_markdown_table(csv.headers, csv.map(&:fields))
98
147
  )
99
148
  )
@@ -102,7 +151,7 @@ module Danger
102
151
  composable_report_path = File.join(metrics_dir, composable_report_path(module_name, build_variant))
103
152
  markdown(
104
153
  folding(
105
- '### Composable Report',
154
+ "### Composable Report",
106
155
  <<~MARKDOWN
107
156
  ```kotlin
108
157
  #{File.read(composable_report_path)}
@@ -115,7 +164,7 @@ module Danger
115
164
  class_report_path = File.join(metrics_dir, class_report_path(module_name, build_variant))
116
165
  markdown(
117
166
  folding(
118
- '### Class Report',
167
+ "### Class Report",
119
168
  <<~MARKDOWN
120
169
  ```kotlin
121
170
  #{File.read(class_report_path)}