node_mutation 1.1.0 → 1.2.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: 181790d29f44cf36742b7666a2b687c0befdd6ff70e30f21a3edcaf6c05ba2d6
4
- data.tar.gz: 898ee69b167c2b6b12b2c3ddb196514deac6084c3b3066e7e634c5b9876dc0a8
3
+ metadata.gz: c27aac4f89bdddee8f7298469d2f26ad17f38c8ed6eb4e76bf4d7af0ea729f98
4
+ data.tar.gz: da1d0b9a9b830890583d88b0b74cca800eb991c4eb86e9b232eabd75678538b0
5
5
  SHA512:
6
- metadata.gz: 0ad795cc5d87cb7e37d225d503946bb7afcd49a04de356306d3d9424845d98a7223812fc35f38122e954b38b9a446523d05033186ba312a4bccfc8492c131f83
7
- data.tar.gz: 1dff8c627b676e4e3b7d333229abb1e1a5eb92871089a9b23c2ee96e872bd47121928d9e6e3b56e7b47b0d97c9bac7104c06991d42c2e414eb7d149c12042203
6
+ metadata.gz: 12d58838fec06d87e0ffad8fce9a1879221726fa57cf15e0e3c4d08541d7a7ef0fff0249601814edc9bad95e73cc5eac46a9f91a55816fee8c3773b0e397b74e
7
+ data.tar.gz: '02870efef507899a92a021a8532c175c0ba230815f76eba8391421b97cd628697a035b31bd17110564aa1c273f78db795a7f1a9d775742917abce56ee703efee'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # NodeMutation
2
2
 
3
+ ## 1.2.0 (2022-07-02)
4
+
5
+ * Return new source instead of writing file
6
+ * Revert Add erb engine
7
+ * Revert Add `ReplaceErbStmtWithExprAction`
8
+
3
9
  ## 1.1.0 (2022-07-02)
4
10
 
5
11
  * Add erb engine
data/Gemfile CHANGED
@@ -13,5 +13,4 @@ gem "parser"
13
13
  gem "parser_node_ext"
14
14
  gem "guard"
15
15
  gem "guard-rspec"
16
- gem "fakefs", require: 'fakefs/safe'
17
16
  gem "pp"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_mutation (1.1.0)
4
+ node_mutation (1.2.0)
5
5
  activesupport
6
6
  erubis
7
7
 
@@ -18,7 +18,6 @@ GEM
18
18
  concurrent-ruby (1.1.10)
19
19
  diff-lcs (1.5.0)
20
20
  erubis (2.7.0)
21
- fakefs (1.8.0)
22
21
  ffi (1.15.5)
23
22
  formatador (1.1.0)
24
23
  guard (2.18.0)
@@ -84,7 +83,6 @@ PLATFORMS
84
83
  x86_64-linux
85
84
 
86
85
  DEPENDENCIES
87
- fakefs
88
86
  guard
89
87
  guard-rspec
90
88
  node_mutation!
data/README.md CHANGED
@@ -25,7 +25,7 @@ Or install it yourself as:
25
25
  ```ruby
26
26
  require 'node_mutation'
27
27
 
28
- mutation = NodeMutation.new(file_path)
28
+ mutation = NodeMutation.new(source)
29
29
  ```
30
30
 
31
31
  2. call the rewrite apis:
@@ -45,8 +45,6 @@ mutation.prepend node, '{{arguments.first}}.include FactoryGirl::Syntax::Methods
45
45
  mutation.remove(node: Node)
46
46
  # replace child node of the ast node with new code
47
47
  mutation.replace node, :message, with: 'test'
48
- # replace erb stmt node with expr code
49
- replace_erb_stmt_with_expr node
50
48
  # replace the ast node with new code
51
49
  mutation.replace_with node, 'create {{arguments}}'
52
50
  # wrap node within a block, class or module
@@ -56,7 +54,13 @@ mutation.wrap node, with: 'module Foo'
56
54
  3. process actions and write the new source code to file:
57
55
 
58
56
  ```ruby
59
- mutation.process
57
+ result = mutation.process
58
+ # if it makes any change to the source
59
+ result.affected?
60
+ # if any action is conflicted
61
+ result.conflicted
62
+ # return the new source if it is affected
63
+ result.new_source
60
64
  ```
61
65
 
