packwerk 1.3.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|