packs 0.0.35 → 0.0.37

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: 29b2c810b50fb84aee08f79e49a7d6710b7bf74f8421efd2ce36a12c61bb5cb5
4
- data.tar.gz: a183ed44f957f94de6736e0272193e873da6ca7d177a6cbad491682fc73596a8
3
+ metadata.gz: 61faca4f667524b1ad3ac80486441315601f3ceda6ff04c413a1412b943e7df4
4
+ data.tar.gz: 347f3a70a95fb188497f7056f88925a5c9ecc409fc0b9561d35ce8fbe13ca191
5
5
  SHA512:
6
- metadata.gz: 5587b5c11a6ffcc20213ddf8c7fc5fd1efe2d82f6d461e70d38c82fa55151956225388f45313cd2a6cda88bc839a6350ee821a3afdb942929f130ef2b5c5165a
7
- data.tar.gz: 3c789067155a3ff7a76eade07734f3acf884fecacea1472a1755afcba7f833bef370dd4f359b2761eeceb907615c2cbbf728bdfc0aa61056b17e9f2cb39593e0
6
+ metadata.gz: 11de5f83297dce2506a151ceb9f6e18d2a7bdfdfb0086f3ac05b2136f2530b638817d5eea079342265102e2e652c6264f6b31df9fd58e9a1bc61a15f0d47eae9
7
+ data.tar.gz: ab4bd4f5e89f880ada5f0d9bf7d4a25119a8e3b9ca1158be241cb3b9530b6470ddf6cf817d3c2930afd53b2c0ddd17821d0ee9b42a61547d0578402f581ce87e
data/README.md CHANGED
@@ -21,7 +21,7 @@ The rest of the [rubyatscale](https://github.com/rubyatscale) ecosystem is inten
21
21
  Here are some example integrations with `packs`:
22
22
  - [`packs-specification`](https://github.com/rubyatscale/packs-specification) is a low-dependency gem that allows your production environment to query simple information about packs
23
23
  - [`packs-rails`](https://github.com/rubyatscale/packs-rails) can be used to integrate `packs` into your `rails` application
24
- - [`rubocop-packs`](https://github.com/rubyatscale/rubocop-packs) contains cops to improve boundaries around `packs`
24
+ - [`rubocop-packs`](https://github.com/rubyatscale/rubocop-packs) contains cops to improve boundaries around `packs`
25
25
  - [`packwerk`](https://github.com/Shopify/packwerk) and [`packwerk-extensions`](https://github.com/rubyatscale/packwerk-extensions) help you describe and constrain your package graph in terms of dependencies between packs and pack public API
26
26
  - [`code_ownership`](https://github.com/rubyatscale/code_ownership) gives your application the capability to determine the owner of a pack
27
27
  - [`pack_stats`](https://github.com/rubyatscale/pack_stats) makes it easy to send metrics about pack adoption and modularization to your favorite metrics provider, such as DataDog (which has built-in support).
@@ -77,7 +77,7 @@ If no pack name is passed in, this will list out violations across all packs.
77
77
  ## Make files or directories public API
78
78
  `bin/packs make_public path/to/file.rb path/to/directory`
79
79
 
80
- This moves a file or directory to public API (that is -- the `app/public` folder).
80
+ This moves a file or directory to public API (either the `app/public` folder or the pack's specified public path).
81
81
 
82
82
  Make sure there are no spaces between the comma-separated list of paths of directories.
83
83
 
@@ -111,7 +111,10 @@ Make sure there are no spaces between the comma-separated list of paths of direc
111
111
  `bin/packs rename`
112
112
 
113
113
  ## Set packs/child_pack as a child of packs/parent_pack
114
- `bin/packs move_to_parent packs/child_pack packs/parent_pack `
114
+ `bin/packs move_to_parent packs/child_pack packs/parent_pack`
115
+
116
+ ## Move packs/foo to the some/directory folder, where some/directory does not contain a package.yml file
117
+ `bin/packs move_to_folder packs/foo some/directory`
115
118
 
116
119
 
117
120
  ## Releasing
data/lib/packs/cli.rb CHANGED
@@ -68,7 +68,7 @@ module Packs
68
68
 
69
69
  desc 'make_public path/to/file.rb path/to/directory', 'Make files or directories public API'
70
70
  long_desc <<~LONG_DESC
71
- This moves a file or directory to public API (that is -- the `app/public` folder).
71
+ This moves a file or directory to public API (either the `#{ParsePackwerk::DEFAULT_PUBLIC_PATH}` folder or the pack's specified public path).
72
72
 
73
73
  Make sure there are no spaces between the comma-separated list of paths of directories.
74
74
  LONG_DESC
@@ -150,7 +150,7 @@ module Packs
150
150
  exit_successfully
151
151
  end
152
152
 
153
- desc 'move_to_parent packs/child_pack packs/parent_pack ', 'Set packs/child_pack as a child of packs/parent_pack'
153
+ desc 'move_to_parent packs/child_pack packs/parent_pack', 'Set packs/child_pack as a child of packs/parent_pack'
154
154
  sig { params(child_pack_name: String, parent_pack_name: String).void }
155
155
  def move_to_parent(child_pack_name, parent_pack_name)
156
156
  Packs.move_to_parent!(
@@ -160,6 +160,16 @@ module Packs
160
160
  exit_successfully
161
161
  end
162
162
 
163
+ desc 'move_to_folder packs/foo some/directory', 'Move packs/foo to the some/directory folder, where some/directory does not contain a package.yml file'
164
+ sig { params(pack_name: String, destination: String).void }
165
+ def move_to_folder(pack_name, destination)
166
+ Packs.move_to_folder!(
167
+ pack_name: pack_name,
168
+ destination: destination
169
+ )
170
+ exit_successfully
171
+ end
172
+
163
173
  private
164
174
 
165
175
  # This is used by thor to know that these private methods are not intended to be CLI commands
data/lib/packs/private.rb CHANGED
@@ -140,6 +140,83 @@ module Packs
140
140
  end
141
141
  end
142
142
 
143
+ sig do
144
+ params(
145
+ pack_name: String,
146
+ destination: String,
147
+ per_file_processors: T::Array[PerFileProcessorInterface]
148
+ ).void
149
+ end
150
+ def self.move_to_folder!(pack_name:, destination:, per_file_processors: [Packs::RubocopPostProcessor.new, Packs::CodeOwnershipPostProcessor.new])
151
+ pack_name = Private.clean_pack_name(pack_name)
152
+ package = ParsePackwerk.all.find { |p| p.name == pack_name }
153
+ if package.nil?
154
+ raise StandardError, "Can not find package with name #{pack_name}. Make sure the argument is of the form `packs/my_pack/`"
155
+ end
156
+
157
+ # First we create a new pack that has the exact same properties of the old one!
158
+ package_last_name = package.directory.basename
159
+ new_package_name = File.join(destination, package_last_name)
160
+
161
+ new_package = ParsePackwerk::Package.new(
162
+ name: new_package_name,
163
+ enforce_privacy: package.enforce_privacy,
164
+ enforce_dependencies: package.enforce_dependencies,
165
+ dependencies: package.dependencies,
166
+ violations: package.violations,
167
+ metadata: package.metadata,
168
+ config: package.config
169
+ )
170
+ ParsePackwerk.write_package_yml!(new_package)
171
+ ParsePackwerk.bust_cache!
172
+
173
+ # Move everything from the old pack to the new one
174
+ move_to_pack!(
175
+ pack_name: new_package_name,
176
+ paths_relative_to_root: [package.directory.to_s],
177
+ per_file_processors: per_file_processors
178
+ )
179
+
180
+ # Then delete the old package.yml and package_todo.yml files
181
+ package.yml.delete
182
+ package_todo_file = ParsePackwerk::PackageTodo.for(package).pathname
183
+ package_todo_file.delete if package_todo_file.exist?
184
+
185
+ ParsePackwerk.bust_cache!
186
+
187
+ ParsePackwerk.all.each do |other_package|
188
+ new_dependencies = other_package.dependencies.map { |d| d == pack_name ? new_package_name : d }
189
+
190
+ new_config = other_package.config.dup
191
+ if new_config['ignored_dependencies']
192
+ new_config['ignored_dependencies'] = new_config['ignored_dependencies'].map do |d|
193
+ d == pack_name ? new_package_name : d
194
+ end
195
+ end
196
+
197
+ new_other_package = ParsePackwerk::Package.new(
198
+ name: other_package.name,
199
+ enforce_privacy: other_package.enforce_privacy,
200
+ enforce_dependencies: other_package.enforce_dependencies,
201
+ dependencies: new_dependencies.uniq.sort,
202
+ violations: other_package.violations,
203
+ metadata: other_package.metadata,
204
+ config: new_config
205
+ )
206
+
207
+ ParsePackwerk.write_package_yml!(new_other_package)
208
+ end
209
+
210
+ sorbet_config = Pathname.new('sorbet/config')
211
+ if sorbet_config.exist?
212
+ Packs.replace_in_file(
213
+ file: sorbet_config.to_s,
214
+ find: package.directory.join('spec'),
215
+ replace_with: new_package.directory.join('spec')
216
+ )
217
+ end
218
+ end
219
+
143
220
  sig do
144
221
  params(
145
222
  pack_name: String,
@@ -348,7 +425,7 @@ module Packs
348
425
 
349
426
  sig { params(package: ParsePackwerk::Package).void }
350
427
  def self.add_public_directory(package)
351
- public_directory = package.directory.join('app/public')
428
+ public_directory = package.directory.join(package.public_path)
352
429
 
353
430
  if public_directory.glob('**/**.rb').none?
354
431
  FileUtils.mkdir_p(public_directory)
@@ -376,8 +453,9 @@ module Packs
376
453
  ).returns(ParsePackwerk::Package)
377
454
  end
378
455
  def self.create_pack_if_not_exists!(pack_name:, enforce_privacy:, enforce_dependencies:, team: nil)
379
- if PERMITTED_PACK_LOCATIONS.none? { |permitted_location| pack_name.start_with?(permitted_location) }
380
- raise StandardError, "Packs only supports packages in the the following directories: #{PERMITTED_PACK_LOCATIONS.inspect}. Please make sure to pass in the name of the pack including the full directory path, e.g. `packs/my_pack`."
456
+ allowed_locations = Packs::Specification.config.pack_paths
457
+ if allowed_locations.none? { |location| File.fnmatch(location, pack_name) }
458
+ raise StandardError, "Packs only supports packages in the the following directories: #{allowed_locations}. Please make sure to pass in the name of the pack including the full directory path, e.g. `packs/my_pack`."
381
459
  end
382
460
 
383
461
  existing_package = ParsePackwerk.all.find { |p| p.name == pack_name }
@@ -512,7 +590,10 @@ module Packs
512
590
  outbound: {}
513
591
  }
514
592
 
593
+ package_by_name = {}
594
+
515
595
  ParsePackwerk.all.each do |p|
596
+ package_by_name[p.name] = p
516
597
  p.violations.each do |violation|
517
598
  violations[:outbound][p.name] ||= []
518
599
  violations[:outbound][p.name] << violation
@@ -557,7 +638,7 @@ module Packs
557
638
  pack_name: pack.name,
558
639
  owner: owner.nil? ? 'No one' : owner.name,
559
640
  size: pack.relative_path.glob('**/*.rb').count,
560
- public_api: pack.relative_path.join('app/public')
641
+ public_api: pack.relative_path.join(package_by_name[pack.name].public_path)
561
642
  }
562
643
 
563
644
  row.delete(:date) unless include_date
@@ -23,7 +23,7 @@ module Packs
23
23
 
24
24
  2) Run `bin/packwerk update-todo` to update the violations. Make sure to run `spring stop` if you've added new load paths (new top-level directories) in your pack.
25
25
 
26
- 3) Expose public API in #{pack_name}/app/public. Try `bin/packs make_public #{pack_name}/path/to/file.rb`
26
+ 3) Expose public API in #{pack_name}/#{ParsePackwerk::DEFAULT_PUBLIC_PATH}. Try `bin/packs make_public #{pack_name}/path/to/file.rb`
27
27
 
28
28
  4) Update your readme at #{pack_name}/README.md
29
29
  MSG
@@ -45,7 +45,7 @@ module Packs
45
45
 
46
46
  2) Touch base with each team who owns files involved in this move
47
47
 
48
- 3) Expose public API in #{pack_name}/app/public. Try `bin/packs make_public #{pack_name}/path/to/file.rb`
48
+ 3) Expose public API in #{pack_name}/#{ParsePackwerk::DEFAULT_PUBLIC_PATH}. Try `bin/packs make_public #{pack_name}/path/to/file.rb`
49
49
 
50
50
  4) Update your readme at #{pack_name}/README.md
51
51
  MSG
@@ -105,6 +105,24 @@ module Packs
105
105
  MSG
106
106
  end
107
107
 
108
+ sig { params(pack_name: String).returns(String) }
109
+ def before_move_to_folder(pack_name)
110
+ <<~MSG
111
+ You are moving one pack to a new directory. Check out #{documentation_link} for more info!
112
+ MSG
113
+ end
114
+
115
+ sig { params(pack_name: String).returns(String) }
116
+ def after_move_to_folder(pack_name)
117
+ <<~MSG
118
+ Your next steps might be:
119
+
120
+ 1) Delete the old pack when things look good: `git rm -r #{pack_name}`
121
+
122
+ 2) Run `bin/packwerk update-todo` to update the violations. Make sure to run `spring stop` first.
123
+ MSG
124
+ end
125
+
108
126
  sig { params(pack_name: String).returns(String) }
