packwerk 3.2.2 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/exe/packwerk +0 -4
  3. data/lib/packwerk/application_validator.rb +13 -11
  4. data/lib/packwerk/association_inspector.rb +21 -32
  5. data/lib/packwerk/cache.rb +43 -36
  6. data/lib/packwerk/checker.rb +24 -26
  7. data/lib/packwerk/cli.rb +13 -20
  8. data/lib/packwerk/commands/base_command.rb +20 -26
  9. data/lib/packwerk/commands/check_command.rb +8 -8
  10. data/lib/packwerk/commands/help_command.rb +3 -4
  11. data/lib/packwerk/commands/init_command.rb +2 -3
  12. data/lib/packwerk/commands/lazy_loaded_entry.rb +5 -7
  13. data/lib/packwerk/commands/update_todo_command.rb +3 -3
  14. data/lib/packwerk/commands/uses_parse_run.rb +20 -26
  15. data/lib/packwerk/commands/validate_command.rb +6 -7
  16. data/lib/packwerk/commands/version_command.rb +2 -3
  17. data/lib/packwerk/commands.rb +5 -8
  18. data/lib/packwerk/configuration.rb +29 -43
  19. data/lib/packwerk/const_node_inspector.rb +5 -9
  20. data/lib/packwerk/constant_context.rb +0 -2
  21. data/lib/packwerk/constant_discovery.rb +3 -16
  22. data/lib/packwerk/constant_name_inspector.rb +4 -11
  23. data/lib/packwerk/extension_loader.rb +1 -2
  24. data/lib/packwerk/file_processor.rb +20 -25
  25. data/lib/packwerk/files_for_processing.rb +13 -29
  26. data/lib/packwerk/formatters/default_offenses_formatter.rb +14 -12
  27. data/lib/packwerk/formatters/progress_formatter.rb +10 -12
  28. data/lib/packwerk/generators/configuration_file.rb +5 -9
  29. data/lib/packwerk/generators/root_package.rb +3 -7
  30. data/lib/packwerk/graph.rb +14 -61
  31. data/lib/packwerk/node_helpers.rb +32 -38
  32. data/lib/packwerk/node_processor.rb +2 -14
  33. data/lib/packwerk/node_processor_factory.rb +13 -7
  34. data/lib/packwerk/node_visitor.rb +2 -10
  35. data/lib/packwerk/offense.rb +6 -12
  36. data/lib/packwerk/offense_collection.rb +22 -35
  37. data/lib/packwerk/offenses_formatter.rb +27 -34
  38. data/lib/packwerk/output_style.rb +10 -11
  39. data/lib/packwerk/output_styles/coloured.rb +6 -4
  40. data/lib/packwerk/output_styles/plain.rb +6 -4
  41. data/lib/packwerk/package.rb +15 -16
  42. data/lib/packwerk/package_set.rb +15 -25
  43. data/lib/packwerk/package_todo.rb +21 -30
  44. data/lib/packwerk/parse_run.rb +10 -37
  45. data/lib/packwerk/parsed_constant_definitions.rb +10 -24
  46. data/lib/packwerk/parsers/erb.rb +11 -22
  47. data/lib/packwerk/parsers/factory.rb +9 -9
  48. data/lib/packwerk/parsers/parser_interface.rb +5 -10
  49. data/lib/packwerk/parsers/ruby.rb +9 -14
  50. data/lib/packwerk/parsers.rb +2 -4
  51. data/lib/packwerk/rails_load_paths.rb +6 -11
  52. data/lib/packwerk/reference_checking/checkers/dependency_checker.rb +11 -17
  53. data/lib/packwerk/reference_checking/reference_checker.rb +2 -8
  54. data/lib/packwerk/reference_extractor.rb +22 -55
  55. data/lib/packwerk/reference_offense.rb +5 -15
  56. data/lib/packwerk/run_context.rb +32 -38
  57. data/lib/packwerk/spring_command.rb +4 -7
  58. data/lib/packwerk/validator/result.rb +12 -5
  59. data/lib/packwerk/validator.rb +23 -33
  60. data/lib/packwerk/validators/dependency_validator.rb +14 -14
  61. data/lib/packwerk/version.rb +1 -1
  62. data/lib/packwerk.rb +0 -1
  63. data/sorbet/config +2 -0
  64. data/sorbet/rbi/gems/{actionpack@7.0.3.1.rbi → actionpack@7.0.8.7.rbi} +1338 -1227
  65. data/sorbet/rbi/gems/{actionview@7.0.3.1.rbi → actionview@7.0.8.7.rbi} +548 -503
  66. data/sorbet/rbi/gems/{activesupport@7.0.3.1.rbi → activesupport@7.0.8.7.rbi} +714 -635
  67. data/sorbet/rbi/gems/{better_html@2.0.1.rbi → better_html@2.1.1.rbi} +21 -21
  68. data/sorbet/rbi/gems/{concurrent-ruby@1.1.10.rbi → concurrent-ruby@1.3.5.rbi} +1390 -1366
  69. data/sorbet/rbi/gems/{constant_resolver@0.2.0.rbi → constant_resolver@0.3.0.rbi} +22 -13
  70. data/sorbet/rbi/gems/{erubi@1.11.0.rbi → erubi@1.13.1.rbi} +28 -17
  71. data/sorbet/rbi/gems/{i18n@1.12.0.rbi → i18n@1.14.7.rbi} +234 -172
  72. data/sorbet/rbi/gems/{json@2.6.2.rbi → json@2.7.2.rbi} +94 -74
  73. data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +14237 -0
  74. data/sorbet/rbi/gems/{loofah@2.18.0.rbi → loofah@2.24.0.rbi} +470 -243
  75. data/sorbet/rbi/gems/{minitest@5.16.2.rbi → minitest@5.25.4.rbi} +577 -472
  76. data/sorbet/rbi/gems/{mocha@1.14.0.rbi → mocha@2.5.0.rbi} +468 -684
  77. data/sorbet/rbi/gems/{nokogiri@1.15.3.rbi → nokogiri@1.18.4.rbi} +1756 -869
  78. data/sorbet/rbi/gems/{parallel@1.24.0.rbi → parallel@1.25.1.rbi} +26 -20
  79. data/sorbet/rbi/gems/prism@1.9.0.rbi +43359 -0
  80. data/sorbet/rbi/gems/{racc@1.7.1.rbi → racc@1.8.1.rbi} +36 -36
  81. data/sorbet/rbi/gems/{rack-test@2.0.2.rbi → rack-test@2.2.0.rbi} +87 -114
  82. data/sorbet/rbi/gems/{rack@2.2.4.rbi → rack@2.2.13.rbi} +243 -195
  83. data/sorbet/rbi/gems/rails-dom-testing@2.2.0.rbi +754 -0
  84. data/sorbet/rbi/gems/rails-html-sanitizer@1.6.2.rbi +764 -0
  85. data/sorbet/rbi/gems/{railties@7.0.3.1.rbi → railties@7.0.8.7.rbi} +146 -140
  86. data/sorbet/rbi/gems/{regexp_parser@2.5.0.rbi → regexp_parser@2.9.2.rbi} +947 -542
  87. data/sorbet/rbi/gems/{rexml@3.2.5.rbi → rexml@3.3.9.rbi} +452 -312
  88. data/sorbet/rbi/gems/{rubocop-ast@1.21.0.rbi → rubocop-ast@1.31.3.rbi} +717 -588
  89. data/sorbet/rbi/gems/{rubocop@1.34.1.rbi → rubocop@1.64.1.rbi} +10916 -4406
  90. data/sorbet/rbi/gems/{ruby-progressbar@1.11.0.rbi → ruby-progressbar@1.13.0.rbi} +359 -281
  91. data/sorbet/rbi/gems/ruby2_keywords@0.0.5.rbi +8 -0
  92. data/sorbet/rbi/gems/{tzinfo@2.0.5.rbi → tzinfo@2.0.6.rbi} +144 -141
  93. data/sorbet/rbi/gems/{unicode-display_width@2.2.0.rbi → unicode-display_width@2.5.0.rbi} +24 -7
  94. data/sorbet/rbi/shims/packwerk/reference.rbi +5 -12
  95. data/sorbet/rbi/shims/packwerk/unresolved_reference.rbi +5 -12
  96. data/sorbet/rbi/shims/parser.rbi +1 -1
  97. metadata +50 -56
  98. data/lib/packwerk/disable_sorbet.rb +0 -41
  99. data/sorbet/rbi/gems/language_server-protocol@3.16.0.3.rbi +0 -8
  100. data/sorbet/rbi/gems/prettier_print@0.1.0.rbi +0 -8
  101. data/sorbet/rbi/gems/prism@0.27.0.rbi +0 -36983
  102. data/sorbet/rbi/gems/rails-dom-testing@2.0.3.rbi +0 -455
  103. data/sorbet/rbi/gems/rails-html-sanitizer@1.4.3.rbi +0 -542
  104. data/sorbet/rbi/gems/ruby-lsp@0.2.3.rbi +0 -11
  105. data/sorbet/rbi/gems/syntax_tree@3.3.0.rbi +0 -8
  106. /data/sorbet/rbi/gems/{builder@3.2.4.rbi → builder@3.3.0.rbi} +0 -0
  107. /data/sorbet/rbi/gems/{parser@3.3.1.0.rbi → parser@3.3.3.0.rbi} +0 -0
