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.
- checksums.yaml +4 -4
- data/exe/packwerk +0 -4
- data/lib/packwerk/application_validator.rb +11 -10
- data/lib/packwerk/association_inspector.rb +21 -32
- data/lib/packwerk/cache.rb +43 -36
- data/lib/packwerk/checker.rb +24 -26
- data/lib/packwerk/cli.rb +13 -20
- data/lib/packwerk/commands/base_command.rb +20 -26
- data/lib/packwerk/commands/check_command.rb +8 -8
- data/lib/packwerk/commands/help_command.rb +3 -4
- data/lib/packwerk/commands/init_command.rb +2 -3
- data/lib/packwerk/commands/lazy_loaded_entry.rb +5 -7
- data/lib/packwerk/commands/update_todo_command.rb +3 -3
- data/lib/packwerk/commands/uses_parse_run.rb +20 -26
- data/lib/packwerk/commands/validate_command.rb +6 -7
- data/lib/packwerk/commands/version_command.rb +2 -3
- data/lib/packwerk/commands.rb +5 -8
- data/lib/packwerk/configuration.rb +29 -43
- data/lib/packwerk/const_node_inspector.rb +5 -9
- data/lib/packwerk/constant_context.rb +0 -2
- data/lib/packwerk/constant_discovery.rb +3 -16
- data/lib/packwerk/constant_name_inspector.rb +4 -11
- data/lib/packwerk/extension_loader.rb +1 -2
- data/lib/packwerk/file_processor.rb +20 -25
- data/lib/packwerk/files_for_processing.rb +13 -29
- data/lib/packwerk/formatters/default_offenses_formatter.rb +14 -12
- data/lib/packwerk/formatters/progress_formatter.rb +10 -12
- data/lib/packwerk/generators/configuration_file.rb +5 -9
- data/lib/packwerk/generators/root_package.rb +3 -7
- data/lib/packwerk/graph.rb +1 -7
- data/lib/packwerk/node_helpers.rb +32 -38
- data/lib/packwerk/node_processor.rb +2 -14
- data/lib/packwerk/node_processor_factory.rb +13 -7
- data/lib/packwerk/node_visitor.rb +2 -10
- data/lib/packwerk/offense.rb +6 -12
- data/lib/packwerk/offense_collection.rb +22 -35
- data/lib/packwerk/offenses_formatter.rb +27 -34
- data/lib/packwerk/output_style.rb +10 -11
- data/lib/packwerk/output_styles/coloured.rb +6 -4
- data/lib/packwerk/output_styles/plain.rb +6 -4
- data/lib/packwerk/package.rb +15 -16
- data/lib/packwerk/package_set.rb +15 -25
- data/lib/packwerk/package_todo.rb +21 -30
- data/lib/packwerk/parse_run.rb +10 -37
- data/lib/packwerk/parsed_constant_definitions.rb +10 -24
- data/lib/packwerk/parsers/erb.rb +11 -22
- data/lib/packwerk/parsers/factory.rb +9 -9
- data/lib/packwerk/parsers/parser_interface.rb +5 -10
- data/lib/packwerk/parsers/ruby.rb +9 -14
- data/lib/packwerk/parsers.rb +2 -4
- data/lib/packwerk/rails_load_paths.rb +6 -11
- data/lib/packwerk/reference_checking/checkers/dependency_checker.rb +10 -15
- data/lib/packwerk/reference_checking/reference_checker.rb +2 -8
- data/lib/packwerk/reference_extractor.rb +22 -55
- data/lib/packwerk/reference_offense.rb +5 -15
- data/lib/packwerk/run_context.rb +28 -39
- data/lib/packwerk/spring_command.rb +4 -7
- data/lib/packwerk/validator/result.rb +12 -5
- data/lib/packwerk/validator.rb +23 -33
- data/lib/packwerk/validators/dependency_validator.rb +9 -10
- data/lib/packwerk/version.rb +1 -1
- data/lib/packwerk.rb +0 -1
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/prism@1.9.0.rbi +43359 -0
- data/sorbet/rbi/shims/packwerk/reference.rbi +5 -12
- data/sorbet/rbi/shims/packwerk/unresolved_reference.rbi +5 -12
- data/sorbet/rbi/shims/parser.rbi +1 -1
- metadata +18 -19
- data/lib/packwerk/disable_sorbet.rb +0 -41
- 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
|
-
|
|
8
|
-
|
|
9
|
-
sig { returns(String) }
|
|
7
|
+
#: String
|
|
10
8
|
attr_reader :name
|
|
11
9
|
|
|
12
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22
|
+
#: -> String
|
|
25
23
|
def description
|
|
26
24
|
command_class.description
|
|
27
25
|
end
|
|
28
26
|
|
|
29
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 =
|
|
27
|
-
@offenses_formatter =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
+
#: -> Hash[Symbol, untyped]
|
|
56
50
|
def parsed_options
|
|
57
51
|
return @parsed_options if @parsed_options
|
|
58
52
|
|
|
59
|
-
@parsed_options =
|
|
53
|
+
@parsed_options = nil #: Hash[Symbol, untyped]?
|
|
60
54
|
|
|
61
55
|
@parsed_options = {
|
|
62
|
-
relative_file_paths:
|
|
63
|
-
ignore_nested_packages:
|
|
64
|
-
formatter_name:
|
|
65
|
-
parallel:
|
|
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
|
-
|
|
9
|
+
# @override
|
|
10
|
+
#: -> bool
|
|
12
11
|
def run
|
|
13
|
-
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 =
|
|
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
|
-
|
|
31
|
+
#: -> ApplicationValidator
|
|
33
32
|
def validator
|
|
34
33
|
ApplicationValidator.new
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
#: -> PackageSet
|
|
38
37
|
def package_set
|
|
39
38
|
PackageSet.load_all_from(
|
|
40
39
|
configuration.root_path,
|
data/lib/packwerk/commands.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
31
|
+
#: -> Array[LazyLoadedEntry]
|
|
35
32
|
def all
|
|
36
33
|
registry.dup
|
|
37
34
|
end
|
|
38
35
|
|
|
39
36
|
private
|
|
40
37
|
|
|
41
|
-
|
|
38
|
+
#: -> Array[LazyLoadedEntry]
|
|
42
39
|
def registry
|
|
43
|
-
@registry ||=
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
40
|
-
DEFAULT_EXCLUDE_GLOBS =
|
|
35
|
+
DEFAULT_INCLUDE_GLOBS = ["**/*.{rb,rake,erb}"] #: Array[String]
|
|
36
|
+
DEFAULT_EXCLUDE_GLOBS = ["{bin,node_modules,script,tmp,vendor}/**/*"] #: Array[String]
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
#: Array[String]
|
|
43
39
|
attr_reader(:include)
|
|
44
40
|
|
|
45
|
-
|
|
41
|
+
#: Array[String]
|
|
46
42
|
attr_reader(:exclude)
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
#: String
|
|
49
45
|
attr_reader(:root_path)
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
#: (String | Array[String])
|
|
52
48
|
attr_reader(:package_paths)
|
|
53
49
|
|
|
54
|
-
|
|
50
|
+
#: Array[Symbol]
|
|
55
51
|
attr_reader(:custom_associations)
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
#: Array[String]
|
|
58
54
|
attr_reader(:associations_exclude)
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
#: String?
|
|
61
57
|
attr_reader(:config_path)
|
|
62
58
|
|
|
63
|
-
|
|
59
|
+
#: Pathname
|
|
64
60
|
attr_reader(:cache_directory)
|
|
65
61
|
|
|
66
|
-
|
|
62
|
+
#: bool
|
|
67
63
|
attr_writer(:parallel)
|
|
68
64
|
|
|
69
|
-
|
|
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 =
|
|
77
|
-
@exclude =
|
|
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 =
|
|
80
|
-
@package_paths =
|
|
81
|
-
@custom_associations =
|
|
82
|
-
@associations_exclude =
|
|
83
|
-
@parallel =
|
|
84
|
-
@cache_enabled =
|
|
85
|
-
@cache_directory =
|
|
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 =
|
|
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
|
-
|
|
88
|
+
#: -> Hash[String, Module[top]]
|
|
100
89
|
def load_paths
|
|
101
|
-
@load_paths ||=
|
|
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
|
-
|
|
93
|
+
#: -> bool
|
|
108
94
|
def parallel?
|
|
109
95
|
@parallel
|
|
110
96
|
end
|
|
111
97
|
|
|
112
|
-
|
|
98
|
+
#: -> OffensesFormatter
|
|
113
99
|
def offenses_formatter
|
|
114
100
|
OffensesFormatter.find(@offenses_formatter_identifier)
|
|
115
101
|
end
|
|
116
102
|
|
|
117
|
-
|
|
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
|
-
|
|
11
|
-
|
|
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
|
-
|
|
33
|
+
#: (AST::Node? parent) -> bool
|
|
38
34
|
def root_constant?(parent)
|
|
39
35
|
!(parent && NodeHelpers.constant?(parent))
|
|
40
36
|
end
|
|
41
37
|
|
|
42
|
-
|
|
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
|
-
|
|
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
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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
|
|
4
|
+
require "parser"
|
|
5
5
|
|
|
6
6
|
module Packwerk
|
|
7
7
|
class FileProcessor
|
|
8
|
-
extend T::Sig
|
|
9
|
-
|
|
10
8
|
class UnknownFileTypeResult < Offense
|
|
11
|
-
|
|
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
|
-
|
|
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 =
|
|
19
|
+
@parser_factory = parser_factory || Packwerk::Parsers::Factory.instance #: Parsers::Factory
|
|
30
20
|
end
|
|
31
21
|
|
|
32
|
-
class ProcessedFile
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
end
|
|
22
|
+
class ProcessedFile
|
|
23
|
+
#: Array[UnresolvedReference]
|
|
24
|
+
attr_reader :unresolved_references
|
|
36
25
|
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
86
|
+
#: (String file_path) -> Parsers::ParserInterface?
|
|
92
87
|
def parser_for(file_path)
|
|
93
88
|
@parser_factory.for_path(file_path)
|
|
94
89
|
end
|