use_packwerk 0.51.0 → 0.53.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: f2b4528c3f2bf62833a4e6098e9f316e02ac3d26174738805c42da0461109415
4
- data.tar.gz: 1d96176b9238a26ba97b82c5d231826f0a8485b8969bd9b74b13ed785cfbe917
3
+ metadata.gz: 4e5318956ac8b8fef165830d798565e79f0ef230686671fd0f66b81074b3d369
4
+ data.tar.gz: 8902e5d32f23d10916829928a1eff0c4d6e2b48163bf55a06f52fb32bdcfb544
5
5
  SHA512:
6
- metadata.gz: b2580a1e2bf19166f41e67ee0c6ad42052da9b49c3754251e9f898ba3839b41d29c68e97bc2a35ccd01b799078a6e6ebe2a00ec705e39b7e785c4b50169e35af
7
- data.tar.gz: 923ebb508fcfc122d1a1e01c7a2a6e2849258bcfb99bc2d543bea3fecd43e7f64d9467c003034d167ba9f3c4e9f6b3091284915d7e0f98cbfbd8dd45d9dee940
6
+ metadata.gz: 672a7e528294e21fe993ebeb2c9c22c048163374d15483a7cdc203a1c14f336a768538c68ab75febb77ee3eb1da0bd694aec1f32ea80ca621ddcade02798abb4
7
+ data.tar.gz: bcd5e51dfe5d3060babca2c650534ed1f8c55acb9e61f5e492c2adcd10a70998fbaa3b2cc014f3c5c9732159188b82b2e6bd6115d2b3cd155e15771ab5dee5f4
@@ -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,26 +143,62 @@ 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.
159
-
160
- 2) Update TODO lists for rubocop implemented protections. See #{UsePackwerk.config.documentation_link} for more info
161
-
162
- 3) Touch base with each team who owns files involved in this move
163
-
164
- 4) Expose public API in #{pack_name}/app/public. Try `bin/use_packwerk make_public #{pack_name}/path/to/file.rb`
165
-
166
- 5) Update your readme at #{pack_name}/README.md
167
- NEXT_STEPS
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
168
165
 
169
- Logging.print_bold_green(next_steps)
170
- end
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)
171
170
  end
172
171
 
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
+ # Add a dependency from parent to child
199
+ self.add_dependency!(pack_name: parent_name, dependency_name: new_package_name)
200
+ end
201
+
173
202
  sig do
174
203
  params(
175
204
  paths_relative_to_root: T::Array[String],
@@ -177,19 +206,12 @@ module UsePackwerk
177
206
  ).void
178
207
  end
179
208
  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
209
  if paths_relative_to_root.any?
188
210
  Logging.section('File Operations') do
189
211
  file_paths = paths_relative_to_root.flat_map do |path|
190
212
  origin_pathname = Pathname.new(path).cleanpath
191
213
  if origin_pathname.directory?
192
- origin_pathname.glob('**/*.rb').map(&:to_s)
214
+ origin_pathname.glob('**/*.*').map(&:to_s)
193
215
  else
194
216
  path
195
217
  end
@@ -197,19 +219,7 @@ module UsePackwerk
197
219
 
198
220
 
199
221
  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
-
222
+ package = T.must(ParsePackwerk.package_from_path(path))
213
223
  origin_pathname = Pathname.new(path).cleanpath
214
224
 
215
225
  FileMoveOperation.new(
@@ -225,22 +235,6 @@ module UsePackwerk
225
235
  end
226
236
  end
227
237
  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
238
  end
245
239
 
246
240
  sig do
@@ -250,13 +244,6 @@ module UsePackwerk
250
244
  ).void
251
245
  end
252
246
  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
247
  all_packages = ParsePackwerk.all
261
248
 
262
249
  pack_name = Private.clean_pack_name(pack_name)
@@ -279,18 +266,6 @@ module UsePackwerk
279
266
  metadata: package.metadata,
280
267
  )
281
268
  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
269
  end
295
270
 
296
271
  sig { params(file_move_operation: FileMoveOperation, per_file_processors: T::Array[UsePackwerk::PerFileProcessorInterface]).void }
@@ -427,6 +402,7 @@ module UsePackwerk
427
402
 
428
403
  sig { params(original_package: ParsePackwerk::Package).returns(ParsePackwerk::Package) }
429
404
  def self.rewrite_package_with_original_packwerk_values(original_package)
405
+ ParsePackwerk.bust_cache!
430
406
  package_with_protection_defaults = T.must(ParsePackwerk.all.find { |package| package.name == original_package.name })
431
407
  # PackageProtections also sets `enforce_privacy` and `enforce_dependency` to be true, so we set these back down to their original values
432
408
  package = ParsePackwerk::Package.new(
@@ -34,9 +34,11 @@ module UsePackwerk
34
34
  if destination_rubocop_todo.exist?
35
35
  new_destination_rubocop_todo = YAML.load_file(destination_rubocop_todo).dup
36
36
  else
37
- new_destination_rubocop_todo = { cop_name => { 'Exclude' => [] } }
37
+ new_destination_rubocop_todo = {}
38
38
  end
39
39
 
40
+ new_destination_rubocop_todo[cop_name] ||= { 'Exclude' => [] }
41
+
40
42
  new_destination_rubocop_todo[cop_name]['Exclude'] += [relative_path_to_destination.to_s]
41
43
  destination_rubocop_todo.write(YAML.dump(new_destination_rubocop_todo))
42
44
  end
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.0
4
+ version: 0.53.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-03 00:00:00.000000000 Z
11
+ date: 2022-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize