synvert 1.4.7 → 1.5.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: 6eade43328f9d5aba7b9d9449dfb5dc15486a6f873de4d3b218bdd15ee641f36
4
- data.tar.gz: 7bf99ac9fe64b3735d546cc4cc008fdcaf3a6bcbea683c619b5bdaeaf710a5c0
3
+ metadata.gz: 202949a760e4597b388d3f01804eac78e1caa59f1bcf54af018923e8e70e57ac
4
+ data.tar.gz: 2a9122faffaabade6bfd688ece159012e14da7699f3ab40e458b417a8e5568a6
5
5
  SHA512:
6
- metadata.gz: 07bac2ce5407c8de8547fbb1b6ab19beec293d024ae6b85369baa4b9737754aa24ab7f1ea6738bb170a5cb4390ae2c85a52a7dd844415211511c6e8f4fa4b9ce
7
- data.tar.gz: ffda87151ed06cd72cee9d48236d8b29f2e4dba26d1bb56083b3df04705471aa99f0aa8a9c0407514500dc8069f1e7ea65fb494417fddf49d7ca79c4928c43ca
6
+ metadata.gz: 1a0c7ce37d608c40fe040d1ae59323e97bf34531e982f0123ef1be5381d4e480c5523dd1947f71eeaf781e1ff47351243d67e69503265917b7f0f3d08387b13e
7
+ data.tar.gz: 3b2f3add6f28774ae73f1ad2ad517cef9920654311ba9451268459a743c7de9621bf2dcaa6ba0e2d36a648e9be9e487e8a1ec969d3d132b4b6010281fe243b4f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.5.0 (2023-10-28)
4
+
5
+ * Update `synvert-core` to 1.29.3
6
+ * Remove `bin/synvert`
7
+ * Add `guard` for test
8
+ * Abstract `Synvert::Command`
9
+
3
10
  ## 1.4.5 (2023-07-03)
4
11
 
5
12
  * Update `synvert-core` to 1.28.3
data/Gemfile CHANGED
@@ -5,4 +5,7 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in synvert.gemspec
6
6
  gemspec
7
7
 
8
- gem 'coveralls', require: false
8
+ gem 'guard'
9
+ gem 'guard-rspec'
10
+ gem 'rake'
11
+ gem 'rspec'
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- synvert (1.4.7)
5
- synvert-core (>= 1.28.3)
4
+ synvert (1.5.0)
5
+ synvert-core (>= 1.29.3)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -13,36 +13,53 @@ GEM
13
13
  minitest (>= 5.1)
14
14
  tzinfo (~> 2.0)
15
15
  zeitwerk (~> 2.3)
16
- addressable (2.8.0)
17
- public_suffix (>= 2.0.2, < 5.0)
18
16
  ast (2.4.2)
17
+ coderay (1.1.3)
19
18
  concurrent-ruby (1.2.2)
20
- coveralls (0.8.23)
21
- json (>= 1.8, < 3)
22
- simplecov (~> 0.16.1)
23
- term-ansicolor (~> 1.3)
24
- thor (>= 0.19.4, < 2.0)
25
- tins (~> 1.6)
26
- crack (0.4.5)
27
- rexml
28
19
  diff-lcs (1.4.4)
29
- docile (1.4.0)
30
- hashdiff (1.0.1)
20
+ ffi (1.16.3)
21
+ formatador (1.1.0)
22
+ guard (2.18.1)
23
+ formatador (>= 0.2.4)
24
+ listen (>= 2.7, < 4.0)
25
+ lumberjack (>= 1.0.12, < 2.0)
26
+ nenv (~> 0.1)
27
+ notiffany (~> 0.0)
28
+ pry (>= 0.13.0)
29
+ shellany (~> 0.0)
30
+ thor (>= 0.18.1)
31
+ guard-compat (1.2.1)
32
+ guard-rspec (4.7.3)
33
+ guard (~> 2.1)
34
+ guard-compat (~> 1.1)
35
+ rspec (>= 2.99.0, < 4.0)
31
36
  i18n (1.12.0)
32
37
  concurrent-ruby (~> 1.0)
33
- json (2.5.1)
38
+ listen (3.8.0)
39
+ rb-fsevent (~> 0.10, >= 0.10.3)
40
+ rb-inotify (~> 0.9, >= 0.9.10)
41
+ lumberjack (1.2.9)
42
+ method_source (1.0.0)
34
43
  minitest (5.18.0)
35
- node_mutation (1.19.3)
36
- node_query (1.13.8)
44
+ nenv (0.3.0)
45
+ node_mutation (1.21.4)
46
+ node_query (1.13.12)
47
+ notiffany (0.1.3)
48
+ nenv (~> 0.1)
49
+ shellany (~> 0.0)
37
50
  parallel (1.22.1)
38
51
  parser (3.2.1.1)
39
52
  ast (~> 2.4.1)
40
- parser_node_ext (1.2.0)
53
+ parser_node_ext (1.2.1)
41
54
  parser
42
55
  prettier_print (1.2.1)
43
- public_suffix (4.0.6)
56
+ pry (0.14.2)
57
+ coderay (~> 1.1)
58
+ method_source (~> 1.0)
44
59
  rake (13.0.6)
45
- rexml (3.2.5)
60
+ rb-fsevent (0.11.2)
61
+ rb-inotify (0.10.1)
62
+ ffi (~> 1.0)
46
63
  rspec (3.10.0)
47
64
  rspec-core (~> 3.10.0)
48
65
  rspec-expectations (~> 3.10.0)
@@ -56,48 +73,34 @@ GEM
56
73
  diff-lcs (>= 1.2.0, < 2.0)
57
74
  rspec-support (~> 3.10.0)
58
75
  rspec-support (3.10.2)
59
- simplecov (0.16.1)
60
- docile (~> 1.1)
61
- json (>= 1.8, < 3)
62
- simplecov-html (~> 0.10.0)
63
- simplecov-html (0.10.2)
64
- sync (0.5.0)
76
+ shellany (0.0.1)
65
77
  syntax_tree (6.1.1)
66
78
  prettier_print (>= 1.2.0)
67
- syntax_tree_ext (0.6.3)
79
+ syntax_tree_ext (0.6.4)
68
80
  syntax_tree
69
- synvert-core (1.28.3)
81
+ synvert-core (1.29.3)
70
82
  activesupport (< 7.0.0)
71
- node_mutation (>= 1.19.1)
72
- node_query (>= 1.13.5)
83
+ node_mutation (>= 1.21.4)
84
+ node_query (>= 1.13.12)
73
85
  parallel
74
86
  parser
75
- parser_node_ext (>= 1.2.0)
87
+ parser_node_ext (>= 1.2.1)
76
88
  syntax_tree
77
- syntax_tree_ext (>= 0.6.0)
78
- term-ansicolor (1.7.1)
79
- tins (~> 1.0)
80
- thor (1.1.0)
81
- tins (1.29.1)
82
- sync
89
+ syntax_tree_ext (>= 0.6.4)
90
+ thor (1.3.0)
83
91
  tzinfo (2.0.6)
84
92
  concurrent-ruby (~> 1.0)
85
- webmock (3.14.0)
86
- addressable (>= 2.8.0)
87
- crack (>= 0.3.2)
88
- hashdiff (>= 0.4.0, < 2.0.0)
89
93
  zeitwerk (2.6.7)
90
94
 
91
95
  PLATFORMS
92
96
  ruby
93
97
 
94
98
  DEPENDENCIES
95
- bundler
96
- coveralls
99
+ guard
100
+ guard-rspec
97
101
  rake
98
102
  rspec
99
103
  synvert!
100
- webmock
101
104
 
102
105
  BUNDLED WITH
103
106
  2.4.7
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+ guard :rspec, cmd: "bundle exec rspec" do
2
+ require "guard/rspec/dsl"
3
+ dsl = Guard::RSpec::Dsl.new(self)
4
+
5
+ # Feel free to open issues for suggestions and improvements
6
+
7
+ # RSpec files
8
+ rspec = dsl.rspec
9
+ watch(rspec.spec_helper) { rspec.spec_dir }
10
+ watch(rspec.spec_support) { rspec.spec_dir }
11
+ watch(rspec.spec_files)
12
+
13
+ # Ruby files
14
+ ruby = dsl.ruby
15
+ dsl.watch_spec_files_for(ruby.lib_files)
16
+ end
data/lib/synvert/cli.rb CHANGED
@@ -28,30 +28,35 @@ module Synvert
28
28
 
29
29
  case @options[:command]
30
30
  when 'list'
31
- read_rewriters
32
- list_available_rewriters
31
+ Command.read_rewriters
32
+ Command.list_available_rewriters(@options[:foramt])
33
33
  when 'open'
34
- open_rewriter
34
+ Command.open_rewriter(@options[:snippet_name])
35
35
  when 'query'
36
- read_rewriters
37
- query_available_rewriters
36
+ Command.read_rewriters
37
+ Command.query_available_rewriters
38
38
  when 'show'
39
- show_rewriter
39
+ Command.show_rewriter(@options[:snippet_name])
40
40
  when 'sync'
41
- sync_snippets
41
+ Command.sync_snippets
42
42
  when 'generate'
43
- generate_snippet
43
+ Comamnd.generate_snippet(@options[:snippet_name])
44
44
  when 'execute'
45
- read_helpers
46
- execute_snippet(@options[:execute_command])
45
+ Command.read_helpers
46
+ rewriter = eval_snippet_name_by_input(STDIN.read)
47
+ if @options[:execute_command] == 'test'
48
+ Comamnd.test_snippet(rewriter)
49
+ else
50
+ Comamnd.run_snippet(rewriter, @options[:format])
51
+ end
47
52
  when 'test'
48
- read_helpers
53
+ Command.read_helpers
49
54
  rewriter = Synvert::Core::Utils.eval_snippet(@options[:snippet_name])
50
- test_snippet(rewriter)
55
+ Command.test_snippet(rewriter)
51
56
  when 'run'
52
- read_helpers
57
+ Command.read_helpers
53
58
  rewriter = Synvert::Core::Utils.eval_snippet(@options[:snippet_name])
54
- run_snippet(rewriter)
59
+ Command.run_snippet(rewriter, @options[:format])
55
60
  else
56
61
  # nothing to do
57
62
  end
@@ -153,214 +158,9 @@ module Synvert
153
158
  end
154
159
  end
155
160
 
156
- # read all rewriters.
157
- def read_rewriters
158
- Dir.glob(File.join(default_snippets_home, 'lib/**/*.rb')).each { |file| require file }
159
- end
160
-
161
- # read all helpers.
162
- def read_helpers
163
- Dir.glob(File.join(default_snippets_home, 'lib/helpers/**/*.rb')).each { |file| require file }
164
- end
165
-
166
- # List and print all available rewriters.
167
- def list_available_rewriters
168
- if Core::Rewriter.availables.empty?
169
- puts "There is no snippet under #{default_snippets_home}, please run `synvert-ruby --sync` to fetch snippets."
170
- return
171
- end
172
-
173
- if plain_output?
174
- Core::Rewriter.availables.each do |group, rewriters|
175
- puts group
176
- rewriters.each do |name, _rewriter|
177
- puts ' ' + name
178
- end
179
- end
180
- puts
181
- elsif json_output?
182
- output = []
183
- Core::Rewriter.availables.each do |group, rewriters|
184
- rewriters.each do |name, rewriter|
185
- rewriter.process_with_sandbox
186
- sub_snippets =
187
- rewriter.sub_snippets.map { |sub_snippet|
188
- { group: sub_snippet.group, name: sub_snippet.name }
189
- }
190
- item = { group: group, name: name, description: rewriter.description, sub_snippets: sub_snippets }
191
- item[:ruby_version] = rewriter.ruby_version.version if rewriter.ruby_version
192
- item[:gem_spec] = { name: rewriter.gem_spec.name, version: rewriter.gem_spec.version } if rewriter.gem_spec
193
- output << item
194
- end
195
- end
196
-
197
- puts output.to_json
198
- end
199
- end
200
-
201
- # Open one rewriter.
202
- def open_rewriter
203
- editor = [ENV['SYNVERT_EDITOR'], ENV['EDITOR']].find { |e| !e.nil? && !e.empty? }
204
- return puts 'To open a synvert snippet, set $EDITOR or $SYNVERT_EDITOR' unless editor
205
-
206
- path = File.expand_path(File.join(default_snippets_home, "lib/#{@options[:snippet_name]}.rb"))
207
- if File.exist?(path)
208
- system editor, path
209
- else
210
- puts "Can't run #{editor} #{path}"
211
- end
212
- end
213
-
214
- # Query and print available rewriters.
215
- def query_available_rewriters
216
- Core::Rewriter.availables.each do |group, rewriters|
217
- if group.include? @options[:query]
218
- puts group
219
- rewriters.each do |name, _rewriter|
220
- puts ' ' + name
221
- end
222
- elsif rewriters.keys.any? { |name| name.include? @options[:query] }
223
- puts group
224
- rewriters.each do |name, _rewriter|
225
- puts ' ' + name if name.include?(@options[:query])
226
- end
227
- end
228
- end
229
- puts
230
- end
231
-
232
- # Show and print one rewriter.
233
- def show_rewriter
234
- path = File.expand_path(File.join(default_snippets_home, "lib/#{@options[:snippet_name]}.rb"))
235
- if File.exist?(path)
236
- puts File.read(path)
237
- else
238
- puts "snippet #{@options[:snippet_name]} not found"
239
- end
240
- end
241
-
242
- # sync snippets
243
- def sync_snippets
244
- Snippet.new(default_snippets_home).sync
245
- puts 'synvert snippets are synced'
246
- end
247
-
248
161
  # eval snippet name by user input
249
162
  def eval_snippet_name_by_input(input)
250
163
  eval(input)
251
164
  end
252
-
253
- # run a snippet
254
- def run_snippet(rewriter)
255
- if plain_output?
256
- puts "===== #{rewriter.group}/#{rewriter.name} started ====="
257
- rewriter.process
258
- rewriter.warnings.each do |warning|
259
- puts '[Warn] ' + warning.message
260
- end
261
- puts "===== #{rewriter.group}/#{rewriter.name} done ====="
262
- elsif json_output?
263
- rewriter.process
264
- output = {
265
- affected_files: rewriter.affected_files.union(rewriter.sub_snippets.sum(Set.new, &:affected_files)).to_a,
266
- warnings: rewriter.warnings.union(rewriter.sub_snippets.sum([], &:warnings))
267
- }
268
- puts output.to_json
269
- end
270
- rescue StandardError => e
271
- if ENV['DEBUG']
272
- puts e.backtrace.join("\n")
273
- end
274
- if plain_output?
275
- puts "Error: #{e.message}"
276
- else
277
- puts({ error: e.message }.to_json)
278
- end
279
- raise
280
- end
281
-
282
- # test a snippet
283
- def test_snippet(rewriter)
284
- results = rewriter.test
285
- puts results.to_json
286
- rescue StandardError => e
287
- if ENV['DEBUG']
288
- puts e.backtrace.join("\n")
289
- end
290
- puts({ error: e.message }.to_json)
291
- raise
292
- end
293
-
294
- # execute snippet
295
- def execute_snippet(execute_command)
296
- rewriter = eval_snippet_name_by_input(STDIN.read)
297
- if execute_command == 'test'
298
- test_snippet(rewriter)
299
- else
300
- run_snippet(rewriter)
301
- end
302
- end
303
-
304
- # generate a new snippet
305
- def generate_snippet
306
- group, name = @options[:snippet_name].split('/')
307
- FileUtils.mkdir_p("lib/#{group}")
308
- FileUtils.mkdir_p("spec/#{group}")
309
- lib_content = <<~EOF
310
- # frozen_string_literal: true
311
-
312
- Synvert::Rewriter.new '#{group}', '#{name}' do
313
- description <<~EOS
314
- It converts Foo to Bar
315
-
316
- ```ruby
317
- Foo
318
- ```
319
-
320
- =>
321
-
322
- ```ruby
323
- Bar
324
- ```
325
- EOS
326
-
327
- within_files '**/*.rb' do
328
- with_node type: 'const', to_source: 'Foo' do
329
- replace_with 'Bar'
330
- end
331
- end
332
- end
333
- EOF
334
- spec_content = <<~EOF
335
- # frozen_string_literal: true
336
-
337
- require 'spec_helper'
338
-
339
- RSpec.describe 'Convert Foo to Bar' do
340
- let(:rewriter_name) { '#{group}/#{name}' }
341
- let(:fake_file_path) { 'foobar.rb' }
342
- let(:test_content) { 'Foo' }
343
- let(:test_rewritten_content) { 'Bar' }
344
-
345
- include_examples 'convertable'
346
- end
347
- EOF
348
- File.write("lib/#{group}/#{name}.rb", lib_content)
349
- File.write("spec/#{group}/#{name}_spec.rb", spec_content)
350
- end
351
-
352
- def default_snippets_home
353
- # ENV['HOME'] may use \ as file separator,
354
- # but File.join always uses / as file separator.
355
- ENV['SYNVERT_SNIPPETS_HOME'] || File.join(ENV['HOME'].gsub("\\", "/"), '.synvert-ruby')
356
- end
357
-
358
- def plain_output?
359
- @options[:format] == 'plain'
360
- end
361
-
362
- def json_output?
363
- @options[:format] == 'json'
364
- end
365
165
  end
366
166
  end
