use_packwerk 0.51.1 → 0.54.0

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: 285e57f72e02b4ef6389a90efce2c9513028a72b9e5b1d9c9b0cbcf10c2c0c4b
4
- data.tar.gz: b3c901d0fbab3054bb30e1db668aca9833a4829d36d3e6ffc2555981d9d79fe0
3
+ metadata.gz: f058e80dcae7e5bc36702bf0ccf3d0e81b044c9f162ac66e74c99eec6bcc8cdb
4
+ data.tar.gz: 9536a0e463e7d7708e7843bdcefdd892e32343cf1a5ae670024eed1b116546a4
5
5
  SHA512:
6
- metadata.gz: 1a2fb745ee2c0f89e16f01d7793f86c4b8e2043a4fa7c3120c58d25651d6481d3b577f5208a75a8075de767796388f420bcabb78bd25a54cb30c3ece0858a68f
7
- data.tar.gz: cfa9a6db6615a488928182c1f0aec82a572a27f92b140580cb3656df404a0e9071e9f03ae7ad7e42d146de87641604281b4e4979d2601fa76fc67dc2ef4a671b
6
+ metadata.gz: 703bbd5300f6565a690563b9bf86ee8d23d91d52a0a48a75b162350aeac3a6455d6ec8fb38c22a43c334700890c0ccb5d5bcffdabe7672b064e295932dcf9df2
7
+ data.tar.gz: 61302158b9f8afba60a256079350e03c9484ec97a5e241e516ab33031593b36882910b7e32d1fb5e9044575d5e3b79c68eb98b4cd1026a0eafcd2dbcdac55b9e
@@ -67,5 +67,15 @@ module UsePackwerk
67
67
  per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new],
68
68
  )
69
69
  end
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!"
72
+ sig { params(parent_name: String, pack_name: String).void }
73
+ def move_to_parent(parent_name, pack_name)
74
+ UsePackwerk.move_to_parent!(
75
+ parent_name: parent_name,
76
+ pack_name: pack_name,
77
+ per_file_processors: [UsePackwerk::RubocopPostProcessor.new, UsePackwerk::CodeOwnershipPostProcessor.new],
78
+ )
79
+ end
70
80
  end
71
81
  end
@@ -9,24 +9,29 @@ 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
- puts ColorizedString.new("#{title}").green.bold
13
- puts "\n"
12
+ out ColorizedString.new("#{title}").green.bold
13
+ out "\n"
14
14
  yield
15
15
  end
16
16
 
17
17
  sig { params(text: String).void }
18
18
  def self.print_bold_green(text)
19
- puts ColorizedString.new(text).green.bold
19
+ out ColorizedString.new(text).green.bold
20
20
  end
21
21
 
22
22
  sig { params(text: String).void }
23
23
  def self.print(text)
24
- puts text
24
+ out text
25
25
  end
26
26
 
27
27
  sig { void }
28
28
  def self.print_divider
29
- puts '=' * 100
29
+ out '=' * 100
30
+ end
31
+
32
+ sig { params(str: String).void }
33
+ def self.out(str)
34
+ puts str
30
35
  end
31
36
  end
32
37
  end
@@ -16,37 +16,37 @@ module UsePackwerk
16
16
 
17
17
  sig { params(origin_pathname: Pathname, new_package_root: Pathname).returns(Pathname) }
18
18
  def self.destination_pathname_for_package_move(origin_pathname, new_package_root)
19
- parts = origin_pathname.to_s.split('/')
20
- toplevel_directory = parts[0]
19
+ origin_pack = T.must(ParsePackwerk.package_from_path(origin_pathname))
21
20
 
22
- case toplevel_directory.to_s
23
- # This allows us to move files from monolith to packs
24
- when 'app', 'spec', 'lib'
21
+ new_implementation = nil
22
+ if origin_pack.name == ParsePackwerk::ROOT_PACKAGE_NAME
25
23
  new_package_root.join(origin_pathname).cleanpath
26
- # This allows us to move files from packs to packs
27
- when *PERMITTED_PACK_LOCATIONS # parts looks like ['packs', 'organisms', 'app', 'services', 'bird_like', 'eagle.rb']
28
- new_package_root.join(T.must(parts[2..]).join('/')).cleanpath
29
24
  else
30
- raise StandardError.new("Don't know how to find destination path for #{origin_pathname.inspect}")
25
+ Pathname.new(origin_pathname.to_s.gsub(origin_pack.name, new_package_root.to_s)).cleanpath
31
26
  end
32
27
  end
33
28
 
34
29
  sig { params(origin_pathname: Pathname).returns(Pathname) }
35
30
  def self.destination_pathname_for_new_public_api(origin_pathname)
36
- parts = origin_pathname.to_s.split('/')
37
- toplevel_directory = Pathname.new(parts[0])
38
31
 
39
- case toplevel_directory.to_s
40
- # This allows us to make API in the monolith public
41
- when 'app', 'spec'
42
- toplevel_directory.join('public').join(T.must(parts[2..]).join('/')).cleanpath
43
- # This allows us to make API in existing packs public
44
- when *PERMITTED_PACK_LOCATIONS # parts looks like ['packs', 'organisms', 'app', 'services', 'bird_like', 'eagle.rb']
45
- pack_name = Pathname.new(parts[1])
46
- toplevel_directory.join(pack_name).join('app/public').join(T.must(parts[4..]).join('/')).cleanpath
32
+ origin_pack = T.must(ParsePackwerk.package_from_path(origin_pathname))
33
+ if origin_pack.name == ParsePackwerk::ROOT_PACKAGE_NAME
34
+ filepath_without_pack_name = origin_pathname.to_s
47
35
  else
48
- raise StandardError.new("Don't know how to find destination path for #{origin_pathname.inspect}")
36
+ filepath_without_pack_name = origin_pathname.to_s.gsub("#{origin_pack.name}/", '')
49
37
  end
38
+
39
+ # We join the pack name with the rest of the path...
40
+ path_parts = filepath_without_pack_name.split("/")
41
+ Pathname.new(origin_pack.name).join(
42
+ # ... keeping the "app" or "spec"
43
+ T.must(path_parts[0]),
44
+ # ... substituting "controllers," "services," etc. with "public"
45
+ 'public',
46
+ # ... then the rest is the same
47
+ T.must(path_parts[2..]).join("/")
48
+ # and we take the cleanpath so `./app/...` becomes `app/...`
49
+ ).cleanpath
50
50
  end
51
51
 
52
52
  sig { returns(FileMoveOperation) }
@@ -96,16 +96,6 @@ module UsePackwerk
96
96
  raise StandardError.new("Can not find package with name #{pack_name}. Make sure the argument is of the form `packs/my_pack/`")
97
97
  end
98
98
 
99
- Logging.section('👋 Hi!') do
100
- intro = <<~INTRO
101
- You are moving a file to a pack, which is great. Check out #{UsePackwerk.config.documentation_link} for more info!
102
-
103
- Please bring any questions or issues you have in your development process to #ruby-modularity or #product-infrastructure.
104
- We'd be happy to try to help through pairing, accepting feedback, changing our process, changing our tools, and more.
105
- INTRO
106
- Logging.print_bold_green(intro)
107
- end
108
-
109
99
  add_public_directory(package)
110
100
  add_readme_todo(package)
111
101
  package_location = package.directory
@@ -128,7 +118,10 @@ module UsePackwerk
128
118
  # Later, if we choose to go back to moving whole directories at a time, it should be a refactor and all tests should still pass
129
119
  #
130
120
  if origin_pathname.directory?
