modularization_statistics 1.43.0 → 2.0.1
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/lib/modularization_statistics/private/metrics/packages.rb +0 -3
- data/lib/modularization_statistics/private/metrics/packages_by_team.rb +1 -4
- data/lib/modularization_statistics/private/metrics/packwerk_checker_usage.rb +9 -14
- data/lib/modularization_statistics/private/metrics/rubocop_usage.rb +23 -19
- data/lib/modularization_statistics/private.rb +46 -0
- data/lib/modularization_statistics.rb +27 -6
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4b5268e6966983f8e8195225a5450391bb6ccf5b993d939b03d317b4523ef52
|
4
|
+
data.tar.gz: 79a35f5a9cb61e4fb43a069314c282f978cbbfe1e6b71ba2e3dc7a34a6714df0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04fce30c1cefb4aac8265695b0ad7814842cea6138390223f634010f7869a98952b0f08a3bc065a9a4141e810a930f2ce62bf32c9445ae34a0d10f2e5e347c0b
|
7
|
+
data.tar.gz: 344d3b87d0ac22538f9ff72e053fc4bfdde5cb7857867d8a6e68254ce485a889f9c4f9a78a16e94f588b718cd66e2cae814bab7a77eefee0555d1ea34582668e
|
@@ -25,9 +25,6 @@ module ModularizationStatistics
|
|
25
25
|
all_metrics << GaugeMetric.for('all_packages.enforcing_dependencies.count', packages.count(&:enforces_dependencies?), package_tags)
|
26
26
|
all_metrics << GaugeMetric.for('all_packages.enforcing_privacy.count', packages.count(&:enforces_privacy?), package_tags)
|
27
27
|
|
28
|
-
all_metrics << GaugeMetric.for('all_packages.notify_on_package_yml_changes.count', packages.count { |p| p.metadata['notify_on_package_yml_changes'] }, package_tags)
|
29
|
-
all_metrics << GaugeMetric.for('all_packages.notify_on_new_violations.count', packages.count { |p| p.metadata['notify_on_new_violations'] }, package_tags)
|
30
|
-
|
31
28
|
all_metrics << GaugeMetric.for('all_packages.with_violations.count', packages.count { |package| package.violations.any? }, package_tags)
|
32
29
|
all_metrics += Metrics::PublicUsage.get_public_usage_metrics('all_packages', packages, package_tags)
|
33
30
|
all_metrics << GaugeMetric.for('all_packages.has_readme.count', packages.count { |package| Metrics.has_readme?(package) }, package_tags)
|
@@ -24,11 +24,8 @@ module ModularizationStatistics
|
|
24
24
|
team_tags = Metrics.tags_for_team(team_name) + [app_level_tag]
|
25
25
|
all_metrics << GaugeMetric.for('by_team.all_packages.count', packages_by_team.count, team_tags)
|
26
26
|
all_metrics += Metrics::PackwerkCheckerUsage.get_checker_metrics('by_team', packages_by_team, team_tags)
|
27
|
+
all_metrics += Metrics::RubocopUsage.get_metrics('by_team', packages_by_team, team_tags)
|
27
28
|
all_metrics += Metrics::PublicUsage.get_public_usage_metrics('by_team', packages_by_team, team_tags)
|
28
|
-
|
29
|
-
all_metrics << GaugeMetric.for('by_team.notify_on_package_yml_changes.count', packages_by_team.count { |p| p.metadata['notify_on_package_yml_changes'] }, team_tags)
|
30
|
-
all_metrics << GaugeMetric.for('by_team.notify_on_new_violations.count', packages_by_team.count { |p| p.metadata['notify_on_new_violations'] }, team_tags)
|
31
|
-
|
32
29
|
#
|
33
30
|
# VIOLATIONS (implicit dependencies)
|
34
31
|
#
|
@@ -13,11 +13,6 @@ module ModularizationStatistics
|
|
13
13
|
class PackwerkChecker < T::Struct
|
14
14
|
const :setting, String
|
15
15
|
const :strict_mode, String
|
16
|
-
# Later, we might convert to legacy metric names later so new clients get more sensible metric names
|
17
|
-
# That is, we might want to see metrics that are more closely connected to the new API.
|
18
|
-
# e.g. instead of `all_packages.prevent_this_package_from_violating_its_stated_dependencies.fail_on_any.count`, we'd see `all_packages.checkers.enforce_dependencies.strict.count`
|
19
|
-
# e.g. instead of `all_packages.prevent_this_package_from_creating_other_namespaces.fail_on_new.count`, `all_packages.cops.packs_namespaceconvention.true.count`
|
20
|
-
const :legacy_metric_name, String
|
21
16
|
end
|
22
17
|
|
23
18
|
sig { params(prefix: String, packages: T::Array[ParsePackwerk::Package], package_tags: T::Array[Tag]).returns(T::Array[GaugeMetric]) }
|
@@ -25,26 +20,26 @@ module ModularizationStatistics
|
|
25
20
|
metrics = T.let([], T::Array[GaugeMetric])
|
26
21
|
|
27
22
|
checkers = [
|
28
|
-
PackwerkChecker.new(setting: 'enforce_dependencies', strict_mode: 'enforce_dependencies_strictly'
|
29
|
-
PackwerkChecker.new(setting: 'enforce_privacy', strict_mode: 'enforce_privacy_strictly'
|
23
|
+
PackwerkChecker.new(setting: 'enforce_dependencies', strict_mode: 'enforce_dependencies_strictly'),
|
24
|
+
PackwerkChecker.new(setting: 'enforce_privacy', strict_mode: 'enforce_privacy_strictly')
|
30
25
|
]
|
31
26
|
|
32
27
|
checkers.each do |checker|
|
33
|
-
['
|
28
|
+
['false', 'true', 'strict'].each do |enabled_mode|
|
34
29
|
count_of_packages = ParsePackwerk.all.count do |package|
|
35
30
|
strict_mode = package.metadata[checker.strict_mode]
|
36
31
|
enabled = YAML.load_file(package.yml)[checker.setting]
|
37
|
-
case
|
38
|
-
when '
|
39
|
-
!!strict_mode
|
40
|
-
when 'no'
|
32
|
+
case enabled_mode
|
33
|
+
when 'false'
|
41
34
|
!enabled
|
42
|
-
when '
|
35
|
+
when 'true'
|
43
36
|
enabled && !strict_mode
|
37
|
+
when 'strict'
|
38
|
+
!!strict_mode
|
44
39
|
end
|
45
40
|
end
|
46
41
|
|
47
|
-
metric_name = "#{prefix}.#{checker.
|
42
|
+
metric_name = "#{prefix}.packwerk_checkers.#{checker.setting}.#{enabled_mode}.count"
|
48
43
|
metrics << GaugeMetric.for(metric_name, count_of_packages, package_tags)
|
49
44
|
end
|
50
45
|
end
|
@@ -17,11 +17,10 @@ module ModularizationStatistics
|
|
17
17
|
|
18
18
|
sig { params(prefix: String, packages: T::Array[ParsePackwerk::Package], package_tags: T::Array[Tag]).returns(T::Array[GaugeMetric]) }
|
19
19
|
def self.get_rubocop_usage_metrics(prefix, packages, package_tags)
|
20
|
-
# Rubocops
|
21
20
|
metrics = T.let([], T::Array[GaugeMetric])
|
22
21
|
|
23
|
-
|
24
|
-
['
|
22
|
+
rubocops.each do |cop_name|
|
23
|
+
['false', 'true', 'strict'].each do |enabled_mode|
|
25
24
|
count_of_packages = ParsePackwerk.all.count do |package|
|
26
25
|
# We will likely want a rubocop-packs API for this, to be able to ask if a cop is enabled for a pack.
|
27
26
|
# It's possible we will want to allow these to be enabled at the top-level `.rubocop.yml`,
|
@@ -34,17 +33,17 @@ module ModularizationStatistics
|
|
34
33
|
|
35
34
|
strict_mode = cop_config && cop_config['FailureMode'] == 'strict'
|
36
35
|
enabled = cop_config && cop_config['Enabled']
|
37
|
-
case
|
38
|
-
when '
|
39
|
-
!!strict_mode
|
40
|
-
when 'no'
|
36
|
+
case enabled_mode
|
37
|
+
when 'false'
|
41
38
|
!enabled
|
42
|
-
when '
|
39
|
+
when 'true'
|
43
40
|
enabled && !strict_mode
|
41
|
+
when 'strict'
|
42
|
+
!!strict_mode
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
|
-
metric_name = "#{prefix}.#{
|
46
|
+
metric_name = "#{prefix}.rubocops.#{to_tag_name(cop_name)}.#{enabled_mode}.count"
|
48
47
|
metrics << GaugeMetric.for(metric_name, count_of_packages, package_tags)
|
49
48
|
end
|
50
49
|
end
|
@@ -54,8 +53,8 @@ module ModularizationStatistics
|
|
54
53
|
|
55
54
|
sig { params(prefix: String, packages: T::Array[ParsePackwerk::Package], package_tags: T::Array[Tag]).returns(T::Array[GaugeMetric]) }
|
56
55
|
def self.get_rubocop_exclusions(prefix, packages, package_tags)
|
57
|
-
|
58
|
-
metric_name = "#{prefix}.#{
|
56
|
+
rubocops.flat_map do |cop_name|
|
57
|
+
metric_name = "#{prefix}.rubocops.#{to_tag_name(cop_name)}.exclusions.count"
|
59
58
|
all_exclusions_count = ParsePackwerk.all.sum { |package| exclude_count_for_package_and_protection(package, cop_name)}
|
60
59
|
GaugeMetric.for(metric_name, all_exclusions_count, package_tags)
|
61
60
|
end
|
@@ -79,14 +78,19 @@ module ModularizationStatistics
|
|
79
78
|
end
|
80
79
|
end
|
81
80
|
|
82
|
-
sig { returns(T::
|
83
|
-
def self.
|
84
|
-
|
85
|
-
'Packs/ClassMethodsAsPublicApis'
|
86
|
-
'Packs/RootNamespaceIsPackName'
|
87
|
-
'Packs/TypedPublicApis'
|
88
|
-
'Packs/DocumentedPublicApis'
|
89
|
-
|
81
|
+
sig { returns(T::Array[String])}
|
82
|
+
def self.rubocops
|
83
|
+
[
|
84
|
+
'Packs/ClassMethodsAsPublicApis',
|
85
|
+
'Packs/RootNamespaceIsPackName',
|
86
|
+
'Packs/TypedPublicApis',
|
87
|
+
'Packs/DocumentedPublicApis',
|
88
|
+
]
|
89
|
+
end
|
90
|
+
|
91
|
+
sig { params(cop_name: String).returns(String) }
|
92
|
+
def self.to_tag_name(cop_name)
|
93
|
+
cop_name.gsub('/', '_').downcase
|
90
94
|
end
|
91
95
|
end
|
92
96
|
end
|
@@ -2,6 +2,52 @@
|
|
2
2
|
|
3
3
|
module ModularizationStatistics
|
4
4
|
module Private
|
5
|
+
extend T::Sig
|
6
|
+
|
7
|
+
METRIC_REPLACEMENTS = T.let({
|
8
|
+
# enforce_dependencies
|
9
|
+
'packwerk_checkers.enforce_dependencies.false' => 'prevent_this_package_from_violating_its_stated_dependencies.no',
|
10
|
+
'packwerk_checkers.enforce_dependencies.true' => 'prevent_this_package_from_violating_its_stated_dependencies.fail_the_build_if_new_instances_appear',
|
11
|
+
'packwerk_checkers.enforce_dependencies.strict' => 'prevent_this_package_from_violating_its_stated_dependencies.fail_the_build_on_any_instances',
|
12
|
+
# enforce_privacy
|
13
|
+
'packwerk_checkers.enforce_privacy.false' => 'prevent_other_packages_from_using_this_packages_internals.no',
|
14
|
+
'packwerk_checkers.enforce_privacy.true' => 'prevent_other_packages_from_using_this_packages_internals.fail_the_build_if_new_instances_appear',
|
15
|
+
'packwerk_checkers.enforce_privacy.strict' => 'prevent_other_packages_from_using_this_packages_internals.fail_the_build_on_any_instances',
|
16
|
+
# Packs/TypedPublicApis
|
17
|
+
'rubocops.packs_typedpublicapis.false' => 'prevent_this_package_from_exposing_an_untyped_api.no',
|
18
|
+
'rubocops.packs_typedpublicapis.true' => 'prevent_this_package_from_exposing_an_untyped_api.fail_the_build_if_new_instances_appear',
|
19
|
+
'rubocops.packs_typedpublicapis.strict' => 'prevent_this_package_from_exposing_an_untyped_api.fail_the_build_on_any_instances',
|
20
|
+
'rubocops.packs_typedpublicapis.exclusions' => 'prevent_this_package_from_exposing_an_untyped_api.rubocop_exclusions',
|
21
|
+
# Packs/RootNamespaceIsPackName
|
22
|
+
'rubocops.packs_rootnamespaceispackname.false' => 'prevent_this_package_from_creating_other_namespaces.no',
|
23
|
+
'rubocops.packs_rootnamespaceispackname.true' => 'prevent_this_package_from_creating_other_namespaces.fail_the_build_if_new_instances_appear',
|
24
|
+
'rubocops.packs_rootnamespaceispackname.strict' => 'prevent_this_package_from_creating_other_namespaces.fail_the_build_on_any_instances',
|
25
|
+
'rubocops.packs_rootnamespaceispackname.exclusions' => 'prevent_this_package_from_creating_other_namespaces.rubocop_exclusions',
|
26
|
+
# Packs/ClassMethodsAsPublicApis
|
27
|
+
'rubocops.packs_classmethodsaspublicapis.false' => 'prevent_this_package_from_exposing_instance_method_public_apis.no',
|
28
|
+
'rubocops.packs_classmethodsaspublicapis.true' => 'prevent_this_package_from_exposing_instance_method_public_apis.fail_the_build_if_new_instances_appear',
|
29
|
+
'rubocops.packs_classmethodsaspublicapis.strict' => 'prevent_this_package_from_exposing_instance_method_public_apis.fail_the_build_on_any_instances',
|
30
|
+
'rubocops.packs_classmethodsaspublicapis.exclusions' => 'prevent_this_package_from_exposing_instance_method_public_apis.rubocop_exclusions',
|
31
|
+
# Packs/DocumentedPublicApis
|
32
|
+
'rubocops.packs_documentedpublicapis.false' => 'prevent_this_package_from_exposing_undocumented_public_apis.no',
|
33
|
+
'rubocops.packs_documentedpublicapis.true' => 'prevent_this_package_from_exposing_undocumented_public_apis.fail_the_build_if_new_instances_appear',
|
34
|
+
'rubocops.packs_documentedpublicapis.strict' => 'prevent_this_package_from_exposing_undocumented_public_apis.fail_the_build_on_any_instances',
|
35
|
+
'rubocops.packs_documentedpublicapis.exclusions' => 'prevent_this_package_from_exposing_undocumented_public_apis.rubocop_exclusions',
|
36
|
+
}, T::Hash[String, String])
|
37
|
+
|
38
|
+
sig { params(metrics: T::Array[GaugeMetric]).returns(T::Array[GaugeMetric]) }
|
39
|
+
def self.convert_metrics_to_legacy(metrics)
|
40
|
+
metrics.map do |metric|
|
41
|
+
new_metric = metric
|
42
|
+
METRIC_REPLACEMENTS.each do |current_name, legacy_name|
|
43
|
+
new_metric = new_metric.with(
|
44
|
+
name: new_metric.name.gsub(current_name, legacy_name)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
new_metric
|
49
|
+
end
|
50
|
+
end
|
5
51
|
end
|
6
52
|
|
7
53
|
private_constant :Private
|
@@ -7,6 +7,7 @@ require 'benchmark'
|
|
7
7
|
require 'code_teams'
|
8
8
|
require 'code_ownership'
|
9
9
|
require 'pathname'
|
10
|
+
require 'modularization_statistics/private'
|
10
11
|
require 'modularization_statistics/private/source_code_file'
|
11
12
|
require 'modularization_statistics/private/datadog_reporter'
|
12
13
|
require 'parse_packwerk'
|
@@ -41,7 +42,9 @@ module ModularizationStatistics
|
|
41
42
|
componentized_source_code_locations: T::Array[Pathname],
|
42
43
|
packaged_source_code_locations: T::Array[Pathname],
|
43
44
|
report_time: Time,
|
44
|
-
verbose: T::Boolean
|
45
|
+
verbose: T::Boolean,
|
46
|
+
# See note on get_metrics
|
47
|
+
use_gusto_legacy_names: T::Boolean
|
45
48
|
).void
|
46
49
|
end
|
47
50
|
def self.report_to_datadog!(
|
@@ -51,14 +54,16 @@ module ModularizationStatistics
|
|
51
54
|
componentized_source_code_locations: DEFAULT_COMPONENTIZED_SOURCE_CODE_LOCATIONS,
|
52
55
|
packaged_source_code_locations: DEFAULT_PACKAGED_SOURCE_CODE_LOCATIONS,
|
53
56
|
report_time: Time.now, # rubocop:disable Rails/TimeZone
|
54
|
-
verbose: false
|
57
|
+
verbose: false,
|
58
|
+
use_gusto_legacy_names: false
|
55
59
|
)
|
56
60
|
|
57
61
|
all_metrics = self.get_metrics(
|
58
62
|
source_code_pathnames: source_code_pathnames,
|
59
63
|
componentized_source_code_locations: componentized_source_code_locations,
|
60
64
|
packaged_source_code_locations: packaged_source_code_locations,
|
61
|
-
app_name: app_name
|
65
|
+
app_name: app_name,
|
66
|
+
use_gusto_legacy_names: use_gusto_legacy_names,
|
62
67
|
)
|
63
68
|
|
64
69
|
# This helps us debug what metrics are being sent
|
@@ -68,6 +73,10 @@ module ModularizationStatistics
|
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
76
|
+
if use_gusto_legacy_names
|
77
|
+
all_metrics = Private.convert_metrics_to_legacy(all_metrics)
|
78
|
+
end
|
79
|
+
|
71
80
|
Private::DatadogReporter.report!(
|
72
81
|
datadog_client: datadog_client,
|
73
82
|
report_time: report_time,
|
@@ -80,16 +89,22 @@ module ModularizationStatistics
|
|
80
89
|
source_code_pathnames: T::Array[Pathname],
|
81
90
|
componentized_source_code_locations: T::Array[Pathname],
|
82
91
|
packaged_source_code_locations: T::Array[Pathname],
|
83
|
-
app_name: String
|
92
|
+
app_name: String,
|
93
|
+
# It is not recommended to set this to true.
|
94
|
+
# Gusto uses this to preserve historical trends in Dashboards as the names of
|
95
|
+
# things changed, but new dashboards can use names that better match current tooling conventions.
|
96
|
+
# The behavior of setting this parameter to true might change without warning
|
97
|
+
use_gusto_legacy_names: T::Boolean
|
84
98
|
).returns(T::Array[GaugeMetric])
|
85
99
|
end
|
86
100
|
def self.get_metrics(
|
87
101
|
source_code_pathnames:,
|
88
102
|
componentized_source_code_locations:,
|
89
103
|
packaged_source_code_locations:,
|
90
|
-
app_name
|
104
|
+
app_name:,
|
105
|
+
use_gusto_legacy_names: false
|
91
106
|
)
|
92
|
-
Private::DatadogReporter.get_metrics(
|
107
|
+
all_metrics = Private::DatadogReporter.get_metrics(
|
93
108
|
source_code_files: source_code_files(
|
94
109
|
source_code_pathnames: source_code_pathnames,
|
95
110
|
componentized_source_code_locations: componentized_source_code_locations,
|
@@ -97,6 +112,12 @@ module ModularizationStatistics
|
|
97
112
|
),
|
98
113
|
app_name: app_name
|
99
114
|
)
|
115
|
+
|
116
|
+
if use_gusto_legacy_names
|
117
|
+
all_metrics = Private.convert_metrics_to_legacy(all_metrics)
|
118
|
+
end
|
119
|
+
|
120
|
+
all_metrics
|
100
121
|
end
|
101
122
|
|
102
123
|
sig do
|