ffast 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -36,12 +36,16 @@ module Fast
36
36
  # @param headless [Boolean] Skip printing the file name and line before content
37
37
  # @example
38
38
  # Fast.highlight(Fast.search(...))
39
- def report(result, show_sexp: false, file: nil, headless: false, colorize: true)
39
+ def report(result, show_link: false, show_sexp: false, file: nil, headless: false, bodyless: false, colorize: true) # rubocop:disable Metrics/ParameterLists
40
40
  if file
41
41
  line = result.loc.expression.line if result.is_a?(Parser::AST::Node)
42
- puts(highlight("# #{file}:#{line}", colorize: colorize)) unless headless
42
+ if show_link
43
+ puts(result.link)
44
+ elsif !headless
45
+ puts(highlight("# #{file}:#{line}", colorize: colorize))
46
+ end
43
47
  end
44
- puts highlight(result, show_sexp: show_sexp, colorize: colorize)
48
+ puts(highlight(result, show_sexp: show_sexp, colorize: colorize)) unless bodyless
45
49
  end
46
50
 
47
51
  # Command Line Interface for Fast
@@ -69,6 +73,15 @@ module Fast
69
73
  @show_sexp = true
70
74
  end
71
75
 
76
+ opts.on('--link', 'Print link to repository URL instead of code') do
77
+ require 'fast/git'
78
+ @show_link = true
79
+ end
80
+
81
+ opts.on('-p', '--parallel', 'Paralelize search') do
82
+ @parallel = true
83
+ end
84
+
72
85
  opts.on('--captures', 'Print only captures of the patterns and skip node results') do
73
86
  @captures = true
74
87
  end
@@ -77,6 +90,10 @@ module Fast
77
90
  @headless = true
78
91
  end
79
92
 
93
+ opts.on('--bodyless', 'Print results without the code details') do
94
+ @bodyless = true
95
+ end
96
+
80
97
  opts.on('--pry', 'Jump into a pry session with results') do
81
98
  @pry = true
82
99
  require 'pry'
@@ -112,12 +129,13 @@ module Fast
112
129
  end
113
130
 
114
131
  def replace_args_with_shortcut(args)
115
- shortcut = find_shortcut args.first[1..-1]
132
+ shortcut = find_shortcut args.first[1..]
133
+
116
134
  if shortcut.single_run_with_block?
117
135
  shortcut.run
118
136
  exit
119
137
  else
120
- args.one? ? shortcut.args : shortcut.merge_args(args[1..-1])
138
+ args.one? ? shortcut.args : shortcut.merge_args(args[1..])
121
139
  end
122
140
  end
123
141
 
@@ -129,6 +147,8 @@ module Fast
129
147
 
130
148
  # Show help or search for node patterns
131
149
  def run!
150
+ raise 'pry and parallel options are incompatible :(' if @parallel && @pry
151
+
132
152
  if @help || @files.empty? && @pattern.nil?
133
153
  puts option_parser.help
134
154
  else
@@ -137,6 +157,7 @@ module Fast
137
157
  end
138
158
 
139
159
  # Create fast expression from node pattern using the command line
160
+ # @return [Array<Fast::Find>] with the expression from string.
140
161
  def expression
141
162
  Fast.expression(@pattern)
142
163
  end
@@ -146,24 +167,29 @@ module Fast
146
167
  # If capture option is enabled it will only print the captures, otherwise it
147
168
  # prints all the results.
148
169
  def search
149
- if debug_mode?
150
- Fast.debug { execute_search }
151
- else
152
- execute_search do |file, results|
153
- results.each do |result|
154
- binding.pry if @pry # rubocop:disable Lint/Debugger
155
- report(result, file)
156
- end
170
+ return Fast.debug(&method(:execute_search)) if debug_mode?
171
+
172
+ execute_search do |file, results|
173
+ results.each do |result|
174
+ binding.pry if @pry # rubocop:disable Lint/Debugger
175
+ report(file, result)
157
176
  end