131
- origin_pathname.glob('**/*.{rb,rake,erb}')
121
+ origin_pathname.glob('**/*.*').reject do |path|
122
+ path.to_s.include?(ParsePackwerk::PACKAGE_YML_NAME) ||
123
+ path.to_s.include?(ParsePackwerk::DEPRECATED_REFERENCES_YML_NAME)
124
+ end
132
125
  else
133
126
  origin_pathname
134
127
  end
@@ -150,25 +143,86 @@ module UsePackwerk
150
143
  per_file_processors.each do |per_file_processor|
151
144
  per_file_processor.print_final_message!
152
145
  end
146
+ end
153
147
 
154
- Logging.section('Next steps') do
155
- next_steps = <<~NEXT_STEPS
156
- Your next steps might be:
157
-
158
- 1) Run `bin/packwerk update-deprecations` to update the violations. Make sure to run `spring stop` if you've added new load paths (new top-level directories) in your pack.
148
+ sig do
149
+ params(
150
+ pack_name: String,
151
+ parent_name: String,
152
+ per_file_processors: T::Array[PerFileProcessorInterface],
153
+ ).void
154
+ end
155
+ def self.move_to_parent!(
156
+ pack_name:,
157
+ parent_name:,
158
+ per_file_processors: []
159
+ )
160
+ pack_name = Private.clean_pack_name(pack_name)
161
+ package = ParsePackwerk.all.find { |package| package.name == pack_name }
162
+ if package.nil?
163
+ raise StandardError.new("Can not find package with name #{pack_name}. Make sure the argument is of the form `packs/my_pack/`")
164
+ end
159
165
 
160
- 2) Update TODO lists for rubocop implemented protections. See #{UsePackwerk.config.documentation_link} for more info
166
+ parent_name = Private.clean_pack_name(parent_name)
167
+ parent_package = ParsePackwerk.all.find { |package| package.name == parent_name }
168
+ if parent_package.nil?
169
+ parent_package = create_pack_if_not_exists!(pack_name: parent_name, enforce_privacy: true, enforce_dependencies: true)
170
+ end
161
171
 
162
- 3) Touch base with each team who owns files involved in this move
172
+ # First we create a new pack that has the exact same properties of the old one!
173
+ package_last_name = package.directory.basename
174
+ new_package_name = parent_package.directory.join(package_last_name).to_s
175
+
176
+ new_package = ParsePackwerk::Package.new(
177
+ name: new_package_name,
178
+ enforce_privacy: package.enforce_dependencies,
179
+ enforce_dependencies: package.enforce_dependencies,
180
+ dependencies: package.dependencies,
181
+ metadata: package.metadata,
182
+ )
183
+ ParsePackwerk.write_package_yml!(new_package)
184
+ ParsePackwerk.bust_cache!
185
+
186
+ # Move everything from the old pack to the new one
187
+ self.move_to_pack!(
188
+ pack_name: new_package_name,
189
+ paths_relative_to_root: [package.directory.to_s],
190
+ per_file_processors: per_file_processors,
191
+ )
192
+
193
+ # Then delete the old package.yml and deprecated_references.yml files
194
+ package.yml.delete
195
+ deprecated_references_file = ParsePackwerk::DeprecatedReferences.for(package).pathname
196
+ deprecated_references_file.delete if deprecated_references_file.exist?
197
+
198
+ ParsePackwerk.bust_cache!
199
+
200
+ ParsePackwerk.all.each do |other_package|
201
+ new_dependencies = other_package.dependencies.map{|d| d == pack_name ? new_package_name : d}
202
+ if other_package.name == parent_name && !new_dependencies.include?(new_package_name)
203
+ new_dependencies += [new_package_name]
204
+ end
163
205
 
164
- 4) Expose public API in #{pack_name}/app/public. Try `bin/use_packwerk make_public #{pack_name}/path/to/file.rb`
206
+ new_other_package = ParsePackwerk::Package.new(
207
+ name: other_package.name,
208
+ enforce_privacy: other_package.enforce_dependencies,
209
+ enforce_dependencies: other_package.enforce_dependencies,
210
+ dependencies: new_dependencies.uniq.sort,
211
+ metadata: other_package.metadata,
212
+ )
165
213
 
