cql_ruby 0.0.4 → 0.0.5
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/bin/cql_ruby +26 -6
- data/lib/cql_ruby.rb +5 -1
- data/lib/cql_ruby/executor.rb +74 -27
- data/lib/cql_ruby/pattern_matcher.rb +4 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50e03910538e8b57539419210406155ba4a9d0aed14f0852edfd1867e6fbccbe
|
4
|
+
data.tar.gz: acb0f56f0faefb1f39613f2805b25cbee66e61d0a715138007c021036e05e03a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71feb8dab0a500e27989d7a96117b2f558b09f1eade1db44503a69ee3cadf6f21bec65d7e921ae219a39835ded528fc62cf91216989a9121006343636098b81b
|
7
|
+
data.tar.gz: e3fdf1a7ecdc01fb7f5f3174d932a60e4718d2c08534414ec0627666590df1d29985cc113763423a3eb913a0d7994b789d1ad7c8baed645e04fe2b8104ecdb98
|
data/bin/cql_ruby
CHANGED
@@ -6,13 +6,14 @@ def show_help
|
|
6
6
|
puts <<~HELP
|
7
7
|
|
8
8
|
\tSYNOPSIS
|
9
|
-
\tcql_ruby options pattern path filters ...
|
9
|
+
\t\tcql_ruby options pattern path filters ...
|
10
10
|
|
11
11
|
\tDESCRIPTION
|
12
|
-
\tCQL (Code Query Language) is a semantic search tool for your Ruby source code.
|
12
|
+
\t\tCQL (Code Query Language) is a semantic search tool for your Ruby source code.
|
13
13
|
|
14
14
|
\tFILTERS
|
15
|
-
\t\tParent node type: type:T(,T)*
|
15
|
+
\t\tParent node type: type:T(,T)* Example: type:def,send,arg
|
16
|
+
\t\tNesting under: nest:T(=NAME) Example: nest:def=save_user nest:class=UserManager
|
16
17
|
|
17
18
|
\tOPTIONS
|
18
19
|
\t\t-nc (--no-color) No color on output.
|
@@ -20,7 +21,7 @@ def show_help
|
|
20
21
|
\t\t-ns (--no-source) No source code.
|
21
22
|
|
22
23
|
\tEXAMPLES
|
23
|
-
\tcql_ruby -ns update_user_info ./ type:send,arg
|
24
|
+
\t\tcql_ruby -ns update_user_info ./ type:send,arg
|
24
25
|
HELP
|
25
26
|
|
26
27
|
exit
|
@@ -32,6 +33,7 @@ def extract_options
|
|
32
33
|
show_color: true,
|
33
34
|
show_file: true,
|
34
35
|
show_source: true,
|
36
|
+
recursive_search: true,
|
35
37
|
}
|
36
38
|
|
37
39
|
ARGV.delete_if do |arg|
|
@@ -42,8 +44,13 @@ def extract_options
|
|
42
44
|
options[:show_file] = false
|
43
45
|
elsif %w[-ns --no-source].include?(arg)
|
44
46
|
options[:show_source] = false
|
45
|
-
elsif %w[-h --help]
|
47
|
+
elsif %w[-h --help].include?(arg)
|
46
48
|
show_help
|
49
|
+
elsif %w[-v -vv -vvv].include?(arg)
|
50
|
+
lvl = arg.chars.find_all { |c| c == 'v' }.size
|
51
|
+
CqlRuby::Config.debug_level = lvl
|
52
|
+
elsif %w[-nr --no-recursive].include?(arg)
|
53
|
+
options[:recursive_search] = false
|
47
54
|
else
|
48
55
|
raise "Unknown arg #{arg}"
|
49
56
|
end
|
@@ -64,15 +71,21 @@ end
|
|
64
71
|
|
65
72
|
begin
|
66
73
|
options = extract_options
|
74
|
+
CqlRuby.log "Call options: #{options}" if CqlRuby::Config.debug_level_2?
|
67
75
|
|
68
76
|
raise unless ARGV.size >= 2
|
69
77
|
|
70
78
|
pattern = ARGV.shift
|
79
|
+
CqlRuby.log "Call pattern: <#{pattern}>" if CqlRuby::Config.debug_level_2?
|
80
|
+
|
71
81
|
# TODO Make path patterns universal.
|
72
82
|
path = ARGV.shift
|
83
|
+
CqlRuby.log "Call path: <#{path}>" if CqlRuby::Config.debug_level_2?
|
73
84
|
|
74
85
|
# Rest must be filters - can sink ARGV now.
|
75
86
|
filters = extract_filters
|
87
|
+
CqlRuby.log "Call filters: #{filters}" if CqlRuby::Config.debug_level_2?
|
88
|
+
|
76
89
|
filter_reader = CqlRuby::FilterReader.new(filters)
|
77
90
|
|
78
91
|
printer = CqlRuby::ConsolePrinter.new
|
@@ -81,7 +94,14 @@ begin
|
|
81
94
|
printer.source_on = options[:show_source]
|
82
95
|
|
83
96
|
collector = CqlRuby::CrumbCollector.new(printer)
|
84
|
-
CqlRuby::Executor.new(
|
97
|
+
CqlRuby::Executor.new(
|
98
|
+
collector: collector,
|
99
|
+
filter_reader: filter_reader,
|
100
|
+
pattern: pattern,
|
101
|
+
path: path,
|
102
|
+
filters: filters,
|
103
|
+
recursive: options[:recursive_search],
|
104
|
+
).search_all
|
85
105
|
rescue => e
|
86
106
|
puts "Error: #{e}"
|
87
107
|
show_help
|
data/lib/cql_ruby.rb
CHANGED
data/lib/cql_ruby/executor.rb
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'parser/current'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
module CqlRuby
|
7
|
+
class Config
|
8
|
+
@@debug_level = 0
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def debug_level=(lvl); @@debug_level = lvl; end
|
12
|
+
def debug_level; @@debug_level; end
|
13
|
+
def debug_level_1?; @@debug_level >= 1; end
|
14
|
+
def debug_level_2?; @@debug_level >= 2; end
|
15
|
+
def debug_level_3?; @@debug_level >= 3; end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
4
19
|
|
5
20
|
#
|
6
21
|
# Executes search and dumps results into the collector.
|
@@ -10,43 +25,75 @@ require 'parser/current'
|
|
10
25
|
# @param path [String]
|
11
26
|
# @param filters [Array<String>]
|
12
27
|
#
|
13
|
-
CqlRuby
|
14
|
-
|
15
|
-
|
16
|
-
|
28
|
+
module CqlRuby
|
29
|
+
class Executor
|
30
|
+
def initialize(
|
31
|
+
collector:,
|
32
|
+
filter_reader:,
|
33
|
+
pattern:,
|
34
|
+
path:,
|
35
|
+
filters: [],
|
36
|
+
recursive: true
|
37
|
+
)
|
38
|
+
@collector = collector
|
39
|
+
@filter_reader = filter_reader
|
40
|
+
@pattern = pattern
|
41
|
+
@path = path
|
42
|
+
@filters = filters
|
43
|
+
@recursive = recursive
|
17
44
|
end
|
18
|
-
end
|
19
45
|
|
20
|
-
|
46
|
+
def search_all
|
47
|
+
files.flat_map do |file|
|
48
|
+
CqlRuby.log "File check: #{file}" if CqlRuby::Config.debug_level_3?
|
49
|
+
search(file)
|
50
|
+
end
|
51
|
+
end
|
21
52
|
|
22
|
-
|
23
|
-
ast = Parser::CurrentRuby.parse(File.read(file))
|
24
|
-
source_reader = CqlRuby::SourceReader.new(file)
|
25
|
-
walk(ast, [], source_reader)
|
53
|
+
private
|
26
54
|
|
27
|
-
|
28
|
-
|
55
|
+
def search(file)
|
56
|
+
ast = Parser::CurrentRuby.parse(File.read(file))
|
57
|
+
source_reader = CqlRuby::SourceReader.new(file)
|
58
|
+
walk(ast, [], source_reader)
|
29
59
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def walk(node, ancestors, source_reader)
|
64
|
+
if node.is_a?(Parser::AST::Node)
|
65
|
+
node.children.flat_map do |child|
|
66
|
+
walk(child, ancestors.dup + [node], source_reader)
|
67
|
+
end
|
68
|
+
else
|
69
|
+
if match?(node) && CqlRuby::FilterEvaluator.pass?(filter_reader, node, ancestors)
|
70
|
+
collector.add(CqlRuby::Crumb.new(node, ancestors, source_reader))
|
71
|
+
end
|
38
72
|
end
|
73
|
+
|
74
|
+
nil
|
39
75
|
end
|
40
76
|
|
41
|
-
|
42
|
-
|
77
|
+
def match?(target)
|
78
|
+
CqlRuby::PatternMatcher.match?(pattern, target)
|
79
|
+
end
|
43
80
|
|
44
|
-
|
45
|
-
|
46
|
-
|
81
|
+
def files
|
82
|
+
return [path] if File.file?(path)
|
83
|
+
|
84
|
+
clean_path = Pathname(path).cleanpath.to_s
|
85
|
+
clean_path += '/**' if recursive
|
86
|
+
clean_path += '/*.rb'
|
87
|
+
|
88
|
+
Dir.glob(clean_path)
|
89
|
+
end
|
47
90
|
|
48
|
-
|
49
|
-
|
91
|
+
attr_reader :collector
|
92
|
+
attr_reader :filter_reader
|
93
|
+
attr_reader :pattern
|
94
|
+
attr_reader :path
|
95
|
+
attr_reader :filters
|
96
|
+
attr_reader :recursive
|
50
97
|
end
|
51
98
|
end
|
52
99
|
|
@@ -15,7 +15,7 @@ module CqlRuby
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.regex?(pattern)
|
18
|
-
pattern[0..1] == 'r
|
18
|
+
pattern[0..1] == 'r/'
|
19
19
|
end
|
20
20
|
private_class_method :regex?
|
21
21
|
|
@@ -26,7 +26,9 @@ module CqlRuby
|
|
26
26
|
|
27
27
|
def self.regex_match?(pattern, subject)
|
28
28
|
pattern = pattern[2..]
|
29
|
-
|
29
|
+
delim_idx = pattern.rindex('/')
|
30
|
+
mods = pattern[delim_idx + 1..].chars
|
31
|
+
pattern = pattern[0..delim_idx - 1]
|
30
32
|
|
31
33
|
fops = 0
|
32
34
|
fops |= Regexp::IGNORECASE if mods.include?('i')
|