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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '087052a5ee210069f8924a622aec5c335221c0b2558ab9773e08bb1a674a3802'
|
|
4
|
+
data.tar.gz: '09e3fa99ed0eb9ee0d73803725667ea21d3e200c16bb4d7cd2c487784a55d457'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f1a4719aec0613776fa7ae34d7518a3c88142bd9f82875b1e8a0e257a6832c3e2ae6546997a58922e7c3a04de39e59bc7cb50bd2cf650701417711d99a1458fb
|
|
7
|
+
data.tar.gz: f2e0e1a12f63a9ec25daa3e34ed5ba13ef4129e172665a103f4938cdc06a0a9d3a804f83eb8984ed5dfbee74d22fc6b0185f2b6ba4688d22ce230712d6b70f09
|
data/exe/packwerk
CHANGED
|
@@ -10,18 +10,18 @@ module Packwerk
|
|
|
10
10
|
# correct results.
|
|
11
11
|
class ApplicationValidator
|
|
12
12
|
include Validator
|
|
13
|
-
extend T::Sig
|
|
14
13
|
extend ActiveSupport::Autoload
|
|
15
14
|
|
|
16
15
|
autoload :Helpers
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
#: (PackageSet package_set, Configuration configuration) -> Validator::Result
|
|
19
18
|
def check_all(package_set, configuration)
|
|
20
19
|
results = Validator.all.flat_map { |validator| validator.call(package_set, configuration) }
|
|
21
20
|
merge_results(results)
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
# @override
|
|
24
|
+
#: (PackageSet package_set, Configuration configuration) -> Validator::Result
|
|
25
25
|
def call(package_set, configuration)
|
|
26
26
|
results = [
|
|
27
27
|
check_package_manifest_syntax(configuration),
|
|
@@ -33,14 +33,15 @@ module Packwerk
|
|
|
33
33
|
merge_results(results, separator: "\n❓ ")
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
# @override
|
|
37
|
+
#: -> Array[String]
|
|
37
38
|
def permitted_keys
|
|
38
39
|
[
|
|
39
40
|
"metadata",
|
|
40
41
|
]
|
|
41
42
|
end
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
#: (Configuration configuration) -> Validator::Result
|
|
44
45
|
def check_package_manifest_syntax(configuration)
|
|
45
46
|
errors = []
|
|
46
47
|
|
|
@@ -68,7 +69,7 @@ module Packwerk
|
|
|
68
69
|
end
|
|
69
70
|
end
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
#: (Configuration configuration) -> Validator::Result
|
|
72
73
|
def check_application_structure(configuration)
|
|
73
74
|
resolver = ConstantResolver.new(
|
|
74
75
|
root_path: configuration.root_path.to_s,
|
|
@@ -84,7 +85,7 @@ module Packwerk
|
|
|
84
85
|
end
|
|
85
86
|
end
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
#: (Configuration configuration) -> Validator::Result
|
|
88
89
|
def check_package_manifest_paths(configuration)
|
|
89
90
|
all_package_manifests = package_manifests(configuration, "**/")
|
|
90
91
|
package_paths_package_manifests = package_manifests(configuration, package_glob(configuration))
|
|
@@ -105,7 +106,7 @@ module Packwerk
|
|
|
105
106
|
end
|
|
106
107
|
end
|
|
107
108
|
|
|
108
|
-
|
|
109
|
+
#: (Configuration configuration) -> Validator::Result
|
|
109
110
|
def check_root_package_exists(configuration)
|
|
110
111
|
root_package_path = File.join(configuration.root_path, "package.yml")
|
|
111
112
|
all_packages_manifests = package_manifests(configuration, package_glob(configuration))
|
|
@@ -124,12 +125,12 @@ module Packwerk
|
|
|
124
125
|
|
|
125
126
|
private
|
|
126
127
|
|
|
127
|
-
|
|
128
|
+
#: (untyped list) -> untyped
|
|
128
129
|
def format_yaml_strings(list)
|
|
129
130
|
list.sort.map { |p| "- \"#{p}\"" }.join("\n")
|
|
130
131
|
end
|
|
131
132
|
|
|
132
|
-
|
|
133
|
+
#: (Configuration configuration, Array[String] paths) -> Array[Pathname]
|
|
133
134
|
def relative_paths(configuration, paths)
|
|
134
135
|
paths.map { |path| relative_path(configuration, path) }
|
|
135
136
|
end
|
|
@@ -4,39 +4,28 @@
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
# Extracts the implicit constant reference from an active record association
|
|
6
6
|
class AssociationInspector
|
|
7
|
-
extend T::Sig
|
|
8
7
|
include ConstantNameInspector
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
sig do
|
|
23
|
-
params(
|
|
24
|
-
inflector: T.class_of(ActiveSupport::Inflector),
|
|
25
|
-
custom_associations: CustomAssociations,
|
|
26
|
-
excluded_files: T::Set[String]
|
|
27
|
-
).void
|
|
28
|
-
end
|
|
9
|
+
RAILS_ASSOCIATIONS = [
|
|
10
|
+
:belongs_to,
|
|
11
|
+
:has_many,
|
|
12
|
+
:has_one,
|
|
13
|
+
:has_and_belongs_to_many,
|
|
14
|
+
].to_set #: Set[Symbol]
|
|
15
|
+
|
|
16
|
+
#: (
|
|
17
|
+
#| inflector: singleton(ActiveSupport::Inflector),
|
|
18
|
+
#| ?custom_associations: Set[Symbol],
|
|
19
|
+
#| ?excluded_files: Set[String]
|
|
20
|
+
#| ) -> void
|
|
29
21
|
def initialize(inflector:, custom_associations: Set.new, excluded_files: Set.new)
|
|
30
22
|
@inflector = inflector
|
|
31
|
-
@associations =
|
|
32
|
-
@excluded_files =
|
|
23
|
+
@associations = RAILS_ASSOCIATIONS + custom_associations #: Set[Symbol]
|
|
24
|
+
@excluded_files = excluded_files #: Set[String]
|
|
33
25
|
end
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.params(node: AST::Node, ancestors: T::Array[AST::Node], relative_file: String)
|
|
38
|
-
.returns(T.nilable(String))
|
|
39
|
-
end
|
|
27
|
+
# @override
|
|
28
|
+
#: (AST::Node node, ancestors: Array[AST::Node], relative_file: String) -> String?
|
|
40
29
|
def constant_name_from_node(node, ancestors:, relative_file:)
|
|
41
30
|
return unless NodeHelpers.method_call?(node)
|
|
42
31
|
return if excluded?(relative_file)
|
|
@@ -56,18 +45,18 @@ module Packwerk
|
|
|
56
45
|
|
|
57
46
|
private
|
|
58
47
|
|
|
59
|
-
|
|
48
|
+
#: (String relative_file) -> bool
|
|
60
49
|
def excluded?(relative_file)
|
|
61
50
|
@excluded_files.include?(relative_file)
|
|
62
51
|
end
|
|
63
52
|
|
|
64
|
-
|
|
53
|
+
#: (AST::Node node) -> bool
|
|
65
54
|
def association?(node)
|
|
66
55
|
method_name = NodeHelpers.method_name(node)
|
|
67
56
|
@associations.include?(method_name)
|
|
68
57
|
end
|
|
69
58
|
|
|
70
|
-
|
|
59
|
+
#: (Array[AST::Node] arguments) -> AST::Node?
|
|
71
60
|
def custom_class_name(arguments)
|
|
72
61
|
association_options = arguments.detect { |n| NodeHelpers.hash?(n) }
|
|
73
62
|
return unless association_options
|
|
@@ -75,9 +64,9 @@ module Packwerk
|
|
|
75
64
|
NodeHelpers.value_from_hash(association_options, :class_name)
|
|
76
65
|
end
|
|
77
66
|
|
|
78
|
-
|
|
67
|
+
#: (Array[AST::Node] arguments) -> (Symbol | String)?
|
|
79
68
|
def association_name(arguments)
|
|
80
|
-
association_name_node =
|
|
69
|
+
association_name_node = arguments[0] #: as !nil
|
|
81
70
|
return unless NodeHelpers.symbol?(association_name_node)
|
|
82
71
|
|
|
83
72
|
NodeHelpers.literal_value(association_name_node)
|
data/lib/packwerk/cache.rb
CHANGED
|
@@ -5,18 +5,21 @@ require "digest"
|
|
|
5
5
|
|
|
6
6
|
module Packwerk
|
|
7
7
|
class Cache
|
|
8
|
-
|
|
8
|
+
class CacheContents
|
|
9
|
+
#: String
|
|
10
|
+
attr_reader :file_contents_digest
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
#: Array[UnresolvedReference]
|
|
13
|
+
attr_reader :unresolved_references
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
#: (file_contents_digest: String, unresolved_references: Array[UnresolvedReference]) -> void
|
|
16
|
+
def initialize(file_contents_digest:, unresolved_references:)
|
|
17
|
+
@file_contents_digest = file_contents_digest
|
|
18
|
+
@unresolved_references = unresolved_references
|
|
19
|
+
end
|
|
15
20
|
|
|
16
21
|
class << self
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
sig { params(serialized_cache_contents: String).returns(CacheContents) }
|
|
22
|
+
#: (String serialized_cache_contents) -> CacheContents
|
|
20
23
|
def deserialize(serialized_cache_contents)
|
|
21
24
|
cache_contents_json = JSON.parse(serialized_cache_contents)
|
|
22
25
|
unresolved_references = cache_contents_json["unresolved_references"].map do |json|
|
|
@@ -35,24 +38,36 @@ module Packwerk
|
|
|
35
38
|
end
|
|
36
39
|
end
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
#: (*untyped _args) -> String
|
|
42
|
+
def to_json(*_args)
|
|
43
|
+
JSON.generate({
|
|
44
|
+
file_contents_digest: @file_contents_digest,
|
|
45
|
+
unresolved_references: @unresolved_references.map do |ref|
|
|
46
|
+
source_location = ref.source_location #: as !nil
|
|
47
|
+
|
|
48
|
+
{
|
|
49
|
+
constant_name: ref.constant_name,
|
|
50
|
+
namespace_path: ref.namespace_path,
|
|
51
|
+
relative_path: ref.relative_path,
|
|
52
|
+
source_location: { line: source_location.line, column: source_location.column },
|
|
53
|
+
}
|
|
54
|
+
end,
|
|
55
|
+
})
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
#: -> String
|
|
39
59
|
def serialize
|
|
40
60
|
to_json
|
|
41
61
|
end
|
|
42
62
|
end
|
|
43
63
|
|
|
44
|
-
|
|
45
|
-
T::Hash[
|
|
46
|
-
String,
|
|
47
|
-
CacheContents
|
|
48
|
-
]
|
|
49
|
-
end
|
|
64
|
+
#: type cache_shape = Hash[String, CacheContents]
|
|
50
65
|
|
|
51
|
-
|
|
66
|
+
#: (enable_cache: bool, cache_directory: Pathname, config_path: String?) -> void
|
|
52
67
|
def initialize(enable_cache:, cache_directory:, config_path:)
|
|
53
68
|
@enable_cache = enable_cache
|
|
54
|
-
@cache =
|
|
55
|
-
@files_by_digest =
|
|
69
|
+
@cache = {} #: cache_shape
|
|
70
|
+
@files_by_digest = {} #: Hash[String, String]
|
|
56
71
|
@config_path = config_path
|
|
57
72
|
@cache_directory = cache_directory
|
|
58
73
|
|
|
@@ -63,25 +78,19 @@ module Packwerk
|
|
|
63
78
|
end
|
|
64
79
|
end
|
|
65
80
|
|
|
66
|
-
|
|
81
|
+
#: -> void
|
|
67
82
|
def bust_cache!
|
|
68
83
|
FileUtils.rm_rf(@cache_directory)
|
|
69
84
|
end
|
|
70
85
|
|
|
71
|
-
|
|
72
|
-
params(
|
|
73
|
-
file_path: String,
|
|
74
|
-
block: T.proc.returns(T::Array[UnresolvedReference])
|
|
75
|
-
).returns(T::Array[UnresolvedReference])
|
|
76
|
-
end
|
|
86
|
+
#: (String file_path) { -> Array[UnresolvedReference] } -> Array[UnresolvedReference]
|
|
77
87
|
def with_cache(file_path, &block)
|
|
78
88
|
return yield unless @enable_cache
|
|
79
89
|
|
|
80
90
|
cache_location = @cache_directory.join(digest_for_string(file_path))
|
|
81
91
|
|
|
82
92
|
cache_contents = if cache_location.exist?
|
|
83
|
-
|
|
84
|
-
CacheContents)
|
|
93
|
+
CacheContents.deserialize(cache_location.read) #: CacheContents
|
|
85
94
|
end
|
|
86
95
|
|
|
87
96
|
file_contents_digest = digest_for_file(file_path)
|
|
@@ -105,31 +114,31 @@ module Packwerk
|
|
|
105
114
|
end
|
|
106
115
|
end
|
|
107
116
|
|
|
108
|
-
|
|
117
|
+
#: (String file) -> String
|
|
109
118
|
def digest_for_file(file)
|
|
110
119
|
digest_for_string(File.read(file))
|
|
111
120
|
end
|
|
112
121
|
|
|
113
|
-
|
|
122
|
+
#: (String str) -> String
|
|
114
123
|
def digest_for_string(str)
|
|
115
124
|
# MD5 appears to be the fastest
|
|
116
125
|
# https://gist.github.com/morimori/1330095
|
|
117
126
|
Digest::MD5.hexdigest(str)
|
|
118
127
|
end
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
#: -> void
|
|
121
130
|
def bust_cache_if_packwerk_yml_has_changed!
|
|
122
131
|
return nil if @config_path.nil?
|
|
123
132
|
|
|
124
133
|
bust_cache_if_contents_have_changed(File.read(@config_path), :packwerk_yml)
|
|
125
134
|
end
|
|
126
135
|
|
|
127
|
-
|
|
136
|
+
#: -> void
|
|
128
137
|
def bust_cache_if_inflections_have_changed!
|
|
129
138
|
bust_cache_if_contents_have_changed(YAML.dump(ActiveSupport::Inflector.inflections), :inflections)
|
|
130
139
|
end
|
|
131
140
|
|
|
132
|
-
|
|
141
|
+
#: (String contents, Symbol contents_key) -> void
|
|
133
142
|
def bust_cache_if_contents_have_changed(contents, contents_key)
|
|
134
143
|
current_digest = digest_for_string(contents)
|
|
135
144
|
cached_digest_path = @cache_directory.join(contents_key.to_s)
|
|
@@ -153,7 +162,7 @@ module Packwerk
|
|
|
153
162
|
end
|
|
154
163
|
end
|
|
155
164
|
|
|
156
|
-
|
|
165
|
+
#: -> void
|
|
157
166
|
def create_cache_directory!
|
|
158
167
|
FileUtils.mkdir_p(@cache_directory)
|
|
159
168
|
end
|
|
@@ -161,9 +170,7 @@ module Packwerk
|
|
|
161
170
|
|
|
162
171
|
class Debug
|
|
163
172
|
class << self
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
sig { params(out: String).void }
|
|
173
|
+
#: (String out) -> void
|
|
167
174
|
def out(out)
|
|
168
175
|
if ENV["DEBUG_PACKWERK_CACHE"]
|
|
169
176
|
puts(out)
|
data/lib/packwerk/checker.rb
CHANGED
|
@@ -2,62 +2,60 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Packwerk
|
|
5
|
+
# @abstract
|
|
5
6
|
module Checker
|
|
6
|
-
extend T::Sig
|
|
7
|
-
extend T::Helpers
|
|
8
|
-
|
|
9
|
-
abstract!
|
|
10
|
-
|
|
11
7
|
class << self
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
sig { params(base: T::Class[T.anything]).void }
|
|
8
|
+
#: (Class[top] base) -> void
|
|
15
9
|
def included(base)
|
|
16
10
|
checkers << base
|
|
17
11
|
end
|
|
18
12
|
|
|
19
|
-
|
|
13
|
+
#: -> Array[Checker]
|
|
20
14
|
def all
|
|
21
15
|
load_defaults
|
|
22
|
-
|
|
16
|
+
checkers.map(&:new) #: as Array[Checker]
|
|
23
17
|
end
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
#: (String violation_type) -> Checker
|
|
26
20
|
def find(violation_type)
|
|
27
21
|
checker_by_violation_type(violation_type)
|
|
28
22
|
end
|
|
29
23
|
|
|
30
24
|
private
|
|
31
25
|
|
|
32
|
-
|
|
26
|
+
#: -> void
|
|
33
27
|
def load_defaults
|
|
34
28
|
require("packwerk/reference_checking/checkers/dependency_checker")
|
|
35
29
|
end
|
|
36
30
|
|
|
37
|
-
|
|
31
|
+
#: -> Array[Class[top]]
|
|
38
32
|
def checkers
|
|
39
|
-
@checkers ||=
|
|
33
|
+
@checkers ||= [] #: Array[Class[top]]?
|
|
40
34
|
end
|
|
41
35
|
|
|
42
|
-
|
|
36
|
+
#: (String name) -> Checker
|
|
43
37
|
def checker_by_violation_type(name)
|
|
44
|
-
@checker_by_violation_type ||=
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
@checker_by_violation_type ||= Checker.all.to_h do |checker|
|
|
39
|
+
[checker.violation_type, checker]
|
|
40
|
+
end #: Hash[String, Checker]?
|
|
47
41
|
@checker_by_violation_type.fetch(name)
|
|
48
42
|
end
|
|
49
43
|
end
|
|
50
44
|
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
# @abstract
|
|
46
|
+
#: -> String
|
|
47
|
+
def violation_type = raise NotImplementedError, "Abstract method called"
|
|
53
48
|
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
# @abstract
|
|
50
|
+
#: (ReferenceOffense offense) -> bool
|
|
51
|
+
def strict_mode_violation?(offense) = raise NotImplementedError, "Abstract method called"
|
|
56
52
|
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
# @abstract
|
|
54
|
+
#: (Reference reference) -> bool
|
|
55
|
+
def invalid_reference?(reference) = raise NotImplementedError, "Abstract method called"
|
|
59
56
|
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
# @abstract
|
|
58
|
+
#: (Reference reference) -> String
|
|
59
|
+
def message(reference) = raise NotImplementedError, "Abstract method called"
|
|
62
60
|
end
|
|
63
61
|
end
|
data/lib/packwerk/cli.rb
CHANGED
|
@@ -4,18 +4,14 @@
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
# A command-line interface to Packwerk.
|
|
6
6
|
class Cli
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
style: OutputStyle,
|
|
16
|
-
offenses_formatter: T.nilable(OffensesFormatter)
|
|
17
|
-
).void
|
|
18
|
-
end
|
|
7
|
+
#: (
|
|
8
|
+
#| ?configuration: Configuration?,
|
|
9
|
+
#| ?out: (StringIO | IO),
|
|
10
|
+
#| ?err_out: (StringIO | IO),
|
|
11
|
+
#| ?environment: String,
|
|
12
|
+
#| ?style: OutputStyle,
|
|
13
|
+
#| ?offenses_formatter: OffensesFormatter?
|
|
14
|
+
#| ) -> void
|
|
19
15
|
def initialize(
|
|
20
16
|
configuration: nil,
|
|
21
17
|
out: $stdout,
|
|
@@ -28,21 +24,18 @@ module Packwerk
|
|
|
28
24
|
@err_out = err_out
|
|
29
25
|
@environment = environment
|
|
30
26
|
@style = style
|
|
31
|
-
@configuration =
|
|
32
|
-
@progress_formatter =
|
|
33
|
-
@offenses_formatter =
|
|
34
|
-
offenses_formatter || @configuration.offenses_formatter,
|
|
35
|
-
OffensesFormatter
|
|
36
|
-
)
|
|
27
|
+
@configuration = configuration || Configuration.from_path #: Configuration
|
|
28
|
+
@progress_formatter = Formatters::ProgressFormatter.new(@out, style: style) #: Formatters::ProgressFormatter
|
|
29
|
+
@offenses_formatter = offenses_formatter || @configuration.offenses_formatter #: OffensesFormatter
|
|
37
30
|
end
|
|
38
31
|
|
|
39
|
-
|
|
32
|
+
#: (Array[String] args) -> bot
|
|
40
33
|
def run(args)
|
|
41
34
|
success = execute_command(args)
|
|
42
35
|
exit(success)
|
|
43
36
|
end
|
|
44
37
|
|
|
45
|
-
|
|
38
|
+
#: (Array[String] args) -> bool
|
|
46
39
|
def execute_command(args)
|
|
47
40
|
command = args.shift || "help"
|
|
48
41
|
command_class = Commands.for(command)
|
|
@@ -3,17 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
module Commands
|
|
6
|
+
# @abstract
|
|
6
7
|
class BaseCommand
|
|
7
|
-
|
|
8
|
-
extend T::Helpers
|
|
9
|
-
abstract!
|
|
10
|
-
|
|
11
|
-
@description = T.let("", String)
|
|
8
|
+
@description = "" #: String
|
|
12
9
|
|
|
13
10
|
class << self
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
sig { params(description: T.nilable(String)).returns(String) }
|
|
11
|
+
#: (?String? description) -> String
|
|
17
12
|
def description(description = nil)
|
|
18
13
|
if description
|
|
19
14
|
@description = description
|
|
@@ -23,16 +18,14 @@ module Packwerk
|
|
|
23
18
|
end
|
|
24
19
|
end
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
).void
|
|
35
|
-
end
|
|
21
|
+
#: (
|
|
22
|
+
#| Array[String] args,
|
|
23
|
+
#| configuration: Configuration,
|
|
24
|
+
#| out: (StringIO | IO),
|
|
25
|
+
#| err_out: (StringIO | IO),
|
|
26
|
+
#| progress_formatter: Formatters::ProgressFormatter,
|
|
27
|
+
#| offenses_formatter: OffensesFormatter
|
|
28
|
+
#| ) -> void
|
|
36
29
|
def initialize(args, configuration:, out:, err_out:, progress_formatter:, offenses_formatter:)
|
|
37
30
|
@args = args
|
|
38
31
|
@configuration = configuration
|
|
@@ -42,27 +35,28 @@ module Packwerk
|
|
|
42
35
|
@offenses_formatter = offenses_formatter
|
|
43
36
|
end
|
|
44
37
|
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
# @abstract
|
|
39
|
+
#: -> bool
|
|
40
|
+
def run = raise NotImplementedError, "Abstract method called"
|
|
47
41
|
|
|
48
42
|
private
|
|
49
43
|
|
|
50
|
-
|
|
44
|
+
#: Array[String]
|
|
51
45
|
attr_reader :args
|
|
52
46
|
|
|
53
|
-
|
|
47
|
+
#: Configuration
|
|
54
48
|
attr_reader :configuration
|
|
55
49
|
|
|
56
|
-
|
|
50
|
+
#: (StringIO | IO)
|
|
57
51
|
attr_reader :out
|
|
58
52
|
|
|
59
|
-
|
|
53
|
+
#: (StringIO | IO)
|
|
60
54
|
attr_reader :err_out
|
|
61
55
|
|
|
62
|
-
|
|
56
|
+
#: Formatters::ProgressFormatter
|
|
63
57
|
attr_reader :progress_formatter
|
|
64
58
|
|
|
65
|
-
|
|
59
|
+
#: OffensesFormatter
|
|
66
60
|
attr_reader :offenses_formatter
|
|
67
61
|
end
|
|
68
62
|
end
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
module Commands
|
|
6
6
|
class CheckCommand < BaseCommand
|
|
7
|
-
extend T::Sig
|
|
8
7
|
include UsesParseRun
|
|
9
8
|
|
|
10
9
|
description "run all checks"
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
# @override
|
|
12
|
+
#: -> bool
|
|
13
13
|
def run
|
|
14
14
|
if @files_for_processing.files.empty?
|
|
15
15
|
out.puts(<<~MSG.squish)
|
|
@@ -20,8 +20,8 @@ module Packwerk
|
|
|
20
20
|
true
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
all_offenses =
|
|
24
|
-
on_interrupt =
|
|
23
|
+
all_offenses = [] #: Array[Offense]
|
|
24
|
+
on_interrupt = -> { progress_formatter.interrupted } #: ^-> void
|
|
25
25
|
|
|
26
26
|
progress_formatter.started_inspection(@files_for_processing.files) do
|
|
27
27
|
all_offenses = parse_run.find_offenses(run_context, on_interrupt: on_interrupt) do |offenses|
|
|
@@ -48,14 +48,14 @@ module Packwerk
|
|
|
48
48
|
|
|
49
49
|
private
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
#: -> RunContext
|
|
52
52
|
def run_context
|
|
53
|
-
@run_context ||=
|
|
53
|
+
@run_context ||= RunContext.from_configuration(configuration) #: RunContext?
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
#: -> OffenseCollection
|
|
57
57
|
def offense_collection
|
|
58
|
-
@offense_collection ||=
|
|
58
|
+
@offense_collection ||= OffenseCollection.new(configuration.root_path) #: OffenseCollection?
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -4,11 +4,10 @@
|
|
|
4
4
|
module Packwerk
|
|
5
5
|
module Commands
|
|
6
6
|
class HelpCommand < BaseCommand
|
|
7
|
-
extend T::Sig
|
|
8
|
-
|
|
9
7
|
description "display help information about packwerk"
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
# @override
|
|
10
|
+
#: -> bool
|
|
12
11
|
def run
|
|
13
12
|
err_out.puts(<<~USAGE)
|
|
14
13
|
Usage: #{$PROGRAM_NAME} <subcommand>
|
|
@@ -22,7 +21,7 @@ module Packwerk
|
|
|
22
21
|
|
|
23
22
|
private
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
#: -> String
|
|
26
25
|
def command_help_lines
|
|
27
26
|
Commands.all.map do |command|
|
|
28
27
|
" #{command.name} - #{command.description}"
|