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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f058e80dcae7e5bc36702bf0ccf3d0e81b044c9f162ac66e74c99eec6bcc8cdb
4
- data.tar.gz: 9536a0e463e7d7708e7843bdcefdd892e32343cf1a5ae670024eed1b116546a4
3
+ metadata.gz: 6f2315b30561bd988826f08430f4bcecade3056549d1c78069dcbd72cd8aa90b
4
+ data.tar.gz: 2d8cb765865b07158ffb0dd6e7e30765e66e93912b49ccb63ede8e0e6116b41c
5
5
  SHA512:
6
- metadata.gz: 703bbd5300f6565a690563b9bf86ee8d23d91d52a0a48a75b162350aeac3a6455d6ec8fb38c22a43c334700890c0ccb5d5bcffdabe7672b064e295932dcf9df2
7
- data.tar.gz: 61302158b9f8afba60a256079350e03c9484ec97a5e241e516ab33031593b36882910b7e32d1fb5e9044575d5e3b79c68eb98b4cd1026a0eafcd2dbcdac55b9e
6
+ metadata.gz: 03d1a533f3323bad78ddef6843a3bcf996cb6390f71feeafdc7844baed5af13ee18ebe558b98c5e4fea89240f0f7645732ca90d73a555e78630758e90d04424a
7
+ data.tar.gz: 1cada76edf9ec7c76b343946c8c6373d1eaeb665312b226a7a2fecc2facca855c42a0b18d08f847722663f16799aca20383da82ef0f866bc962260652183d373
@@ -6,13 +6,13 @@ module UsePackwerk
6
6
  class CLI < Thor
7
7
  extend T::Sig
8
8
 
9
- desc "create packs/your_pack", "Create pack with name packs/your_pack"
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 "add_dependency packs/from_pack packs/to_pack", "Add packs/to_pack to packs/from_pack/package.yml list of dependencies"
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 "list_top_dependency_violations packs/your_pack", "List the top dependency violations of packs/your_pack"
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 "list_top_privacy_violations packs/your_pack", "List the top privacy violations of packs/your_pack"
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 "make_public path/to/file.rb path/to/directory", "Pass in a space-separated list of file or directory paths to make public"
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 "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"
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 "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!"
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 { |team, instances| -instances.count }.each do |team, instances|
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 "Since the destination package has package-based ownership, file-annotations were removed from moved files."
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 { params(documentation_link: String).void }
11
- attr_writer :documentation_link
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(@enforce_dependencies, T.nilable(T::Boolean))
16
- @documentation_link = T.let(documentation_link, T.nilable(String) )
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
- if !@enforce_dependencies.nil?
22
- @enforce_dependencies
23
- else
24
- true
25
- end
24
+ @enforce_dependencies
26
25
  end
27
26
 
28
- # Configure a link to show up for users who are looking for more info
29
- sig { returns(String) }
30
- def documentation_link
31
- "https://go/packwerk"
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) # rubocop:disable Lint/UnusedMethodArgument
49
+ def configure(&blk)
46
50
  yield(config)
47
51
  end
48
52
  end
@@ -0,0 +1,7 @@
1
+ # typed: strict
2
+
3
+ module UsePackwerk
4
+ class DefaultUserEventLogger
5
+ include UserEventLogger
6
+ end
7
+ end
@@ -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("#{title}").green.bold
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
- # and we take the cleanpath so `./app/...` becomes `app/...`
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(/^lib\//, 'spec/lib/').sub('.rake', '_spec.rb')
58
- new_destination_pathname = destination_pathname.sub('/lib/', '/spec/lib/').sub(/^lib\//, 'spec/lib/').sub('.rake', '_spec.rb')
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(/^app\//, 'spec/').sub('.rb', '_spec.rb')
61
- new_destination_pathname = destination_pathname.sub('/app/', '/spec/').sub(/^app\//, 'spec/').sub('.rb', '_spec.rb')
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 !pack_name.nil?
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 { |package| package.name == pack_name }
20
+ package = all_packages.find { |p| p.name == pack_name }
19
21
  if package.nil?
20
- raise StandardError.new("Can not find package with name #{pack_name}. Make sure the argument is of the form `packs/my_pack/`")
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 = <<~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 = "#{violation.class_name}"
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(" - By package:")
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 !pack_name.nil?
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 { |package| package.name == pack_name }
84
+ package = all_packages.find { |p| p.name == pack_name }
126
85
  if package.nil?
127
- raise StandardError.new("Can not find package with name #{pack_name}. Make sure the argument is of the form `packs/my_pack/`")
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 = <<~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 = "#{violation.class_name}"
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(" - By package:")
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