@@ -0,0 +1,203 @@
1
+ # frozen_stirng_literal: true
2
+
3
+ module Synvert
4
+ class Command
5
+ class << self
6
+ # sync snippets
7
+ def sync_snippets
8
+ if File.exist?(default_snippets_home)
9
+ Dir.chdir(default_snippets_home) do
10
+ Kernel.system('git checkout . && git pull --rebase')
11
+ end
12
+ else
13
+ Kernel.system("git clone https://github.com/xinminlabs/synvert-snippets-ruby.git #{default_snippets_home}")
14
+ end
15
+ puts 'synvert snippets are synced'
16
+ end
17
+
18
+ # read all rewriters.
19
+ def read_rewriters
20
+ Dir.glob(File.join(default_snippets_home, 'lib/**/*.rb')).each { |file| require file }
21
+ end
22
+
23
+ # read all helpers.
24
+ def read_helpers
25
+ Dir.glob(File.join(default_snippets_home, 'lib/helpers/**/*.rb')).each { |file| require file }
26
+ end
27
+
28
+ # Open one rewriter.
29
+ def open_rewriter(snippet_name)
30
+ editor = [ENV['SYNVERT_EDITOR'], ENV['EDITOR']].find { |e| !e.nil? && !e.empty? }
31
+ return puts 'To open a synvert snippet, set $EDITOR or $SYNVERT_EDITOR' unless editor
32
+
33
+ path = File.expand_path(File.join(default_snippets_home, "lib/#{snippet_name}.rb"))
34
+ if File.exist?(path)
35
+ system editor, path
36
+ else
37
+ puts "Can't run #{editor} #{path}"
38
+ end
39
+ end
40
+
41
+ # List and print all available rewriters.
42
+ def list_available_rewriters(format)
43
+ if Core::Rewriter.availables.empty?
44
+ puts "There is no snippet under #{default_snippets_home}, please run `synvert-ruby --sync` to fetch snippets."
45
+ return
46
+ end
47
+
48
+ if format == 'json'
49
+ puts available_rewriters.to_json
50
+ else
51
+ Core::Rewriter.availables.each do |group, rewriters|
52
+ puts group
53
+ rewriters.each do |name, _rewriter|
54
+ puts ' ' + name
55
+ end
56
+ end
57
+ puts
58
+ end
59
+ end
60
+
61
+ def available_rewriters
62
+ output = []
63
+ Core::Rewriter.availables.each do |group, rewriters|
64
+ rewriters.each do |name, rewriter|
65
+ rewriter.process_with_sandbox
66
+ sub_snippets =
67
+ rewriter.sub_snippets.map { |sub_snippet|
68
+ { group: sub_snippet.group, name: sub_snippet.name }
69
+ }
70
+ item = { group: group, name: name, description: rewriter.description, sub_snippets: sub_snippets }
71
+ item[:ruby_version] = rewriter.ruby_version.version if rewriter.ruby_version
72
+ item[:gem_spec] = { name: rewriter.gem_spec.name, version: rewriter.gem_spec.version } if rewriter.gem_spec
73
+ output << item
74
+ end
75
+ end
76
+ output
77
+ end
78
+
79
+ # Query and print available rewriters.
80
+ def query_available_rewriters
81
+ Core::Rewriter.availables.each do |group, rewriters|
82
+ if group.include? @options[:query]
83
+ puts group
84
+ rewriters.each do |name, _rewriter|
85
+ puts ' ' + name
86
+ end
87
+ elsif rewriters.keys.any? { |name| name.include? @options[:query] }
88
+ puts group
89
+ rewriters.each do |name, _rewriter|
90
+ puts ' ' + name if name.include?(@options[:query])
91
+ end
92
+ end
93
+ end
94
+ puts
95
+ end
96
+
97
+ # Show and print one rewriter.
98
+ def show_rewriter(snippet_name)
99
+ path = File.expand_path(File.join(default_snippets_home, "lib/#{snippet_name}.rb"))
100
+ if File.exist?(path)
101
+ puts File.read(path)
102
+ else
103
+ puts "snippet #{snippet_name} not found"
104
+ end
105
+ end
106
+
107
+ # generate a new snippet
108
+ def generate_snippet(snippet_name)
109
+ group, name = snippet_name.split('/')
110
+ FileUtils.mkdir_p("lib/#{group}")
111
+ FileUtils.mkdir_p("spec/#{group}")
112
+ lib_content = <<~EOF
113
+ # frozen_string_literal: true
114
+
115
+ Synvert::Rewriter.new '#{group}', '#{name}' do
116
+ description <<~EOS
117
+ It converts Foo to Bar
118
+
119
+ ```ruby
120
+ Foo
121
+ ```
122
+
123
+ =>
124
+
125
+ ```ruby
126
+ Bar
127
+ ```
128
+ EOS
129
+
130
+ within_files '**/*.rb' do
131
+ with_node type: 'const', to_source: 'Foo' do
132
+ replace_with 'Bar'
133
+ end
134
+ end
135
+ end
136
+ EOF
137
+ spec_content = <<~EOF
138
+ # frozen_string_literal: true
139
+
140
+ require 'spec_helper'
141
+
142
+ RSpec.describe 'Convert Foo to Bar' do
143
+ let(:rewriter_name) { '#{group}/#{name}' }
144
+ let(:fake_file_path) { 'foobar.rb' }
145
+ let(:test_content) { 'Foo' }
146
+ let(:test_rewritten_content) { 'Bar' }
147
+
148
+ include_examples 'convertable'
149
+ end
150
+ EOF
151
+ File.write("lib/#{group}/#{name}.rb", lib_content)
152
+ File.write("spec/#{group}/#{name}_spec.rb", spec_content)
153
+ end
154
+
155
+ # run a snippet
156
+ def run_snippet(rewriter, format)
157
+ if format == 'json'
158
+ rewriter.process
159
+ output = {
160
+ affected_files: rewriter.affected_files.union(rewriter.sub_snippets.sum(Set.new, &:affected_files)).to_a,
161
+ warnings: rewriter.warnings.union(rewriter.sub_snippets.sum([], &:warnings))
162
+ }
163
+ puts output.to_json
164
+ else
165
+ puts "===== #{rewriter.group}/#{rewriter.name} started ====="
166
+ rewriter.process
167
+ rewriter.warnings.each do |warning|
168
+ puts '[Warn] ' + warning.message
169
+ end
170
+ puts "===== #{rewriter.group}/#{rewriter.name} done ====="
171
+ end
172
+ rescue StandardError => e
173
+ if ENV['DEBUG']
174
+ puts e.backtrace.join("\n")
175
+ end
176
+ if plain_output?
177
+ puts "Error: #{e.message}"
178
+ else
179
+ puts({ error: e.message }.to_json)
180
+ end
181
+ raise
182
+ end
183
+
184
+ # test a snippet
185
+ def test_snippet(rewriter)
186
+ results = rewriter.test
187
+ puts results.to_json
188
+ rescue StandardError => e
189
+ if ENV['DEBUG']
190
+ puts e.backtrace.join("\n")
191
+ end
192
+ puts({ error: e.message }.to_json)
193
+ raise
194
+ end
195
+
196
+ def default_snippets_home
197
+ # ENV['HOME'] may use \ as file separator,
198
+ # but File.join always uses / as file separator.
199
+ ENV['SYNVERT_SNIPPETS_HOME'] || File.join(ENV['HOME'].gsub("\\", "/"), '.synvert-ruby')
200
+ end
201
+ end
202
+ end
203
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Synvert
4
- VERSION = '1.4.7'
4
+ VERSION = '1.5.0'
5
5
  end