109
127
  def on_create_public_directory_todo(pack_name)
110
128
  <<~MSG
@@ -136,7 +154,7 @@ module Packs
136
154
  If you're the author, please consider replacing this file with a README.md, which may contain:
137
155
  - What your pack is and does
138
156
  - How you expect people to use your pack
139
- - Example usage of your pack's public API (which lives in `#{pack_name}/app/public`)
157
+ - Example usage of your pack's public API (which lives in `#{pack_name}/#{ParsePackwerk::DEFAULT_PUBLIC_PATH}`)
140
158
  - Limitations, risks, and important considerations of usage
141
159
  - How to get in touch with eng and other stakeholders for questions or issues pertaining to this pack (note: it is recommended to add ownership in `#{pack_name}/package.yml` under the `owner` metadata key)
142
160
  - What SLAs/SLOs (service level agreements/objectives), if any, your package provides
@@ -157,7 +175,7 @@ module Packs
157
175
  Pass in a limit to display more or less, e.g. `bin/packs list_top_violations #{type} #{pack_name} -l 1000`
158
176
 
159
177
  This script is intended to help you find which of YOUR pack's private classes, constants, or modules other packs are using the most.
160
- Anything not in pack_name/app/public is considered private API.
178
+ Anything not in pack_name/#{ParsePackwerk::DEFAULT_PUBLIC_PATH} is considered private API.
161
179
  PACK_CONTENT
