packs 0.1.0 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cedac59e21e3cfabcc0e70369a37f099d917c6092c75a9415e4935a9bec705af
4
- data.tar.gz: 36307b5c6d741d2145e73b827ea66ace06cffa0123101443f4b0d2b30e09a5e9
3
+ metadata.gz: 221210e029bee06a127a705570b20d9856571bb3ad187f4be782521c65be5901
4
+ data.tar.gz: b401bf88686e51f1316e5e81330edca9dd1a3b8cf78a90f5c46f4dad1058a6bf
5
5
  SHA512:
6
- metadata.gz: 9478f4344cdb4dc234abb52da988b9e63033234a78289d9bdcbdacb738f911c6fb98050b0c699d19157f100df7a0139ff0a4be453776bdefc0aafd140a71d9e8
7
- data.tar.gz: 718c24457bc7b6f5d0b471f2954dbff83ebbbbb0602a32295fb8ffc6d0e9cfea44a8e49c3a9d26c938b78e34d1d67d774502b8db1b659e5a3f88cd3f7071802d
6
+ metadata.gz: ba96edf990cff199f9bdc26d79477724e294770d66de07520e48d7c7311c30d371cb8b00ae4529c35029ec65d4386e77f9009d62f5df07c29957c5e597c45dc1
7
+ data.tar.gz: 65696d3da54c5b85de8107ae76ed60c79c38167eacd4a98597026405379edfa7de8a117e7a347ed2e7c7ffbb1aa6e69c23145b878d97391e48de227d0d1152c0
data/README.md CHANGED
@@ -53,6 +53,9 @@ bin/packwerk init
53
53
  ## Describe available commands or one specific command
54
54
  `bin/packs help [COMMAND]`
55
55
 
56
+ ## Print a tree of all available commands
57
+ `bin/packs tree`
58
+
56
59
  ## Create pack with name packs/your_pack
57
60
  `bin/packs create packs/your_pack`
58
61
 
@@ -90,7 +93,7 @@ Make sure there are no spaces between the comma-separated list of paths of direc
90
93
  `bin/packs move packs/destination_pack path/to/file.rb path/to/directory`
91
94
 
92
95
  This is used for moving files into a pack (the pack must already exist).
93
- Note this works for moving files to packs from the monolith or from other packs
96
+ Note this works for moving files to packs from the monolith or from other packs.
94
97
 
95
98
  Make sure there are no spaces between the comma-separated list of paths of directories.
96
99
 
data/bin/rubocop CHANGED
@@ -8,22 +8,9 @@
8
8
  # this file is here to facilitate running it.
9
9
  #
10
10
 
11
- require 'pathname'
12
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
- Pathname.new(__FILE__).realpath)
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
14
12
 
15
- bundle_binstub = File.expand_path('bundle', __dir__)
13
+ require "rubygems"
14
+ require "bundler/setup"
16
15
 
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require 'rubygems'
27
- require 'bundler/setup'
28
-
29
- load Gem.bin_path('rubocop', 'rubocop')
16
+ load Gem.bin_path("rubocop", "rubocop")
data/bin/tapioca CHANGED
@@ -8,22 +8,9 @@
8
8
  # this file is here to facilitate running it.
9
9
  #
10
10
 
11
- require 'pathname'
12
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
- Pathname.new(__FILE__).realpath)
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
14
12
 
15
- bundle_binstub = File.expand_path('bundle', __dir__)
13
+ require "rubygems"
14
+ require "bundler/setup"
16
15
 
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require 'rubygems'
27
- require 'bundler/setup'
28
-
29
- load Gem.bin_path('tapioca', 'tapioca')
16
+ load Gem.bin_path("tapioca", "tapioca")
data/lib/packs/cli.rb CHANGED
@@ -39,10 +39,10 @@ module Packs
39
39
  exit_successfully
40
40
  end
41
41
 
42
- POSIBLE_TYPES = T.let(%w[dependency privacy layer], T::Array[String])
42
+ POSSIBLE_TYPES = T.let(%w(dependency privacy layer).freeze, T::Array[String])
43
43
  desc 'list_top_violations type [ packs/your_pack ]', 'List the top violations of a specific type for packs/your_pack.'