@@ -4,19 +4,10 @@
4
4
  module Packwerk
5
5
  # Extracts a possible constant reference from a given AST node.
6
6
  class ReferenceExtractor
7
- extend T::Sig
8
-
9
7
  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
8
+ #: (Array[UnresolvedReference] unresolved_references, ConstantDiscovery context_provider) -> Array[Reference]
18
9
  def get_fully_qualified_references_from(unresolved_references, context_provider)
19
- fully_qualified_references = T.let([], T::Array[Reference])
10
+ fully_qualified_references = [] #: Array[Reference]
20
11
 
21
12
  unresolved_references.each do |unresolved_references_or_offense|
22
13
  unresolved_reference = unresolved_references_or_offense
@@ -49,13 +40,7 @@ module Packwerk
49
40
  end
50
41
  end
51
42
 
52
- sig do
53
- params(
54
- constant_name_inspectors: T::Array[ConstantNameInspector],
55
- root_node: AST::Node,
56
- root_path: String,
57
- ).void
58
- end
43
+ #: (constant_name_inspectors: Array[ConstantNameInspector], root_node: AST::Node, root_path: String) -> void
59
44
  def initialize(
60
45
  constant_name_inspectors:,
61
46
  root_node:,
@@ -63,21 +48,12 @@ module Packwerk
63
48
  )
