packwerk 1.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d150d89ede62e601246e2ff0290ecda4aab883a7c8b8be02feb86760ad26b72
4
- data.tar.gz: 33b088b3387b8fdfe694967f20529fb8795dec8572dc9e036cb4979402f19c5b
3
+ metadata.gz: a473db2c54adea132ca7e61a51072b570d7e37b7d63c021259eef3cc7625177b
4
+ data.tar.gz: 1b8486e61969621fac562d2fb6ebe47dcf6f71fcd13f6d18524337a3ed831ac2
5
5
  SHA512:
6
- metadata.gz: 102154447670b85dc4e0825dcdf1ec11cd0fd291ffc1c7230b98da2208b0a39c38d2c8726a33226aeea68082e16a24917db7ad3380c871b9b02b0d76c8ac69fc
7
- data.tar.gz: 666e3745e9167028e5d3901d74400848c87c1b8a64a7487d3e4bfe13916e2902990633db7c448057b8106fd4b6b5c5de08c697c88151a305c92d34259266448f
6
+ metadata.gz: 8c05f0ce6e8b398a87e98453c721d00707628918ce8455600c1cb00fb2cb9c68efc6bea373323e889d36fc3658ff45db3508b0e6386b876da58ca50cdb53ab9f
7
+ data.tar.gz: 51586b68f489ff1f32df06338d05a64cab753da56c11575b3c5c8fa55019e9a8527e0a20c54c8695e1432307227d26c10f01b0d6c610e41c55d84296be000bd8
data/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ See https://github.com/Shopify/packwerk/releases.
data/Gemfile.lock CHANGED
@@ -87,7 +87,7 @@ GIT
87
87
  PATH
88
88
  remote: .
89
89
  specs:
90
- packwerk (1.4.0)
90
+ packwerk (2.0.0)
91
91
  activesupport (>= 5.2)
92
92
  ast
93
93
  better_html