44
44
  long_desc <<~LONG_DESC
45
- Possible types are: #{POSIBLE_TYPES.join(', ')}.
45
+ Possible types are: #{POSSIBLE_TYPES.join(', ')}.
46
46
 
47
47
  Want to see who is depending on you? Not sure how your pack's code is being used in an unstated way? You can use this command to list the top dependency violations.
48
48
 
@@ -60,7 +60,7 @@ module Packs
60
60
  ).void
61
61
  end
62
62
  def list_top_violations(type, pack_name = nil)
63
- raise StandardError, "Invalid type #{type}. Possible types are: #{POSIBLE_TYPES.join(', ')}" unless POSIBLE_TYPES.include?(type)
63
+ raise StandardError, "Invalid type #{type}. Possible types are: #{POSSIBLE_TYPES.join(', ')}" unless POSSIBLE_TYPES.include?(type)
64
64
 
65
65
  Packs.list_top_violations(
66
66
  type: type,
@@ -85,7 +85,7 @@ module Packs
85
85
  desc 'move packs/destination_pack path/to/file.rb path/to/directory', 'Move files or directories from one pack to another'
86
86
  long_desc <<~LONG_DESC
87
87
  This is used for moving files into a pack (the pack must already exist).
88
- Note this works for moving files to packs from the monolith or from other packs
88
+ Note this works for moving files to packs from the monolith or from other packs.
89
89
 
90
90
  Make sure there are no spaces between the comma-separated list of paths of directories.
91
91
  LONG_DESC
@@ -135,8 +135,8 @@ module Packs
135
135
  sig { params(pack_names: String).void }
136
136
  def get_info(*pack_names)
137
137
  selected_types = options[:types].to_s.downcase.split(',')
138
- invalid_types = selected_types - POSIBLE_TYPES
139
- raise StandardError, "Invalid type(s): #{invalid_types.join(', ')}. Possible types are: #{POSIBLE_TYPES.join(', ')}" unless invalid_types.empty?
138
+ invalid_types = selected_types - POSSIBLE_TYPES
139
+ raise StandardError, "Invalid type(s): #{invalid_types.join(', ')}. Possible types are: #{POSSIBLE_TYPES.join(', ')}" unless invalid_types.empty?
140
140
 
141
141
  Private.get_info(
142
142
  packs: parse_pack_names(pack_names),
@@ -176,17 +176,14 @@ module Packs
176
176
 
177
177
  private
178
178
 
179
- # This is used by thor to know that these private methods are not intended to be CLI commands
180
- no_commands do
181
- sig { params(pack_names: T::Array[String]).returns(T::Array[Packs::Pack]) }
182
- def parse_pack_names(pack_names)
183
- pack_names.empty? ? Packs.all : pack_names.map { |p| Packs.find(p.gsub(%r{/$}, '')) }.compact
184
- end
185
-
186
- sig { void }
187
- def exit_successfully
188
- Private.exit_with(true)
189
- end
179
+ sig { params(pack_names: T::Array[String]).returns(T::Array[Packs::Pack]) }
180
+ def parse_pack_names(pack_names)
181
+ pack_names.empty? ? Packs.all : pack_names.filter_map { |p| Packs.find(p.delete_suffix('/')) }
182
+ end
183
+
184
+ sig { void }
185
+ def exit_successfully
186
+ Private.exit_with(true)
190
187
  end
191
188
  end
192
189
  end
@@ -25,7 +25,7 @@ module Packs
25
25
  replace_with: relative_path_to_destination
26
26
  )
27
27
 
28
- team = CodeOwnership.for_file(relative_path_to_origin.to_s)
28
+ team = CodeOwnership.for_file(relative_path_to_origin.to_s, from_codeowners: false)
29
29
 
30
30
  if team
31
31
  @teams << team.name
@@ -30,7 +30,7 @@ module Packs
30
30
  def initialize
31
31
  @enforce_dependencies = T.let(default_enforce_dependencies, T::Boolean)
32
32
  @user_event_logger = T.let(DefaultUserEventLogger.new, UserEventLogger)
33
- @on_package_todo_lint_failure = T.let(->(output) {}, OnPackageTodoLintFailure)
33
+ @on_package_todo_lint_failure = T.let(-> (output) {}, OnPackageTodoLintFailure)
34
34
  @use_pks = T.let(false, T::Boolean)
35
35
  end
36
36
 
@@ -68,8 +68,7 @@ module Packs
68
68
  sig { returns(Configuration) }
69
69
  def config
70
70
  Private.load_client_configuration
71
- @config = T.let(@config, T.nilable(Configuration))
72
- @config ||= Configuration.new
71
+ @config ||= T.let(Configuration.new, T.nilable(Configuration))
73
72
  end
74
73
 
75
74
  sig { params(blk: T.proc.params(arg0: Configuration).void).void }
@@ -8,7 +8,8 @@ module Packs
8
8
  abstract!
9
9
 
10
10
  sig { abstract.params(file_move_operation: Private::FileMoveOperation).void }
11
- def before_move_file!(file_move_operation); end
11
+ def before_move_file!(file_move_operation)
12
+ end
12
13
 
13
14
  sig { overridable.params(file_move_operations: T::Array[Private::FileMoveOperation]).void }
14
15
  def after_move_files!(file_move_operations)
@@ -51,8 +51,8 @@ module Packs
51
51
  ).cleanpath
