packwerk 2.1.1 → 2.2.1

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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +29 -20
  3. data/.github/workflows/cla.yml +22 -0
  4. data/.rubocop.yml +48 -19
  5. data/Gemfile +7 -2
  6. data/Gemfile.lock +204 -177
  7. data/README.md +7 -2
  8. data/RESOLVING_VIOLATIONS.md +81 -0
  9. data/Rakefile +1 -1
  10. data/USAGE.md +14 -5
  11. data/bin/m +1 -1
  12. data/bin/rake +1 -1
  13. data/bin/rubocop +1 -1
  14. data/bin/srb +1 -1
  15. data/bin/tapioca +1 -1
  16. data/gemfiles/Gemfile-rails-6-0 +1 -1
  17. data/gemfiles/Gemfile-rails-6-1 +22 -0
  18. data/lib/packwerk/application_load_paths.rb +12 -18
  19. data/lib/packwerk/application_validator.rb +7 -6
  20. data/lib/packwerk/association_inspector.rb +17 -15
  21. data/lib/packwerk/cache.rb +36 -29
  22. data/lib/packwerk/cli.rb +14 -8
  23. data/lib/packwerk/const_node_inspector.rb +8 -7
  24. data/lib/packwerk/constant_name_inspector.rb +2 -2
  25. data/lib/packwerk/deprecated_references.rb +34 -19
  26. data/lib/packwerk/file_processor.rb +25 -23
  27. data/lib/packwerk/files_for_processing.rb +33 -35
  28. data/lib/packwerk/formatters/offenses_formatter.rb +3 -3
  29. data/lib/packwerk/formatters/progress_formatter.rb +2 -2
  30. data/lib/packwerk/node.rb +1 -294
  31. data/lib/packwerk/node_helpers.rb +335 -0
  32. data/lib/packwerk/node_processor.rb +6 -5
  33. data/lib/packwerk/node_processor_factory.rb +3 -3
  34. data/lib/packwerk/node_visitor.rb +1 -1
  35. data/lib/packwerk/offense_collection.rb +6 -3
  36. data/lib/packwerk/offenses_formatter.rb +2 -2
  37. data/lib/packwerk/package.rb +3 -0
  38. data/lib/packwerk/package_set.rb +3 -1
  39. data/lib/packwerk/parse_run.rb +15 -13
  40. data/lib/packwerk/parsed_constant_definitions.rb +23 -20
  41. data/lib/packwerk/parsers/erb.rb +3 -3
  42. data/lib/packwerk/parsers/parser_interface.rb +2 -0
  43. data/lib/packwerk/reference_checking/checkers/checker.rb +16 -3
  44. data/lib/packwerk/reference_checking/checkers/dependency_checker.rb +16 -0
  45. data/lib/packwerk/reference_checking/checkers/privacy_checker.rb +18 -0
  46. data/lib/packwerk/reference_checking/reference_checker.rb +4 -4
  47. data/lib/packwerk/reference_extractor.rb +51 -54
  48. data/lib/packwerk/reference_offense.rb +3 -27
  49. data/lib/packwerk/run_context.rb +9 -7
  50. data/lib/packwerk/spring_command.rb +1 -1
  51. data/lib/packwerk/version.rb +1 -1
  52. data/lib/packwerk.rb +1 -0
  53. data/packwerk.gemspec +4 -11
  54. data/sorbet/rbi/gems/actioncable@7.0.3.1.rbi +2754 -0
  55. data/sorbet/rbi/gems/actionmailbox@7.0.3.1.rbi +1496 -0
  56. data/sorbet/rbi/gems/actionmailer@7.0.3.1.rbi +2362 -0
  57. data/sorbet/rbi/gems/actionpack@7.0.3.1.rbi +19397 -0
  58. data/sorbet/rbi/gems/actiontext@7.0.3.1.rbi +1569 -0
  59. data/sorbet/rbi/gems/actionview@7.0.3.1.rbi +14907 -0
  60. data/sorbet/rbi/gems/activejob@7.0.3.1.rbi +2553 -0
  61. data/sorbet/rbi/gems/activemodel@7.0.3.1.rbi +5999 -0
  62. data/sorbet/rbi/gems/activerecord@7.0.3.1.rbi +37832 -0
  63. data/sorbet/rbi/gems/activestorage@7.0.3.1.rbi +2321 -0
  64. data/sorbet/rbi/gems/activesupport@7.0.3.1.rbi +18818 -0
  65. data/sorbet/rbi/gems/concurrent-ruby@1.1.10.rbi +11722 -0
  66. data/sorbet/rbi/gems/constant_resolver@0.2.0.rbi +90 -0
  67. data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +1079 -0
  68. data/sorbet/rbi/gems/digest@3.1.0.rbi +189 -0
  69. data/sorbet/rbi/gems/erubi@1.11.0.rbi +140 -0
  70. data/sorbet/rbi/gems/globalid@1.0.0.rbi +572 -0
  71. data/sorbet/rbi/gems/i18n@1.12.0.rbi +2296 -0
  72. data/sorbet/rbi/gems/json@2.6.2.rbi +1548 -0
  73. data/sorbet/rbi/gems/language_server-protocol@3.16.0.3.rbi +8 -0
  74. data/sorbet/rbi/gems/loofah@2.18.0.rbi +877 -0
  75. data/sorbet/rbi/gems/m@1.6.0.rbi +257 -0
  76. data/sorbet/rbi/gems/marcel@1.0.2.rbi +220 -0
  77. data/sorbet/rbi/gems/mini_mime@1.1.2.rbi +170 -0
  78. data/sorbet/rbi/gems/mini_portile2@2.8.0.rbi +8 -0
  79. data/sorbet/rbi/gems/minitest-focus@1.3.1.rbi +104 -0
  80. data/sorbet/rbi/gems/minitest@5.16.2.rbi +2136 -0
  81. data/sorbet/rbi/gems/mocha@1.14.0.rbi +4177 -0
  82. data/sorbet/rbi/gems/net-imap@0.2.3.rbi +2147 -0
  83. data/sorbet/rbi/gems/net-pop@0.1.1.rbi +926 -0
  84. data/sorbet/rbi/gems/net-protocol@0.1.3.rbi +11 -0
  85. data/sorbet/rbi/gems/net-smtp@0.3.1.rbi +1108 -0
  86. data/sorbet/rbi/gems/netrc@0.11.0.rbi +153 -0
  87. data/sorbet/rbi/gems/nio4r@2.5.8.rbi +292 -0
  88. data/sorbet/rbi/gems/nokogiri@1.13.8.rbi +6478 -0
  89. data/sorbet/rbi/gems/parallel@1.22.1.rbi +277 -0
  90. data/sorbet/rbi/gems/parser@3.1.2.1.rbi +9029 -0
  91. data/sorbet/rbi/gems/prettier_print@0.1.0.rbi +8 -0
  92. data/sorbet/rbi/gems/pry@0.14.1.rbi +8 -0
  93. data/sorbet/rbi/gems/racc@1.6.0.rbi +152 -0
  94. data/sorbet/rbi/gems/rack-test@2.0.2.rbi +953 -0
  95. data/sorbet/rbi/gems/rack@2.2.4.rbi +5636 -0
  96. data/sorbet/rbi/gems/rails-html-sanitizer@1.4.3.rbi +688 -0
  97. data/sorbet/rbi/gems/rails@7.0.3.1.rbi +8 -0
  98. data/sorbet/rbi/gems/railties@7.0.3.1.rbi +3507 -0
  99. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +392 -0
  100. data/sorbet/rbi/gems/rake@13.0.6.rbi +2924 -0
  101. data/sorbet/rbi/gems/rbi@0.0.15.rbi +3007 -0
  102. data/sorbet/rbi/gems/regexp_parser@2.5.0.rbi +3383 -0
  103. data/sorbet/rbi/gems/rexml@3.2.5.rbi +4714 -0
  104. data/sorbet/rbi/gems/rubocop-ast@1.21.0.rbi +6961 -0
  105. data/sorbet/rbi/gems/rubocop-performance@1.14.3.rbi +2986 -0
  106. data/sorbet/rbi/gems/{rubocop-shopify@2.0.1.rbi → rubocop-shopify@2.9.0.rbi} +4 -4
  107. data/sorbet/rbi/gems/rubocop-sorbet@0.6.11.rbi +992 -0
  108. data/sorbet/rbi/gems/rubocop@1.34.1.rbi +51820 -0
  109. data/sorbet/rbi/gems/ruby-lsp@0.2.1.rbi +11 -0
  110. data/sorbet/rbi/gems/smart_properties@1.17.0.rbi +474 -0
  111. data/sorbet/rbi/gems/spoom@1.1.11.rbi +2181 -0
  112. data/sorbet/rbi/gems/spring@4.0.0.rbi +411 -0
  113. data/sorbet/rbi/gems/strscan@3.0.4.rbi +8 -0
  114. data/sorbet/rbi/gems/syntax_tree@3.3.0.rbi +8 -0
  115. data/sorbet/rbi/gems/tapioca@0.9.2.rbi +3181 -0
  116. data/sorbet/rbi/gems/thor@1.2.1.rbi +3956 -0
  117. data/sorbet/rbi/gems/timeout@0.3.0.rbi +142 -0
  118. data/sorbet/rbi/gems/tzinfo@2.0.5.rbi +5896 -0
  119. data/sorbet/rbi/gems/unicode-display_width@2.2.0.rbi +48 -0
  120. data/sorbet/rbi/gems/unparser@0.6.5.rbi +4529 -0
  121. data/sorbet/rbi/gems/webrick@1.7.0.rbi +2582 -0
  122. data/sorbet/rbi/gems/websocket-driver@0.7.5.rbi +993 -0
  123. data/sorbet/rbi/gems/yard-sorbet@0.6.1.rbi +388 -0
  124. data/sorbet/rbi/gems/yard@0.9.28.rbi +18242 -0
  125. data/sorbet/rbi/gems/zeitwerk@2.6.0.rbi +867 -0
  126. data/sorbet/rbi/shims/psych.rbi +5 -0
  127. data/sorbet/tapioca/require.rb +2 -3
  128. metadata +88 -143
  129. data/.github/probots.yml +0 -2
  130. data/library.yml +0 -6
  131. data/service.yml +0 -1
  132. data/sorbet/rbi/gems/actioncable@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -860
  133. data/sorbet/rbi/gems/actionmailbox@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -568
  134. data/sorbet/rbi/gems/actionmailer@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -587
  135. data/sorbet/rbi/gems/actionpack@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -5314
  136. data/sorbet/rbi/gems/actiontext@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -699
  137. data/sorbet/rbi/gems/actionview@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -2515
  138. data/sorbet/rbi/gems/activejob@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -624
  139. data/sorbet/rbi/gems/activemodel@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -1248
  140. data/sorbet/rbi/gems/activerecord@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -8363
  141. data/sorbet/rbi/gems/activestorage@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -876
  142. data/sorbet/rbi/gems/activesupport@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -3987
  143. data/sorbet/rbi/gems/colorize@0.8.1.rbi +0 -40
  144. data/sorbet/rbi/gems/commander@4.5.2.rbi +0 -8
  145. data/sorbet/rbi/gems/concurrent-ruby@1.1.8.rbi +0 -1969
  146. data/sorbet/rbi/gems/constant_resolver@0.1.5.rbi +0 -26
  147. data/sorbet/rbi/gems/erubi@1.10.0.rbi +0 -41
  148. data/sorbet/rbi/gems/globalid@0.4.2.rbi +0 -178
  149. data/sorbet/rbi/gems/highline@2.0.3.rbi +0 -8
  150. data/sorbet/rbi/gems/i18n@1.8.10.rbi +0 -600
  151. data/sorbet/rbi/gems/loofah@2.9.0.rbi +0 -274
  152. data/sorbet/rbi/gems/m@1.5.1.rbi +0 -108
  153. data/sorbet/rbi/gems/marcel@1.0.0.rbi +0 -70
  154. data/sorbet/rbi/gems/mini_mime@1.0.3.rbi +0 -71
  155. data/sorbet/rbi/gems/minitest-focus@1.2.1.rbi +0 -8
  156. data/sorbet/rbi/gems/minitest@5.14.4.rbi +0 -544
  157. data/sorbet/rbi/gems/mocha@1.12.0.rbi +0 -953
  158. data/sorbet/rbi/gems/nio4r@2.5.7.rbi +0 -90
  159. data/sorbet/rbi/gems/nokogiri@1.11.2.rbi +0 -1647
  160. data/sorbet/rbi/gems/parallel@1.20.1.rbi +0 -117
  161. data/sorbet/rbi/gems/parlour@6.0.0.rbi +0 -1272
  162. data/sorbet/rbi/gems/parser@3.0.0.0.rbi +0 -1745
  163. data/sorbet/rbi/gems/pry@0.14.0.rbi +0 -8
  164. data/sorbet/rbi/gems/psych@3.3.2.rbi +0 -24
  165. data/sorbet/rbi/gems/racc@1.5.2.rbi +0 -57
  166. data/sorbet/rbi/gems/rack-test@1.1.0.rbi +0 -335
  167. data/sorbet/rbi/gems/rack@2.2.3.rbi +0 -1718
  168. data/sorbet/rbi/gems/rails-html-sanitizer@1.3.0.rbi +0 -213
  169. data/sorbet/rbi/gems/rails@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -8
  170. data/sorbet/rbi/gems/railties@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi +0 -880
  171. data/sorbet/rbi/gems/rainbow@3.0.0.rbi +0 -155
  172. data/sorbet/rbi/gems/rake@13.0.3.rbi +0 -837
  173. data/sorbet/rbi/gems/regexp_parser@2.1.1.rbi +0 -8
  174. data/sorbet/rbi/gems/rexml@3.2.4.rbi +0 -8
  175. data/sorbet/rbi/gems/rubocop-ast@1.4.1.rbi +0 -8
  176. data/sorbet/rbi/gems/rubocop-performance@1.10.2.rbi +0 -8
  177. data/sorbet/rbi/gems/rubocop-sorbet@0.6.1.rbi +0 -8
  178. data/sorbet/rbi/gems/rubocop@1.12.0.rbi +0 -8
  179. data/sorbet/rbi/gems/smart_properties@1.15.0.rbi +0 -168
  180. data/sorbet/rbi/gems/spoom@1.1.0.rbi +0 -1061
  181. data/sorbet/rbi/gems/spring@2.1.1.rbi +0 -160
  182. data/sorbet/rbi/gems/sprockets-rails@3.2.2.rbi +0 -451
  183. data/sorbet/rbi/gems/sprockets@4.0.2.rbi +0 -1133
  184. data/sorbet/rbi/gems/tapioca@0.4.19.rbi +0 -603
  185. data/sorbet/rbi/gems/thor@1.1.0.rbi +0 -893
  186. data/sorbet/rbi/gems/tzinfo@2.0.4.rbi +0 -566
  187. data/sorbet/rbi/gems/unicode-display_width@2.0.0.rbi +0 -8
  188. data/sorbet/rbi/gems/websocket-driver@0.7.3.rbi +0 -438
  189. data/sorbet/rbi/gems/zeitwerk@2.4.2.rbi +0 -177