data/lib/synvert.rb CHANGED
@@ -6,6 +6,5 @@ require 'synvert/core'
6
6
 
7
7
  module Synvert
8
8
  autoload :CLI, 'synvert/cli'
9
- autoload :Utils, 'synvert/utils'
10
- autoload :Snippet, 'synvert/snippet'
9
+ autoload :Command, 'synvert/command'
11
10
  end
data/spec/spec_helper.rb CHANGED
@@ -3,10 +3,6 @@
3
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
4
 
5
5
  require 'synvert'
6
- require 'webmock/rspec'
7
-
8
- require 'coveralls'
9
- Coveralls.wear!
10
6
 
11
7
  RSpec.configure do |config|
12
8
  config.run_all_when_everything_filtered = true
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ module Synvert
6
+ RSpec.describe Command do
7
+ let(:snippets_path) { File.join(File.dirname(__FILE__), '.synvert-ruby') }
8
+ before { allow(described_class).to receive(:default_snippets_home).and_return(snippets_path) }
9
+ before { FileUtils.rm_rf(snippets_path) if Dir.exist?(snippets_path) }
10
+ after { FileUtils.rm_rf(snippets_path) if Dir.exist?(snippets_path) }
11
+
12
+ describe '.sync_snippets' do
13
+ it 'git clones snippets' do
14
+ expect(Kernel).to receive(:system).with(
15
+ "git clone https://github.com/xinminlabs/synvert-snippets-ruby.git #{snippets_path}"
16
+ )
17
+ described_class.sync_snippets
18
+ end
19
+
20
+ it 'git pull snippets' do
21
+ FileUtils.mkdir snippets_path
22
+ expect(Kernel).to receive(:system).with('git checkout . && git pull --rebase')
23
+ described_class.sync_snippets
24
+ FileUtils.cd File.dirname(__FILE__)
25
+ end
26
+ end
27
+
28
+ describe '.read_rewriters' do
29
+ before do
30
+ FileUtils.mkdir_p(File.join(snippets_path, 'lib'))
31
+ File.write(File.join(snippets_path, 'lib', 'foo_rewriter.rb'), <<~EOS)
32
+ Synvert::Rewriter.new 'ruby', 'foo_rewriter' do
33
+ end
34
+ EOS
35
+ File.write(File.join(snippets_path, 'lib', 'bar_rewriter.rb'), <<~EOS)
36
+ Synvert::Rewriter.new 'ruby', 'bar_rewriter' do
37
+ end
38
+ EOS
39
+ end
40
+
41
+ it 'requires all .rb files in the lib directory of the snippets home' do
42
+ described_class.read_rewriters
43
+ expect(Synvert::Rewriter.fetch('ruby', 'foo_rewriter')).to be_a(Synvert::Rewriter)
44
+ expect(Synvert::Rewriter.fetch('ruby', 'bar_rewriter')).to be_a(Synvert::Rewriter)
45
+ end
46
+ end
47
+
48
+ describe '.read_helpers' do
49
+ before do
50
+ FileUtils.mkdir_p(File.join(snippets_path, 'lib', 'helpers'))
51
+ File.write(File.join(snippets_path, 'lib', 'helpers', 'foo_helper.rb'), <<~EOS)
52
+ Synvert::Helper.new 'foo_helper' do
53
+ end
54
+ EOS
55
+ File.write(File.join(snippets_path, 'lib', 'helpers', 'bar_helper.rb'), <<~EOS)
56
+ Synvert::Helper.new 'bar_helper' do
57
+ end
58
+ EOS
59
+ end
60
+
61
+ it 'requires all .rb files in the lib/helpers directory of the snippets home' do
62
+ described_class.read_helpers
63
+ expect(Synvert::Helper.fetch('foo_helper')).to be_a(Synvert::Helper)
64
+ expect(Synvert::Helper.fetch('bar_helper')).to be_a(Synvert::Helper)
65
+ end
66
+ end
67
+
68
+ describe '.available_rewriters' do
69
+ it 'requires all .rb files in the lib directory of the snippets home' do
70
+ Synvert::Rewriter.new 'ruby', 'foo_rewriter' do
71
+ end
72
+ Synvert::Rewriter.new 'ruby', 'bar_rewriter' do
73
+ end
74
+ expect(described_class.available_rewriters).to match_array [
75
+ { description: nil, group: "ruby", name: "foo_rewriter", sub_snippets: [] },
76
+ { description: nil, group: "ruby", name: "bar_rewriter", sub_snippets: [] }
77
+ ]
78
+ end
79
+ end
80
+
81
+ describe '.generate_snippet' do
82
+ it 'generates both snippet code and test code' do
83
+ described_class.generate_snippet('ruby/foobar')
84
+ expect(File.read('lib/ruby/foobar.rb')).to eq <<~EOF
85
+ # frozen_string_literal: true
86
+
87
+ Synvert::Rewriter.new 'ruby', 'foobar' do
88
+ description <<~EOS
89
+ It converts Foo to Bar
90
+
91
+ ```ruby
92
+ Foo
93
+ ```
94
+
95
+ =>
96
+
97
+ ```ruby
98
+ Bar
99
+ ```
100
+ EOS
101
+
102
+ within_files '**/*.rb' do
103
+ with_node type: 'const', to_source: 'Foo' do
104
+ replace_with 'Bar'
105
+ end
106
+ end
107
+ end
108
+ EOF
109
+ expect(File.read('spec/ruby/foobar_spec.rb')).to eq <<~EOF
110
+ # frozen_string_literal: true
111
+
112
+ require 'spec_helper'
113
+
114
+ RSpec.describe 'Convert Foo to Bar' do
115
+ let(:rewriter_name) { 'ruby/foobar' }
116
+ let(:fake_file_path) { 'foobar.rb' }
117
+ let(:test_content) { 'Foo' }
118
+ let(:test_rewritten_content) { 'Bar' }
119
+
120
+ include_examples 'convertable'
121
+ end
122
+ EOF
123
+ FileUtils.rm_rf('lib/ruby')
124
+ FileUtils.rm_rf('spec/ruby')
125
+ end
126
+ end
127
+ end
128
+ end
data/synvert-ruby.gemspec CHANGED
@@ -20,10 +20,5 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ['lib']
21
21
  spec.post_install_message = 'Please run `synvert-ruby --sync` first to sync snippets remotely.'
