modularization_statistics 1.38.0 → 1.39.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ab5b40d2d974d45aae986a4a0418e8d50984c4d4d39e963815dfd5fb875efc6
4
- data.tar.gz: 91a571c247677445e408cd8aa0d2cc0a4adc2e5daed55ce4a6a8cc2e69429b81
3
+ metadata.gz: c11bc9704708d387bff6b5d7245832c6d57c9291a7dcc306513e3942afb53311
4
+ data.tar.gz: 7d5403d37a5811f5ef1798a3a8bfb96b304124ada289b75dba14db0844fd252e
5
5
  SHA512:
6
- metadata.gz: e3454d7e5f523f3d6030e1b1789fa1d0b363fbcc6c7069170797c4efd4256a463a77d43dbfa94da1fce24b13283592eb016f7923591b28406038ed9e44fd0eb5
7
- data.tar.gz: 5718efcffc45331f23b185f8b7565301cd35d8c1735eca4e9723b3086725ec30b7b6c399c16fdcc0788795fa4d39654c7bfa8348ec8b6188d3522584e55de147
6
+ metadata.gz: 2c82a234d983ddc50d494f6eb8933633a0b61a7e82783d375f5d22b02c1e12fb476f9fb70ca35885ecadc879dd1fc94179cf6db3b1d52f47501afe38c6349651
7
+ data.tar.gz: ec00762292cdec0eb441ad424bdd5e80733a9acd418925f82c92142988df9d4b3b6843b8e4de1d9b8190e48cf23f6818b2e4f7176bf263a6541fa490181c38b0
@@ -37,37 +37,112 @@ module ModularizationStatistics
37
37
  if p.metadata['protections']
38
38
  p.violation_behavior_for(protection.identifier) == violation_behavior
39
39
  else
40
- case violation_behavior
41
- when PackageProtections::ViolationBehavior::FailOnAny
42
- # There is not yet an implementation for `FailOnAny` for systems that don't use package protections
43
- false
44
- when PackageProtections::ViolationBehavior::FailNever
45
- if protection.identifier == 'prevent_this_package_from_violating_its_stated_dependencies'
46
- !p.original_package.enforces_dependencies?
47
- elsif protection.identifier == 'prevent_other_packages_from_using_this_packages_internals'
48
- !p.original_package.enforces_privacy?
49
- else
50
- # This is not applicable if you're not using package protections
51
- true
52
- end
53
- when PackageProtections::ViolationBehavior::FailOnNew
54
- if protection.identifier == 'prevent_this_package_from_violating_its_stated_dependencies'
55
- p.original_package.enforces_dependencies?
56
- elsif protection.identifier == 'prevent_other_packages_from_using_this_packages_internals'
57
- p.original_package.enforces_privacy?
58
- else
59
- # This is not applicable if you're not using package protections
60
- false
61
- end
62
- else
63
- T.absurd(violation_behavior)
64
- end
40
+ should_count_package?(p.original_package, protection, violation_behavior)
65
41
  end
66
42
  end
67
43
  GaugeMetric.for(metric_name, count_of_packages, package_tags)
68
44
  end
69
45
  end
70
46
  end
