synvert-core 0.21.1 → 0.25.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: 945aecfd794891da0a5fc8d5a1ac1f03946090c7bb01ff458545292a91296160
4
- data.tar.gz: d0e863e0fdeda70cba509a84a44a3665de4edabb178bdb38aa3649095d0b4c99
3
+ metadata.gz: 8365e77c33d2effc81fe2cd19d522785282db9c06aa8e399c6469f9cbdc32cc7
4
+ data.tar.gz: c60c8a032106b681abdac98b31a87cfbac6649959eb21fe1bbd0e6be1486c53c
5
5
  SHA512:
6
- metadata.gz: b328ae8b13f6c056d18f59fdd643bab5e97aba335f34b9b0d50ef558f5b74a4ed14549c19675495bd213d852db09a3bbf2da8fc95abfa2cb3f833b06e2aca50a
7
- data.tar.gz: 92050432ab95a2cec0cbbfa3b54f12101880da2f856935537e85fef43e196c8f560d78b2d06f6ed26e866c64bf889ded1b4d1b4e88c04ac4b4f0df6f6c16cb31
6
+ metadata.gz: 2017b6bb33289a7a2c2cba047f966079ae07fa6035acf819b1898c32ee7fc38417dc424c9ba263a33989e3eb0e241bdef32b816135ae1b86e0aae9f176be14d0
7
+ data.tar.gz: a71a80f5a7c177950a52eebad506778fd7a8993577d7c7ec22e57467a7a80a0610edf5a08bc23d9d831547ec4560da077bae5e358f9f4e3c34c089a6674bbd7f
data/CHANGELOG.md CHANGED
@@ -1,8 +1,21 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 0.21.1 (2021-02-26)
3
+ ## 0.25.0 (2021-03-23)
4
4
 
5
- * Fix `find_matching_nodes` if `current_node` is a `Parser::AST::Node`
5
+ * Use `Gem::Dependency#match?` to check gem version
6
+
7
+ ## 0.24.0 (2021-03-17)
8
+
9
+ * Rename helper method `has_key?` to `key?`
10
+
11
+ ## 0.23.0 (2021-03-14)
12
+
13
+ * Accept a node as goto_node argument
14
+
15
+ ## 0.22.0 (2021-03-13)
16
+
17
+ * Track `affected_files` for rewriter
18
+ * Fix `find_matching_nodes` for `current_node`
6
19
 
7
20
  ## 0.21.0 (2021-02-25)
8
21
 
data/lib/synvert/core.rb CHANGED
@@ -7,6 +7,7 @@ require 'parser/current'
7
7
  require 'ast'
8
8
  require 'active_support/core_ext/object'
9
9
  require 'erubis'
10
+ require 'set'
10
11
  require 'synvert/core/node_ext'
11
12
 
12
13
  module Synvert
@@ -187,11 +187,11 @@ module Parser::AST
187
187
  # @param [Object] key value.
188
188
  # @return [Boolean] true if specified key exists.
189
189
  # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
190
- def has_key?(key)
190
+ def key?(key)
191
191
  if :hash == type
192
192
  children.any? { |pair_node| pair_node.key.to_value == key }
193
193
  else
194
- raise Synvert::Core::MethodNotSupported, "has_key? is not handled for #{debug_info}"
194
+ raise Synvert::Core::MethodNotSupported, "key? is not handled for #{debug_info}"
195
195
  end
196
196
  end
197
197
 
@@ -205,7 +205,7 @@ module Parser::AST
205
205
  value_node = children.find { |pair_node| pair_node.key.to_value == key }
206
206
  value_node ? value_node.value : nil
207
207
  else
208
- raise Synvert::Core::MethodNotSupported, "has_key? is not handled for #{debug_info}"
208
+ raise Synvert::Core::MethodNotSupported, "hash_value is not handled for #{debug_info}"
209
209
  end
210
210
  end
211
211
 
@@ -335,24 +335,22 @@ module Parser::AST
335
335
  # @param rules [Hash] rules to match.