@@ -23,8 +23,24 @@ module Packwerk
23
23
  return false unless reference.source_package
24
24
  return false unless reference.source_package.enforce_dependencies?
25
25
  return false if reference.source_package.dependency?(reference.constant.package)
26
+
26
27
  true
27
28
  end
29
+
30
+ sig do
31
+ override
32
+ .params(reference: Packwerk::Reference)
33
+ .returns(String)
34
+ end
35
+ def message(reference)
36
+ <<~EOS
37
+ Dependency violation: #{reference.constant.name} belongs to '#{reference.constant.package}', but '#{reference.source_package}' does not specify a dependency on '#{reference.constant.package}'.
38
+ Are we missing an abstraction?
39
+ Is the code making the reference, and the referenced constant, in the right packages?
40
+
41
+ #{standard_help_message(reference)}
42
+ EOS
43
+ end
28
44
  end
29
45
  end
30
46
  end
@@ -31,6 +31,24 @@ module Packwerk
31
31
  true
32
32
  end
33
33
 
34
+ sig do
35
+ override
36
+ .params(reference: Packwerk::Reference)
37
+ .returns(String)
38
+ end
39
+ def message(reference)
40
+ source_desc = "'#{reference.source_package}'"
41
+
42
+ message = <<~EOS
43
+ Privacy violation: '#{reference.constant.name}' is private to '#{reference.constant.package}' but referenced from #{source_desc}.
44
+ Is there a public entrypoint in '#{reference.constant.package.public_path}' that you can use instead?
45
+
46
+ #{standard_help_message(reference)}
47
+ EOS
48
+
49
+ message.chomp
50
+ end
51
+
34
52
  private
35
53
 
36
54
  sig do
@@ -13,18 +13,18 @@ module Packwerk
13
13
 
14
14
  sig do
15
15
  params(
16
- reference: T.any(Packwerk::Reference, Packwerk::Offense)
16
+ reference: Reference
17
17
  ).returns(T::Array[Packwerk::Offense])
18
18
  end
19
19
  def call(reference)
20
- return [reference] if reference.is_a?(Packwerk::Offense)
21
-
22
20
  @checkers.each_with_object([]) do |checker, violations|
23
21
  next unless checker.invalid_reference?(reference)
22
+
24
23
  offense = Packwerk::ReferenceOffense.new(
25
24
  location: reference.source_location,
26
25
  reference: reference,
27
- violation_type: checker.violation_type
26
+ violation_type: checker.violation_type,
27
+ message: checker.message(reference)
28
28
  )
29
29
  violations << offense
30
30
  end
@@ -6,6 +6,49 @@ module Packwerk
6
6
  class ReferenceExtractor
7
7
  extend T::Sig
8
8
 
9
+ class << self
10
+ extend T::Sig
11
+
12
+ sig do
13
+ params(
14
+ unresolved_references: T::Array[UnresolvedReference],
15
+ context_provider: ConstantDiscovery
16
+ ).returns(T::Array[Reference])
17
+ end
18
+ def get_fully_qualified_references_from(unresolved_references, context_provider)
19
+ fully_qualified_references = T.let([], T::Array[Reference])
20
+
21
+ unresolved_references.each do |unresolved_references_or_offense|
22
+ unresolved_reference = unresolved_references_or_offense
23
+
24
+ constant =
25
+ context_provider.context_for(
26
+ unresolved_reference.constant_name,
27
+ current_namespace_path: unresolved_reference.namespace_path
28
+ )
29
+
30
+ next if constant.nil?
31
+
32
+ package_for_constant = constant.package
33
+
34
+ next if package_for_constant.nil?
35
+
36
+ source_package = context_provider.package_from_path(unresolved_reference.relative_path)
37
+
38
+ next if source_package == package_for_constant
39
+
40
+ fully_qualified_references << Reference.new(
41
+ source_package,
42
+ unresolved_reference.relative_path,
43
+ constant,
44
+ unresolved_reference.source_location
45
+ )
46
+ end
47
+
48
+ fully_qualified_references
49
+ end
50
+ end
51
+
9
52
  sig do