166
- 5) Update your readme at #{pack_name}/README.md
167
- NEXT_STEPS
214
+ ParsePackwerk.write_package_yml!(new_other_package)
215
+ end
168
216
 
169
- Logging.print_bold_green(next_steps)
170
- end
217
+ sorbet_config = Pathname.new('sorbet/config')
218
+ if sorbet_config.exist?
219
+ UsePackwerk.replace_in_file(
220
+ file: sorbet_config.to_s,
221
+ find: package.directory.join('spec'),
222
+ replace_with: new_package.directory.join('spec'),
223
+ )
171
224
  end
225
+ end
172
226
 
173
227
  sig do
174
228
  params(
@@ -177,19 +231,12 @@ module UsePackwerk
177
231
  ).void
178
232
  end
179
233
  def self.make_public!(paths_relative_to_root:, per_file_processors:)
180
- Logging.section('Making files public') do
181
- intro = <<~INTRO
182
- You are moving some files into public API. See #{UsePackwerk.config.documentation_link} for other utilities!
183
- INTRO
184
- Logging.print_bold_green(intro)
185
- end
186
-
187
234
  if paths_relative_to_root.any?
188
235
  Logging.section('File Operations') do
189
236
  file_paths = paths_relative_to_root.flat_map do |path|
190
237
  origin_pathname = Pathname.new(path).cleanpath
191
238
  if origin_pathname.directory?
192
- origin_pathname.glob('**/*.rb').map(&:to_s)
239
+ origin_pathname.glob('**/*.*').map(&:to_s)
193
240
  else
194
241
  path
195
242
  end
@@ -197,19 +244,7 @@ module UsePackwerk
197
244
 
198
245
 
199
246
  file_move_operations = file_paths.map do |path|
200
- parts = path.to_s.split('/')
201
- first_part_of_path = T.must(parts[0])
202
-
203
- if Pathname.new(first_part_of_path).dirname.join(ParsePackwerk::PACKAGE_YML_NAME).exist?
204
- package_location = Pathname.new('.')
205
- elsif PERMITTED_PACK_LOCATIONS.include?(first_part_of_path)
206
- package_location = Pathname.new(first_part_of_path).join(T.must(parts[1]))
207
- else
208
- raise StandardError.new('Can only make files in the monolith or in existing packs public')
209
- end
210
-
211
- package = ParsePackwerk::Package.from(package_location.join(ParsePackwerk::PACKAGE_YML_NAME))
212
-
247
+ package = T.must(ParsePackwerk.package_from_path(path))
213
248
  origin_pathname = Pathname.new(path).cleanpath
214
249
 
215
250
  FileMoveOperation.new(
@@ -225,22 +260,6 @@ module UsePackwerk
225
260
  end
226
261
  end
227
262
  end
228
-
229
- Logging.section('Next steps') do
230
- next_steps = <<~NEXT_STEPS
231
- Your next steps might be:
232
-
233
- 1) Run `bin/packwerk update-deprecations` to update the violations. Make sure to run `spring stop` if you've added new load paths (new top-level directories) in your pack.
234
-
235
- 2) Update TODO lists for rubocop implemented protections. See #{UsePackwerk.config.documentation_link} for more info
236
-
237
- 3) Work to migrate clients of private API to your new public API
238
-
239
- 4) Update your README at packs/your_package_name/README.md
240
- NEXT_STEPS
241
-
242
- Logging.print_bold_green(next_steps)
243
- end
244
263
  end
245
264
 
246
265
  sig do
@@ -250,13 +269,6 @@ module UsePackwerk
250
269
  ).void
251
270
  end
252
271
  def self.add_dependency!(pack_name:, dependency_name:)
253
- Logging.section('Adding a dependency') do
254
- intro = <<~INTRO
255
- You are adding a dependency. See #{UsePackwerk.config.documentation_link} for other utilities!
256
- INTRO
257
- Logging.print_bold_green(intro)
258
- end
259
-
260
272
  all_packages = ParsePackwerk.all
261
273
 
262
274
  pack_name = Private.clean_pack_name(pack_name)
@@ -279,18 +291,6 @@ module UsePackwerk
279
291
  metadata: package.metadata,
280
292
  )
281
293
  ParsePackwerk.write_package_yml!(new_package)
282
-
283
- Logging.section('Next steps') do
284
- next_steps = <<~NEXT_STEPS
285
- Your next steps might be:
286
-
287
- 1) Run `bin/packwerk validate` to ensure you haven't introduced a cyclic dependency
288
-
289
- 2) Run `bin/packwerk update-deprecations` to update the violations.
290
- NEXT_STEPS
291
-
292
- Logging.print_bold_green(next_steps)
293
- end
294
294
  end
295
295
 
296
296
  sig { params(file_move_operation: FileMoveOperation, per_file_processors: T::Array[UsePackwerk::PerFileProcessorInterface]).void }
@@ -427,6 +427,7 @@ module UsePackwerk
427
427
 
428
428
  sig { params(original_package: ParsePackwerk::Package).returns(ParsePackwerk::Package) }
429
429
  def self.rewrite_package_with_original_packwerk_values(original_package)
430
+ ParsePackwerk.bust_cache!
430
431
  package_with_protection_defaults = T.must(ParsePackwerk.all.find { |package| package.name == original_package.name })
431
432
  # PackageProtections also sets `enforce_privacy` and `enforce_dependency` to be true, so we set these back down to their original values
432
433
  package = ParsePackwerk::Package.new(
data/lib/use_packwerk.rb CHANGED
@@ -61,11 +61,39 @@ module UsePackwerk
61
61
  paths_relative_to_root: [],
62
62
  per_file_processors: []
63
63
  )
64
+ Logging.section('👋 Hi!') do
65
+ intro = <<~INTRO
66
+ You are moving a file to a pack, which is great. Check out #{UsePackwerk.config.documentation_link} for more info!
67
+
68
+ Please bring any questions or issues you have in your development process to #ruby-modularity or #product-infrastructure.
69
+ We'd be happy to try to help through pairing, accepting feedback, changing our process, changing our tools, and more.
70
+ INTRO
71
+ Logging.print_bold_green(intro)
72
+ end
73
+
64
74
  Private.move_to_pack!(
65
75
  pack_name: pack_name,
66
76
  paths_relative_to_root: paths_relative_to_root,
67
77
  per_file_processors: per_file_processors,
68
78
  )
79
+
80
+ Logging.section('Next steps') do
81
+ next_steps = <<~NEXT_STEPS
82
+ Your next steps might be:
83
+
84
+ 1) Run `bin/packwerk update-deprecations` to update the violations. Make sure to run `spring stop` if you've added new load paths (new top-level directories) in your pack.
85
+
86
+ 2) Update TODO lists for rubocop implemented protections. See #{UsePackwerk.config.documentation_link} for more info
87
+
88
+ 3) Touch base with each team who owns files involved in this move
89
+
90
+ 4) Expose public API in #{pack_name}/app/public. Try `bin/use_packwerk make_public #{pack_name}/path/to/file.rb`
91
+
92
+ 5) Update your readme at #{pack_name}/README.md
93
+ NEXT_STEPS
94
+
95
+ Logging.print_bold_green(next_steps)
96
+ end
69
97
  end
70
98
 
71
99
  sig do
@@ -78,10 +106,33 @@ module UsePackwerk
78
106
  paths_relative_to_root: [],
79
107
  per_file_processors: []
80
108
  )
