packwerk-extensions 0.1.7 → 0.1.8
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/README.md +43 -1
- data/lib/packwerk/folder_visibility/checker.rb +93 -0
- data/lib/packwerk/folder_visibility/package.rb +23 -0
- data/lib/packwerk/folder_visibility/validator.rb +36 -0
- data/lib/packwerk-extensions.rb +1 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 077e4a805c3061339f9c18e26d1768bbe3c3966e9e4c958b078ba1bcd0292c07
|
4
|
+
data.tar.gz: c292cb8cb900a9746d20e426a94ca89fc2a55cea542662812cb14f450466ae55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 601a651716181f5da48a302a7dd3b9a5eb3d46fa81a13ebd7138602aef8c11576344d724a2907b7bb950161ba11f0bb2a68207a9338de4b4e780c569320e8900
|
7
|
+
data.tar.gz: 288a0af58508deebdc3904a4a716ff933c837f4ca1cf840ece8ef8f4509936dfc6839fa7737e0f6d5805a007a00803dcafde59054a8e4089a11228a1d4b2486e
|
data/README.md
CHANGED
@@ -5,7 +5,8 @@
|
|
5
5
|
Currently, it ships the following checkers to help improve the boundaries between packages. These checkers are:
|
6
6
|
- A `privacy` checker that ensures other packages are using your package's public API
|
7
7
|
- A `visibility` checker that allows packages to be private except to an explicit group of other packages.
|
8
|
-
-
|
8
|
+
- A `folder_visibility` checker that allows packages to their sibling packs and parent pack (to be used in an application that uses folder packs)
|
9
|
+
- An `architecture` checker that allows packages to specify their "layer" and requires that each layer only communicate with layers below it.
|
9
10
|
|
10
11
|
## Installation
|
11
12
|
|
@@ -24,6 +25,7 @@ Alternatively, you can require individual checkers:
|
|
24
25
|
require:
|
25
26
|
- packwerk/privacy/checker
|
26
27
|
- packwerk/visibility/checker
|
28
|
+
- packwerk/folder_visibility/checker
|
27
29
|
- packwerk/architecture/checker
|
28
30
|
```
|
29
31
|
|
@@ -87,6 +89,30 @@ visible_to:
|
|
87
89
|
- components/other_package
|
88
90
|
```
|
89
91
|
|
92
|
+
## Folder-Visibility Checker
|
93
|
+
The folder visibility checker can be used to allow a package to be private to their sibling packs and parent packs and will create todos if used by any other package.
|
94
|
+
|
95
|
+
To enforce visibility for your package, set `enforce_folder_visibility` to `true` on your pack.
|
96
|
+
|
97
|
+
```yaml
|
98
|
+
# components/merchandising/package.yml
|
99
|
+
enforce_folder_visibility: true
|
100
|
+
```
|
101
|
+
|
102
|
+
Here is an example of paths and whether their use of `packs/b/packs/e` is OK or not, assuming that protects itself via `enforce_folder_visibility`
|
103
|
+
|
104
|
+
```
|
105
|
+
. OK (parent of parent)
|
106
|
+
packs/a VIOLATION
|
107
|
+
packs/b OK (parent)
|
108
|
+
packs/b/packs/d OK (sibling)
|
109
|
+
packs/b/packs/e ENFORCE_NESTED_VISIBILITY: TRUE
|
110
|
+
packs/b/packs/e/packs/f VIOLATION
|
111
|
+
packs/b/packs/e/packs/g VIOLATION
|
112
|
+
packs/b/packs/h OK (sibling)
|
113
|
+
packs/c VIOLATION
|
114
|
+
```
|
115
|
+
|
90
116
|
## Architecture Checker
|
91
117
|
The architecture checker can be used to enforce constraints on what can depend on what.
|
92
118
|
|
@@ -105,3 +131,19 @@ layer: utility
|
|
105
131
|
```
|
106
132
|
|
107
133
|
Now this pack can only depend on other utility packages.
|
134
|
+
|
135
|
+
|
136
|
+
## Contributing
|
137
|
+
|
138
|
+
Got another checker you would like to add? Add it to this repo!
|
139
|
+
|
140
|
+
Please ensure these commands pass for you locally:
|
141
|
+
|
142
|
+
```
|
143
|
+
bundle
|
144
|
+
srb tc
|
145
|
+
bin/rubocop
|
146
|
+
bin/rake test
|
147
|
+
```
|
148
|
+
|
149
|
+
Then, submit a PR!
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'packwerk/folder_visibility/package'
|
5
|
+
require 'packwerk/folder_visibility/validator'
|
6
|
+
|
7
|
+
module Packwerk
|
8
|
+
module FolderVisibility
|
9
|
+
class Checker
|
10
|
+
extend T::Sig
|
11
|
+
include Packwerk::Checker
|
12
|
+
|
13
|
+
VIOLATION_TYPE = T.let('folder_visibility', String)
|
14
|
+
|
15
|
+
sig { override.returns(String) }
|
16
|
+
def violation_type
|
17
|
+
VIOLATION_TYPE
|
18
|
+
end
|
19
|
+
|
20
|
+
sig do
|
21
|
+
override
|
22
|
+
.params(reference: Packwerk::Reference)
|
23
|
+
.returns(T::Boolean)
|
24
|
+
end
|
25
|
+
def invalid_reference?(reference)
|
26
|
+
referencing_package = reference.package
|
27
|
+
referenced_package = reference.constant.package
|
28
|
+
|
29
|
+
return false if enforcement_disabled?(Package.from(referenced_package).enforce_folder_visibility)
|
30
|
+
|
31
|
+
# the root pack is parent folder of all packs, so we short-circuit this here
|
32
|
+
referencing_package_is_root_pack = referencing_package.name == '.'
|
33
|
+
return false if referencing_package_is_root_pack
|
34
|
+
|
35
|
+
packages_are_sibling_folders = Pathname.new(referenced_package.name).dirname == Pathname.new(referencing_package.name).dirname
|
36
|
+
return false if packages_are_sibling_folders
|
37
|
+
|
38
|
+
referencing_package_is_parent_folder = Pathname.new(referenced_package.name).to_s.start_with?(referencing_package.name)
|
39
|
+
return false if referencing_package_is_parent_folder
|
40
|
+
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
sig do
|
45
|
+
override
|
46
|
+
.params(listed_offense: Packwerk::ReferenceOffense)
|
47
|
+
.returns(T::Boolean)
|
48
|
+
end
|
49
|
+
def strict_mode_violation?(listed_offense)
|
50
|
+
publishing_package = listed_offense.reference.constant.package
|
51
|
+
publishing_package.config['enforce_folder_visibility'] == 'strict'
|
52
|
+
end
|
53
|
+
|
54
|
+
sig do
|
55
|
+
override
|
56
|
+
.params(reference: Packwerk::Reference)
|
57
|
+
.returns(String)
|
58
|
+
end
|
59
|
+
def message(reference)
|
60
|
+
source_desc = "'#{reference.package}'"
|
61
|
+
|
62
|
+
message = <<~MESSAGE
|
63
|
+
Folder Visibility violation: '#{reference.constant.name}' belongs to '#{reference.constant.package}', which is not visible to #{source_desc} as it is not a sibling pack or parent pack.
|
64
|
+
Is there a different package to use instead, or should '#{reference.constant.package}' also be visible to #{source_desc}?
|
65
|
+
|
66
|
+
#{standard_help_message(reference)}
|
67
|
+
MESSAGE
|
68
|
+
|
69
|
+
message.chomp
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
sig do
|
75
|
+
params(visibility_option: T.nilable(T.any(T::Boolean, String)))
|
76
|
+
.returns(T::Boolean)
|
77
|
+
end
|
78
|
+
def enforcement_disabled?(visibility_option)
|
79
|
+
[false, nil].include?(visibility_option)
|
80
|
+
end
|
81
|
+
|
82
|
+
sig { params(reference: Reference).returns(String) }
|
83
|
+
def standard_help_message(reference)
|
84
|
+
standard_message = <<~MESSAGE.chomp
|
85
|
+
Inference details: this is a reference to #{reference.constant.name} which seems to be defined in #{reference.constant.location}.
|
86
|
+
To receive help interpreting or resolving this error message, see: https://github.com/Shopify/packwerk/blob/main/TROUBLESHOOT.md#Troubleshooting-violations
|
87
|
+
MESSAGE
|
88
|
+
|
89
|
+
standard_message.chomp
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Packwerk
|
5
|
+
module FolderVisibility
|
6
|
+
class Package < T::Struct
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
const :enforce_folder_visibility, T.nilable(T.any(T::Boolean, String))
|
10
|
+
|
11
|
+
class << self
|
12
|
+
extend T::Sig
|
13
|
+
|
14
|
+
sig { params(package: ::Packwerk::Package).returns(Package) }
|
15
|
+
def from(package)
|
16
|
+
Package.new(
|
17
|
+
enforce_folder_visibility: package.config['enforce_folder_visibility']
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Packwerk
|
5
|
+
module FolderVisibility
|
6
|
+
class Validator
|
7
|
+
extend T::Sig
|
8
|
+
include Packwerk::Validator
|
9
|
+
|
10
|
+
Result = Packwerk::Validator::Result
|
11
|
+
|
12
|
+
sig { override.params(package_set: PackageSet, configuration: Configuration).returns(Result) }
|
13
|
+
def call(package_set, configuration)
|
14
|
+
results = T.let([], T::Array[Result])
|
15
|
+
|
16
|
+
package_manifests_settings_for(configuration, 'enforce_folder_visibility').each do |config, setting|
|
17
|
+
next if setting.nil?
|
18
|
+
|
19
|
+
next if [TrueClass, FalseClass].include?(setting.class) || setting == 'strict'
|
20
|
+
|
21
|
+
results << Result.new(
|
22
|
+
ok: false,
|
23
|
+
error_value: "\tInvalid 'enforce_folder_visibility' option: #{setting.inspect} in #{config.inspect}"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
merge_results(results, separator: "\n---\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
sig { override.returns(T::Array[String]) }
|
31
|
+
def permitted_keys
|
32
|
+
%w[enforce_folder_visibility]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/packwerk-extensions.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packwerk-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gusto Engineers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: packwerk
|
@@ -191,6 +191,9 @@ files:
|
|
191
191
|
- lib/packwerk/architecture/layers.rb
|
192
192
|
- lib/packwerk/architecture/package.rb
|
193
193
|
- lib/packwerk/architecture/validator.rb
|
194
|
+
- lib/packwerk/folder_visibility/checker.rb
|
195
|
+
- lib/packwerk/folder_visibility/package.rb
|
196
|
+
- lib/packwerk/folder_visibility/validator.rb
|
194
197
|
- lib/packwerk/privacy/checker.rb
|
195
198
|
- lib/packwerk/privacy/package.rb
|
196
199
|
- lib/packwerk/privacy/validator.rb
|