ffast 0.1.8 → 0.1.9

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: d07f3e9f3161db325a672703937f6c25aeacf21f76e835fd1547d34437a62a13
4
- data.tar.gz: 1faf3b9d8e3bbbc6ee9b859fc5ae5779bca6750b7e510667502359db779d0e46
3
+ metadata.gz: 18d062e72ef849cb0b6533af8c6dc37a6612036faead3c53e1d0427a001e8f24
4
+ data.tar.gz: 55b4dfdd79ee4b789fa7652760fb3516a49f68b7503d827042b78c5101fecee6
5
5
  SHA512:
6
- metadata.gz: 2945758fe9f1a818ec8154acb3585959c2b76c557d92ddcc14fc396b13394da8607924db5e3a84d579826e77951d5a41c8c003a2a055e653e1897475fa146ed0
7
- data.tar.gz: 6637f8426a03b2ff25b4975a0887f6d11428155764029e94956d875d85625b7ee15d17eb5c5c30876c7e70cdd3f027e1228946084a18abd362935acf62352766
6
+ metadata.gz: 813ca8cbe0bad2ce3f6dce1477820b68c00ac06021a3fd4263df9ea5634a6510ae0cac6cd178ffc8342b31bf7e956522a482d809dbcbe3500a488b6bc609a78a
7
+ data.tar.gz: 7fb04918062ca0f972622fe69e8d6bb77631b1e7df9ba9aa5b1e37385c0cdbcd802324d6e46801a89e53d4f30b7fe92edf51ad3eba0252cf6fce5183c76f60de
@@ -0,0 +1,80 @@
1
+ # Ideas I want to build with Fast
2
+
3
+ I don't have all the time I need to develop all the ideas I have to build
4
+ around this tool, so here is a dump of a few brainstormings:
5
+
6
+ ## Inline target code
7
+
8
+ I started [fast-inline](https://github.com/jonatas/fast-inline) that can be
9
+ useful to try to see how much every library is used in a project.
10
+
11
+ My idea is try to inline some specific method call to understand if it makes
12
+ sense to have an entire library in the stock.
13
+
14
+ Understanding dependencies and how the code works can be a first step to get an
15
+ "algorithm as a service". Instead of loading everything from the library, it
16
+ would facilitate the cherry pick of only the proper dependencies necessaries to
17
+ run the code you have and not the code that is overloading the project.
18
+
19
+ ## Neo4J adapter
20
+
21
+ Easy pipe fast results to Neo4J. It would facilitate to explore more complex
22
+ scenarios and combine data from other sources.
23
+
24
+ ## Git adapter
25
+
26
+ Add extra tags to nodes with information from Git.
27
+
28
+ * Revision
29
+ * Author
30
+ * Date
31
+
32
+ Tag every node with the proper author.
33
+
34
+ ## Ast Diff
35
+
36
+ Allow to compare and return a summary of differences between two trees.
37
+
38
+ It would be useful to identify renamings or other small changes, like only
39
+ changes in comments that does not affect the file and possibly be ignored for
40
+ some operations like run or not run tests.
41
+
42
+ ## Transition synapses
43
+
44
+ Following the previous idea, it would be great if we can understand the
45
+ transition synapses and make it easily available to catch up with previous
46
+ learnings.
47
+
48
+ https://github.com/jonatas/chewy-diff/blob/master/lib/chewy/diff.rb
49
+
50
+ This example, shows adds and removals from specific node targets between two
51
+ different files.
52
+
53
+ If we start tracking AST transition synapses and associating with "Fixes" or
54
+ "Reverts" we can predict introduction of new bugs by inpecting if the
55
+ introduction of new patterns that can be possibly reverted or improved.
56
+
57
+ ## Fast Rewriter with pure strings
58
+
59
+ As the AST rewriter adopts a custom block that needs to implement ruby code,
60
+ we can expand the a query language for rewriting files without need to take the
61
+ custom Ruby block.
62
+
63
+ Example:
64
+
65
+ ```ruby
66
+ Fast.gsub_expression('remove(@expression)') # (node) => { remove(node.location.expression) }
67
+ ```
68
+
69
+ And later we can bind it in the command line to allow implement custom
70
+ replacements without need to write a ruby file.
71
+
72
+ ```
73
+ fast (def my_target_method) lib spec --rewrite "remove(@expression)"
74
+ ```
75
+
76
+ or
77
+
78
+ ```
79
+ fast (def my_target_method) lib spec --rewrite "replace(@name, 'renamed_method')"
80
+ ```
@@ -0,0 +1,93 @@
1
+
2
+ # Research
3
+
4
+ I love to research about codebase as data and prototyping ideas several times
5
+ doesn't fit in simple [shortcuts](/shortcuts).
6
+
7
+ Here is my first research that worth sharing:
8
+
9
+ ## Combining Runtime metadata with AST complex searches
10
+
11
+ This example covers how to find RSpec `allow` combined with `and_return` missing
12
+ the `with` clause specifying the nested parameters.
13
+
14
+ Here is the [gist](https://gist.github.com/jonatas/c1e580dcb74e20d4f2df4632ceb084ef)
15
+ if you want to go straight and run it.
16
+
17
+ Scenario for simple example:
18
+
19
+ Given I have the following class:
20
+
21
+ ```ruby
22
+ class Account
23
+ def withdraw(value)
24
+ if @total >= value
25
+ @total -= value
26
+ :ok
27
+ else
28
+ :not_allowed
29
+ end
30
+ end
31
+ end
32
+ ```
33
+
34
+ And I'm testing it with `allow` and some possibilities:
35
+
36
+ ```ruby
37
+ # bad
38
+ allow(Account).to receive(:withdraw).and_return(:ok)
39
+ # good
40
+ allow(Account).to receive(:withdraw).with(100).and_return(:ok)
41
+ ```
42
+
43
+ **Objective:** find all bad cases of **any** class that does not respect the method
44
+ parameters signature.
45
+
46
+ First, let's understand the method signature of a method:
47
+
48
+ ```ruby
49
+ Account.instance_method(:withdraw).parameters
50
+ # => [[:req, :value]]
51
+ ```
52
+
53
+ Now, we can build a small script to use the node pattern to match the proper
54
+ specs that are using such pattern and later visit their method signatures.
55
+
56
+
57
+ ```ruby
58
+ Fast.class_eval do
59
+ # Captures class and method name when find syntax like:
60
+ # `allow(...).to receive(...)` that does not end with `.with(...)`
61
+ pattern_with_captures = <<~FAST
62
+ (send (send nil allow (const nil $_)) to
63
+ (send (send nil receive (sym $_)) !with))
64
+ FAST
65
+
66
+ pattern = expression(pattern_with_captures.tr('$',''))
67
+
68
+ ruby_files_from('spec').each do |file|
69
+ results = search_file(pattern, file) || [] rescue next
70
+ results.each do |n|
71
+ clazz, method = capture(n, pattern_with_captures)
72
+ if klazz = Object.const_get(clazz.to_s) rescue nil
73
+ if klazz.respond_to?(method)
74
+ params = klazz.method(method).parameters
75
+ if params.any?{|e|e.first == :req}
76
+ code = n.loc.expression
77
+ range = [code.first_line, code.last_line].uniq.join(",")
78
+ boom_message = "BOOM! #{clazz}.#{method} does not include the REQUIRED parameters!"
79
+ puts boom_message, "#{file}:#{range}", code.source
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ ```
87
+
88
+ !!! hint "Preload your environment **before** run the script"
89
+
90
+ Keep in mind that you should run it with your environment preloaded otherwise it
91
+ will skip the classes.
92
+ You can add elses for `const_get` and `respond_to` and report weird cases if
93
+ your environment is not preloading properly.
@@ -11,6 +11,70 @@ first param is not a shortcut. It should start with `.`.
11
11
  I'm building several researches and I'll make the examples open here to show
12
12
  several interesting cases in action.
13
13
 
14
+ ## List your fast shortcuts
15
+
16
+ As the interface is very rudimentar, let's build a shortcut to print what
17
+ shortcuts are available. This is a good one to your `$HOME/Fastfile`:
18
+
19
+ ```ruby
20
+ # List all shortcut with comments
21
+ Fast.shortcut :shortcuts do
22
+ fast_files.each do |file|
23
+ lines = File.readlines(file).map{|line|line.chomp.gsub(/\s*#/,'').strip}
24
+ result = capture_file('(send ... shortcut $(sym _', file)
25
+ result = [result] unless result.is_a?Array
26
+ result.each do |capture|
27
+ target = capture.loc.expression
28
+ puts "fast .#{target.source[1..-1].ljust(30)} # #{lines[target.line-2]}"
29
+ end
30
+ end
31
+ end
32
+ ```
33
+
34
+ And using it on `fast` project that loads both `~/Fastfile` and the Fastfile from the project:
35
+
36
+ ```
37
+ fast .version # Let's say you'd like to show the version that is over the version file
38
+ fast .parser # Simple shortcut that I used often to show how the expression parser works
39
+ fast .bump_version # Use `fast .bump_version` to rewrite the version file
40
+ fast .shortcuts # List all shortcut with comments
41
+ ```
42
+
43
+ ## Search for references
44
+
45
+ I always miss bringing something simple as `grep keyword` where I can leave a simple string and it can
46
+ search in all types of nodes and report interesting things about it.
47
+
48
+ Let's consider a very flexible search that can target any code related to some
49
+ keyword. Considering that we're talking about code indentifiers:
50
+
51
+
52
+ ```ruby
53
+ # Search all references about some keyword or regular expression
54
+ Fast.shortcut(:ref) do
55
+ require 'fast/cli'
56
+ Kernel.class_eval do
57
+ def matches_args? identifier
58
+ search = ARGV.last
59
+ regex = Regexp.new(search, Regexp::IGNORECASE)
60
+ case identifier
61
+ when Symbol, String
62
+ regex.match?(identifier) || identifier.to_s.include?(search)
63
+ when Astrolabe::Node
64
+ regex.match?(identifier.to_sexp)
65
+ end
66
+ end
67
+ end
68
+ pattern = <<~FAST
69
+ {
70
+ ({class def sym str} #matches_args?)'
71
+ ({const send} nil #matches_args?)'
72
+ }
73
+ FAST
74
+ Fast::Cli.run!([pattern, '.', '--parallel'])
75
+ end
76
+ ```
77
+
14
78
  ## Rails: Show validations from models
15
79
 
16
80
  If the shortcut does not define a block, it works as a holder for arguments from
@@ -73,35 +137,6 @@ module Fast
73
137
  end
74
138
  ```
75
139
 
76
- ## List Shortcuts
77
-
78
- As the interface is very rudimentar, let's build a shortcut to print what
79
- shortcuts are available. This is a good one to your `$HOME/Fastfile`:
80
-
81
- ```ruby
82
- # List all shortcut with comments
83
- Fast.shortcut :shortcuts do
84
- fast_files.each do |file|
85
- lines = File.readlines(file).map{|line|line.chomp.gsub(/\s*#/,'').strip}
86
- result = capture_file('(send ... shortcut $(sym _', file)
87
- result = [result] unless result.is_a?Array
88
- result.each do |capture|
89
- target = capture.loc.expression
90
- puts "fast .#{target.source[1..-1].ljust(30)} # #{lines[target.line-2]}"
91
- end
92
- end
93
- end
94
- ```
95
-
96
- And using it on `fast` project that loads both `~/Fastfile` and the Fastfile from the project:
97
-
98
- ```
99
- fast .version # Let's say you'd like to show the version that is over the version file
100
- fast .parser # Simple shortcut that I used often to show how the expression parser works
101
- fast .bump_version # Use `fast .bump_version` to rewrite the version file
102
- fast .shortcuts # List all shortcut with comments
103
- ```
104
-
105
140
  ## RSpec: Find unused shared contexts
106
141
 
107
142
  If you build shared contexts often, probably you can forget some left overs.
@@ -28,12 +28,12 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency 'coderay'
29
29
  spec.add_dependency 'parallel'
30
30
  spec.add_dependency 'parser'
31
- spec.add_dependency 'pry'
32
31
 
33
32
  spec.add_development_dependency 'bundler'
34
33
  spec.add_development_dependency 'guard'
35
34
  spec.add_development_dependency 'guard-livereload'
36
35
  spec.add_development_dependency 'guard-rspec'
36
+ spec.add_development_dependency 'pry'
37
37
  spec.add_development_dependency 'rake'
38
38
  spec.add_development_dependency 'rspec', '~> 3.0'
39
39
  spec.add_development_dependency 'rspec-its', '~> 1.2'
@@ -226,14 +226,15 @@ module Fast
226
226
  # @param files can be file paths or directories.
227
227
  # When the argument is a folder, it recursively fetches all `.rb` files from it.
228
228
  def ruby_files_from(*files)
229
- directories = files.select(&File.method(:directory?))
229
+ dir_filter = File.method(:directory?)
230
+ directories = files.select(&dir_filter)
230
231
 
231
232
  if directories.any?
232
233
  files -= directories
233
234
  files |= directories.flat_map { |dir| Dir["#{dir}/**/*.rb"] }
234
235
  files.uniq!
235
236
  end
236
- files
237
+ files.reject(&dir_filter)
237
238
  end
238
239
 
239
240
  # Extracts a node pattern expression from a given node supressing identifiers and primitive types.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fast
4
- VERSION = '0.1.8'
4
+ VERSION = '0.1.9'
5
5
  end
data/mkdocs.yml CHANGED
@@ -22,4 +22,6 @@ nav:
22
22
  - Code Similarity: similarity_tutorial.md
23
23
  - Pry Integration: pry-integration.md
24
24
  - Editors' Integration: editors-integration.md
25
+ - Research: research.md
26
+ - Ideas: ideas.md
25
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.8
4
+ version: 0.1.9
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: 2020-02-29 00:00:00.000000000 Z
11
+ date: 2020-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: astrolabe
@@ -67,13 +67,13 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: pry
70
+ name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- type: :runtime
76
+ type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: bundler
84
+ name: guard
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: guard
98
+ name: guard-livereload
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: guard-livereload
112
+ name: guard-rspec
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -123,7 +123,7 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: guard-rspec
126
+ name: pry
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -243,7 +243,6 @@ executables:
243
243
  extensions: []
244
244
  extra_rdoc_files: []
245
245
  files:
246
- - ".github/FUNDING.yml"
247
246
  - ".gitignore"
248
247
  - ".projections.json"
249
248
  - ".rspec"
@@ -264,8 +263,10 @@ files:
264
263
  - docs/command_line.md
265
264
  - docs/editors-integration.md
266
265
  - docs/experiments.md
266
+ - docs/ideas.md
267
267
  - docs/index.md
268
268
  - docs/pry-integration.md
269
+ - docs/research.md
269
270
  - docs/shortcuts.md
270
271
  - docs/similarity_tutorial.md
271
272
  - docs/syntax.md
@@ -1,3 +0,0 @@
1
- # These are supported funding model platforms
2
-
3
- github: [jonatas]