109
+ Logging.section('Making files public') do
110
+ intro = <<~INTRO
111
+ You are moving some files into public API. See #{UsePackwerk.config.documentation_link} for other utilities!
112
+ INTRO
113
+ Logging.print_bold_green(intro)
114
+ end
115
+
81
116
  Private.make_public!(
82
117
  paths_relative_to_root: paths_relative_to_root,
83
118
  per_file_processors: per_file_processors
84
119
  )
120
+
121
+ Logging.section('Next steps') do
122
+ next_steps = <<~NEXT_STEPS
123
+ Your next steps might be:
124
+
125
+ 1) Run `bin/packwerk update-deprecations` to update the violations. Make sure to run `spring stop` if you've added new load paths (new top-level directories) in your pack.
126
+
127
+ 2) Update TODO lists for rubocop implemented protections. See #{UsePackwerk.config.documentation_link} for more info
128
+
129
+ 3) Work to migrate clients of private API to your new public API
130
+
131
+ 4) Update your README at packs/your_package_name/README.md
132
+ NEXT_STEPS
133
+
134
+ Logging.print_bold_green(next_steps)
135
+ end
85
136
  end
86
137
 
87
138
  sig do
@@ -94,10 +145,70 @@ module UsePackwerk
94
145
  pack_name:,
95
146
  dependency_name:
96
147
  )
148
+ Logging.section('Adding a dependency') do
149
+ intro = <<~INTRO
150
+ You are adding a dependency. See #{UsePackwerk.config.documentation_link} for other utilities!
151
+ INTRO
152
+ Logging.print_bold_green(intro)
153
+ end
154
+
97
155
  Private.add_dependency!(
98
156
  pack_name: pack_name,
99
157
  dependency_name: dependency_name
100
158
  )
159
+
160
+ Logging.section('Next steps') do
161
+ next_steps = <<~NEXT_STEPS
162
+ Your next steps might be:
163
+
164
+ 1) Run `bin/packwerk validate` to ensure you haven't introduced a cyclic dependency
165
+
166
+ 2) Run `bin/packwerk update-deprecations` to update the violations.
167
+ NEXT_STEPS
168
+
169
+ Logging.print_bold_green(next_steps)
170
+ end
171
+ end
172
+
173
+ sig do
174
+ params(
175
+ pack_name: String,
176
+ parent_name: String,
177
+ per_file_processors: T::Array[PerFileProcessorInterface],
178
+ ).void
179
+ end
180
+ def self.move_to_parent!(
181
+ pack_name:,
182
+ parent_name:,
183
+ per_file_processors: []
184
+ )
185
+ Logging.section('👋 Hi!') do
186
+ intro = <<~INTRO
187
+ You are moving one pack to be a child of a different pack. Check out #{UsePackwerk.config.documentation_link} for more info!
188
+
189
+ Please bring any questions or issues you have in your development process to #ruby-modularity or #product-infrastructure.
190
+ We'd be happy to try to help through pairing, accepting feedback, changing our process, changing our tools, and more.
191
+ INTRO
192
+ Logging.print_bold_green(intro)
193
+ end
194
+
195
+ Private.move_to_parent!(
196
+ pack_name: pack_name,
197
+ parent_name: parent_name,
198
+ per_file_processors: per_file_processors,
199
+ )
200
+
201
+ Logging.section('Next steps') do
202
+ next_steps = <<~NEXT_STEPS
203
+ Your next steps might be:
204
+
205
+ 1) Delete the old pack when things look good: `rm -rf #{pack_name}`
206
+
207
+ 2) Run `bin/packwerk update-deprecations` to update the violations. Make sure to run `spring stop` first.
208
+ NEXT_STEPS
209
+
210
+ Logging.print_bold_green(next_steps)
211
+ end
101
212
  end
102
213
 
103
214
  sig do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: use_packwerk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.51.1
4
+ version: 0.54.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-04 00:00:00.000000000 Z
11
+ date: 2022-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize