packwerk 1.3.1 → 2.1.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/CHANGELOG.md +1 -0
- data/Gemfile.lock +12 -9
- data/README.md +9 -3
- data/TROUBLESHOOT.md +3 -3
- data/UPGRADING.md +54 -0
- data/USAGE.md +32 -51
- data/exe/packwerk +7 -1
- data/lib/packwerk/application_load_paths.rb +1 -0
- data/lib/packwerk/application_validator.rb +17 -59
- data/lib/packwerk/association_inspector.rb +1 -1
- data/lib/packwerk/cache.rb +168 -0
- data/lib/packwerk/cli.rb +37 -20
- data/lib/packwerk/configuration.rb +40 -5
- data/lib/packwerk/const_node_inspector.rb +3 -2
- data/lib/packwerk/constant_discovery.rb +4 -4
- data/lib/packwerk/constant_name_inspector.rb +1 -1
- data/lib/packwerk/deprecated_references.rb +18 -6
- data/lib/packwerk/file_processor.rb +53 -14
- data/lib/packwerk/files_for_processing.rb +15 -4
- data/lib/packwerk/formatters/offenses_formatter.rb +1 -1
- data/lib/packwerk/formatters/progress_formatter.rb +1 -1
- data/lib/packwerk/generators/configuration_file.rb +4 -19
- data/lib/packwerk/generators/templates/package.yml +1 -1
- data/lib/packwerk/generators/templates/packwerk.yml.erb +5 -5
- data/lib/packwerk/graph.rb +2 -0
- data/lib/packwerk/node.rb +2 -0
- data/lib/packwerk/node_processor.rb +10 -22
- data/lib/packwerk/node_processor_factory.rb +0 -3
- data/lib/packwerk/node_visitor.rb +7 -2
- data/lib/packwerk/package.rb +25 -4
- data/lib/packwerk/package_set.rb +44 -8
- data/lib/packwerk/parsed_constant_definitions.rb +5 -4
- data/lib/packwerk/reference.rb +2 -1
- data/lib/packwerk/reference_checking/checkers/checker.rb +21 -0
- data/lib/packwerk/reference_checking/checkers/dependency_checker.rb +31 -0
- data/lib/packwerk/reference_checking/checkers/privacy_checker.rb +58 -0
- data/lib/packwerk/reference_checking/reference_checker.rb +33 -0
- data/lib/packwerk/reference_extractor.rb +66 -19
- data/lib/packwerk/reference_offense.rb +1 -0
- data/lib/packwerk/run_context.rb +32 -11
- data/lib/packwerk/sanity_checker.rb +1 -1
- data/lib/packwerk/spring_command.rb +28 -0
- data/lib/packwerk/unresolved_reference.rb +10 -0
- data/lib/packwerk/version.rb +1 -1
- data/lib/packwerk/violation_type.rb +1 -1
- data/lib/packwerk.rb +19 -12
- data/packwerk.gemspec +4 -1
- data/service.yml +0 -2
- data/sorbet/rbi/gems/psych@3.3.2.rbi +24 -0
- metadata +41 -11
- data/lib/packwerk/checker.rb +0 -17
- data/lib/packwerk/dependency_checker.rb +0 -26
- data/lib/packwerk/generators/inflections_file.rb +0 -43
- data/lib/packwerk/generators/templates/inflections.yml +0 -6
- data/lib/packwerk/inflections/custom.rb +0 -33
- data/lib/packwerk/inflections/default.rb +0 -73
- data/lib/packwerk/inflector.rb +0 -48
- data/lib/packwerk/privacy_checker.rb +0 -53
data/lib/packwerk/run_context.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
require "constant_resolver"
|
5
5
|
|
6
6
|
module Packwerk
|
7
|
+
# Holds the context of a Packwerk run across multiple files.
|
7
8
|
class RunContext
|
8
9
|
extend T::Sig
|
9
10
|
|
@@ -17,19 +18,23 @@ module Packwerk
|
|
17
18
|
)
|
18
19
|
|
19
20
|
DEFAULT_CHECKERS = [
|
20
|
-
::Packwerk::DependencyChecker,
|
21
|
-
::Packwerk::PrivacyChecker,
|
21
|
+
::Packwerk::ReferenceChecking::Checkers::DependencyChecker,
|
22
|
+
::Packwerk::ReferenceChecking::Checkers::PrivacyChecker,
|
22
23
|
]
|
23
24
|
|
24
25
|
class << self
|
25
26
|
def from_configuration(configuration)
|
26
|
-
inflector = ::
|
27
|
+
inflector = ActiveSupport::Inflector
|
28
|
+
|
27
29
|
new(
|
28
30
|
root_path: configuration.root_path,
|
29
31
|
load_paths: configuration.load_paths,
|
30
32
|
package_paths: configuration.package_paths,
|
31
33
|
inflector: inflector,
|
32
|
-
custom_associations: configuration.custom_associations
|
34
|
+
custom_associations: configuration.custom_associations,
|
35
|
+
cache_enabled: configuration.cache_enabled?,
|
36
|
+
cache_directory: configuration.cache_directory,
|
37
|
+
config_path: configuration.config_path,
|
33
38
|
)
|
34
39
|
end
|
35
40
|
end
|
@@ -40,7 +45,10 @@ module Packwerk
|
|
40
45
|
package_paths: nil,
|
41
46
|
inflector: nil,
|
42
47
|
custom_associations: [],
|
43
|
-
checker_classes: DEFAULT_CHECKERS
|
48
|
+
checker_classes: DEFAULT_CHECKERS,
|
49
|
+
cache_enabled: false,
|
50
|
+
cache_directory: nil,
|
51
|
+
config_path: nil
|
44
52
|
)
|
45
53
|
@root_path = root_path
|
46
54
|
@load_paths = load_paths
|
@@ -48,25 +56,33 @@ module Packwerk
|
|
48
56
|
@inflector = inflector
|
49
57
|
@custom_associations = custom_associations
|
50
58
|
@checker_classes = checker_classes
|
59
|
+
@cache_enabled = cache_enabled
|
60
|
+
@cache_directory = cache_directory
|
61
|
+
@config_path = config_path
|
51
62
|
end
|
52
63
|
|
53
|
-
sig { params(file: String).returns(T::Array[
|
64
|
+
sig { params(file: String).returns(T::Array[Packwerk::Offense]) }
|
54
65
|
def process_file(file:)
|
55
|
-
file_processor.call(file)
|
66
|
+
unresolved_references_and_offenses = file_processor.call(file)
|
67
|
+
references_and_offenses = ReferenceExtractor.get_fully_qualified_references_and_offenses_from(
|
68
|
+
unresolved_references_and_offenses,
|
69
|
+
context_provider
|
70
|
+
)
|
71
|
+
reference_checker = ReferenceChecking::ReferenceChecker.new(checkers)
|
72
|
+
references_and_offenses.flat_map { |reference| reference_checker.call(reference) }
|
56
73
|
end
|
57
74
|
|
58
75
|
private
|
59
76
|
|
60
77
|
sig { returns(FileProcessor) }
|
61
78
|
def file_processor
|
62
|
-
@file_processor ||= FileProcessor.new(node_processor_factory: node_processor_factory)
|
79
|
+
@file_processor ||= FileProcessor.new(node_processor_factory: node_processor_factory, cache: cache)
|
63
80
|
end
|
64
81
|
|
65
82
|
sig { returns(NodeProcessorFactory) }
|
66
83
|
def node_processor_factory
|
67
84
|
NodeProcessorFactory.new(
|
68
85
|
context_provider: context_provider,
|
69
|
-
checkers: checkers,
|
70
86
|
root_path: root_path,
|
71
87
|
constant_name_inspectors: constant_name_inspectors
|
72
88
|
)
|
@@ -74,7 +90,7 @@ module Packwerk
|
|
74
90
|
|
75
91
|
sig { returns(ConstantDiscovery) }
|
76
92
|
def context_provider
|
77
|
-
::Packwerk::ConstantDiscovery.new(
|
93
|
+
@context_provider ||= ::Packwerk::ConstantDiscovery.new(
|
78
94
|
constant_resolver: resolver,
|
79
95
|
packages: package_set
|
80
96
|
)
|
@@ -89,12 +105,17 @@ module Packwerk
|
|
89
105
|
)
|
90
106
|
end
|
91
107
|
|
108
|
+
sig { returns(Cache) }
|
109
|
+
def cache
|
110
|
+
@cache ||= Cache.new(enable_cache: @cache_enabled, cache_directory: @cache_directory, config_path: @config_path)
|
111
|
+
end
|
112
|
+
|
92
113
|
sig { returns(PackageSet) }
|
93
114
|
def package_set
|
94
115
|
::Packwerk::PackageSet.load_all_from(root_path, package_pathspec: package_paths)
|
95
116
|
end
|
96
117
|
|
97
|
-
sig { returns(T::Array[Checker]) }
|
118
|
+
sig { returns(T::Array[ReferenceChecking::Checkers::Checker]) }
|
98
119
|
def checkers
|
99
120
|
checker_classes.map(&:new)
|
100
121
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: false
|
3
|
+
|
4
|
+
require "spring/commands"
|
5
|
+
|
6
|
+
module Packwerk
|
7
|
+
class SpringCommand
|
8
|
+
def env(*)
|
9
|
+
# Packwerk needs to run in a test environment, which has a set of autoload paths that are
|
10
|
+
# often a superset of the dev/prod paths (for example, test/support/helpers)
|
11
|
+
"test"
|
12
|
+
end
|
13
|
+
|
14
|
+
def exec_name
|
15
|
+
"packwerk"
|
16
|
+
end
|
17
|
+
|
18
|
+
def gem_name
|
19
|
+
"packwerk"
|
20
|
+
end
|
21
|
+
|
22
|
+
def call
|
23
|
+
load(Gem.bin_path(gem_name, exec_name))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Spring.register_command("packwerk", SpringCommand.new)
|
28
|
+
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
@@ -5,6 +5,9 @@ require "sorbet-runtime"
|
|
5
5
|
require "active_support"
|
6
6
|
require "fileutils"
|
7
7
|
|
8
|
+
# Provides String#pluralize
|
9
|
+
require "active_support/core_ext/string"
|
10
|
+
|
8
11
|
module Packwerk
|
9
12
|
extend ActiveSupport::Autoload
|
10
13
|
|
@@ -12,18 +15,16 @@ module Packwerk
|
|
12
15
|
autoload :ApplicationValidator
|
13
16
|
autoload :AssociationInspector
|
14
17
|
autoload :OffenseCollection
|
15
|
-
autoload :
|
18
|
+
autoload :Cache
|
16
19
|
autoload :Cli
|
17
20
|
autoload :Configuration
|
18
21
|
autoload :ConstantDiscovery
|
19
22
|
autoload :ConstantNameInspector
|
20
23
|
autoload :ConstNodeInspector
|
21
|
-
autoload :DependencyChecker
|
22
24
|
autoload :DeprecatedReferences
|
23
25
|
autoload :FileProcessor
|
24
26
|
autoload :FilesForProcessing
|
25
27
|
autoload :Graph
|
26
|
-
autoload :Inflector
|
27
28
|
autoload :Node
|
28
29
|
autoload :NodeProcessor
|
29
30
|
autoload :NodeProcessorFactory
|
@@ -36,7 +37,7 @@ module Packwerk
|
|
36
37
|
autoload :ParsedConstantDefinitions
|
37
38
|
autoload :Parsers
|
38
39
|
autoload :ParseRun
|
39
|
-
autoload :
|
40
|
+
autoload :UnresolvedReference
|
40
41
|
autoload :Reference
|
41
42
|
autoload :ReferenceExtractor
|
42
43
|
autoload :ReferenceOffense
|
@@ -45,13 +46,6 @@ module Packwerk
|
|
45
46
|
autoload :Version
|
46
47
|
autoload :ViolationType
|
47
48
|
|
48
|
-
module Inflections
|
49
|
-
extend ActiveSupport::Autoload
|
50
|
-
|
51
|
-
autoload :Custom
|
52
|
-
autoload :Default
|
53
|
-
end
|
54
|
-
|
55
49
|
module OutputStyles
|
56
50
|
extend ActiveSupport::Autoload
|
57
51
|
|
@@ -74,7 +68,20 @@ module Packwerk
|
|
74
68
|
extend ActiveSupport::Autoload
|
75
69
|
|
76
70
|
autoload :ConfigurationFile
|
77
|
-
autoload :InflectionsFile
|
78
71
|
autoload :RootPackage
|
79
72
|
end
|
73
|
+
|
74
|
+
module ReferenceChecking
|
75
|
+
extend ActiveSupport::Autoload
|
76
|
+
|
77
|
+
autoload :ReferenceChecker
|
78
|
+
|
79
|
+
module Checkers
|
80
|
+
extend ActiveSupport::Autoload
|
81
|
+
|
82
|
+
autoload :Checker
|
83
|
+
autoload :DependencyChecker
|
84
|
+
autoload :PrivacyChecker
|
85
|
+
end
|
86
|
+
end
|
80
87
|
end
|
data/packwerk.gemspec
CHANGED
@@ -44,11 +44,14 @@ Gem::Specification.new do |spec|
|
|
44
44
|
spec.add_dependency("constant_resolver")
|
45
45
|
spec.add_dependency("parallel")
|
46
46
|
spec.add_dependency("sorbet-runtime")
|
47
|
+
spec.add_dependency("bundler")
|
48
|
+
spec.add_dependency("digest")
|
47
49
|
|
48
|
-
spec.add_development_dependency("bundler")
|
49
50
|
spec.add_development_dependency("rake")
|
50
51
|
spec.add_development_dependency("sorbet")
|
51
52
|
spec.add_development_dependency("m")
|
53
|
+
# https://github.com/ruby/psych/pull/487
|
54
|
+
spec.add_development_dependency("psych", "~> 3")
|
52
55
|
|
53
56
|
# For Ruby parsing
|
54
57
|
spec.add_dependency("ast")
|
data/service.yml
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
# DO NOT EDIT MANUALLY
|
4
|
+
# This is an autogenerated file for types exported from the `psych` gem.
|
5
|
+
# Please instead update this file by running `bin/tapioca gem psych`.
|
6
|
+
|
7
|
+
::RUBY19 = T.let(T.unsafe(nil), TrueClass)
|
8
|
+
|
9
|
+
class Object < ::BasicObject
|
10
|
+
include ::ActiveSupport::ToJsonWithActiveSupportEncoder
|
11
|
+
include ::Kernel
|
12
|
+
include ::JSON::Ext::Generator::GeneratorMethods::Object
|
13
|
+
include ::ActiveSupport::Tryable
|
14
|
+
include ::Minitest::Expectations
|
15
|
+
include ::Mocha::ParameterMatchers::InstanceMethods
|
16
|
+
include ::Mocha::Inspect::ObjectMethods
|
17
|
+
include ::Mocha::ObjectMethods
|
18
|
+
|
19
|
+
def to_yaml(options = T.unsafe(nil)); end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def yaml_tag(url); end
|
23
|
+
end
|
24
|
+
end
|
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: 1.
|
4
|
+
version: 2.1.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-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -73,7 +73,21 @@ dependencies:
|
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
|
-
type: :
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: digest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
@@ -122,6 +136,20 @@ dependencies:
|
|
122
136
|
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: psych
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '3'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '3'
|
125
153
|
- !ruby/object:Gem::Dependency
|
126
154
|
name: ast
|
127
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -181,6 +209,7 @@ files:
|
|
181
209
|
- ".gitignore"
|
182
210
|
- ".rubocop.yml"
|
183
211
|
- ".ruby-version"
|
212
|
+
- CHANGELOG.md
|
184
213
|
- CODEOWNERS
|
185
214
|
- CODE_OF_CONDUCT.md
|
186
215
|
- CONTRIBUTING.md
|
@@ -190,6 +219,7 @@ files:
|
|
190
219
|
- README.md
|
191
220
|
- Rakefile
|
192
221
|
- TROUBLESHOOT.md
|
222
|
+
- UPGRADING.md
|
193
223
|
- USAGE.md
|
194
224
|
- bin/console
|
195
225
|
- bin/m
|
@@ -206,28 +236,22 @@ files:
|
|
206
236
|
- lib/packwerk/application_load_paths.rb
|
207
237
|
- lib/packwerk/application_validator.rb
|
208
238
|
- lib/packwerk/association_inspector.rb
|
209
|
-
- lib/packwerk/
|
239
|
+
- lib/packwerk/cache.rb
|
210
240
|
- lib/packwerk/cli.rb
|
211
241
|
- lib/packwerk/configuration.rb
|
212
242
|
- lib/packwerk/const_node_inspector.rb
|
213
243
|
- lib/packwerk/constant_discovery.rb
|
214
244
|
- lib/packwerk/constant_name_inspector.rb
|
215
|
-
- lib/packwerk/dependency_checker.rb
|
216
245
|
- lib/packwerk/deprecated_references.rb
|
217
246
|
- lib/packwerk/file_processor.rb
|
218
247
|
- lib/packwerk/files_for_processing.rb
|
219
248
|
- lib/packwerk/formatters/offenses_formatter.rb
|
220
249
|
- lib/packwerk/formatters/progress_formatter.rb
|
221
250
|
- lib/packwerk/generators/configuration_file.rb
|
222
|
-
- lib/packwerk/generators/inflections_file.rb
|
223
251
|
- lib/packwerk/generators/root_package.rb
|
224
|
-
- lib/packwerk/generators/templates/inflections.yml
|
225
252
|
- lib/packwerk/generators/templates/package.yml
|
226
253
|
- lib/packwerk/generators/templates/packwerk.yml.erb
|
227
254
|
- lib/packwerk/graph.rb
|
228
|
-
- lib/packwerk/inflections/custom.rb
|
229
|
-
- lib/packwerk/inflections/default.rb
|
230
|
-
- lib/packwerk/inflector.rb
|
231
255
|
- lib/packwerk/node.rb
|
232
256
|
- lib/packwerk/node_processor.rb
|
233
257
|
- lib/packwerk/node_processor_factory.rb
|
@@ -246,13 +270,18 @@ files:
|
|
246
270
|
- lib/packwerk/parsers/erb.rb
|
247
271
|
- lib/packwerk/parsers/factory.rb
|
248
272
|
- lib/packwerk/parsers/ruby.rb
|
249
|
-
- lib/packwerk/privacy_checker.rb
|
250
273
|
- lib/packwerk/reference.rb
|
274
|
+
- lib/packwerk/reference_checking/checkers/checker.rb
|
275
|
+
- lib/packwerk/reference_checking/checkers/dependency_checker.rb
|
276
|
+
- lib/packwerk/reference_checking/checkers/privacy_checker.rb
|
277
|
+
- lib/packwerk/reference_checking/reference_checker.rb
|
251
278
|
- lib/packwerk/reference_extractor.rb
|
252
279
|
- lib/packwerk/reference_offense.rb
|
253
280
|
- lib/packwerk/result.rb
|
254
281
|
- lib/packwerk/run_context.rb
|
255
282
|
- lib/packwerk/sanity_checker.rb
|
283
|
+
- lib/packwerk/spring_command.rb
|
284
|
+
- lib/packwerk/unresolved_reference.rb
|
256
285
|
- lib/packwerk/version.rb
|
257
286
|
- lib/packwerk/violation_type.rb
|
258
287
|
- library.yml
|
@@ -301,6 +330,7 @@ files:
|
|
301
330
|
- sorbet/rbi/gems/parlour@6.0.0.rbi
|
302
331
|
- sorbet/rbi/gems/parser@3.0.0.0.rbi
|
303
332
|
- sorbet/rbi/gems/pry@0.14.0.rbi
|
333
|
+
- sorbet/rbi/gems/psych@3.3.2.rbi
|
304
334
|
- sorbet/rbi/gems/racc@1.5.2.rbi
|
305
335
|
- sorbet/rbi/gems/rack-test@1.1.0.rbi
|
306
336
|
- sorbet/rbi/gems/rack@2.2.3.rbi
|
data/lib/packwerk/checker.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# typed: true
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module Packwerk
|
5
|
-
module Checker
|
6
|
-
extend T::Sig
|
7
|
-
extend T::Helpers
|
8
|
-
|
9
|
-
interface!
|
10
|
-
|
11
|
-
sig { returns(ViolationType).abstract }
|
12
|
-
def violation_type; end
|
13
|
-
|
14
|
-
sig { params(reference: Reference).returns(T::Boolean).abstract }
|
15
|
-
def invalid_reference?(reference); end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module Packwerk
|
5
|
-
class DependencyChecker
|
6
|
-
extend T::Sig
|
7
|
-
include Checker
|
8
|
-
|
9
|
-
sig { override.returns(ViolationType) }
|
10
|
-
def violation_type
|
11
|
-
ViolationType::Dependency
|
12
|
-
end
|
13
|
-
|
14
|
-
sig do
|
15
|
-
override
|
16
|
-
.params(reference: Packwerk::Reference)
|
17
|
-
.returns(T::Boolean)
|
18
|
-
end
|
19
|
-
def invalid_reference?(reference)
|
20
|
-
return false unless reference.source_package
|
21
|
-
return false unless reference.source_package.enforce_dependencies?
|
22
|
-
return false if reference.source_package.dependency?(reference.constant.package)
|
23
|
-
true
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# typed: true
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module Packwerk
|
5
|
-
module Generators
|
6
|
-
class InflectionsFile
|
7
|
-
extend T::Sig
|
8
|
-
|
9
|
-
class << self
|
10
|
-
def generate(root:, out:)
|
11
|
-
new(root, out: out).generate
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize(root, out: $stdout)
|
16
|
-
@root = root
|
17
|
-
@out = out
|
18
|
-
end
|
19
|
-
|
20
|
-
sig { returns(T::Boolean) }
|
21
|
-
def generate
|
22
|
-
ruby_inflection_file_exist = Dir.glob("#{@root}/**/inflections.rb").any?
|
23
|
-
yaml_inflection_file_exist = Dir.glob("#{@root}/**/inflections.yml").any?
|
24
|
-
|
25
|
-
if !ruby_inflection_file_exist || yaml_inflection_file_exist
|
26
|
-
return true
|
27
|
-
end
|
28
|
-
|
29
|
-
@out.puts("📦 Generating `inflections.yml` file...")
|
30
|
-
|
31
|
-
destination_file_path = File.join(@root, "config")
|
32
|
-
FileUtils.mkdir_p(destination_file_path)
|
33
|
-
|
34
|
-
source_file_path = File.join(__dir__, "/templates/inflections.yml")
|
35
|
-
FileUtils.cp(source_file_path, destination_file_path)
|
36
|
-
|
37
|
-
@out.puts("✅ `inflections.yml` generated in #{destination_file_path}")
|
38
|
-
|
39
|
-
true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# typed: true
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "yaml"
|
5
|
-
|
6
|
-
module Packwerk
|
7
|
-
module Inflections
|
8
|
-
class Custom
|
9
|
-
SUPPORTED_INFLECTION_METHODS = %w(acronym human irregular plural singular uncountable)
|
10
|
-
|
11
|
-
attr_accessor :inflections
|
12
|
-
|
13
|
-
def initialize(custom_inflection_file = nil)
|
14
|
-
if custom_inflection_file && File.exist?(custom_inflection_file)
|
15
|
-
@inflections = YAML.load_file(custom_inflection_file) || {}
|
16
|
-
|
17
|
-
invalid_inflections = @inflections.keys - SUPPORTED_INFLECTION_METHODS
|
18
|
-
raise ArgumentError, "Unsupported inflection types: #{invalid_inflections}" if invalid_inflections.any?
|
19
|
-
else
|
20
|
-
@inflections = []
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def apply_to(inflections_object)
|
25
|
-
@inflections.each do |inflection_type, inflections|
|
26
|
-
inflections.each do |inflection|
|
27
|
-
inflections_object.public_send(inflection_type, *Array(inflection))
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# typed: true
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module Packwerk
|
5
|
-
module Inflections
|
6
|
-
module Default
|
7
|
-
class << self
|
8
|
-
def apply_to(inflections_object)
|
9
|
-
# copied from active_support/inflections
|
10
|
-
# https://github.com/rails/rails/blob/d2ae2c3103e93783971d5356d0b3fd1b4070d6cf/activesupport/lib/active_support/inflections.rb#L12
|
11
|
-
inflections_object.plural(/$/, "s")
|
12
|
-
inflections_object.plural(/s$/i, "s")
|
13
|
-
inflections_object.plural(/^(ax|test)is$/i, '\1es')
|
14
|
-
inflections_object.plural(/(octop|vir)us$/i, '\1i')
|
15
|
-
inflections_object.plural(/(octop|vir)i$/i, '\1i')
|
16
|
-
inflections_object.plural(/(alias|status)$/i, '\1es')
|
17
|
-
inflections_object.plural(/(bu)s$/i, '\1ses')
|
18
|
-
inflections_object.plural(/(buffal|tomat)o$/i, '\1oes')
|
19
|
-
inflections_object.plural(/([ti])um$/i, '\1a')
|
20
|
-
inflections_object.plural(/([ti])a$/i, '\1a')
|
21
|
-
inflections_object.plural(/sis$/i, "ses")
|
22
|
-
inflections_object.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
|
23
|
-
inflections_object.plural(/(hive)$/i, '\1s')
|
24
|
-
inflections_object.plural(/([^aeiouy]|qu)y$/i, '\1ies')
|
25
|
-
inflections_object.plural(/(x|ch|ss|sh)$/i, '\1es')
|
26
|
-
inflections_object.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices')
|
27
|
-
inflections_object.plural(/^(m|l)ouse$/i, '\1ice')
|
28
|
-
inflections_object.plural(/^(m|l)ice$/i, '\1ice')
|
29
|
-
inflections_object.plural(/^(ox)$/i, '\1en')
|
30
|
-
inflections_object.plural(/^(oxen)$/i, '\1')
|
31
|
-
inflections_object.plural(/(quiz)$/i, '\1zes')
|
32
|
-
|
33
|
-
inflections_object.singular(/s$/i, "")
|
34
|
-
inflections_object.singular(/(ss)$/i, '\1')
|
35
|
-
inflections_object.singular(/(n)ews$/i, '\1ews')
|
36
|
-
inflections_object.singular(/([ti])a$/i, '\1um')
|
37
|
-
inflections_object.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1sis')
|
38
|
-
inflections_object.singular(/(^analy)(sis|ses)$/i, '\1sis')
|
39
|
-
inflections_object.singular(/([^f])ves$/i, '\1fe')
|
40
|
-
inflections_object.singular(/(hive)s$/i, '\1')
|
41
|
-
inflections_object.singular(/(tive)s$/i, '\1')
|
42
|
-
inflections_object.singular(/([lr])ves$/i, '\1f')
|
43
|
-
inflections_object.singular(/([^aeiouy]|qu)ies$/i, '\1y')
|
44
|
-
inflections_object.singular(/(s)eries$/i, '\1eries')
|
45
|
-
inflections_object.singular(/(m)ovies$/i, '\1ovie')
|
46
|
-
inflections_object.singular(/(x|ch|ss|sh)es$/i, '\1')
|
47
|
-
inflections_object.singular(/^(m|l)ice$/i, '\1ouse')
|
48
|
-
inflections_object.singular(/(bus)(es)?$/i, '\1')
|
49
|
-
inflections_object.singular(/(o)es$/i, '\1')
|
50
|
-
inflections_object.singular(/(shoe)s$/i, '\1')
|
51
|
-
inflections_object.singular(/(cris|test)(is|es)$/i, '\1is')
|
52
|
-
inflections_object.singular(/^(a)x[ie]s$/i, '\1xis')
|
53
|
-
inflections_object.singular(/(octop|vir)(us|i)$/i, '\1us')
|
54
|
-
inflections_object.singular(/(alias|status)(es)?$/i, '\1')
|
55
|
-
inflections_object.singular(/^(ox)en/i, '\1')
|
56
|
-
inflections_object.singular(/(vert|ind)ices$/i, '\1ex')
|
57
|
-
inflections_object.singular(/(matr)ices$/i, '\1ix')
|
58
|
-
inflections_object.singular(/(quiz)zes$/i, '\1')
|
59
|
-
inflections_object.singular(/(database)s$/i, '\1')
|
60
|
-
|
61
|
-
inflections_object.irregular("person", "people")
|
62
|
-
inflections_object.irregular("man", "men")
|
63
|
-
inflections_object.irregular("child", "children")
|
64
|
-
inflections_object.irregular("sex", "sexes")
|
65
|
-
inflections_object.irregular("move", "moves")
|
66
|
-
inflections_object.irregular("zombie", "zombies")
|
67
|
-
|
68
|
-
inflections_object.uncountable(%w(equipment information rice money species series fish sheep jeans police))
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
data/lib/packwerk/inflector.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
# typed: true
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "active_support/inflector"
|
5
|
-
|
6
|
-
module Packwerk
|
7
|
-
class Inflector
|
8
|
-
class << self
|
9
|
-
extend T::Sig
|
10
|
-
|
11
|
-
def default
|
12
|
-
@default ||= new(custom_inflector: Inflections::Custom.new)
|
13
|
-
end
|
14
|
-
|
15
|
-
sig { params(inflections_file: String).returns(::Packwerk::Inflector) }
|
16
|
-
def from_file(inflections_file)
|
17
|
-
new(custom_inflector: Inflections::Custom.new(inflections_file))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
extend T::Sig
|
22
|
-
include ::ActiveSupport::Inflector # For #camelize, #classify, #pluralize, #singularize
|
23
|
-
|
24
|
-
sig do
|
25
|
-
params(
|
26
|
-
custom_inflector: Inflections::Custom
|
27
|
-
).void
|
28
|
-
end
|
29
|
-
def initialize(custom_inflector:)
|
30
|
-
@inflections = ::ActiveSupport::Inflector::Inflections.new
|
31
|
-
|
32
|
-
Inflections::Default.apply_to(@inflections)
|
33
|
-
custom_inflector.apply_to(@inflections)
|
34
|
-
end
|
35
|
-
|
36
|
-
def pluralize(word, count = nil)
|
37
|
-
if count == 1
|
38
|
-
singularize(word)
|
39
|
-
else
|
40
|
-
super(word)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def inflections(_ = nil)
|
45
|
-
@inflections
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|