use_packwerk 0.54.0 → 0.56.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/lib/use_packwerk/cli.rb +10 -10
- data/lib/use_packwerk/code_ownership_post_processor.rb +3 -3
- data/lib/use_packwerk/configuration.rb +18 -14
- data/lib/use_packwerk/default_user_event_logger.rb +7 -0
- data/lib/use_packwerk/logging.rb +1 -2
- data/lib/use_packwerk/per_file_processor_interface.rb +1 -2
- data/lib/use_packwerk/private/file_move_operation.rb +9 -11
- data/lib/use_packwerk/private/pack_relationship_analyzer.rb +24 -108
- data/lib/use_packwerk/private.rb +117 -155
- data/lib/use_packwerk/rubocop_post_processor.rb +17 -17
- data/lib/use_packwerk/user_event_logger.rb +265 -0
- data/lib/use_packwerk.rb +28 -74
- metadata +49 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f2315b30561bd988826f08430f4bcecade3056549d1c78069dcbd72cd8aa90b
|
4
|
+
data.tar.gz: 2d8cb765865b07158ffb0dd6e7e30765e66e93912b49ccb63ede8e0e6116b41c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03d1a533f3323bad78ddef6843a3bcf996cb6390f71feeafdc7844baed5af13ee18ebe558b98c5e4fea89240f0f7645732ca90d73a555e78630758e90d04424a
|
7
|
+
data.tar.gz: 1cada76edf9ec7c76b343946c8c6373d1eaeb665312b226a7a2fecc2facca855c42a0b18d08f847722663f16799aca20383da82ef0f866bc962260652183d373
|
data/lib/use_packwerk/cli.rb
CHANGED
@@ -6,13 +6,13 @@ module UsePackwerk
|
|
6
6
|
class CLI < Thor
|
7
7
|
extend T::Sig
|
8
8
|
|
9
|
-
desc
|
9
|
+
desc 'create packs/your_pack', 'Create pack with name packs/your_pack'
|
10
10
|
sig { params(pack_name: String).void }
|
11
11
|
def create(pack_name)
|
12
12
|
UsePackwerk.create_pack!(pack_name: pack_name)
|
13
13
|
end
|
14
14
|
|
15
|
-
desc
|
15
|
+
desc 'add_dependency packs/from_pack packs/to_pack', 'Add packs/to_pack to packs/from_pack/package.yml list of dependencies'
|
16
16
|
long_desc <<~LONG_DESC
|
17
17
|
Use this to add a dependency between packs.
|
18
18
|
|
@@ -29,7 +29,7 @@ module UsePackwerk
|
|
29
29
|
)
|
30
30
|
end
|
31
31
|
|
32
|
-
desc
|
32
|
+
desc 'list_top_dependency_violations packs/your_pack', 'List the top dependency violations of packs/your_pack'
|
33
33
|
option :limit, type: :numeric, default: 10, aliases: :l, banner: 'Specify the limit of constants to analyze'
|
34
34
|
sig { params(pack_name: String).void }
|
35
35
|
def list_top_dependency_violations(pack_name)
|
@@ -39,7 +39,7 @@ module UsePackwerk
|
|
39
39
|
)
|
40
40
|
end
|
41
41
|
|
42
|
-
desc
|
42
|
+
desc 'list_top_privacy_violations packs/your_pack', 'List the top privacy violations of packs/your_pack'
|
43
43
|
option :limit, type: :numeric, default: 10, aliases: :l, banner: 'Specify the limit of constants to analyze'
|
44
44
|
sig { params(pack_name: String).void }
|
45
45
|
def list_top_privacy_violations(pack_name)
|
@@ -49,32 +49,32 @@ module UsePackwerk
|
|
49
49
|
)
|
50
50
|
end
|
51
51
|
|
52
|
-
desc
|
52
|
+
desc 'make_public path/to/file.rb path/to/directory', 'Pass in a space-separated list of file or directory paths to make public'
|
53
53
|
sig { params(paths: String).void }
|
54
54
|
def make_public(*paths)
|
55
55
|
UsePackwerk.make_public!(
|
56
56
|
paths_relative_to_root: paths,
|
57
|
-
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
57
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
58
58
|
)
|
59
59
|
end
|
60
60
|
|
61
|
-
desc
|
61
|
+
desc 'move packs/destination_pack path/to/file.rb path/to/directory', 'Pass in a destination pack and a space-separated list of file or directory paths to move to the destination pack'
|
62
62
|
sig { params(pack_name: String, paths: String).void }
|
63
63
|
def move(pack_name, *paths)
|
64
64
|
UsePackwerk.move_to_pack!(
|
65
65
|
pack_name: pack_name,
|
66
66
|
paths_relative_to_root: paths,
|
67
|
-
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
67
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
68
68
|
)
|
69
69
|
end
|
70
70
|
|
71
|
-
desc
|
71
|
+
desc 'move_to_parent packs/parent_pack packs/child_pack', 'Pass in a parent pack and another pack to be made as a child to the parent pack!'
|
72
72
|
sig { params(parent_name: String, pack_name: String).void }
|
73
73
|
def move_to_parent(parent_name, pack_name)
|
74
74
|
UsePackwerk.move_to_parent!(
|
75
75
|
parent_name: parent_name,
|
76
76
|
pack_name: pack_name,
|
77
|
-
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
77
|
+
per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new]
|
78
78
|
)
|
79
79
|
end
|
80
80
|
end
|
@@ -22,7 +22,7 @@ module UsePackwerk
|
|
22
22
|
UsePackwerk.replace_in_file(
|
23
23
|
file: code_owners_allow_list_file.to_s,
|
24
24
|
find: relative_path_to_origin,
|
25
|
-
replace_with: relative_path_to_destination
|
25
|
+
replace_with: relative_path_to_destination
|
26
26
|
)
|
27
27
|
end
|
28
28
|
|
@@ -45,11 +45,11 @@ module UsePackwerk
|
|
45
45
|
if @teams.any?
|
46
46
|
Logging.section('Code Ownership') do
|
47
47
|
Logging.print('This section contains info about the current ownership distribution of the moved files.')
|
48
|
-
@teams.group_by { |team| team }.sort_by { |
|
48
|
+
@teams.group_by { |team| team }.sort_by { |_team, instances| -instances.count }.each do |team, instances|
|
49
49
|
Logging.print " #{team} - #{instances.count} files"
|
50
50
|
end
|
51
51
|
if @did_move_files
|
52
|
-
Logging.print
|
52
|
+
Logging.print 'Since the destination package has package-based ownership, file-annotations were removed from moved files.'
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# typed: strict
|
2
2
|
|
3
|
+
require 'use_packwerk/user_event_logger'
|
4
|
+
require 'use_packwerk/default_user_event_logger'
|
5
|
+
|
3
6
|
module UsePackwerk
|
4
7
|
class Configuration
|
5
8
|
extend T::Sig
|
@@ -7,28 +10,28 @@ module UsePackwerk
|
|
7
10
|
sig { params(enforce_dependencies: T::Boolean).void }
|
8
11
|
attr_writer :enforce_dependencies
|
9
12
|
|
10
|
-
sig {
|
11
|
-
|
13
|
+
sig { returns(UserEventLogger) }
|
14
|
+
attr_accessor :user_event_logger
|
12
15
|
|
13
16
|
sig { void }
|
14
17
|
def initialize
|
15
|
-
@enforce_dependencies = T.let(
|
16
|
-
@
|
18
|
+
@enforce_dependencies = T.let(default_enforce_dependencies, T::Boolean)
|
19
|
+
@user_event_logger = T.let(DefaultUserEventLogger.new, UserEventLogger)
|
17
20
|
end
|
18
21
|
|
19
22
|
sig { returns(T::Boolean) }
|
20
23
|
def enforce_dependencies
|
21
|
-
|
22
|
-
@enforce_dependencies
|
23
|
-
else
|
24
|
-
true
|
25
|
-
end
|
24
|
+
@enforce_dependencies
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
sig { void }
|
28
|
+
def bust_cache!
|
29
|
+
@enforce_dependencies = default_enforce_dependencies
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { returns(T::Boolean) }
|
33
|
+
def default_enforce_dependencies
|
34
|
+
true
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
@@ -37,12 +40,13 @@ module UsePackwerk
|
|
37
40
|
|
38
41
|
sig { returns(Configuration) }
|
39
42
|
def config
|
43
|
+
Private.load_client_configuration
|
40
44
|
@config = T.let(@config, T.nilable(Configuration))
|
41
45
|
@config ||= Configuration.new
|
42
46
|
end
|
43
47
|
|
44
48
|
sig { params(blk: T.proc.params(arg0: Configuration).void).void }
|
45
|
-
def configure(&blk)
|
49
|
+
def configure(&blk)
|
46
50
|
yield(config)
|
47
51
|
end
|
48
52
|
end
|
data/lib/use_packwerk/logging.rb
CHANGED
@@ -9,7 +9,7 @@ module UsePackwerk
|
|
9
9
|
sig { params(title: String, block: T.proc.void).void }
|
10
10
|
def self.section(title, &block)
|
11
11
|
print_divider
|
12
|
-
out ColorizedString.new(
|
12
|
+
out ColorizedString.new(title).green.bold
|
13
13
|
out "\n"
|
14
14
|
yield
|
15
15
|
end
|
@@ -35,4 +35,3 @@ module UsePackwerk
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
@@ -8,8 +8,7 @@ module UsePackwerk
|
|
8
8
|
abstract!
|
9
9
|
|
10
10
|
sig { abstract.params(file_move_operation: Private::FileMoveOperation).void }
|
11
|
-
def before_move_file!(file_move_operation)
|
12
|
-
end
|
11
|
+
def before_move_file!(file_move_operation); end
|
13
12
|
|
14
13
|
sig { void }
|
15
14
|
def print_final_message!
|
@@ -18,7 +18,6 @@ module UsePackwerk
|
|
18
18
|
def self.destination_pathname_for_package_move(origin_pathname, new_package_root)
|
19
19
|
origin_pack = T.must(ParsePackwerk.package_from_path(origin_pathname))
|
20
20
|
|
21
|
-
new_implementation = nil
|
22
21
|
if origin_pack.name == ParsePackwerk::ROOT_PACKAGE_NAME
|
23
22
|
new_package_root.join(origin_pathname).cleanpath
|
24
23
|
else
|
@@ -28,7 +27,6 @@ module UsePackwerk
|
|
28
27
|
|
29
28
|
sig { params(origin_pathname: Pathname).returns(Pathname) }
|
30
29
|
def self.destination_pathname_for_new_public_api(origin_pathname)
|
31
|
-
|
32
30
|
origin_pack = T.must(ParsePackwerk.package_from_path(origin_pathname))
|
33
31
|
if origin_pack.name == ParsePackwerk::ROOT_PACKAGE_NAME
|
34
32
|
filepath_without_pack_name = origin_pathname.to_s
|
@@ -37,15 +35,15 @@ module UsePackwerk
|
|
37
35
|
end
|
38
36
|
|
39
37
|
# We join the pack name with the rest of the path...
|
40
|
-
path_parts = filepath_without_pack_name.split(
|
38
|
+
path_parts = filepath_without_pack_name.split('/')
|
41
39
|
Pathname.new(origin_pack.name).join(
|
42
40
|
# ... keeping the "app" or "spec"
|
43
41
|
T.must(path_parts[0]),
|
44
42
|
# ... substituting "controllers," "services," etc. with "public"
|
45
43
|
'public',
|
46
44
|
# ... then the rest is the same
|
47
|
-
T.must(path_parts[2..]).join(
|
48
|
-
|
45
|
+
T.must(path_parts[2..]).join('/')
|
46
|
+
# and we take the cleanpath so `./app/...` becomes `app/...`
|
49
47
|
).cleanpath
|
50
48
|
end
|
51
49
|
|
@@ -54,16 +52,16 @@ module UsePackwerk
|
|
54
52
|
# This could probably be implemented by some "strategy pattern" where different extension types are handled by different helpers
|
55
53
|
# Such a thing could also include, for example, when moving a controller, moving its ERB view too.
|
56
54
|
if origin_pathname.extname == '.rake'
|
57
|
-
new_origin_pathname = origin_pathname.sub('/lib/', '/spec/lib/').sub(
|
58
|
-
new_destination_pathname = destination_pathname.sub('/lib/', '/spec/lib/').sub(
|
55
|
+
new_origin_pathname = origin_pathname.sub('/lib/', '/spec/lib/').sub(%r{^lib/}, 'spec/lib/').sub('.rake', '_spec.rb')
|
56
|
+
new_destination_pathname = destination_pathname.sub('/lib/', '/spec/lib/').sub(%r{^lib/}, 'spec/lib/').sub('.rake', '_spec.rb')
|
59
57
|
else
|
60
|
-
new_origin_pathname = origin_pathname.sub('/app/', '/spec/').sub(
|
61
|
-
new_destination_pathname = destination_pathname.sub('/app/', '/spec/').sub(
|
58
|
+
new_origin_pathname = origin_pathname.sub('/app/', '/spec/').sub(%r{^app/}, 'spec/').sub('.rb', '_spec.rb')
|
59
|
+
new_destination_pathname = destination_pathname.sub('/app/', '/spec/').sub(%r{^app/}, 'spec/').sub('.rb', '_spec.rb')
|
62
60
|
end
|
63
61
|
FileMoveOperation.new(
|
64
62
|
origin_pathname: new_origin_pathname,
|
65
63
|
destination_pathname: new_destination_pathname,
|
66
|
-
destination_pack: destination_pack
|
64
|
+
destination_pack: destination_pack
|
67
65
|
)
|
68
66
|
end
|
69
67
|
|
@@ -74,7 +72,7 @@ module UsePackwerk
|
|
74
72
|
FileMoveOperation.new(
|
75
73
|
origin_pathname: origin_pathname.relative_path_from(path),
|
76
74
|
destination_pathname: destination_pathname.relative_path_from(path),
|
77
|
-
destination_pack: destination_pack
|
75
|
+
destination_pack: destination_pack
|
78
76
|
)
|
79
77
|
end
|
80
78
|
end
|
@@ -8,72 +8,28 @@ module UsePackwerk
|
|
8
8
|
sig do
|
9
9
|
params(
|
10
10
|
pack_name: T.nilable(String),
|
11
|
-
limit: Integer
|
11
|
+
limit: Integer
|
12
12
|
).void
|
13
13
|
end
|
14
14
|
def self.list_top_privacy_violations(pack_name, limit)
|
15
15
|
all_packages = ParsePackwerk.all
|
16
|
-
if
|
16
|
+
if pack_name.nil?
|
17
|
+
to_package_names = all_packages.map(&:name)
|
18
|
+
else
|
17
19
|
pack_name = Private.clean_pack_name(pack_name)
|
18
|
-
package = all_packages.find { |
|
20
|
+
package = all_packages.find { |p| p.name == pack_name }
|
19
21
|
if package.nil?
|
20
|
-
raise StandardError
|
22
|
+
raise StandardError, "Can not find package with name #{pack_name}. Make sure the argument is of the form `packs/my_pack/`"
|
21
23
|
end
|
22
24
|
|
23
|
-
pack_specific_content = <<~PACK_CONTENT
|
24
|
-
You are listing top #{limit} privacy violations for #{pack_name}. See #{UsePackwerk.config.documentation_link} for other utilities!
|
25
|
-
Pass in a limit to display more or less, e.g. `bin/use_packwerk list_top_privacy_violations #{pack_name} -l 1000`
|
26
|
-
|
27
|
-
This script is intended to help you find which of YOUR pack's private classes, constants, or modules other packs are using the most.
|
28
|
-
Anything not in #{pack_name}/app/public is considered private API.
|
29
|
-
PACK_CONTENT
|
30
|
-
|
31
25
|
to_package_names = [pack_name]
|
32
|
-
else
|
33
|
-
pack_specific_content = <<~PACK_CONTENT
|
34
|
-
You are listing top #{limit} privacy violations for all packs. See #{UsePackwerk.config.documentation_link} for other utilities!
|
35
|
-
Pass in a limit to display more or less, e.g. `bin/use_packwerk list_top_privacy_violations #{pack_name} -l 1000`
|
36
|
-
|
37
|
-
This script is intended to help you find which of YOUR pack's private classes, constants, or modules other packs are using the most.
|
38
|
-
Anything not in pack_name/app/public is considered private API.
|
39
|
-
PACK_CONTENT
|
40
|
-
|
41
|
-
to_package_names = all_packages.map(&:name)
|
42
26
|
end
|
43
27
|
|
44
28
|
violations_by_count = {}
|
45
29
|
total_pack_violation_count = 0
|
46
30
|
|
47
31
|
Logging.section('👋 Hi there') do
|
48
|
-
intro =
|
49
|
-
#{pack_specific_content}
|
50
|
-
|
51
|
-
When using this script, ask yourself some questions like:
|
52
|
-
- What do I want to support?
|
53
|
-
- What do I *not* want to support?
|
54
|
-
- What is considered simply an implementation detail, and what is essential to the behavior of my pack?
|
55
|
-
- What is a simple, minimialistic API for clients to engage with the behavior of your pack?
|
56
|
-
- How do I ensure my public API is not coupled to specific client's use cases?
|
57
|
-
|
58
|
-
Looking at privacy violations can help guide the development of your public API, but it is just the beginning!
|
59
|
-
|
60
|
-
The script will output in the following format:
|
61
|
-
|
62
|
-
SomeConstant # This is the name of a class, constant, or module defined in your pack, outside of app/public
|
63
|
-
- Total Count: 5 # This is the total number of uses of this outside your pack
|
64
|
-
- By package: # This is a breakdown of the use of this constant by other packages
|
65
|
-
# This is the number of files in this pack that this constant is used.
|
66
|
-
# Check `packs/other_pack_a/deprecated_references.yml` under the '#{pack_name}'.'SomeConstant' key to see where this constant is used
|
67
|
-
- packs/other_pack_a: 3
|
68
|
-
- packs/other_pack_b: 2
|
69
|
-
SomeClass # This is the second most violated class, constant, or module defined in your pack
|
70
|
-
- Total Count: 2
|
71
|
-
- By package:
|
72
|
-
- packs/other_pack_a: 1
|
73
|
-
- packs/other_pack_b: 1
|
74
|
-
|
75
|
-
Lastly, remember you can use `bin/use_packwerk make_public #{pack_name}/path/to/file.rb` to make your class, constant, or module public API.
|
76
|
-
INTRO
|
32
|
+
intro = UsePackwerk.config.user_event_logger.before_list_top_privacy_violations(pack_name, limit)
|
77
33
|
Logging.print_bold_green(intro)
|
78
34
|
end
|
79
35
|
|
@@ -81,10 +37,11 @@ module UsePackwerk
|
|
81
37
|
all_packages.each do |client_package|
|
82
38
|
PackageProtections::ProtectedPackage.from(client_package).violations.select(&:privacy?).each do |violation|
|
83
39
|
next unless to_package_names.include?(violation.to_package_name)
|
40
|
+
|
84
41
|
if pack_name.nil?
|
85
42
|
violated_symbol = "#{violation.class_name} (#{violation.to_package_name})"
|
86
43
|
else
|
87
|
-
violated_symbol =
|
44
|
+
violated_symbol = violation.class_name
|
88
45
|
end
|
89
46
|
violations_by_count[violated_symbol] ||= {}
|
90
47
|
violations_by_count[violated_symbol][:total_count] ||= 0
|
@@ -104,8 +61,8 @@ module UsePackwerk
|
|
104
61
|
Logging.print(violated_symbol)
|
105
62
|
Logging.print(" - Total Count: #{count_info[:total_count]} (#{percentage_of_total}% of total)")
|
106
63
|
|
107
|
-
Logging.print(
|
108
|
-
count_info[:by_package].sort_by{ |client_package_name, count| [-count, client_package_name] }.each do |client_package_name, count|
|
64
|
+
Logging.print(' - By package:')
|
65
|
+
count_info[:by_package].sort_by { |client_package_name, count| [-count, client_package_name] }.each do |client_package_name, count|
|
109
66
|
Logging.print(" - #{client_package_name}: #{count}")
|
110
67
|
end
|
111
68
|
end
|
@@ -120,76 +77,35 @@ module UsePackwerk
|
|
120
77
|
def self.list_top_dependency_violations(pack_name, limit)
|
121
78
|
all_packages = ParsePackwerk.all
|
122
79
|
|
123
|
-
if
|
80
|
+
if pack_name.nil?
|
81
|
+
to_package_names = all_packages.map(&:name)
|
82
|
+
else
|
124
83
|
pack_name = Private.clean_pack_name(pack_name)
|
125
|
-
package = all_packages.find { |
|
84
|
+
package = all_packages.find { |p| p.name == pack_name }
|
126
85
|
if package.nil?
|
127
|
-
raise StandardError
|
86
|
+
raise StandardError, "Can not find package with name #{pack_name}. Make sure the argument is of the form `packs/my_pack/`"
|
128
87
|
end
|
129
88
|
|
130
|
-
pack_specific_content = <<~PACK_CONTENT
|
131
|
-
You are listing top #{limit} dependency violations for #{pack_name}. See #{UsePackwerk.config.documentation_link} for other utilities!
|
132
|
-
Pass in a limit to display more or less, e.g. `bin/use_packwerk list_top_dependency_violations #{pack_name} -l 1000`
|
133
|
-
|
134
|
-
This script is intended to help you find which of YOUR pack's private classes, constants, or modules other packs are using the most.
|
135
|
-
Anything not in #{pack_name}/app/public is considered private API.
|
136
|
-
PACK_CONTENT
|
137
|
-
|
138
89
|
to_package_names = [pack_name]
|
139
|
-
else
|
140
|
-
pack_specific_content = <<~PACK_CONTENT
|
141
|
-
You are listing top #{limit} dependency violations for all packs. See #{UsePackwerk.config.documentation_link} for other utilities!
|
142
|
-
Pass in a limit to display more or less, e.g. `use_packwerk list_top_dependency_violations #{pack_name} -l 1000`
|
143
|
-
|
144
|
-
This script is intended to help you find which of YOUR pack's private classes, constants, or modules other packs are using the most.
|
145
|
-
Anything not in pack_name/app/public is considered private API.
|
146
|
-
PACK_CONTENT
|
147
|
-
|
148
|
-
to_package_names = all_packages.map(&:name)
|
149
90
|
end
|
150
91
|
|
151
|
-
violations_by_count = {}
|
152
|
-
total_pack_violation_count = 0
|
153
|
-
|
154
92
|
Logging.section('👋 Hi there') do
|
155
|
-
intro =
|
156
|
-
#{pack_specific_content}
|
157
|
-
|
158
|
-
When using this script, ask yourself some questions like:
|
159
|
-
- What do I want to support?
|
160
|
-
- What do I *not* want to support?
|
161
|
-
- Which direction should a dependency go?
|
162
|
-
- What packs should depend on you, and what packs should not depend on you?
|
163
|
-
- Would it be simpler if other packs only depended on interfaces to your pack rather than implementation?
|
164
|
-
|
165
|
-
Looking at dependency violations can help guide the development of your public API, but it is just the beginning!
|
166
|
-
|
167
|
-
The script will output in the following format:
|
168
|
-
|
169
|
-
SomeConstant # This is the name of a class, constant, or module defined in your pack, outside of app/public
|
170
|
-
- Total Count: 5 # This is the total number of unstated uses of this outside your pack
|
171
|
-
- By package: # This is a breakdown of the use of this constant by other packages
|
172
|
-
# This is the number of files in this pack that this constant is used.
|
173
|
-
# Check `packs/other_pack_a/deprecated_references.yml` under the '#{pack_name}'.'SomeConstant' key to see where this constant is used
|
174
|
-
- packs/other_pack_a: 3
|
175
|
-
- packs/other_pack_b: 2
|
176
|
-
SomeClass # This is the second most violated class, constant, or module defined in your pack
|
177
|
-
- Total Count: 2
|
178
|
-
- By package:
|
179
|
-
- packs/other_pack_a: 1
|
180
|
-
- packs/other_pack_b: 1
|
181
|
-
INTRO
|
93
|
+
intro = UsePackwerk.config.user_event_logger.before_list_top_dependency_violations(pack_name, limit)
|
182
94
|
Logging.print_bold_green(intro)
|
183
95
|
end
|
184
96
|
|
97
|
+
violations_by_count = {}
|
98
|
+
total_pack_violation_count = 0
|
99
|
+
|
185
100
|
# TODO: This is a copy of the implementation above. We may want to refactor out this implementation detail before making changes that apply to both.
|
186
101
|
all_packages.each do |client_package|
|
187
102
|
PackageProtections::ProtectedPackage.from(client_package).violations.select(&:dependency?).each do |violation|
|
188
103
|
next unless to_package_names.include?(violation.to_package_name)
|
104
|
+
|
189
105
|
if pack_name.nil?
|
190
106
|
violated_symbol = "#{violation.class_name} (#{violation.to_package_name})"
|
191
107
|
else
|
192
|
-
violated_symbol =
|
108
|
+
violated_symbol = violation.class_name
|
193
109
|
end
|
194
110
|
violations_by_count[violated_symbol] ||= {}
|
195
111
|
violations_by_count[violated_symbol][:total_count] ||= 0
|
@@ -208,8 +124,8 @@ module UsePackwerk
|
|
208
124
|
percentage_of_total = (count_info[:total_count] * 100.0 / total_pack_violation_count).round(2)
|
209
125
|
Logging.print(violated_symbol)
|
210
126
|
Logging.print(" - Total Count: #{count_info[:total_count]} (#{percentage_of_total}% of total)")
|
211
|
-
Logging.print(
|
212
|
-
count_info[:by_package].sort_by{ |client_package_name, count| [-count, client_package_name] }.each do |client_package_name, count|
|
127
|
+
Logging.print(' - By package:')
|
128
|
+
count_info[:by_package].sort_by { |client_package_name, count| [-count, client_package_name] }.each do |client_package_name, count|
|
213
129
|
Logging.print(" - #{client_package_name}: #{count}")
|
214
130
|
end
|
215
131
|
end
|