ffast 0.1.5 → 0.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.
@@ -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
  - - ">="