modularization_statistics 1.43.0 → 2.0.1

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: f62a7a832093f586bea43e63af693a848f52cf0e4528348746424d4a80c10d12
4
- data.tar.gz: a7d15eff1dc8014fd5552372081d6a171dff2625dade956b6ef0554e45631c3f
3
+ metadata.gz: b4b5268e6966983f8e8195225a5450391bb6ccf5b993d939b03d317b4523ef52
4
+ data.tar.gz: 79a35f5a9cb61e4fb43a069314c282f978cbbfe1e6b71ba2e3dc7a34a6714df0
5
5
  SHA512:
6
- metadata.gz: 2b510bef418709597c3c215d24752de7db71f411765517c350cfc4e8ebf5e396ecb7399ab340defbdc8bb6538e38cdb713f2d209407c5ced0ed4ff0a17f9b04a
7
- data.tar.gz: 3dc87181542fcb8bcb37561d9aa12df9ebe152f397da7c5f01c3b5b579c048102e9640929d1d6e6d3d806d6bbf5386524b411d2679324bf483e335d8b8065730
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', legacy_metric_name: 'prevent_this_package_from_violating_its_stated_dependencies'),
29
- PackwerkChecker.new(setting: 'enforce_privacy', strict_mode: 'enforce_privacy_strictly', legacy_metric_name: 'prevent_other_packages_from_using_this_packages_internals')
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
- ['no', 'fail_the_build_if_new_instances_appear', 'fail_the_build_on_any_instances'].each do |violation_behavior|
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 violation_behavior
38
- when 'fail_the_build_on_any_instances'
39
- !!strict_mode
40
- when 'no'
32
+ case enabled_mode
33
+ when 'false'
41
34
  !enabled
42
- when 'fail_the_build_if_new_instances_appear'
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.legacy_metric_name}.#{violation_behavior}.count"
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
- rubocop_legacy_metric_map.each do |cop_name, legacy_name|
24
- ['no', 'fail_the_build_if_new_instances_appear', 'fail_the_build_on_any_instances'].each do |violation_behavior|
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 violation_behavior
38
- when 'fail_the_build_on_any_instances'
39
- !!strict_mode
40
- when 'no'
36
+ case enabled_mode
37
+ when 'false'
41
38
  !enabled
42
- when 'fail_the_build_if_new_instances_appear'
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}.#{legacy_name}.#{violation_behavior}.count"
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
- rubocop_legacy_metric_map.flat_map do |cop_name, legacy_name|
58
- metric_name = "#{prefix}.#{legacy_name}.rubocop_exclusions.count"
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::Hash[String, String])}
83
- def self.rubocop_legacy_metric_map
84
- {
85
- 'Packs/ClassMethodsAsPublicApis' => 'prevent_this_package_from_exposing_an_untyped_api',
86
- 'Packs/RootNamespaceIsPackName' => 'prevent_this_package_from_creating_other_namespaces',
87
- 'Packs/TypedPublicApis' => 'prevent_this_package_from_exposing_an_untyped_api',
88
- 'Packs/DocumentedPublicApis' => 'prevent_this_package_from_exposing_undocumented_public_apis',
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modularization_statistics
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.43.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers