synvert-core 1.13.1 → 1.14.0

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: 27baedce6ee22b8bac638cfab9caceb27f8fef82dd4af238b3b239ff64d9d19a
4
- data.tar.gz: 8e0ef98086e9a0e74d87ea62899628bb0271fcf1a011b380bc51e224061606e4
3
+ metadata.gz: c463c762e05473bfe948bce32491283f192da99afd514d4a32d9e144e86562d8
4
+ data.tar.gz: 142b810da918430620441d636e050c08b69abd84d6b1a14db9c76874fc4ce665
5
5
  SHA512:
6
- metadata.gz: 0aa91008955762f7a8f6362d0e23372651430e85eb6804b59c2cf9ea1577deda113c6dddf1ae92d44623bbd1bb3328f8414c0c8c8a910df9d575c294301e3c9a
7
- data.tar.gz: 3ec198c9d26fd0e8166dbaf102f606e89f52751f1152a50aa6283d525e848970765cf04d67bcb5f7ca6008c029c3c7f876a8a087d9d5ffbce688b0b22f4b4be6
6
+ metadata.gz: 87953d43e4e0988a29197c708e6dc1a453de2fde0ebd1d3bd44dc7b8b191558bfd54e8637674a8bb8ce152eb2825a86c434737a5e889484e1654fb5aeef92417
7
+ data.tar.gz: d1d43308e1f1afb0e1547aa79c14365e379376a666e83b0508fdd525aa00c9078cb780be671f43ed27597bc087e57a451494d603a33eaea19337008fdf846401
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.14.0 (2022-10-25)
4
+
5
+ * `insert_after` and `insert_before` accepts `to` option
6
+ * Add `configure` dsl to configure the strategy
7
+
3
8
  ## 1.13.1 (2022-10-17)
4
9
 
5
10
  * Do not send hash to keyword arguments
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- synvert-core (1.13.1)
4
+ synvert-core (1.14.0)
5
5
  activesupport (< 7.0.0)
6
6
  erubis
7
7
  node_mutation
@@ -50,10 +50,10 @@ GEM
50
50
  method_source (1.0.0)
51
51
  minitest (5.16.3)
52
52
  nenv (0.3.0)
53
- node_mutation (1.5.0)
53
+ node_mutation (1.7.0)
54
54
  activesupport (< 7.0.0)
55
55
  erubis
56
- node_query (1.8.1)
56
+ node_query (1.9.0)
57
57
  activesupport (< 7.0.0)
58
58
  notiffany (0.1.3)
59
59
  nenv (~> 0.1)
@@ -61,7 +61,7 @@ GEM
61
61
  parallel (1.22.1)
62
62
  parser (3.1.2.1)
63
63
  ast (~> 2.4.1)
64
- parser_node_ext (0.4.0)
64
+ parser_node_ext (0.4.1)
65
65
  parser
66
66
  pry (0.14.1)
67
67
  coderay (~> 1.1)