47
+
48
+ #
49
+ # Later, when we remove package protections, we can make this simpler by iterating over
50
+ # packwerk checkers and rubocop packs specifically. That would let us use a common, simple
51
+ # strategy to get metrics for both of them. For the first iteration, we'll want to continue
52
+ # to map the old names of things to the "protection" names. After that, I think we will want to
53
+ # extract that mapping into a tool that transforms the metrics that can be optionally turned off
54
+ # so that we can see metrics that are more closely connected to the new API.
55
+ # e.g. instead of `all_packages.prevent_this_package_from_violating_its_stated_dependencies.fail_on_any.count`, we'd see
56
+ # e.g. instead of `all_packages.checkers.enforce_dependencies.strict.count`, we'd see
57
+ # e.g. instead of `all_packages.prevent_this_package_from_creating_other_namespaces.fail_on_new.count`, we'd see
58
+ # e.g. instead of `all_packages.cops.packs_namespaceconvention.true.count`, we'd see
59
+ #
60
+ sig do
61
+ params(
62
+ package: ParsePackwerk::Package,
63
+ protection: PackageProtections::ProtectionInterface,
64
+ violation_behavior: PackageProtections::ViolationBehavior
65
+ ).returns(T::Boolean)
66
+ end
67
+ def self.should_count_package?(package, protection, violation_behavior)
68
+ if protection.identifier == 'prevent_this_package_from_violating_its_stated_dependencies'
69
+ strict_mode = package.metadata['strictly_enforce_dependencies']
70
+ enabled = package.enforces_dependencies?
71
+
72
+ case violation_behavior
73
+ when PackageProtections::ViolationBehavior::FailOnAny
74
+ !!strict_mode
75
+ when PackageProtections::ViolationBehavior::FailNever
76
+ !enabled
77
+ when PackageProtections::ViolationBehavior::FailOnNew
78
+ enabled && !strict_mode
79
+ else
80
+ T.absurd(violation_behavior)
81
+ end
82
+ elsif protection.identifier == 'prevent_other_packages_from_using_this_packages_internals'
83
+ strict_mode = package.metadata['strictly_enforce_privacy']
84
+ enabled = package.enforces_privacy?
85
+
86
+ case violation_behavior
87
+ when PackageProtections::ViolationBehavior::FailOnAny
88
+ !!strict_mode
89
+ when PackageProtections::ViolationBehavior::FailNever
90
+ !enabled
91
+ when PackageProtections::ViolationBehavior::FailOnNew
92
+ enabled && !strict_mode
93
+ else
94
+ T.absurd(violation_behavior)
95
+ end
96
+ elsif protection.identifier == 'prevent_other_packages_from_using_this_package_without_explicit_visibility'
97
+ case violation_behavior
98
+ when PackageProtections::ViolationBehavior::FailOnAny
99
+ # We'd probably not want to support this right away
100
+ false
101
+ when PackageProtections::ViolationBehavior::FailNever
102
+ # We'd need to add this to `parse_packwerk` so that we can get other arbitrary top-level keys.
103
+ # Alternatively we can put this in `metadata` for the time being to unblock us.
104
+ # package.config['enforce_visibility']
105
+ !package.metadata['enforce_visibility']
106
+ when PackageProtections::ViolationBehavior::FailOnNew
107
+ !!package.metadata['enforce_visibility']
108
+ else
109
+ T.absurd(violation_behavior)
110
+ end
111
+ else
112
+ # Otherwise, we're in a rubocop case
113
+ rubocop_yml_file = package.directory.join('.rubocop.yml')
114
+ return false if !rubocop_yml_file.exist?
115
+ rubocop_yml = YAML.load_file(rubocop_yml_file)
116
+ protection = T.cast(protection, PackageProtections::RubocopProtectionInterface)
117
+ # We will likely want a rubocop-packs API for this, to be able to ask if a cop is enabled for a pack.
118
+ # It's possible we will want to allow these to be enabled at the top-level `.rubocop.yml`,
119
+ # in which case we wouldn't get the right metrics with this approach. However, we can also accept
120
+ # that as a current limitation.
121
+ cop_map = {
122
+ 'PackageProtections/TypedPublicApi' => 'Packs/TypedPublicApi',
123
+ 'PackageProtections/NamespacedUnderPackageName' => 'Packs/NamespaceConvention',
124
+ 'PackageProtections/OnlyClassMethods' => 'Packs/ClassMethodsAsPublicApis',
125
+ 'PackageProtections/RequireDocumentedPublicApis' => 'Packs/RequireDocumentedPublicApis',
126
+ }
127
+ # We want to use the cop names from `rubocop-packs`. Eventually, we'll just literate over these
128
+ # cop names directly, or ask `rubocop-packs` for the list of cops to care about.
129
+ cop_config = rubocop_yml[cop_map[protection.cop_name]]
130
+ return false if cop_config.nil?
131
+ enabled = cop_config['Enabled']
132
+ strict_mode = cop_config['FailureMode'] == 'strict'
133
+
134
+ case violation_behavior
135
+ when PackageProtections::ViolationBehavior::FailOnAny
136
+ !!strict_mode
137
+ when PackageProtections::ViolationBehavior::FailNever
138
+ !enabled
139
+ when PackageProtections::ViolationBehavior::FailOnNew
140
+ enabled && !strict_mode
141
+ else
142
+ T.absurd(violation_behavior)
143
+ end
144
+ end
145
+ end
71
146
  end
72
147
  end
73
148
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modularization_statistics
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.38.0
4
+ version: 1.39.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-26 00:00:00.000000000 Z
11
+ date: 2022-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: code_teams