packs 0.0.35 → 0.0.37

Sign up to get free protection for your applications and to get access to all the features.
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