packwerk 1.0.2 → 1.1.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/Gemfile.lock +1 -1
- data/USAGE.md +22 -1
- data/lib/packwerk/application_validator.rb +3 -3
- data/lib/packwerk/cache_deprecated_references.rb +47 -0
- data/lib/packwerk/cli.rb +21 -10
- data/lib/packwerk/commands/detect_stale_violations_command.rb +63 -0
- data/lib/packwerk/commands/offense_progress_marker.rb +24 -0
- data/lib/packwerk/deprecated_references.rb +19 -0
- data/lib/packwerk/detect_stale_deprecated_references.rb +14 -0
- data/lib/packwerk/package_set.rb +6 -2
- data/lib/packwerk/parsers/erb.rb +4 -0
- data/lib/packwerk/parsers/factory.rb +10 -1
- data/lib/packwerk/run_context.rb +2 -1
- data/lib/packwerk/updating_deprecated_references.rb +2 -39
- data/lib/packwerk/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91ec92f15d9d87fa8c54861afd424fe6149ef8f8e05f114b6ee04559fa6053fc
|
4
|
+
data.tar.gz: b83cc17ff9cd7d2d37db4456017d429b4a8f8e45766cdfa4551ace2e32c58183
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 596f4f1a6b026e96ab6299e9ba7ceb63b7d709bd49c0629390f50e62e751174e4a92557243bef3a8f7f36aaf416e54fbf1fdb9f368fc2e478eb033e208358dc6
|
7
|
+
data.tar.gz: fdca4107315ea6140d7b92e5cd7b53216a73f65fac4c1c3147c798a1d407f75d3898b31517bec6bf2452e7ca0a3d1ad87599142250cf75684ccc9a48436bcd91
|
data/Gemfile.lock
CHANGED
data/USAGE.md
CHANGED
@@ -63,10 +63,31 @@ Packwerk reads from the `packwerk.yml` configuration file in the root directory.
|
|
63
63
|
|----------------------|-------------------------------------------|--------------|
|
64
64
|
| include | **/*.{rb,rake,erb} | list of patterns for folder paths to include |
|
65
65
|
| exclude | {bin,node_modules,script,tmp,vendor}/**/* | list of patterns for folder paths to exclude |
|
66
|
-
| package_paths | **/ | patterns to find package configuration files, see: Defining packages |
|
66
|
+
| package_paths | **/ | a single pattern or a list of patterns to find package configuration files, see: [Defining packages](#Defining-packages) |
|
67
67
|
| load_paths | All application autoload paths | list of load paths |
|
68
68
|
| custom_associations | N/A | list of custom associations, if any |
|
69
69
|
|
70
|
+
### Using a custom ERB parser
|
71
|
+
|
72
|
+
You can specify a custom ERB parser if needed. For example, if you're using `<%graphql>` tags from https://github.com/github/graphql-client in your ERBs, you can use a custom parser subclass to comment them out so that Packwerk can parse the rest of the file:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
class CustomParser < Packwerk::Parsers::Erb
|
76
|
+
def parse_buffer(buffer, file_path:)
|
77
|
+
preprocessed_source = buffer.source
|
78
|
+
|
79
|
+
# Comment out <%graphql ... %> tags. They won't contain any object
|
80
|
+
# references anyways.
|
81
|
+
preprocessed_source = preprocessed_source.gsub(/<%graphql/, "<%#")
|
82
|
+
|
83
|
+
preprocessed_buffer = Parser::Source::Buffer.new(file_path)
|
84
|
+
preprocessed_buffer.source = preprocessed_source
|
85
|
+
super(preprocessed_buffer, file_path: file_path)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Packwerk::Parsers::Factory.instance.erb_parser_class = CustomParser
|
90
|
+
```
|
70
91
|
|
71
92
|
### Inflections
|
72
93
|
|
@@ -32,7 +32,7 @@ module Packwerk
|
|
32
32
|
check_acyclic_graph,
|
33
33
|
check_package_manifest_paths,
|
34
34
|
check_valid_package_dependencies,
|
35
|
-
|
35
|
+
check_root_package_exists,
|
36
36
|
]
|
37
37
|
|
38
38
|
results.reject!(&:ok?)
|
@@ -207,7 +207,7 @@ module Packwerk
|
|
207
207
|
end
|
208
208
|
|
209
209
|
def check_acyclic_graph
|
210
|
-
packages = Packwerk::PackageSet.load_all_from(
|
210
|
+
packages = Packwerk::PackageSet.load_all_from(@configuration.root_path)
|
211
211
|
|
212
212
|
edges = packages.flat_map do |package|
|
213
213
|
package.dependencies.map { |dependency| [package, packages.fetch(dependency)] }
|
@@ -297,7 +297,7 @@ module Packwerk
|
|
297
297
|
end
|
298
298
|
end
|
299
299
|
|
300
|
-
def
|
300
|
+
def check_root_package_exists
|
301
301
|
root_package_path = File.join(@configuration.root_path, "package.yml")
|
302
302
|
all_packages_manifests = package_manifests(package_glob)
|
303
303
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
6
|
+
require "packwerk/deprecated_references"
|
7
|
+
require "packwerk/reference"
|
8
|
+
require "packwerk/reference_lister"
|
9
|
+
require "packwerk/violation_type"
|
10
|
+
|
11
|
+
module Packwerk
|
12
|
+
class CacheDeprecatedReferences
|
13
|
+
extend T::Sig
|
14
|
+
extend T::Helpers
|
15
|
+
include ReferenceLister
|
16
|
+
abstract!
|
17
|
+
|
18
|
+
def initialize(root_path, deprecated_references = {})
|
19
|
+
@root_path = root_path
|
20
|
+
@deprecated_references = T.let(deprecated_references, T::Hash[String, Packwerk::DeprecatedReferences])
|
21
|
+
end
|
22
|
+
|
23
|
+
sig do
|
24
|
+
params(reference: Packwerk::Reference, violation_type: ViolationType)
|
25
|
+
.returns(T::Boolean)
|
26
|
+
.override
|
27
|
+
end
|
28
|
+
def listed?(reference, violation_type:)
|
29
|
+
deprecated_references = deprecated_references_for(reference.source_package)
|
30
|
+
deprecated_references.add_entries(reference, violation_type.serialize)
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def deprecated_references_for(package)
|
37
|
+
@deprecated_references[package] ||= Packwerk::DeprecatedReferences.new(
|
38
|
+
package,
|
39
|
+
deprecated_references_file_for(package),
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def deprecated_references_file_for(package)
|
44
|
+
File.join(@root_path, package.name, "deprecated_references.yml")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/packwerk/cli.rb
CHANGED
@@ -12,10 +12,13 @@ require "packwerk/output_styles"
|
|
12
12
|
require "packwerk/run_context"
|
13
13
|
require "packwerk/updating_deprecated_references"
|
14
14
|
require "packwerk/checking_deprecated_references"
|
15
|
+
require "packwerk/commands/detect_stale_violations_command"
|
16
|
+
require "packwerk/commands/offense_progress_marker"
|
15
17
|
|
16
18
|
module Packwerk
|
17
19
|
class Cli
|
18
20
|
extend T::Sig
|
21
|
+
include OffenseProgressMarker
|
19
22
|
|
20
23
|
def initialize(run_context: nil, configuration: nil, out: $stdout, err_out: $stderr, style: OutputStyles::Plain)
|
21
24
|
@out = out
|
@@ -45,6 +48,8 @@ module Packwerk
|
|
45
48
|
generate_configs
|
46
49
|
when "check"
|
47
50
|
check(args)
|
51
|
+
when "detect-stale-violations"
|
52
|
+
detect_stale_violations(args)
|
48
53
|
when "update"
|
49
54
|
update(args)
|
50
55
|
when "update-deprecations"
|
@@ -142,7 +147,9 @@ module Packwerk
|
|
142
147
|
all_offenses = T.let([], T.untyped)
|
143
148
|
execution_time = Benchmark.realtime do
|
144
149
|
all_offenses = files.flat_map do |path|
|
145
|
-
@run_context.process_file(file: path).tap
|
150
|
+
@run_context.process_file(file: path).tap do |offenses|
|
151
|
+
mark_progress(offenses: offenses, progress_formatter: @progress_formatter)
|
152
|
+
end
|
146
153
|
end
|
147
154
|
|
148
155
|
updating_deprecated_references.dump_deprecated_references_files
|
@@ -165,7 +172,7 @@ module Packwerk
|
|
165
172
|
execution_time = Benchmark.realtime do
|
166
173
|
files.each do |path|
|
167
174
|
@run_context.process_file(file: path).tap do |offenses|
|
168
|
-
mark_progress(offenses)
|
175
|
+
mark_progress(offenses: offenses, progress_formatter: @progress_formatter)
|
169
176
|
all_offenses.concat(offenses)
|
170
177
|
end
|
171
178
|
end
|
@@ -181,6 +188,18 @@ module Packwerk
|
|
181
188
|
all_offenses.empty?
|
182
189
|
end
|
183
190
|
|
191
|
+
def detect_stale_violations(paths)
|
192
|
+
detect_stale_violations = DetectStaleViolationsCommand.new(
|
193
|
+
files: fetch_files_to_process(paths),
|
194
|
+
configuration: @configuration,
|
195
|
+
progress_formatter: @progress_formatter
|
196
|
+
)
|
197
|
+
result = detect_stale_violations.run
|
198
|
+
@out.puts
|
199
|
+
@out.puts(result.message)
|
200
|
+
result.status
|
201
|
+
end
|
202
|
+
|
184
203
|
def fetch_files_to_process(paths)
|
185
204
|
files = FilesForProcessing.fetch(paths: paths, configuration: @configuration)
|
186
205
|
abort("No files found or given. "\
|
@@ -188,14 +207,6 @@ module Packwerk
|
|
188
207
|
files
|
189
208
|
end
|
190
209
|
|
191
|
-
def mark_progress(offenses)
|
192
|
-
if offenses.empty?
|
193
|
-
@progress_formatter.mark_as_inspected
|
194
|
-
else
|
195
|
-
@progress_formatter.mark_as_failed
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
210
|
def validate(_paths)
|
200
211
|
warn("`packwerk validate` should be run within the application. "\
|
201
212
|
"Generate the bin script using `packwerk init` and"\
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require "packwerk/cli"
|
4
|
+
require "sorbet-runtime"
|
5
|
+
require "benchmark"
|
6
|
+
require "packwerk/configuration"
|
7
|
+
require "packwerk/formatters/progress_formatter"
|
8
|
+
require "packwerk/run_context"
|
9
|
+
require "packwerk/detect_stale_deprecated_references"
|
10
|
+
require "packwerk/commands/offense_progress_marker"
|
11
|
+
|
12
|
+
module Packwerk
|
13
|
+
class DetectStaleViolationsCommand
|
14
|
+
extend T::Sig
|
15
|
+
include OffenseProgressMarker
|
16
|
+
Result = Struct.new(:message, :status)
|
17
|
+
|
18
|
+
def initialize(files:, configuration:, run_context: nil, progress_formatter: nil, reference_lister: nil)
|
19
|
+
@configuration = configuration
|
20
|
+
@run_context = run_context
|
21
|
+
@reference_lister = reference_lister
|
22
|
+
@progress_formatter = progress_formatter
|
23
|
+
@files = files
|
24
|
+
end
|
25
|
+
|
26
|
+
sig { returns(Result) }
|
27
|
+
def run
|
28
|
+
@progress_formatter.started(@files)
|
29
|
+
|
30
|
+
all_offenses = T.let([], T.untyped)
|
31
|
+
execution_time = Benchmark.realtime do
|
32
|
+
all_offenses = @files.flat_map do |path|
|
33
|
+
run_context.process_file(file: path).tap do |offenses|
|
34
|
+
mark_progress(offenses: offenses, progress_formatter: @progress_formatter)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
@progress_formatter.finished(execution_time)
|
40
|
+
calculate_result
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def run_context
|
46
|
+
@run_context ||= Packwerk::RunContext.from_configuration(@configuration, reference_lister: reference_lister)
|
47
|
+
end
|
48
|
+
|
49
|
+
def reference_lister
|
50
|
+
@reference_lister ||= ::Packwerk::DetectStaleDeprecatedReferences.new(@configuration.root_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
sig { returns Result }
|
54
|
+
def calculate_result
|
55
|
+
result_status = !reference_lister.stale_violations?
|
56
|
+
message = "There were stale violations found, please run `packwerk update`"
|
57
|
+
if result_status
|
58
|
+
message = "No stale violations detected"
|
59
|
+
end
|
60
|
+
Result.new(message, result_status)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
require "sorbet-runtime"
|
4
|
+
require "packwerk/formatters/progress_formatter"
|
5
|
+
|
6
|
+
module Packwerk
|
7
|
+
module OffenseProgressMarker
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
sig do
|
11
|
+
params(
|
12
|
+
offenses: T::Array[T.nilable(::Packwerk::Offense)],
|
13
|
+
progress_formatter: ::Packwerk::Formatters::ProgressFormatter
|
14
|
+
).void
|
15
|
+
end
|
16
|
+
def mark_progress(offenses:, progress_formatter:)
|
17
|
+
if offenses.empty?
|
18
|
+
progress_formatter.mark_as_inspected
|
19
|
+
else
|
20
|
+
progress_formatter.mark_as_failed
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require "sorbet-runtime"
|
5
5
|
require "yaml"
|
6
|
+
require "sorbet-runtime"
|
6
7
|
|
7
8
|
require "packwerk/reference"
|
8
9
|
require "packwerk/reference_lister"
|
@@ -47,6 +48,24 @@ module Packwerk
|
|
47
48
|
@new_entries[reference.constant.package.name] = package_violations
|
48
49
|
end
|
49
50
|
|
51
|
+
sig { returns(T::Boolean) }
|
52
|
+
def stale_violations?
|
53
|
+
prepare_entries_for_dump
|
54
|
+
deprecated_references.any? do |package, package_violations|
|
55
|
+
package_violations.any? do |constant_name, entries_for_file|
|
56
|
+
new_entries_violation_types = @new_entries.dig(package, constant_name, "violations")
|
57
|
+
return true if new_entries_violation_types.nil?
|
58
|
+
if entries_for_file["violations"].all? { |type| new_entries_violation_types.include?(type) }
|
59
|
+
stale_violations =
|
60
|
+
entries_for_file["files"] - Array(@new_entries.dig(package, constant_name, "files"))
|
61
|
+
stale_violations.present?
|
62
|
+
else
|
63
|
+
return true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
50
69
|
def dump
|
51
70
|
if @new_entries.empty?
|
52
71
|
File.delete(@filepath) if File.exist?(@filepath)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "packwerk/cache_deprecated_references"
|
5
|
+
|
6
|
+
module Packwerk
|
7
|
+
class DetectStaleDeprecatedReferences < CacheDeprecatedReferences
|
8
|
+
extend T::Sig
|
9
|
+
sig { returns(T::Boolean) }
|
10
|
+
def stale_violations?
|
11
|
+
@deprecated_references.values.any?(&:stale_violations?)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/packwerk/package_set.rb
CHANGED
@@ -28,8 +28,12 @@ module Packwerk
|
|
28
28
|
def package_paths(root_path, package_pathspec)
|
29
29
|
bundle_path_match = Bundler.bundle_path.join("**").to_s
|
30
30
|
|
31
|
-
|
32
|
-
.
|
31
|
+
glob_patterns = Array(package_pathspec).map do |pathspec|
|
32
|
+
File.join(root_path, pathspec, PACKAGE_CONFIG_FILENAME)
|
33
|
+
end
|
34
|
+
|
35
|
+
Dir.glob(glob_patterns)
|
36
|
+
.map { |path| Pathname.new(path).cleanpath }
|
33
37
|
.reject { |path| path.realpath.fnmatch(bundle_path_match) }
|
34
38
|
end
|
35
39
|
|
data/lib/packwerk/parsers/erb.rb
CHANGED
@@ -19,6 +19,10 @@ module Packwerk
|
|
19
19
|
def call(io:, file_path: "<unknown>")
|
20
20
|
buffer = Parser::Source::Buffer.new(file_path)
|
21
21
|
buffer.source = io.read
|
22
|
+
parse_buffer(buffer, file_path: file_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_buffer(buffer, file_path:)
|
22
26
|
parser = @parser_class.new(buffer, template_language: :html)
|
23
27
|
to_ruby_ast(parser.ast, file_path)
|
24
28
|
rescue EncodingError => e
|
@@ -26,9 +26,18 @@ module Packwerk
|
|
26
26
|
when RUBY_REGEX
|
27
27
|
@ruby_parser ||= Ruby.new
|
28
28
|
when ERB_REGEX
|
29
|
-
@erb_parser ||=
|
29
|
+
@erb_parser ||= erb_parser_class.new
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
def erb_parser_class
|
34
|
+
@erb_parser_class || Erb
|
35
|
+
end
|
36
|
+
|
37
|
+
def erb_parser_class=(klass)
|
38
|
+
@erb_parser_class = klass
|
39
|
+
@erb_parser = nil
|
40
|
+
end
|
32
41
|
end
|
33
42
|
end
|
34
43
|
end
|
data/lib/packwerk/run_context.rb
CHANGED
@@ -1,51 +1,14 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "
|
5
|
-
|
6
|
-
require "packwerk/deprecated_references"
|
7
|
-
require "packwerk/reference"
|
8
|
-
require "packwerk/reference_lister"
|
9
|
-
require "packwerk/violation_type"
|
4
|
+
require "packwerk/cache_deprecated_references"
|
10
5
|
|
11
6
|
module Packwerk
|
12
|
-
class UpdatingDeprecatedReferences
|
13
|
-
extend T::Sig
|
14
|
-
include ReferenceLister
|
15
|
-
|
16
|
-
def initialize(root_path, deprecated_references = {})
|
17
|
-
@root_path = root_path
|
18
|
-
@deprecated_references = deprecated_references
|
19
|
-
end
|
20
|
-
|
21
|
-
sig do
|
22
|
-
params(reference: Packwerk::Reference, violation_type: ViolationType)
|
23
|
-
.returns(T::Boolean)
|
24
|
-
.override
|
25
|
-
end
|
26
|
-
def listed?(reference, violation_type:)
|
27
|
-
deprecated_references = deprecated_references_for(reference.source_package)
|
28
|
-
deprecated_references.add_entries(reference, violation_type.serialize)
|
29
|
-
true
|
30
|
-
end
|
31
|
-
|
7
|
+
class UpdatingDeprecatedReferences < CacheDeprecatedReferences
|
32
8
|
def dump_deprecated_references_files
|
33
9
|
@deprecated_references.each do |_, deprecated_references_file|
|
34
10
|
deprecated_references_file.dump
|
35
11
|
end
|
36
12
|
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def deprecated_references_for(package)
|
41
|
-
@deprecated_references[package] ||= Packwerk::DeprecatedReferences.new(
|
42
|
-
package,
|
43
|
-
deprecated_references_file_for(package),
|
44
|
-
)
|
45
|
-
end
|
46
|
-
|
47
|
-
def deprecated_references_file_for(package)
|
48
|
-
File.join(@root_path, package.name, "deprecated_references.yml")
|
49
|
-
end
|
50
13
|
end
|
51
14
|
end
|
data/lib/packwerk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packwerk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -186,15 +186,19 @@ files:
|
|
186
186
|
- lib/packwerk/application_load_paths.rb
|
187
187
|
- lib/packwerk/application_validator.rb
|
188
188
|
- lib/packwerk/association_inspector.rb
|
189
|
+
- lib/packwerk/cache_deprecated_references.rb
|
189
190
|
- lib/packwerk/checker.rb
|
190
191
|
- lib/packwerk/checking_deprecated_references.rb
|
191
192
|
- lib/packwerk/cli.rb
|
193
|
+
- lib/packwerk/commands/detect_stale_violations_command.rb
|
194
|
+
- lib/packwerk/commands/offense_progress_marker.rb
|
192
195
|
- lib/packwerk/configuration.rb
|
193
196
|
- lib/packwerk/const_node_inspector.rb
|
194
197
|
- lib/packwerk/constant_discovery.rb
|
195
198
|
- lib/packwerk/constant_name_inspector.rb
|
196
199
|
- lib/packwerk/dependency_checker.rb
|
197
200
|
- lib/packwerk/deprecated_references.rb
|
201
|
+
- lib/packwerk/detect_stale_deprecated_references.rb
|
198
202
|
- lib/packwerk/file_processor.rb
|
199
203
|
- lib/packwerk/files_for_processing.rb
|
200
204
|
- lib/packwerk/formatters/progress_formatter.rb
|