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 +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 -1
- data/lib/compose_compiler_metrics/metrics.rb +96 -0
- data/lib/compose_compiler_metrics/plugin.rb +100 -76
- data/spec/compose_compiler_metrics_spec.rb +395 -27
- 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: 2cc60271478af15e0a283d10f7d2b5e1cd1ecc5d899496b6ee3e0ed9b1f58da5
|
4
|
+
data.tar.gz: dc17d7971fae2598ef76c779cd120f3a87bcb943fbd2e9645717c20654885bdd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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.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 (
|
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
|
|
@@ -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
|
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
|
-
|
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
|
-
|
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
|
-
|
23
|
-
|
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
|
-
|
40
|
-
|
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
|
-
|
60
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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(
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
167
|
+
"### Class Report",
|
144
168
|
<<~MARKDOWN
|
145
169
|
```kotlin
|
146
170
|
#{File.read(class_report_path)}
|