336
336
  # @return true if matches.
337
337
  def match?(rules)
338
- flat_hash(rules)
339
- .keys
340
- .all? do |multi_keys|
341
- case multi_keys.last
342
- when :any
343
- actual_values = actual_value(self, multi_keys[0...-1])
344
- expected = expected_value(rules, multi_keys)
345
- actual_values.any? { |actual| match_value?(actual, expected) }
346
- when :not
347
- actual = actual_value(self, multi_keys[0...-1])
348
- expected = expected_value(rules, multi_keys)
349
- !match_value?(actual, expected)
350
- else
351
- actual = actual_value(self, multi_keys)
352
- expected = expected_value(rules, multi_keys)
353
- match_value?(actual, expected)
354
- end
338
+ flat_hash(rules).keys.all? do |multi_keys|
339
+ case multi_keys.last
340
+ when :any
341
+ actual_values = actual_value(self, multi_keys[0...-1])
342
+ expected = expected_value(rules, multi_keys)
343
+ actual_values.any? { |actual| match_value?(actual, expected) }
344
+ when :not
345
+ actual = actual_value(self, multi_keys[0...-1])
346
+ expected = expected_value(rules, multi_keys)
347
+ !match_value?(actual, expected)
348
+ else
349
+ actual = actual_value(self, multi_keys)
350
+ expected = expected_value(rules, multi_keys)
351
+ match_value?(actual, expected)
355
352
  end
353
+ end
356
354
  end
357
355
 
358
356
  # Get rewritten source code.
@@ -145,7 +145,9 @@ module Synvert::Core
145
145
  # @return [Array] helper methods.
146
146
  # @!attribute [r] warnings
147
147
  # @return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
148
- attr_reader :group, :name, :sub_snippets, :helpers, :warnings
148
+ # @!attribute [r] affected_files
149
+ # @return [Set] affected fileds
150
+ attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files
149
151
 
150
152
  # Initialize a rewriter.
151
153
  # When a rewriter is initialized, it is also registered.
@@ -161,6 +163,7 @@ module Synvert::Core
161
163
  @helpers = []
162
164
  @sub_snippets = []
163
165
  @warnings = []
166
+ @affected_files = Set.new
164
167
  self.class.register(@group, @name, self)
165
168
  end
166
169
 
@@ -188,6 +191,13 @@ module Synvert::Core
188
191
  @warnings << warning
189
192
  end
190
193
 
194
+ # Add an affected file.
195
+ #
196
+ # @param file_path [String]
197
+ def add_affected_file(file_path)
198
+ @affected_files.add(file_path)
199
+ end
200
+
191
201
  #######
192
202
  # DSL #
193
203
  #######
@@ -23,11 +23,9 @@ module Synvert::Core
23
23
  def rewritten_code
24
24
  if rewritten_source.split("\n").length > 1
25
25
  new_code = []
26
- rewritten_source
27
- .split("\n")
28
- .each_with_index { |line, index|
29
- new_code << (index == 0 || !@options[:autoindent] ? line : indent(@node) + line)
30
- }
26
+ rewritten_source.split("\n").each_with_index { |line, index|
27
+ new_code << (index == 0 || !@options[:autoindent] ? line : indent(@node) + line)
28
+ }
31
29
  new_code.join("\n")
32
30
  else
33
31
  rewritten_source
@@ -3,22 +3,13 @@
3
3
  module Synvert::Core
4
4
  # GemSpec checks and compares gem version.
5
5
  class Rewriter::GemSpec
6
- OPERATORS = { eq: '==', lt: '<', gt: '>', lte: '<=', gte: '>=', ne: '!=' }.freeze
7
-
8
6
  # Initialize a gem_spec.
9
7
  #
10
8
  # @param name [String] gem name
11
- # @param comparator [Hash] comparator to gem version, e.g. {eq: '2.0.0'},
12
- # comparator key can be eq, lt, gt, lte, gte or ne.
13
- def initialize(name, comparator)
9
+ # @param version [String] gem version, e.g. '~> 2.0.0',
10
+ def initialize(name, version)
14
11
  @name = name
15
- if comparator.is_a?(Hash)
16
- @operator = comparator.keys.first
17
- @version = Gem::Version.new comparator.values.first
18
- else
19
- @operator = :eq
20
- @version = Gem::Version.new comparator
21
- end
12
+ @version = version
22
13
  end
23
14
 
24
15
  # Check if the specified gem version in Gemfile.lock matches gem_spec comparator.
@@ -33,11 +24,7 @@ module Synvert::Core
33
24
 
34
25
  ENV['BUNDLE_GEMFILE'] = Configuration.path # make sure bundler reads Gemfile.lock in the correct path
35
26
  parser = Bundler::LockfileParser.new(File.read(gemfile_lock_path))
36
- if spec = parser.specs.find { |spec| spec.name == @name }
37
- Gem::Version.new(spec.version).send(OPERATORS[@operator], @version)
38
- else
39
- false
40
- end
27
+ parser.specs.any? { |spec| Gem::Dependency.new(@name, @version).match?(spec) }
41
28
  end
42
29
  end
43
30
  end
@@ -87,43 +87,41 @@ module Synvert::Core
87
87
  # and rewrite source code back to original file.
88
88
  def process
89
89
  file_pattern = File.join(Configuration.path, @file_pattern)
90
- Dir
91
- .glob(file_pattern)
92
- .each do |file_path|
93
- next if Configuration.skip_files.include? file_path
94
-
95
- begin
96
- conflict_actions = []
97
- source = +self.class.file_source(file_path)
98
- ast = self.class.file_ast(file_path)
99
-
100
- @current_file = file_path
101
-
102
- process_with_node ast do
103
- begin
104
- instance_eval(&@block)
105
- rescue NoMethodError
106
- puts @current_node.debug_info
107
- raise
108
- end
90
+ Dir.glob(file_pattern).each do |file_path|
91
+ next if Configuration.skip_files.include? file_path
92
+
93
+ begin
94
+ conflict_actions = []
95
+ source = +self.class.file_source(file_path)
96
+ ast = self.class.file_ast(file_path)
97
+
98
+ @current_file = file_path
99
+
100
+ process_with_node ast do
101
+ begin
102
+ instance_eval(&@block)
103
+ rescue NoMethodError
104
+ puts @current_node.debug_info
105
+ raise
109
106
  end
107
+ end
110
108
 
111
- if @actions.length > 0
112
- @actions.sort_by! { |action| action.send(@options[:sort_by]) }
113
- conflict_actions = get_conflict_actions
114
- @actions.reverse_each do |action|
115
- source[action.begin_pos...action.end_pos] = action.rewritten_code
116
- source = remove_code_or_whole_line(source, action.line)
117
- end
118
- @actions = []
119
-
120
- self.class.write_file(file_path, source)
109
+ if @actions.length > 0
110
+ @actions.sort_by! { |action| action.send(@options[:sort_by]) }
111
+ conflict_actions = get_conflict_actions
112
+ @actions.reverse_each do |action|
113
+ source[action.begin_pos...action.end_pos] = action.rewritten_code
114
+ source = remove_code_or_whole_line(source, action.line)
121
115
  end
122
- rescue Parser::SyntaxError
123
- puts "[Warn] file #{file_path} was not parsed correctly."
124
- # do nothing, iterate next file
125
- end while !conflict_actions.empty?
126
- end
116
+ @actions = []
117
+
118
+ update_file(file_path, source)
119
+ end
120
+ rescue Parser::SyntaxError
121
+ puts "[Warn] file #{file_path} was not parsed correctly."
122
+ # do nothing, iterate next file
123
+ end while !conflict_actions.empty?
124
+ end
127
125
  end
128
126
 
129
127
  # Gets current node, it allows to get current node in block code.
@@ -312,5 +310,14 @@ module Synvert::Core
312
310
  source
313
311
  end