10
53
  params(
11
54
  constant_name_inspectors: T::Array[Packwerk::ConstantNameInspector],
@@ -27,10 +70,10 @@ module Packwerk
27
70
  params(
28
71
  node: Parser::AST::Node,
29
72
  ancestors: T::Array[Parser::AST::Node],
30
- absolute_file: String
73
+ relative_file: String
31
74
  ).returns(T.nilable(UnresolvedReference))
32
75
  end
33
- def reference_from_node(node, ancestors:, absolute_file:)
76
+ def reference_from_node(node, ancestors:, relative_file:)
34
77
  constant_name = T.let(nil, T.nilable(String))
35
78
 
36
79
  @constant_name_inspectors.each do |inspector|
@@ -44,56 +87,11 @@ module Packwerk
44
87
  constant_name,
45
88
  node: node,
46
89
  ancestors: ancestors,
47
- absolute_file: absolute_file
90
+ relative_file: relative_file
48
91
  )
49
92
  end
50
93
  end
51
94
 
52
- sig do
53
- params(
54
- unresolved_references_and_offenses: T::Array[T.any(UnresolvedReference, Offense)],
55
- context_provider: ConstantDiscovery
56
- ).returns(T::Array[T.any(Reference, Offense)])
57
- end
58
- def self.get_fully_qualified_references_and_offenses_from(unresolved_references_and_offenses, context_provider)
59
- fully_qualified_references_and_offenses = T.let([], T::Array[T.any(Reference, Offense)])
60
-
61
- unresolved_references_and_offenses.each do |unresolved_references_or_offense|
62
- if unresolved_references_or_offense.is_a?(Offense)
63
- fully_qualified_references_and_offenses << unresolved_references_or_offense
64
-
65
- next
66
- end
67
-
68
- unresolved_reference = unresolved_references_or_offense
69
-
70
- constant =
71
- context_provider.context_for(
72
- unresolved_reference.constant_name,
73
- current_namespace_path: unresolved_reference.namespace_path
74
- )
75
-
76
- next if constant.nil?
77
-
78
- package_for_constant = constant.package
79
-
80
- next if package_for_constant.nil?
81
-
82
- source_package = context_provider.package_from_path(unresolved_reference.relative_path)
83
-
84
- next if source_package == package_for_constant
85
-
86
- fully_qualified_references_and_offenses << Reference.new(
87
- source_package,
88
- unresolved_reference.relative_path,
89
- constant,
90
- unresolved_reference.source_location
91
- )
92
- end
93
-
94
- fully_qualified_references_and_offenses
95
- end
96
-
97
95
  private
98
96
 
99
97
  sig do
@@ -101,16 +99,15 @@ module Packwerk
101
99
  constant_name: String,
102
100
  node: Parser::AST::Node,
103
101
  ancestors: T::Array[Parser::AST::Node],
104
- absolute_file: String
102
+ relative_file: String
105
103
  ).returns(T.nilable(UnresolvedReference))
106
104
  end
107
- def reference_from_constant(constant_name, node:, ancestors:, absolute_file:)
108
- namespace_path = Node.enclosing_namespace_path(node, ancestors: ancestors)
105
+ def reference_from_constant(constant_name, node:, ancestors:, relative_file:)
106
+ namespace_path = NodeHelpers.enclosing_namespace_path(node, ancestors: ancestors)
109
107
 
110
- return if local_reference?(constant_name, Node.name_location(node), namespace_path)
108
+ return if local_reference?(constant_name, NodeHelpers.name_location(node), namespace_path)
111
109
 
112
- relative_file = Pathname.new(absolute_file).relative_path_from(@root_path).to_s
113
- location = Node.location(node)
110
+ location = NodeHelpers.location(node)
114
111
 
115
112
  UnresolvedReference.new(
116
113
  constant_name,
@@ -17,39 +17,15 @@ module Packwerk
17
17
  params(
18
18
  reference: Packwerk::Reference,
19
19
  violation_type: Packwerk::ViolationType,
20
+ message: String,
20
21
  location: T.nilable(Node::Location)
21
22
  )
22
23
  .void
23
24
  end
24
- def initialize(reference:, violation_type:, location: nil)
25
- super(file: reference.relative_path, message: build_message(reference, violation_type), location: location)
25
+ def initialize(reference:, violation_type:, message:, location: nil)
26
+ super(file: reference.relative_path, message: message, location: location)
26
27
  @reference = reference
27
28
  @violation_type = violation_type
28
29
  end
29
-
30
- private
31
-
32
- sig { params(reference: Reference, violation_type: ViolationType).returns(String) }
33
- def build_message(reference, violation_type)
34
- violation_message = case violation_type
35
- when ViolationType::Privacy
36
- source_desc = "'#{reference.source_package}'"
37
- "Privacy violation: '#{reference.constant.name}' is private to '#{reference.constant.package}' but " \
38
- "referenced from #{source_desc}.\n" \
39
- "Is there a public entrypoint in '#{reference.constant.package.public_path}' that you can use instead?"
40
- when ViolationType::Dependency
41
- "Dependency violation: #{reference.constant.name} belongs to '#{reference.constant.package}', but " \
42
- "'#{reference.source_package}' does not specify a dependency on " \
43
- "'#{reference.constant.package}'.\n" \
44
- "Are we missing an abstraction?\n" \
45
- "Is the code making the reference, and the referenced constant, in the right packages?\n"
46
- end
47
-
48
- <<~EOS
49
- #{violation_message}
50
- Inference details: this is a reference to #{reference.constant.name} which seems to be defined in #{reference.constant.location}.
51
- To receive help interpreting or resolving this error message, see: https://github.com/Shopify/packwerk/blob/main/TROUBLESHOOT.md#Troubleshooting-violations
52
- EOS
53
- end
54
30
  end
55
31
  end
@@ -38,7 +38,7 @@ module Packwerk
38
38
  sig do
39
39
  params(
40
40
  root_path: String,
41
- load_paths: T::Array[String],
41
+ load_paths: T::Hash[String, Module],
42
42
  inflector: T.class_of(ActiveSupport::Inflector),
43
43
  cache_directory: Pathname,
44
44
  config_path: T.nilable(String),
@@ -77,15 +77,17 @@ module Packwerk
77
77
  )
78
78
  end
79
79
 
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,
80
+ sig { params(relative_file: String).returns(T::Array[Packwerk::Offense]) }
81
+ def process_file(relative_file:)
82
+ processed_file = file_processor.call(relative_file)
83
+
84
+ references = ReferenceExtractor.get_fully_qualified_references_from(
85
+ processed_file.unresolved_references,
85
86
  context_provider
86
87
  )
87
88
  reference_checker = ReferenceChecking::ReferenceChecker.new(@checkers)
88
- references_and_offenses.flat_map { |reference| reference_checker.call(reference) }
89
+
90
+ processed_file.offenses + references.flat_map { |reference| reference_checker.call(reference) }
89
91
  end
90
92
 
91
93
  private
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
2
1
  # typed: true
2
+ # frozen_string_literal: true
3
3
 
4
4
  require "spring/commands"
5
5
 
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
5
- VERSION = "2.1.1"
5
+ VERSION = "2.2.1"
6
6
  end
data/lib/packwerk.rb CHANGED
@@ -26,6 +26,7 @@ module Packwerk
26
26
  autoload :FilesForProcessing
27
27
  autoload :Graph
28
28
  autoload :Node
29
+ autoload :NodeHelpers
29
30
  autoload :NodeProcessor
30
31
  autoload :NodeProcessorFactory
31
32
  autoload :NodeVisitor
data/packwerk.gemspec CHANGED
@@ -36,22 +36,15 @@ Gem::Specification.new do |spec|
36
36
  spec.files = Dir.chdir(__dir__) do
37
37
  %x(git ls-files -z).split("\x0").reject { |f| f.match(%r{^(test|spec|features|static)/}) }
38
38
  end
39
- spec.require_paths = %w(lib)
39
+ spec.require_paths = ["lib"]
40
40
 
41
41
  spec.required_ruby_version = ">= 2.6"
42
42
 
43
43
  spec.add_dependency("activesupport", ">= 5.2")
44
- spec.add_dependency("constant_resolver")
45
- spec.add_dependency("parallel")
46
- spec.add_dependency("sorbet-runtime")
47
44
  spec.add_dependency("bundler")
48
- spec.add_dependency("digest")
49
-
50
- spec.add_development_dependency("rake")
51
- spec.add_development_dependency("sorbet")
52
- spec.add_development_dependency("m")
53
- # https://github.com/ruby/psych/pull/487
54
- spec.add_development_dependency("psych", "~> 3")
45
+ spec.add_dependency("constant_resolver", ">= 0.2.0")
46
+ spec.add_dependency("parallel")
47
+ spec.add_dependency("sorbet-runtime", ">= 0.5.9914")
55
48
 
56
49
  # For Ruby parsing
57
50
  spec.add_dependency("ast")