62
66
  ## Write Adapter
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NodeMutation::Result
4
+ def initialize(options)
5
+ @options = options
6
+ end
7
+
8
+ def affected?
9
+ @options[:affected]
10
+ end
11
+
12
+ def conflicted?
13
+ @options[:conflicted]
14
+ end
15
+
16
+ def new_source
17
+ @options[:new_source]
18
+ end
19
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeMutation
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
data/lib/node_mutation.rb CHANGED
@@ -22,10 +22,9 @@ class NodeMutation
22
22
  autoload :RemoveAction, 'node_mutation/action/remove_action'
23
23
  autoload :PrependAction, 'node_mutation/action/prepend_action'
24
24
  autoload :ReplaceAction, 'node_mutation/action/replace_action'
25
- autoload :ReplaceErbStmtWithExprAction, 'node_mutation/action/replace_erb_stmt_with_expr_action'
26
25
  autoload :ReplaceWithAction, 'node_mutation/action/replace_with_action'
27
26
  autoload :WrapAction, 'node_mutation/action/wrap_action'
28
- autoload :Engine, 'node_mutation/engine'
27
+ autoload :Result, 'node_mutation/result'
29
28
 
30
29
  attr_reader :actions
31
30
 
@@ -55,9 +54,9 @@ class NodeMutation
55
54
  end
56
55
 
57
56
  # Initialize a NodeMutation.
58
- # @param file_path [String] file path
59
- def initialize(file_path)
60
- @file_path = file_path
57
+ # @param source [String] file source
58
+ def initialize(source)
59
+ @source = source
61
60
  @actions = []
62
61
  end
63
62
 
@@ -176,21 +175,6 @@ class NodeMutation
176
175
  @actions << ReplaceAction.new(node, *selectors, with: with).process
177
176
  end
178
177
 
179
- # Replace erb stmt node with expr code.
180
- # @param node [Node] ast node
181
- # @example
182
- # source code of the ast node is
183
- # <% form_for post do |f| %>
184
- # <% end %>
185
- # then we call
186
- # replace_erb_stmt_with_expr(node)
187
- # the source code will be rewritten to
188
- # # <%= form_for post do |f| %>
189
- # # <% end %>
190
- def replace_erb_stmt_with_expr(node)
191
- @actions << ReplaceErbStmtWithExprAction.new(node).process
192
- end
193
-
194
178
  # Replace source code of the ast node with new code.
195
179
  # @param node [Node] ast node
196
180
  # @param code [String] code need to be replaced with.
@@ -233,43 +217,29 @@ class NodeMutation
233
217
  # if strategy is set to KEEP_RUNNING.
234
218
  # @return {{conflict: Boolean}} if actions are conflicted
235
219
  def process
236
- conflict_actions = []
237
- if @actions.length > 0
238
- source = +read_source(@file_path)
239
- @actions.sort_by! { |action| [action.start, action.end] }
240
- conflict_actions = get_conflict_actions
241
- if conflict_actions.size > 0 && NodeMutation.strategy == THROW_ERROR
242
- raise ConflictActionError, "mutation actions are conflicted"
243
- end
244
- @actions.reverse_each do |action|
245
- source[action.start...action.end] = action.new_code
246
- end
247
- @actions = []
220
+ if @actions.length == 0
221
+ return NodeMutation::Result.new(affected: false)
222
+ end
248
223
 
249
- write_source(@file_path, source)
224
+ conflict_actions = []
225
+ source = +@source
226
+ @actions.sort_by! { |action| [action.start, action.end] }
227
+ conflict_actions = get_conflict_actions
228
+ if conflict_actions.size > 0 && NodeMutation.strategy == THROW_ERROR
229
+ raise ConflictActionError, "mutation actions are conflicted"
250
230
  end
251
- OpenStruct.new(conflict: !conflict_actions.empty?)
231
+ @actions.reverse_each do |action|
232
+ source[action.start...action.end] = action.new_code
233
+ end
234
+ NodeMutation::Result.new(
235
+ affected: true,
236
+ conflicted: !conflict_actions.empty?,
237
+ new_source: source
238
+ )
252
239
  end
253
240
 
254
241
  private
255
242
 
256
- # Read file source.
257
- # @param file_path [String] file path
258
- # @return [String] file source
259
- def read_source(file_path)
260
- source = File.read(file_path, encoding: 'UTF-8')
261
- source = Engine::Erb.encode(source) if /\.erb$/.match?(file_path)
262
- source
263
- end
264
-
265
- # Write file source to file.
266
- # @param file_path [String] file path
267
- # @param source [String] file source
268
- def write_source(file_path, source)
269
- source = Engine::ERB.decode(source) if /\.erb/.match?(file_path)
270
- File.write(file_path, source.gsub(/ +\n/, "\n"))
271
- end
272
-
273
243
  # It changes source code from bottom to top, and it can change source code twice at the same time,
