packwerk 3.2.2 → 3.3.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 +4 -4
- data/exe/packwerk +0 -4
- data/lib/packwerk/application_validator.rb +13 -11
- data/lib/packwerk/association_inspector.rb +21 -32
- data/lib/packwerk/cache.rb +43 -36
- data/lib/packwerk/checker.rb +24 -26
- data/lib/packwerk/cli.rb +13 -20
- data/lib/packwerk/commands/base_command.rb +20 -26
- data/lib/packwerk/commands/check_command.rb +8 -8
- data/lib/packwerk/commands/help_command.rb +3 -4
- data/lib/packwerk/commands/init_command.rb +2 -3
- data/lib/packwerk/commands/lazy_loaded_entry.rb +5 -7
- data/lib/packwerk/commands/update_todo_command.rb +3 -3
- data/lib/packwerk/commands/uses_parse_run.rb +20 -26
- data/lib/packwerk/commands/validate_command.rb +6 -7
- data/lib/packwerk/commands/version_command.rb +2 -3
- data/lib/packwerk/commands.rb +5 -8
- data/lib/packwerk/configuration.rb +29 -43
- data/lib/packwerk/const_node_inspector.rb +5 -9
- data/lib/packwerk/constant_context.rb +0 -2
- data/lib/packwerk/constant_discovery.rb +3 -16
- data/lib/packwerk/constant_name_inspector.rb +4 -11
- data/lib/packwerk/extension_loader.rb +1 -2
- data/lib/packwerk/file_processor.rb +20 -25
- data/lib/packwerk/files_for_processing.rb +13 -29
- data/lib/packwerk/formatters/default_offenses_formatter.rb +14 -12
- data/lib/packwerk/formatters/progress_formatter.rb +10 -12
- data/lib/packwerk/generators/configuration_file.rb +5 -9
- data/lib/packwerk/generators/root_package.rb +3 -7
- data/lib/packwerk/graph.rb +14 -61
- data/lib/packwerk/node_helpers.rb +32 -38
- data/lib/packwerk/node_processor.rb +2 -14
- data/lib/packwerk/node_processor_factory.rb +13 -7
- data/lib/packwerk/node_visitor.rb +2 -10
- data/lib/packwerk/offense.rb +6 -12
- data/lib/packwerk/offense_collection.rb +22 -35
- data/lib/packwerk/offenses_formatter.rb +27 -34
- data/lib/packwerk/output_style.rb +10 -11
- data/lib/packwerk/output_styles/coloured.rb +6 -4
- data/lib/packwerk/output_styles/plain.rb +6 -4
- data/lib/packwerk/package.rb +15 -16
- data/lib/packwerk/package_set.rb +15 -25
- data/lib/packwerk/package_todo.rb +21 -30
- data/lib/packwerk/parse_run.rb +10 -37
- data/lib/packwerk/parsed_constant_definitions.rb +10 -24
- data/lib/packwerk/parsers/erb.rb +11 -22
- data/lib/packwerk/parsers/factory.rb +9 -9
- data/lib/packwerk/parsers/parser_interface.rb +5 -10
- data/lib/packwerk/parsers/ruby.rb +9 -14
- data/lib/packwerk/parsers.rb +2 -4
- data/lib/packwerk/rails_load_paths.rb +6 -11
- data/lib/packwerk/reference_checking/checkers/dependency_checker.rb +11 -17
- data/lib/packwerk/reference_checking/reference_checker.rb +2 -8
- data/lib/packwerk/reference_extractor.rb +22 -55
- data/lib/packwerk/reference_offense.rb +5 -15
- data/lib/packwerk/run_context.rb +32 -38
- data/lib/packwerk/spring_command.rb +4 -7
- data/lib/packwerk/validator/result.rb +12 -5
- data/lib/packwerk/validator.rb +23 -33
- data/lib/packwerk/validators/dependency_validator.rb +14 -14
- data/lib/packwerk/version.rb +1 -1
- data/lib/packwerk.rb +0 -1
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/{actionpack@7.0.3.1.rbi → actionpack@7.0.8.7.rbi} +1338 -1227
- data/sorbet/rbi/gems/{actionview@7.0.3.1.rbi → actionview@7.0.8.7.rbi} +548 -503
- data/sorbet/rbi/gems/{activesupport@7.0.3.1.rbi → activesupport@7.0.8.7.rbi} +714 -635
- data/sorbet/rbi/gems/{better_html@2.0.1.rbi → better_html@2.1.1.rbi} +21 -21
- data/sorbet/rbi/gems/{concurrent-ruby@1.1.10.rbi → concurrent-ruby@1.3.5.rbi} +1390 -1366
- data/sorbet/rbi/gems/{constant_resolver@0.2.0.rbi → constant_resolver@0.3.0.rbi} +22 -13
- data/sorbet/rbi/gems/{erubi@1.11.0.rbi → erubi@1.13.1.rbi} +28 -17
- data/sorbet/rbi/gems/{i18n@1.12.0.rbi → i18n@1.14.7.rbi} +234 -172
- data/sorbet/rbi/gems/{json@2.6.2.rbi → json@2.7.2.rbi} +94 -74
- data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +14237 -0
- data/sorbet/rbi/gems/{loofah@2.18.0.rbi → loofah@2.24.0.rbi} +470 -243
- data/sorbet/rbi/gems/{minitest@5.16.2.rbi → minitest@5.25.4.rbi} +577 -472
- data/sorbet/rbi/gems/{mocha@1.14.0.rbi → mocha@2.5.0.rbi} +468 -684
- data/sorbet/rbi/gems/{nokogiri@1.15.3.rbi → nokogiri@1.18.4.rbi} +1756 -869
- data/sorbet/rbi/gems/{parallel@1.24.0.rbi → parallel@1.25.1.rbi} +26 -20
- data/sorbet/rbi/gems/prism@1.9.0.rbi +43359 -0
- data/sorbet/rbi/gems/{racc@1.7.1.rbi → racc@1.8.1.rbi} +36 -36
- data/sorbet/rbi/gems/{rack-test@2.0.2.rbi → rack-test@2.2.0.rbi} +87 -114
- data/sorbet/rbi/gems/{rack@2.2.4.rbi → rack@2.2.13.rbi} +243 -195
- data/sorbet/rbi/gems/rails-dom-testing@2.2.0.rbi +754 -0
- data/sorbet/rbi/gems/rails-html-sanitizer@1.6.2.rbi +764 -0
- data/sorbet/rbi/gems/{railties@7.0.3.1.rbi → railties@7.0.8.7.rbi} +146 -140
- data/sorbet/rbi/gems/{regexp_parser@2.5.0.rbi → regexp_parser@2.9.2.rbi} +947 -542
- data/sorbet/rbi/gems/{rexml@3.2.5.rbi → rexml@3.3.9.rbi} +452 -312
- data/sorbet/rbi/gems/{rubocop-ast@1.21.0.rbi → rubocop-ast@1.31.3.rbi} +717 -588
- data/sorbet/rbi/gems/{rubocop@1.34.1.rbi → rubocop@1.64.1.rbi} +10916 -4406
- data/sorbet/rbi/gems/{ruby-progressbar@1.11.0.rbi → ruby-progressbar@1.13.0.rbi} +359 -281
- data/sorbet/rbi/gems/ruby2_keywords@0.0.5.rbi +8 -0
- data/sorbet/rbi/gems/{tzinfo@2.0.5.rbi → tzinfo@2.0.6.rbi} +144 -141
- data/sorbet/rbi/gems/{unicode-display_width@2.2.0.rbi → unicode-display_width@2.5.0.rbi} +24 -7
- data/sorbet/rbi/shims/packwerk/reference.rbi +5 -12
- data/sorbet/rbi/shims/packwerk/unresolved_reference.rbi +5 -12
- data/sorbet/rbi/shims/parser.rbi +1 -1
- metadata +50 -56
- data/lib/packwerk/disable_sorbet.rb +0 -41
- data/sorbet/rbi/gems/language_server-protocol@3.16.0.3.rbi +0 -8
- data/sorbet/rbi/gems/prettier_print@0.1.0.rbi +0 -8
- data/sorbet/rbi/gems/prism@0.27.0.rbi +0 -36983
- data/sorbet/rbi/gems/rails-dom-testing@2.0.3.rbi +0 -455
- data/sorbet/rbi/gems/rails-html-sanitizer@1.4.3.rbi +0 -542
- data/sorbet/rbi/gems/ruby-lsp@0.2.3.rbi +0 -11
- data/sorbet/rbi/gems/syntax_tree@3.3.0.rbi +0 -8
- /data/sorbet/rbi/gems/{builder@3.2.4.rbi → builder@3.3.0.rbi} +0 -0
- /data/sorbet/rbi/gems/{parser@3.3.1.0.rbi → parser@3.3.3.0.rbi} +0 -0
|
@@ -4,19 +4,10 @@
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
# Extracts a possible constant reference from a given AST node.
|
|
6
6
|
class ReferenceExtractor
|
|
7
|
-
extend T::Sig
|
|
8
|
-
|
|
9
7
|
class << self
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
sig do
|
|
13
|
-
params(
|
|
14
|
-
unresolved_references: T::Array[UnresolvedReference],
|
|
15
|
-
context_provider: ConstantDiscovery
|
|
16
|
-
).returns(T::Array[Reference])
|
|
17
|
-
end
|
|
8
|
+
#: (Array[UnresolvedReference] unresolved_references, ConstantDiscovery context_provider) -> Array[Reference]
|
|
18
9
|
def get_fully_qualified_references_from(unresolved_references, context_provider)
|
|
19
|
-
fully_qualified_references =
|
|
10
|
+
fully_qualified_references = [] #: Array[Reference]
|
|
20
11
|
|
|
21
12
|
unresolved_references.each do |unresolved_references_or_offense|
|
|
22
13
|
unresolved_reference = unresolved_references_or_offense
|
|
@@ -49,13 +40,7 @@ module Packwerk
|
|
|
49
40
|
end
|
|
50
41
|
end
|
|
51
42
|
|
|
52
|
-
|
|
53
|
-
params(
|
|
54
|
-
constant_name_inspectors: T::Array[ConstantNameInspector],
|
|
55
|
-
root_node: AST::Node,
|
|
56
|
-
root_path: String,
|
|
57
|
-
).void
|
|
58
|
-
end
|
|
43
|
+
#: (constant_name_inspectors: Array[ConstantNameInspector], root_node: AST::Node, root_path: String) -> void
|
|
59
44
|
def initialize(
|
|
60
45
|
constant_name_inspectors:,
|
|
61
46
|
root_node:,
|
|
@@ -63,21 +48,12 @@ module Packwerk
|
|
|
63
48
|
)
|
|
64
49
|
@constant_name_inspectors = constant_name_inspectors
|
|
65
50
|
@root_path = root_path
|
|
66
|
-
@local_constant_definitions =
|
|
67
|
-
ParsedConstantDefinitions.new(root_node: root_node),
|
|
68
|
-
ParsedConstantDefinitions,
|
|
69
|
-
)
|
|
51
|
+
@local_constant_definitions = ParsedConstantDefinitions.new(root_node: root_node) #: ParsedConstantDefinitions
|
|
70
52
|
end
|
|
71
53
|
|
|
72
|
-
|
|
73
|
-
params(
|
|
74
|
-
node: Parser::AST::Node,
|
|
75
|
-
ancestors: T::Array[Parser::AST::Node],
|
|
76
|
-
relative_file: String
|
|
77
|
-
).returns(T.nilable(UnresolvedReference))
|
|
78
|
-
end
|
|
54
|
+
#: (Parser::AST::Node node, ancestors: Array[Parser::AST::Node], relative_file: String) -> UnresolvedReference?
|
|
79
55
|
def reference_from_node(node, ancestors:, relative_file:)
|
|
80
|
-
constant_name =
|
|
56
|
+
constant_name = nil #: String?
|
|
81
57
|
|
|
82
58
|
@constant_name_inspectors.each do |inspector|
|
|
83
59
|
constant_name = inspect_node(
|
|
@@ -102,21 +78,20 @@ module Packwerk
|
|
|
102
78
|
|
|
103
79
|
private
|
|
104
80
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
).returns(T.nilable(String))
|
|
112
|
-
end
|
|
81
|
+
#: (
|
|
82
|
+
#| ConstantNameInspector inspector,
|
|
83
|
+
#| node: Parser::AST::Node,
|
|
84
|
+
#| ancestors: Array[Parser::AST::Node],
|
|
85
|
+
#| relative_file: String
|
|
86
|
+
#| ) -> String?
|
|
113
87
|
def inspect_node(inspector, node:, ancestors:, relative_file:)
|
|
114
88
|
inspector.constant_name_from_node(node, ancestors: ancestors, relative_file: relative_file)
|
|
115
89
|
rescue ArgumentError => error
|
|
116
90
|
if error.message == "unknown keyword: :relative_file"
|
|
117
|
-
|
|
91
|
+
inspector_ = inspector #: as untyped
|
|
92
|
+
inspector_.constant_name_from_node(node, ancestors: ancestors).tap do
|
|
118
93
|
warn(<<~MSG.squish)
|
|
119
|
-
#{
|
|
94
|
+
#{inspector_.class}#reference_from_node without a relative_file: keyword
|
|
120
95
|
argument is deprecated and will be required in Packwerk 3.1.1.
|
|
121
96
|
MSG
|
|
122
97
|
end
|
|
@@ -125,14 +100,12 @@ module Packwerk
|
|
|
125
100
|
end
|
|
126
101
|
end
|
|
127
102
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
).returns(T.nilable(UnresolvedReference))
|
|
135
|
-
end
|
|
103
|
+
#: (
|
|
104
|
+
#| String constant_name,
|
|
105
|
+
#| node: Parser::AST::Node,
|
|
106
|
+
#| ancestors: Array[Parser::AST::Node],
|
|
107
|
+
#| relative_file: String
|
|
108
|
+
#| ) -> UnresolvedReference?
|
|
136
109
|
def reference_from_constant(constant_name, node:, ancestors:, relative_file:)
|
|
137
110
|
namespace_path = NodeHelpers.enclosing_namespace_path(node, ancestors: ancestors)
|
|
138
111
|
|
|
@@ -148,13 +121,7 @@ module Packwerk
|
|
|
148
121
|
)
|
|
149
122
|
end
|
|
150
123
|
|
|
151
|
-
|
|
152
|
-
params(
|
|
153
|
-
constant_name: String,
|
|
154
|
-
name_location: T.nilable(Node::Location),
|
|
155
|
-
namespace_path: T::Array[String],
|
|
156
|
-
).returns(T::Boolean)
|
|
157
|
-
end
|
|
124
|
+
#: (String constant_name, Node::Location? name_location, Array[String] namespace_path) -> bool
|
|
158
125
|
def local_reference?(constant_name, name_location, namespace_path)
|
|
159
126
|
@local_constant_definitions.local_reference?(
|
|
160
127
|
constant_name,
|
|
@@ -4,26 +4,16 @@
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
# An offense related to a {Packwerk::Reference}.
|
|
6
6
|
class ReferenceOffense < Offense
|
|
7
|
-
|
|
8
|
-
extend T::Helpers
|
|
9
|
-
|
|
10
|
-
sig { returns(Reference) }
|
|
7
|
+
#: Reference
|
|
11
8
|
attr_reader :reference
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
#: String
|
|
14
11
|
attr_reader :violation_type
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
params(
|
|
18
|
-
reference: Packwerk::Reference,
|
|
19
|
-
violation_type: String,
|
|
20
|
-
message: String,
|
|
21
|
-
location: T.nilable(Node::Location)
|
|
22
|
-
)
|
|
23
|
-
.void
|
|
24
|
-
end
|
|
13
|
+
#: (reference: Packwerk::Reference, violation_type: String, message: String, ?location: Node::Location?) -> void
|
|
25
14
|
def initialize(reference:, violation_type:, message:, location: nil)
|
|
26
|
-
|
|
15
|
+
file = reference.relative_path #: as !nil
|
|
16
|
+
super(file: file, message: message, location: location)
|
|
27
17
|
@reference = reference
|
|
28
18
|
@violation_type = violation_type
|
|
29
19
|
end
|
data/lib/packwerk/run_context.rb
CHANGED
|
@@ -6,22 +6,17 @@ require "constant_resolver"
|
|
|
6
6
|
module Packwerk
|
|
7
7
|
# Holds the context of a Packwerk run across multiple files.
|
|
8
8
|
class RunContext
|
|
9
|
-
extend T::Sig
|
|
10
|
-
|
|
11
9
|
class << self
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
sig do
|
|
15
|
-
params(configuration: Configuration).returns(RunContext)
|
|
16
|
-
end
|
|
10
|
+
#: (Configuration configuration) -> RunContext
|
|
17
11
|
def from_configuration(configuration)
|
|
18
12
|
new(
|
|
19
13
|
root_path: configuration.root_path,
|
|
20
14
|
load_paths: configuration.load_paths,
|
|
21
15
|
package_paths: configuration.package_paths,
|
|
22
16
|
inflector: ActiveSupport::Inflector,
|
|
23
|
-
custom_associations: configuration.custom_associations,
|
|
17
|
+
custom_associations: configuration.custom_associations.to_set,
|
|
24
18
|
associations_exclude: configuration.associations_exclude,
|
|
19
|
+
exclude: configuration.exclude,
|
|
25
20
|
cache_enabled: configuration.cache_enabled?,
|
|
26
21
|
cache_directory: configuration.cache_directory,
|
|
27
22
|
config_path: configuration.config_path,
|
|
@@ -29,20 +24,19 @@ module Packwerk
|
|
|
29
24
|
end
|
|
30
25
|
end
|
|
31
26
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
end
|
|
27
|
+
#: (
|
|
28
|
+
#| root_path: String,
|
|
29
|
+
#| load_paths: Hash[String, Module[top]],
|
|
30
|
+
#| inflector: singleton(ActiveSupport::Inflector),
|
|
31
|
+
#| cache_directory: Pathname,
|
|
32
|
+
#| ?config_path: String?,
|
|
33
|
+
#| ?package_paths: (Array[String] | String)?,
|
|
34
|
+
#| ?custom_associations: Set[Symbol],
|
|
35
|
+
#| ?associations_exclude: Array[String],
|
|
36
|
+
#| ?exclude: Array[String],
|
|
37
|
+
#| ?checkers: Array[Checker],
|
|
38
|
+
#| ?cache_enabled: bool
|
|
39
|
+
#| ) -> void
|
|
46
40
|
def initialize(
|
|
47
41
|
root_path:,
|
|
48
42
|
load_paths:,
|
|
@@ -50,8 +44,9 @@ module Packwerk
|
|
|
50
44
|
cache_directory:,
|
|
51
45
|
config_path: nil,
|
|
52
46
|
package_paths: nil,
|
|
53
|
-
custom_associations:
|
|
47
|
+
custom_associations: Set.new,
|
|
54
48
|
associations_exclude: [],
|
|
49
|
+
exclude: [],
|
|
55
50
|
checkers: Checker.all,
|
|
56
51
|
cache_enabled: false
|
|
57
52
|
)
|
|
@@ -65,17 +60,16 @@ module Packwerk
|
|
|
65
60
|
@cache_enabled = cache_enabled
|
|
66
61
|
@cache_directory = cache_directory
|
|
67
62
|
@config_path = config_path
|
|
63
|
+
@exclude = exclude
|
|
68
64
|
|
|
69
|
-
@file_processor =
|
|
70
|
-
@context_provider =
|
|
71
|
-
@package_set =
|
|
65
|
+
@file_processor = nil #: FileProcessor?
|
|
66
|
+
@context_provider = nil #: ConstantDiscovery?
|
|
67
|
+
@package_set = nil #: PackageSet?
|
|
72
68
|
# We need to initialize this before we fork the process, see https://github.com/Shopify/packwerk/issues/182
|
|
73
|
-
@cache =
|
|
74
|
-
Cache.new(enable_cache: @cache_enabled, cache_directory: @cache_directory, config_path: @config_path), Cache
|
|
75
|
-
)
|
|
69
|
+
@cache = Cache.new(enable_cache: @cache_enabled, cache_directory: @cache_directory, config_path: @config_path) #: Cache
|
|
76
70
|
end
|
|
77
71
|
|
|
78
|
-
|
|
72
|
+
#: (relative_file: String) -> Array[Packwerk::Offense]
|
|
79
73
|
def process_file(relative_file:)
|
|
80
74
|
processed_file = file_processor.call(relative_file)
|
|
81
75
|
|
|
@@ -88,28 +82,27 @@ module Packwerk
|
|
|
88
82
|
processed_file.offenses + references.flat_map { |reference| reference_checker.call(reference) }
|
|
89
83
|
end
|
|
90
84
|
|
|
91
|
-
|
|
85
|
+
#: -> PackageSet
|
|
92
86
|
def package_set
|
|
93
87
|
@package_set ||= ::Packwerk::PackageSet.load_all_from(@root_path, package_pathspec: @package_paths)
|
|
94
88
|
end
|
|
95
89
|
|
|
96
90
|
private
|
|
97
91
|
|
|
98
|
-
|
|
92
|
+
#: -> FileProcessor
|
|
99
93
|
def file_processor
|
|
100
94
|
@file_processor ||= FileProcessor.new(node_processor_factory: node_processor_factory, cache: @cache)
|
|
101
95
|
end
|
|
102
96
|
|
|
103
|
-
|
|
97
|
+
#: -> NodeProcessorFactory
|
|
104
98
|
def node_processor_factory
|
|
105
99
|
NodeProcessorFactory.new(
|
|
106
|
-
context_provider: context_provider,
|
|
107
100
|
root_path: @root_path,
|
|
108
101
|
constant_name_inspectors: constant_name_inspectors
|
|
109
102
|
)
|
|
110
103
|
end
|
|
111
104
|
|
|
112
|
-
|
|
105
|
+
#: -> ConstantDiscovery
|
|
113
106
|
def context_provider
|
|
114
107
|
@context_provider ||= ConstantDiscovery.new(
|
|
115
108
|
constant_resolver: resolver,
|
|
@@ -117,16 +110,17 @@ module Packwerk
|
|
|
117
110
|
)
|
|
118
111
|
end
|
|
119
112
|
|
|
120
|
-
|
|
113
|
+
#: -> ConstantResolver
|
|
121
114
|
def resolver
|
|
122
115
|
ConstantResolver.new(
|
|
123
116
|
root_path: @root_path,
|
|
124
117
|
load_paths: @load_paths,
|
|
125
118
|
inflector: @inflector,
|
|
119
|
+
exclude: @exclude,
|
|
126
120
|
)
|
|
127
121
|
end
|
|
128
122
|
|
|
129
|
-
|
|
123
|
+
#: -> Array[ConstantNameInspector]
|
|
130
124
|
def constant_name_inspectors
|
|
131
125
|
[
|
|
132
126
|
ConstNodeInspector.new,
|
|
@@ -138,7 +132,7 @@ module Packwerk
|
|
|
138
132
|
]
|
|
139
133
|
end
|
|
140
134
|
|
|
141
|
-
|
|
135
|
+
#: (Array[String] relative_globs) -> FilesForProcessing::relative_file_set
|
|
142
136
|
def relative_files_for_globs(relative_globs)
|
|
143
137
|
Set.new(relative_globs.flat_map { |glob| Dir[glob] })
|
|
144
138
|
end
|
|
@@ -2,30 +2,27 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "spring/commands"
|
|
5
|
-
require "sorbet-runtime"
|
|
6
5
|
|
|
7
6
|
module Packwerk
|
|
8
7
|
class SpringCommand
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
sig { params(args: T.untyped).returns(String) }
|
|
8
|
+
#: (untyped args) -> String
|
|
12
9
|
def env(args)
|
|
13
10
|
# Packwerk needs to run in a test environment, which has a set of autoload paths that are
|
|
14
11
|
# often a superset of the dev/prod paths (for example, test/support/helpers)
|
|
15
12
|
"test"
|
|
16
13
|
end
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
#: -> String
|
|
19
16
|
def exec_name
|
|
20
17
|
"packwerk"
|
|
21
18
|
end
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
#: -> String
|
|
24
21
|
def gem_name
|
|
25
22
|
"packwerk"
|
|
26
23
|
end
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
#: -> bool
|
|
29
26
|
def call
|
|
30
27
|
load(Gem.bin_path(gem_name, exec_name))
|
|
31
28
|
end
|
|
@@ -3,13 +3,20 @@
|
|
|
3
3
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
module Validator
|
|
6
|
-
class Result
|
|
7
|
-
|
|
6
|
+
class Result
|
|
7
|
+
#: bool
|
|
8
|
+
attr_reader :ok
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
#: String?
|
|
11
|
+
attr_reader :error_value
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
#: (ok: bool, ?error_value: String?) -> void
|
|
14
|
+
def initialize(ok:, error_value: nil)
|
|
15
|
+
@ok = ok
|
|
16
|
+
@error_value = error_value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#: -> bool
|
|
13
20
|
def ok?
|
|
14
21
|
ok
|
|
15
22
|
end
|
data/lib/packwerk/validator.rb
CHANGED
|
@@ -6,78 +6,68 @@ require "pathname"
|
|
|
6
6
|
require "yaml"
|
|
7
7
|
|
|
8
8
|
module Packwerk
|
|
9
|
+
# @abstract
|
|
9
10
|
module Validator
|
|
10
|
-
extend T::Sig
|
|
11
|
-
extend T::Helpers
|
|
12
11
|
extend ActiveSupport::Autoload
|
|
13
12
|
|
|
14
13
|
autoload :Result
|
|
15
14
|
|
|
16
|
-
abstract!
|
|
17
|
-
|
|
18
15
|
class << self
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
sig { params(base: T::Class[T.anything]).void }
|
|
16
|
+
#: (Class[top] base) -> void
|
|
22
17
|
def included(base)
|
|
23
18
|
validators << base
|
|
24
19
|
end
|
|
25
20
|
|
|
26
|
-
|
|
21
|
+
#: -> Array[Validator]
|
|
27
22
|
def all
|
|
28
23
|
load_defaults
|
|
29
|
-
|
|
24
|
+
validators.map(&:new) #: as Array[Validator]
|
|
30
25
|
end
|
|
31
26
|
|
|
32
27
|
private
|
|
33
28
|
|
|
34
|
-
|
|
29
|
+
#: -> void
|
|
35
30
|
def load_defaults
|
|
36
31
|
require("packwerk/validators/dependency_validator")
|
|
37
32
|
end
|
|
38
33
|
|
|
39
|
-
|
|
34
|
+
#: -> Array[Class[top]]
|
|
40
35
|
def validators
|
|
41
|
-
@validators ||=
|
|
36
|
+
@validators ||= [] #: Array[Class[top]]?
|
|
42
37
|
end
|
|
43
38
|
end
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
# @abstract
|
|
41
|
+
#: -> Array[String]
|
|
42
|
+
def permitted_keys = raise NotImplementedError, "Abstract method called"
|
|
48
43
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
# @abstract
|
|
45
|
+
#: (PackageSet package_set, Configuration configuration) -> Validator::Result
|
|
46
|
+
def call(package_set, configuration) = raise NotImplementedError, "Abstract method called"
|
|
52
47
|
|
|
53
|
-
|
|
48
|
+
#: (Configuration configuration, untyped setting) -> untyped
|
|
54
49
|
def package_manifests_settings_for(configuration, setting)
|
|
55
50
|
package_manifests(configuration).map { |f| [f, (YAML.load_file(File.join(f)) || {})[setting]] }
|
|
56
51
|
end
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
params(configuration: Configuration,
|
|
60
|
-
glob_pattern: T.nilable(T.any(T::Array[String], String))).returns(T::Array[String])
|
|
61
|
-
end
|
|
53
|
+
#: (Configuration configuration, ?(Array[String] | String)? glob_pattern) -> Array[String]
|
|
62
54
|
def package_manifests(configuration, glob_pattern = nil)
|
|
63
55
|
glob_pattern ||= package_glob(configuration)
|
|
64
56
|
PackageSet.package_paths(configuration.root_path, glob_pattern, configuration.exclude)
|
|
65
57
|
.map { |f| File.realpath(f) }
|
|
66
58
|
end
|
|
67
59
|
|
|
68
|
-
|
|
60
|
+
#: (Configuration configuration) -> (Array[String] | String)
|
|
69
61
|
def package_glob(configuration)
|
|
70
62
|
configuration.package_paths
|
|
71
63
|
end
|
|
72
64
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
).returns(Validator::Result)
|
|
80
|
-
end
|
|
65
|
+
#: (
|
|
66
|
+
#| Array[Validator::Result] results,
|
|
67
|
+
#| ?separator: String,
|
|
68
|
+
#| ?before_errors: String,
|
|
69
|
+
#| ?after_errors: String
|
|
70
|
+
#| ) -> Validator::Result
|
|
81
71
|
def merge_results(results, separator: "\n", before_errors: "", after_errors: "")
|
|
82
72
|
results.reject!(&:ok?)
|
|
83
73
|
|
|
@@ -96,7 +86,7 @@ module Packwerk
|
|
|
96
86
|
end
|
|
97
87
|
end
|
|
98
88
|
|
|
99
|
-
|
|
89
|
+
#: (Configuration configuration, String path) -> Pathname
|
|
100
90
|
def relative_path(configuration, path)
|
|
101
91
|
Pathname.new(path).relative_path_from(configuration.root_path)
|
|
102
92
|
end
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
module Validators
|
|
6
6
|
class DependencyValidator
|
|
7
|
-
extend T::Sig
|
|
8
7
|
include Validator
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
end
|
|
9
|
+
# @override
|
|
10
|
+
#: (PackageSet package_set, Configuration configuration) -> Validator::Result
|
|
13
11
|
def call(package_set, configuration)
|
|
14
12
|
results = [
|
|
15
13
|
check_package_manifest_syntax(configuration),
|
|
@@ -20,7 +18,8 @@ module Packwerk
|
|
|
20
18
|
merge_results(results)
|
|
21
19
|
end
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
# @override
|
|
22
|
+
#: -> Array[String]
|
|
24
23
|
def permitted_keys
|
|
25
24
|
[
|
|
26
25
|
"enforce_dependencies",
|
|
@@ -30,7 +29,7 @@ module Packwerk
|
|
|
30
29
|
|
|
31
30
|
private
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
#: (Configuration configuration) -> Validator::Result
|
|
34
33
|
def check_package_manifest_syntax(configuration)
|
|
35
34
|
errors = []
|
|
36
35
|
|
|
@@ -63,12 +62,13 @@ module Packwerk
|
|
|
63
62
|
end
|
|
64
63
|
end
|
|
65
64
|
|
|
66
|
-
|
|
65
|
+
#: (PackageSet package_set) -> Validator::Result
|
|
67
66
|
def check_acyclic_graph(package_set)
|
|
68
|
-
edges = package_set.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
edges = package_set.to_h do |package|
|
|
68
|
+
[
|
|
69
|
+
package.name,
|
|
70
|
+
package.dependencies.map { |dependency| package_set.fetch(dependency)&.name },
|
|
71
|
+
]
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
dependency_graph = Graph.new(edges)
|
|
@@ -89,7 +89,7 @@ module Packwerk
|
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
#: (Configuration configuration) -> Validator::Result
|
|
93
93
|
def check_valid_package_dependencies(configuration)
|
|
94
94
|
packages_dependencies = package_manifests_settings_for(configuration, "dependencies")
|
|
95
95
|
.delete_if { |_, deps| deps.nil? }
|
|
@@ -125,7 +125,7 @@ module Packwerk
|
|
|
125
125
|
end
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
#: (Configuration configuration, untyped path) -> bool
|
|
129
129
|
def invalid_package_path?(configuration, path)
|
|
130
130
|
# Packages at the root can be implicitly specified as "."
|
|
131
131
|
return false if path == "."
|
|
@@ -141,7 +141,7 @@ module Packwerk
|
|
|
141
141
|
# to the string:
|
|
142
142
|
#
|
|
143
143
|
# ["a -> b -> c -> a", "b -> c -> b"]
|
|
144
|
-
|
|
144
|
+
#: (untyped cycles) -> Array[String]
|
|
145
145
|
def build_cycle_strings(cycles)
|
|
146
146
|
cycles.map do |cycle|
|
|
147
147
|
cycle_strings = cycle.map(&:to_s)
|
data/lib/packwerk/version.rb
CHANGED
data/lib/packwerk.rb
CHANGED