ffast 0.0.3 → 0.0.4

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: c75d9b66509133b2f2579a03d663a80ece65421f309819f6c04b67c641973816
4
- data.tar.gz: d172f92548e5080074d9edc2ec23bbc0a3febd3cfcfe1296d743a0a219ebfb8f
3
+ metadata.gz: 0c7eee39cf27764a49009037c603ebd8f9afe0b8f0d78ac651c2bdee1d65f329
4
+ data.tar.gz: '09eefe65daeeb37ed5d49120cbee73018303156df11f25daa5258ce310a1be89'
5
5
  SHA512:
6
- metadata.gz: 12f1c29903c12fe53e0b1a6b9c8c54664eb34411dbb9ae88c813359fe0df342c4a0c4168f13598a357281992ba89f7e5a1bdf8196e4217ce6b451d60d1cef364
7
- data.tar.gz: 98e8a7f6b9a374197124b2a0b293fececd46bf396f86d6981de27193b9dc5c92532bc66763a31f446dae4d638967ea601f1348f633bbee6ca383ab5a2d63e54d
6
+ metadata.gz: 163730827f44a4d9a5491b47f96e6d3f10d883921710b5fa2e6f9573a586e71ff84460710288b3388ef209c90744f01d7dfc03ca5f5daff5a62c2179e3da43c5
7
+ data.tar.gz: 0ecc89dd396c151c07fcf6bc9de52c3dc183909bb29498715f2e703124db75e03847894a3d7394e79b9beabee750fa13db23d74bcc95b68a721553d6f5b8c46b
@@ -15,6 +15,7 @@ Metrics/LineLength:
15
15
  Metrics/BlockLength:
16
16
  Exclude:
17
17
  - 'spec/**/*'
18
+ - 'fast.gemspec'
18
19
 
19
20
  Lint/InterpolationCheck:
20
21
  Exclude:
@@ -35,3 +36,6 @@ RSpec/NestedGroups:
35
36
 
36
37
  RSpec/ExampleLength:
37
38
  Max: 20
39
+
40
+ RSpec/MultipleExpectations:
41
+ Enabled: false
data/README.md CHANGED
@@ -23,6 +23,7 @@ The current version cover the following elements:
23
23
  - `^` is to get the **parent node** of an expression
24
24
  - `?` is for **maybe**
25
25
  - `\1` to use the first **previous captured** element
26
+ - `%1` to bind the first extra argument
26
27
  - `""` surround the value with double quotes to match literal strings
27
28
 
28
29
  The syntax is inspired on [RuboCop Node Pattern](https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/node_pattern.rb).
@@ -192,6 +193,17 @@ It will output each comparison to stdout:
192
193
  int == (int 1) # => true
193
194
  1 == 1 # => true
194
195
  ```
196
+ ## Bind arguments to expressions
197
+
198
+ Sometimes we need to define useful functions and bind arguments that will be
199
+ based on dynamic decisions or other external input.
200
+ For such cases you can bind the arguments with `%` and the index start from `1`.
201
+
202
+ Example:
203
+
204
+ ```ruby
205
+ Fast.match?(code['a = 1'], '(lvasgn %1 (int _))', :a) # true
206
+ ```
195
207
 
196
208
  ## Use previous captures in search
197
209
 
data/bin/fast CHANGED
@@ -4,61 +4,6 @@
4
4
  $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
5
5
 
6
6
  require 'fast'
7
- require 'coderay'
7
+ require 'fast/cli'
8
8
 
9
- arguments = ARGV
10
- show_sexp = arguments.delete('--ast')
11
- pry = arguments.delete('--pry')
12
- from_code = arguments.delete('--code') || arguments.delete('-c')
13
- similar = arguments.delete('--similar') || arguments.delete('-s')
14
- debug = arguments.delete('--debug') || arguments.delete('-d')
15
-
16
- pattern = arguments.shift
17
-
18
- if similar || from_code
19
- ast = Fast.ast(pattern)
20
- if similar
21
- puts "Looking for code similar to #{pattern}" if debug
22
- pattern = Fast.expression_from(ast)
23
- elsif from_code
24
- pattern = ast.to_sexp
25
- puts 'The generated expression from AST was:', pattern if debug
26
- end
27
- end
28
- arguments << '.' if arguments.empty?
29
-
30
- files = Fast.ruby_files_from(*arguments)
31
-
32
- expression = Fast.expression(pattern)
33
-
34
- puts "Expression: #{expression.map(&:to_s).join(' ')}" if debug
35
-
36
- files.each do |file|
37
- results =
38
- if debug
39
- Fast.debug { Fast.search_file(expression, file) }
40
- else
41
- begin
42
- Fast.search_file(expression, file)
43
- rescue Parser::SyntaxError
44
- if debug
45
- puts "Ops! An error occurred trying to search in #{expression.inspect} in #{file}",
46
- $ERROR_INFO,
47
- $ERROR_POSITION
48
- end
49
- end
50
- end
51
-
52
- next unless results
53
-
54
- results.each do |result|
55
- next if result.nil? || result == []
56
-
57
- if pry
58
- require 'pry'
59
- binding.pry # rubocop:disable Lint/Debugger
60
- else
61
- Fast.report(result, file: file, show_sexp: show_sexp)
62
- end
63
- end
64
- end
9
+ Fast::Cli.run! ARGV
@@ -145,3 +145,9 @@ You can limit experiments or file escope:
145
145
  fast-experiment RSpec/RemoveUselessBeforeAfterHook spec/models/**/*_spec.rb
146
146
  ```
