package_protections 2.5.2 → 3.1.0

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: db265db203f34615ababcc47b7c18ac926cc2dde00c87ff6e7e88ada45eca909
4
- data.tar.gz: 9a4d401d4b3c6806e047cf34ee37e92a68c53f59cbf3a18b2a048233388e18e1
3
+ metadata.gz: 217ae8f6eee7f084ff39ce7c4cf0bb06a08c361abff49e411d730a3a79592b71
4
+ data.tar.gz: 21a4eea2876078f531a67d3705e7a0d38c11b3bf87cd265e552bda9e8661638a
5
5
  SHA512:
6
- metadata.gz: d89ef740b11b54d759cc4548279a45bf4c924ed215ef7cb07b0203cf8cf14aaff8b33d363f3e50c58a440fc71fa35d93dc7443ee965999d3c95c7be53fe0eb39
7
- data.tar.gz: d0abae5dfc74ab2b66b9e32ef9f22b31cd5ad1c2d3e37c42a779d7b1d773aaa3cccc8099d298cad36a219c18b693fe17f997db1f0f929207793f25bc16ab27b0
6
+ metadata.gz: 1633812b257db230cf9f0244c8dd397197d4feb98f37abcd9906e5660adbfb7985c82fc6758254f99771726d49d3796c2e30438a54bd14a75c9ed3b64dbca1a0
7
+ data.tar.gz: e1aafb82c4a5a93425cbfc28135bae436b792681f6cbd8257f95e2d51d985a436e80d191313d2959a3e9c37423f970608109bca773a5ffe0ad01af3d6214b6da
data/README.md CHANGED
@@ -56,7 +56,7 @@ This protection only looks at files in `packs/your_pack/app` (it ignores spec fi
56
56
  This protection is implemented via Rubocop -- expect to see results for this when running `rubocop` however you normally do. To add to the TODO list, add to `.rubocop_todo.yml`
57
57
  Lastly – this protection can be configured by setting `globally_permitted_namespaces`, e.g.:
58
58
  ```ruby
59
- PackageProtections.configure do |config|
59
+ RuboCop::Packs.configure do |config|
60
60
  config.globally_permitted_namespaces = ['SomeGlobalNamespace']
61
61
  end
62
62
  ```
@@ -13,14 +13,7 @@ module PackageProtections
13
13
  sig { params(original_package: ParsePackwerk::Package).returns(ProtectedPackage) }
14
14
  def self.from(original_package)
15
15
  metadata = original_package.metadata['protections'] || {}
16
-
17
16
  valid_identifiers = PackageProtections.all.map(&:identifier)
18
- invalid_identifiers = metadata.keys - valid_identifiers
19
-
20
- if invalid_identifiers.any?
21
- raise IncorrectPublicApiUsageError.new("Invalid configuration for package `#{original_package.name}`. The metadata keys #{invalid_identifiers.inspect} are not valid behaviors under the `protection` metadata namespace. Valid keys are #{valid_identifiers.inspect}. See https://github.com/rubyatscale/package_protections#readme for more info") # rubocop:disable Style/RaiseArgs
22
- end
23
-
24
17
  protections = {}
25
18
  metadata.each_key do |protection_key|
26
19
  protection = PackageProtections.with_identifier(protection_key)
@@ -32,18 +25,8 @@ module PackageProtections
32
25
  end
33
26
 
34
27
  unspecified_protections = valid_identifiers - protections.keys
35
- protections_requiring_explicit_configuration = T.let([], T::Array[Identifier])
36
28
  unspecified_protections.each do |protection_key|
37
- protection = PackageProtections.with_identifier(protection_key)
38
- if !protection.default_behavior.fail_never?
39
- protections_requiring_explicit_configuration << protection.identifier
40
- end
41
- protections[protection_key] = protection.default_behavior
42
- end
43
-
44
- if protections_requiring_explicit_configuration.any?
45
- error = "All protections must explicitly set unless their default behavior is `fail_never`. Missing protections: #{protections_requiring_explicit_configuration.join(', ')}"
46
- raise IncorrectPublicApiUsageError, error
29
+ protections[protection_key] = PackageProtections.with_identifier(protection_key).default_behavior
47
30
  end
48
31
 
49
32
  new(
@@ -55,13 +38,7 @@ module PackageProtections
55
38
 
56
39
  sig { params(protection: ProtectionInterface, metadata: T::Hash[T.untyped, T.untyped], package: ParsePackwerk::Package).returns(ViolationBehavior) }
57
40
  def self.get_violation_behavior(protection, metadata, package)
58
- behavior = ViolationBehavior.from_raw_value(metadata[protection.identifier])
59
- unmet_preconditions = protection.unmet_preconditions_for_behavior(behavior, package)
60
- if !unmet_preconditions.nil?
61
- raise IncorrectPublicApiUsageError.new("#{protection.identifier} protection does not have the valid preconditions. #{unmet_preconditions}. See https://github.com/rubyatscale/package_protections#readme for more info") # rubocop:disable Style/RaiseArgs
62
- end
63
-
64
- behavior
41
+ ViolationBehavior.from_raw_value(metadata[protection.identifier])
65
42
  end
66
43
 
67
44
  sig { params(key: Identifier).returns(ViolationBehavior) }
@@ -91,6 +91,49 @@ module PackageProtections
91
91
  ).compact
92
92
  end
93
93
 
94
+ sig do
95
+ returns(T::Array[String])
96
+ end
97
+ def self.validate!
98
+ errors = T.let([], T::Array[String])
99
+ valid_identifiers = PackageProtections.all.map(&:identifier)
100
+
101
+ ParsePackwerk.all.each do |p|
102
+ metadata = p.metadata['protections'] || {}
103
+
104
+ # Validate that there are no invalid keys
105
+ invalid_identifiers = metadata.keys - valid_identifiers
106
+ if invalid_identifiers.any?
107
+ errors << "Invalid configuration for package `#{p.name}`. The metadata keys #{invalid_identifiers.inspect} are not a valid behavior under the `protection` metadata namespace. Valid keys are #{valid_identifiers.inspect}. See https://github.com/rubyatscale/package_protections#readme for more info"
108
+ end
109
+
110
+ # Validate that all protections requiring configuration have explicit configuration
111
+ unspecified_protections = valid_identifiers - metadata.keys
112
+ protections_requiring_explicit_configuration = unspecified_protections.reject do |protection_key|
113
+ protection = PackageProtections.with_identifier(protection_key)
114
+ protection.default_behavior.fail_never?
115
+ end
116
+
117
+ protections_requiring_explicit_configuration.each do |protection_identifier|
118
+ errors << "All protections must explicitly set unless their default behavior is `fail_never`. Missing protection #{protection_identifier} for package #{p.name}."
119
+ end
120
+
121
+ # Validate that all protections have all preconditions met
122
+ metadata.each do |protection_identifier, value|
123
+ next if !valid_identifiers.include?(protection_identifier)
124
+
125
+ behavior = ViolationBehavior.from_raw_value(value)
126
+ protection = PackageProtections.with_identifier(protection_identifier)
127
+ unmet_preconditions = protection.unmet_preconditions_for_behavior(behavior, p)
128
+ if unmet_preconditions
129
+ errors << "#{protection_identifier} protection does not have the valid preconditions in #{p.name}. #{unmet_preconditions}. See https://github.com/rubyatscale/package_protections#readme for more info"
130
+ end
131
+ end
132
+ end
133
+
134
+ errors
135
+ end
136
+
94
137
  #
95
138
  # PackageProtections.set_defaults! sets any unset protections to their default enforcement
96
139
  #
@@ -34,7 +34,7 @@ module RuboCop
34
34
  enabled: include_packs.any?,
35
35
  metadata: {
36
36
  'IncludePacks' => include_packs,
37
- 'GloballyPermittedNamespaces' => ::PackageProtections.config.globally_permitted_namespaces
37
+ 'GloballyPermittedNamespaces' => ::RuboCop::Packs.config.globally_permitted_namespaces
38
38
  }
39
39
  )
