danger-compose_compiler_metrics 0.0.2 → 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: 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)}