packwerk 1.3.0 → 2.0.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/Gemfile.lock +11 -8
  4. data/README.md +2 -3
  5. data/TROUBLESHOOT.md +3 -3
  6. data/UPGRADING.md +54 -0
  7. data/USAGE.md +27 -53
  8. data/exe/packwerk +7 -1
  9. data/lib/packwerk/application_load_paths.rb +1 -0
  10. data/lib/packwerk/application_validator.rb +3 -54
  11. data/lib/packwerk/association_inspector.rb +1 -1
  12. data/lib/packwerk/cli.rb +37 -20
  13. data/lib/packwerk/configuration.rb +34 -4
  14. data/lib/packwerk/const_node_inspector.rb +3 -2
  15. data/lib/packwerk/constant_discovery.rb +1 -1
  16. data/lib/packwerk/constant_name_inspector.rb +1 -1
  17. data/lib/packwerk/deprecated_references.rb +19 -7
  18. data/lib/packwerk/file_processor.rb +39 -14
  19. data/lib/packwerk/files_for_processing.rb +15 -4
  20. data/lib/packwerk/formatters/offenses_formatter.rb +1 -1
  21. data/lib/packwerk/formatters/progress_formatter.rb +1 -1
  22. data/lib/packwerk/generators/configuration_file.rb +4 -19
  23. data/lib/packwerk/generators/templates/package.yml +1 -1
  24. data/lib/packwerk/generators/templates/packwerk.yml.erb +0 -6
  25. data/lib/packwerk/graph.rb +2 -0
  26. data/lib/packwerk/node.rb +1 -0
  27. data/lib/packwerk/node_processor.rb +10 -22
  28. data/lib/packwerk/node_processor_factory.rb +0 -2
  29. data/lib/packwerk/node_visitor.rb +4 -2
  30. data/lib/packwerk/package.rb +25 -4
  31. data/lib/packwerk/package_set.rb +43 -8
  32. data/lib/packwerk/parsed_constant_definitions.rb +1 -0
  33. data/lib/packwerk/reference.rb +2 -1
  34. data/lib/packwerk/reference_checking/checkers/checker.rb +21 -0
  35. data/lib/packwerk/reference_checking/checkers/dependency_checker.rb +31 -0
  36. data/lib/packwerk/reference_checking/checkers/privacy_checker.rb +58 -0
  37. data/lib/packwerk/reference_checking/reference_checker.rb +33 -0
  38. data/lib/packwerk/reference_extractor.rb +2 -2
  39. data/lib/packwerk/reference_offense.rb +1 -0
  40. data/lib/packwerk/run_context.rb +10 -7
  41. data/lib/packwerk/sanity_checker.rb +1 -1
  42. data/lib/packwerk/spring_command.rb +28 -0
  43. data/lib/packwerk/version.rb +1 -1
  44. data/lib/packwerk/violation_type.rb +1 -1
  45. data/lib/packwerk.rb +17 -12
  46. data/packwerk.gemspec +3 -1
  47. data/service.yml +0 -2
  48. data/sorbet/rbi/gems/psych@3.3.2.rbi +24 -0
  49. metadata +25 -11
  50. data/lib/packwerk/checker.rb +0 -17
  51. data/lib/packwerk/dependency_checker.rb +0 -26
  52. data/lib/packwerk/generators/inflections_file.rb +0 -43
  53. data/lib/packwerk/generators/templates/inflections.yml +0 -6
  54. data/lib/packwerk/inflections/custom.rb +0 -33
  55. data/lib/packwerk/inflections/default.rb +0 -73
  56. data/lib/packwerk/inflector.rb +0 -48
  57. data/lib/packwerk/privacy_checker.rb +0 -53