162
180
  else
163
181
  <<~PACK_CONTENT
@@ -165,7 +183,7 @@ module Packs
165
183
  Pass in a limit to display more or less, e.g. `bin/packs list_top_violations #{type} #{pack_name} -l 1000`
166
184
 
167
185
  This script is intended to help you find which of YOUR pack's private classes, constants, or modules other packs are using the most.
168
- Anything not in #{pack_name}/app/public is considered private API.
186
+ Anything not in #{pack_name}/#{ParsePackwerk::DEFAULT_PUBLIC_PATH} is considered private API.
169
187
  PACK_CONTENT
170
188
  end
171
189
  end
data/lib/packs.rb CHANGED
@@ -25,12 +25,6 @@ require 'packs/cli'
25
25
  module Packs
26
26
  extend T::Sig
27
27
 
28
- PERMITTED_PACK_LOCATIONS = T.let(%w[
29
- gems
30
- components
31
- packs
32
- ], T::Array[String])
33
-
34
28
  sig { void }
35
29
  def self.start_interactive_mode!
36
30
  Private::InteractiveCli.start!
@@ -184,6 +178,36 @@ module Packs
184
178
  end
185
179
  end
186
180
 
181
+ sig do
182
+ params(
183
+ pack_name: String,
184
+ destination: String,
185
+ per_file_processors: T::Array[PerFileProcessorInterface]
186
+ ).void
187
+ end
188
+ def self.move_to_folder!(
189
+ pack_name:,
190
+ destination:,
191
+ per_file_processors: [Packs::RubocopPostProcessor.new, Packs::CodeOwnershipPostProcessor.new]
192
+ )
193
+ Logging.section('👋 Hi!') do
194
+ intro = Packs.config.user_event_logger.before_move_to_folder(pack_name)
195
+ Logging.print_bold_green(intro)
196
+ end
197
+
198
+ Private.move_to_folder!(
199
+ pack_name: pack_name,
200
+ destination: destination,
201
+ per_file_processors: per_file_processors
202
+ )
203
+
204
+ Logging.section('Next steps') do
205
+ next_steps = Packs.config.user_event_logger.after_move_to_folder(pack_name)
206
+
207
+ Logging.print_bold_green(next_steps)
208
+ end
209
+ end
210
+
187
211
  sig do
188
212
  params(
189
213
  type: String,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.35
4
+ version: 0.0.37
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-24 00:00:00.000000000 Z
11
+ date: 2023-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: code_ownership