314
312
  end
313
+
314
+ # It updates a file with new source code.
315
+ #
316
+ # @param file_path [String] the file path
317
+ # @param source [String] the new source code
318
+ def update_file(file_path, source)
319
+ self.class.write_file(file_path, source)
320
+ @rewriter.add_affected_file(file_path)
321
+ end
315
322
  end
316
323
  end
@@ -19,7 +19,7 @@ module Synvert::Core
19
19
  current_node = @instance.current_node
20
20
  return unless current_node
21
21
 
22
- child_node = current_node.send @child_node_name
22
+ child_node = @child_node_name.is_a?(Parser::AST::Node) ? @child_node_name : current_node.send(@child_node_name)
23
23
  @instance.process_with_other_node child_node do
24
24
  @instance.instance_eval(&@block)
25
25
  end
@@ -42,7 +42,13 @@ module Synvert::Core
42
42
  matching_nodes << child_node if child_node.match? @rules
43
43
  end
44
44
  elsif current_node.is_a?(Parser::AST::Node)
45
- matching_nodes << current_node if current_node.match? @rules
45
+ if current_node.type == :begin
46
+ current_node.children.each do |child_node|
47
+ matching_nodes << child_node if child_node.match? @rules
48
+ end
49
+ elsif current_node.match? @rules
50
+ matching_nodes << current_node
51
+ end
46
52
  else
47
53
  current_node.each do |child_node|
48
54
  matching_nodes << child_node if child_node.match? @rules
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '0.21.1'
5
+ VERSION = '0.25.0'
6
6
  end
7
7
  end
@@ -186,15 +186,15 @@ describe Parser::AST::Node do
186
186
  end
187
187
  end
188
188
 
189
- describe '#has_key?' do
189
+ describe '#key?' do
190
190
  it 'gets true if key exists' do
191
191
  node = parse('{:foo => :bar}')
192
- expect(node.has_key?(:foo)).to be_truthy
192
+ expect(node.key?(:foo)).to be_truthy
193
193
  end
194
194
 
195
195
  it 'gets false if key does not exist' do
196
196
  node = parse('{:foo => :bar}')
197
- expect(node.has_key?('foo')).to be_falsey
197
+ expect(node.key?('foo')).to be_falsey
198
198
  end
199
199
  end
200
200
 
@@ -21,7 +21,7 @@ GEM
21
21
  it 'returns true if version in Gemfile.lock is greater than definition' do
22
22
  expect(File).to receive(:exist?).with('./Gemfile.lock').and_return(true)
23
23
  expect(File).to receive(:read).with('./Gemfile.lock').and_return(gemfile_lock_content)
24
- gem_spec = Rewriter::GemSpec.new('ast', { gte: '1.0.0' })
24
+ gem_spec = Rewriter::GemSpec.new('ast', '~> 1.1')
25
25
  expect(gem_spec).to be_match
26
26
  end
27
27
 
@@ -35,7 +35,7 @@ GEM
35
35
  it 'returns false if version in Gemfile.lock is less than definition' do
36
36
  expect(File).to receive(:exist?).with('./Gemfile.lock').and_return(true)
37
37
  expect(File).to receive(:read).with('./Gemfile.lock').and_return(gemfile_lock_content)
38
- gem_spec = Rewriter::GemSpec.new('ast', { gt: '1.2.0' })
38
+ gem_spec = Rewriter::GemSpec.new('ast', '> 1.2.0')
39
39
  expect(gem_spec).not_to be_match
40
40
  end
41
41
 
@@ -243,6 +243,7 @@ end
243
243
  expect(File).to receive(:read).with('spec/models/post_spec.rb').and_return(output)
244
244
  instance.process
245
245
  instance.process
246
+ expect(rewriter.affected_files).to be_include('spec/models/post_spec.rb')
246
247
  end
247
248
  end
248
249
 
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.21.1
4
+ version: 0.25.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: 2021-02-26 00:00:00.000000000 Z
11
+ date: 2021-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport