packwerk 3.2.3 → 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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/exe/packwerk +0 -4
  3. data/lib/packwerk/application_validator.rb +11 -10
  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 +1 -7
  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 +10 -15
  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 +28 -39
  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 +9 -10
  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/prism@1.9.0.rbi +43359 -0
  65. data/sorbet/rbi/shims/packwerk/reference.rbi +5 -12
  66. data/sorbet/rbi/shims/packwerk/unresolved_reference.rbi +5 -12
  67. data/sorbet/rbi/shims/parser.rbi +1 -1
  68. metadata +18 -19
  69. data/lib/packwerk/disable_sorbet.rb +0 -41
  70. data/sorbet/rbi/gems/prism@0.27.0.rbi +0 -36983
@@ -4,29 +4,27 @@
4
4
  module Packwerk
5
5
  module Commands
6
6
  class LazyLoadedEntry
7
- extend T::Sig
8
-
9
- sig { returns(String) }
7
+ #: String
10
8
  attr_reader :name
11
9
 
12
- sig { params(name: String, aliases: T::Array[String]).void }
10
+ #: (String name, ?aliases: Array[String]) -> void
13
11
  def initialize(name, aliases: [])
14
12
  @name = name
15
13
  @aliases = aliases
16
14
  end
17
15
 
18
- sig { returns(T.class_of(BaseCommand)) }
16
+ #: -> singleton(BaseCommand)
19
17
  def command_class
20
18
  classname = @name.sub(" ", "_").underscore.classify + "Command"
21
19
  Commands.const_get(classname) # rubocop:disable Sorbet/ConstantsFromStrings
22
20
  end
23
21
 
24
- sig { returns(String) }
22
+ #: -> String
25
23
  def description
26
24
  command_class.description
27
25
  end
28
26
 
29
- sig { params(name_or_alias: String).returns(T::Boolean) }
27
+ #: (String name_or_alias) -> bool
30
28
  def matches_command?(name_or_alias)
31
29
  @name == name_or_alias || @aliases.include?(name_or_alias)
32
30
  end
@@ -4,12 +4,12 @@
4
4
  module Packwerk
5
5
  module Commands
6
6
  class UpdateTodoCommand < BaseCommand
7
- extend T::Sig
8
7
  include UsesParseRun
9
8
 
10
9
  description "update package_todo.yml files"
11
10
 
12
- sig { override.returns(T::Boolean) }
11
+ # @override
12
+ #: -> bool
13
13
  def run
14
14
  if @files_for_processing.files_specified?
15
15
  out.puts(<<~MSG.squish)
@@ -28,7 +28,7 @@ module Packwerk
28
28
  end
29
29
 
30
30
  run_context = RunContext.from_configuration(configuration)
31
- offenses = T.let([], T::Array[Offense])
31
+ offenses = [] #: Array[Offense]
32
32
  progress_formatter.started_inspection(@files_for_processing.files) do
33
33
  offenses = parse_run.find_offenses(run_context, on_interrupt: -> { progress_formatter.interrupted }) do
34
34
  progress_formatter.increment_progress
@@ -5,32 +5,26 @@ require "optparse"
5
5
 
6
6
  module Packwerk
7
7
  module Commands
8
+ # @requires_ancestor: BaseCommand
8
9
  module UsesParseRun
9
- extend T::Sig
10
- extend T::Helpers
11
-
12
- requires_ancestor { BaseCommand }
13
-
14
- sig do
15
- params(
16
- args: T::Array[String],
17
- configuration: Configuration,
18
- out: T.any(StringIO, IO),
19
- err_out: T.any(StringIO, IO),
20
- progress_formatter: Formatters::ProgressFormatter,
21
- offenses_formatter: OffensesFormatter,
22
- ).void
23
- end
10
+ #: (
11
+ #| Array[String] args,
12
+ #| configuration: Configuration,
13
+ #| out: (StringIO | IO),
14
+ #| err_out: (StringIO | IO),
15
+ #| progress_formatter: Formatters::ProgressFormatter,
16
+ #| offenses_formatter: OffensesFormatter
17
+ #| ) -> void
24
18
  def initialize(args, configuration:, out:, err_out:, progress_formatter:, offenses_formatter:)
25
19
  super
