packwerk 1.4.0 → 2.1.1
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 +22 -19
- data/README.md +7 -2
- data/UPGRADING.md +54 -0
- data/USAGE.md +5 -40
- data/lib/packwerk/application_validator.rb +88 -93
- data/lib/packwerk/association_inspector.rb +1 -1
- data/lib/packwerk/cache.rb +169 -0
- data/lib/packwerk/cli.rb +32 -28
- data/lib/packwerk/configuration.rb +40 -5
- data/lib/packwerk/constant_discovery.rb +21 -5
- data/lib/packwerk/constant_name_inspector.rb +1 -1
- data/lib/packwerk/deprecated_references.rb +1 -1
- data/lib/packwerk/file_processor.rb +34 -15
- data/lib/packwerk/files_for_processing.rb +49 -22
- 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/packwerk.yml.erb +5 -5
- 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 +3 -2
- 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 +17 -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 +2 -1
- data/lib/packwerk/reference_extractor.rb +78 -20
- data/lib/packwerk/reference_offense.rb +8 -3
- data/lib/packwerk/result.rb +2 -2
- data/lib/packwerk/run_context.rb +62 -38
- 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 +5 -9
- data/packwerk.gemspec +1 -0
- data/sorbet/config +1 -0
- data/sorbet/rbi/gems/tapioca@0.4.19.rbi +1 -1
- data/sorbet/tapioca/require.rb +1 -1
- metadata +21 -7
- 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 -49
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,105 @@ 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
|
-
inflector = ::
|
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::Array[String],
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
80
|
+
sig { params(absolute_file: String).returns(T::Array[Packwerk::Offense]) }
|
81
|
+
def process_file(absolute_file:)
|
82
|
+
unresolved_references_and_offenses = file_processor.call(absolute_file)
|
83
|
+
references_and_offenses = ReferenceExtractor.get_fully_qualified_references_and_offenses_from(
|
84
|
+
unresolved_references_and_offenses,
|
85
|
+
context_provider
|
86
|
+
)
|
87
|
+
reference_checker = ReferenceChecking::ReferenceChecker.new(@checkers)
|
88
|
+
references_and_offenses.flat_map { |reference| reference_checker.call(reference) }
|
60
89
|
end
|
61
90
|
|
62
91
|
private
|
63
92
|
|
64
93
|
sig { returns(FileProcessor) }
|
65
94
|
def file_processor
|
66
|
-
@file_processor ||= FileProcessor.new(node_processor_factory: node_processor_factory)
|
95
|
+
@file_processor ||= FileProcessor.new(node_processor_factory: node_processor_factory, cache: @cache)
|
67
96
|
end
|
68
97
|
|
69
98
|
sig { returns(NodeProcessorFactory) }
|
70
99
|
def node_processor_factory
|
71
100
|
NodeProcessorFactory.new(
|
72
101
|
context_provider: context_provider,
|
73
|
-
root_path: root_path,
|
102
|
+
root_path: @root_path,
|
74
103
|
constant_name_inspectors: constant_name_inspectors
|
75
104
|
)
|
76
105
|
end
|
77
106
|
|
78
107
|
sig { returns(ConstantDiscovery) }
|
79
108
|
def context_provider
|
80
|
-
::Packwerk::ConstantDiscovery.new(
|
109
|
+
@context_provider ||= ::Packwerk::ConstantDiscovery.new(
|
81
110
|
constant_resolver: resolver,
|
82
111
|
packages: package_set
|
83
112
|
)
|
@@ -86,27 +115,22 @@ module Packwerk
|
|
86
115
|
sig { returns(ConstantResolver) }
|
87
116
|
def resolver
|
88
117
|
ConstantResolver.new(
|
89
|
-
root_path: root_path,
|
90
|
-
load_paths: load_paths,
|
91
|
-
inflector: inflector,
|
118
|
+
root_path: @root_path,
|
119
|
+
load_paths: @load_paths,
|
120
|
+
inflector: @inflector,
|
92
121
|
)
|
93
122
|
end
|
94
123
|
|
95
124
|
sig { returns(PackageSet) }
|
96
125
|
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)
|
126
|
+
::Packwerk::PackageSet.load_all_from(@root_path, package_pathspec: @package_paths)
|
103
127
|
end
|
104
128
|
|
105
129
|
sig { returns(T::Array[ConstantNameInspector]) }
|
106
130
|
def constant_name_inspectors
|
107
131
|
[
|
108
132
|
::Packwerk::ConstNodeInspector.new,
|
109
|
-
::Packwerk::AssociationInspector.new(inflector: inflector, custom_associations: custom_associations),
|
133
|
+
::Packwerk::AssociationInspector.new(inflector: @inflector, custom_associations: @custom_associations),
|
110
134
|
]
|
111
135
|
end
|
112
136
|
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,6 +15,7 @@ module Packwerk
|
|
12
15
|
autoload :ApplicationValidator
|
13
16
|
autoload :AssociationInspector
|
14
17
|
autoload :OffenseCollection
|
18
|
+
autoload :Cache
|
15
19
|
autoload :Cli
|
16
20
|
autoload :Configuration
|
17
21
|
autoload :ConstantDiscovery
|
@@ -21,7 +25,6 @@ module Packwerk
|
|
21
25
|
autoload :FileProcessor
|
22
26
|
autoload :FilesForProcessing
|
23
27
|
autoload :Graph
|
24
|
-
autoload :Inflector
|
25
28
|
autoload :Node
|
26
29
|
autoload :NodeProcessor
|
27
30
|
autoload :NodeProcessorFactory
|
@@ -34,6 +37,7 @@ module Packwerk
|
|
34
37
|
autoload :ParsedConstantDefinitions
|
35
38
|
autoload :Parsers
|
36
39
|
autoload :ParseRun
|
40
|
+
autoload :UnresolvedReference
|
37
41
|
autoload :Reference
|
38
42
|
autoload :ReferenceExtractor
|
39
43
|
autoload :ReferenceOffense
|
@@ -42,13 +46,6 @@ module Packwerk
|
|
42
46
|
autoload :Version
|
43
47
|
autoload :ViolationType
|
44
48
|
|
45
|
-
module Inflections
|
46
|
-
extend ActiveSupport::Autoload
|
47
|
-
|
48
|
-
autoload :Custom
|
49
|
-
autoload :Default
|
50
|
-
end
|
51
|
-
|
52
49
|
module OutputStyles
|
53
50
|
extend ActiveSupport::Autoload
|
54
51
|
|
@@ -71,7 +68,6 @@ module Packwerk
|
|
71
68
|
extend ActiveSupport::Autoload
|
72
69
|
|
73
70
|
autoload :ConfigurationFile
|
74
|
-
autoload :InflectionsFile
|
75
71
|
autoload :RootPackage
|
76
72
|
end
|
77
73
|
|
data/packwerk.gemspec
CHANGED
@@ -45,6 +45,7 @@ Gem::Specification.new do |spec|
|
|
45
45
|
spec.add_dependency("parallel")
|
46
46
|
spec.add_dependency("sorbet-runtime")
|
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")
|
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: 1.
|
4
|
+
version: 2.1.1
|
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-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
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
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rake
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -195,6 +209,7 @@ files:
|
|
195
209
|
- ".gitignore"
|
196
210
|
- ".rubocop.yml"
|
197
211
|
- ".ruby-version"
|
212
|
+
- CHANGELOG.md
|
198
213
|
- CODEOWNERS
|
199
214
|
- CODE_OF_CONDUCT.md
|
200
215
|
- CONTRIBUTING.md
|
@@ -204,6 +219,7 @@ files:
|
|
204
219
|
- README.md
|
205
220
|
- Rakefile
|
206
221
|
- TROUBLESHOOT.md
|
222
|
+
- UPGRADING.md
|
207
223
|
- USAGE.md
|
208
224
|
- bin/console
|
209
225
|
- bin/m
|
@@ -220,6 +236,7 @@ files:
|
|
220
236
|
- lib/packwerk/application_load_paths.rb
|
221
237
|
- lib/packwerk/application_validator.rb
|
222
238
|
- lib/packwerk/association_inspector.rb
|
239
|
+
- lib/packwerk/cache.rb
|
223
240
|
- lib/packwerk/cli.rb
|
224
241
|
- lib/packwerk/configuration.rb
|
225
242
|
- lib/packwerk/const_node_inspector.rb
|
@@ -231,15 +248,10 @@ files:
|
|
231
248
|
- lib/packwerk/formatters/offenses_formatter.rb
|
232
249
|
- lib/packwerk/formatters/progress_formatter.rb
|
233
250
|
- lib/packwerk/generators/configuration_file.rb
|
234
|
-
- lib/packwerk/generators/inflections_file.rb
|
235
251
|
- lib/packwerk/generators/root_package.rb
|
236
|
-
- lib/packwerk/generators/templates/inflections.yml
|
237
252
|
- lib/packwerk/generators/templates/package.yml
|
238
253
|
- lib/packwerk/generators/templates/packwerk.yml.erb
|
239
254
|
- lib/packwerk/graph.rb
|
240
|
-
- lib/packwerk/inflections/custom.rb
|
241
|
-
- lib/packwerk/inflections/default.rb
|
242
|
-
- lib/packwerk/inflector.rb
|
243
255
|
- lib/packwerk/node.rb
|
244
256
|
- lib/packwerk/node_processor.rb
|
245
257
|
- lib/packwerk/node_processor_factory.rb
|
@@ -257,6 +269,7 @@ files:
|
|
257
269
|
- lib/packwerk/parsers.rb
|
258
270
|
- lib/packwerk/parsers/erb.rb
|
259
271
|
- lib/packwerk/parsers/factory.rb
|
272
|
+
- lib/packwerk/parsers/parser_interface.rb
|
260
273
|
- lib/packwerk/parsers/ruby.rb
|
261
274
|
- lib/packwerk/reference.rb
|
262
275
|
- lib/packwerk/reference_checking/checkers/checker.rb
|
@@ -269,6 +282,7 @@ files:
|
|
269
282
|
- lib/packwerk/run_context.rb
|
270
283
|
- lib/packwerk/sanity_checker.rb
|
271
284
|
- lib/packwerk/spring_command.rb
|
285
|
+
- lib/packwerk/unresolved_reference.rb
|
272
286
|
- lib/packwerk/version.rb
|
273
287
|
- lib/packwerk/violation_type.rb
|
274
288
|
- library.yml
|
@@ -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,49 +0,0 @@
|
|
1
|
-
# typed: true
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "active_support/inflector"
|
5
|
-
|
6
|
-
module Packwerk
|
7
|
-
# A custom inflector used, among other things, to map between constant names and file names.
|
8
|
-
class Inflector
|
9
|
-
class << self
|
10
|
-
extend T::Sig
|
11
|
-
|
12
|
-
def default
|
13
|
-
@default ||= new(custom_inflector: Inflections::Custom.new)
|
14
|
-
end
|
15
|
-
|
16
|
-
sig { params(inflections_file: String).returns(::Packwerk::Inflector) }
|
17
|
-
def from_file(inflections_file)
|
18
|
-
new(custom_inflector: Inflections::Custom.new(inflections_file))
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
extend T::Sig
|
23
|
-
include ::ActiveSupport::Inflector # For #camelize, #classify, #pluralize, #singularize
|
24
|
-
|
25
|
-
sig do
|
26
|
-
params(
|
27
|
-
custom_inflector: Inflections::Custom
|
28
|
-
).void
|
29
|
-
end
|
30
|
-
def initialize(custom_inflector:)
|
31
|
-
@inflections = ::ActiveSupport::Inflector::Inflections.new
|
32
|
-
|
33
|
-
Inflections::Default.apply_to(@inflections)
|
34
|
-
custom_inflector.apply_to(@inflections)
|
35
|
-
end
|
36
|
-
|
37
|
-
def pluralize(word, count = nil)
|
38
|
-
if count == 1
|
39
|
-
singularize(word)
|
40
|
-
else
|
41
|
-
super(word)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def inflections(_ = nil)
|
46
|
-
@inflections
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|