packwerk 1.1.2 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +17 -8
  3. data/.ruby-version +1 -1
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +129 -111
  6. data/README.md +9 -2
  7. data/TROUBLESHOOT.md +2 -2
  8. data/USAGE.md +30 -30
  9. data/bin/m +29 -0
  10. data/bin/rake +29 -0
  11. data/bin/rubocop +29 -0
  12. data/bin/srb +29 -0
  13. data/bin/tapioca +29 -0
  14. data/dev.yml +7 -7
  15. data/gemfiles/Gemfile-rails-6-0 +22 -0
  16. data/lib/packwerk.rb +72 -36
  17. data/lib/packwerk/application_load_paths.rb +18 -8
  18. data/lib/packwerk/application_validator.rb +26 -27
  19. data/lib/packwerk/association_inspector.rb +0 -3
  20. data/lib/packwerk/checker.rb +2 -8
  21. data/lib/packwerk/cli.rb +29 -109
  22. data/lib/packwerk/configuration.rb +5 -0
  23. data/lib/packwerk/const_node_inspector.rb +0 -2
  24. data/lib/packwerk/constant_discovery.rb +2 -0
  25. data/lib/packwerk/constant_name_inspector.rb +0 -1
  26. data/lib/packwerk/dependency_checker.rb +2 -15
  27. data/lib/packwerk/deprecated_references.rb +5 -11
  28. data/lib/packwerk/file_processor.rb +0 -4
  29. data/lib/packwerk/formatters/offenses_formatter.rb +13 -9
  30. data/lib/packwerk/formatters/progress_formatter.rb +5 -4
  31. data/lib/packwerk/generators/configuration_file.rb +0 -1
  32. data/lib/packwerk/inflector.rb +0 -2
  33. data/lib/packwerk/node.rb +1 -0
  34. data/lib/packwerk/node_processor.rb +15 -32
  35. data/lib/packwerk/node_processor_factory.rb +0 -5
  36. data/lib/packwerk/node_visitor.rb +1 -4
  37. data/lib/packwerk/offense.rb +0 -4
  38. data/lib/packwerk/offense_collection.rb +84 -0
  39. data/lib/packwerk/offenses_formatter.rb +19 -0
  40. data/lib/packwerk/package.rb +17 -1
  41. data/lib/packwerk/package_set.rb +0 -2
  42. data/lib/packwerk/parse_run.rb +106 -0
  43. data/lib/packwerk/parsed_constant_definitions.rb +0 -2
  44. data/lib/packwerk/parsers.rb +0 -2
  45. data/lib/packwerk/parsers/erb.rb +0 -2
  46. data/lib/packwerk/parsers/factory.rb +0 -2
  47. data/lib/packwerk/privacy_checker.rb +2 -15
  48. data/lib/packwerk/reference_extractor.rb +0 -8
  49. data/lib/packwerk/reference_offense.rb +49 -0
  50. data/lib/packwerk/result.rb +9 -0
  51. data/lib/packwerk/run_context.rb +4 -21
  52. data/lib/packwerk/sanity_checker.rb +0 -2
  53. data/lib/packwerk/version.rb +1 -1
  54. data/lib/packwerk/violation_type.rb +0 -2
  55. data/library.yml +1 -1
  56. data/packwerk.gemspec +1 -0
  57. data/service.yml +1 -4
  58. data/shipit.rubygems.yml +5 -1
  59. data/sorbet/rbi/gems/{actioncable@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actioncable@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +56 -36
  60. data/sorbet/rbi/gems/{actionmailbox@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actionmailbox@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +25 -28
  61. data/sorbet/rbi/gems/{actionmailer@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actionmailer@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +43 -24
  62. data/sorbet/rbi/gems/{actionpack@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actionpack@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +382 -284
  63. data/sorbet/rbi/gems/{actiontext@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actiontext@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +76 -40
  64. data/sorbet/rbi/gems/{actionview@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actionview@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +206 -195
  65. data/sorbet/rbi/gems/{activejob@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activejob@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +64 -75
  66. data/sorbet/rbi/gems/{activemodel@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activemodel@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +103 -56
  67. data/sorbet/rbi/gems/{activerecord@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activerecord@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +1250 -898
  68. data/sorbet/rbi/gems/{activestorage@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activestorage@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +92 -120
  69. data/sorbet/rbi/gems/{activesupport@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activesupport@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +292 -193
  70. data/sorbet/rbi/gems/{ast@2.4.1.rbi → ast@2.4.2.rbi} +2 -1
  71. data/sorbet/rbi/gems/{better_html@1.0.15.rbi → better_html@1.0.16.rbi} +2 -2
  72. data/sorbet/rbi/gems/{concurrent-ruby@1.1.6.rbi → concurrent-ruby@1.1.8.rbi} +12 -9
  73. data/sorbet/rbi/gems/{erubi@1.9.0.rbi → erubi@1.10.0.rbi} +3 -1
  74. data/sorbet/rbi/gems/{i18n@1.8.2.rbi → i18n@1.8.10.rbi} +19 -52
  75. data/sorbet/rbi/gems/{loofah@2.5.0.rbi → loofah@2.9.0.rbi} +3 -1
  76. data/sorbet/rbi/gems/marcel@1.0.0.rbi +70 -0
  77. data/sorbet/rbi/gems/{mini_mime@1.0.2.rbi → mini_mime@1.0.3.rbi} +6 -6
  78. data/sorbet/rbi/gems/{mini_portile2@2.4.0.rbi → minitest-focus@1.2.1.rbi} +2 -2
  79. data/sorbet/rbi/gems/{minitest@5.14.0.rbi → minitest@5.14.4.rbi} +31 -29
  80. data/sorbet/rbi/gems/{mocha@1.11.2.rbi → mocha@1.12.0.rbi} +25 -36
  81. data/sorbet/rbi/gems/{nio4r@2.5.2.rbi → nio4r@2.5.7.rbi} +21 -20
  82. data/sorbet/rbi/gems/{nokogiri@1.10.9.rbi → nokogiri@1.11.2.rbi} +193 -154
  83. data/sorbet/rbi/gems/parallel@1.20.1.rbi +117 -0
  84. data/sorbet/rbi/gems/parlour@6.0.0.rbi +1272 -0
  85. data/sorbet/rbi/gems/{parser@2.7.1.4.rbi → parser@3.0.0.0.rbi} +287 -174
  86. data/sorbet/rbi/gems/{pry@0.13.1.rbi → pry@0.14.0.rbi} +1 -1
  87. data/sorbet/rbi/gems/racc@1.5.2.rbi +57 -0
  88. data/sorbet/rbi/gems/{rack@2.2.2.rbi → rack@2.2.3.rbi} +23 -35
  89. data/sorbet/rbi/gems/{rails@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → rails@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +1 -1
  90. data/sorbet/rbi/gems/{railties@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → railties@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +132 -121
  91. data/sorbet/rbi/gems/{rake@13.0.1.rbi → rake@13.0.3.rbi} +16 -20
  92. data/sorbet/rbi/gems/{parallel@1.19.1.rbi → regexp_parser@2.1.1.rbi} +2 -2
  93. data/sorbet/rbi/gems/rubocop-ast@1.4.1.rbi +8 -0
  94. data/sorbet/rbi/gems/{rubocop-performance@1.5.2.rbi → rubocop-performance@1.10.2.rbi} +1 -1
  95. data/sorbet/rbi/gems/{rubocop-shopify@1.0.2.rbi → rubocop-shopify@2.0.1.rbi} +1 -1
  96. data/sorbet/rbi/gems/{rubocop-sorbet@0.3.7.rbi → rubocop-sorbet@0.6.1.rbi} +1 -1
  97. data/sorbet/rbi/gems/{rubocop@0.82.0.rbi → rubocop@1.12.0.rbi} +1 -1
  98. data/sorbet/rbi/gems/{ruby-progressbar@1.10.1.rbi → ruby-progressbar@1.11.0.rbi} +1 -1
  99. data/sorbet/rbi/gems/spoom@1.1.0.rbi +1061 -0
  100. data/sorbet/rbi/gems/{spring@2.1.0.rbi → spring@2.1.1.rbi} +7 -7
  101. data/sorbet/rbi/gems/{sprockets-rails@3.2.1.rbi → sprockets-rails@3.2.2.rbi} +88 -68
  102. data/sorbet/rbi/gems/{sprockets@4.0.0.rbi → sprockets@4.0.2.rbi} +8 -7
  103. data/sorbet/rbi/gems/{tapioca@0.4.5.rbi → tapioca@0.4.19.rbi} +109 -24
  104. data/sorbet/rbi/gems/{thor@1.0.1.rbi → thor@1.1.0.rbi} +16 -15
  105. data/sorbet/rbi/gems/{tzinfo@2.0.2.rbi → tzinfo@2.0.4.rbi} +21 -2
  106. data/sorbet/rbi/gems/{unicode-display_width@1.7.0.rbi → unicode-display_width@2.0.0.rbi} +1 -1
  107. data/sorbet/rbi/gems/{websocket-driver@0.7.1.rbi → websocket-driver@0.7.3.rbi} +29 -29
  108. data/sorbet/rbi/gems/{websocket-extensions@0.1.4.rbi → websocket-extensions@0.1.5.rbi} +2 -2
  109. data/sorbet/rbi/gems/zeitwerk@2.4.2.rbi +177 -0
  110. data/sorbet/tapioca/require.rb +1 -0
  111. metadata +79 -66
  112. data/lib/packwerk/cache_deprecated_references.rb +0 -55
  113. data/lib/packwerk/checking_deprecated_references.rb +0 -43
  114. data/lib/packwerk/commands/detect_stale_violations_command.rb +0 -60
  115. data/lib/packwerk/commands/offense_progress_marker.rb +0 -24
  116. data/lib/packwerk/commands/result.rb +0 -13
  117. data/lib/packwerk/commands/update_deprecations_command.rb +0 -81
  118. data/lib/packwerk/detect_stale_deprecated_references.rb +0 -14
  119. data/lib/packwerk/generators/application_validation.rb +0 -62
  120. data/lib/packwerk/generators/templates/packwerk +0 -23
  121. data/lib/packwerk/generators/templates/packwerk_validator_test.rb +0 -11
  122. data/lib/packwerk/reference_lister.rb +0 -23
  123. data/lib/packwerk/spring_command.rb +0 -28
  124. data/lib/packwerk/updating_deprecated_references.rb +0 -14
  125. data/sorbet/rbi/gems/jaro_winkler@1.5.4.rbi +0 -8
  126. data/sorbet/rbi/gems/marcel@0.3.3.rbi +0 -30
  127. data/sorbet/rbi/gems/mimemagic@0.3.5.rbi +0 -47
  128. data/sorbet/rbi/gems/parlour@4.0.1.rbi +0 -561
  129. data/sorbet/rbi/gems/spoom@1.0.4.rbi +0 -418
  130. data/sorbet/rbi/gems/zeitwerk@2.3.0.rbi +0 -8
@@ -1,17 +1,11 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- require "sorbet-runtime"
5
4
  require "yaml"
6
5
 
7
- require "packwerk/reference"
8
- require "packwerk/reference_lister"
9
- require "packwerk/violation_type"
10
-
11
6
  module Packwerk
12
7
  class DeprecatedReferences
13
8
  extend T::Sig
14
- include ReferenceLister
15
9
 
16
10
  sig { params(package: Packwerk::Package, filepath: String).void }
17
11
  def initialize(package, filepath)
@@ -23,7 +17,6 @@ module Packwerk
23
17
  sig do
24
18
  params(reference: Packwerk::Reference, violation_type: ViolationType)
25
19
  .returns(T::Boolean)
26
- .override
27
20
  end
28
21
  def listed?(reference, violation_type:)
29
22
  violated_constants_found = deprecated_references.dig(reference.constant.package.name, reference.constant.name)
@@ -35,18 +28,19 @@ module Packwerk
35
28
  violated_constants_found.fetch("violations", []).include?(violation_type.serialize)
36
29
  end
37
30
 
38
- sig { params(reference: Packwerk::Reference, violation_type: String).void }
31
+ sig { params(reference: Packwerk::Reference, violation_type: Packwerk::ViolationType).returns(T::Boolean) }
39
32
  def add_entries(reference, violation_type)
40
33
  package_violations = @new_entries.fetch(reference.constant.package.name, {})
41
34
  entries_for_file = package_violations[reference.constant.name] ||= {}
42
35
 
43
36
  entries_for_file["violations"] ||= []
44
- entries_for_file["violations"] << violation_type
37
+ entries_for_file["violations"] << violation_type.serialize
45
38
 
46
39
  entries_for_file["files"] ||= []
47
40
  entries_for_file["files"] << reference.relative_path.to_s
48
41
 
49
42
  @new_entries[reference.constant.package.name] = package_violations
43
+ listed?(reference, violation_type: violation_type)
50
44
  end
51
45
 
52
46
  sig { returns(T::Boolean) }
@@ -59,7 +53,7 @@ module Packwerk
59
53
  if entries_for_file["violations"].all? { |type| new_entries_violation_types.include?(type) }
60
54
  stale_violations =
61
55
  entries_for_file["files"] - Array(@new_entries.dig(package, constant_name, "files"))
62
- stale_violations.present?
56
+ stale_violations.any?
63
57
  else
64
58
  return true
65
59
  end
@@ -79,7 +73,7 @@ module Packwerk
79
73
  #
80
74
  # You can regenerate this file using the following command:
81
75
  #
82
- # bundle exec packwerk update-deprecations #{@package.name}
76
+ # packwerk update-deprecations #{@package.name}
83
77
  MESSAGE
84
78
  File.open(@filepath, "w") do |f|
85
79
  f.write(message)
@@ -3,10 +3,6 @@
3
3
 
4
4
  require "ast/node"
5
5
 
6
- require "packwerk/node"
7
- require "packwerk/offense"
8
- require "packwerk/parsers"
9
-
10
6
  module Packwerk
11
7
  class FileProcessor
12
8
  class UnknownFileTypeResult < Offense
@@ -1,16 +1,11 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "benchmark"
5
- require "sorbet-runtime"
6
-
7
- require "packwerk/inflector"
8
- require "packwerk/output_style"
9
- require "packwerk/output_styles/plain"
10
-
11
4
  module Packwerk
12
5
  module Formatters
13
6
  class OffensesFormatter
7
+ include Packwerk::OffensesFormatter
8
+
14
9
  extend T::Sig
15
10
 
16
11
  sig { params(style: OutputStyle).void }
@@ -18,9 +13,9 @@ module Packwerk
18
13
  @style = style
19
14
  end
20
15
 
21
- sig { params(offenses: T::Array[T.nilable(Offense)]).returns(String) }
16
+ sig { override.params(offenses: T::Array[T.nilable(Offense)]).returns(String) }
22
17
  def show_offenses(offenses)
23
- return "No offenses detected 🎉" if offenses.empty?
18
+ return "No offenses detected" if offenses.empty?
24
19
 
25
20
  <<~EOS
26
21
  #{offenses_list(offenses)}
@@ -28,6 +23,15 @@ module Packwerk
28
23
  EOS
29
24
  end
30
25
 
26
+ sig { override.params(offense_collection: Packwerk::OffenseCollection).returns(String) }
27
+ def show_stale_violations(offense_collection)
28
+ if offense_collection.stale_violations?
29
+ "There were stale violations found, please run `packwerk update-deprecations`"
30
+ else
31
+ "No stale violations detected"
32
+ end
33
+ end
34
+
31
35
  private
32
36
 
33
37
  sig { params(offenses: T::Array[T.nilable(Offense)]).returns(String) }
@@ -3,10 +3,6 @@
3
3
 
4
4
  require "benchmark"
5
5
 
6
- require "packwerk/inflector"
7
- require "packwerk/output_style"
8
- require "packwerk/output_styles/plain"
9
-
10
6
  module Packwerk
11
7
  module Formatters
12
8
  class ProgressFormatter
@@ -45,6 +41,11 @@ module Packwerk
45
41
  @out.puts
46
42
  @out.puts("📦 Finished in #{execution_time.round(2)} seconds")
47
43
  end
44
+
45
+ def interrupted
46
+ @out.puts
47
+ @out.puts("Manually interrupted. Violations caught so far are listed below:")
48
+ end
48
49
  end
49
50
  end
50
51
  end
@@ -1,7 +1,6 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- require "packwerk/configuration"
5
4
  require "erb"
6
5
 
7
6
  module Packwerk
@@ -2,8 +2,6 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "active_support/inflector"
5
- require "packwerk/inflections/default"
6
- require "packwerk/inflections/custom"
7
5
 
8
6
  module Packwerk
9
7
  class Inflector
data/lib/packwerk/node.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "parser"
4
5
  require "parser/ast/node"
5
6
 
6
7
  module Packwerk
@@ -1,11 +1,6 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- require "packwerk/node"
5
- require "packwerk/offense"
6
- require "packwerk/checker"
7
- require "packwerk/reference_lister"
8
-
9
4
  module Packwerk
10
5
  class NodeProcessor
11
6
  extend T::Sig
@@ -13,48 +8,36 @@ module Packwerk
13
8
  sig do
14
9
  params(
15
10
  reference_extractor: ReferenceExtractor,
16
- reference_lister: ReferenceLister,
17
11
  filename: String,
18
12
  checkers: T::Array[Checker]
19
13
  ).void
20
14
  end
21
- def initialize(reference_extractor:, reference_lister:, filename:, checkers:)
15
+ def initialize(reference_extractor:, filename:, checkers:)
22
16
  @reference_extractor = reference_extractor
23
- @reference_lister = reference_lister
24
17
  @filename = filename
25
18
  @checkers = checkers
26
19
  end
27
20
 
28
- def call(node, ancestors:)
29
- if Node.method_call?(node) || Node.constant?(node)
30
- reference = @reference_extractor.reference_from_node(node, ancestors: ancestors, file_path: @filename)
31
- check_reference(reference, node) if reference
32
- end
21
+ sig { params(node: Parser::AST::Node, ancestors: T::Array[Parser::AST::Node]).returns(T::Array[Offense]) }
22
+ def call(node, ancestors)
23
+ return [] unless Node.method_call?(node) || Node.constant?(node)
24
+ reference = @reference_extractor.reference_from_node(node, ancestors: ancestors, file_path: @filename)
25
+ check_reference(reference, node)
33
26
  end
34
27
 
35
28
  private
36
29
 
37
30
  def check_reference(reference, node)
38
- return nil unless (message = failed_check(reference))
39
-
40
- constant = reference.constant
41
-
42
- Packwerk::Offense.new(
43
- location: Node.location(node),
44
- file: reference.relative_path,
45
- message: <<~EOS
46
- #{message}
47
- Inference details: this is a reference to #{constant.name} which seems to be defined in #{constant.location}.
48
- To receive help interpreting or resolving this error message, see: https://github.com/Shopify/packwerk/blob/main/TROUBLESHOOT.md#Troubleshooting-violations
49
- EOS
50
- )
51
- end
52
-
53
- def failed_check(reference)
54
- failing_checker = @checkers.find do |checker|
55
- checker.invalid_reference?(reference, @reference_lister)
31
+ return [] unless reference
32
+ @checkers.each_with_object([]) do |checker, violations|
33
+ next unless checker.invalid_reference?(reference)
34
+ offense = Packwerk::ReferenceOffense.new(
35
+ location: Node.location(node),
36
+ reference: reference,
37
+ violation_type: checker.violation_type
38
+ )
39
+ violations << offense
56
40
  end
57
- failing_checker&.message_for(reference)
58
41
  end
59
42
  end
60
43
  end
@@ -1,15 +1,11 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "packwerk/constant_name_inspector"
5
- require "packwerk/checker"
6
-
7
4
  module Packwerk
8
5
  class NodeProcessorFactory < T::Struct
9
6
  extend T::Sig
10
7
 
11
8
  const :root_path, String
12
- const :reference_lister, ReferenceLister
13
9
  const :context_provider, Packwerk::ConstantDiscovery
14
10
  const :constant_name_inspectors, T::Array[ConstantNameInspector]
15
11
  const :checkers, T::Array[Checker]
@@ -18,7 +14,6 @@ module Packwerk
18
14
  def for(filename:, node:)
19
15
  ::Packwerk::NodeProcessor.new(
20
16
  reference_extractor: reference_extractor(node: node),
21
- reference_lister: reference_lister,
22
17
  filename: filename,
23
18
  checkers: checkers,
24
19
  )
@@ -1,8 +1,6 @@
1
1
  # typed: false
2
2
  # frozen_string_literal: true
3
3
 
4
- require "packwerk/node"
5
-
6
4
  module Packwerk
7
5
  class NodeVisitor
8
6
  def initialize(node_processor:)
@@ -10,8 +8,7 @@ module Packwerk
10
8
  end
11
9
 
12
10
  def visit(node, ancestors:, result:)
13
- offense = @node_processor.call(node, ancestors: ancestors)
14
- result << offense if offense
11
+ result.concat(@node_processor.call(node, ancestors))
15
12
 
16
13
  child_ancestors = [node] + ancestors
17
14
  Node.each_child(node) do |child|
@@ -2,10 +2,6 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "parser/source/map"
5
- require "sorbet-runtime"
6
-
7
- require "packwerk/output_style"
8
- require "packwerk/output_styles/plain"
9
5
 
10
6
  module Packwerk
11
7
  class Offense
@@ -0,0 +1,84 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Packwerk
5
+ class OffenseCollection
6
+ extend T::Sig
7
+ extend T::Helpers
8
+
9
+ sig do
10
+ params(
11
+ root_path: String,
12
+ deprecated_references: T::Hash[Packwerk::Package, Packwerk::DeprecatedReferences]
13
+ ).void
14
+ end
15
+ def initialize(root_path, deprecated_references = {})
16
+ @root_path = root_path
17
+ @deprecated_references = T.let(deprecated_references, T::Hash[Packwerk::Package, Packwerk::DeprecatedReferences])
18
+ @new_violations = T.let([], T::Array[Packwerk::ReferenceOffense])
19
+ @errors = T.let([], T::Array[Packwerk::Offense])
20
+ end
21
+
22
+ sig { returns(T::Array[Packwerk::ReferenceOffense]) }
23
+ attr_reader :new_violations
24
+
25
+ sig { returns(T::Array[Packwerk::Offense]) }
26
+ attr_reader :errors
27
+
28
+ sig do
29
+ params(offense: Packwerk::Offense)
30
+ .returns(T::Boolean)
31
+ end
32
+ def listed?(offense)
33
+ return false unless offense.is_a?(ReferenceOffense)
34
+ reference = offense.reference
35
+ deprecated_references_for(reference.source_package).listed?(reference, violation_type: offense.violation_type)
36
+ end
37
+
38
+ sig do
39
+ params(offense: Packwerk::Offense).void
40
+ end
41
+ def add_offense(offense)
42
+ unless offense.is_a?(ReferenceOffense)
43
+ @errors << offense
44
+ return
45
+ end
46
+ deprecated_references = deprecated_references_for(offense.reference.source_package)
47
+ unless deprecated_references.add_entries(offense.reference, offense.violation_type)
48
+ new_violations << offense
49
+ end
50
+ end
51
+
52
+ sig { returns(T::Boolean) }
53
+ def stale_violations?
54
+ @deprecated_references.values.any?(&:stale_violations?)
55
+ end
56
+
57
+ sig { void }
58
+ def dump_deprecated_references_files
59
+ @deprecated_references.each do |_, deprecated_references_file|
60
+ deprecated_references_file.dump
61
+ end
62
+ end
63
+
64
+ sig { returns(T::Array[Packwerk::Offense]) }
65
+ def outstanding_offenses
66
+ errors + new_violations
67
+ end
68
+
69
+ private
70
+
71
+ sig { params(package: Packwerk::Package).returns(Packwerk::DeprecatedReferences) }
72
+ def deprecated_references_for(package)
73
+ @deprecated_references[package] ||= Packwerk::DeprecatedReferences.new(
74
+ package,
75
+ deprecated_references_file_for(package),
76
+ )
77
+ end
78
+
79
+ sig { params(package: Packwerk::Package).returns(String) }
80
+ def deprecated_references_file_for(package)
81
+ File.join(@root_path, package.name, "deprecated_references.yml")
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,19 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Packwerk
5
+ module OffensesFormatter
6
+ extend T::Sig
7
+ extend T::Helpers
8
+
9
+ interface!
10
+
11
+ sig { abstract.params(offenses: T::Array[T.nilable(Offense)]).returns(String) }
12
+ def show_offenses(offenses)
13
+ end
14
+
15
+ sig { abstract.params(offense_collection: Packwerk::OffenseCollection).returns(String) }
16
+ def show_stale_violations(offense_collection)
17
+ end
18
+ end
19
+ end
@@ -33,7 +33,15 @@ module Packwerk
33
33
  end
34
34
 
35
35
  def public_path
36
- @public_path ||= File.join(@name, user_defined_public_path || "app/public/")
36
+ @public_path ||= begin
37
+ unprefixed_public_path = user_defined_public_path || "app/public/"
38
+
39
+ if root?
40
+ unprefixed_public_path
41
+ else
42
+ File.join(@name, unprefixed_public_path)
43
+ end
44
+ end
37
45
  end
38
46
 
39
47
  def public_path?(path)
@@ -52,6 +60,14 @@ module Packwerk
52
60
  name <=> other.name
53
61
  end
54
62
 
63
+ def eql?(other)
64
+ self == other
65
+ end
66
+
67
+ def hash
68
+ name.hash
69
+ end
70
+
55
71
  def to_s
56
72
  name
57
73
  end
@@ -3,8 +3,6 @@
3
3
 
4
4
  require "pathname"
5
5
 
6
- require "packwerk/package"
7
-
8
6
  module Packwerk
9
7
  class PackageSet
10
8
  include Enumerable