packwerk 1.0.2 → 1.2.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/.github/workflows/ci.yml +14 -5
- data/.ruby-version +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +129 -111
- data/README.md +8 -1
- data/USAGE.md +39 -17
- data/dev.yml +1 -1
- data/exe/packwerk +1 -1
- data/gemfiles/Gemfile-rails-6-0 +22 -0
- data/lib/packwerk.rb +73 -34
- data/lib/packwerk/application_load_paths.rb +3 -2
- data/lib/packwerk/application_validator.rb +85 -69
- data/lib/packwerk/association_inspector.rb +23 -11
- data/lib/packwerk/checker.rb +4 -7
- data/lib/packwerk/cli.rb +36 -93
- data/lib/packwerk/configuration.rb +10 -2
- data/lib/packwerk/const_node_inspector.rb +13 -14
- data/lib/packwerk/constant_discovery.rb +2 -0
- data/lib/packwerk/constant_name_inspector.rb +0 -1
- data/lib/packwerk/dependency_checker.rb +12 -17
- data/lib/packwerk/deprecated_references.rb +25 -8
- data/lib/packwerk/file_processor.rb +0 -4
- data/lib/packwerk/formatters/offenses_formatter.rb +43 -0
- data/lib/packwerk/formatters/progress_formatter.rb +9 -4
- data/lib/packwerk/generators/configuration_file.rb +0 -1
- data/lib/packwerk/inflector.rb +0 -2
- data/lib/packwerk/node.rb +9 -2
- data/lib/packwerk/node_processor.rb +15 -32
- data/lib/packwerk/node_processor_factory.rb +0 -5
- data/lib/packwerk/node_visitor.rb +1 -4
- data/lib/packwerk/offense.rb +2 -8
- data/lib/packwerk/offense_collection.rb +84 -0
- data/lib/packwerk/offenses_formatter.rb +15 -0
- data/lib/packwerk/output_style.rb +20 -0
- data/lib/packwerk/output_styles/coloured.rb +29 -0
- data/lib/packwerk/output_styles/plain.rb +26 -0
- data/lib/packwerk/package.rb +8 -0
- data/lib/packwerk/package_set.rb +8 -5
- data/lib/packwerk/parse_run.rb +104 -0
- data/lib/packwerk/parsed_constant_definitions.rb +2 -4
- data/lib/packwerk/parsers.rb +0 -2
- data/lib/packwerk/parsers/erb.rb +4 -2
- data/lib/packwerk/parsers/factory.rb +10 -3
- data/lib/packwerk/privacy_checker.rb +22 -17
- data/lib/packwerk/reference_extractor.rb +0 -8
- data/lib/packwerk/reference_offense.rb +49 -0
- data/lib/packwerk/result.rb +9 -0
- data/lib/packwerk/run_context.rb +4 -20
- data/lib/packwerk/sanity_checker.rb +1 -3
- data/lib/packwerk/spring_command.rb +1 -1
- data/lib/packwerk/version.rb +1 -1
- data/lib/packwerk/violation_type.rb +0 -2
- data/library.yml +1 -1
- data/packwerk.gemspec +1 -0
- data/service.yml +1 -4
- data/shipit.rubygems.yml +5 -1
- data/sorbet/rbi/gems/{actioncable@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actioncable@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +56 -36
- data/sorbet/rbi/gems/{actionmailbox@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actionmailbox@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +25 -28
- data/sorbet/rbi/gems/{actionmailer@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actionmailer@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +43 -24
- data/sorbet/rbi/gems/{actionpack@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actionpack@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +382 -284
- data/sorbet/rbi/gems/{actiontext@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actiontext@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +76 -40
- data/sorbet/rbi/gems/{actionview@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → actionview@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +206 -195
- data/sorbet/rbi/gems/{activejob@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activejob@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +64 -75
- data/sorbet/rbi/gems/{activemodel@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activemodel@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +103 -56
- data/sorbet/rbi/gems/{activerecord@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activerecord@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +1250 -898
- data/sorbet/rbi/gems/{activestorage@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activestorage@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +92 -120
- data/sorbet/rbi/gems/{activesupport@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → activesupport@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +292 -193
- data/sorbet/rbi/gems/{ast@2.4.1.rbi → ast@2.4.2.rbi} +2 -1
- data/sorbet/rbi/gems/{better_html@1.0.15.rbi → better_html@1.0.16.rbi} +2 -2
- data/sorbet/rbi/gems/{concurrent-ruby@1.1.6.rbi → concurrent-ruby@1.1.8.rbi} +12 -9
- data/sorbet/rbi/gems/{erubi@1.9.0.rbi → erubi@1.10.0.rbi} +3 -1
- data/sorbet/rbi/gems/{i18n@1.8.2.rbi → i18n@1.8.10.rbi} +19 -52
- data/sorbet/rbi/gems/{loofah@2.5.0.rbi → loofah@2.9.0.rbi} +3 -1
- data/sorbet/rbi/gems/marcel@1.0.0.rbi +70 -0
- data/sorbet/rbi/gems/{mini_mime@1.0.2.rbi → mini_mime@1.0.3.rbi} +6 -6
- data/sorbet/rbi/gems/{mini_portile2@2.4.0.rbi → minitest-focus@1.2.1.rbi} +2 -2
- data/sorbet/rbi/gems/{minitest@5.14.0.rbi → minitest@5.14.4.rbi} +31 -29
- data/sorbet/rbi/gems/{mocha@1.11.2.rbi → mocha@1.12.0.rbi} +25 -36
- data/sorbet/rbi/gems/{nio4r@2.5.2.rbi → nio4r@2.5.7.rbi} +21 -20
- data/sorbet/rbi/gems/{nokogiri@1.10.9.rbi → nokogiri@1.11.2.rbi} +193 -154
- data/sorbet/rbi/gems/parallel@1.20.1.rbi +117 -0
- data/sorbet/rbi/gems/parlour@6.0.0.rbi +1272 -0
- data/sorbet/rbi/gems/{parser@2.7.1.4.rbi → parser@3.0.0.0.rbi} +287 -174
- data/sorbet/rbi/gems/{pry@0.13.1.rbi → pry@0.14.0.rbi} +1 -1
- data/sorbet/rbi/gems/racc@1.5.2.rbi +57 -0
- data/sorbet/rbi/gems/{rack@2.2.2.rbi → rack@2.2.3.rbi} +23 -35
- data/sorbet/rbi/gems/{rails@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → rails@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +1 -1
- data/sorbet/rbi/gems/{railties@6.1.0.alpha-d80c18a391e33552ae2d943e68af56946f883f65.rbi → railties@7.0.0.alpha-d612542336d9a61381311c95a27d801bb4094779.rbi} +132 -121
- data/sorbet/rbi/gems/{rake@13.0.1.rbi → rake@13.0.3.rbi} +16 -20
- data/sorbet/rbi/gems/{parallel@1.19.1.rbi → regexp_parser@2.1.1.rbi} +2 -2
- data/sorbet/rbi/gems/rubocop-ast@1.4.1.rbi +8 -0
- data/sorbet/rbi/gems/{rubocop-performance@1.5.2.rbi → rubocop-performance@1.10.2.rbi} +1 -1
- data/sorbet/rbi/gems/{rubocop-shopify@1.0.2.rbi → rubocop-shopify@2.0.1.rbi} +1 -1
- data/sorbet/rbi/gems/{rubocop-sorbet@0.3.7.rbi → rubocop-sorbet@0.6.1.rbi} +1 -1
- data/sorbet/rbi/gems/{rubocop@0.82.0.rbi → rubocop@1.12.0.rbi} +1 -1
- data/sorbet/rbi/gems/{ruby-progressbar@1.10.1.rbi → ruby-progressbar@1.11.0.rbi} +1 -1
- data/sorbet/rbi/gems/spoom@1.1.0.rbi +1061 -0
- data/sorbet/rbi/gems/{spring@2.1.0.rbi → spring@2.1.1.rbi} +7 -7
- data/sorbet/rbi/gems/{sprockets-rails@3.2.1.rbi → sprockets-rails@3.2.2.rbi} +88 -68
- data/sorbet/rbi/gems/{sprockets@4.0.0.rbi → sprockets@4.0.2.rbi} +8 -7
- data/sorbet/rbi/gems/{tapioca@0.4.5.rbi → tapioca@0.4.19.rbi} +109 -24
- data/sorbet/rbi/gems/{thor@1.0.1.rbi → thor@1.1.0.rbi} +16 -15
- data/sorbet/rbi/gems/{tzinfo@2.0.2.rbi → tzinfo@2.0.4.rbi} +21 -2
- data/sorbet/rbi/gems/{unicode-display_width@1.7.0.rbi → unicode-display_width@2.0.0.rbi} +1 -1
- data/sorbet/rbi/gems/{websocket-driver@0.7.1.rbi → websocket-driver@0.7.3.rbi} +29 -29
- data/sorbet/rbi/gems/{websocket-extensions@0.1.4.rbi → websocket-extensions@0.1.5.rbi} +2 -2
- data/sorbet/rbi/gems/zeitwerk@2.4.2.rbi +177 -0
- data/sorbet/tapioca/require.rb +1 -0
- metadata +78 -57
- data/lib/packwerk/checking_deprecated_references.rb +0 -40
- data/lib/packwerk/output_styles.rb +0 -41
- data/lib/packwerk/reference_lister.rb +0 -23
- data/lib/packwerk/updating_deprecated_references.rb +0 -51
- data/sorbet/rbi/gems/jaro_winkler@1.5.4.rbi +0 -8
- data/sorbet/rbi/gems/marcel@0.3.3.rbi +0 -30
- data/sorbet/rbi/gems/mimemagic@0.3.5.rbi +0 -47
- data/sorbet/rbi/gems/parlour@4.0.1.rbi +0 -561
- data/sorbet/rbi/gems/spoom@1.0.4.rbi +0 -418
- data/sorbet/rbi/gems/zeitwerk@2.3.0.rbi +0 -8
@@ -0,0 +1,26 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Packwerk
|
5
|
+
module OutputStyles
|
6
|
+
class Plain
|
7
|
+
extend T::Sig
|
8
|
+
include OutputStyle
|
9
|
+
|
10
|
+
sig { override.returns(String) }
|
11
|
+
def reset
|
12
|
+
""
|
13
|
+
end
|
14
|
+
|
15
|
+
sig { override.returns(String) }
|
16
|
+
def filename
|
17
|
+
""
|
18
|
+
end
|
19
|
+
|
20
|
+
sig { override.returns(String) }
|
21
|
+
def error
|
22
|
+
""
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/packwerk/package.rb
CHANGED
data/lib/packwerk/package_set.rb
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
|
4
4
|
require "pathname"
|
5
5
|
|
6
|
-
require "packwerk/package"
|
7
|
-
|
8
6
|
module Packwerk
|
9
7
|
class PackageSet
|
10
8
|
include Enumerable
|
@@ -28,8 +26,12 @@ module Packwerk
|
|
28
26
|
def package_paths(root_path, package_pathspec)
|
29
27
|
bundle_path_match = Bundler.bundle_path.join("**").to_s
|
30
28
|
|
31
|
-
|
32
|
-
.
|
29
|
+
glob_patterns = Array(package_pathspec).map do |pathspec|
|
30
|
+
File.join(root_path, pathspec, PACKAGE_CONFIG_FILENAME)
|
31
|
+
end
|
32
|
+
|
33
|
+
Dir.glob(glob_patterns)
|
34
|
+
.map { |path| Pathname.new(path).cleanpath }
|
33
35
|
.reject { |path| path.realpath.fnmatch(bundle_path_match) }
|
34
36
|
end
|
35
37
|
|
@@ -56,7 +58,8 @@ module Packwerk
|
|
56
58
|
end
|
57
59
|
|
58
60
|
def package_from_path(file_path)
|
59
|
-
|
61
|
+
path_string = file_path.to_s
|
62
|
+
@packages.values.find { |package| package.package_path?(path_string) }
|
60
63
|
end
|
61
64
|
end
|
62
65
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "benchmark"
|
5
|
+
require "parallel"
|
6
|
+
|
7
|
+
module Packwerk
|
8
|
+
class ParseRun
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
files:,
|
13
|
+
configuration:,
|
14
|
+
progress_formatter: Formatters::ProgressFormatter.new(StringIO.new),
|
15
|
+
offenses_formatter: Formatters::OffensesFormatter.new
|
16
|
+
)
|
17
|
+
@configuration = configuration
|
18
|
+
@progress_formatter = progress_formatter
|
19
|
+
@offenses_formatter = offenses_formatter
|
20
|
+
@files = files
|
21
|
+
end
|
22
|
+
|
23
|
+
def detect_stale_violations
|
24
|
+
offense_collection = find_offenses
|
25
|
+
|
26
|
+
result_status = !offense_collection.stale_violations?
|
27
|
+
message = if result_status
|
28
|
+
"No stale violations detected"
|
29
|
+
else
|
30
|
+
"There were stale violations found, please run `packwerk update-deprecations`"
|
31
|
+
end
|
32
|
+
|
33
|
+
Result.new(message: message, status: result_status)
|
34
|
+
end
|
35
|
+
|
36
|
+
def update_deprecations
|
37
|
+
offense_collection = find_offenses
|
38
|
+
offense_collection.dump_deprecated_references_files
|
39
|
+
|
40
|
+
message = <<~EOS
|
41
|
+
#{@offenses_formatter.show_offenses(offense_collection.errors)}
|
42
|
+
✅ `deprecated_references.yml` has been updated.
|
43
|
+
EOS
|
44
|
+
|
45
|
+
Result.new(message: message, status: offense_collection.errors.empty?)
|
46
|
+
end
|
47
|
+
|
48
|
+
def check
|
49
|
+
offense_collection = find_offenses(show_errors: true)
|
50
|
+
message = @offenses_formatter.show_offenses(offense_collection.outstanding_offenses)
|
51
|
+
Result.new(message: message, status: offense_collection.outstanding_offenses.empty?)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def find_offenses(show_errors: false)
|
57
|
+
offense_collection = OffenseCollection.new(@configuration.root_path)
|
58
|
+
@progress_formatter.started(@files)
|
59
|
+
|
60
|
+
run_context = Packwerk::RunContext.from_configuration(@configuration)
|
61
|
+
all_offenses = T.let([], T.untyped)
|
62
|
+
|
63
|
+
process_file = -> (path) do
|
64
|
+
run_context.process_file(file: path).tap do |offenses|
|
65
|
+
failed = show_errors && offenses.any? { |offense| !offense_collection.listed?(offense) }
|
66
|
+
update_progress(failed: failed)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
execution_time = Benchmark.realtime do
|
71
|
+
all_offenses = if @configuration.parallel?
|
72
|
+
Parallel.flat_map(@files, &process_file)
|
73
|
+
else
|
74
|
+
serial_find_offenses(&process_file)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
@progress_formatter.finished(execution_time)
|
79
|
+
|
80
|
+
all_offenses.each { |offense| offense_collection.add_offense(offense) }
|
81
|
+
offense_collection
|
82
|
+
end
|
83
|
+
|
84
|
+
def serial_find_offenses
|
85
|
+
all_offenses = T.let([], T.untyped)
|
86
|
+
@files.each do |path|
|
87
|
+
offenses = yield path
|
88
|
+
all_offenses.concat(offenses)
|
89
|
+
end
|
90
|
+
all_offenses
|
91
|
+
rescue Interrupt
|
92
|
+
@progress_formatter.interrupted
|
93
|
+
all_offenses
|
94
|
+
end
|
95
|
+
|
96
|
+
def update_progress(failed: false)
|
97
|
+
if failed
|
98
|
+
@progress_formatter.mark_as_failed
|
99
|
+
else
|
100
|
+
@progress_formatter.mark_as_inspected
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -3,8 +3,6 @@
|
|
3
3
|
|
4
4
|
require "ast/node"
|
5
5
|
|
6
|
-
require "packwerk/node"
|
7
|
-
|
8
6
|
module Packwerk
|
9
7
|
class ParsedConstantDefinitions
|
10
8
|
def initialize(root_node:)
|
@@ -28,8 +26,8 @@ module Packwerk
|
|
28
26
|
|
29
27
|
fully_qualified_constant_name = "::#{constant_name}"
|
30
28
|
|
31
|
-
possible_namespaces = namespace_path.
|
32
|
-
acc << acc.last
|
29
|
+
possible_namespaces = namespace_path.each_with_object([""]) do |current, acc|
|
30
|
+
acc << "#{acc.last}::#{current}" if acc.last && current
|
33
31
|
end
|
34
32
|
|
35
33
|
possible_namespaces.map { |namespace| namespace + fully_qualified_constant_name }
|
data/lib/packwerk/parsers.rb
CHANGED
data/lib/packwerk/parsers/erb.rb
CHANGED
@@ -6,8 +6,6 @@ require "better_html"
|
|
6
6
|
require "better_html/parser"
|
7
7
|
require "parser/source/buffer"
|
8
8
|
|
9
|
-
require "packwerk/parsers"
|
10
|
-
|
11
9
|
module Packwerk
|
12
10
|
module Parsers
|
13
11
|
class Erb
|
@@ -19,6 +17,10 @@ module Packwerk
|
|
19
17
|
def call(io:, file_path: "<unknown>")
|
20
18
|
buffer = Parser::Source::Buffer.new(file_path)
|
21
19
|
buffer.source = io.read
|
20
|
+
parse_buffer(buffer, file_path: file_path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_buffer(buffer, file_path:)
|
22
24
|
parser = @parser_class.new(buffer, template_language: :html)
|
23
25
|
to_ruby_ast(parser.ast, file_path)
|
24
26
|
rescue EncodingError => e
|
@@ -3,8 +3,6 @@
|
|
3
3
|
|
4
4
|
require "singleton"
|
5
5
|
|
6
|
-
require "packwerk/parsers"
|
7
|
-
|
8
6
|
module Packwerk
|
9
7
|
module Parsers
|
10
8
|
class Factory
|
@@ -26,9 +24,18 @@ module Packwerk
|
|
26
24
|
when RUBY_REGEX
|
27
25
|
@ruby_parser ||= Ruby.new
|
28
26
|
when ERB_REGEX
|
29
|
-
@erb_parser ||=
|
27
|
+
@erb_parser ||= erb_parser_class.new
|
30
28
|
end
|
31
29
|
end
|
30
|
+
|
31
|
+
def erb_parser_class
|
32
|
+
@erb_parser_class ||= Erb
|
33
|
+
end
|
34
|
+
|
35
|
+
def erb_parser_class=(klass)
|
36
|
+
@erb_parser_class = klass
|
37
|
+
@erb_parser = nil
|
38
|
+
end
|
32
39
|
end
|
33
40
|
end
|
34
41
|
end
|
@@ -1,46 +1,51 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "packwerk/violation_type"
|
5
|
-
require "packwerk/checker"
|
6
|
-
|
7
4
|
module Packwerk
|
8
5
|
class PrivacyChecker
|
6
|
+
extend T::Sig
|
9
7
|
include Checker
|
10
8
|
|
9
|
+
sig { override.returns(Packwerk::ViolationType) }
|
11
10
|
def violation_type
|
12
11
|
ViolationType::Privacy
|
13
12
|
end
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
sig do
|
15
|
+
override
|
16
|
+
.params(reference: Packwerk::Reference)
|
17
|
+
.returns(T::Boolean)
|
18
|
+
end
|
19
|
+
def invalid_reference?(reference)
|
20
|
+
return false if reference.constant.public?
|
17
21
|
|
18
22
|
privacy_option = reference.constant.package.enforce_privacy
|
19
|
-
return if enforcement_disabled?(privacy_option)
|
23
|
+
return false if enforcement_disabled?(privacy_option)
|
20
24
|
|
21
|
-
return unless privacy_option == true ||
|
25
|
+
return false unless privacy_option == true ||
|
22
26
|
explicitly_private_constant?(reference.constant, explicitly_private_constants: privacy_option)
|
23
27
|
|
24
|
-
return if reference_lister.listed?(reference, violation_type: violation_type)
|
25
|
-
|
26
28
|
true
|
27
29
|
end
|
28
30
|
|
29
|
-
def message_for(reference)
|
30
|
-
source_desc = reference.source_package ? "'#{reference.source_package}'" : "here"
|
31
|
-
"Privacy violation: '#{reference.constant.name}' is private to '#{reference.constant.package}' but " \
|
32
|
-
"referenced from #{source_desc}.\n" \
|
33
|
-
"Is there a public entrypoint in '#{reference.constant.package.public_path}' that you can use instead?"
|
34
|
-
end
|
35
|
-
|
36
31
|
private
|
37
32
|
|
33
|
+
sig do
|
34
|
+
params(
|
35
|
+
constant: ConstantDiscovery::ConstantContext,
|
36
|
+
explicitly_private_constants: T::Array[String]
|
37
|
+
).returns(T::Boolean)
|
38
|
+
end
|
38
39
|
def explicitly_private_constant?(constant, explicitly_private_constants:)
|
39
40
|
explicitly_private_constants.include?(constant.name) ||
|
40
41
|
# nested constants
|
41
42
|
explicitly_private_constants.any? { |epc| constant.name.start_with?(epc + "::") }
|
42
43
|
end
|
43
44
|
|
45
|
+
sig do
|
46
|
+
params(privacy_option: T.nilable(T.any(T::Boolean, T::Array[String])))
|
47
|
+
.returns(T::Boolean)
|
48
|
+
end
|
44
49
|
def enforcement_disabled?(privacy_option)
|
45
50
|
[false, nil].include?(privacy_option)
|
46
51
|
end
|
@@ -1,14 +1,6 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "sorbet-runtime"
|
5
|
-
|
6
|
-
require "packwerk/constant_discovery"
|
7
|
-
require "packwerk/constant_name_inspector"
|
8
|
-
require "packwerk/node"
|
9
|
-
require "packwerk/parsed_constant_definitions"
|
10
|
-
require "packwerk/reference"
|
11
|
-
|
12
4
|
module Packwerk
|
13
5
|
# extracts a possible constant reference from a given AST node
|
14
6
|
class ReferenceExtractor
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Packwerk
|
5
|
+
class ReferenceOffense < Offense
|
6
|
+
extend T::Sig
|
7
|
+
extend T::Helpers
|
8
|
+
|
9
|
+
attr_reader :reference, :violation_type
|
10
|
+
|
11
|
+
sig do
|
12
|
+
params(
|
13
|
+
reference: Packwerk::Reference,
|
14
|
+
violation_type: Packwerk::ViolationType,
|
15
|
+
location: T.nilable(Node::Location)
|
16
|
+
)
|
17
|
+
.void
|
18
|
+
end
|
19
|
+
def initialize(reference:, violation_type:, location: nil)
|
20
|
+
super(file: reference.relative_path, message: build_message(reference, violation_type), location: location)
|
21
|
+
@reference = reference
|
22
|
+
@violation_type = violation_type
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def build_message(reference, violation_type)
|
28
|
+
violation_message = case violation_type
|
29
|
+
when ViolationType::Privacy
|
30
|
+
source_desc = reference.source_package ? "'#{reference.source_package}'" : "here"
|
31
|
+
"Privacy violation: '#{reference.constant.name}' is private to '#{reference.constant.package}' but " \
|
32
|
+
"referenced from #{source_desc}.\n" \
|
33
|
+
"Is there a public entrypoint in '#{reference.constant.package.public_path}' that you can use instead?"
|
34
|
+
when ViolationType::Dependency
|
35
|
+
"Dependency violation: #{reference.constant.name} belongs to '#{reference.constant.package}', but " \
|
36
|
+
"'#{reference.source_package}' does not specify a dependency on " \
|
37
|
+
"'#{reference.constant.package}'.\n" \
|
38
|
+
"Are we missing an abstraction?\n" \
|
39
|
+
"Is the code making the reference, and the referenced constant, in the right packages?\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
<<~EOS
|
43
|
+
#{violation_message}
|
44
|
+
Inference details: this is a reference to #{reference.constant.name} which seems to be defined in #{reference.constant.location}.
|
45
|
+
To receive help interpreting or resolving this error message, see: https://github.com/Shopify/packwerk/blob/main/TROUBLESHOOT.md#Troubleshooting-violations
|
46
|
+
EOS
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/packwerk/run_context.rb
CHANGED
@@ -3,17 +3,6 @@
|
|
3
3
|
|
4
4
|
require "constant_resolver"
|
5
5
|
|
6
|
-
require "packwerk/association_inspector"
|
7
|
-
require "packwerk/constant_discovery"
|
8
|
-
require "packwerk/const_node_inspector"
|
9
|
-
require "packwerk/dependency_checker"
|
10
|
-
require "packwerk/file_processor"
|
11
|
-
require "packwerk/inflector"
|
12
|
-
require "packwerk/package_set"
|
13
|
-
require "packwerk/privacy_checker"
|
14
|
-
require "packwerk/reference_extractor"
|
15
|
-
require "packwerk/node_processor_factory"
|
16
|
-
|
17
6
|
module Packwerk
|
18
7
|
class RunContext
|
19
8
|
extend T::Sig
|
@@ -25,7 +14,6 @@ module Packwerk
|
|
25
14
|
:inflector,
|
26
15
|
:custom_associations,
|
27
16
|
:checker_classes,
|
28
|
-
:reference_lister,
|
29
17
|
)
|
30
18
|
|
31
19
|
DEFAULT_CHECKERS = [
|
@@ -34,15 +22,14 @@ module Packwerk
|
|
34
22
|
]
|
35
23
|
|
36
24
|
class << self
|
37
|
-
def from_configuration(configuration
|
25
|
+
def from_configuration(configuration)
|
38
26
|
inflector = ::Packwerk::Inflector.from_file(configuration.inflections_file)
|
39
27
|
new(
|
40
28
|
root_path: configuration.root_path,
|
41
29
|
load_paths: configuration.load_paths,
|
42
30
|
package_paths: configuration.package_paths,
|
43
31
|
inflector: inflector,
|
44
|
-
custom_associations: configuration.custom_associations
|
45
|
-
reference_lister: reference_lister,
|
32
|
+
custom_associations: configuration.custom_associations
|
46
33
|
)
|
47
34
|
end
|
48
35
|
end
|
@@ -53,8 +40,7 @@ module Packwerk
|
|
53
40
|
package_paths: nil,
|
54
41
|
inflector: nil,
|
55
42
|
custom_associations: [],
|
56
|
-
checker_classes: DEFAULT_CHECKERS
|
57
|
-
reference_lister:
|
43
|
+
checker_classes: DEFAULT_CHECKERS
|
58
44
|
)
|
59
45
|
@root_path = root_path
|
60
46
|
@load_paths = load_paths
|
@@ -62,7 +48,6 @@ module Packwerk
|
|
62
48
|
@inflector = inflector
|
63
49
|
@custom_associations = custom_associations
|
64
50
|
@checker_classes = checker_classes
|
65
|
-
@reference_lister = reference_lister
|
66
51
|
end
|
67
52
|
|
68
53
|
sig { params(file: String).returns(T::Array[T.nilable(::Packwerk::Offense)]) }
|
@@ -83,8 +68,7 @@ module Packwerk
|
|
83
68
|
context_provider: context_provider,
|
84
69
|
checkers: checkers,
|
85
70
|
root_path: root_path,
|
86
|
-
constant_name_inspectors: constant_name_inspectors
|
87
|
-
reference_lister: reference_lister
|
71
|
+
constant_name_inspectors: constant_name_inspectors
|
88
72
|
)
|
89
73
|
end
|
90
74
|
|