packwerk 2.0.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +26 -22
- data/README.md +13 -1
- data/USAGE.md +7 -0
- data/lib/packwerk/application_load_paths.rb +12 -18
- data/lib/packwerk/application_validator.rb +88 -40
- data/lib/packwerk/cache.rb +169 -0
- data/lib/packwerk/cli.rb +29 -13
- data/lib/packwerk/configuration.rb +17 -12
- data/lib/packwerk/constant_discovery.rb +20 -4
- data/lib/packwerk/constant_name_inspector.rb +1 -1
- data/lib/packwerk/deprecated_references.rb +1 -1
- data/lib/packwerk/file_processor.rb +43 -22
- data/lib/packwerk/files_for_processing.rb +55 -26
- data/lib/packwerk/generators/templates/packwerk.yml.erb +6 -0
- data/lib/packwerk/node.rb +2 -1
- data/lib/packwerk/node_processor.rb +6 -6
- data/lib/packwerk/node_processor_factory.rb +3 -4
- data/lib/packwerk/node_visitor.rb +3 -0
- data/lib/packwerk/offense.rb +10 -2
- data/lib/packwerk/package.rb +1 -1
- data/lib/packwerk/package_set.rb +4 -3
- data/lib/packwerk/parse_run.rb +37 -17
- data/lib/packwerk/parsed_constant_definitions.rb +4 -4
- data/lib/packwerk/parsers/erb.rb +2 -0
- data/lib/packwerk/parsers/factory.rb +2 -0
- data/lib/packwerk/parsers/parser_interface.rb +19 -0
- data/lib/packwerk/parsers/ruby.rb +2 -0
- data/lib/packwerk/parsers.rb +1 -0
- data/lib/packwerk/reference_checking/checkers/checker.rb +1 -1
- data/lib/packwerk/reference_checking/reference_checker.rb +3 -4
- data/lib/packwerk/reference_extractor.rb +72 -20
- data/lib/packwerk/reference_offense.rb +8 -3
- data/lib/packwerk/result.rb +2 -2
- data/lib/packwerk/run_context.rb +62 -36
- data/lib/packwerk/spring_command.rb +1 -1
- data/lib/packwerk/unresolved_reference.rb +10 -0
- data/lib/packwerk/version.rb +1 -1
- data/lib/packwerk.rb +2 -0
- data/packwerk.gemspec +4 -2
- data/sorbet/config +1 -0
- data/sorbet/rbi/gems/tapioca@0.4.19.rbi +1 -1
- data/sorbet/tapioca/require.rb +1 -1
- metadata +36 -5
data/lib/packwerk/run_context.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "constant_resolver"
|
@@ -8,76 +8,107 @@ module Packwerk
|
|
8
8
|
class RunContext
|
9
9
|
extend T::Sig
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
:inflector,
|
16
|
-
:custom_associations,
|
17
|
-
:checker_classes,
|
18
|
-
)
|
19
|
-
|
20
|
-
DEFAULT_CHECKERS = [
|
21
|
-
::Packwerk::ReferenceChecking::Checkers::DependencyChecker,
|
22
|
-
::Packwerk::ReferenceChecking::Checkers::PrivacyChecker,
|
23
|
-
]
|
11
|
+
DEFAULT_CHECKERS = T.let([
|
12
|
+
::Packwerk::ReferenceChecking::Checkers::DependencyChecker.new,
|
13
|
+
::Packwerk::ReferenceChecking::Checkers::PrivacyChecker.new,
|
14
|
+
], T::Array[ReferenceChecking::Checkers::Checker])
|
24
15
|
|
25
16
|
class << self
|
17
|
+
extend T::Sig
|
18
|
+
|
19
|
+
sig do
|
20
|
+
params(configuration: Configuration).returns(RunContext)
|
21
|
+
end
|
26
22
|
def from_configuration(configuration)
|
27
23
|
inflector = ActiveSupport::Inflector
|
24
|
+
|
28
25
|
new(
|
29
26
|
root_path: configuration.root_path,
|
30
27
|
load_paths: configuration.load_paths,
|
31
28
|
package_paths: configuration.package_paths,
|
32
29
|
inflector: inflector,
|
33
|
-
custom_associations: configuration.custom_associations
|
30
|
+
custom_associations: configuration.custom_associations,
|
31
|
+
cache_enabled: configuration.cache_enabled?,
|
32
|
+
cache_directory: configuration.cache_directory,
|
33
|
+
config_path: configuration.config_path,
|
34
34
|
)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
sig do
|
39
|
+
params(
|
40
|
+
root_path: String,
|
41
|
+
load_paths: T::Hash[String, Module],
|
42
|
+
inflector: T.class_of(ActiveSupport::Inflector),
|
43
|
+
cache_directory: Pathname,
|
44
|
+
config_path: T.nilable(String),
|
45
|
+
package_paths: T.nilable(T.any(T::Array[String], String)),
|
46
|
+
custom_associations: AssociationInspector::CustomAssociations,
|
47
|
+
checkers: T::Array[ReferenceChecking::Checkers::Checker],
|
48
|
+
cache_enabled: T::Boolean,
|
49
|
+
).void
|
50
|
+
end
|
38
51
|
def initialize(
|
39
52
|
root_path:,
|
40
53
|
load_paths:,
|
54
|
+
inflector:,
|
55
|
+
cache_directory:,
|
56
|
+
config_path: nil,
|
41
57
|
package_paths: nil,
|
42
|
-
inflector: nil,
|
43
58
|
custom_associations: [],
|
44
|
-
|
59
|
+
checkers: DEFAULT_CHECKERS,
|
60
|
+
cache_enabled: false
|
45
61
|
)
|
46
62
|
@root_path = root_path
|
47
63
|
@load_paths = load_paths
|
48
64
|
@package_paths = package_paths
|
49
65
|
@inflector = inflector
|
50
66
|
@custom_associations = custom_associations
|
51
|
-
@
|
67
|
+
@checkers = checkers
|
68
|
+
@cache_enabled = cache_enabled
|
69
|
+
@cache_directory = cache_directory
|
70
|
+
@config_path = config_path
|
71
|
+
|
72
|
+
@file_processor = T.let(nil, T.nilable(FileProcessor))
|
73
|
+
@context_provider = T.let(nil, T.nilable(ConstantDiscovery))
|
74
|
+
# We need to initialize this before we fork the process, see https://github.com/Shopify/packwerk/issues/182
|
75
|
+
@cache = T.let(
|
76
|
+
Cache.new(enable_cache: @cache_enabled, cache_directory: @cache_directory, config_path: @config_path), Cache
|
77
|
+
)
|
52
78
|
end
|
53
79
|
|
54
|
-
sig { params(
|
55
|
-
def process_file(
|
56
|
-
|
80
|
+
sig { params(absolute_file: String).returns(T::Array[Packwerk::Offense]) }
|
81
|
+
def process_file(absolute_file:)
|
82
|
+
processed_file = file_processor.call(absolute_file)
|
83
|
+
|
84
|
+
references = ReferenceExtractor.get_fully_qualified_references_from(
|
85
|
+
processed_file.unresolved_references,
|
86
|
+
context_provider
|
87
|
+
)
|
88
|
+
reference_checker = ReferenceChecking::ReferenceChecker.new(@checkers)
|
57
89
|
|
58
|
-
|
59
|
-
references.flat_map { |reference| reference_checker.call(reference) }
|
90
|
+
processed_file.offenses + references.flat_map { |reference| reference_checker.call(reference) }
|
60
91
|
end
|
61
92
|
|
62
93
|
private
|
63
94
|
|
64
95
|
sig { returns(FileProcessor) }
|
65
96
|
def file_processor
|
66
|
-
@file_processor ||= FileProcessor.new(node_processor_factory: node_processor_factory)
|
97
|
+
@file_processor ||= FileProcessor.new(node_processor_factory: node_processor_factory, cache: @cache)
|
67
98
|
end
|
68
99
|
|
69
100
|
sig { returns(NodeProcessorFactory) }
|
70
101
|
def node_processor_factory
|
71
102
|
NodeProcessorFactory.new(
|
72
103
|
context_provider: context_provider,
|
73
|
-
root_path: root_path,
|
104
|
+
root_path: @root_path,
|
74
105
|
constant_name_inspectors: constant_name_inspectors
|
75
106
|
)
|
76
107
|
end
|
77
108
|
|
78
109
|
sig { returns(ConstantDiscovery) }
|
79
110
|
def context_provider
|
80
|
-
::Packwerk::ConstantDiscovery.new(
|
111
|
+
@context_provider ||= ::Packwerk::ConstantDiscovery.new(
|
81
112
|
constant_resolver: resolver,
|
82
113
|
packages: package_set
|
83
114
|
)
|
@@ -86,27 +117,22 @@ module Packwerk
|
|
86
117
|
sig { returns(ConstantResolver) }
|
87
118
|
def resolver
|
88
119
|
ConstantResolver.new(
|
89
|
-
root_path: root_path,
|
90
|
-
load_paths: load_paths,
|
91
|
-
inflector: inflector,
|
120
|
+
root_path: @root_path,
|
121
|
+
load_paths: @load_paths,
|
122
|
+
inflector: @inflector,
|
92
123
|
)
|
93
124
|
end
|
94
125
|
|
95
126
|
sig { returns(PackageSet) }
|
96
127
|
def package_set
|
97
|
-
::Packwerk::PackageSet.load_all_from(root_path, package_pathspec: package_paths)
|
98
|
-
end
|
99
|
-
|
100
|
-
sig { returns(T::Array[ReferenceChecking::Checkers::Checker]) }
|
101
|
-
def checkers
|
102
|
-
checker_classes.map(&:new)
|
128
|
+
::Packwerk::PackageSet.load_all_from(@root_path, package_pathspec: @package_paths)
|
103
129
|
end
|
104
130
|
|
105
131
|
sig { returns(T::Array[ConstantNameInspector]) }
|
106
132
|
def constant_name_inspectors
|
107
133
|
[
|
108
134
|
::Packwerk::ConstNodeInspector.new,
|
109
|
-
::Packwerk::AssociationInspector.new(inflector: inflector, custom_associations: custom_associations),
|
135
|
+
::Packwerk::AssociationInspector.new(inflector: @inflector, custom_associations: @custom_associations),
|
110
136
|
]
|
111
137
|
end
|
112
138
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Packwerk
|
5
|
+
# An unresolved reference from a file in one package to a constant that may be defined in a different package.
|
6
|
+
# Unresolved means that we know how it's referred to in the file,
|
7
|
+
# and we have enough context on that reference to figure out the fully qualified reference such that we
|
8
|
+
# can produce a Reference in a separate pass. However, we have not yet resolved it to its fully qualified version.
|
9
|
+
UnresolvedReference = Struct.new(:constant_name, :namespace_path, :relative_path, :source_location)
|
10
|
+
end
|
data/lib/packwerk/version.rb
CHANGED
data/lib/packwerk.rb
CHANGED
@@ -15,6 +15,7 @@ module Packwerk
|
|
15
15
|
autoload :ApplicationValidator
|
16
16
|
autoload :AssociationInspector
|
17
17
|
autoload :OffenseCollection
|
18
|
+
autoload :Cache
|
18
19
|
autoload :Cli
|
19
20
|
autoload :Configuration
|
20
21
|
autoload :ConstantDiscovery
|
@@ -36,6 +37,7 @@ module Packwerk
|
|
36
37
|
autoload :ParsedConstantDefinitions
|
37
38
|
autoload :Parsers
|
38
39
|
autoload :ParseRun
|
40
|
+
autoload :UnresolvedReference
|
39
41
|
autoload :Reference
|
40
42
|
autoload :ReferenceExtractor
|
41
43
|
autoload :ReferenceOffense
|
data/packwerk.gemspec
CHANGED
@@ -41,16 +41,18 @@ Gem::Specification.new do |spec|
|
|
41
41
|
spec.required_ruby_version = ">= 2.6"
|
42
42
|
|
43
43
|
spec.add_dependency("activesupport", ">= 5.2")
|
44
|
-
spec.add_dependency("constant_resolver")
|
44
|
+
spec.add_dependency("constant_resolver", ">=0.2.0")
|
45
45
|
spec.add_dependency("parallel")
|
46
|
-
spec.add_dependency("sorbet-runtime")
|
46
|
+
spec.add_dependency("sorbet-runtime", ">=0.5.9914")
|
47
47
|
spec.add_dependency("bundler")
|
48
|
+
spec.add_dependency("digest")
|
48
49
|
|
49
50
|
spec.add_development_dependency("rake")
|
50
51
|
spec.add_development_dependency("sorbet")
|
51
52
|
spec.add_development_dependency("m")
|
52
53
|
# https://github.com/ruby/psych/pull/487
|
53
54
|
spec.add_development_dependency("psych", "~> 3")
|
55
|
+
spec.add_development_dependency("zeitwerk")
|
54
56
|
|
55
57
|
# For Ruby parsing
|
56
58
|
spec.add_dependency("ast")
|
data/sorbet/config
CHANGED
@@ -562,7 +562,7 @@ module Tapioca::GenericTypeRegistry
|
|
562
562
|
def name_of(constant); end
|
563
563
|
sig { params(object: BasicObject).returns(Integer) }
|
564
564
|
def object_id_of(object); end
|
565
|
-
sig { params(constant: T.untyped, type_variable_type: T.
|
565
|
+
sig { params(constant: T.untyped, type_variable_type: T.deprecated_enum([:type_member, :type_template]), type_variable: T::Types::TypeVariable, fixed: T.untyped, lower: T.untyped, upper: T.untyped).void }
|
566
566
|
def register_type_variable(constant, type_variable_type, type_variable, fixed, lower, upper); end
|
567
567
|
sig { params(type_variable_type: Symbol, variance: Symbol, fixed: T.untyped, lower: T.untyped, upper: T.untyped).returns(String) }
|
568
568
|
def serialize_type_variable(type_variable_type, variance, fixed, lower, upper); end
|
data/sorbet/tapioca/require.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packwerk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.2.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.2.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: parallel
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,6 +54,20 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: sorbet-runtime
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.5.9914
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.5.9914
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - ">="
|
@@ -67,7 +81,7 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: digest
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
@@ -136,6 +150,20 @@ dependencies:
|
|
136
150
|
- - "~>"
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '3'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: zeitwerk
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
139
167
|
- !ruby/object:Gem::Dependency
|
140
168
|
name: ast
|
141
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -222,6 +250,7 @@ files:
|
|
222
250
|
- lib/packwerk/application_load_paths.rb
|
223
251
|
- lib/packwerk/application_validator.rb
|
224
252
|
- lib/packwerk/association_inspector.rb
|
253
|
+
- lib/packwerk/cache.rb
|
225
254
|
- lib/packwerk/cli.rb
|
226
255
|
- lib/packwerk/configuration.rb
|
227
256
|
- lib/packwerk/const_node_inspector.rb
|
@@ -254,6 +283,7 @@ files:
|
|
254
283
|
- lib/packwerk/parsers.rb
|
255
284
|
- lib/packwerk/parsers/erb.rb
|
256
285
|
- lib/packwerk/parsers/factory.rb
|
286
|
+
- lib/packwerk/parsers/parser_interface.rb
|
257
287
|
- lib/packwerk/parsers/ruby.rb
|
258
288
|
- lib/packwerk/reference.rb
|
259
289
|
- lib/packwerk/reference_checking/checkers/checker.rb
|
@@ -266,6 +296,7 @@ files:
|
|
266
296
|
- lib/packwerk/run_context.rb
|
267
297
|
- lib/packwerk/sanity_checker.rb
|
268
298
|
- lib/packwerk/spring_command.rb
|
299
|
+
- lib/packwerk/unresolved_reference.rb
|
269
300
|
- lib/packwerk/version.rb
|
270
301
|
- lib/packwerk/violation_type.rb
|
271
302
|
- library.yml
|