40
40
  ]
@@ -57,23 +57,19 @@ module RuboCop
57
57
 
58
58
  sig { override.params(behavior: ::PackageProtections::ViolationBehavior, package: ParsePackwerk::Package).returns(T.nilable(String)) }
59
59
  def unmet_preconditions_for_behavior(behavior, package)
60
- if !behavior.enabled? && !package.metadata['global_namespaces'].nil?
61
- "Invalid configuration for package `#{package.name}`. `#{identifier}` must be turned on to use `global_namespaces` configuration."
62
- else
63
- # We don't need to validate if the behavior is currentely fail_never
64
- return if behavior.fail_never?
60
+ # We don't need to validate if the behavior is currentely fail_never
61
+ return if behavior.fail_never?
65
62
 
66
- # The reason for this is precondition is the `MultipleNamespacesProtection` assumes this to work properly.
67
- # To remove this precondition, we need to modify `MultipleNamespacesProtection` to be more generalized!
68
- is_root_package = package.name == ParsePackwerk::ROOT_PACKAGE_NAME
69
- in_allowed_directory = ::PackageProtections::EXPECTED_PACK_DIRECTORIES.any? do |expected_package_directory|
70
- package.directory.to_s.start_with?(expected_package_directory)
71
- end
72
- if in_allowed_directory || is_root_package
73
- nil
74
- else
75
- "Package #{package.name} must be located in one of #{::PackageProtections::EXPECTED_PACK_DIRECTORIES.join(', ')} (or be the root) to use this protection"
76
- end
63
+ # The reason for this is precondition is the `MultipleNamespacesProtection` assumes this to work properly.
64
+ # To remove this precondition, we need to modify `MultipleNamespacesProtection` to be more generalized!
65
+ is_root_package = package.name == ParsePackwerk::ROOT_PACKAGE_NAME
66
+ in_allowed_directory = ::PackageProtections::EXPECTED_PACK_DIRECTORIES.any? do |expected_package_directory|
67
+ package.directory.to_s.start_with?(expected_package_directory)
68
+ end
69
+ if in_allowed_directory || is_root_package
70
+ nil
71
+ else
72
+ "Package #{package.name} must be located in one of #{::PackageProtections::EXPECTED_PACK_DIRECTORIES.join(', ')} (or be the root) to use this protection"
77
73
  end
78
74
  end
79
75
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: package_protections
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.2
4
+ version: 3.1.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-09 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: activesupport
@@ -232,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
232
  - !ruby/object:Gem::Version
233
233
  version: '0'
234
234
  requirements: []
235
- rubygems_version: 3.3.7
235
+ rubygems_version: 3.1.6
236
236
  signing_key:
237
237
  specification_version: 4
238
238
  summary: Package protections for Rails apps