147
147
 
148
+ Or a single file:
149
+
150
+ ```
151
+ fast-experiment RSpec/ReplaceCreateWithBuildStubbed spec/models/my_spec.rb
152
+ ```
153
+
@@ -2,6 +2,8 @@
2
2
 
3
3
  This is a small tutorial to explore code similarity.
4
4
 
5
+ Check the code example [here](https://github.com/jonatas/fast/blob/master/examples/similarity_research.rb).
6
+
5
7
  The major idea is register all expression styles and see if we can find some
6
8
  similarity between the structures.
7
9
 
@@ -94,7 +96,7 @@ files required by bundler.
94
96
  ```ruby
95
97
  similarities = {}
96
98
  Gem.find_files('*.rb').each do |file|
97
- Fast.search_file('',file).map do |n|
99
+ Fast.search_file('{block send if while case def defs class module}', file).map do |n|
98
100
  key = Fast.expression_from(n)
99
101
  similarities[key] ||= Set.new
100
102
  similarities[key] << file
@@ -181,7 +181,7 @@ ANSWER = 42
181
181
 
182
182
  Let's hunt for integer nodes that the parent is also a method:
183
183
 
184
- $ fast '[ ^^int def ]' example.rb
184
+ $ fast '[ ^^int def ]' example.rb
185
185
 
186
186
  The match will filter only nodes that matches all internal expressions.
187
187
 
@@ -199,7 +199,7 @@ type `def`.
199
199
 
200
200
  Looking the method representation we have:
201
201
 
202
- $ fast def example.rb --ast
202
+ $ fast def example.rb --ast
203
203
 
204
204
  ```ruby
205
205
  # example.rb:3
@@ -0,0 +1,58 @@
1
+ require 'bundler/setup'
2
+ require 'fast'
3
+ require 'coderay'
4
+ require 'pp'
5
+ require 'set'
6
+
7
+ arguments = ARGV
8
+ pattern = arguments.shift || '{ block case send def defs while class if }'
9
+
10
+ files = Fast.ruby_files_from(*%w(spec lib app gems)) +
11
+ Dir[File.join(Gem.path.first,'**/*.rb')]
12
+
13
+ total = files.count
14
+ pattern = Fast.expression(pattern)
15
+
16
+ similarities = {}
17
+
18
+ def similarities.show pattern
19
+ files = self[pattern]
20
+ files.each do |file|
21
+ nodes = Fast.search_file(pattern, file)
22
+ nodes.each do |result|
23
+ Fast.report(result, file: file)
24
+ end
25
+ end
26
+ end
27
+
28
+ def similarities.top
29
+ self.transform_values(&:size)
30
+ .sort_by{|search,results|search.size / results.size}
31
+ .reverse.select{|k,v|v > 10}[0,10]
32
+ end
33
+
34
+ begin
35
+ files.each_with_index do |file, i|
36
+ progress = ((i / total.to_f) * 100.0).round(2)
37
+ print "\r (#{i}/#{total}) #{progress}% Researching on #{file}"
38
+ begin
39
+ results = Fast.search_file(pattern, file) || []
40
+ rescue
41
+ next
42
+ end
43
+ results.each do |n|
44
+ search = Fast.expression_from(n)
45
+ similarities[search] ||= Set.new
46
+ similarities[search] << file
47
+ end
48
+ end
49
+ rescue Interrupt
50
+ # require 'pry'; binding.pry
51
+ end
52
+
53
+ puts "mapped #{similarities.size} cases"
54
+ similarities.delete_if {|k,v| k.size < 30 || v.size < 5}
55
+ puts "Removing the small ones we have #{similarities.size} similarities"
56
+
57
+ similarities.show similarities.top[0][0]
58
+
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # For specs using `let(:something) { create ... }` it tries to use
4
+ # `build_stubbed` instead
5
+ Fast.experiment('RSpec/ReplaceCreateWithBuildStubbed') do
6
+ lookup 'spec'
7
+ search '(block (send nil let (sym _)) (args) $(send nil create))'
8
+ edit { |_, (create)| replace(create.loc.selector, 'build_stubbed') }
9
+ policy { |new_file| system("bin/spring rspec --format progress --fail-fast #{new_file}") }
10
+ end
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'fast/version'
6
+
3
7
  Gem::Specification.new do |spec|
4
8
  spec.name = 'ffast'
5
- spec.version = '0.0.3'
9
+ spec.version = Fast::VERSION
6
10
  spec.required_ruby_version = '>= 2.3'
7
11
  spec.authors = ['Jônatas Davi Paganini']
8
- spec.email = ['jonatas.paganini@toptal.com']
12
+ spec.email = ['jonatasdp@gmail.com']
13
+ spec.homepage = 'https://jonatas.github.io/fast/'
9
14
 
10
15
  spec.summary = 'FAST: Find by AST.'
11
16
  spec.description = 'Allow you to search for code using node pattern syntax.'
@@ -14,16 +19,22 @@ Gem::Specification.new do |spec|
14
19
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
20
  f.match(%r{^(test|spec|features)/})
16
21
  end
22
+
17
23
  spec.bindir = 'bin'
18
24
  spec.executables = ['fast', 'fast-experiment']
19
25
  spec.require_paths = %w[lib experiments]
20
26
 
21
- spec.add_development_dependency 'bundler', '~> 1.14'
22
- spec.add_development_dependency 'rake', '~> 10.0'
23
- spec.add_development_dependency 'rspec', '~> 3.0'
24
27
  spec.add_dependency 'coderay'
25
28
  spec.add_dependency 'parser'
26
29
  spec.add_dependency 'pry'
30
+
31
+ spec.add_development_dependency 'bundler', '~> 1.14'
32
+ spec.add_development_dependency 'guard'
33
+ spec.add_development_dependency 'guard-livereload'
34
+ spec.add_development_dependency 'guard-rspec'
35
+ spec.add_development_dependency 'rake', '~> 10.0'
36
+ spec.add_development_dependency 'rspec', '~> 3.0'
37
+ spec.add_development_dependency 'rspec-its', '~> 1.2'
27
38
  spec.add_development_dependency 'rubocop'
28
39
  spec.add_development_dependency 'rubocop-rspec'
29
40
  end
@@ -19,7 +19,6 @@ end
19
19
 
20
20
  # Fast is a tool to help you search in the code through the Abstract Syntax Tree
21
21
  module Fast
22
- VERSION = '0.3.0'
23
22
  LITERAL = {
24
23
  '...' => ->(node) { node&.children&.any? },
25
24
  '_' => ->(node) { !node.nil? },
@@ -54,11 +53,13 @@ module Fast
54
53
  \$ # capture
55
54
  |
56
55
  \\\d # find using captured expression
56
+ |
57
+ %\d # find using binded argument
57
58
  /x
58
59
 
59
60
  class << self
60
- def match?(ast, search)
61
- Matcher.new(ast, search).match?
61
+ def match?(ast, search, *args)
62
+ Matcher.new(ast, search, *args).match?
62
63
  end
63
64
 
64
65
  def replace(ast, search, replacement)
@@ -186,7 +187,7 @@ module Fast
186
187
  "(#{node.type}#{' ' + children_expression if node.children.any?})"
187
188
  when nil, 'nil'
188
189
  'nil'
189
- when Symbol, String, Integer
190
+ when Symbol, String, Numeric
190
191
  '_'
191
192
  when Array, Hash
192
193
  '...'
@@ -228,7 +229,7 @@ module Fast
228
229
  # ExpressionParser empowers the AST search in Ruby.
229
230
  # You can check a few classes inheriting `Fast::Find` and adding extra behavior.
230
231
  # Parens encapsulates node search: `(node_type children...)` .
231
- # Exclamation Mark to negate: `!(int _)` is equilvalent to a `not integer` node.
232
+ # Exclamation Mark to negate: `!(int _)` is equivalent to a `not integer` node.
232
233
  # Curly Braces allows [Any]: `({int float} _)` or `{(int _) (float _)}`.
233
234
  # Square Braquets allows [All]: [(int _) !(int 0)] # all integer less zero.
234
235
  # Dollar sign can be used to capture values: `(${int float} _)` will capture the node type.
@@ -243,6 +244,7 @@ module Fast
243
244
 
244
245
  # rubocop:disable Metrics/CyclomaticComplexity
245
246
  # rubocop:disable Metrics/AbcSize
247
+ # rubocop:disable Metrics/MethodLength
246
248
  def parse
247
249
  case (token = next_token)
248
250
  when '(' then parse_until_peek(')')
@@ -254,11 +256,13 @@ module Fast
254
256
  when '?' then Maybe.new(parse)
255
257
  when '^' then Parent.new(parse)
256
258
  when '\\' then FindWithCapture.new(parse)
259
+ when /^%\d/ then FindFromArgument.new(token[1..-1])
257
260
  else Find.new(token)
258
261
  end
259
262
  end
260
263
  # rubocop:enable Metrics/CyclomaticComplexity
261
264
  # rubocop:enable Metrics/AbcSize
265
+ # rubocop:enable Metrics/MethodLength
262
266
 
263
267
  def parse_until_peek(token)
264
268
  list = []
@@ -302,8 +306,14 @@ module Fast
302
306
  end
303
307
 
304
308
  def compare_symbol_or_head(node, expression)
305
- type = node.respond_to?(:type) ? node.type : node
306
- type == expression
309
+ case node
310
+ when Parser::AST::Node
311
+ node.type == expression.to_sym
312
+ when String
313
+ node == expression.to_s
314
+ else
315
+ node == expression
316
+ end
307
317
  end
308
318
 
309
319
  def debug_match_recursive(node, expression)
@@ -379,6 +389,30 @@ module Fast
379
389
  end
380
390
  end
381
391
 
392
+ # Use `%1` in the expression and the Matcher#prepare_arguments will
393
+ # interpolate the argument in the expression.
394
+ class FindFromArgument < Find
395
+ attr_writer :arguments
396
+
397
+ def initialize(token)
398
+ token = token.token if token.respond_to?(:token)
399
+ raise 'You must define index' unless token
400
+
401
+ @capture_argument = token.to_i - 1
402
+ raise 'Arguments start in one' if @capture_argument.negative?
403
+ end
404
+
405
+ def match?(node)
406
+ raise 'You must define arguments to match' unless @arguments
407
+
408
+ compare_symbol_or_head node, @arguments[@capture_argument]
409
+ end
410
+
411
+ def to_s
412
+ "find_with_arg[\\#{@capture_argument}]"
413
+ end
414
+ end
415
+
382
416
  # Capture some expression while searching for it:
383
417
  # Example: `(${int float} _)` will capture the node type
384
418
  # Example: `$({int float} _)` will capture the node
@@ -458,7 +492,7 @@ module Fast
458
492
 
459
493
  # Joins the AST and the search expression to create a complete match
460
494
  class Matcher
461
- def initialize(ast, fast)
495
+ def initialize(ast, fast, *args)
462
496
  @ast = ast
463
497
  @fast = if fast.is_a?(String)
464
498
  Fast.expression(fast)
@@ -466,9 +500,22 @@ module Fast
466
500
  [*fast].map(&Find.method(:new))
467
501
  end
468
502
  @captures = []
503
+ prepare_arguments(@fast, args) if args.any?
504
+ end
505
+
506
+ def prepare_arguments(expression, arguments)
507
+ case expression
508
+ when Array
509
+ expression.each do |item|
510
+ prepare_arguments(item, arguments)
511
+ end
512
+ when Fast::FindFromArgument
513
+ expression.arguments = arguments
514
+ when Fast::Find
515
+ prepare_arguments expression.token, arguments
516
+ end
469
517
  end
470
518
 
471
- # rubocop:disable Metrics/CyclomaticComplexity
472
519
  # rubocop:disable Metrics/AbcSize
473
520
  def match?(ast = @ast, fast = @fast)
474
521
  head, *tail = fast
@@ -479,13 +526,20 @@ module Fast
479
526
 
480
527
  child = ast.children
481
528
  tail.each_with_index.all? do |token, i|
482
- token.previous_captures = find_captures if token.is_a?(Fast::FindWithCapture)
529
+ prepare_token(token)
483
530
  token.is_a?(Array) ? match?(child[i], token) : token.match?(child[i])
484
531
  end && find_captures
485
532
  end
486
- # rubocop:enable Metrics/CyclomaticComplexity
533
+
487
534
  # rubocop:enable Metrics/AbcSize
488
535
 
536
+ def prepare_token(token)
537
+ case token
538
+ when Fast::FindWithCapture
539
+ token.previous_captures = find_captures
540
+ end
541
+ end
542
+
489
543
  def captures?(fast = @fast)
490
544
  case fast
491
545
  when Capture then true
@@ -645,7 +699,7 @@ module Fast
645
699
 
646
700
  def run
647
701
  while (combinations = suggest_combinations).any?
648
- if combinations.size > 30
702
+ if combinations.size > 50
649
703
  puts "Ignoring #{@file} because it have #{combinations.size} possible combinations"
650
704
  break
651
705
  end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fast'
4
+ require 'fast/version'
5
+ require 'coderay'
6
+ require 'optparse'
7
+ require 'ostruct'
8
+
9
+ module Fast
10
+ # Command Line Interface for Fast
11
+ class Cli
12
+ attr_reader :pattern, :show_sexp, :pry, :from_code, :similar, :help
13
+
14
+ # rubocop:disable Metrics/MethodLength
15
+ # rubocop:disable Metrics/AbcSize
16
+ def initialize(args)
17
+ @opt = OptionParser.new do |opts| # rubocop:disable Metrics/BlockLength
18
+ opts.banner = 'Usage: fast expression <files> [options]'
19
+ opts.on('-d', '--debug', 'Debug fast engine') do
20
+ @debug = true
21
+ end
22
+
23
+ opts.on('--ast', 'Print AST instead of code') do
24
+ @show_sexp = true
25
+ end
26
+
27
+ opts.on('--pry', 'Jump into a pry session with results') do
28
+ @pry = true
29
+ end
30
+
31
+ opts.on('-c', '--code', 'Create a pattern from code example') do
32
+ if @pattern
33
+ @from_code = true
34
+ @pattern = Fast.ast(@pattern).to_sexp
35
+ debug 'Expression from AST:', @pattern
36
+ end
37
+ end
38
+
39
+ opts.on('-s', '--similar', 'Search for similar code.') do
40
+ @similar = true
41
+ @pattern = Fast.expression_from(Fast.ast(@pattern))
42
+ debug "Looking for code similar to #{@pattern}"
43
+ end
44
+
45
+ opts.on_tail('--version', 'Show version') do
46
+ puts Fast::VERSION
47
+ exit
48
+ end
49
+
50
+ opts.on_tail('-h', '--help', 'Show help. More at https://jonatas.github.io/fast') do
51
+ @help = true
52
+ end
53
+
54
+ @pattern, @files = args.reject { |arg| arg.start_with? '-' }
55
+ end
56
+ @opt.parse! args
57
+
58
+ @files = [*@files]
59
+ @files.reject! { |arg| arg.start_with?('-') }
60
+ end
61
+
62
+ # rubocop:enable Metrics/MethodLength
63
+ # rubocop:enable Metrics/AbcSize
64
+
65
+ def self.run!(argv)
66
+ argv = argv.dup
67
+ new(argv).run!
68
+ end
69
+
70
+ def run!
71
+ if @help || @files.empty? && @pattern.nil?
72
+ puts @opt.help
73
+ else
74
+ search
75
+ end
76
+ end
77
+
78
+ def expression
79
+ Fast.expression(@pattern)
80
+ end
81
+
82
+ def search_file(file)
83
+ if debug_mode?
84
+ Fast.debug { Fast.search_file(expression, file) }
85
+ else
86
+ begin
87
+ Fast.search_file(expression, file)
88
+ rescue StandardError
89
+ debug "Ops! An error occurred trying to search in #{expression.inspect} in #{file}", $ERROR_INFO, $ERROR_POSITION
90
+ []
91
+ end
92
+ end
93
+ end
94
+
95
+ def search
96
+ files.each do |file|
97
+ results = search_file(file)
98
+ next if results.nil? || results.empty?
99
+
100
+ results.each do |result|
101
+ if @pry
102
+ require 'pry'
103
+ binding.pry # rubocop:disable Lint/Debugger
104
+ else
105
+ report(result, file)
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ def files
112
+ Fast.ruby_files_from(*@files)
113
+ end
114
+
115
+ def debug_mode?
116
+ @debug == true
117
+ end
118
+
119
+ def debug(*info)
120
+ return unless @debug
121
+
122
+ puts info
123
+ end
124
+
125
+ def report(result, file)
126
+ Fast.report(result, file: file, show_sexp: @show_sexp)
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fast
4
+ VERSION = '0.0.4'
5
+ end
metadata CHANGED
@@ -1,65 +1,79 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jônatas Davi Paganini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-17 00:00:00.000000000 Z
11
+ date: 2018-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: coderay
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.14'
20
- type: :development
19
+ version: '0'
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.14'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: parser
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
34
- type: :development
33
+ version: '0'
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
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: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '3.0'
61
+ version: '1.14'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '3.0'
68
+ version: '1.14'
55
69
  - !ruby/object:Gem::Dependency
56
- name: coderay
70
+ name: guard
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
60
74
  - !ruby/object:Gem::Version
61
75
  version: '0'
62
- type: :runtime
76
+ type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
@@ -67,13 +81,13 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: parser
84
+ name: guard-livereload
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
74
88
  - !ruby/object:Gem::Version
75
89
  version: '0'
76
- type: :runtime
90
+ type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
@@ -81,19 +95,61 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: pry
98
+ name: guard-rspec
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
88
102
  - !ruby/object:Gem::Version
89
103
  version: '0'
90
- type: :runtime
104
+ type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec-its
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.2'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.2'
97
153
  - !ruby/object:Gem::Dependency
98
154
  name: rubocop
99
155
  requirement: !ruby/object:Gem::Requirement
@@ -124,7 +180,7 @@ dependencies:
124
180
  version: '0'
125
181
  description: Allow you to search for code using node pattern syntax.
126
182
  email:
127
- - jonatas.paganini@toptal.com
183
+ - jonatasdp@gmail.com
128
184
  executables:
129
185
  - fast
130
186
  - fast-experiment
@@ -155,12 +211,16 @@ files:
155
211
  - examples/find_usage.rb
156
212
  - examples/let_it_be_experiment.rb
157
213
  - examples/method_complexity.rb
214
+ - examples/similarity_research.rb
158
215
  - experiments/let_it_be_experiment.rb
159
216
  - experiments/remove_useless_hook.rb
217
+ - experiments/replace_create_with_build_stubbed.rb
160
218
  - fast.gemspec
161
219
  - lib/fast.rb
220
+ - lib/fast/cli.rb
221
+ - lib/fast/version.rb
162
222
  - mkdocs.yml
163
- homepage:
223
+ homepage: https://jonatas.github.io/fast/
164
224
  licenses:
165
225
  - MIT
166
226
  metadata: {}