danger-compose_compiler_metrics 0.0.2 → 0.0.4
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 +4 -4
- data/.github/workflows/test.yml +47 -0
- data/.rubocop.yml +1 -1
- data/.ruby-version +1 -0
- data/Gemfile.lock +3 -3
- data/danger-compose_compiler_metrics.gemspec +4 -2
- data/lib/compose_compiler_metrics/gem_version.rb +1 -1
- data/lib/compose_compiler_metrics/helper.rb +7 -3
- data/lib/compose_compiler_metrics/metrics.rb +96 -0
- data/lib/compose_compiler_metrics/plugin.rb +110 -55
- data/spec/compose_compiler_metrics_spec.rb +450 -26
- data/spec/metrics_spec.rb +220 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/fixtures/compose_compiler_metrics/app_debug-classes.txt +8 -0
- data/spec/support/fixtures/compose_compiler_metrics/app_debug-composables.csv +4 -0
- data/spec/support/fixtures/compose_compiler_metrics/app_debug-composables.txt +11 -0
- data/spec/support/fixtures/compose_compiler_metrics/app_debug-module.json +25 -0
- data/spec/support/fixtures/compose_compiler_metrics_baseline/app_debug-classes.txt +8 -0
- data/spec/support/fixtures/compose_compiler_metrics_baseline/app_debug-composables.csv +5 -0
- data/spec/support/fixtures/compose_compiler_metrics_baseline/app_debug-composables.txt +16 -0
- data/spec/support/fixtures/compose_compiler_metrics_baseline/app_debug-module.json +25 -0
- data/spec/support/fixtures/github_pr.json +278 -0
- metadata +43 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b9f0973e51bb4416bad39bb523c7d0b9e81828aa750c435fbdfe2b471857a48
|
4
|
+
data.tar.gz: cffa918441edcfa7bbd58e0d994a508c32abb22679194af550836e5edd5cb294
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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.
|
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 (
|
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
|
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"
|
30
|
+
spec.add_development_dependency "rake"
|
29
31
|
|
30
32
|
# Testing support
|
31
33
|
spec.add_development_dependency "rspec", "~> 3.4"
|
@@ -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(/[_
|
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
|
4
|
-
require
|
3
|
+
require "json"
|
4
|
+
require "csv"
|
5
5
|
|
6
|
-
require_relative
|
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,
|
13
|
+
def report_difference(metrics_dir, reference_metrics_dir, options = {})
|
13
14
|
unless installed?("diff")
|
14
|
-
|
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
|
-
|
25
|
-
|
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
|
-
|
30
|
-
report_file_difference("Composable Stats Report", 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
|
-
|
35
|
-
report_file_difference("Composable Report", 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
|
-
|
40
|
-
report_file_difference("
|
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,
|
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?(
|
51
|
-
warn "DangerComposeCompilerMetrics: reference file not found at #{
|
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 #{
|
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(
|
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
|
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
|
-
|
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
|
-
|
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
|