ffast 0.1.2 → 0.1.3

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: c8acf0aec31914d5a9819f27ea422d293702e5f2bdeee36ae2d0bebcc8fc37b1
4
- data.tar.gz: b0b5b4fcf5a2aa3e8138acd7ffc8ba0ce6799aabd7dd9d88fc51ae5f5e2308e9
3
+ metadata.gz: 49dd19ccc728102aba01cf03b72c5a4ce194e036bb7a489abee40bf488bd9821
4
+ data.tar.gz: 390d27be9261ea3333fe91d8561965ee9127965bf9fd1080134e08fba1914410
5
5
  SHA512:
6
- metadata.gz: 4f6027ca24d6b1107957c7b09ffe7ccadf34c0121aabbfd8d0b374bf72801bcbf65f418fe4f78cefb18c4415c4315b5bdf01f11c6b60d3c73698afa4c6feebe0
7
- data.tar.gz: 48fc1cf1b6d4c821cfd8910b0d1c24ece46194376d0c5d88023cfc29808e558956a3cdb589ae28a2f714ec0da380c041a92527201786bad05cbdd59090c130ca
6
+ metadata.gz: 4b73de237734f1799832f4f724b8a2ebf4dfcf116ade615469af205cb61204d777a4e9f05b8483e7647251f20daeef28edf61e72cec2172319b3b1261beee4b0
7
+ data.tar.gz: 330f5f62da86cfa18508f53c13231bcf55993e44d0bea4a9e4fd59427fae1d1aabd22a27b352adac78d6fe24a8abe1ebaf21ea33ef0c63dbafb7a4fdf3883e12
@@ -0,0 +1,4 @@
1
+ {
2
+ "README.md": { "type": "readme" },
3
+ "lib/*.rb": { "type": "lib", "alternate": "spec/{}_spec.rb" }
4
+ }
@@ -40,3 +40,9 @@ RSpec/ExampleLength:
40
40
 
41
41
  RSpec/MultipleExpectations:
42
42
  Enabled: false
43
+
44
+ RSpec/DescribedClass:
45
+ Enabled: false
46
+
47
+ RSpec/ImplicitSubject:
48
+ Enabled: false
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Fastfile is loaded when you start an expression with a dot.
4
+ #
5
+ # You can introduce shortcuts or methods that can be embedded during your
6
+ # command line interactions with fast.
7
+ #
8
+ # Let's say you'd like to show the version that is over the version file
9
+ Fast.shortcut(:version, '(casgn nil VERSION (str _))', 'lib/fast/version.rb')
10
+
11
+ # You can run shortcuts appending a dot to the shortcut.
12
+ # $ fast .version
13
+ # # lib/fast/version.rb:4
14
+ # VERSION = '0.1.2'
15
+
16
+ # Simple shortcut that I used often to show how the expression parser works
17
+ Fast.shortcut(:parser, '(class (const nil ExpressionParser)', 'lib/fast.rb')
18
+
19
+ # Use `fast .bump_version` to rewrite the version file
20
+ Fast.shortcut :bump_version do
21
+ rewrite_file('lib/fast/version.rb', '(casgn nil VERSION (str _)') do |node|
22
+ target = node.children.last.loc.expression
23
+ pieces = target.source.split('.').map(&:to_i)
24
+ pieces.reverse.each_with_index do |fragment, i|
25
+ if fragment < 9
26
+ pieces[-(i + 1)] = fragment + 1
27
+ break
28
+ else
29
+ pieces[-(i + 1)] = 0
30
+ end
31
+ end
32
+ replace(target, "'#{pieces.join('.')}'")
33
+ end
34
+ end
35
+
36
+ # And now a shortcut to print the other shortcuts :)
37
+ Fast.shortcut :shortcuts do
38
+ report(shortcuts.keys)
39
+ end
data/README.md CHANGED
@@ -426,6 +426,64 @@ The CLI tool takes the following flags
426
426
  - Use `-c` to search from code example
427
427
  - Use `-s` to search similar code
428
428
 
429
+ ### Define your `Fastfile`
430
+
431
+ Fastfile is loaded when you start a pattern with a `.`.
432
+
433
+ You can also define extra Fastfile in your home dir or setting a directory with
434
+ the `FAST_FILE_DIR`.
435
+
436
+ You can define a `Fastfile` in any project with your custom shortcuts.
437
+
438
+ ```ruby
439
+ Fast.shortcut(:version, '(casgn nil VERSION (str _))', 'lib/fast/version.rb')
440
+ ```
441
+
442
+ Let's say you'd like to show the version of your library. Your normal
443
+ command line will look like:
444
+
445
+ $ fast '(casgn nil VERSION)' lib/*/version.rb
446
+
447
+ Or generalizing to search all constants in the version files:
448
+
449
+ $ fast casgn lib/*/version.rb
450
+
451
+ It will output but the command is not very handy. In order to just say `fast .version`
452
+ you can use the previous snipped in your `Fastfile`.
453
+
454
+ And it will output something like this:
455
+
456
+ ```ruby
457
+ # lib/fast/version.rb:4
458
+ VERSION = '0.1.2'
459
+ ```
460
+
461
+ Create shortcuts with blocks that are able to introduce custom coding in
462
+ the scope of the `Fast` module
463
+
464
+ To bump a new version of your library for example you can type `fast .bump_version`
465
+ and add the snippet to your library fixing the filename.
466
+
467
+ ```ruby
468
+ Fast.shortcut :bump_version do
469
+ rewrite_file('lib/fast/version.rb', '(casgn nil VERSION (str _)') do |node|
470
+ target = node.children.last.loc.expression
471
+ pieces = target.source.split(".").map(&:to_i)
472
+ pieces.reverse.each_with_index do |fragment,i|
473
+ if fragment < 9
474
+ pieces[-(i+1)] = fragment +1
475
+ break
476
+ else
477
+ pieces[-(i+1)] = 0
478
+ end
479
+ end
480
+ replace(target, "'#{pieces.join(".")}'")
481
+ end
482
+ end
483
+ ```
484
+
485
+ You can find more examples in the [Fastfile](./Fastfile).
486
+
429
487
  ### Fast with Pry
430
488
 
431
489
  You can use `--pry` to stop on a particular source node, and run Pry at that
@@ -1,7 +1,7 @@
1
1
  # Command line
2
2
 
3
- It will also inject a executable named `fast` and you can use it to search and
4
- find code using the concept:
3
+ When you install the ffast gem, it will also create an executable named `fast`
4
+ and you can use it to search and find code using the concept:
5
5
 
6
6
  ```
7
7
  $ fast '(def match?)' lib/fast.rb
@@ -87,9 +87,9 @@ The option `-s` build an expression from the code ignoring final values.
87
87
  object.method
88
88
  ```
89
89
 
90
- See also [Code Similarity](simi)ilarity_tutorial.md) tutorial.
90
+ See also [Code Similarity](similarity_tutorial.md) tutorial.
91
91
 
92
- # `-c` to search from code example
92
+ ## `-c` to search from code example
93
93
 
94
94
  You can search for the exact expression with `-c`
95
95
 
@@ -110,3 +110,105 @@ The generated expression from AST was:
110
110
  (send nil :object) :method)