data/README.md CHANGED
@@ -59,6 +59,7 @@ Want to use the CLI, check out [synvert-ruby](https://github.com/xinminlabs/synv
59
59
 
60
60
  DSLs are as follows
61
61
 
62
+ * [configure](./Synvert/Core/Rewriter.html#configure-instance_method) - configure the rewriter
62
63
  * [description](./Synvert/Core/Rewriter.html#description-instance_method) - set description of the rewriter
63
64
  * [if_ruby](./Synvert/Core/Rewriter.html#if_ruby-instance_method) - check if ruby version is greater than or equal to the specified ruby version
64
65
  * [if_gem](./Synvert/Core/Rewriter.html#if_gem-instance_method) - compare version of specified gem
@@ -8,6 +8,7 @@ module Synvert::Core
8
8
  # One instance can contain one or many {Synvert::Core::Rewriter::Scope} and {Synvert::Rewriter::Condition}.
9
9
  class Rewriter::Instance
10
10
  include Rewriter::Helper
11
+
11
12
  # Initialize an Instance.
12
13
  #
13
14
  # @param rewriter [Synvert::Core::Rewriter]
@@ -18,6 +19,11 @@ module Synvert::Core
18
19
  @actions = []
19
20
  @file_patterns = file_patterns
20
21
  @block = block
22
+ strategy = NodeMutation::Strategy::KEEP_RUNNING
23
+ if rewriter.options[:strategy] == Strategy::ALLOW_INSERT_AT_SAME_POSITION
24
+ strategy |= NodeMutation::Strategy::ALLOW_INSERT_AT_SAME_POSITION
25
+ end
26
+ NodeMutation.configure({ strategy: strategy })
21
27
  rewriter.helpers.each { |helper| singleton_class.send(:define_method, helper[:name], &helper[:block]) }
22
28
  end
23
29
 
@@ -85,7 +91,7 @@ module Synvert::Core
85
91
  # DSL #
86
92
  #######
87
93
 
88
- # Parse +within_node+ dsl, it creates a {Synvert::Core::Rewriter::WithinScope} to recursively find matching ast nodes,
94
+ # It creates a {Synvert::Core::Rewriter::WithinScope} to recursively find matching ast nodes,
89
95
  # then continue operating on each matching ast node.
90
96
  # @example
91
97
  # # matches User.find_by_login('test')
@@ -109,7 +115,7 @@ module Synvert::Core
109
115
  alias with_node within_node
110
116
  alias find_node within_node
111
117
 
112
- # Parse +goto_node+ dsl, it creates a {Synvert::Core::Rewriter::GotoScope} to go to a child node,
118
+ # It creates a {Synvert::Core::Rewriter::GotoScope} to go to a child node,
113
119
  # then continue operating on the child node.
114
120
  # @example
115
121
  # # head status: 406
@@ -123,7 +129,7 @@ module Synvert::Core
123
129
  Rewriter::GotoScope.new(self, child_node_name, &block).process
124
130
  end
125
131
 
126
- # Parse +if_exist_node+ dsl, it creates a {Synvert::Core::Rewriter::IfExistCondition} to check
132
+ # It creates a {Synvert::Core::Rewriter::IfExistCondition} to check
127
133
  # if matching nodes exist in the child nodes, if so, then continue operating on each matching ast node.
128
134
  # @example
129
135
  # # Klass.any_instance.stub(:message)
@@ -137,7 +143,7 @@ module Synvert::Core
137
143
  Rewriter::IfExistCondition.new(self, nql_or_rules, &block).process
138
144
  end
139
145
 
140
- # Parse +unless_exist_node+ dsl, it creates a {Synvert::Core::Rewriter::UnlessExistCondition} to check
146
+ # It creates a {Synvert::Core::Rewriter::UnlessExistCondition} to check
141
147
  # if matching nodes doesn't exist in the child nodes, if so, then continue operating on each matching ast node.
142
148
  # @example
143
149
  # # obj.stub(:message)
@@ -151,7 +157,7 @@ module Synvert::Core
151
157
  Rewriter::UnlessExistCondition.new(self, nql_or_rules, &block).process
152
158
  end
153
159
 
154
- # Parse +if_only_exist_node+ dsl, it creates a {Synvert::Core::Rewriter::IfOnlyExistCondition} to check
160
+ # It creates a {Synvert::Core::Rewriter::IfOnlyExistCondition} to check
155
161
  # if current node has only one child node and the child node matches,
156
162
  # if so, then continue operating on each matching ast node.
157
163
  # @example
@@ -166,7 +172,7 @@ module Synvert::Core
166
172
  Rewriter::IfOnlyExistCondition.new(self, nql_or_rules, &block).process
167
173
  end
168
174
 
169
- # Parse +append+ dsl, it appends the code to the bottom of current node body.
175
+ # It appends the code to the bottom of current node body.
170
176
  # @example
171
177
  # # def teardown
172
178
  # # clean_something
@@ -184,7 +190,7 @@ module Synvert::Core
184
190
  @current_mutation.append(@current_node, code)
185
191
  end
186
192
 
187
- # Parse +prepend+ dsl, it prepends the code to the top of current node body.
193
+ # It prepends the code to the top of current node body.
188
194
  # @example
189
195
  # # def setup
190
196
  # # do_something
@@ -202,7 +208,7 @@ module Synvert::Core
202
208
  @current_mutation.prepend(@current_node, code)
203
209
  end
204
210
 
205
- # Parse +insert+ dsl, it inserts code.
211
+ # It inserts code.
206
212
  # @example
207
213
  # # open('http://test.com')
208
214
  # # =>
@@ -217,7 +223,7 @@ module Synvert::Core
217
223
  @current_mutation.insert(@current_node, code, at: at, to: to)
218
224
  end
219
225
 
220
- # Parse +insert_after+ dsl, it inserts the code next to the current node.
226
+ # It inserts the code next to the current node.
221
227
  # @example
222
228
  # # Synvert::Application.config.secret_token = "0447aa931d42918bfb934750bb78257088fb671186b5d1b6f9fddf126fc8a14d34f1d045cefab3900751c3da121a8dd929aec9bafe975f1cabb48232b4002e4e"
223
229
  # # =>
@@ -227,12 +233,12 @@ module Synvert::Core
227
233
  # insert_after "{{receiver}}.secret_key_base = \"#{SecureRandom.hex(64)}\""
228
234
  # end
229
235
  # @param code [String] code need to be inserted.
230
- def insert_after(code)
236
+ def insert_after(code, to: nil)
231
237
  column = ' ' * NodeMutation.adapter.get_start_loc(@current_node).column
232
- @current_mutation.insert(@current_node, "\n#{column}#{code}", at: 'end')
238
+ @current_mutation.insert(@current_node, "\n#{column}#{code}", at: 'end', to: to)
233
239
  end
234
240
 
235
- # Parse +insert_before+ dsl, it inserts the code previous to the current node.
241
+ # It inserts the code previous to the current node.
236
242
  # @example
237
243
  # # Synvert::Application.config.secret_token = "0447aa931d42918bfb934750bb78257088fb671186b5d1b6f9fddf126fc8a14d34f1d045cefab3900751c3da121a8dd929aec9bafe975f1cabb48232b4002e4e"
238
244
  # # =>
@@ -242,12 +248,12 @@ module Synvert::Core
242
248
  # insert_before "{{receiver}}.secret_key_base = \"#{SecureRandom.hex(64)}\""
243
249
  # end
244
250
  # @param code [String] code need to be inserted.
245
- def insert_before(code)
251
+ def insert_before(code, to: nil)
246
252
  column = ' ' * NodeMutation.adapter.get_start_loc(@current_node).column
247
- @current_mutation.insert(@current_node, "#{code}\n#{column}", at: 'beginning')
253
+ @current_mutation.insert(@current_node, "#{code}\n#{column}", at: 'beginning', to: to)
248
254
  end
249
255
 
250
- # Parse +replace_erb_stmt_with_expr+ dsl, it replaces erb stmt code to expr code.
256
+ # It replaces erb stmt code to expr code.
251
257
  # @example
252
258
  # # <% form_for post do |f| %>
253
259
  # # <% end %>
@@ -261,7 +267,7 @@ module Synvert::Core
261
267
  @current_mutation.actions << Rewriter::ReplaceErbStmtWithExprAction.new(@current_node).process
262
268
  end
263
269
 
264
- # Parse +replace_with+ dsl, it replaces the whole code of current node.
270
+ # It replaces the whole code of current node.
265
271
  # @example
266
272
  # # obj.stub(:foo => 1, :bar => 2)
267
273
  # # =>
@@ -274,7 +280,7 @@ module Synvert::Core
274
280
  @current_mutation.replace_with(@current_node, code)
275
281
  end
276
282
 
277
- # Parse +replace+ dsl, it replaces the code of specified child nodes.
283
+ # It replaces the code of specified child nodes.
278
284
  # @example
279
285
  # # assert(object.empty?)
280
286
  # # =>
@@ -289,7 +295,7 @@ module Synvert::Core
289
295
  @current_mutation.replace(@current_node, *selectors, with: with)
290
296
  end
291
297
 
292
- # Parse +remove+ dsl, it removes current node.
298
+ # It removes current node.
293
299
  # @example
294
300
  # with_node type: 'send', message: { in: %w[puts p] } do
295
301
  # remove
@@ -300,7 +306,7 @@ module Synvert::Core
300
306
  @current_mutation.remove(@current_node, **options)
301
307
  end
302
308
 
303
- # Parse +delete+ dsl, it deletes child nodes.
309
+ # It deletes child nodes.
304
310
  # @example
305
311
  # # FactoryBot.create(...)
306
312
  # # =>
@@ -315,7 +321,7 @@ module Synvert::Core
315
321
  @current_mutation.delete(@current_node, *selectors, **options)
316
322
  end
317
323
 
318
- # Parse +wrap+ dsl, it wraps current node with code.
324
+ # It wraps current node with code.
319
325
  # @example
320
326
  # # class Foobar
321
327
  # # end
@@ -332,12 +338,12 @@ module Synvert::Core
332
338
  @current_mutation.wrap(@current_node, with: with)
333
339
  end
334
340
 
335
- # Parse +noop dsl.
341
+ # No operation.
336
342
  def noop
337
343
  @current_mutation.noop(@current_node)
338
344
  end
339
345
 
340
- # Parse +warn+ dsl, it creates a {Synvert::Core::Rewriter::Warning} to save warning message.
346
+ # It creates a {Synvert::Core::Rewriter::Warning} to save warning message.
341
347
  # @example
342
348
  # within_files 'vendor/plugins' do
343
349
  # warn 'Rails::Plugin is deprecated and will be removed in Rails 4.0. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies.'
@@ -163,8 +163,18 @@ module Synvert::Core
163
163
  # DSL #
164
164
  #######
165
165
 
166
- # Parse +description+ dsl, it sets description of the rewrite.
167
- # Or get description.
166
+ # Configure the rewriter
167
+ # @example
168
+ # configure({ strategy: 'allow_insert_at_same_position' })
169
+ # @param options [Hash]
170
+ # @option strategy [String] allow_insert_at_same_position
171
+ def configure(options)
172
+ if options[:strategy]
173
+ @options[:strategy] = options[:strategy]
174
+ end
175
+ end
176
+
177
+ # It sets description of the rewrite or get description.
168
178
  # @example
169
179
  # Synvert::Rewriter.new 'rspec', 'use_new_syntax' do
170
180
  # description 'It converts rspec code to new syntax, it calls all rspec sub snippets.'
@@ -179,7 +189,7 @@ module Synvert::Core
179
189
  end
180
190
  end
181
191
 
182
- # Parse +if_ruby+ dsl, it checks if ruby version is greater than or equal to the specified ruby version.
192
+ # It checks if ruby version is greater than or equal to the specified ruby version.
183
193
  # @example
184
194
  # Synvert::Rewriter.new 'ruby', 'new_safe_navigation_operator' do
185
195
  # if_ruby '2.3.0'
@@ -189,7 +199,7 @@ module Synvert::Core
189
199
  @ruby_version = Rewriter::RubyVersion.new(version)
190
200
  end
191
201
 
192
- # Parse +if_gem+ dsl, it compares version of the specified gem.
202
+ # It compares version of the specified gem.
193
203
  # @example
194
204
  # Synvert::Rewriter.new 'rails', 'upgrade_5_2_to_6_0' do
195
205
  # if_gem 'rails', '>= 6.0'
@@ -200,7 +210,7 @@ module Synvert::Core
200
210
  @gem_spec = Rewriter::GemSpec.new(name, version)
201
211
  end
202
212
 
203
- # Parse +within_files+ dsl, it finds specified files.
213
+ # It finds specified files.
204
214
  # It creates a {Synvert::Core::Rewriter::Instance} to rewrite code.
205
215
  # @example
206
216
  # Synvert::Rewriter.new 'rspec', 'be_close_to_be_within' do
@@ -224,10 +234,10 @@ module Synvert::Core
224
234
  end
225
235
  end
226
236
 
227
- # Parse +within_file+ dsl, it finds a specifiled file.
237
+ # It finds a specifiled file.
228
238
  alias within_file within_files
229
239
 
230
- # Parses +add_file+ dsl, it adds a new file.
240
+ # It adds a new file.
231
241
  # @example
232
242
  # Synvert::Rewriter.new 'rails', 'add_application_record' do
233
243
  # add_file 'app/models/application_record.rb', <<~EOS
@@ -251,7 +261,7 @@ module Synvert::Core
251
261
  File.write(filepath, content)
252
262
  end
253
263
 
254
- # Parses +remove_file+ dsl, it removes a file.
264
+ # It removes a file.
255
265
  # @example
256
266
  # Synvert::Rewriter.new 'rails', 'upgrade_4_0_to_4_1' do
257
267
  # remove_file 'config/initializers/secret_token.rb'
@@ -264,7 +274,7 @@ module Synvert::Core
264
274
  File.delete(file_path) if File.exist?(file_path)
265
275
  end
266
276
 
267
- # Parse +add_snippet+ dsl, it calls anther rewriter.
277
+ # It calls anther rewriter.
268
278
  # @example
269
279
  # Synvert::Rewriter.new 'minitest', 'better_syntax' do
270
280
  # add_snippet 'minitest', 'assert_empty'
@@ -299,7 +309,7 @@ module Synvert::Core
299
309
  @sub_snippets << rewriter
300
310
  end
301
311
 
302
- # Parse +helper_method+ dsl, it defines helper method for {Synvert::Core::Rewriter::Instance}.
312
+ # It defines helper method for {Synvert::Core::Rewriter::Instance}.
303
313
  # @example
304
314
  # Synvert::Rewriter.new 'rails', 'convert_active_record_dirty_5_0_to_5_1' do
305
315
  # helper_method :find_callbacks_and_convert do |callback_names, callback_changes|
@@ -316,7 +326,7 @@ module Synvert::Core
316
326
  @helpers << { name: name, block: block }
317
327
  end
318
328
 
319
- # Parse +todo+ dsl, it sets todo of the rewriter.
329
+ # It sets todo of the rewriter.
320
330
  # Or get todo.
321
331
  # @example
322
332
  # Synvert::Rewriter.new 'rails', 'upgrade_3_2_to_4_0' do
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Synvert::Core
4
+ class Strategy
5
+ ALLOW_INSERT_AT_SAME_POSITION = "allow_insert_at_same_position"
6
+ end
7
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '1.13.1'
5
+ VERSION = '1.14.0'
6
6
  end
7
7
  end
data/lib/synvert/core.rb CHANGED
@@ -18,11 +18,13 @@ module Synvert
18
18
  autoload :Rewriter, 'synvert/core/rewriter'
19
19
  autoload :Engine, 'synvert/core/engine'
20
20
  autoload :Utils, 'synvert/core/utils'
21
+ autoload :Strategy, 'synvert/core/strategy'
21
22
  end
22
23
  end
23
24
 
24
25
  module Synvert
25
26
  Rewriter = Core::Rewriter
27
+ Strategy = Core::Strategy
26
28
 
27
29
  ALL_RUBY_FILES = %w[**/*.rb]
28
30
  ALL_RAKE_FILES = %w[**/*.rake]
@@ -128,7 +128,7 @@ module Synvert::Core
128
128
  instance.current_mutation = double
129
129
  instance.current_node = double
130
130
  expect(NodeMutation).to receive_message_chain(:adapter, :get_start_loc, :column).and_return(2)
131
- expect(instance.current_mutation).to receive(:insert).with(instance.current_node, "\n Foobar", at: 'end')
131
+ expect(instance.current_mutation).to receive(:insert).with(instance.current_node, "\n Foobar", at: 'end', to: nil)
132
132
  instance.insert_after 'Foobar'
133
133
  end
134
134
 
@@ -136,7 +136,7 @@ module Synvert::Core
136
136
  instance.current_mutation = double
137
137
  instance.current_node = double
138
138
  expect(NodeMutation).to receive_message_chain(:adapter, :get_start_loc, :column).and_return(2)
139
- expect(instance.current_mutation).to receive(:insert).with(instance.current_node, "Foobar\n ", at: 'beginning')
139
+ expect(instance.current_mutation).to receive(:insert).with(instance.current_node, "Foobar\n ", at: 'beginning', to: nil)
140
140
  instance.insert_before 'Foobar'
141
141
  end
142
142
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synvert-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.1
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-17 00:00:00.000000000 Z
11
+ date: 2022-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -146,6 +146,7 @@ files:
146
146
  - lib/synvert/core/rewriter/scope/goto_scope.rb
147
147
  - lib/synvert/core/rewriter/scope/within_scope.rb
148
148
  - lib/synvert/core/rewriter/warning.rb
149
+ - lib/synvert/core/strategy.rb
149
150
  - lib/synvert/core/utils.rb
150
151
  - lib/synvert/core/version.rb
151
152
  - spec/spec_helper.rb