64
49
  @constant_name_inspectors = constant_name_inspectors
65
50
  @root_path = root_path
66
- @local_constant_definitions = T.let(
67
- ParsedConstantDefinitions.new(root_node: root_node),
68
- ParsedConstantDefinitions,
69
- )
51
+ @local_constant_definitions = ParsedConstantDefinitions.new(root_node: root_node) #: ParsedConstantDefinitions
70
52
  end
71
53
 
72
- sig do
73
- params(
74
- node: Parser::AST::Node,
75
- ancestors: T::Array[Parser::AST::Node],
76
- relative_file: String
77
- ).returns(T.nilable(UnresolvedReference))
78
- end
54
+ #: (Parser::AST::Node node, ancestors: Array[Parser::AST::Node], relative_file: String) -> UnresolvedReference?
79
55
  def reference_from_node(node, ancestors:, relative_file:)
80
- constant_name = T.let(nil, T.nilable(String))
56
+ constant_name = nil #: String?
81
57
 
82
58
  @constant_name_inspectors.each do |inspector|
83
59
  constant_name = inspect_node(
@@ -102,21 +78,20 @@ module Packwerk
102
78
 
103
79
  private
104
80
 
105
- sig do
106
- params(
107
- inspector: ConstantNameInspector,
108
- node: Parser::AST::Node,
109
- ancestors: T::Array[Parser::AST::Node],
110
- relative_file: String
111
- ).returns(T.nilable(String))
112
- end
81
+ #: (
82
+ #| ConstantNameInspector inspector,
83
+ #| node: Parser::AST::Node,
84
+ #| ancestors: Array[Parser::AST::Node],
85
+ #| relative_file: String
86
+ #| ) -> String?
113
87
  def inspect_node(inspector, node:, ancestors:, relative_file:)
114
88
  inspector.constant_name_from_node(node, ancestors: ancestors, relative_file: relative_file)
115
89
  rescue ArgumentError => error
116
90
  if error.message == "unknown keyword: :relative_file"
117
- T.unsafe(inspector).constant_name_from_node(node, ancestors: ancestors).tap do
91
+ inspector_ = inspector #: as untyped
92
+ inspector_.constant_name_from_node(node, ancestors: ancestors).tap do
118
93
  warn(<<~MSG.squish)
119
- #{T.cast(inspector, Object).class}#reference_from_node without a relative_file: keyword
94
+ #{inspector_.class}#reference_from_node without a relative_file: keyword
120
95
  argument is deprecated and will be required in Packwerk 3.1.1.
121
96
  MSG
122
97
  end
@@ -125,14 +100,12 @@ module Packwerk
125
100
  end
126
101
  end
127
102
 
128
- sig do
129
- params(
130
- constant_name: String,
131
- node: Parser::AST::Node,
132
- ancestors: T::Array[Parser::AST::Node],
133
- relative_file: String
134
- ).returns(T.nilable(UnresolvedReference))
135
- end
103
+ #: (
104
+ #| String constant_name,
105
+ #| node: Parser::AST::Node,
106
+ #| ancestors: Array[Parser::AST::Node],
107
+ #| relative_file: String
108
+ #| ) -> UnresolvedReference?
136
109
  def reference_from_constant(constant_name, node:, ancestors:, relative_file:)
137
110
  namespace_path = NodeHelpers.enclosing_namespace_path(node, ancestors: ancestors)
138
111
 
@@ -148,13 +121,7 @@ module Packwerk
148
121
  )