52
52
  end
53
53
 
54
- sig { returns(FileMoveOperation) }
55
- def spec_file_move_operation
54
+ sig { returns(T::Array[FileMoveOperation]) }
55
+ def spec_file_move_operations
56
56
  path_parts = filepath_without_pack_name.split('/')
57
57
  folder = T.must(path_parts[0])
58
58
  file_extension = T.must(filepath_without_pack_name.split('.').last)
@@ -67,11 +67,20 @@ module Packs
67
67
  new_destination_pathname = spec_pathname_for_non_app(destination_pathname, file_extension, folder)
68
68
  end
69
69
 
70
- FileMoveOperation.new(
71
- origin_pathname: new_origin_pathname,
72
- destination_pathname: new_destination_pathname,
73
- destination_pack: destination_pack
74
- )
70
+ ops = [
71
+ FileMoveOperation.new(
72
+ origin_pathname: new_origin_pathname,
73
+ destination_pathname: new_destination_pathname,
74
+ destination_pack: destination_pack
75
+ ),
76
+ ]
77
+
78
+ # For controllers, also include the request spec (spec/requests/<name>_spec.rb) if it exists.
79
+ # Request specs are named without "controller" suffix (e.g. my_controller -> my_spec)
80
+ request_spec_op = request_spec_file_move_operation
81
+ ops << request_spec_op if request_spec_op
82
+
83
+ ops
75
84
  end
76
85
 
77
86
  sig { params(filepath: Pathname, pack: T.nilable(Packs::Pack)).returns(String) }
@@ -94,7 +103,7 @@ module Packs
94
103
  def spec_pathname_for_app(pathname, file_extension)
95
104
  pathname
96
105
  .sub('/app/', '/spec/')
97
- .sub(%r{^app/}, 'spec/')
106
+ .sub(%r(\Aapp/), 'spec/')
98
107
  .sub(".#{file_extension}", '_spec.rb')
99
108
  end
100
109
 
@@ -102,10 +111,39 @@ module Packs
102
111
  def spec_pathname_for_non_app(pathname, file_extension, folder)
103
112
  pathname
104
113
  .sub("/#{folder}/", "/spec/#{folder}/")
105
- .sub(%r{^#{folder}/}, "spec/#{folder}/")
114
+ .sub(%r(\A#{folder}/), "spec/#{folder}/")
106
115
  .sub(".#{file_extension}", '_spec.rb')
107
116
  end
108
117
 
118
+ # Maps app/controllers/<namespaces/>*_controller.rb to spec/requests/<namespaces/>*_spec.rb.
119
+ # Returns nil if the path is not a controller path.
120
+ sig { params(pathname: Pathname).returns(T.nilable(Pathname)) }
121
+ def pathname_to_request_spec(pathname)
122
+ return nil unless pathname.to_s.end_with?('_controller.rb')
123
+
124
+ pathname
125
+ .sub('app/controllers/', 'spec/requests/')
126
+ .sub('/app/', '/spec/') # if destionation doesn't have controller subdirectory
127
+ .sub(%r(\Aapp/), 'spec/')
128
+ .sub(/_controller\.rb\z/, '_spec.rb')
129
+ .cleanpath
130
+ end
131
+
132
+ sig { returns(T.nilable(FileMoveOperation)) }
133
+ def request_spec_file_move_operation
134
+ request_spec_origin = pathname_to_request_spec(origin_pathname)
135
+ return if request_spec_origin.nil? || !request_spec_origin.exist?
136
+
137
+ request_spec_destination = pathname_to_request_spec(destination_pathname)
138
+ return if request_spec_destination.nil?
139
+
140
+ FileMoveOperation.new(
141
+ origin_pathname: request_spec_origin,
142
+ destination_pathname: request_spec_destination,
143
+ destination_pack: destination_pack
144
+ )
145
+ end
146
+
109
147
  sig { params(path: Pathname).returns(FileMoveOperation) }
110
148
  def relative_to(path)
111
149
  FileMoveOperation.new(
@@ -10,13 +10,15 @@ module Packs
10
10
  def self.single_pack_select(prompt, question_text: 'Please use space to select a pack')
11
11
  packs = Packs.all.to_h { |t| [t.name, t] }
12
12
 
13
- pack_selection = T.let(prompt.select(
14
- question_text,
15
- packs,
16
- filter: true,
17
- per_page: 10,
18
- show_help: :always
19
- ), T.nilable(Packs::Pack))
13
+ pack_selection = T.let(
14
+ prompt.select(
15
+ question_text,
16
+ packs,
17
+ filter: true,
18
+ per_page: 10,
19
+ show_help: :always
20
+ ), T.nilable(Packs::Pack)
21
+ )
20
22
 
21
23
  while pack_selection.nil?
22
24
  prompt.error(
@@ -31,13 +33,15 @@ module Packs
31
33
 
32
34
  sig { params(prompt: TTY::Prompt, question_text: String).returns(T::Array[Packs::Pack]) }
33
35
  def self.single_or_all_pack_multi_select(prompt, question_text: 'Please use space to select one or more packs')
34
- pack_selection = T.let(prompt.multi_select(
35
- question_text,
36
- Packs.all.to_h { |t| [t.name, t] },
37
- filter: true,
38
- per_page: 10,
39
- show_help: :always
40
- ), T::Array[Packs::Pack])
36
+ pack_selection = T.let(
37
+ prompt.multi_select(
38
+ question_text,
39
+ Packs.all.to_h { |t| [t.name, t] },
40
+ filter: true,
41
+ per_page: 10,
42
+ show_help: :always
43
+ ), T::Array[Packs::Pack]
44
+ )
41
45
 
42
46
  while pack_selection.empty?
43
47
  prompt.error(
@@ -9,15 +9,17 @@ module Packs
9
9
  sig { params(prompt: TTY::Prompt, question_text: String).returns(T.nilable(CodeTeams::Team)) }
10
10
  def self.single_select(prompt, question_text: 'Please use space to select a team owner')
11
11
  teams = CodeTeams.all.sort_by(&:name).to_h { |t| [t.name, t] }
12
- return nil if teams.count == 0
13
-
14
- team_selection = T.let(prompt.select(
15
- question_text,
16
- teams,
17
- filter: true,
18
- per_page: 10,
19
- show_help: :always
20
- ), T.nilable(CodeTeams::Team))
12
+ return nil if teams.none?
13
+
14
+ team_selection = T.let(
15
+ prompt.select(
16
+ question_text,
17
+ teams,
18
+ filter: true,
19
+ per_page: 10,
20
+ show_help: :always
21
+ ), T.nilable(CodeTeams::Team)
22
+ )
21
23
 
22
24
  while team_selection.nil?
23
25
  prompt.error(
@@ -34,13 +36,15 @@ module Packs
34
36
  def self.multi_select(prompt, question_text: 'Please use space to select team owners')
35
37
  teams = CodeTeams.all.to_h { |t| [t.name, t] }
36
38
 
37
- team_selection = T.let(prompt.multi_select(
38
- question_text,
39
- teams,
40
- filter: true,
41
- per_page: 10,
42
- show_help: :always
43
- ), T::Array[CodeTeams::Team])
39
+ team_selection = T.let(
40
+ prompt.multi_select(
41
+ question_text,
42
+ teams,
43
+ filter: true,
44
+ per_page: 10,
45
+ show_help: :always
46
+ ), T::Array[CodeTeams::Team]
47
+ )
44
48
 
45
49
  while team_selection.empty?
46
50
  prompt.error(
@@ -26,11 +26,11 @@ module Packs
26
26
  selected_packs = PackSelector.single_or_all_pack_multi_select(prompt, question_text: 'What pack(s) would you like info on?')
27
27
  end
28
28
 
29
- format = prompt.select('What output format do you want?', %w[Detail CSV])
29
+ format = prompt.select('What output format do you want?', %w(Detail CSV))
30
30
 
31
31
  types = prompt.multi_select(
32
32
  'What violation types do you want stats for?',
33
- %w[Privacy Dependency Layer]
33
+ %w(Privacy Dependency Layer)
34
34
  )
35
35
 
36
36
  include_date = !prompt.no?('Should the current date be included in the report?')
@@ -23,10 +23,12 @@ module Packs
23
23
  end
24
24
 
25
25
  sig { abstract.params(prompt: TTY::Prompt).void }
26
- def perform!(prompt); end
26
+ def perform!(prompt)
27
+ end
27
28
 
28
29
  sig { abstract.returns(String) }
29
- def user_facing_name; end
30
+ def user_facing_name
31
+ end
30
32
  end
31
33
  end
32
34
  end
@@ -16,7 +16,7 @@ module Packs
16
16
  {
17
17
  'Move a child pack to be nested under a parent pack' => :move_to_parent,
18
18
  'Move a pack to a folder that is not a pack' =>
19
- :move_to_folder
19
+ :move_to_folder,
20
20
  }
21
21
  )
22
22
 
@@ -30,7 +30,7 @@ module Packs
30
30
 
31
31
  limit = prompt.ask('Specify the limit of constants to analyze', default: 10, convert: :integer)
32
32
 
33
- selection = prompt.select('Are you interested in dependency, privacy, or layer violations?', %w[Dependency Privacy Layer], default: 'Privacy')
33
+ selection = prompt.select('Are you interested in dependency, privacy, or layer violations?', %w(Dependency Privacy Layer), default: 'Privacy')
34
34
 
35
35
  Packs.list_top_violations(
36
36
  type: selection.downcase,
@@ -28,16 +28,21 @@ module Packs
28
28
 
29
29
  sig { params(prompt: T.nilable(TTY::Prompt)).void }
30
30
  def self.start!(prompt: nil)
31
- prompt ||= TTY::Prompt.new(interrupt: lambda {
32
- puts "\n\nGoodbye! I hope you have a good day."
33
- exit 1 })
31
+ prompt ||= TTY::Prompt.new(
32
+ interrupt: -> {
33
+ puts "\n\nGoodbye! I hope you have a good day."
34
+ exit 1
35
+ }
36
+ )
34
37
  help_text = '(Press ↑/↓ arrow to move, Enter to select and letters to filter)'
35
- choice = prompt.select('Hello! What would you like to do?',
38
+ choice = prompt.select(
39
+ 'Hello! What would you like to do?',
36
40
  cycle: true,
37
41
  filter: true,
38
42
  help: help_text,
39
43
  show_help: :always,
40
- per_page: 15) do |menu|
44
+ per_page: 15
45
+ ) do |menu|
41
46
  menu.enum '.'
42
47
 
43
48
  UseCases::Interface.all.each do |use_case|
data/lib/packs/private.rb CHANGED
@@ -22,7 +22,7 @@ module Packs
22
22
  # This results in the pack not being found, but when we write the package YML it writes to the same place,
23
23
  # causing a behaviorally confusing diff.
24
24
  # We ignore trailing slashes as an ergonomic feature to the user.
25
- pack_name.gsub(%r{/$}, '')
25
+ pack_name.delete_suffix('/')
26
26
  end
27
27
 
28
28
  sig do
@@ -37,10 +37,12 @@ module Packs
37
37
  return if !file.exist?
38
38
 
39
39
  count = 0
40
- file.write(file.read.gsub(find.to_s) do
41
- count += 1
42
- replace_with.to_s
43
- end)
40
+ file.write(
41
+ file.read.gsub(find.to_s) do
42
+ count += 1
43
+ replace_with.to_s
44
+ end
45
+ )
44
46
  Logging.print "Replaced #{count} occurrence(s) of #{find} in #{file}" if count > 0
45
47
  end
46
48
 
@@ -69,7 +71,7 @@ module Packs
69
71
  team: team
70
72
  )
71
73
  add_public_directory(package) if package.enforce_privacy
72
- add_readme_todo(package)
74
+ add_readme(package)
73
75
 
74
76
  Logging.section('Next steps') do
75
77
  next_steps = Packs.config.user_event_logger.after_create_pack(pack_name)
@@ -131,7 +133,7 @@ module Packs
131
133
  )
132
134
  [
133
135
  file_move_operation,
134
- file_move_operation.spec_file_move_operation
136
+ *file_move_operation.spec_file_move_operations,
135
137
  ]
136
138
  end
137
139
  file_move_operations.each do |file_move_operation|
@@ -140,7 +142,7 @@ module Packs
140
142
  end
141
143
  end
142
144
 
143
- add_readme_todo(package)
145
+ add_readme(package)
144
146
 
145
147
  per_file_processors.each do |processor|
146
148
  processor.after_move_files!(file_move_operations)
@@ -297,8 +299,8 @@ module Packs
297
299
  end
298
300
 
299
301
  if other_package.name == parent_name &&
300
- !new_dependencies.include?(new_package_name) &&
301
- !new_config['ignored_dependencies']&.include?(new_package_name)
302
+ !new_dependencies.include?(new_package_name) &&
303
+ !new_config['ignored_dependencies']&.include?(new_package_name)
302
304
  new_dependencies += [new_package_name]
303
305
  end
304
306
 
@@ -358,7 +360,7 @@ module Packs
358
360
 
359
361
  [
360
362
  file_move_operation,
361
- file_move_operation.spec_file_move_operation
363
+ *file_move_operation.spec_file_move_operations,
362
364
  ]
363
365
  end
364
366
 
@@ -446,18 +448,22 @@ module Packs
446
448
 
447
449
  if public_directory.glob('**/**.rb').none?
448
450
  FileUtils.mkdir_p(public_directory)
449
- todo_md = Packs.config.user_event_logger.on_create_public_directory_todo(package.name)
450
- public_directory.join('TODO.md').write(todo_md)
451
+ package_name = package.directory.basename.to_s
452
+ FileUtils.mkdir_p(public_directory.join(package_name))
451
453
  end
452
454
  end
453
455
 
454
456
  sig { params(package: ParsePackwerk::Package).void }
455
- def self.add_readme_todo(package)
457
+ def self.add_readme(package)
456
458
  pack_directory = package.directory
457
459
 
458
460
  if !pack_directory.join('README.md').exist?
459
- readme_todo_md = Packs.config.user_event_logger.on_create_readme_todo(package.name)
460
- pack_directory.join('README_TODO.md').write(readme_todo_md)
461
+ readme_md = Packs.config.user_event_logger.on_create_readme(package.name)
462
+ pack_directory.join('README.md').write(readme_md)
463
+
464
+ if pack_directory.join('README_TODO.md').exist?
465
+ pack_directory.join('README_TODO.md').delete
466
+ end
461
467
  end
462
468
  end
463
469
 
@@ -484,7 +490,7 @@ module Packs
484
490
  # but we'll need to add an API to CodeOwnership to do this
485
491
  if Pathname.new('config/code_ownership.yml').exist?
486
492
  config = {
487
- 'owner' => team.nil? ? 'MyTeam' : team.name
493
+ 'owner' => team.nil? ? 'MyTeam' : team.name,
488
494
  }
489
495
  else
490
496
  config = {}
@@ -526,7 +532,7 @@ module Packs
526
532
  def self.bust_cache!
527
533
  Packs.config.bust_cache!
528
534
  # This comes explicitly after `Packs.config.bust_cache!` because
529
- # otherwise `Packs.config` will attempt to reload the client configuratoin.
535
+ # otherwise `Packs.config` will attempt to reload the client configuration.
530
536
  @loaded_client_configuration = false
531
537
  end
532
538
 
@@ -555,7 +561,7 @@ module Packs
555
561
  write_package_todo_to_tmp_folder(before, dir_containing_contents_before)
556
562
  write_package_todo_to_tmp_folder(after, dir_containing_contents_after)
557
563
 
558
- diff = `diff -r #{dir_containing_contents_before}/ #{dir_containing_contents_after}/`
564
+ diff = %x(diff -r #{dir_containing_contents_before}/ #{dir_containing_contents_after}/)
559
565
  # For ease of reading, sub out the tmp directory from the diff
560
566
  diff.gsub(dir_containing_contents_before, '').gsub(dir_containing_contents_after, '')
561
567
  ensure
@@ -600,13 +606,13 @@ module Packs
600
606
  include_date: T::Boolean
601
607
  ).void
602
608
  end
603
- def self.get_info(packs: Packs.all, format: :detail, types: %i[privacy dependency layer], include_date: false)
609
+ def self.get_info(packs: Packs.all, format: :detail, types: %i(privacy dependency layer), include_date: false)
604
610
  require 'csv' if format == :csv
605
611
 
606
612
  today = Date.today.iso8601
607
613
  violations = {
608
614
  inbound: {},
609
- outbound: {}
615
+ outbound: {},
610
616
  }
611
617
 
612
618
  package_by_name = {}
@@ -623,7 +629,7 @@ module Packs
623
629
 
624
630
  all = {
625
631
  inbound: T.let([], T::Array[ParsePackwerk::Violation]),
626
- outbound: T.let([], T::Array[ParsePackwerk::Violation])
632
+ outbound: T.let([], T::Array[ParsePackwerk::Violation]),
627
633
  }
628
634
  packs.each do |pack|
629
635
  all[:inbound] += violations[:inbound][pack.name] || []
@@ -657,7 +663,7 @@ module Packs
657
663
  pack_name: pack.name,
658
664
  owner: owner.nil? ? 'No one' : owner.name,
659
665
  size: pack.relative_path.glob('**/*.rb').count,
660
- public_api: pack.relative_path.join(package_by_name[pack.name].public_path)
666
+ public_api: pack.relative_path.join(package_by_name[pack.name].public_path),
661
667
  }
662
668
 
663
669
  row.delete(:date) unless include_date
@@ -19,7 +19,7 @@ module Packs
19
19
  destination_pack = T.must(file_move_operations.first).destination_pack.name
20
20
 
21
21
  if self.class.ripgrep_enabled?
22
- matching_files = `rg -l --hidden '#{origin_pack}' .`
22
+ matching_files = %x(rg -l --hidden '#{origin_pack}' .)
23
23
  matching_files.split("\n").each do |file_name|
24
24
  substitute_references!(file_name, origin_pack, destination_pack)
25
25
  end
@@ -124,30 +124,7 @@ module Packs
124
124
  end
125
125
 
126
126
  sig { params(pack_name: String).returns(String) }
127
- def on_create_public_directory_todo(pack_name)
128
- <<~MSG
129
- This directory holds your public API!
130
-
131
- Any classes, constants, or modules that you want other packs to use and you intend to support should go in here.
132
- Anything that is considered private should go in other folders.
133
-
134
- If another pack uses classes, constants, or modules that are not in your public folder, it will be considered a "privacy violation" by packwerk.
135
- You can prevent other packs from using private API by using packwerk.
136
-
137
- Want to find how your private API is being used today?
138
- Try running: `bin/packs list_top_violations privacy #{pack_name}`
139
-
140
- Want to move something into this folder?
141
- Try running: `bin/packs make_public #{pack_name}/path/to/file.rb`
142
-
143
- One more thing -- feel free to delete this file and replace it with a README.md describing your package in the main package directory.
144
-
145
- See #{documentation_link} for more info!
146
- MSG
147
- end
148
-
149
- sig { params(pack_name: String).returns(String) }
150
- def on_create_readme_todo(pack_name)
127
+ def on_create_readme(pack_name)
151
128
  readme_template_pathname = Packs.config.readme_template_pathname
152
129
  readme_template = readme_template_pathname.read if readme_template_pathname.exist?
153
130
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-18 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bigdecimal
@@ -140,16 +139,16 @@ dependencies:
140
139
  name: bundler
141
140
  requirement: !ruby/object:Gem::Requirement
142
141
  requirements:
143
- - - "~>"
142
+ - - ">="
144
143
  - !ruby/object:Gem::Version
145
- version: '2.2'
144
+ version: '0'
146
145
  type: :development
147
146
  prerelease: false
148
147
  version_requirements: !ruby/object:Gem::Requirement
149
148
  requirements:
150
- - - "~>"
149
+ - - ">="
151
150
  - !ruby/object:Gem::Version
152
- version: '2.2'
151
+ version: '0'
153
152
  - !ruby/object:Gem::Dependency
154
153
  name: pry
155
154
  requirement: !ruby/object:Gem::Requirement
@@ -220,6 +219,20 @@ dependencies:
220
219
  - - ">="
221
220
  - !ruby/object:Gem::Version
222
221
  version: '0'
222
+ - !ruby/object:Gem::Dependency
223
+ name: rubocop-gusto
224
+ requirement: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
229
+ type: :development
230
+ prerelease: false
231
+ version_requirements: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
223
236
  - !ruby/object:Gem::Dependency
224
237
  name: sorbet
225
238
  requirement: !ruby/object:Gem::Requirement
@@ -252,16 +265,16 @@ dependencies:
252
265
  name: spoom
253
266
  requirement: !ruby/object:Gem::Requirement
254
267
  requirements:
255
- - - '='
268
+ - - ">="
256
269
  - !ruby/object:Gem::Version
257
- version: 1.2.1
270
+ version: '0'
258
271
  type: :development
259
272
  prerelease: false
260
273
  version_requirements: !ruby/object:Gem::Requirement
261
274
  requirements:
262
- - - '='
275
+ - - ">="
263
276
  - !ruby/object:Gem::Version
264
- version: 1.2.1
277
+ version: '0'
265
278
  - !ruby/object:Gem::Dependency
266
279
  name: tapioca
267
280
  requirement: !ruby/object:Gem::Requirement
@@ -329,7 +342,6 @@ metadata:
329
342
  source_code_uri: https://github.com/rubyatscale/packs
330
343
  changelog_uri: https://github.com/rubyatscale/packs/releases
331
344
  allowed_push_host: https://rubygems.org
332
- post_install_message:
333
345
  rdoc_options: []
334
346
  require_paths:
335
347
  - lib
@@ -337,15 +349,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
337
349
  requirements:
338
350
  - - ">="
339
351
  - !ruby/object:Gem::Version
340
- version: 2.6.0
352
+ version: '3.2'
341
353
  required_rubygems_version: !ruby/object:Gem::Requirement
342
354
  requirements:
343
355
  - - ">="
344
356
  - !ruby/object:Gem::Version
345
357
  version: '0'
346
358
  requirements: []
347
- rubygems_version: 3.5.22
348
- signing_key:
359
+ rubygems_version: 3.6.9
349
360
  specification_version: 4
350
361
  summary: Provides CLI tools for working with ruby packs.
351
362
  test_files: []