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 +4 -4
- data/README.md +6 -3
- data/lib/packs/cli.rb +12 -2
- data/lib/packs/private.rb +85 -4
- data/lib/packs/user_event_logger.rb +23 -5
- data/lib/packs.rb +30 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61faca4f667524b1ad3ac80486441315601f3ceda6ff04c413a1412b943e7df4
|
4
|
+
data.tar.gz: 347f3a70a95fb188497f7056f88925a5c9ecc409fc0b9561d35ce8fbe13ca191
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 (
|
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 (
|
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
|
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(
|
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
|
-
|
380
|
-
|
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(
|
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}
|
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}
|
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}
|
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
|
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}
|
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.
|
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
|
+
date: 2023-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: code_ownership
|