synvert-core 0.63.1 → 0.64.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -1
- data/README.md +73 -33
- data/lib/synvert/core/configuration.rb +12 -0
- data/lib/synvert/core/exceptions.rb +0 -4
- data/lib/synvert/core/node_ext.rb +188 -87
- data/lib/synvert/core/rewriter/action/append_action.rb +4 -3
- data/lib/synvert/core/rewriter/action/delete_action.rb +13 -6
- data/lib/synvert/core/rewriter/action/insert_action.rb +16 -7
- data/lib/synvert/core/rewriter/action/insert_after_action.rb +3 -2
- data/lib/synvert/core/rewriter/action/prepend_action.rb +3 -2
- data/lib/synvert/core/rewriter/action/remove_action.rb +16 -10
- data/lib/synvert/core/rewriter/action/replace_action.rb +13 -5
- data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +18 -11
- data/lib/synvert/core/rewriter/action/replace_with_action.rb +6 -5
- data/lib/synvert/core/rewriter/action/wrap_action.rb +13 -5
- data/lib/synvert/core/rewriter/action.rb +20 -9
- data/lib/synvert/core/rewriter/any_value.rb +1 -0
- data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +4 -0
- data/lib/synvert/core/rewriter/condition/if_only_exist_condition.rb +4 -0
- data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +4 -0
- data/lib/synvert/core/rewriter/condition.rb +11 -3
- data/lib/synvert/core/rewriter/gem_spec.rb +6 -3
- data/lib/synvert/core/rewriter/helper.rb +2 -2
- data/lib/synvert/core/rewriter/instance.rb +195 -94
- data/lib/synvert/core/rewriter/ruby_version.rb +4 -4
- data/lib/synvert/core/rewriter/scope/goto_scope.rb +5 -6
- data/lib/synvert/core/rewriter/scope/within_scope.rb +9 -4
- data/lib/synvert/core/rewriter/scope.rb +8 -0
- data/lib/synvert/core/rewriter/warning.rb +1 -1
- data/lib/synvert/core/rewriter.rb +90 -43
- data/lib/synvert/core/version.rb +1 -1
- data/lib/synvert/core.rb +0 -1
- data/spec/synvert/core/node_ext_spec.rb +0 -7
- data/spec/synvert/core/rewriter/action_spec.rb +0 -4
- data/spec/synvert/core/rewriter/gem_spec_spec.rb +1 -1
- data/spec/synvert/core/rewriter/instance_spec.rb +7 -17
- data/synvert-core-ruby.gemspec +2 -1
- metadata +20 -6
@@ -5,18 +5,8 @@ require 'fileutils'
|
|
5
5
|
module Synvert::Core
|
6
6
|
# Rewriter is the top level namespace in a snippet.
|
7
7
|
#
|
8
|
-
# One Rewriter can contain one or many
|
8
|
+
# One Rewriter checks if the depndency version matches, and it can contain one or many {Synvert::Core::Rewriter::Instance},
|
9
9
|
# which define the behavior what files and what codes to detect and rewrite to what code.
|
10
|
-
#
|
11
|
-
# Synvert::Rewriter.new 'factory_girl_short_syntax', 'use FactoryGirl short syntax' do
|
12
|
-
# if_gem 'factory_girl', '>= 2.0.0'
|
13
|
-
#
|
14
|
-
# within_files 'spec/**/*.rb' do
|
15
|
-
# with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
|
16
|
-
# replace_with "create({{arguments}})"
|
17
|
-
# end
|
18
|
-
# end
|
19
|
-
# end
|
20
10
|
class Rewriter
|
21
11
|
autoload :Action, 'synvert/core/rewriter/action'
|
22
12
|
autoload :AppendAction, 'synvert/core/rewriter/action/append_action'
|
@@ -53,7 +43,7 @@ module Synvert::Core
|
|
53
43
|
class << self
|
54
44
|
# Execute the temporary rewriter without group and name.
|
55
45
|
#
|
56
|
-
# @
|
46
|
+
# @yield defines the behaviors of the rewriter.
|
57
47
|
def execute(&block)
|
58
48
|
rewriter = Rewriter.new('', '', &block)
|
59
49
|
rewriter.process
|
@@ -91,7 +81,7 @@ module Synvert::Core
|
|
91
81
|
#
|
92
82
|
# @param group [String] the rewriter group.
|
93
83
|
# @param name [String] the rewriter name.
|
94
|
-
# @param sandbox [Boolean] if run in sandbox mode
|
84
|
+
# @param sandbox [Boolean] if run in sandbox mode.
|
95
85
|
# @return [Synvert::Core::Rewriter] the registered rewriter.
|
96
86
|
# @raise [Synvert::Core::RewriterNotFound] if the registered rewriter is not found.
|
97
87
|
def call(group, name, sandbox = false)
|
@@ -141,13 +131,12 @@ module Synvert::Core
|
|
141
131
|
# @return [Rewriter::GemSpec] the gem spec
|
142
132
|
attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec
|
143
133
|
|
144
|
-
# Initialize a
|
145
|
-
# When a rewriter is initialized, it is
|
134
|
+
# Initialize a Rewriter.
|
135
|
+
# When a rewriter is initialized, it is already registered.
|
146
136
|
#
|
147
137
|
# @param group [String] group of the rewriter.
|
148
138
|
# @param name [String] name of the rewriter.
|
149
|
-
# @
|
150
|
-
# @return [Synvert::Core::Rewriter]
|
139
|
+
# @yield defines the behaviors of the rewriter, block code won't be called when initialization.
|
151
140
|
def initialize(group, name, &block)
|
152
141
|
@group = group
|
153
142
|
@name = name
|
@@ -198,9 +187,12 @@ module Synvert::Core
|
|
198
187
|
# DSL #
|
199
188
|
#######
|
200
189
|
|
201
|
-
# Parse description dsl, it sets description of the rewrite.
|
190
|
+
# Parse +description+ dsl, it sets description of the rewrite.
|
202
191
|
# Or get description.
|
203
|
-
#
|
192
|
+
# @example
|
193
|
+
# Synvert::Rewriter.new 'rspec', 'use_new_syntax' do
|
194
|
+
# description 'It converts rspec code to new syntax, it calls all rspec sub snippets.'
|
195
|
+
# end
|
204
196
|
# @param description [String] rewriter description.
|
205
197
|
# @return rewriter description.
|
206
198
|
def description(description = nil)
|
@@ -211,24 +203,34 @@ module Synvert::Core
|
|
211
203
|
end
|
212
204
|
end
|
213
205
|
|
214
|
-
# Parse if_ruby dsl, it checks if ruby version
|
215
|
-
#
|
216
|
-
#
|
206
|
+
# Parse +if_ruby+ dsl, it checks if ruby version is greater than or equal to the specified ruby version.
|
207
|
+
# @example
|
208
|
+
# Synvert::Rewriter.new 'ruby', 'new_safe_navigation_operator' do
|
209
|
+
# if_ruby '2.3.0'
|
210
|
+
# end
|
211
|
+
# @param version [String] specified ruby version.
|
217
212
|
def if_ruby(version)
|
218
213
|
@ruby_version = Rewriter::RubyVersion.new(version)
|
219
214
|
end
|
220
215
|
|
221
|
-
# Parse if_gem dsl, it compares version of the specified gem.
|
222
|
-
#
|
216
|
+
# Parse +if_gem+ dsl, it compares version of the specified gem.
|
217
|
+
# @example
|
218
|
+
# Synvert::Rewriter.new 'rails', 'upgrade_5_2_to_6_0' do
|
219
|
+
# if_gem 'rails', '>= 6.0'
|
220
|
+
# end
|
223
221
|
# @param name [String] gem name.
|
224
222
|
# @param version [String] equal, less than or greater than specified version, e.g. '>= 2.0.0',
|
225
223
|
def if_gem(name, version)
|
226
224
|
@gem_spec = Rewriter::GemSpec.new(name, version)
|
227
225
|
end
|
228
226
|
|
229
|
-
# Parse within_files dsl, it finds specified files.
|
230
|
-
# It creates a
|
231
|
-
#
|
227
|
+
# Parse +within_files+ dsl, it finds specified files.
|
228
|
+
# It creates a {Synvert::Core::Rewriter::Instance} to rewrite code.
|
229
|
+
# @example
|
230
|
+
# Synvert::Rewriter.new 'rspec', 'be_close_to_be_within' do
|
231
|
+
# within_files '**/*.rb' do
|
232
|
+
# end
|
233
|
+
# end
|
232
234
|
# @param file_patterns [String|Array<String>] string pattern or list of string pattern to find files, e.g. ['spec/**/*_spec.rb']
|
233
235
|
# @param block [Block] the block to rewrite code in the matching files.
|
234
236
|
def within_files(file_patterns, &block)
|
@@ -240,11 +242,18 @@ module Synvert::Core
|
|
240
242
|
Rewriter::Instance.new(self, Array(file_patterns), &block).process
|
241
243
|
end
|
242
244
|
|
243
|
-
# Parse within_file dsl, it finds a specifiled file.
|
245
|
+
# Parse +within_file+ dsl, it finds a specifiled file.
|
244
246
|
alias within_file within_files
|
245
247
|
|
246
|
-
# Parses add_file dsl, it adds a new file.
|
247
|
-
#
|
248
|
+
# Parses +add_file+ dsl, it adds a new file.
|
249
|
+
# @example
|
250
|
+
# Synvert::Rewriter.new 'rails', 'add_application_record' do
|
251
|
+
# add_file 'app/models/application_record.rb', <<~EOS
|
252
|
+
# class ApplicationRecord < ActiveRecord::Base
|
253
|
+
# self.abstract_class = true
|
254
|
+
# end
|
255
|
+
# EOS
|
256
|
+
# end
|
248
257
|
# @param filename [String] file name of newly created file.
|
249
258
|
# @param content [String] file body of newly created file.
|
250
259
|
def add_file(filename, content)
|
@@ -257,13 +266,14 @@ module Synvert::Core
|
|
257
266
|
end
|
258
267
|
|
259
268
|
FileUtils.mkdir_p File.dirname(filepath)
|
260
|
-
File.
|
261
|
-
file.write content
|
262
|
-
end
|
269
|
+
File.write(filepath, content)
|
263
270
|
end
|
264
271
|
|
265
|
-
# Parses remove_file dsl, it removes a file.
|
266
|
-
#
|
272
|
+
# Parses +remove_file+ dsl, it removes a file.
|
273
|
+
# @example
|
274
|
+
# Synvert::Rewriter.new 'rails', 'upgrade_4_0_to_4_1' do
|
275
|
+
# remove_file 'config/initializers/secret_token.rb'
|
276
|
+
# end
|
267
277
|
# @param filename [String] file name.
|
268
278
|
def remove_file(filename)
|
269
279
|
return if @sandbox
|
@@ -272,26 +282,59 @@ module Synvert::Core
|
|
272
282
|
File.delete(file_path) if File.exist?(file_path)
|
273
283
|
end
|
274
284
|
|
275
|
-
# Parse add_snippet dsl, it calls anther rewriter.
|
276
|
-
#
|
285
|
+
# Parse +add_snippet+ dsl, it calls anther rewriter.
|
286
|
+
# @example
|
287
|
+
# Synvert::Rewriter.new 'minitest', 'better_syntax' do
|
288
|
+
# add_snippet 'minitest', 'assert_empty'
|
289
|
+
# add_snippet 'minitest', 'assert_equal_arguments_order'
|
290
|
+
# add_snippet 'minitest', 'assert_includes'
|
291
|
+
# add_snippet 'minitest', 'assert_instance_of'
|
292
|
+
# add_snippet 'minitest', 'assert_kind_of'
|
293
|
+
# add_snippet 'minitest', 'assert_match'
|
294
|
+
# add_snippet 'minitest', 'assert_nil'
|
295
|
+
# add_snippet 'minitest', 'assert_operator'
|
296
|
+
# add_snippet 'minitest', 'assert_path_exists'
|
297
|
+
# add_snippet 'minitest', 'assert_predicate'
|
298
|
+
# add_snippet 'minitest', 'assert_respond_to'
|
299
|
+
# add_snippet 'minitest', 'assert_silent'
|
300
|
+
# add_snippet 'minitest', 'assert_truthy'
|
301
|
+
# end
|
277
302
|
# @param group [String] group of another rewriter.
|
278
303
|
# @param name [String] name of another rewriter.
|
279
304
|
def add_snippet(group, name)
|
280
305
|
@sub_snippets << self.class.call(group.to_s, name.to_s, @sandbox)
|
281
306
|
end
|
282
307
|
|
283
|
-
# Parse helper_method dsl, it defines helper method for
|
284
|
-
#
|
308
|
+
# Parse +helper_method+ dsl, it defines helper method for {Synvert::Core::Rewriter::Instance}.
|
309
|
+
# @example
|
310
|
+
# Synvert::Rewriter.new 'rails', 'convert_active_record_dirty_5_0_to_5_1' do
|
311
|
+
# helper_method :find_callbacks_and_convert do |callback_names, callback_changes|
|
312
|
+
# # do anything, method find_callbacks_and_convert can be reused later.
|
313
|
+
# end
|
314
|
+
# within_files Synvert::RAILS_MODEL_FILES + Synvert::RAILS_OBSERVER_FILES do
|
315
|
+
# find_callbacks_and_convert(before_callback_names, before_callback_changes)
|
316
|
+
# find_callbacks_and_convert(after_callback_names, after_callback_changes)
|
317
|
+
# end
|
318
|
+
# end
|
285
319
|
# @param name [String] helper method name.
|
286
|
-
# @
|
320
|
+
# @yield helper method block.
|
287
321
|
def helper_method(name, &block)
|
288
322
|
@helpers << { name: name, block: block }
|
289
323
|
end
|
290
324
|
|
291
|
-
# Parse todo dsl, it sets todo of the rewriter.
|
325
|
+
# Parse +todo+ dsl, it sets todo of the rewriter.
|
292
326
|
# Or get todo.
|
293
|
-
#
|
294
|
-
#
|
327
|
+
# @example
|
328
|
+
# Synvert::Rewriter.new 'rails', 'upgrade_3_2_to_4_0' do
|
329
|
+
# todo <<~EOS
|
330
|
+
# 1. Rails 4.0 no longer supports loading plugins from vendor/plugins. You must replace any plugins by extracting them to gems and adding them to your Gemfile. If you choose not to make them gems, you can move them into, say, lib/my_plugin/* and add an appropriate initializer in config/initializers/my_plugin.rb.
|
331
|
+
# 2. Make the following changes to your Gemfile.
|
332
|
+
# gem 'sass-rails', '~> 4.0.0'
|
333
|
+
# gem 'coffee-rails', '~> 4.0.0'
|
334
|
+
# gem 'uglifier', '>= 1.3.0'
|
335
|
+
# EOS
|
336
|
+
# end
|
337
|
+
# @param todo [String] rewriter todo.
|
295
338
|
# @return [String] rewriter todo.
|
296
339
|
def todo(todo = nil)
|
297
340
|
if todo
|
@@ -302,6 +345,10 @@ module Synvert::Core
|
|
302
345
|
end
|
303
346
|
|
304
347
|
# Rerun the snippet until no change.
|
348
|
+
# @example
|
349
|
+
# Synvert::Rewriter.new 'ruby', 'nested_class_definition' do
|
350
|
+
# redo_until_no_change
|
351
|
+
# end
|
305
352
|
def redo_until_no_change
|
306
353
|
@redo_until_no_change = true
|
307
354
|
end
|
data/lib/synvert/core/version.rb
CHANGED
data/lib/synvert/core.rb
CHANGED
@@ -18,7 +18,6 @@ module Synvert
|
|
18
18
|
autoload :Rewriter, 'synvert/core/rewriter'
|
19
19
|
autoload :Engine, 'synvert/core/engine'
|
20
20
|
autoload :RewriterNotFound, 'synvert/core/exceptions'
|
21
|
-
autoload :GemfileLockNotFound, 'synvert/core/exceptions'
|
22
21
|
autoload :MethodNotSupported, 'synvert/core/exceptions'
|
23
22
|
end
|
24
23
|
end
|
@@ -404,13 +404,6 @@ describe Parser::AST::Node do
|
|
404
404
|
end
|
405
405
|
end
|
406
406
|
|
407
|
-
describe '#to_s' do
|
408
|
-
it 'gets for mlhs node' do
|
409
|
-
node = parse('var.each { |(param1, param2)| }')
|
410
|
-
expect(node.arguments.first.to_s).to eq '(param1, param2)'
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
407
|
describe '#filename' do
|
415
408
|
it 'gets file name' do
|
416
409
|
source = 'foobar'
|
@@ -46,7 +46,7 @@ module Synvert::Core
|
|
46
46
|
expect(gem_spec).not_to be_match
|
47
47
|
end
|
48
48
|
|
49
|
-
it '
|
49
|
+
it 'returns true if Gemfile.lock does not exist' do
|
50
50
|
expect(File).to receive(:exist?).with(lock_path).and_return(false)
|
51
51
|
gem_spec = Rewriter::GemSpec.new('ast', '1.1.0')
|
52
52
|
expect(gem_spec).to be_match
|
@@ -15,7 +15,7 @@ module Synvert::Core
|
|
15
15
|
scope = double
|
16
16
|
block = proc {}
|
17
17
|
expect(Rewriter::WithinScope).to receive(:new)
|
18
|
-
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: false }, &block)
|
18
|
+
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: false, direct: false }, &block)
|
19
19
|
.and_return(scope)
|
20
20
|
expect(scope).to receive(:process)
|
21
21
|
instance.within_node(type: 'send', message: 'create', &block)
|
@@ -25,40 +25,30 @@ module Synvert::Core
|
|
25
25
|
scope = double
|
26
26
|
block = proc {}
|
27
27
|
expect(Rewriter::WithinScope).to receive(:new)
|
28
|
-
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: false }, &block)
|
28
|
+
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: false, direct: false }, &block)
|
29
29
|
.and_return(scope)
|
30
30
|
expect(scope).to receive(:process)
|
31
31
|
instance.with_node(type: 'send', message: 'create', &block)
|
32
32
|
end
|
33
33
|
|
34
|
-
it 'parses within_node with
|
34
|
+
it 'parses within_node with stop_when_match true' do
|
35
35
|
scope = double
|
36
36
|
block = proc {}
|
37
37
|
expect(Rewriter::WithinScope).to receive(:new)
|
38
|
-
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: true }, &block)
|
38
|
+
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: true, direct: false }, &block)
|
39
39
|
.and_return(scope)
|
40
40
|
expect(scope).to receive(:process)
|
41
41
|
instance.within_node({ type: 'send', message: 'create' }, { stop_when_match: true }, &block)
|
42
42
|
end
|
43
43
|
|
44
|
-
it 'parses
|
44
|
+
it 'parses within_node with direct true' do
|
45
45
|
scope = double
|
46
46
|
block = proc {}
|
47
47
|
expect(Rewriter::WithinScope).to receive(:new)
|
48
|
-
.with(instance, { type: 'send', message: 'create' }, { direct: true }, &block)
|
48
|
+
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: false, direct: true }, &block)
|
49
49
|
.and_return(scope)
|
50
50
|
expect(scope).to receive(:process)
|
51
|
-
instance.
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'parses with_direct_node' do
|
55
|
-
scope = double
|
56
|
-
block = proc {}
|
57
|
-
expect(Rewriter::WithinScope).to receive(:new)
|
58
|
-
.with(instance, { type: 'send', message: 'create' }, { direct: true }, &block)
|
59
|
-
.and_return(scope)
|
60
|
-
expect(scope).to receive(:process)
|
61
|
-
instance.with_direct_node(type: 'send', message: 'create', &block)
|
51
|
+
instance.within_node({ type: 'send', message: 'create' }, { direct: true }, &block)
|
62
52
|
end
|
63
53
|
|
64
54
|
it 'parses goto_node' do
|
data/synvert-core-ruby.gemspec
CHANGED
@@ -27,5 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency "guard"
|
28
28
|
spec.add_development_dependency "guard-rspec"
|
29
29
|
spec.add_development_dependency "rake"
|
30
|
-
spec.add_development_dependency "rspec"
|
30
|
+
spec.add_development_dependency "rspec", "3.10.0"
|
31
|
+
spec.add_development_dependency "rspec-mocks", "3.10.2" # rspec-mocks 3.10.3 breaks tests
|
31
32
|
end
|
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: 0.
|
4
|
+
version: 0.64.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-02
|
11
|
+
date: 2022-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -112,16 +112,30 @@ dependencies:
|
|
112
112
|
name: rspec
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 3.10.0
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - '='
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: 3.10.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec-mocks
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 3.10.2
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 3.10.2
|
125
139
|
description: convert ruby code to better syntax automatically.
|
126
140
|
email:
|
127
141
|
- flyerhzm@gmail.com
|