synvert-core 0.21.1 → 0.25.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: 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