149
122
  end
150
123
 
151
- sig do
152
- params(
153
- constant_name: String,
154
- name_location: T.nilable(Node::Location),
155
- namespace_path: T::Array[String],
156
- ).returns(T::Boolean)
157
- end
124
+ #: (String constant_name, Node::Location? name_location, Array[String] namespace_path) -> bool
158
125
  def local_reference?(constant_name, name_location, namespace_path)
159
126
  @local_constant_definitions.local_reference?(
160
127
  constant_name,
@@ -4,26 +4,16 @@
4
4
  module Packwerk
5
5
  # An offense related to a {Packwerk::Reference}.
6
6
  class ReferenceOffense < Offense
7
- extend T::Sig
8
- extend T::Helpers
9
-
10
- sig { returns(Reference) }
7
+ #: Reference
11
8
  attr_reader :reference
12
9
 
13
- sig { returns(String) }
10
+ #: String
14
11
  attr_reader :violation_type
15
12
 
16
- sig do
17
- params(
18
- reference: Packwerk::Reference,
19
- violation_type: String,
20
- message: String,
21
- location: T.nilable(Node::Location)
22
- )
23
- .void
24
- end
13
+ #: (reference: Packwerk::Reference, violation_type: String, message: String, ?location: Node::Location?) -> void
25
14
  def initialize(reference:, violation_type:, message:, location: nil)
26
- super(file: T.must(reference.relative_path), message: message, location: location)
15
+ file = reference.relative_path #: as !nil
16
+ super(file: file, message: message, location: location)
27
17
  @reference = reference
28
18
  @violation_type = violation_type
29
19
  end
@@ -6,22 +6,17 @@ require "constant_resolver"
6
6
  module Packwerk
7
7
  # Holds the context of a Packwerk run across multiple files.
8
8
  class RunContext
9
- extend T::Sig
10
-
11
9
  class << self
12
- extend T::Sig
13
-
14
- sig do
15
- params(configuration: Configuration).returns(RunContext)
16
- end
10
+ #: (Configuration configuration) -> RunContext
17
11
  def from_configuration(configuration)
18
12
  new(
19
13
  root_path: configuration.root_path,
20
14
  load_paths: configuration.load_paths,
21
15
  package_paths: configuration.package_paths,
22
16
  inflector: ActiveSupport::Inflector,
23
- custom_associations: configuration.custom_associations,
17
+ custom_associations: configuration.custom_associations.to_set,
24
18
  associations_exclude: configuration.associations_exclude,
19
+ exclude: configuration.exclude,
25
20
  cache_enabled: configuration.cache_enabled?,
26
21
  cache_directory: configuration.cache_directory,
27
22
  config_path: configuration.config_path,
@@ -29,20 +24,19 @@ module Packwerk
29
24
  end
30
25
  end
31
26
 
32
- sig do
33
- params(
34
- root_path: String,
35
- load_paths: T::Hash[String, Module],
36
- inflector: T.class_of(ActiveSupport::Inflector),
37
- cache_directory: Pathname,
38
- config_path: T.nilable(String),
39
- package_paths: T.nilable(T.any(T::Array[String], String)),
40
- custom_associations: AssociationInspector::CustomAssociations,
41
- associations_exclude: T::Array[String],
42
- checkers: T::Array[Checker],
43
- cache_enabled: T::Boolean,
44
- ).void
45
- end
27
+ #: (
28
+ #| root_path: String,
29
+ #| load_paths: Hash[String, Module[top]],
30
+ #| inflector: singleton(ActiveSupport::Inflector),
31
+ #| cache_directory: Pathname,
32
+ #| ?config_path: String?,
33
+ #| ?package_paths: (Array[String] | String)?,
34
+ #| ?custom_associations: Set[Symbol],
35
+ #| ?associations_exclude: Array[String],
36
+ #| ?exclude: Array[String],
37
+ #| ?checkers: Array[Checker],
38
+ #| ?cache_enabled: bool
39
+ #| ) -> void
46
40
  def initialize(
47
41
  root_path:,
48
42
  load_paths:,
@@ -50,8 +44,9 @@ module Packwerk
50
44
  cache_directory:,
51
45
  config_path: nil,
52
46
  package_paths: nil,
53
- custom_associations: [],
47
+ custom_associations: Set.new,
54
48
  associations_exclude: [],
49
+ exclude: [],
55
50
  checkers: Checker.all,
56
51
  cache_enabled: false
57
52
  )
@@ -65,17 +60,16 @@ module Packwerk
65
60
  @cache_enabled = cache_enabled
66
61
  @cache_directory = cache_directory
67
62
  @config_path = config_path
63
+ @exclude = exclude
68
64
 
69
- @file_processor = T.let(nil, T.nilable(FileProcessor))
70
- @context_provider = T.let(nil, T.nilable(ConstantDiscovery))
71
- @package_set = T.let(nil, T.nilable(PackageSet))
65
+ @file_processor = nil #: FileProcessor?
66
+ @context_provider = nil #: ConstantDiscovery?
67
+ @package_set = nil #: PackageSet?
72
68
  # We need to initialize this before we fork the process, see https://github.com/Shopify/packwerk/issues/182
73
- @cache = T.let(
74
- Cache.new(enable_cache: @cache_enabled, cache_directory: @cache_directory, config_path: @config_path), Cache
75
- )
69
+ @cache = Cache.new(enable_cache: @cache_enabled, cache_directory: @cache_directory, config_path: @config_path) #: Cache
76
70
  end
77
71
 
78
- sig { params(relative_file: String).returns(T::Array[Packwerk::Offense]) }
72
+ #: (relative_file: String) -> Array[Packwerk::Offense]
79
73
  def process_file(relative_file:)
80
74
  processed_file = file_processor.call(relative_file)
81
75
 
@@ -88,28 +82,27 @@ module Packwerk
88
82
  processed_file.offenses + references.flat_map { |reference| reference_checker.call(reference) }
89
83
  end
90
84
 
91
- sig { returns(PackageSet) }
85
+ #: -> PackageSet
92
86
  def package_set
93
87
  @package_set ||= ::Packwerk::PackageSet.load_all_from(@root_path, package_pathspec: @package_paths)
94
88
  end
95
89
 
96
90
  private
97
91
 
98
- sig { returns(FileProcessor) }
92
+ #: -> FileProcessor
99
93
  def file_processor
100
94
  @file_processor ||= FileProcessor.new(node_processor_factory: node_processor_factory, cache: @cache)
101
95
  end
102
96
 
103
- sig { returns(NodeProcessorFactory) }
97
+ #: -> NodeProcessorFactory
104
98
  def node_processor_factory
105
99
  NodeProcessorFactory.new(
106
- context_provider: context_provider,
107
100
  root_path: @root_path,
108
101
  constant_name_inspectors: constant_name_inspectors
109
102
  )
110
103
  end
111
104
 
112
- sig { returns(ConstantDiscovery) }
105
+ #: -> ConstantDiscovery
113
106
  def context_provider
114
107
  @context_provider ||= ConstantDiscovery.new(
115
108
  constant_resolver: resolver,
@@ -117,16 +110,17 @@ module Packwerk
117
110
  )
118
111
  end
119
112
 
120
- sig { returns(ConstantResolver) }
113
+ #: -> ConstantResolver
121
114
  def resolver
122
115
  ConstantResolver.new(
123
116
  root_path: @root_path,
124
117
  load_paths: @load_paths,
125
118
  inflector: @inflector,
119
+ exclude: @exclude,
126
120
  )
127
121
  end
128
122
 
129
- sig { returns(T::Array[ConstantNameInspector]) }
123
+ #: -> Array[ConstantNameInspector]
130
124
  def constant_name_inspectors
131
125
  [
132
126
  ConstNodeInspector.new,
@@ -138,7 +132,7 @@ module Packwerk
138
132
  ]
139
133
  end
140
134
 
141
- sig { params(relative_globs: T::Array[String]).returns(FilesForProcessing::RelativeFileSet) }
135
+ #: (Array[String] relative_globs) -> FilesForProcessing::relative_file_set
142
136
  def relative_files_for_globs(relative_globs)
143
137
  Set.new(relative_globs.flat_map { |glob| Dir[glob] })
144
138
  end
@@ -2,30 +2,27 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "spring/commands"
5
- require "sorbet-runtime"
6
5
 
7
6
  module Packwerk
8
7
  class SpringCommand
9
- extend T::Sig
10
-
11
- sig { params(args: T.untyped).returns(String) }
8
+ #: (untyped args) -> String
12
9
  def env(args)
13
10
  # Packwerk needs to run in a test environment, which has a set of autoload paths that are
14
11
  # often a superset of the dev/prod paths (for example, test/support/helpers)
15
12
  "test"
16
13
  end
17
14
 
18
- sig { returns(String) }
15
+ #: -> String
19
16
  def exec_name
20
17
  "packwerk"
21
18
  end
22
19
 
23
- sig { returns(String) }
20
+ #: -> String
24
21
  def gem_name
25
22
  "packwerk"
26
23
  end
27
24
 
28
- sig { returns(T::Boolean) }
25
+ #: -> bool
29
26
  def call
30
27
  load(Gem.bin_path(gem_name, exec_name))
31
28
  end
@@ -3,13 +3,20 @@
3
3
 
4
4
  module Packwerk
5
5
  module Validator
6
- class Result < T::Struct
7
- extend T::Sig
6
+ class Result
7
+ #: bool
8
+ attr_reader :ok
8
9
 
9
- const :ok, T::Boolean
10
- const :error_value, T.nilable(String)
10
+ #: String?
11
+ attr_reader :error_value
11
12
 
12
- sig { returns(T::Boolean) }
13
+ #: (ok: bool, ?error_value: String?) -> void
14
+ def initialize(ok:, error_value: nil)
15
+ @ok = ok
16
+ @error_value = error_value
17
+ end
18
+
19
+ #: -> bool
13
20
  def ok?
14
21
  ok
15
22
  end
@@ -6,78 +6,68 @@ require "pathname"
6
6
  require "yaml"
7
7
 
8
8
  module Packwerk
9
+ # @abstract
9
10
  module Validator
10
- extend T::Sig
11
- extend T::Helpers
12
11
  extend ActiveSupport::Autoload
13
12
 
14
13
  autoload :Result
15
14
 
16
- abstract!
17
-
18
15
  class << self
19
- extend T::Sig
20
-
21
- sig { params(base: T::Class[T.anything]).void }
16
+ #: (Class[top] base) -> void
22
17
  def included(base)
23
18
  validators << base
24
19
  end
25
20
 
26
- sig { returns(T::Array[Validator]) }
21
+ #: -> Array[Validator]
27
22
  def all
28
23
  load_defaults
29
- T.cast(validators.map(&:new), T::Array[Validator])
24
+ validators.map(&:new) #: as Array[Validator]
30
25
  end
31
26
 
32
27
  private
33
28
 
34
- sig { void }
29
+ #: -> void
35
30
  def load_defaults
36
31
  require("packwerk/validators/dependency_validator")
37
32
  end
38
33
 
39
- sig { returns(T::Array[T::Class[T.anything]]) }
34
+ #: -> Array[Class[top]]
40
35
  def validators
41
- @validators ||= T.let([], T.nilable(T::Array[T::Class[T.anything]]))
36
+ @validators ||= [] #: Array[Class[top]]?
42
37
  end
43
38
  end
44
39
 
45
- sig { abstract.returns(T::Array[String]) }
46
- def permitted_keys
47
- end
40
+ # @abstract
41
+ #: -> Array[String]
42
+ def permitted_keys = raise NotImplementedError, "Abstract method called"
48
43
 
49
- sig { abstract.params(package_set: PackageSet, configuration: Configuration).returns(Validator::Result) }
50
- def call(package_set, configuration)
51
- end
44
+ # @abstract
45
+ #: (PackageSet package_set, Configuration configuration) -> Validator::Result
46
+ def call(package_set, configuration) = raise NotImplementedError, "Abstract method called"
52
47
 
53
- sig { params(configuration: Configuration, setting: T.untyped).returns(T.untyped) }
48
+ #: (Configuration configuration, untyped setting) -> untyped
54
49
  def package_manifests_settings_for(configuration, setting)
55
50
  package_manifests(configuration).map { |f| [f, (YAML.load_file(File.join(f)) || {})[setting]] }
56
51
  end
57
52
 
58
- sig do
59
- params(configuration: Configuration,
60
- glob_pattern: T.nilable(T.any(T::Array[String], String))).returns(T::Array[String])
61
- end
53
+ #: (Configuration configuration, ?(Array[String] | String)? glob_pattern) -> Array[String]
62
54
  def package_manifests(configuration, glob_pattern = nil)
63
55
  glob_pattern ||= package_glob(configuration)
64
56
  PackageSet.package_paths(configuration.root_path, glob_pattern, configuration.exclude)
65
57
  .map { |f| File.realpath(f) }
66
58
  end
67
59
 
68
- sig { params(configuration: Configuration).returns(T.any(T::Array[String], String)) }
60
+ #: (Configuration configuration) -> (Array[String] | String)
69
61
  def package_glob(configuration)
70
62
  configuration.package_paths
71
63
  end
72
64
 
73
- sig do
74
- params(
75
- results: T::Array[Validator::Result],
76
- separator: String,
77
- before_errors: String,
78
- after_errors: String,
79
- ).returns(Validator::Result)
80
- end
65
+ #: (
66
+ #| Array[Validator::Result] results,
67
+ #| ?separator: String,
68
+ #| ?before_errors: String,
69
+ #| ?after_errors: String
70
+ #| ) -> Validator::Result
81
71
  def merge_results(results, separator: "\n", before_errors: "", after_errors: "")
82
72
  results.reject!(&:ok?)
83
73
 
@@ -96,7 +86,7 @@ module Packwerk
96
86
  end
97
87
  end
98
88
 
99
- sig { params(configuration: Configuration, path: String).returns(Pathname) }
89
+ #: (Configuration configuration, String path) -> Pathname
100
90
  def relative_path(configuration, path)
101
91
  Pathname.new(path).relative_path_from(configuration.root_path)
102
92
  end
@@ -4,12 +4,10 @@
4
4
  module Packwerk
5
5
  module Validators
6
6
  class DependencyValidator
7
- extend T::Sig
8
7
  include Validator
9
8
 
10
- sig do
11
- override.params(package_set: PackageSet, configuration: Configuration).returns(Validator::Result)
12
- end
9
+ # @override
10
+ #: (PackageSet package_set, Configuration configuration) -> Validator::Result
13
11
  def call(package_set, configuration)
14
12
  results = [
15
13
  check_package_manifest_syntax(configuration),
@@ -20,7 +18,8 @@ module Packwerk
20
18
  merge_results(results)
21
19
  end
22
20
 
23
- sig { override.returns(T::Array[String]) }
21
+ # @override
22
+ #: -> Array[String]
24
23
  def permitted_keys
25
24
  [
26
25
  "enforce_dependencies",
@@ -30,7 +29,7 @@ module Packwerk
30
29
 
31
30
  private
32
31
 
33
- sig { params(configuration: Configuration).returns(Validator::Result) }
32
+ #: (Configuration configuration) -> Validator::Result
34
33
  def check_package_manifest_syntax(configuration)
35
34
  errors = []
36
35
 
@@ -63,12 +62,13 @@ module Packwerk
63
62
  end
64
63
  end
65
64
 
66
- sig { params(package_set: PackageSet).returns(Validator::Result) }
65
+ #: (PackageSet package_set) -> Validator::Result
67
66
  def check_acyclic_graph(package_set)
68
- edges = package_set.flat_map do |package|
69
- package.dependencies.map do |dependency|
70
- [package.name, package_set.fetch(dependency)&.name]
71
- end
67
+ edges = package_set.to_h do |package|
68
+ [
69
+ package.name,
70
+ package.dependencies.map { |dependency| package_set.fetch(dependency)&.name },
71
+ ]
72
72
  end
73
73
 
74
74
  dependency_graph = Graph.new(edges)
@@ -89,7 +89,7 @@ module Packwerk
89
89
  end
90
90
  end
91
91
 
92
- sig { params(configuration: Configuration).returns(Validator::Result) }
92
+ #: (Configuration configuration) -> Validator::Result
93
93
  def check_valid_package_dependencies(configuration)
94
94
  packages_dependencies = package_manifests_settings_for(configuration, "dependencies")
95
95
  .delete_if { |_, deps| deps.nil? }
@@ -125,7 +125,7 @@ module Packwerk
125
125
  end
126
126
  end
127
127
 
128
- sig { params(configuration: Configuration, path: T.untyped).returns(T::Boolean) }
128
+ #: (Configuration configuration, untyped path) -> bool
129
129
  def invalid_package_path?(configuration, path)
130
130
  # Packages at the root can be implicitly specified as "."
131
131
  return false if path == "."
@@ -141,7 +141,7 @@ module Packwerk
141
141
  # to the string:
142
142
  #
143
143
  # ["a -> b -> c -> a", "b -> c -> b"]
144
- sig { params(cycles: T.untyped).returns(T::Array[String]) }
144
+ #: (untyped cycles) -> Array[String]
145
145
  def build_cycle_strings(cycles)
146
146
  cycles.map do |cycle|
147
147
  cycle_strings = cycle.map(&:to_s)
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
5
- VERSION = "3.2.2"
5
+ VERSION = "3.3.0"
6
6
  end
data/lib/packwerk.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "sorbet-runtime"
5
4
  require "active_support"
6
5
  require "fileutils"
7
6
  require "stringio"
data/sorbet/config CHANGED
@@ -1,4 +1,6 @@
1
1
  --dir
2
2
  .
3
+ --parser=prism
3
4
  --enable-experimental-requires-ancestor
5
+ --enable-experimental-rbs-comments
4
6
  --ignore=/vendor/bundle