26
- @files_for_processing = T.let(fetch_files_to_process, FilesForProcessing)
27
- @offenses_formatter = T.let(offenses_formatter_from_options || @offenses_formatter, OffensesFormatter)
20
+ @files_for_processing = fetch_files_to_process #: FilesForProcessing
21
+ @offenses_formatter = offenses_formatter_from_options || @offenses_formatter #: OffensesFormatter
28
22
  configuration.parallel = parsed_options[:parallel]
29
23
  end
30
24
 
31
25
  private
32
26
 
33
- sig { returns(FilesForProcessing) }
27
+ #: -> FilesForProcessing
34
28
  def fetch_files_to_process
35
29
  FilesForProcessing.fetch(
36
30
  relative_file_paths: parsed_options[:relative_file_paths],
@@ -39,12 +33,12 @@ module Packwerk
39
33
  )
40
34
  end
41
35
 
42
- sig { returns(T.nilable(OffensesFormatter)) }
36
+ #: -> OffensesFormatter?
43
37
  def offenses_formatter_from_options
44
38
  OffensesFormatter.find(parsed_options[:formatter_name]) if parsed_options[:formatter_name]
45
39
  end
46
40
 
47
- sig { returns(ParseRun) }
41
+ #: -> ParseRun
48
42
  def parse_run
49
43
  ParseRun.new(
50
44
  relative_file_set: @files_for_processing.files,
@@ -52,17 +46,17 @@ module Packwerk
52
46
  )
53
47
  end
54
48
 
55
- sig { returns(T::Hash[Symbol, T.untyped]) }
49
+ #: -> Hash[Symbol, untyped]
56
50
  def parsed_options
57
51
  return @parsed_options if @parsed_options
58
52
 
59
- @parsed_options = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped]))
53
+ @parsed_options = nil #: Hash[Symbol, untyped]?
60
54
 
61
55
  @parsed_options = {
62
- relative_file_paths: T.let([], T::Array[String]),
63
- ignore_nested_packages: T.let(false, T::Boolean),
64
- formatter_name: T.let(nil, T.nilable(String)),
65
- parallel: T.let(configuration.parallel?, T::Boolean),
56
+ relative_file_paths: [], #: Array[String]
57
+ ignore_nested_packages: false, #: bool
58
+ formatter_name: nil, #: String?
59
+ parallel: configuration.parallel?,
66
60
  }
67
61
 
68
62
  OptionParser.new do |parser|
@@ -4,19 +4,18 @@
4
4
  module Packwerk
5
5
  module Commands
6
6
  class ValidateCommand < BaseCommand
7
- extend T::Sig
8
-
9
7
  description "verify integrity of packwerk and package configuration"
10
8
 
11
- sig { override.returns(T::Boolean) }
9
+ # @override
10
+ #: -> bool
12
11
  def run
13
- validator_result = T.let(nil, T.nilable(Validator::Result))
12
+ validator_result = nil #: Validator::Result?
14
13
 
15
14
  progress_formatter.started_validation do
16
15
  validator_result = validator.check_all(package_set, configuration)
17
16
  end
18
17
 
19
- validator_result = T.must(validator_result)
18
+ validator_result = validator_result #: as !nil
20
19
 
21
20
  if validator_result.ok?
22
21
  out.puts("Validation successful 🎉")
@@ -29,12 +28,12 @@ module Packwerk
29
28
 
30
29
  private
31
30
 
32
- sig { returns(ApplicationValidator) }
31
+ #: -> ApplicationValidator
33
32
  def validator
34
33
  ApplicationValidator.new
35
34
  end
36
35
 
37
- sig { returns(PackageSet) }
36
+ #: -> PackageSet
38
37
  def package_set