@@ -0,0 +1,58 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Packwerk
5
+ module ReferenceChecking
6
+ module Checkers
7
+ # Checks whether a given reference references a private constant of another package.
8
+ class PrivacyChecker
9
+ extend T::Sig
10
+ include Checker
11
+
12
+ sig { override.returns(Packwerk::ViolationType) }
13
+ def violation_type
14
+ ViolationType::Privacy
15
+ end
16
+
17
+ sig do
18
+ override
19
+ .params(reference: Packwerk::Reference)
20
+ .returns(T::Boolean)
21
+ end
22
+ def invalid_reference?(reference)
23
+ return false if reference.constant.public?
24
+
25
+ privacy_option = reference.constant.package.enforce_privacy
26
+ return false if enforcement_disabled?(privacy_option)
27
+
28
+ return false unless privacy_option == true ||
29
+ explicitly_private_constant?(reference.constant, explicitly_private_constants: privacy_option)
30
+
31
+ true
32
+ end
33
+
34
+ private
35
+
36
+ sig do
37
+ params(
38
+ constant: ConstantDiscovery::ConstantContext,
39
+ explicitly_private_constants: T::Array[String]
40
+ ).returns(T::Boolean)
41
+ end
42
+ def explicitly_private_constant?(constant, explicitly_private_constants:)
43
+ explicitly_private_constants.include?(constant.name) ||
44
+ # nested constants
45
+ explicitly_private_constants.any? { |epc| constant.name.start_with?(epc + "::") }
46
+ end
47
+
48
+ sig do
49
+ params(privacy_option: T.nilable(T.any(T::Boolean, T::Array[String])))
50
+ .returns(T::Boolean)
51
+ end
52
+ def enforcement_disabled?(privacy_option)
53
+ [false, nil].include?(privacy_option)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,33 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Packwerk
5
+ module ReferenceChecking
6
+ class ReferenceChecker
7
+ extend T::Sig
8
+
9
+ def initialize(checkers)
10
+ @checkers = checkers
11
+ end
12
+
13
+ sig do
14
+ params(
15
+ reference: T.any(Packwerk::Reference, Packwerk::Offense)
16
+ ).returns(T::Array[Packwerk::Offense])
17
+ end
18
+ def call(reference)
19
+ return [reference] if reference.is_a?(Packwerk::Offense)
20
+
21
+ @checkers.each_with_object([]) do |checker, violations|
22
+ next unless checker.invalid_reference?(reference)
23
+ offense = Packwerk::ReferenceOffense.new(
24
+ location: reference.source_location,
25
+ reference: reference,
26
+ violation_type: checker.violation_type
27
+ )
28
+ violations << offense
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
5
- # extracts a possible constant reference from a given AST node
5
+ # Extracts a possible constant reference from a given AST node.
6
6
  class ReferenceExtractor
7
7
  extend T::Sig
8
8
 
@@ -59,7 +59,7 @@ module Packwerk
59
59
 
60
60
  return if source_package == constant.package
61
61
 
62
- Reference.new(source_package, relative_path, constant)
62
+ Reference.new(source_package, relative_path, constant, Node.location(node))
63
63
  end
64
64
 
65
65
  def local_reference?(constant_name, name_location, namespace_path)
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
5
+ # An offense related to a {Packwerk::Reference}.
5
6
  class ReferenceOffense < Offense
6
7
  extend T::Sig
7
8
  extend T::Helpers