111
111
  ```
112
112
 
113
+ ## Fastfile
114
+
115
+ `Fastfile` will loaded when you start a pattern with a dot. It means the pattern
116
+ will be a shortcut predefined on these Fastfiles.
117
+
118
+ It will make three attempts to load `Fastfile` defined in `$PWD`, `$HOME` or
119
+ checking if the `$FAST_FILE_DIR` is configured.
120
+
121
+ You can define a `Fastfile` in any project with your custom shortcuts and easy
122
+ check some code or run some task.
123
+
124
+
125
+ ## Shortcuts
126
+
127
+ Create shortcuts with blocks enables introduce custom coding in
128
+ the scope of the `Fast` module.
129
+
130
+ ## Example: Print library version.
131
+
132
+ Let's say you'd like to show the version of your library. Your regular params
133
+ in the command line will look like:
134
+
135
+ $ fast '(casgn nil VERSION)' lib/*/version.rb
136
+
137
+ It will output but the command is not very handy. In order to just say `fast .version`
138
+ you can use the previous snippet in your `Fastfile`.
139
+
140
+ ```ruby
141
+ Fast.shortcut(:version, '(casgn nil VERSION)', 'lib/fast/version.rb')
142
+ ```
143
+
144
+ And calling `fast .version` it will output something like this:
145
+
146
+ ```ruby
147
+ # lib/fast/version.rb:4
148
+ VERSION = '0.1.2'
149
+ ```
150
+
151
+ We can also always override the files params passing some other target file
152
+ like `fast .version lib/other/file.rb` and it will reuse the other arguments
153
+ from command line but replace the target files.
154
+
155
+ ### Example: Bumping a gem version
156
+
157
+ While releasing a new gem version, we always need to mechanical go through the
158
+ `lib/<your_gem>/version.rb` and change the string value to bump the version
159
+ of your library. It's pretty mechanical and here is an example that allow you
160
+ to simple use `fast .bump_version`:
161
+
162
+ ```ruby
163
+ Fast.shortcut :bump_version do
164
+ rewrite_file('lib/fast/version.rb', '(casgn nil VERSION (str _)') do |node|
165
+ target = node.children.last.loc.expression
166
+ pieces = target.source.split(".").map(&:to_i)
167
+ pieces.reverse.each_with_index do |fragment,i|
168
+ if fragment < 9
169
+ pieces[-(i+1)] = fragment +1
170
+ break
171
+ else
172
+ pieces[-(i+1)] = 0
173
+ end
174
+ end
175
+ replace(target, "'#{pieces.join(".")}'")
176
+ end
177
+ end
178
+ ```
179
+
180
+ !!! note "Note the shortcut scope"
181
+ The shortcut calls `rewrite_file` from `Fast` scope as it use
182
+ `Fast.instance_exec` for shortcuts that yields blocks.
183
+
184
+ Checking the version:
185
+
186
+ ```bash
187
+ $ fast .version 13:58:40
188
+ # lib/fast/version.rb:4
189
+ VERSION = '0.1.2'
190
+ ```
191
+ Bumping the version:
192
+
193
+ ```bash
194
+ $ fast .bump_version 13:58:43
195
+ ```
196
+
197
+ No output because we don't print anything. Checking version again:
198
+
199
+ ```bash
200
+ $ fast .version 13:58:54
201
+ # lib/fast/version.rb:4
202
+ VERSION = '0.1.3'
203
+ ```
204
+
205
+ And now a fancy shortcut to report the other shortcuts :)
206
+
207
+ ```ruby
208
+ Fast.shortcut :shortcuts do
209
+ report(shortcuts.keys)
210
+ end
211
+ ```
212
+
213
+ You can find these examples in the [Fastfile](https://github.com/jonatas/fast/tree/master/Fastfile).
214
+
@@ -338,7 +338,7 @@ You can use `search_file` and pass the path for search for expressions inside
338
338
  files.
339
339
 
340
340
  ```ruby