39
38
  PackageSet.load_all_from(
40
39
  configuration.root_path,
@@ -4,11 +4,10 @@
4
4
  module Packwerk
5
5
  module Commands
6
6
  class VersionCommand < BaseCommand
7
- extend T::Sig
8
-
9
7
  description "output packwerk version"
10
8
 
11
- sig { override.returns(T::Boolean) }
9
+ # @override
10
+ #: -> bool
12
11
  def run
13
12
  out.puts(Packwerk::VERSION)
14
13
  true
@@ -3,7 +3,6 @@
3
3
 
4
4
  module Packwerk
5
5
  module Commands
6
- extend T::Sig
7
6
  extend ActiveSupport::Autoload
8
7
 
9
8
  autoload :BaseCommand
@@ -17,30 +16,28 @@ module Packwerk
17
16
  autoload :VersionCommand
18
17
 
19
18
  class << self
20
- extend T::Sig
21
-
22
- sig { params(name: String, aliases: T::Array[String]).void }
19
+ #: (String name, ?aliases: Array[String]) -> void
23
20
  def register(name, aliases: [])
24
21
  registry << LazyLoadedEntry.new(name, aliases: aliases)
25
22
  end
26
23
 
27
- sig { params(name_or_alias: String).returns(T.nilable(T.class_of(BaseCommand))) }
24
+ #: (String name_or_alias) -> singleton(BaseCommand)?
28
25
  def for(name_or_alias)
29
26
  registry
30
27
  .find { |command| command.matches_command?(name_or_alias) }
31
28
  &.command_class
32
29
  end
33
30
 
34
- sig { returns(T::Array[LazyLoadedEntry]) }
31
+ #: -> Array[LazyLoadedEntry]
35
32
  def all
36
33
  registry.dup
37
34
  end
38
35
 
39
36
  private
40
37
 
41
- sig { returns(T::Array[LazyLoadedEntry]) }
38
+ #: -> Array[LazyLoadedEntry]
42
39
  def registry
43
- @registry ||= T.let([], T.nilable(T::Array[LazyLoadedEntry]))
40
+ @registry ||= [] #: Array[LazyLoadedEntry]?
44
41
  end
45
42
  end
46
43
 
@@ -6,12 +6,8 @@ require "yaml"
6
6
 
7
7
  module Packwerk
8
8
  class Configuration
9
- extend T::Sig
10
-
11
9
  class << self
12
- extend T::Sig
13
-
14
- sig { params(path: String).returns(Configuration) }
10
+ #: (?String path) -> Configuration
15
11
  def from_path(path = Dir.pwd)
16
12
  raise ArgumentError, "#{File.expand_path(path)} does not exist" unless File.exist?(path)
17
13
 
@@ -26,7 +22,7 @@ module Packwerk
26
22
 
27
23
  private
28
24
 
29
- sig { params(path: String).returns(Configuration) }
25
+ #: (String path) -> Configuration
30
26
  def from_packwerk_config(path)
31
27
  new(
32
28
  YAML.load_file(path) || {},
@@ -36,58 +32,51 @@ module Packwerk
36
32
  end
37
33
 
38
34
  DEFAULT_CONFIG_PATH = "packwerk.yml"
39
- DEFAULT_INCLUDE_GLOBS = T.let(["**/*.{rb,rake,erb}"], T::Array[String])
40
- DEFAULT_EXCLUDE_GLOBS = T.let(["{bin,node_modules,script,tmp,vendor}/**/*"], T::Array[String])
35
+ DEFAULT_INCLUDE_GLOBS = ["**/*.{rb,rake,erb}"] #: Array[String]
36
+ DEFAULT_EXCLUDE_GLOBS = ["{bin,node_modules,script,tmp,vendor}/**/*"] #: Array[String]
41
37
 
42
- sig { returns(T::Array[String]) }
38
+ #: Array[String]
43
39
  attr_reader(:include)
44
40
 
45
- sig { returns(T::Array[String]) }
41
+ #: Array[String]
46
42
  attr_reader(:exclude)
47
43
 
48
- sig { returns(String) }
44
+ #: String
49
45
  attr_reader(:root_path)
50
46
 
51
- sig { returns(T.any(String, T::Array[String])) }
47
+ #: (String | Array[String])
52
48
  attr_reader(:package_paths)
53
49
 
54
- sig { returns(T::Array[Symbol]) }
50
+ #: Array[Symbol]
55
51
  attr_reader(:custom_associations)
56
52
 
57
- sig { returns(T::Array[String]) }
53
+ #: Array[String]
58
54
  attr_reader(:associations_exclude)
59
55
 
60
- sig { returns(T.nilable(String)) }
56
+ #: String?
61
57
  attr_reader(:config_path)
62
58
 
63
- sig { returns(Pathname) }
59
+ #: Pathname
64
60
  attr_reader(:cache_directory)
65
61
 
66
- sig { params(parallel: T::Boolean).returns(T::Boolean) }
62
+ #: bool
67
63
  attr_writer(:parallel)
68
64
 
69
- sig do
70
- params(
71
- configs: T::Hash[String, T.untyped],
72
- config_path: T.nilable(String),
73
- ).void
74
- end
65
+ #: (?Hash[String, untyped] configs, ?config_path: String?) -> void
75
66
  def initialize(configs = {}, config_path: nil)
76
- @include = T.let(configs["include"] || DEFAULT_INCLUDE_GLOBS, T::Array[String])
77
- @exclude = T.let(configs["exclude"] || DEFAULT_EXCLUDE_GLOBS, T::Array[String])
67
+ @include = configs["include"] || DEFAULT_INCLUDE_GLOBS #: Array[String]
68
+ @exclude = configs["exclude"] || DEFAULT_EXCLUDE_GLOBS #: Array[String]
78
69
  root = config_path ? File.dirname(config_path) : "."
79
- @root_path = T.let(File.expand_path(root), String)
80
- @package_paths = T.let(configs["package_paths"] || "**/", T.any(String, T::Array[String]))
81
- @custom_associations = T.let((configs["custom_associations"] || []).map(&:to_sym), T::Array[Symbol])
82
- @associations_exclude = T.let(configs["associations_exclude"] || [], T::Array[String])
83
- @parallel = T.let(configs.key?("parallel") ? configs["parallel"] : true, T::Boolean)
84
- @cache_enabled = T.let(configs.key?("cache") ? configs["cache"] : false, T::Boolean)
85
- @cache_directory = T.let(Pathname.new(configs["cache_directory"] || "tmp/cache/packwerk"), Pathname)
70
+ @root_path = File.expand_path(root) #: String
71
+ @package_paths = configs["package_paths"] || "**/" #: (String | Array[String])
72
+ @custom_associations = (configs["custom_associations"] || []).map(&:to_sym) #: Array[Symbol]
73
+ @associations_exclude = configs["associations_exclude"] || [] #: Array[String]
74
+ @parallel = configs.key?("parallel") ? configs["parallel"] : true #: bool
75
+ @cache_enabled = configs.key?("cache") ? configs["cache"] : false #: bool
76
+ @cache_directory = Pathname.new(configs["cache_directory"] || "tmp/cache/packwerk") #: Pathname
86
77
  @config_path = config_path
87
78
 
88
- @offenses_formatter_identifier = T.let(
89
- configs["offenses_formatter"] || Formatters::DefaultOffensesFormatter::IDENTIFIER, String
90
- )
79
+ @offenses_formatter_identifier = configs["offenses_formatter"] || Formatters::DefaultOffensesFormatter::IDENTIFIER #: String
91
80
 
92
81
  if configs.key?("require")
93
82
  configs["require"].each do |require_directive|
@@ -96,25 +85,22 @@ module Packwerk
96
85
  end
97
86
  end
98
87
 
99
- sig { returns(T::Hash[String, Module]) }
88
+ #: -> Hash[String, Module[top]]
100
89
  def load_paths
101
- @load_paths ||= T.let(
102
- RailsLoadPaths.for(@root_path, environment: "test"),
103
- T.nilable(T::Hash[String, Module]),
104
- )
90
+ @load_paths ||= RailsLoadPaths.for(@root_path, environment: "test") #: Hash[String, Module[top]]?
105
91
  end
106
92
 
107
- sig { returns(T::Boolean) }
93
+ #: -> bool
108
94
  def parallel?
109
95
  @parallel
110
96
  end
111
97
 
112
- sig { returns(OffensesFormatter) }
98
+ #: -> OffensesFormatter
113
99
  def offenses_formatter
114
100
  OffensesFormatter.find(@offenses_formatter_identifier)
115
101
  end
116
102
 
117
- sig { returns(T::Boolean) }
103
+ #: -> bool
118
104
  def cache_enabled?
119
105
  @cache_enabled
120
106
  end
@@ -4,14 +4,10 @@
4
4
  module Packwerk
5
5
  # Extracts a constant name from an AST node of type :const
6
6
  class ConstNodeInspector
7
- extend T::Sig
8
7
  include ConstantNameInspector
9
8
 
10
- sig do
11
- override
12
- .params(node: AST::Node, ancestors: T::Array[AST::Node], relative_file: String)
13
- .returns(T.nilable(String))
14
- end
9
+ # @override
10
+ #: (AST::Node node, ancestors: Array[AST::Node], relative_file: String) -> String?
15
11
  def constant_name_from_node(node, ancestors:, relative_file:)
16
12
  return nil unless NodeHelpers.constant?(node)
17
13
 
@@ -34,18 +30,18 @@ module Packwerk
34
30
 
35
31
  private
36
32
 
37
- sig { params(parent: T.nilable(AST::Node)).returns(T::Boolean) }
33
+ #: (AST::Node? parent) -> bool
38
34
  def root_constant?(parent)
39
35
  !(parent && NodeHelpers.constant?(parent))
40
36
  end
41
37
 
42
- sig { params(node: AST::Node, parent: AST::Node).returns(T.nilable(T::Boolean)) }
38
+ #: (AST::Node node, parent: AST::Node) -> bool?
43
39
  def constant_in_module_or_class_definition?(node, parent:)
44
40
  parent_name = NodeHelpers.module_name_from_definition(parent)
45
41
  parent_name && parent_name == NodeHelpers.constant_name(node)
46
42
  end
47
43
 
48
- sig { params(ancestors: T::Array[AST::Node]).returns(String) }
44
+ #: (Array[AST::Node] ancestors) -> String
49
45
  def fully_qualify_constant(ancestors)
50
46
  # We're defining a class with this name, in which case the constant is implicitly fully qualified by its
51
47
  # enclosing namespace
@@ -2,7 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
5
- extend T::Sig
6
-
7
5
  ConstantContext = Struct.new(:name, :location, :package)
8
6
  end
@@ -15,13 +15,9 @@ module Packwerk
15
15
  # have no way of inferring the file it is defined in. You could argue though that inheritance means that another
16
16
  # constant with the same name exists in the inheriting class, and this view is sufficient for all our use cases.
17
17
  class ConstantDiscovery
18
- extend T::Sig
19
-
20
18
  # @param constant_resolver [ConstantResolver]
21
19
  # @param packages [Packwerk::PackageSet]
22
- sig do
23
- params(constant_resolver: ConstantResolver, packages: Packwerk::PackageSet).void
24
- end
20
+ #: (constant_resolver: ConstantResolver, packages: Packwerk::PackageSet) -> void
25
21
  def initialize(constant_resolver:, packages:)
26
22
  @packages = packages
27
23
  @resolver = constant_resolver
@@ -33,11 +29,7 @@ module Packwerk
33
29
  #
34
30
  # @return [Packwerk::Package] the package that contains the given file,
35
31
  # or nil if the path is not owned by any component
36
- sig do
37
- params(
38
- path: String,
39
- ).returns(Packwerk::Package)
40
- end
32
+ #: (String path) -> Packwerk::Package
41
33
  def package_from_path(path)
42
34
  @packages.package_from_path(path)
43
35
  end
@@ -49,12 +41,7 @@ module Packwerk
49
41
  # @param current_namespace_path [Array<String>] (optional) The namespace of the context in which the constant is
50
42
  # used, e.g. ["Apps", "Models"] for `Apps::Models`. Defaults to [] which means top level.
51
43
  # @return [ConstantContext]
52
- sig do
53
- params(
54
- const_name: String,
55
- current_namespace_path: T.nilable(T::Array[String]),
56
- ).returns(T.nilable(ConstantContext))
57
- end
44
+ #: (String const_name, ?current_namespace_path: Array[String]?) -> ConstantContext?
58
45
  def context_for(const_name, current_namespace_path: [])
59
46
  begin
60
47
  constant = @resolver.resolve(const_name, current_namespace_path: current_namespace_path)
@@ -5,18 +5,11 @@ require "ast"
5
5
 
6
6
  module Packwerk
7
7
  # An interface describing an object that can extract a constant name from an AST node.
8
+ # @interface
8
9
  module ConstantNameInspector
9
- extend T::Sig
10
- extend T::Helpers
11
-
12
- interface!
13
-
14
- sig do
15
- abstract
16
- .params(node: ::AST::Node, ancestors: T::Array[::AST::Node], relative_file: String)
17
- .returns(T.nilable(String))
18
- end
19
- def constant_name_from_node(node, ancestors:, relative_file:); end
10
+ # @abstract
11
+ #: (::AST::Node node, ancestors: Array[::AST::Node], relative_file: String) -> String?
12
+ def constant_name_from_node(node, ancestors:, relative_file:) = raise NotImplementedError, "Abstract method called"
20
13
  end
21
14
 
22
15
  private_constant :ConstantNameInspector
@@ -6,8 +6,7 @@ module Packwerk
6
6
  # in the `packwerk.yml` configuration.
7
7
  module ExtensionLoader
8
8
  class << self
9
- extend T::Sig
10
- sig { params(require_directive: String, config_dir_path: String).void }
9
+ #: (String require_directive, String config_dir_path) -> void
11
10
  def load(require_directive, config_dir_path)
12
11
  # We want to transform the require directive to behave differently
13
12
  # if it's a specific local file being required versus a gem
@@ -1,42 +1,39 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "parser/ast/node"
4
+ require "parser"
5
5
 
6
6
  module Packwerk
7
7
  class FileProcessor
8
- extend T::Sig
9
-
10
8
  class UnknownFileTypeResult < Offense
11
- extend T::Sig
12
-
13
- sig { params(file: String).void }
9
+ #: (file: String) -> void
14
10
  def initialize(file:)
15
11
  super(file: file, message: "unknown file type")
16
12
  end
17
13
  end
18
14
 
19
- sig do
20
- params(
21
- node_processor_factory: NodeProcessorFactory,
22
- cache: Cache,
23
- parser_factory: T.nilable(Parsers::Factory)
24
- ).void
25
- end
15
+ #: (node_processor_factory: NodeProcessorFactory, cache: Cache, ?parser_factory: Parsers::Factory?) -> void
26
16
  def initialize(node_processor_factory:, cache:, parser_factory: nil)
27
17
  @node_processor_factory = node_processor_factory
28
18
  @cache = cache
29
- @parser_factory = T.let(parser_factory || Packwerk::Parsers::Factory.instance, Parsers::Factory)
19
+ @parser_factory = parser_factory || Packwerk::Parsers::Factory.instance #: Parsers::Factory
30
20
  end
31
21
 
32
- class ProcessedFile < T::Struct
33
- const :unresolved_references, T::Array[UnresolvedReference], default: []
34
- const :offenses, T::Array[Offense], default: []
35
- end
22
+ class ProcessedFile
23
+ #: Array[UnresolvedReference]
24
+ attr_reader :unresolved_references
36
25
 
37
- sig do
38
- params(relative_file: String).returns(ProcessedFile)
26
+ #: Array[Offense]
27
+ attr_reader :offenses
28
+
29
+ #: (?unresolved_references: Array[UnresolvedReference], ?offenses: Array[Offense]) -> void
30
+ def initialize(unresolved_references: [], offenses: [])
31
+ @unresolved_references = unresolved_references
32
+ @offenses = offenses
33
+ end
39
34
  end
35
+
36
+ #: (String relative_file) -> ProcessedFile
40
37
  def call(relative_file)
41
38
  parser = parser_for(relative_file)
42
39
  if parser.nil?
@@ -68,9 +65,7 @@ module Packwerk
68
65
 
69
66
  private
70
67
 
71
- sig do
72
- params(node: Parser::AST::Node, relative_file: String).returns(T::Array[UnresolvedReference])
73
- end
68
+ #: (Parser::AST::Node node, String relative_file) -> Array[UnresolvedReference]
74
69
  def references_from_ast(node, relative_file)
75
70
  references = []
76
71
 
@@ -81,14 +76,14 @@ module Packwerk
81
76
  references
82
77
  end
83
78
 
84
- sig { params(relative_file: String, parser: Parsers::ParserInterface).returns(T.untyped) }
79
+ #: (String relative_file, Parsers::ParserInterface parser) -> untyped
85
80
  def parse_into_ast(relative_file, parser)
86
81
  File.open(relative_file, "r", nil, external_encoding: Encoding::UTF_8) do |file|
87
82
  parser.call(io: file, file_path: relative_file)
88
83
  end
89
84
  end
90
85
 
91
- sig { params(file_path: String).returns(T.nilable(Parsers::ParserInterface)) }
86
+ #: (String file_path) -> Parsers::ParserInterface?
92
87
  def parser_for(file_path)
93
88
  @parser_factory.for_path(file_path)
94
89
  end