data/README.md CHANGED
@@ -35,8 +35,6 @@ Watch a [1-minute video demo](https://www.youtube.com/watch?v=NwqlyBAxVpQ&featur
35
35
  gem 'packwerk'
36
36
  ```
37
37
 
38
- _Note: Packwerk has to be grouped in production environment within the Gemfile if your Rails app has custom inflections._
39
-
40
38
  2. Install the gem
41
39
 
42
40
  Execute:
data/UPGRADING.md ADDED
@@ -0,0 +1,54 @@
1
+ # Upgrading from 1.x to 2.0
2
+
3
+ With Packwerk 2.0, we made a few changes to simplify the setup. Updating will require removing some previously necessary files and configuration.
4
+
5
+ ## Gem group
6
+
7
+ Because packwerk is no longer involved in specifying the application's inflections, it doesn't have to live in the `production` group in your `Gemfile` anymore. We recommend moving it to the `development` group.
8
+
9
+ ## Removing application config caches
10
+
11
+ ### Load paths
12
+ We no longer require the `load_paths` key in `packwerk.yml`. You can simply delete the load_paths key as it will not be read anymore. Instead, Packwerk will ask Rails for load paths. If you're using spring, make sure to properly set up spring (see [USAGE.md](USAGE.md#setting-up-spring)) to keep packwerk fast.
13
+
14
+ ### Inflections
15
+ We no longer require a custom `inflections.yml` file. Instead, you'll want to revert BACK to using the `inflections.rb` initializer as you would have done prior to adopting packwerk. To do this, you'll want to convert back to using the plain [ActiveSupport Inflections API](https://api.rubyonrails.org/classes/ActiveSupport/Inflector/Inflections.html).
16
+
17
+
18
+ Given the following example `inflections.yml`, here is an example `inflections.rb` that would follow. Tip: if you're using git, you can run `git log config/inflections.yml`, find the first commit that introduced `inflections.yml`, find the COMMIT_SHA, and then run `git show COMMIT_SHA` to see what your inflections file looked like before (note that you may have changed `inflections.yml` since then, though).
19
+
20
+ `config/inflections.yml`
21
+ ```yml
22
+ # List your inflections in this file instead of `inflections.rb`
23
+ # See steps to set up custom inflections:
24
+ # https://github.com/Shopify/packwerk/blob/main/USAGE.md#Inflections
25
+
26
+ acronym:
27
+ - 'HTML'
28
+ - 'API'
29
+
30
+ singular:
31
+ - ['oxen', 'oxen']
32
+
33
+ irregular:
34
+ - ['person', 'people']
35
+
36
+ uncountable:
37
+ - 'fish'
38
+ - 'sheep'
39
+ ```
40
+
41
+ `config/initializers/inflections.rb`
42
+ ```ruby
43
+ ActiveSupport::Inflector.inflections(:en) do |inflect|
44
+ inflect.acronym('HTML')
45
+ inflect.acronym('API')
46
+
47
+ inflect.singular('oxen', 'oxen')
48
+
49
+ inflect.irregular('person', 'people')
50
+
51
+ inflect.uncountable('fish')
52
+ inflect.uncountable('sheep')
53
+ end
54
+ ```
data/USAGE.md CHANGED
@@ -9,7 +9,6 @@
9
9
  * [Setting up Spring](#setting-up-spring)
10
10
  * [Configuring Packwerk](#configuring-packwerk)
11
11
  * [Using a custom ERB parser](#using-a-custom-erb-parser)
12
- * [Inflections](#inflections)
13
12
  * [Validating the package system](#validating-the-package-system)
14
13
  * [Defining packages](#defining-packages)
15
14
  * [Package metadata](#package-metadata)
@@ -57,7 +56,6 @@ Here is a list of files generated:
57
56
  |-----------------------------|--------------|------------|
58
57
  | Packwerk configuration | packwerk.yml | See [Setting up the configuration file](#Setting-up-the-configuration-file) |
59
58
  | Root package | package.yml | A package for the root folder |
60
- | Custom inflections | config/inflections.yml | A custom inflections file is only required if you have custom inflections in `inflections.rb`, see [Inflections](#Inflections) |
61
59
 
62
60
  After that, you may begin creating packages for your application. See [Defining packages](#Defining-packages)
63
61
 
@@ -77,7 +75,6 @@ Packwerk reads from the `packwerk.yml` configuration file in the root directory.
77
75
  | include | **/*.{rb,rake,erb} | list of patterns for folder paths to include |
78
76
  | exclude | {bin,node_modules,script,tmp,vendor}/**/* | list of patterns for folder paths to exclude |
79
77
  | package_paths | **/ | a single pattern or a list of patterns to find package configuration files, see: [Defining packages](#Defining-packages) |
80
- | load_paths | All application autoload paths | list of load paths |
81
78
  | custom_associations | N/A | list of custom associations, if any |
82
79
  | parallel | true | when true, fork code parsing out to subprocesses |
83
80
 
@@ -103,45 +100,6 @@ end
103
100
  Packwerk::Parsers::Factory.instance.erb_parser_class = CustomParser
104
101
  ```
105
102
 
106
- ### Inflections
107
-
108
- Packwerk requires custom inflections to be defined in `inflections.yml` instead of the traditional `inflections.rb`. This is because Packwerk accounts for custom inflections, such as acronyms, when resolving constants. Additionally, Packwerk interprets Active Record associations as references to constants. For example, `has_many :birds` is a reference to the `Bird` constant.
109
-
110
- In order to make your custom inflections compatible with Active Support and Packwerk, you must create a `config/inflections.yml` file and point `ActiveSupport::Inflector` to that file.
111
-
112
- In `inflections.rb`, add:
113
-
114
- ```rb
115
- require "packwerk/inflections/custom"
116
-
117
- ActiveSupport::Inflector.inflections do |inflect|
118
- # please add all custom inflections in the file below.
119
- Packwerk::Inflections::Custom.new(
120
- Rails.root.join("config", "inflections.yml")
121
- ).apply_to(inflect)
122
- end
123
- ```
124
-
125
- _Note: Packwerk has to be grouped in production environment within the Gemfile if you have custom inflections._
126
-
127
- Next, move your existing custom inflections into `config/inflections.yml`:
128
-
129
- ```yaml
130
- acronym:
131
- - 'GraphQL'
132
- - 'MRuby'
133
- - 'TOS'
134
- irregular:
135
- - ['analysis', 'analyses']
136
- - ['reserve', 'reserves']
137
- uncountable:
138
- - 'payment_details'
139
- singular:
140
- - [!ruby/regexp /status$/, 'status']
141
- ```
142
-
143
- Any new inflectors should be added to `config/inflections.yml`.
144
-
145
103
  ## Validating the package system
146
104
 
147
105
  There are some criteria that an application must meet in order to have a valid package system. These criteria include having a valid autoload path cache, package definition files, and application folder structure. The dependency graph within the package system also has to be acyclic.
@@ -1,7 +1,6 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- require "active_support/inflector/inflections"
5
4
  require "constant_resolver"
6
5
  require "pathname"
7
6
  require "yaml"
@@ -14,19 +13,15 @@ module Packwerk
14
13
  @config_file_path = config_file_path
15
14
  @configuration = configuration
16
15
  @environment = environment
17
-
18
- @application_load_paths = ApplicationLoadPaths.extract_relevant_paths(configuration.root_path, environment)
19
16
  end
20
17
 
21
18
  Result = Struct.new(:ok?, :error_value)
22
19
 
23
20
  def check_all
24
21
  results = [
25
- check_autoload_path_cache,
26
22
  check_package_manifests_for_privacy,
27
23
  check_package_manifest_syntax,
28
24
  check_application_structure,
29
- check_inflection_file,
30
25
  check_acyclic_graph,
31
26
  check_package_manifest_paths,
32
27
  check_valid_package_dependencies,
@@ -36,21 +31,6 @@ module Packwerk
36
31
  merge_results(results)
37
32
  end
38
33
 
39
- def check_autoload_path_cache
40
- expected = Set.new(@application_load_paths)
41
- actual = Set.new(@configuration.load_paths)
42
- if expected == actual
43
- Result.new(true)
44
- else
45
- Result.new(
46
- false,
47
- "Load path cache in #{@config_file_path} incorrect!\n"\
48
- "Paths missing from file:\n#{format_yaml_strings(expected - actual)}\n"\
49
- "Extraneous load paths in file:\n#{format_yaml_strings(actual - expected)}"
50
- )
51
- end
52
- end
53
-
54
34
  def check_package_manifests_for_privacy
55
35
  privacy_settings = package_manifests_settings_for("enforce_privacy")
56
36
 
@@ -142,39 +122,6 @@ module Packwerk
142
122
  end
143
123
  end
144
124
 
145
- def check_inflection_file
146
- inflections_file = @configuration.inflections_file
147
-
148
- application_inflections = ActiveSupport::Inflector.inflections
149
- packwerk_inflections = Packwerk::Inflector.from_file(inflections_file).inflections
150
-
151
- results = %i(plurals singulars uncountables humans acronyms).map do |type|
152
- expected = application_inflections.public_send(type).to_set
153
- actual = packwerk_inflections.public_send(type).to_set
154
-
155
- if expected == actual
156
- Result.new(true)
157
- else
158
- missing_msg = unless (expected - actual).empty?
159
- "Expected #{type} to be specified in file: #{expected - actual}"
160
- end
161
- extraneous_msg = unless (actual - expected).empty?
162
- "Extraneous #{type} was specified in file: #{actual - expected}"
163
- end
164
- Result.new(
165
- false,
166
- [missing_msg, extraneous_msg].join("\n")
167
- )
168
- end
169
- end
170
-
171
- merge_results(
172
- results,
173
- separator: "\n",
174
- errors_headline: "Inflections specified in #{inflections_file} don't line up with application!\n"
175
- )
176
- end
177
-
178
125
  def check_acyclic_graph
179
126
  edges = package_set.flat_map do |package|
180
127
  package.dependencies.map { |dependency| [package, package_set.fetch(dependency)] }
@@ -19,7 +19,7 @@ module Packwerk
19
19
  CustomAssociations
20
20
  )
21
21
 
22
- sig { params(inflector: Inflector, custom_associations: CustomAssociations).void }
22
+ sig { params(inflector: T.class_of(ActiveSupport::Inflector), custom_associations: CustomAssociations).void }
23
23
  def initialize(inflector:, custom_associations: Set.new)
24
24
  @inflector = inflector
25
25
  @associations = T.let(RAILS_ASSOCIATIONS + custom_associations, CustomAssociations)
data/lib/packwerk/cli.rb CHANGED
@@ -53,8 +53,6 @@ module Packwerk
53
53
  output_result(parse_run(args).check)
54
54
  when "detect-stale-violations"
55
55
  output_result(parse_run(args).detect_stale_violations)
56
- when "update"
57
- update(args)
58
56
  when "update-deprecations"
59
57
  output_result(parse_run(args).update_deprecations)
60
58
  when "validate"
@@ -88,14 +86,13 @@ module Packwerk
88
86
 
89
87
  def generate_configs
90
88
  configuration_file = Packwerk::Generators::ConfigurationFile.generate(
91
- load_paths: Packwerk::ApplicationLoadPaths.extract_relevant_paths(@configuration.root_path, @environment),
92
89
  root: @configuration.root_path,
93
90
  out: @out
94
91
  )
95
- inflections_file = Packwerk::Generators::InflectionsFile.generate(root: @configuration.root_path, out: @out)
92
+
96
93
  root_package = Packwerk::Generators::RootPackage.generate(root: @configuration.root_path, out: @out)
97
94
 
98
- success = configuration_file && inflections_file && root_package
95
+ success = configuration_file && root_package
99
96
 
100
97
  result = if success
101
98
  <<~EOS
@@ -115,11 +112,6 @@ module Packwerk
115
112
  success
116
113
  end
117
114
 
118
- def update(paths)
119
- warn("`packwerk update` is deprecated in favor of `packwerk update-deprecations`.")
120
- output_result(parse_run(paths).update_deprecations)
121
- end
122
-
123
115
  def output_result(result)
124
116
  @out.puts
125
117
  @out.puts(result.message)
@@ -139,11 +131,6 @@ module Packwerk
139
131
 
140
132
  def validate(_paths)
141
133
  @progress_formatter.started_validation do
142
- checker = Packwerk::ApplicationValidator.new(
143
- config_file_path: @configuration.config_path,
144
- configuration: @configuration,
145
- environment: @environment,
146
- )
147
134
  result = checker.check_all
148
135
 
149
136
  list_validation_errors(result)
@@ -152,6 +139,14 @@ module Packwerk
152
139
  end
153
140
  end
154
141
 
142
+ def checker
143
+ Packwerk::ApplicationValidator.new(
144
+ config_file_path: @configuration.config_path,
145
+ configuration: @configuration,
146
+ environment: @environment,
147
+ )
148
+ end
149
+
155
150
  def list_validation_errors(result)
156
151
  @out.puts
157
152
  if result.ok?
@@ -34,24 +34,54 @@ module Packwerk
34
34
  DEFAULT_EXCLUDE_GLOBS = ["{bin,node_modules,script,tmp,vendor}/**/*"]
35
35
 
36
36
  attr_reader(
37
- :include, :exclude, :root_path, :package_paths, :custom_associations, :load_paths, :inflections_file,
38
- :config_path,
37
+ :include, :exclude, :root_path, :package_paths, :custom_associations, :config_path
39
38
  )
40
39
 
41
40
  def initialize(configs = {}, config_path: nil)
41
+ if configs["load_paths"]
42
+ warning = <<~WARNING
43
+ DEPRECATION WARNING: The 'load_paths' key in `packwerk.yml` is deprecated.
44
+ This value is no longer cached, and you can remove the key from `packwerk.yml`.
45
+ WARNING
46
+
47
+ warn(warning)
48
+ end
49
+
50
+ inflection_file = File.expand_path(configs["inflections_file"] || "config/inflections.yml", @root_path)
51
+ if configs["inflections_file"]
52
+ warning = <<~WARNING
53
+ DEPRECATION WARNING: The 'inflections_file' key in `packwerk.yml` is deprecated.
54
+ This value is no longer cached, and you can remove the key from `packwerk.yml`.
55
+ You can also delete #{configs["inflections_file"]}.
56
+ WARNING
57
+
58
+ warn(warning)
59
+ end
60
+
61
+ if Pathname.new(inflection_file).exist?
62
+ warning = <<~WARNING
63
+ DEPRECATION WARNING: Inflections YMLs in packwerk are now deprecated.
64
+ This value is no longer cached, and you can now delete #{inflection_file}
65
+ WARNING
66
+
67
+ warn(warning)
68
+ end
69
+
42
70
  @include = configs["include"] || DEFAULT_INCLUDE_GLOBS
43
71
  @exclude = configs["exclude"] || DEFAULT_EXCLUDE_GLOBS
44
72
  root = config_path ? File.dirname(config_path) : "."
45
73
  @root_path = File.expand_path(root)
46
74
  @package_paths = configs["package_paths"] || "**/"
47
75
  @custom_associations = configs["custom_associations"] || []
48
- @load_paths = (configs["load_paths"] || []).uniq
49
- @inflections_file = File.expand_path(configs["inflections_file"] || "config/inflections.yml", @root_path)
50
76
  @parallel = configs.key?("parallel") ? configs["parallel"] : true
51
77
 
52
78
  @config_path = config_path
53
79
  end
54
80
 
81
+ def load_paths
82
+ @load_paths ||= ApplicationLoadPaths.extract_relevant_paths(@root_path, "test")
83
+ end
84
+
55
85
  def parallel?
56
86
  @parallel
57
87
  end
@@ -45,7 +45,7 @@ module Packwerk
45
45
  begin
46
46
  constant = @resolver.resolve(const_name, current_namespace_path: current_namespace_path)
47
47
  rescue ConstantResolver::Error => e
48
- raise(ConstantResolver::Error, e.message + "\n Make sure autoload paths are added to the config file.")
48
+ raise(ConstantResolver::Error, e.message)
49
49
  end
50
50
 
51
51
  return unless constant
@@ -44,7 +44,7 @@ module Packwerk
44
44
 
45
45
  sig { params(offenses: T::Array[T.nilable(Offense)]).returns(String) }
46
46
  def offenses_summary(offenses)
47
- offenses_string = Inflector.default.pluralize("offense", offenses.length)
47
+ offenses_string = "offense".pluralize(offenses.length)
48
48
  "#{offenses.length} #{offenses_string} detected"
49
49
  end
50
50
  end
@@ -16,7 +16,7 @@ module Packwerk
16
16
 
17
17
  def started(target_files)
18
18
  files_size = target_files.size
19
- files_string = Inflector.default.pluralize("file", files_size)
19
+ files_string = "file".pluralize(files_size)
20
20
  @out.puts("📦 Packwerk is inspecting #{files_size} #{files_string}")
21
21
  end
22
22
 
@@ -11,18 +11,15 @@ module Packwerk
11
11
  CONFIGURATION_TEMPLATE_FILE_PATH = "templates/packwerk.yml.erb"
12
12
 
13
13
  class << self
14
- def generate(load_paths:, root:, out:)
15
- new(load_paths: load_paths, root: root, out: out).generate
14
+ def generate(root:, out:)
15
+ new(root: root, out: out).generate
16
16
  end
17
17
  end
18
18
 
19
- sig { params(load_paths: T::Array[String], root: String, out: T.any(StringIO, IO)).void }
20
- def initialize(load_paths:, root:, out: $stdout)
21
- @load_paths = load_paths
19
+ sig { params(root: String, out: T.any(StringIO, IO)).void }
20
+ def initialize(root:, out: $stdout)
22
21
  @root = root
23
22
  @out = out
24
-
25
- set_template_variables
26
23
  end
27
24
 
28
25
  sig { returns(T::Boolean) }
@@ -43,18 +40,6 @@ module Packwerk
43
40
 
44
41
  private
45
42
 
46
- def set_template_variables
47
- @load_paths_formatted = if @load_paths.empty?
48
- "# load_paths:\n# - 'app/models'\n"
49
- else
50
- @load_paths.map { |path| "- #{path}\n" }.join
51
- end
52
-
53
- @load_paths_comment = unless @load_paths.empty?
54
- "# These load paths were auto generated by Packwerk.\nload_paths:\n"
55
- end
56
- end
57
-
58
43
  def render
59
44
  ERB.new(template, trim_mode: "-").result(binding)
60
45
  end
@@ -12,12 +12,6 @@
12
12
  # Patterns to find package configuration files
13
13
  # package_paths: "**/"
14
14
 
15
- # List of application load paths
16
- <%= @load_paths_comment -%>
17
- <%= @load_paths_formatted %>
18
15
  # List of custom associations, if any
19
16
  # custom_associations:
20
17
  # - "cache_belongs_to"
21
-
22
- # Location of inflections file
23
- # inflections_file: "config/inflections.yml"
@@ -24,7 +24,7 @@ module Packwerk
24
24
 
25
25
  class << self
26
26
  def from_configuration(configuration)
27
- inflector = ::Packwerk::Inflector.from_file(configuration.inflections_file)
27
+ inflector = ActiveSupport::Inflector
28
28
  new(
29
29
  root_path: configuration.root_path,
30
30
  load_paths: configuration.load_paths,
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
5
- VERSION = "1.4.0"
5
+ VERSION = "2.0.0"
6
6
  end
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
 
@@ -21,7 +24,6 @@ module Packwerk
21
24
  autoload :FileProcessor
22
25
  autoload :FilesForProcessing
23
26
  autoload :Graph
24
- autoload :Inflector
25
27
  autoload :Node
26
28
  autoload :NodeProcessor
27
29
  autoload :NodeProcessorFactory
@@ -42,13 +44,6 @@ module Packwerk
42
44
  autoload :Version
43
45
  autoload :ViolationType
44
46
 
45
- module Inflections
46
- extend ActiveSupport::Autoload
47
-
48
- autoload :Custom
49
- autoload :Default
50
- end
51
-
52
47
  module OutputStyles
53
48
  extend ActiveSupport::Autoload
54
49
 
@@ -71,7 +66,6 @@ module Packwerk
71
66
  extend ActiveSupport::Autoload
72
67
 
73
68
  autoload :ConfigurationFile
74
- autoload :InflectionsFile
75
69
  autoload :RootPackage
76
70
  end
77
71
 
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.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-11-24 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
@@ -195,6 +195,7 @@ files:
195
195
  - ".gitignore"
196
196
  - ".rubocop.yml"
197
197
  - ".ruby-version"
198
+ - CHANGELOG.md
198
199
  - CODEOWNERS
199
200
  - CODE_OF_CONDUCT.md
200
201
  - CONTRIBUTING.md
@@ -204,6 +205,7 @@ files:
204
205
  - README.md
205
206
  - Rakefile
206
207
  - TROUBLESHOOT.md
208
+ - UPGRADING.md
207
209
  - USAGE.md
208
210
  - bin/console
209
211
  - bin/m
@@ -231,15 +233,10 @@ files:
231
233
  - lib/packwerk/formatters/offenses_formatter.rb
232
234
  - lib/packwerk/formatters/progress_formatter.rb
233
235
  - lib/packwerk/generators/configuration_file.rb
234
- - lib/packwerk/generators/inflections_file.rb
235
236
  - lib/packwerk/generators/root_package.rb
236
- - lib/packwerk/generators/templates/inflections.yml
237
237
  - lib/packwerk/generators/templates/package.yml
238
238
  - lib/packwerk/generators/templates/packwerk.yml.erb
239
239
  - lib/packwerk/graph.rb
240
- - lib/packwerk/inflections/custom.rb
241
- - lib/packwerk/inflections/default.rb
242
- - lib/packwerk/inflector.rb
243
240
  - lib/packwerk/node.rb
244
241
  - lib/packwerk/node_processor.rb
245
242
  - lib/packwerk/node_processor_factory.rb
@@ -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
@@ -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