22
22
 
23
- spec.add_runtime_dependency 'synvert-core', '>= 1.28.3'
24
-
25
- spec.add_development_dependency 'bundler'
26
- spec.add_development_dependency 'rake'
27
- spec.add_development_dependency 'rspec'
28
- spec.add_development_dependency 'webmock'
23
+ spec.add_runtime_dependency 'synvert-core', '>= 1.29.3'
29
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synvert
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.7
4
+ version: 1.5.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: 2023-07-03 00:00:00.000000000 Z
11
+ date: 2023-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: synvert-core
@@ -16,75 +16,18 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.28.3
19
+ version: 1.29.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.28.3
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: webmock
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
26
+ version: 1.29.3
83
27
  description: synvert is used to convert ruby code to better syntax.
84
28
  email:
85
29
  - flyerhzm@gmail.com
86
30
  executables:
87
- - synvert
88
31
  - synvert-ruby
89
32
  extensions: []
90
33
  extra_rdoc_files: []
@@ -95,19 +38,17 @@ files:
95
38
  - CHANGELOG.md
96
39
  - Gemfile
97
40
  - Gemfile.lock
41
+ - Guardfile
98
42
  - LICENSE.txt
99
43
  - README.md
100
44
  - Rakefile
101
- - bin/synvert
102
45
  - bin/synvert-ruby
103
46
  - lib/synvert.rb
104
47
  - lib/synvert/cli.rb
105
- - lib/synvert/snippet.rb
106
- - lib/synvert/utils.rb
48
+ - lib/synvert/command.rb
107
49
  - lib/synvert/version.rb
108
50
  - spec/spec_helper.rb
109
- - spec/synvert/snippet_spec.rb
110
- - spec/synvert/utils_spec.rb
51
+ - spec/synvert/command_spec.rb
111
52
  - synvert-ruby.gemspec
112
53
  homepage: https://github.com/xinminlabs/synvert-ruby
113
54
  licenses:
@@ -128,11 +69,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
69
  - !ruby/object:Gem::Version
129
70
  version: '0'
130
71
  requirements: []
131
- rubygems_version: 3.4.13
72
+ rubygems_version: 3.4.20
132
73
  signing_key:
133
74
  specification_version: 4
134
75
  summary: synvert = syntax + convert.
135
76
  test_files:
136
77
  - spec/spec_helper.rb
137
- - spec/synvert/snippet_spec.rb
138
- - spec/synvert/utils_spec.rb
78
+ - spec/synvert/command_spec.rb
data/bin/synvert DELETED
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
5
- require 'synvert'
6
-
7
- puts "synvert is deprecated, use synvert-ruby instead."
8
- puts
9
- result = Synvert::CLI.run
10
- exit(result ? 0 : 1)
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Synvert
4
- # Manage synvert snippets.
5
- class Snippet
6
- def initialize(snippets_path)
7
- @snippets_path = snippets_path
8
- end
9
-
10
- # synchronize snippets from github.
11
- def sync
12
- if File.exist?(@snippets_path)
13
- Dir.chdir(@snippets_path) do
14
- Kernel.system('git checkout . && git pull --rebase')
15
- end
16
- else
17
- Kernel.system("git clone https://github.com/xinminlabs/synvert-snippets-ruby.git #{@snippets_path}")
18
- end
19
- end
20
- end
21
- end
data/lib/synvert/utils.rb DELETED
@@ -1,18 +0,0 @@
1
- module Synvert
2
- module Utils
3
- class << self
4
- def format_url(url)
5
- convert_to_github_raw_url(url)
6
- end
7
-
8
- private
9
-
10
- def convert_to_github_raw_url(url)
11
- if url.include?('//github.com/')
12
- url = url.sub('//github.com/', '//raw.githubusercontent.com/').sub('/blob/', '/')
13
- end
14
- url
15
- end
16
- end
17
- end
18
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Synvert
6
- describe Snippet do
7
- let(:snippets_path) { File.join(File.dirname(__FILE__), '.synvert-ruby') }
8
- let(:snippet) { Snippet.new(snippets_path) }
9
- after { FileUtils.rmdir(snippets_path) if File.exist?(snippets_path) }
10
-
11
- describe 'sync' do
12
- it 'git clones snippets' do
13
- expect(Kernel).to receive(:system).with(
14
- "git clone https://github.com/xinminlabs/synvert-snippets-ruby.git #{snippets_path}"
15
- )
16
- snippet.sync
17
- end
18
-
19
- it 'git pull snippets' do
20
- FileUtils.mkdir snippets_path
21
- expect(Kernel).to receive(:system).with('git checkout . && git pull --rebase')
22
- snippet.sync
23
- FileUtils.cd File.dirname(__FILE__)
24
- end
25
- end
26
- end
27
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Synvert
6
- RSpec.describe Utils do
7
- describe '.format_url' do
8
- it 'converts github url to github raw url' do
9
- url = 'https://github.com/xinminlabs/synvert-snippets-ruby/blob/main/lib/ruby/map_and_flatten_to_flat_map.rb'
10
- raw_url = 'https://raw.githubusercontent.com/xinminlabs/synvert-snippets-ruby/main/lib/ruby/map_and_flatten_to_flat_map.rb'
11
- expect(described_class.format_url(url)).to eq raw_url
12
- end
13
- end
14
- end
15
- end