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.
- checksums.yaml +4 -4
- data/.rubocop.yml +114 -2
- data/.sourcelevel.yml +2 -0
- data/.travis.yml +2 -2
- data/Fastfile +3 -0
- data/README.md +10 -5
- data/docs/command_line.md +1 -0
- data/docs/editors-integration.md +46 -0
- data/docs/ideas.md +80 -0
- data/docs/index.md +5 -0
- data/docs/research.md +93 -0
- data/docs/shortcuts.md +323 -0
- data/docs/videos.md +16 -0
- data/fast.gemspec +6 -4
- data/lib/fast.rb +135 -40
- data/lib/fast/cli.rb +61 -23
- data/lib/fast/experiment.rb +1 -2
- data/lib/fast/git.rb +101 -0
- data/lib/fast/shortcut.rb +6 -9
- data/lib/fast/version.rb +1 -1
- data/mkdocs.yml +5 -0
- metadata +54 -13
data/lib/fast/cli.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
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
|
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
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
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
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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(
|
182
|
-
Fast.report(result,
|
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
|
-
|
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
|
data/lib/fast/experiment.rb
CHANGED
@@ -290,7 +290,7 @@ module Fast
|
|
290
290
|
Fast.search(experiment.expression, @ast) || []
|
291
291
|
end
|
292
292
|
|
293
|
-
# rubocop:disable Metrics/
|
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
|
data/lib/fast/git.rb
ADDED
@@ -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
|
data/lib/fast/shortcut.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/fast/version.rb
CHANGED
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.
|
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:
|
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:
|
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:
|
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: '
|
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: '
|
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.
|
328
|
+
version: '2.6'
|
288
329
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
289
330
|
requirements:
|
290
331
|
- - ">="
|