@@ -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,13 +18,13 @@ 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 = ::Packwerk::Inflector.from_file(configuration.inflections_file)
27
+ inflector = ActiveSupport::Inflector
27
28
  new(
28
29
  root_path: configuration.root_path,
29
30
  load_paths: configuration.load_paths,
@@ -50,9 +51,12 @@ module Packwerk
50
51
  @checker_classes = checker_classes
51
52
  end
52
53
 
53
- sig { params(file: String).returns(T::Array[T.nilable(::Packwerk::Offense)]) }
54
+ sig { params(file: String).returns(T::Array[Packwerk::Offense]) }
54
55
  def process_file(file:)
55
- file_processor.call(file)
56
+ references = file_processor.call(file)
57
+
58
+ reference_checker = ReferenceChecking::ReferenceChecker.new(checkers)
59
+ references.flat_map { |reference| reference_checker.call(reference) }
56
60
  end
57
61
 
58
62
  private
@@ -66,7 +70,6 @@ module Packwerk
66
70
  def node_processor_factory
67
71
  NodeProcessorFactory.new(
68
72
  context_provider: context_provider,
69
- checkers: checkers,
70
73
  root_path: root_path,
71
74
  constant_name_inspectors: constant_name_inspectors
72
75
  )
@@ -94,7 +97,7 @@ module Packwerk
94
97
  ::Packwerk::PackageSet.load_all_from(root_path, package_pathspec: package_paths)
95
98
  end
96
99
 
97
- sig { returns(T::Array[Checker]) }
100
+ sig { returns(T::Array[ReferenceChecking::Checkers::Checker]) }
98
101
  def checkers
99
102
  checker_classes.map(&:new)
100
103
  end
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
@@ -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
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
5
- VERSION = "1.3.0"
5
+ VERSION = "2.0.0"
6
6
  end
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
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,15 @@ module Packwerk
12
15
  autoload :ApplicationValidator
13
16
  autoload :AssociationInspector
14
17
  autoload :OffenseCollection
15
- autoload :Checker
16
18
  autoload :Cli
17
19
  autoload :Configuration
18
20
  autoload :ConstantDiscovery
19
21
  autoload :ConstantNameInspector
20
22
  autoload :ConstNodeInspector
21
- autoload :DependencyChecker
22
23
  autoload :DeprecatedReferences
23
24
  autoload :FileProcessor
24
25
  autoload :FilesForProcessing
25
26
  autoload :Graph
26
- autoload :Inflector
27
27
  autoload :Node
28
28
  autoload :NodeProcessor
29
29
  autoload :NodeProcessorFactory
@@ -36,7 +36,6 @@ module Packwerk
36
36
  autoload :ParsedConstantDefinitions
37
37
  autoload :Parsers
38
38
  autoload :ParseRun
39
- autoload :PrivacyChecker
40
39
  autoload :Reference
41
40
  autoload :ReferenceExtractor
42
41
  autoload :ReferenceOffense
@@ -45,13 +44,6 @@ module Packwerk
45
44
  autoload :Version
46
45
  autoload :ViolationType
47
46
 
48
- module Inflections
49
- extend ActiveSupport::Autoload
50
-
51
- autoload :Custom
52
- autoload :Default
53
- end
54
-
55
47
  module OutputStyles
56
48
  extend ActiveSupport::Autoload
57
49
 
@@ -74,7 +66,20 @@ module Packwerk
74
66
  extend ActiveSupport::Autoload
75
67
 
76
68
  autoload :ConfigurationFile
77
- autoload :InflectionsFile
78
69
  autoload :RootPackage
79
70
  end
71
+
72
+ module ReferenceChecking
73
+ extend ActiveSupport::Autoload
74
+
75
+ autoload :ReferenceChecker
76
+
77
+ module Checkers
78
+ extend ActiveSupport::Autoload
79
+
80
+ autoload :Checker
81
+ autoload :DependencyChecker
82
+ autoload :PrivacyChecker
83
+ end
84
+ end
80
85
  end
data/packwerk.gemspec CHANGED
@@ -44,11 +44,13 @@ 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")
47
48
 
48
- spec.add_development_dependency("bundler")
49
49
  spec.add_development_dependency("rake")
50
50
  spec.add_development_dependency("sorbet")
51
51
  spec.add_development_dependency("m")
52
+ # https://github.com/ruby/psych/pull/487
53
+ spec.add_development_dependency("psych", "~> 3")
52
54
 
53
55
  # For Ruby parsing
54
56
  spec.add_dependency("ast")
data/service.yml CHANGED
@@ -1,3 +1 @@
1
1
  classification: library
2
- slack_channels:
3
- - core-stewardship
@@ -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.3.0
4
+ version: 2.0.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: 2021-07-07 00:00:00.000000000 Z
11
+ date: 2021-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -73,7 +73,7 @@ dependencies:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- type: :development
76
+ type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: psych
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: ast
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -181,6 +195,7 @@ files:
181
195
  - ".gitignore"
182
196
  - ".rubocop.yml"
183
197
  - ".ruby-version"
198
+ - CHANGELOG.md
184
199
  - CODEOWNERS
185
200
  - CODE_OF_CONDUCT.md
186
201
  - CONTRIBUTING.md
@@ -190,6 +205,7 @@ files:
190
205
  - README.md
191
206
  - Rakefile
192
207
  - TROUBLESHOOT.md
208
+ - UPGRADING.md
193
209
  - USAGE.md
194
210
  - bin/console
195
211
  - bin/m
@@ -206,28 +222,21 @@ files:
206
222
  - lib/packwerk/application_load_paths.rb
207
223
  - lib/packwerk/application_validator.rb
208
224
  - lib/packwerk/association_inspector.rb
209
- - lib/packwerk/checker.rb
210
225
  - lib/packwerk/cli.rb
211
226
  - lib/packwerk/configuration.rb
212
227
  - lib/packwerk/const_node_inspector.rb
213
228
  - lib/packwerk/constant_discovery.rb
214
229
  - lib/packwerk/constant_name_inspector.rb
215
- - lib/packwerk/dependency_checker.rb
216
230
  - lib/packwerk/deprecated_references.rb
217
231
  - lib/packwerk/file_processor.rb
218
232
  - lib/packwerk/files_for_processing.rb
219
233
  - lib/packwerk/formatters/offenses_formatter.rb
220
234
  - lib/packwerk/formatters/progress_formatter.rb
221
235
  - lib/packwerk/generators/configuration_file.rb
222
- - lib/packwerk/generators/inflections_file.rb
223
236
  - lib/packwerk/generators/root_package.rb
224
- - lib/packwerk/generators/templates/inflections.yml
225
237
  - lib/packwerk/generators/templates/package.yml
226
238
  - lib/packwerk/generators/templates/packwerk.yml.erb
227
239
  - lib/packwerk/graph.rb
228
- - lib/packwerk/inflections/custom.rb
229
- - lib/packwerk/inflections/default.rb
230
- - lib/packwerk/inflector.rb
231
240
  - lib/packwerk/node.rb
232
241
  - lib/packwerk/node_processor.rb
233
242
  - lib/packwerk/node_processor_factory.rb
@@ -246,13 +255,17 @@ files:
246
255
  - lib/packwerk/parsers/erb.rb
247
256
  - lib/packwerk/parsers/factory.rb
248
257
  - lib/packwerk/parsers/ruby.rb
249
- - lib/packwerk/privacy_checker.rb
250
258
  - lib/packwerk/reference.rb
259
+ - lib/packwerk/reference_checking/checkers/checker.rb
260
+ - lib/packwerk/reference_checking/checkers/dependency_checker.rb
261
+ - lib/packwerk/reference_checking/checkers/privacy_checker.rb
262
+ - lib/packwerk/reference_checking/reference_checker.rb
251
263
  - lib/packwerk/reference_extractor.rb
252
264
  - lib/packwerk/reference_offense.rb
253
265
  - lib/packwerk/result.rb
254
266
  - lib/packwerk/run_context.rb
255
267
  - lib/packwerk/sanity_checker.rb
268
+ - lib/packwerk/spring_command.rb
256
269
  - lib/packwerk/version.rb
257
270
  - lib/packwerk/violation_type.rb
258
271
  - library.yml
@@ -301,6 +314,7 @@ files:
301
314
  - sorbet/rbi/gems/parlour@6.0.0.rbi
302
315
  - sorbet/rbi/gems/parser@3.0.0.0.rbi
303
316
  - sorbet/rbi/gems/pry@0.14.0.rbi
317
+ - sorbet/rbi/gems/psych@3.3.2.rbi
304
318
  - sorbet/rbi/gems/racc@1.5.2.rbi
305
319
  - sorbet/rbi/gems/rack-test@1.1.0.rbi
306
320
  - sorbet/rbi/gems/rack@2.2.3.rbi
@@ -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,6 +0,0 @@
1
- # List your inflections in this file instead of `inflections.rb`
2
- # See steps to set up custom inflections:
3
- # https://github.com/Shopify/packwerk/blob/main/USAGE.md#Inflections
4
-
5
- # acronym:
6
- # - "GraphQL"
@@ -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