cql_ruby 0.0.7 → 0.0.12
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 +139 -116
- data/lib/cql_ruby.rb +15 -15
- data/lib/cql_ruby/abstract_printer.rb +12 -12
- data/lib/cql_ruby/console_printer.rb +97 -97
- data/lib/cql_ruby/crumb_collector.rb +18 -18
- data/lib/cql_ruby/executor.rb +194 -148
- data/lib/cql_ruby/filter_evaluator.rb +178 -54
- data/lib/cql_ruby/filter_reader.rb +130 -81
- data/lib/cql_ruby/pattern_matcher.rb +57 -53
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbbc47dff29d232d492edfe95e28eab6a4bd9710ace6332ae7e14c9487830a4a
|
4
|
+
data.tar.gz: 39401f85b2ed054755aa5c8497a3822d3c1b2458119d151264029cdd97b4a3ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e94c7852a7fffe0d0d3d7221caf42c20be76392188c46faf58e44aff12dea386b6202368ae911ddf7abaf894835138e99103f6f78383c9c02462845e19b6fcb0
|
7
|
+
data.tar.gz: 93815de02dffcb1f1b61b1574ef03a610b2e758479048c25a58b22f50d0dd5d6d3dba69316eb10f1339160da91876a9b198a5e2337adbba1d9750035f59cd4d3
|
data/bin/cql_ruby
CHANGED
@@ -1,116 +1,139 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
\
|
10
|
-
|
11
|
-
\
|
12
|
-
|
13
|
-
|
14
|
-
\
|
15
|
-
|
16
|
-
\
|
17
|
-
|
18
|
-
\
|
19
|
-
\t\
|
20
|
-
\t\
|
21
|
-
|
22
|
-
\
|
23
|
-
\t\t
|
24
|
-
\t\t
|
25
|
-
|
26
|
-
\
|
27
|
-
\t\
|
28
|
-
\t\
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
options[:
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'parser'
|
4
|
+
require 'cql_ruby'
|
5
|
+
|
6
|
+
def show_help
|
7
|
+
puts <<~HELP
|
8
|
+
|
9
|
+
\tSYNOPSIS
|
10
|
+
\t\tcql_ruby [--token] pattern path options filters ...
|
11
|
+
\t\tcql_ruby --node type path options filters ...
|
12
|
+
|
13
|
+
\tDESCRIPTION
|
14
|
+
\t\tCQL (Code Query Language) is a semantic search tool for your Ruby source code.
|
15
|
+
|
16
|
+
\tFILTERS
|
17
|
+
\t\tParent node type: type:T(,T)* Example: type:def,send,arg
|
18
|
+
\t\tNesting under: nest:T(=NAME) Example: nest:def=save_user nest:class=UserManager
|
19
|
+
\t\tHas child: has:T(=NAME) Example: has:const has:def=valid?
|
20
|
+
\t\tPattern: pattern:(T-)*X(-T)* Example: pattern:class-def-X-block
|
21
|
+
|
22
|
+
\tOPTIONS
|
23
|
+
\t\t--include=PATTERN Parses only files whose name matches the pattern.
|
24
|
+
\t\t--exclude=PATTERN Parses only files whose name does not match the pattern.
|
25
|
+
\t\t-lN (N is integer) Add N surrounding line before and after.
|
26
|
+
\t\t-nc (--no-color) No color on output.
|
27
|
+
\t\t-nf (--no-file) No file names.
|
28
|
+
\t\t-ns (--no-source) No source code.
|
29
|
+
\t\t-nr (--no-recursion) Non-recursive search.
|
30
|
+
\t\t-v -vv -vvv Debug output levels.
|
31
|
+
|
32
|
+
\tALLOWED NODE TYPES
|
33
|
+
\t\tWhen defining filters only valid AST types can be defined. They are:
|
34
|
+
#{Parser::Meta::NODE_TYPES.to_a.join(' ')}
|
35
|
+
|
36
|
+
\tEXAMPLES
|
37
|
+
\t\tcql_ruby user ./
|
38
|
+
\t\tcql_ruby -ns -nr %user_info ./ type:send,arg nest:block nest:class=r/User/i has:str=WARNING
|
39
|
+
HELP
|
40
|
+
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Hash{Symbol->Boolean}]
|
45
|
+
def extract_options
|
46
|
+
options = {
|
47
|
+
show_color: true,
|
48
|
+
show_file: true,
|
49
|
+
show_source: true,
|
50
|
+
recursive_search: true,
|
51
|
+
surrounding_lines: 0,
|
52
|
+
include_pattern: nil,
|
53
|
+
exclude_pattern: nil,
|
54
|
+
search_type: :token,
|
55
|
+
}
|
56
|
+
|
57
|
+
ARGV.delete_if do |arg|
|
58
|
+
if arg[0] == '-'
|
59
|
+
if %w[-nc --no-color].include?(arg)
|
60
|
+
options[:show_color] = false
|
61
|
+
elsif %w[-nf --no-file].include?(arg)
|
62
|
+
options[:show_file] = false
|
63
|
+
elsif %w[-ns --no-source].include?(arg)
|
64
|
+
options[:show_source] = false
|
65
|
+
elsif %w[-h --help].include?(arg)
|
66
|
+
show_help
|
67
|
+
elsif %w[-v -vv -vvv].include?(arg)
|
68
|
+
lvl = arg.chars.find_all { |c| c == 'v' }.size
|
69
|
+
CqlRuby::Config.debug_level = lvl
|
70
|
+
elsif %w[-nr --no-recursive].include?(arg)
|
71
|
+
options[:recursive_search] = false
|
72
|
+
elsif arg[0..1] == '-l' && arg[2..].to_i > 0
|
73
|
+
options[:surrounding_lines] = arg[2..].to_i
|
74
|
+
elsif arg.start_with?('--include=')
|
75
|
+
options[:include_pattern] = arg.split('=')[1]
|
76
|
+
elsif arg.start_with?('--exclude=')
|
77
|
+
options[:exclude_pattern] = arg.split('=')[1]
|
78
|
+
elsif arg == '--node'
|
79
|
+
options[:search_type] = :node
|
80
|
+
elsif arg == '--token'
|
81
|
+
options[:search_type] = :token
|
82
|
+
else
|
83
|
+
raise "Unknown arg #{arg}"
|
84
|
+
end
|
85
|
+
|
86
|
+
true
|
87
|
+
else
|
88
|
+
false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
options
|
93
|
+
end
|
94
|
+
|
95
|
+
# @return [Array]
|
96
|
+
def extract_filters
|
97
|
+
ARGV.take(ARGV.size)
|
98
|
+
end
|
99
|
+
|
100
|
+
begin
|
101
|
+
options = extract_options
|
102
|
+
CqlRuby.log "Call options: #{options}" if CqlRuby::Config.debug_level_2?
|
103
|
+
|
104
|
+
raise unless ARGV.size >= 2
|
105
|
+
|
106
|
+
pattern = ARGV.shift
|
107
|
+
CqlRuby.log "Call pattern: <#{pattern}>" if CqlRuby::Config.debug_level_2?
|
108
|
+
|
109
|
+
path = ARGV.shift
|
110
|
+
CqlRuby.log "Call path: <#{path}>" if CqlRuby::Config.debug_level_2?
|
111
|
+
|
112
|
+
# Rest must be filters - can sink ARGV now.
|
113
|
+
filters = extract_filters
|
114
|
+
CqlRuby.log "Call filters: #{filters}" if CqlRuby::Config.debug_level_2?
|
115
|
+
|
116
|
+
filter_reader = CqlRuby::FilterReader.new(filters)
|
117
|
+
|
118
|
+
printer = CqlRuby::ConsolePrinter.new
|
119
|
+
printer.color_on = options[:show_color]
|
120
|
+
printer.file_on = options[:show_file]
|
121
|
+
printer.source_on = options[:show_source]
|
122
|
+
printer.surrounding_lines = options[:surrounding_lines]
|
123
|
+
|
124
|
+
collector = CqlRuby::CrumbCollector.new(printer)
|
125
|
+
CqlRuby::Executor.new(
|
126
|
+
collector: collector,
|
127
|
+
filter_reader: filter_reader,
|
128
|
+
pattern: pattern,
|
129
|
+
path: path,
|
130
|
+
filters: filters,
|
131
|
+
recursive: options[:recursive_search],
|
132
|
+
include: options[:include_pattern],
|
133
|
+
exclude: options[:exclude_pattern],
|
134
|
+
search_type: options[:search_type],
|
135
|
+
).search_all
|
136
|
+
rescue
|
137
|
+
puts "Error: #{$!}"
|
138
|
+
show_help
|
139
|
+
end
|
data/lib/cql_ruby.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CqlRuby;
|
4
|
-
def self.log(txt)
|
5
|
-
p txt
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
require 'cql_ruby/executor'
|
10
|
-
require 'cql_ruby/crumb_collector'
|
11
|
-
require 'cql_ruby/abstract_printer'
|
12
|
-
require 'cql_ruby/console_printer'
|
13
|
-
require 'cql_ruby/filter_reader'
|
14
|
-
require 'cql_ruby/filter_evaluator'
|
15
|
-
require 'cql_ruby/pattern_matcher'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CqlRuby;
|
4
|
+
def self.log(txt)
|
5
|
+
p txt
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'cql_ruby/executor'
|
10
|
+
require 'cql_ruby/crumb_collector'
|
11
|
+
require 'cql_ruby/abstract_printer'
|
12
|
+
require 'cql_ruby/console_printer'
|
13
|
+
require 'cql_ruby/filter_reader'
|
14
|
+
require 'cql_ruby/filter_evaluator'
|
15
|
+
require 'cql_ruby/pattern_matcher'
|
@@ -1,12 +1,12 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CqlRuby
|
4
|
-
#
|
5
|
-
# Printing
|
6
|
-
#
|
7
|
-
class AbstractPrinter
|
8
|
-
def print(_crumb)
|
9
|
-
raise NotImplementedError
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CqlRuby
|
4
|
+
#
|
5
|
+
# Printing CqlRuby::Crumb-s.
|
6
|
+
#
|
7
|
+
class AbstractPrinter
|
8
|
+
def print(_crumb)
|
9
|
+
raise NotImplementedError
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,97 +1,97 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CqlRuby
|
4
|
-
#
|
5
|
-
# Prints to console.
|
6
|
-
#
|
7
|
-
class ConsolePrinter < ::CqlRuby::AbstractPrinter
|
8
|
-
attr_writer :color_on
|
9
|
-
attr_writer :file_on
|
10
|
-
attr_writer :source_on
|
11
|
-
attr_writer :surrounding_lines
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
super
|
15
|
-
|
16
|
-
@color_on = true
|
17
|
-
@file_on = true
|
18
|
-
@source_on = true
|
19
|
-
@surrounding_lines = 0
|
20
|
-
@counter = 0
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
# @param crumb [
|
25
|
-
#
|
26
|
-
def print(crumb)
|
27
|
-
parts = "##{color(97)}#{@counter}#{decor_reset}"
|
28
|
-
parts += " #{color(94)}#{crumb.file_name}#{decor_reset}:#{color(33)}#{crumb.line_no}#{decor_reset} #{color(93)}#{crumb.type}#{decor_reset}" if @file_on
|
29
|
-
|
30
|
-
if @source_on && @surrounding_lines.positive?
|
31
|
-
parts_visible_len = parts.gsub(/\e\[\d+m/, '').size + 1
|
32
|
-
indent = ' ' * parts_visible_len
|
33
|
-
(-@surrounding_lines).upto(-1).each { |offs| puts "#{indent}#{crumb.surrounding_line(offs)}" }
|
34
|
-
end
|
35
|
-
|
36
|
-
parts += ' ' + decorate_source_line(crumb) if @source_on
|
37
|
-
|
38
|
-
puts parts
|
39
|
-
|
40
|
-
if @source_on && @surrounding_lines.positive?
|
41
|
-
1.upto(@surrounding_lines).each { |offs| puts "#{indent}#{crumb.surrounding_line(offs)}" }
|
42
|
-
puts '--'
|
43
|
-
end
|
44
|
-
|
45
|
-
@counter += 1
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def color(code)
|
51
|
-
if @color_on
|
52
|
-
"\e[#{code}m"
|
53
|
-
else
|
54
|
-
''
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def bold
|
59
|
-
if @color_on
|
60
|
-
"\e[1m"
|
61
|
-
else
|
62
|
-
''
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def decor_reset
|
67
|
-
if @color_on
|
68
|
-
"\e[0m"
|
69
|
-
else
|
70
|
-
''
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# @param [
|
75
|
-
# @return [String]
|
76
|
-
def decorate_source_line(crumb)
|
77
|
-
source = crumb.source
|
78
|
-
from = crumb.line_col_no
|
79
|
-
to = from + crumb.expression_size
|
80
|
-
|
81
|
-
prefix = source[0..from - 1] || ''
|
82
|
-
subject = source[from..to - 1] || ''
|
83
|
-
suffix = source[to..] || ''
|
84
|
-
|
85
|
-
color(97) +
|
86
|
-
prefix +
|
87
|
-
decor_reset +
|
88
|
-
color(31) +
|
89
|
-
bold +
|
90
|
-
subject +
|
91
|
-
decor_reset +
|
92
|
-
color(97) +
|
93
|
-
suffix +
|
94
|
-
decor_reset
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CqlRuby
|
4
|
+
#
|
5
|
+
# Prints to console.
|
6
|
+
#
|
7
|
+
class ConsolePrinter < ::CqlRuby::AbstractPrinter
|
8
|
+
attr_writer :color_on
|
9
|
+
attr_writer :file_on
|
10
|
+
attr_writer :source_on
|
11
|
+
attr_writer :surrounding_lines
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super
|
15
|
+
|
16
|
+
@color_on = true
|
17
|
+
@file_on = true
|
18
|
+
@source_on = true
|
19
|
+
@surrounding_lines = 0
|
20
|
+
@counter = 0
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# @param crumb [CqlRuby::Crumb]
|
25
|
+
#
|
26
|
+
def print(crumb)
|
27
|
+
parts = "##{color(97)}#{@counter}#{decor_reset}"
|
28
|
+
parts += " #{color(94)}#{crumb.file_name}#{decor_reset}:#{color(33)}#{crumb.line_no}#{decor_reset} #{color(93)}#{crumb.type}#{decor_reset}" if @file_on
|
29
|
+
|
30
|
+
if @source_on && @surrounding_lines.positive?
|
31
|
+
parts_visible_len = parts.gsub(/\e\[\d+m/, '').size + 1
|
32
|
+
indent = ' ' * parts_visible_len
|
33
|
+
(-@surrounding_lines).upto(-1).each { |offs| puts "#{indent}#{crumb.surrounding_line(offs)}" }
|
34
|
+
end
|
35
|
+
|
36
|
+
parts += ' ' + decorate_source_line(crumb) if @source_on
|
37
|
+
|
38
|
+
puts parts
|
39
|
+
|
40
|
+
if @source_on && @surrounding_lines.positive?
|
41
|
+
1.upto(@surrounding_lines).each { |offs| puts "#{indent}#{crumb.surrounding_line(offs)}" }
|
42
|
+
puts '--'
|
43
|
+
end
|
44
|
+
|
45
|
+
@counter += 1
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def color(code)
|
51
|
+
if @color_on
|
52
|
+
"\e[#{code}m"
|
53
|
+
else
|
54
|
+
''
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def bold
|
59
|
+
if @color_on
|
60
|
+
"\e[1m"
|
61
|
+
else
|
62
|
+
''
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def decor_reset
|
67
|
+
if @color_on
|
68
|
+
"\e[0m"
|
69
|
+
else
|
70
|
+
''
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param [CqlRuby::Crumb] crumb
|
75
|
+
# @return [String]
|
76
|
+
def decorate_source_line(crumb)
|
77
|
+
source = crumb.source
|
78
|
+
from = crumb.line_col_no
|
79
|
+
to = from + crumb.expression_size
|
80
|
+
|
81
|
+
prefix = source[0..from - 1] || ''
|
82
|
+
subject = source[from..to - 1] || ''
|
83
|
+
suffix = source[to..] || ''
|
84
|
+
|
85
|
+
color(97) +
|
86
|
+
prefix +
|
87
|
+
decor_reset +
|
88
|
+
color(31) +
|
89
|
+
bold +
|
90
|
+
subject +
|
91
|
+
decor_reset +
|
92
|
+
color(97) +
|
93
|
+
suffix +
|
94
|
+
decor_reset
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|