158
177
  end
159
178
  end
160
179
 
161
- def execute_search
162
- method_name = @captures ? :capture_all : :search_all
163
- (Fast.public_send(method_name, expression, @files) || []).each do |file, results|
164
- results = [results] unless results.is_a?(Array)
165
- yield file, results
166
- end
180
+ # Executes search for all files yielding the results
181
+ # @yieldparam [String, Array] with file and respective search results
182
+ def execute_search(&on_result)
183
+ Fast.public_send(search_method_name,
184
+ expression,
185
+ @files,
186
+ parallel: parallel?,
187
+ on_result: on_result)
188
+ end
189
+
190
+ # @return [Symbol] with `:capture_all` or `:search_all` depending the command line options
191
+ def search_method_name
192
+ @captures ? :capture_all : :search_all
167
193
  end
168
194
 
169
195
  # @return [Boolean] true when "-d" or "--debug" option is passed
@@ -176,10 +202,20 @@ module Fast
176
202
  puts(info) if debug_mode?
177
203
  end
178
204
 
205
+ def parallel?
206
+ @parallel == true
207
+ end
208
+
179
209
  # Report results using the actual options binded from command line.
180
210
  # @see Fast.report
181
- def report(result, file)
182
- Fast.report(result, file: file, show_sexp: @show_sexp, headless: @headless, colorize: @colorize)
211
+ def report(file, result)
212
+ Fast.report(result,
213
+ file: file,
214
+ show_link: @show_link,
215
+ show_sexp: @show_sexp,
216
+ headless: @headless,
217
+ bodyless: @bodyless,
218
+ colorize: @colorize)
183
219
  end
184
220
 
185
221
  # Find shortcut by name. Preloads all `Fastfiles` before start.
@@ -190,7 +226,6 @@ module Fast
190
226
  Fast.load_fast_files!
191
227
 
192
228
  shortcut = Fast.shortcuts[name] || Fast.shortcuts[name.to_sym]
193
-
194
229
  shortcut || exit_shortcut_not_found(name)
195
230
  end
196
231
 
@@ -198,7 +233,10 @@ module Fast
198
233
  # Prints available shortcuts as extra help and exit with code 1.
199
234
  def exit_shortcut_not_found(name)
200
235
  puts "Shortcut \033[1m#{name}\033[0m not found :("
201
- puts "Available shortcuts are: #{Fast.shortcuts.keys.join(', ')}." if Fast.shortcuts.any?
236
+ if Fast.shortcuts.any?
237
+ puts "Available shortcuts are: #{Fast.shortcuts.keys.join(', ')}."
238
+ Fast.load_fast_files!
239
+ end
202
240
  exit 1
203
241
  end
204
242
  end
@@ -290,7 +290,7 @@ module Fast
290
290
  Fast.search(experiment.expression, @ast) || []
291
291
  end
292
292
 
293
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
293
+ # rubocop:disable Metrics/MethodLength
294
294
  #
295
295
  # Execute partial replacements generating new file with the
296
296
  # content replaced.
@@ -312,7 +312,6 @@ module Fast
312
312
  new_content
313
313
  end
314
314
 
315
- # rubocop:enable Metrics/AbcSize
316
315
  # rubocop:enable Metrics/MethodLength
317
316
 
318
317
  # Write new file name depending on the combination
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Git plugin for Fast::Node.
4
+ # It allows to easily access metadata from current file.
5
+ module Fast
6
+ # This is not required by default, so to use it, you should require it first.
7
+ #
8
+ # @example
9
+ # require 'fast/git'
10
+ # Fast.ast_from_file('lib/fast.rb').git_log.first.author.name # => "Jonatas Davi Paganini"
11
+ class Node < Astrolabe::Node
12
+ # @return [Git::Base] from current directory
13
+ def git
14
+ require 'git' unless defined? Git
15
+ Git.open('.')
16
+ end
17
+
18
+ # @return [Git::Object::Blob] from current #buffer_name
19
+ def git_blob
20
+ return unless from_file?
21
+
22
+ git.gblob(buffer_name)
23
+ end
24
+
25
+ # @return [Git::Log] from the current #git_blob
26
+ # buffer-name
27
+ def git_log
28
+ git_blob.log
29
+ end
30
+
31
+ # @return [Git::Object::Commit]
32
+ def last_commit
33
+ git_log.first
34
+ end
35
+
36
+ # @return [String] with last commit SHA
37
+ def sha
38
+ last_commit.sha
39
+ end
40
+
41
+ # @return [String] with remote URL
42
+ def remote_url
43
+ git.remote.url
44
+ end
45
+
46
+ # Given #remote_url is "git@github.com:namespace/project.git"
47
+ # Or #remote_url is "https://github.com/namespace/project.git"
48
+ # @return [String] "https://github.com/namespace/project"
49
+ def project_url
50
+ return remote_url.gsub(/\.git$/, '') if remote_url.start_with?('https')
51
+
52
+ remote_url
53
+ .gsub('git@', 'https://')
54
+ .gsub(/:(\w)/, '/\\1')
55
+ .gsub(/\.git$/, '')
56
+ end
57
+
58
+ def file
59
+ buffer_name.gsub("#{Dir.pwd}/", '')
60
+ end
61
+
62
+ # @return
63
+ def line_range
64
+ lines.map { |l| "L#{l}" }.join('-')
65
+ end
66
+
67
+ # @return [Array] with lines range
68
+ def lines
69
+ exp = loc.expression
70
+ first_line = exp.first_line
71
+ last_line = exp.last_line
72
+ [first_line, last_line].uniq
73
+ end
74
+
75
+ # @return [Integer] lines of code from current block
76
+ def lines_of_code
77
+ lines.last - lines.first + 1
78
+ end
79
+
80
+ # @return [String] a markdown link with #md_link_description and #link
81
+ def md_link(text = md_link_description)
82
+ "[#{text}](#{link})"
83
+ end
84
+
85
+ # @return [String] with the source cutting arguments from method calls to be
86
+ # able to create a markdown link without parens.
87
+ def md_link_description
88
+ source[/([^\r\(]+)\(/, 1] || source
89
+ end
90
+
91
+ # @return [String] with formatted repositorym link
92
+ def link
93
+ "#{project_url}/blob/master/#{buffer_name}##{line_range}"
94
+ end
95
+
96
+ # @return [String] with permanent link to the actual commit
97
+ def permalink
98
+ "#{project_url}/blob/#{sha}/#{buffer_name}##{line_range}"
99
+ end
100
+ end
101
+ end
@@ -54,19 +54,16 @@ module Fast
54
54
  @block && @args.nil?
55
55
  end
56
56
 
57
- def options
58
- @args.select { |arg| arg.start_with? '-' }
59
- end
60
-
61
- def params
62
- @args - options
63
- end
64
-
65
57
  # Merge extra arguments from input returning a new arguments array keeping
66
58
  # the options from previous alias and replacing the files with the
67
59
  # @param [Array] extra_args
68
60
  def merge_args(extra_args)
69
- [params[0], *options, *extra_args]
61
+ all_args = (@args + extra_args).uniq
62
+ options = all_args.select { |arg| arg.start_with? '-' }
63
+ files = extra_args.select(&File.method(:exists?))
64
+ command = (@args - options - files).first
65
+
66
+ [command, *options, *files]
70
67
  end
71
68
 
72
69
  # If the shortcut was defined with a single block and no extra arguments, it
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fast
4
- VERSION = '0.1.5'
4
+ VERSION = '0.2.0'
5
5
  end
data/mkdocs.yml CHANGED
@@ -18,5 +18,10 @@ nav:
18
18
  - Syntax: syntax.md
19
19
  - Command Line: command_line.md
20
20
  - Experiments: experiments.md
21
+ - Shortcuts: shortcuts.md
21
22
  - Code Similarity: similarity_tutorial.md
22
23
  - Pry Integration: pry-integration.md
24
+ - Editors' Integration: editors-integration.md
25
+ - Research: research.md
26
+ - Ideas: ideas.md
27
+ - Videos: videos.md
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
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: 2019-11-18 00:00:00.000000000 Z
11
+ date: 2020-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: astrolabe
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: parser
42
+ name: parallel
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: pry
56
+ name: parser
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -122,20 +122,48 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: git
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: rake
127
155
  requirement: !ruby/object:Gem::Requirement
128
156
  requirements:
129
- - - "~>"
157
+ - - ">="
130
158
  - !ruby/object:Gem::Version
131
- version: '10.0'
159
+ version: '0'
132
160
  type: :development
133
161
  prerelease: false
134
162
  version_requirements: !ruby/object:Gem::Requirement
135
163
  requirements:
136
- - - "~>"
164
+ - - ">="
137
165
  - !ruby/object:Gem::Version
138
- version: '10.0'
166
+ version: '0'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: rspec
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -210,16 +238,22 @@ dependencies:
210
238
  name: simplecov
211
239
  requirement: !ruby/object:Gem::Requirement
212
240
  requirements:
213
- - - ">="
241
+ - - "~>"
214
242
  - !ruby/object:Gem::Version
215
- version: '0'
243
+ version: '0.10'
244
+ - - "<"
245
+ - !ruby/object:Gem::Version
246
+ version: '0.18'
216
247
  type: :development
217
248
  prerelease: false
218
249
  version_requirements: !ruby/object:Gem::Requirement
219
250
  requirements:
220
- - - ">="
251
+ - - "~>"
221
252
  - !ruby/object:Gem::Version
222
- version: '0'
253
+ version: '0.10'
254
+ - - "<"
255
+ - !ruby/object:Gem::Version
256
+ version: '0.18'
223
257
  description: Allow you to search for code using node pattern syntax.
224
258
  email:
225
259
  - jonatasdp@gmail.com
@@ -233,6 +267,7 @@ files:
233
267
  - ".projections.json"
234
268
  - ".rspec"
235
269
  - ".rubocop.yml"
270
+ - ".sourcelevel.yml"
236
271
  - ".travis.yml"
237
272
  - CODE_OF_CONDUCT.md
238
273
  - Fastfile
@@ -247,11 +282,16 @@ files:
247
282
  - bin/fast-experiment
248
283
  - bin/setup
249
284
  - docs/command_line.md
285
+ - docs/editors-integration.md
250
286
  - docs/experiments.md
287
+ - docs/ideas.md
251
288
  - docs/index.md
252
289
  - docs/pry-integration.md
290
+ - docs/research.md
291
+ - docs/shortcuts.md
253
292
  - docs/similarity_tutorial.md
254
293
  - docs/syntax.md
294
+ - docs/videos.md
255
295
  - examples/build_stubbed_and_let_it_be_experiment.rb
256
296
  - examples/experimental_replacement.rb
257
297
  - examples/find_usage.rb
@@ -267,6 +307,7 @@ files:
267
307
  - lib/fast.rb
268
308
  - lib/fast/cli.rb
269
309
  - lib/fast/experiment.rb
310
+ - lib/fast/git.rb
270
311
  - lib/fast/rewriter.rb
271
312
  - lib/fast/shortcut.rb
272
313
  - lib/fast/version.rb
@@ -284,7 +325,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
284
325
  requirements:
285
326
  - - ">="
286
327
  - !ruby/object:Gem::Version
287
- version: '2.3'
328
+ version: '2.6'
288
329
  required_rubygems_version: !ruby/object:Gem::Requirement
289
330
  requirements:
290
331
  - - ">="