packwerk 1.3.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/Gemfile.lock +12 -9
  4. data/README.md +9 -3
  5. data/TROUBLESHOOT.md +3 -3
  6. data/UPGRADING.md +54 -0
  7. data/USAGE.md +32 -51
  8. data/exe/packwerk +7 -1
  9. data/lib/packwerk/application_load_paths.rb +1 -0
  10. data/lib/packwerk/application_validator.rb +17 -59
  11. data/lib/packwerk/association_inspector.rb +1 -1
  12. data/lib/packwerk/cache.rb +168 -0
  13. data/lib/packwerk/cli.rb +37 -20
  14. data/lib/packwerk/configuration.rb +40 -5
  15. data/lib/packwerk/const_node_inspector.rb +3 -2
  16. data/lib/packwerk/constant_discovery.rb +4 -4
  17. data/lib/packwerk/constant_name_inspector.rb +1 -1
  18. data/lib/packwerk/deprecated_references.rb +18 -6
  19. data/lib/packwerk/file_processor.rb +53 -14
  20. data/lib/packwerk/files_for_processing.rb +15 -4
  21. data/lib/packwerk/formatters/offenses_formatter.rb +1 -1
  22. data/lib/packwerk/formatters/progress_formatter.rb +1 -1
  23. data/lib/packwerk/generators/configuration_file.rb +4 -19
  24. data/lib/packwerk/generators/templates/package.yml +1 -1
  25. data/lib/packwerk/generators/templates/packwerk.yml.erb +5 -5
  26. data/lib/packwerk/graph.rb +2 -0
  27. data/lib/packwerk/node.rb +2 -0
  28. data/lib/packwerk/node_processor.rb +10 -22
  29. data/lib/packwerk/node_processor_factory.rb +0 -3
  30. data/lib/packwerk/node_visitor.rb +7 -2
  31. data/lib/packwerk/package.rb +25 -4
  32. data/lib/packwerk/package_set.rb +44 -8
  33. data/lib/packwerk/parsed_constant_definitions.rb +5 -4
  34. data/lib/packwerk/reference.rb +2 -1
  35. data/lib/packwerk/reference_checking/checkers/checker.rb +21 -0
  36. data/lib/packwerk/reference_checking/checkers/dependency_checker.rb +31 -0
  37. data/lib/packwerk/reference_checking/checkers/privacy_checker.rb +58 -0
  38. data/lib/packwerk/reference_checking/reference_checker.rb +33 -0
  39. data/lib/packwerk/reference_extractor.rb +66 -19
  40. data/lib/packwerk/reference_offense.rb +1 -0
  41. data/lib/packwerk/run_context.rb +32 -11
  42. data/lib/packwerk/sanity_checker.rb +1 -1
  43. data/lib/packwerk/spring_command.rb +28 -0
  44. data/lib/packwerk/unresolved_reference.rb +10 -0
  45. data/lib/packwerk/version.rb +1 -1
  46. data/lib/packwerk/violation_type.rb +1 -1
  47. data/lib/packwerk.rb +19 -12
  48. data/packwerk.gemspec +4 -1
  49. data/service.yml +0 -2
  50. data/sorbet/rbi/gems/psych@3.3.2.rbi +24 -0
  51. metadata +41 -11
  52. data/lib/packwerk/checker.rb +0 -17
  53. data/lib/packwerk/dependency_checker.rb +0 -26
  54. data/lib/packwerk/generators/inflections_file.rb +0 -43
  55. data/lib/packwerk/generators/templates/inflections.yml +0 -6
  56. data/lib/packwerk/inflections/custom.rb +0 -33
  57. data/lib/packwerk/inflections/default.rb +0 -73
  58. data/lib/packwerk/inflector.rb +0 -48
  59. data/lib/packwerk/privacy_checker.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bd8ccbf44a3bfe1eb5a0afb97fce3740ae641d1f8e938ad8bc8351d4ff8f74b
4
- data.tar.gz: 697369e81f54c8130844d4de6bcee75c328eeda1de8b24e04736acd5bbe1ed2a
3
+ metadata.gz: 66332315c1155336fbe79f8aeb6e44a0893d4100a1d4b6b5f08c81574c940fe0
4
+ data.tar.gz: 88da350ce07daaf7556d23edbc318a19ca33b74af71ee624d547a8a8598bc16b
5
5
  SHA512:
6
- metadata.gz: ac77bcba32e7e15a2c61aae6b90d76ef2dcae8c3d408a9e5b9746ea268c14a7421aabf082ac63148a1d53fb74b7ab3780c8145e50a9868a67472ad09294718e6
7
- data.tar.gz: 3c1819b3cf5417add105c1755856033dbc5339ed093450c45f241dd9aeb4828000fa67633f2a402f43634ea61af29d0f23d1244ea9049811714aab10f23fdd59
6
+ metadata.gz: b54eeeac5e68285e03c32916d72f2afdc291d9d6d4993de0d2875d7dbb4a9cdf8cde7ca2677107f35288a20a20c1f8fc2f9ddcc330c9a7fe0dfaf8e245c07b3c
7
+ data.tar.gz: d8597878958e00a069cb5e51c609e04da9526b3c1933c4824399e4bad1173d718703c88ec582411a9c73fb5c88899707b04ebdb7b296a22b70e25598e11b57d6
data/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ See https://github.com/Shopify/packwerk/releases.
data/Gemfile.lock CHANGED
@@ -87,11 +87,13 @@ GIT
87
87
  PATH
88
88
  remote: .
89
89
  specs:
90
- packwerk (1.3.1)
90
+ packwerk (2.1.0)
91
91
  activesupport (>= 5.2)
92
92
  ast
93
93
  better_html
94
+ bundler
94
95
  constant_resolver
96
+ digest
95
97
  parallel
96
98
  parser
97
99
  sorbet-runtime
@@ -117,6 +119,7 @@ GEM
117
119
  concurrent-ruby (1.1.8)
118
120
  constant_resolver (0.1.5)
119
121
  crass (1.0.6)
122
+ digest (3.1.0)
120
123
  erubi (1.10.0)
121
124
  globalid (0.4.2)
122
125
  activesupport (>= 4.2.0)
@@ -135,16 +138,14 @@ GEM
135
138
  marcel (1.0.0)
136
139
  method_source (1.0.0)
137
140
  mini_mime (1.0.3)
138
- mini_portile2 (2.5.1)
141
+ mini_portile2 (2.6.1)
139
142
  minitest (5.14.4)
140
143
  minitest-focus (1.2.1)
141
144
  minitest (>= 4, < 6)
142
145
  mocha (1.12.0)
143
146
  nio4r (2.5.7)
144
- nokogiri (1.11.5)
145
- mini_portile2 (~> 2.5.0)
146
- racc (~> 1.4)
147
- nokogiri (1.11.5-x86_64-darwin)
147
+ nokogiri (1.12.5)
148
+ mini_portile2 (~> 2.6.1)
148
149
  racc (~> 1.4)
149
150
  parallel (1.20.1)
150
151
  parlour (6.0.0)
@@ -157,6 +158,7 @@ GEM
157
158
  pry (0.14.0)
158
159
  coderay (~> 1.1)
159
160
  method_source (~> 1.0)
161
+ psych (3.3.2)
160
162
  racc (1.5.2)
161
163
  rack (2.2.3)
162
164
  rack-test (1.1.0)
@@ -189,7 +191,7 @@ GEM
189
191
  rubocop-sorbet (0.6.1)
190
192
  rubocop
191
193
  ruby-progressbar (1.11.0)
192
- smart_properties (1.15.0)
194
+ smart_properties (1.16.3)
193
195
  sorbet (0.5.6360)
194
196
  sorbet-static (= 0.5.6360)
195
197
  sorbet-runtime (0.5.6360)
@@ -233,16 +235,17 @@ GEM
233
235
 
234
236
  PLATFORMS
235
237
  ruby
238
+ x86_64-darwin
236
239
  x86_64-darwin-20
237
240
 
238
241
  DEPENDENCIES
239
- bundler
240
242
  byebug
241
243
  constant_resolver
242
244
  m
243
245
  minitest-focus
244
246
  mocha
245
247
  packwerk!
248
+ psych (~> 3)
246
249
  rails!
247
250
  rake
248
251
  rubocop-performance
@@ -254,4 +257,4 @@ DEPENDENCIES
254
257
  tapioca
255
258
 
256
259
  BUNDLED WITH
257
- 2.2.15
260
+ 2.3.4
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:
@@ -47,7 +45,8 @@ Or install it yourself as:
47
45
 
48
46
  $ gem install packwerk
49
47
 
50
- 3. Run `packwerk init` to generate the configuration files
48
+ 2. Run `bundle binstub packwerk` to generate the binstub
49
+ 3. Run `bin/packwerk init` to generate the configuration files
51
50
 
52
51
  ## Usage
53
52
 
@@ -57,6 +56,13 @@ Read [USAGE.md](USAGE.md) for usage once Packwerk is installed on your project.
57
56
 
58
57
  "Packwerk" is pronounced [[ˈpakvɛʁk]](https://cdn.shopify.com/s/files/1/0258/7469/files/packwerk.mp3).
59
58
 
59
+ ## Ecosystem
60
+
61
+ You can use these third party tools to enhance your packwerk experience:
62
+
63
+ - https://github.com/bellroy/graphwerk draws a graph of your package dependencies
64
+ - https://github.com/Gusto/packwerk-vscode integrates packwerk into Visual Studio Code so you can see violations right in your editor
65
+
60
66
  ## Development
61
67
 
62
68
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/TROUBLESHOOT.md CHANGED
@@ -14,11 +14,11 @@ Packwerk can give feedback via continuous integration (CI) if you have it set up
14
14
 
15
15
  You can specify folders or packages in Packwerk commands for a shorter run time:
16
16
 
17
- packwerk check components/your_package
17
+ bin/packwerk check components/your_package
18
18
 
19
- packwerk update-deprecations components/your_package
19
+ bin/packwerk update-deprecations components/your_package
20
20
 
21
- _Note: You cannot specify folders or packages for `packwerk validate` because the command runs for the entire application._
21
+ _Note: You cannot specify folders or packages for `bin/packwerk validate` because the command runs for the entire application._
22
22
 
23
23
  ![](static/packwerk_check_violation.gif)
24
24
 
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
@@ -6,8 +6,9 @@
6
6
  * [What is a package?](#what-is-a-package)
7
7
  * [Package principles](#package-principles)
8
8
  * [Getting started](#getting-started)
9
- * [Setting up the configuration file](#setting-up-the-configuration-file)
10
- * [Inflections](#inflections)
9
+ * [Setting up Spring](#setting-up-spring)
10
+ * [Configuring Packwerk](#configuring-packwerk)
11
+ * [Using a custom ERB parser](#using-a-custom-erb-parser)
11
12
  * [Validating the package system](#validating-the-package-system)
12
13
  * [Defining packages](#defining-packages)
13
14
  * [Package metadata](#package-metadata)
@@ -42,9 +43,12 @@ The [package principles](https://en.wikipedia.org/wiki/Package_principles) page
42
43
 
43
44
  ## Getting started
44
45
 
45
- After including Packwerk in the Gemfile, you can generate the necessary files to get Packwerk running by executing:
46
+ After including Packwerk in the Gemfile, you will first want to generate a binstub:
47
+ You can do this by running `bundle binstub packwerk`, which will generate a [binstub](https://bundler.io/man/bundle-binstubs.1.html#DESCRIPTION) at `bin/packwerk`.
46
48
 
47
- packwerk init
49
+ Then, you can generate the necessary files to get Packwerk running by executing:
50
+
51
+ bin/packwerk init
48
52
 
49
53
  Here is a list of files generated:
50
54
 
@@ -52,11 +56,17 @@ Here is a list of files generated:
52
56
  |-----------------------------|--------------|------------|
53
57
  | Packwerk configuration | packwerk.yml | See [Setting up the configuration file](#Setting-up-the-configuration-file) |
54
58
  | Root package | package.yml | A package for the root folder |
55
- | Custom inflections | config/inflections.yml | A custom inflections file is only required if you have custom inflections in `inflections.rb`, see [Inflections](#Inflections) |
56
59
 
57
60
  After that, you may begin creating packages for your application. See [Defining packages](#Defining-packages)
58
61
 
59
- ## Setting up the configuration file
62
+ ### Setting up Spring
63
+
64
+ [Spring](https://github.com/rails/spring) is a preloader for Rails. Because `packwerk` loads `Rails`, it can be sped up dramatically by enabling spring. Packwerk supports the usage of Spring.
65
+ Firstly, spring needs to know about the packwerk spring command when spring is loading. To do that, add `require 'packwerk/spring_command'` to `config/spring.rb` in your application.
66
+ Secondly, to enable Spring, first run `bin/spring binstub packwerk` which will "springify" the generated binstub.
67
+
68
+
69
+ ## Configuring Packwerk
60
70
 
61
71
  Packwerk reads from the `packwerk.yml` configuration file in the root directory. Packwerk will run with the default configuration if any of these settings are not specified.
62
72
 
@@ -65,9 +75,10 @@ Packwerk reads from the `packwerk.yml` configuration file in the root directory.
65
75
  | include | **/*.{rb,rake,erb} | list of patterns for folder paths to include |
66
76
  | exclude | {bin,node_modules,script,tmp,vendor}/**/* | list of patterns for folder paths to exclude |
67
77
  | package_paths | **/ | a single pattern or a list of patterns to find package configuration files, see: [Defining packages](#Defining-packages) |
68
- | load_paths | All application autoload paths | list of load paths |
69
78
  | custom_associations | N/A | list of custom associations, if any |
70
79
  | parallel | true | when true, fork code parsing out to subprocesses |
80
+ | cache | false | when true, caches the results of parsing files |
81
+ | cache_directory | tmp/cache/packwerk | the directory that will hold the packwerk cache |
71
82
 
72
83
  ### Using a custom ERB parser
73
84
 
@@ -91,50 +102,16 @@ end
91
102
  Packwerk::Parsers::Factory.instance.erb_parser_class = CustomParser
92
103
  ```
93
104
 
94
- ### Inflections
95
-
96
- 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.
97
-
98
- 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.
99
-
100
- In `inflections.rb`, add:
101
-
102
- ```rb
103
- require "packwerk/inflections/custom"
104
-
105
- ActiveSupport::Inflector.inflections do |inflect|
106
- # please add all custom inflections in the file below.
107
- Packwerk::Inflections::Custom.new(
108
- Rails.root.join("config", "inflections.yml")
109
- ).apply_to(inflect)
110
- end
111
- ```
112
-
113
- _Note: Packwerk has to be grouped in production environment within the Gemfile if you have custom inflections._
105
+ ## Using the cache
106
+ Packwerk ships with an cache to help speed up file parsing. You can turn this on by setting `cache: true` in `packwerk.yml`.
114
107
 
115
- Next, move your existing custom inflections into `config/inflections.yml`:
116
-
117
- ```yaml
118
- acronym:
119
- - 'GraphQL'
120
- - 'MRuby'
121
- - 'TOS'
122
- irregular:
123
- - ['analysis', 'analyses']
124
- - ['reserve', 'reserves']
125
- uncountable:
126
- - 'payment_details'
127
- singular:
128
- - [!ruby/regexp /status$/, 'status']
129
- ```
130
-
131
- Any new inflectors should be added to `config/inflections.yml`.
108
+ This will write to `tmp/cache/packwerk`.
132
109
 
133
110
  ## Validating the package system
134
111
 
135
112
  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.
136
113
 
137
- We recommend setting up the package system validation for your Rails application in a CI step (or through a test suite for Ruby projects) separate from `packwerk check`.
114
+ We recommend setting up the package system validation for your Rails application in a CI step (or through a test suite for Ruby projects) separate from `bin/packwerk check`.
138
115
 
139
116
  Use the following command to validate the application:
140
117
 
@@ -231,13 +208,17 @@ After enforcing the boundary checks for a package, you may execute:
231
208
 
232
209
  Packwerk will check the entire codebase for any new or stale violations.
233
210
 
234
- You can also specify folders or packages for a shorter run time:
211
+ You can also specify folders for a shorter run time. When checking against folders all subfolders will be analyzed, irrespective of nested package boundaries.
235
212
 
236
213
  packwerk check components/your_package
237
214
 
215
+ You can also specify packages for a shorter run time. When checking against packages any packages nested underneath the specified packages will not be checked. This can be helpful to test packages like the root package, which can have many nested packages.
216
+
217
+ packwerk check --packages=components/your_package,components/your_other_package
218
+
238
219
  ![](static/packwerk_check.gif)
239
220
 
240
- In order to keep the package system valid at each version of the application, we recommend running `packwerk check` in your CI pipeline.
221
+ In order to keep the package system valid at each version of the application, we recommend running `bin/packwerk check` in your CI pipeline.
241
222
 
242
223
  See: [TROUBLESHOOT.md - Sample violations](TROUBLESHOOT.md#Sample-violations)
243
224
 
@@ -247,17 +228,17 @@ For existing codebases, packages are likely to have existing boundary violations
247
228
 
248
229
  If so, you will want to stop the bleeding and prevent more violations from occuring. The existing violations in the codebase can be recorded in a [deprecated references list](#Understanding_the_list_of_deprecated_references) by executing:
249
230
 
250
- packwerk update-deprecations
231
+ bin/packwerk update-deprecations
251
232
 
252
- Similar to `packwerk check`, you may also run `packwerk update-deprecations` on folders or packages:
233
+ Similar to `bin/packwerk check`, you may also run `bin/packwerk update-deprecations` on folders or packages:
253
234
 
254
- packwerk update-deprecations components/your_package
235
+ bin/packwerk update-deprecations components/your_package
255
236
 
256
237
  ![](static/packwerk_update.gif)
257
238
 
258
239
  _Note: Changing dependencies or enabling dependencies will not require a full update of the codebase, only the package that changed. On the other hand, changing or enabling privacy will require a full update of the codebase._
259
240
 
260
- `packwerk update-deprecations` should only be run to record existing violations and to remove deprecated references that have been worked off. Running `packwerk update-deprecations` to resolve a violation should be the very last resort.
241
+ `bin/packwerk update-deprecations` should only be run to record existing violations and to remove deprecated references that have been worked off. Running `bin/packwerk update-deprecations` to resolve a violation should be the very last resort.
261
242
 
262
243
  See: [TROUBLESHOOT.md - Troubleshooting violations](TROUBLESHOOT.md#Troubleshooting_violations)
263
244
 
data/exe/packwerk CHANGED
@@ -3,4 +3,10 @@
3
3
 
4
4
  require "packwerk"
5
5
 
6
- Packwerk::Cli.new(style: Packwerk::OutputStyles::Coloured.new).run(ARGV.dup)
6
+ # Needs to be run in test environment in order to have test helper paths available in the autoload paths
7
+ ENV["RAILS_ENV"] = "test"
8
+
9
+ # Command line arguments needs to be duplicated because spring modifies it
10
+ packwerk_argv = ARGV.dup
11
+ cli = Packwerk::Cli.new(style: Packwerk::OutputStyles::Coloured.new)
12
+ cli.run(packwerk_argv)
@@ -4,6 +4,7 @@
4
4
  require "bundler"
5
5
 
6
6
  module Packwerk
7
+ # Extracts the load paths from the analyzed application so that we can map constant names to paths.
7
8
  module ApplicationLoadPaths
8
9
  class << self
9
10
  extend T::Sig
@@ -1,30 +1,27 @@
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"
8
7
 
9
8
  module Packwerk
9
+ # Checks the structure of the application and its packwerk configuration to make sure we can run a check and deliver
10
+ # correct results.
10
11
  class ApplicationValidator
11
12
  def initialize(config_file_path:, configuration:, environment:)
12
13
  @config_file_path = config_file_path
13
14
  @configuration = configuration
14
15
  @environment = environment
15
-
16
- @application_load_paths = ApplicationLoadPaths.extract_relevant_paths(configuration.root_path, environment)
17
16
  end
18
17
 
19
18
  Result = Struct.new(:ok?, :error_value)
20
19
 
21
20
  def check_all
22
21
  results = [
23
- check_autoload_path_cache,
24
22
  check_package_manifests_for_privacy,
25
23
  check_package_manifest_syntax,
26
24
  check_application_structure,
27
- check_inflection_file,
28
25
  check_acyclic_graph,
29
26
  check_package_manifest_paths,
30
27
  check_valid_package_dependencies,
@@ -34,21 +31,6 @@ module Packwerk
34
31
  merge_results(results)
35
32
  end
36
33
 
37
- def check_autoload_path_cache
38
- expected = @application_load_paths
39
- actual = @configuration.load_paths
40
- if expected.sort == actual.sort
41
- Result.new(true)
42
- else
43
- Result.new(
44
- false,
45
- "Load path cache in #{@config_file_path} incorrect!\n"\
46
- "Paths missing from file:\n#{format_yaml_strings(expected - actual)}\n"\
47
- "Extraneous load paths in file:\n#{format_yaml_strings(actual - expected)}"
48
- )
49
- end
50
- end
51
-
52
34
  def check_package_manifests_for_privacy
53
35
  privacy_settings = package_manifests_settings_for("enforce_privacy")
54
36
 
@@ -57,13 +39,13 @@ module Packwerk
57
39
  load_paths: @configuration.load_paths
58
40
  )
59
41
 
60
- results = []
42
+ results = T.let([], T::Array[Packwerk::Result])
61
43
 
62
44
  privacy_settings.each do |config_file_path, setting|
63
45
  next unless setting.is_a?(Array)
64
46
  constants = setting
65
47
 
66
- assert_constants_can_be_loaded(constants)
48
+ results += assert_constants_can_be_loaded(constants, config_file_path)
67
49
 
68
50
  constant_locations = constants.map { |c| [c, resolver.resolve(c)&.location] }
69
51
 
@@ -140,39 +122,6 @@ module Packwerk
140
122
  end
141
123
  end
142
124
 
143
- def check_inflection_file
144
- inflections_file = @configuration.inflections_file
145
-
146
- application_inflections = ActiveSupport::Inflector.inflections
147
- packwerk_inflections = Packwerk::Inflector.from_file(inflections_file).inflections
148
-
149
- results = %i(plurals singulars uncountables humans acronyms).map do |type|
150
- expected = application_inflections.public_send(type).to_set
151
- actual = packwerk_inflections.public_send(type).to_set
152
-
153
- if expected == actual
154
- Result.new(true)
155
- else
156
- missing_msg = unless (expected - actual).empty?
157
- "Expected #{type} to be specified in file: #{expected - actual}"
158
- end
159
- extraneous_msg = unless (actual - expected).empty?
160
- "Extraneous #{type} was specified in file: #{actual - expected}"
161
- end
162
- Result.new(
163
- false,
164
- [missing_msg, extraneous_msg].join("\n")
165
- )
166
- end
167
- end
168
-
169
- merge_results(
170
- results,
171
- separator: "\n",
172
- errors_headline: "Inflections specified in #{inflections_file} don't line up with application!\n"
173
- )
174
- end
175
-
176
125
  def check_acyclic_graph
177
126
  edges = package_set.flat_map do |package|
178
127
  package.dependencies.map { |dependency| [package, package_set.fetch(dependency)] }
@@ -296,7 +245,7 @@ module Packwerk
296
245
  end
297
246
 
298
247
  def package_manifests(glob_pattern = package_glob)
299
- PackageSet.package_paths(@configuration.root_path, glob_pattern)
248
+ PackageSet.package_paths(@configuration.root_path, glob_pattern, @configuration.exclude)
300
249
  .map { |f| File.realpath(f) }
301
250
  end
302
251
 
@@ -316,9 +265,18 @@ module Packwerk
316
265
  !File.file?(package_path)
317
266
  end
318
267
 
319
- def assert_constants_can_be_loaded(constants)
320
- constants.each(&:constantize)
321
- nil
268
+ def assert_constants_can_be_loaded(constants, config_file_path)
269
+ constants.map do |constant|
270
+ if !constant.start_with?("::")
271
+ Result.new(
272
+ false,
273
+ "'#{constant}', listed in the 'enforce_privacy' option in #{config_file_path}, is invalid.\n"\
274
+ "Private constants need to be prefixed with the top-level namespace operator `::`."
275
+ )
276
+ else
277
+ constant.try(&:constantize) && Result.new(true)
278
+ end
279
+ end
322
280
  end
323
281
 
324
282
  def private_constant_unresolvable(name, config_file_path)
@@ -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)