274
244
  # So if there is an overlap between two actions, it removes the conflict actions and operate them in the next loop.
275
245
  def get_conflict_actions
@@ -0,0 +1,9 @@
1
+ class NodeMutation::Result
2
+ def initialize: (source: String) -> NodeMutation::Result
3
+
4
+ def affected?: () -> bool
5
+
6
+ def conflicted?: () -> bool
7
+
8
+ def new_source: () -> String
9
+ end
@@ -19,7 +19,7 @@ module NodeMutation[T]
19
19
 
20
20
  def self.strategry: () -> Integer
21
21
 
22
- def initialize: (file_path: String) -> NodeMutation
22
+ def initialize: (source: String) -> NodeMutation
23
23
 
24
24
  def append: (node: T, code: String) -> void
25
25
 
@@ -35,11 +35,9 @@ module NodeMutation[T]
35
35
 
36
36
  def replace: (node: T, *selectors: Array[String], with: String) -> void
37
37
 
38
- def replace_erb_stmt_with_expr: (node: T) -> void
39
-
40
38
  def replace_with: (node: T, code: String) -> void
41
39
 
42
40
  def wrap: (node: T, with: String) -> void
43
41
 
44
- def process: () -> void
42
+ def process: () -> NodeMutation::Result
45
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: node_mutation
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
@@ -62,17 +62,18 @@ files:
62
62
  - lib/node_mutation/action/prepend_action.rb
63
63
  - lib/node_mutation/action/remove_action.rb
64
64
  - lib/node_mutation/action/replace_action.rb
65
- - lib/node_mutation/action/replace_erb_stmt_with_expr_action.rb
66
65
  - lib/node_mutation/action/replace_with_action.rb
67
66
  - lib/node_mutation/action/wrap_action.rb
68
67
  - lib/node_mutation/adapter.rb
69
68
  - lib/node_mutation/engine.rb
70
69
  - lib/node_mutation/engine/erb.rb
71
70
  - lib/node_mutation/parser_adapter.rb
71
+ - lib/node_mutation/result.rb
72
72
  - lib/node_mutation/version.rb
73
73
  - node_mutation.gemspec
74
74
  - sig/node_mutation.rbs
75
75
  - sig/node_mutation/adapter.rbs
76
+ - sig/node_mutation/result.rbs
76
77
  homepage: https://github.com/xinminlabs/node-mutation-ruby
77
78
  licenses: []
78
79
  metadata:
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # ReplaceErbStmtWithExprAction to replace erb stmt code to expr,
4
- # @example
5
- # e.g. <% form_for ... %> => <%= form_for ... %>.
6
- class NodeMutation::ReplaceErbStmtWithExprAction < NodeMutation::Action
7
- # Initialize a ReplaceErbStmtWithExprAction.
8
- #
9
- # @param node [Synvert::Core::Rewriter::Node]
10
- def initialize(node)
11
- super(node, nil)
12
- end
13
-
14
- # The new erb expr code.
15
- #
16
- # @return [String] new code.
17
- def new_code
18
- NodeMutation.adapter.file_content(@node)[@start...@end]
19
- .sub(NodeMutation::Engine::ERUBY_STMT_SPLITTER, '@output_buffer.append= ')
20
- .sub(NodeMutation::Engine::ERUBY_STMT_SPLITTER, NodeMutation::Engine::ERUBY_EXPR_SPLITTER)
21
- end
22
-
23
- private
24
-
25
- # Calculate the begin the end positions.
26
- def calculate_position
27
- node_start = NodeMutation.adapter.get_start(@node)
28
- node_source = NodeMutation.adapter.get_source(@node)
29
- file_content = NodeMutation.adapter.file_content(@node)
30
-
31
- whitespace_index = node_start
32
- while file_content[whitespace_index -= 1] == ' '
33
- end
34
- @start = whitespace_index - NodeMutation::Engine::ERUBY_STMT_SPLITTER.length + 1
35
-
36
- at_index = node_start + node_source.index('do')
37
- while file_content[at_index += 1] != '@'
38
- end
39
- @end = at_index
40
- end
41
- end