341
- Fast.search_file('file.rb', expression)
341
+ Fast.search_file(expression, 'file.rb')
342
342
  ```
343
343
 
344
344
  It's simple combination of `Fast.ast_from_file` with `Fast.search`.
@@ -104,11 +104,12 @@ module Fast
104
104
  # end # => variable_renamed = 1
105
105
  # @return [String] with the new source code after apply the replacement
106
106
  # @see Fast::Rewriter
107
- def replace(ast, pattern, &replacement)
107
+ def replace(ast, pattern, source = nil, &replacement)
108
108
  buffer = Parser::Source::Buffer.new('replacement')
109
- buffer.source = ast.loc.expression.source
109
+ buffer.source = source || ast.loc.expression.source
110
110
  to_replace = search(ast, pattern)
111
111
  types = to_replace.grep(Parser::AST::Node).map(&:type).uniq
112
+
112
113
  rewriter = Rewriter.new
113
114
  rewriter.buffer = buffer
114
115
  rewriter.search = pattern
@@ -117,18 +118,26 @@ module Fast
117
118
  rewriter.rewrite(buffer, ast)
118
119
  end
119
120
 
121
+ # Search with pattern directly on file
122
+ # @return [Array<Astrolabe::Node>] that matches the pattern
123
+ def search_file(pattern, file)
124
+ node = ast_from_file(file)
125
+ search node, pattern
126
+ end
127
+
120
128
  # Replaces the source of an {Fast#ast_from_file} with
121
129
  # and the same source if the pattern does not match.
122
130
  def replace_file(file, pattern, &replacement)
123
131
  ast = ast_from_file(file)
124
- replace(ast, pattern, &replacement)
132
+ replace(ast, pattern, IO.read(file), &replacement)
125
133
  end
126
134
 
127
- # Search with pattern directly on file
128
- # @return [Array<Astrolabe::Node>] that matches the pattern
129
- def search_file(pattern, file)
130
- node = ast_from_file(file)
131
- search node, pattern
135
+ # Combines #replace_file output overriding the file if the output is different
136
+ # from the original file content.
137
+ def rewrite_file(file, pattern, &replacement)
138
+ previous_content = IO.read(file)
139
+ content = replace_file(file, pattern, &replacement)
140
+ File.open(file, 'w+') { |f| f.puts content } if content != previous_content
132
141
  end
133
142
 
134
143
  # Capture elements from searches in files. Keep in mind you need to use `$`
@@ -244,8 +253,7 @@ module Fast
244
253
  # ast = Fast.ast("a = 1")
245
254
  # buffer = Parser::Source::Buffer.new('replacement')
246
255
  # buffer.source = ast.loc.expression.source
247
- # rewriter = Rewriter.new
248
- # rewriter.buffer = buffer
256
+ # rewriter = Rewriter.new buffer
249
257
  # rewriter.search ='(lvasgn _ ...)'
250
258
  # rewriter.replacement = -> (node) { replace(node.location.name, 'variable_renamed') }
251
259
  # rewriter.replace_on(:lvasgn)
@@ -6,7 +6,9 @@ require 'coderay'
6
6
  require 'optparse'
7
7
  require 'ostruct'
8
8
 
9
- # Command Line Interface powered by CodeRay
9
+ # Fast is a powerful tool to search through the command line for specific Ruby code.
10
+ # It defines #report and #highlight functions that can be used to pretty print
11
+ # code and results from the search.
10
12
  module Fast
11
13
  module_function
12
14
 
@@ -27,18 +29,19 @@ module Fast
27
29
  # @param result [Astrolabe::Node]
28
30
  # @param show_sexp [Boolean] Show string expression instead of source
29
31
  # @param file [String] Show the file name and result line before content
32
+ # @param headless [Boolean] Skip printing the file name and line before content
30
33
  # @example
31
34
  # Fast.highlight(Fast.search(...))
32
- def report(result, show_sexp: nil, file: nil)
35
+ def report(result, show_sexp: false, file: nil, headless: false)
33
36
  if file
34
37
  line = result.loc.expression.line if result.is_a?(Parser::AST::Node)
35
- puts Fast.highlight("# #{file}:#{line}")
38
+ puts(Fast.highlight("# #{file}:#{line}")) unless headless
36
39
  end
37
40
  puts Fast.highlight(result, show_sexp: show_sexp)
38
41
  end
39
42
 
40
43
  # Command Line Interface for Fast
41
- class Cli
44
+ class Cli # rubocop:disable Metrics/ClassLength
42
45
  attr_reader :pattern, :show_sexp, :pry, :from_code, :similar, :help
43
46
 
44
47
  # rubocop:disable Metrics/MethodLength
@@ -54,6 +57,14 @@ module Fast
54
57
  @show_sexp = true
55
58
  end
56
59
 
60
+ opts.on('--captures', 'Print only captures of the patterns and skip node results') do
61
+ @captures = true
62
+ end
63
+
64
+ opts.on('--headless', 'Print results without the file name in the header') do
65
+ @headless = true
66
+ end
67
+
57
68
  opts.on('--pry', 'Jump into a pry session with results') do
58
69
  @pry = true
59
70
  end
@@ -80,23 +91,34 @@ module Fast
80
91
  opts.on_tail('-h', '--help', 'Show help. More at https://jonatas.github.io/fast') do
81
92
  @help = true
82
93
  end
94
+ end
83
95
 
84
- @pattern, *@files = args.reject { |arg| arg.start_with? '-' }
96
+ if args.first&.start_with?('.') # shortcut! :tada:
97
+ shortcut = find_shortcut args.first[1..-1]
98
+ if shortcut.single_run_with_block?
99
+ shortcut.run
100
+ exit
101
+ else
102
+ args = args.one? ? shortcut.args : shortcut.merge_args(args[1..-1])
103
+ end
85
104
  end
105
+
106
+ @pattern, *@files = args.reject { |arg| arg.start_with? '-' }
107
+
86
108
  @opt.parse! args
87
109
 
88
- @files = [*@files]
89
- @files.reject! { |arg| arg.start_with?('-') }
110
+ @files = [*@files].reject { |arg| arg.start_with?('-') }
90
111
  end
91
-
92
112
  # rubocop:enable Metrics/MethodLength
93
113
  # rubocop:enable Metrics/AbcSize
94
114
 
115
+ # Run a new command line interface digesting the arguments
95
116
  def self.run!(argv)
96
117
  argv = argv.dup
97
118
  new(argv).run!
98
119
  end
99
120
 
121
+ # Show help or search for node patterns
100
122
  def run!
101
123
  if @help || @files.empty? && @pattern.nil?
102
124
  puts @opt.help
@@ -105,16 +127,21 @@ module Fast
105
127
  end
106
128
  end
107
129
 
130
+ # Create fast expression from node pattern using the command line
108
131
  def expression
109
132
  Fast.expression(@pattern)
110
133
  end
111
134
 
135
+ # Search for each file independent.
136
+ # If -d (debug option) is enabled, it will output details of each search.
137
+ # If capture option is enabled it will only print the captures, otherwise it
138
+ # prints all the results.
112
139
  def search_file(file)
113
140
  if debug_mode?
114
141
  Fast.debug { Fast.search_file(expression, file) }
115
142
  else
116
143
  begin
117
- Fast.search_file(expression, file)
144
+ Fast.public_send(@captures ? :capture_file : :search_file, expression, file)
118
145
  rescue StandardError
119
146
  debug "Ops! An error occurred trying to search in #{expression.inspect} in #{file}", $ERROR_INFO, $ERROR_POSITION
120
147
  []
@@ -122,10 +149,14 @@ module Fast
122
149
  end
123
150
  end
124
151
 
152
+ # Search for the {#expression} on all the {#files}.
153
+ # It {#report} results if no options are passed.
154
+ # It binds pry if option "--pry" is passed.
125
155
  def search
126
156
  files.each do |file|
127
- results = search_file(file)
128
- next if results.nil? || results.empty?
157
+ results = [*search_file(file)]
158
+
159
+ next if results.empty?
129
160
 
130
161
  results.each do |result|
131
162
  if @pry
@@ -138,20 +169,46 @@ module Fast
138
169
  end
139
170
  end
140
171
 
172
+ # @return [Array<String>] with files from command line expression.
173
+ # @see Fast.ruby_files_from
141
174
  def files
142
175
  Fast.ruby_files_from(*@files)
143
176
  end
144
177
 
178
+ # @return [Boolean] true when "-d" or "--debug" option is passed
145
179
  def debug_mode?
146
180
  @debug == true
147
181
  end
148
182
 
183
+ # Output information if #debug_mode? is true.
149
184
  def debug(*info)
150
185
  puts(info) if debug_mode?
151
186
  end
152
187
 
188
+ # Report results using the actual options binded from command line.
189
+ # @see Fast.report
153
190
  def report(result, file)
154
- Fast.report(result, file: file, show_sexp: @show_sexp)
191
+ Fast.report(result, file: file, show_sexp: @show_sexp, headless: @headless)
192
+ end
193
+
194
+ # Find shortcut by name. Preloads all `Fastfiles` before start.
195
+ # @param name [String]
196
+ # @return [Fast::Shortcut]
197
+ def find_shortcut(name)
198
+ require 'fast/shortcut'
199
+ Fast.load_fast_files!
200
+
201
+ shortcut = Fast.shortcuts[name] || Fast.shortcuts[name.to_sym]
202
+
203
+ shortcut || exit_shortcut_not_found(name)
204
+ end
205
+
206
+ # Exit process with warning message bolding the shortcut that was not found.
207
+ # Prints available shortcuts as extra help and exit with code 1.
208
+ def exit_shortcut_not_found(name)
209
+ puts "Shortcut \033[1m#{name}\033[0m not found :("
210
+ puts "Available shortcuts are: #{Fast.shortcuts.keys.join(', ')}." if Fast.shortcuts.any?
211
+ exit 1
155
212
  end
156
213
  end
157
214
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Allow user to define shortcuts and reuse them in the command line.
4
+ module Fast
5
+ class << self
6
+ # Where to search for `Fastfile` archives?
7
+ # 1. Current directory that the command is being runned
8
+ # 2. Home folder
9
+ # 3. Using the `FAST_FILE_DIR` variable to set an extra folder
10
+ LOOKUP_FAST_FILES_DIRECTORIES = [Dir.pwd, ENV['HOME'], ENV['FAST_FILE_DIR']].freeze
11
+
12
+ # Store predefined searches with default paths through shortcuts.
13
+ # define your Fastfile in you root folder or
14
+ # @example Shortcut for finding validations in rails models
15
+ # Fast.shortcut(:validations, "(send nil {validate validates})", "app/models")
16
+ def shortcut(identifier, *args, &block)
17
+ puts "identifier #{identifier.inspect} will be override" if shortcuts.key?(identifier)
18
+ shortcuts[identifier] = Shortcut.new(*args, &block)
19
+ end
20
+
21
+ # Stores shortcuts in a simple hash where the key is the identifier
22
+ # and the value is the object itself.
23
+ # @return [Hash<String,Shortcut>] as a dictionary.
24
+ def shortcuts
25
+ @shortcuts ||= {}
26
+ end
27
+
28
+ # @return [Array<String>] with existent Fastfiles from {LOOKUP_FAST_FILES_DIRECTORIES}.
29
+ def fast_files
30
+ @fast_files ||= LOOKUP_FAST_FILES_DIRECTORIES.compact
31
+ .map { |dir| File.join(dir, 'Fastfile') }
32
+ .select(&File.method(:exists?))
33
+ end
34
+
35
+ # Loads `Fastfiles` from {.fast_files} list
36
+ def load_fast_files!
37
+ fast_files.each(&method(:load))
38
+ end
39
+ end
40
+
41
+ # Wraps shortcuts for repeated command line actions or build custom scripts
42
+ # with shorcut blocks
43
+ # This is an utility that can be used preloading several shortcuts
44
+ # The shortcut structure will be consumed by [Fast::Cli] and feed with the
45
+ # command line arguments in realtime.
46
+ class Shortcut
47
+ attr_reader :args
48
+ def initialize(*args, &block)
49
+ @args = args if args.any?
50
+ @block = block
51
+ end
52
+
53
+ def single_run_with_block?
54
+ @block && @args.nil?
55
+ end
56
+
57
+ def options
58
+ @args.select { |arg| arg.start_with? '-' }
59
+ end
60
+
61
+ def params
62
+ @args - options
63
+ end
64
+
65
+ # Merge extra arguments from input returning a new arguments array keeping
66
+ # the options from previous alias and replacing the files with the
67
+ # @param [Array] extra_args
68
+ def merge_args(extra_args)
69
+ [params[0], *options, *extra_args]
70
+ end
71
+
72
+ # If the shortcut was defined with a single block and no extra arguments, it
73
+ # only runs the block and return the result of the yielded block.
74
+ # The block is also executed in the [Fast] module level. Making it easy to
75
+ # implement smalls scripts using several Fast methods.
76
+ # Use ARGV to catch regular arguments from command line if the block is
77
+ # given.
78
+ #
79
+ # @return [Hash<String, Array<Astrolabe::Node>] with file => search results.
80
+ def run
81
+ Fast.instance_exec(&@block) if single_run_with_block?
82
+ end
83
+ end
84
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fast
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.3'
5
5
  end
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.2
4
+ version: 0.1.3
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-07-10 00:00:00.000000000 Z
11
+ date: 2019-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: astrolabe
@@ -230,10 +230,12 @@ extensions: []
230
230
  extra_rdoc_files: []
231
231
  files:
232
232
  - ".gitignore"
233
+ - ".projections.json"
233
234
  - ".rspec"
234
235
  - ".rubocop.yml"
235
236
  - ".travis.yml"
236
237
  - CODE_OF_CONDUCT.md
238
+ - Fastfile
237
239
  - Gemfile
238
240
  - Guardfile
239
241
  - LICENSE.txt
@@ -264,6 +266,7 @@ files:
264
266
  - lib/fast.rb
265
267
  - lib/fast/cli.rb
266
268
  - lib/fast/experiment.rb
269
+ - lib/fast/shortcut.rb
267
270
  - lib/fast/version.rb
268
271
  - mkdocs.yml
269
272
  homepage: https://jonatas.github.io/fast/