-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsrch
executable file
·143 lines (121 loc) · 3.86 KB
/
srch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env ruby
require "bundler"
Bundler.setup
require_relative "ndex"
require "colorize"
require "thor"
module Srch
class << self
extend NdexPlugin
def text(pattern, recent, name=nil)
recent = recent || Ndex.max_id
matches = {}
# Make this faster by relying upon the_silver_searcher (much faster)
# to determine candidate files with possible matches, and skipping HTML
# parsing if the file isn't contained in ag results
filter = {}
`ag -l "#{pattern}"`.split("\n").each do |path|
filter[path.downcase] = true
end
Ndex.sessions.each do |session|
if session.subfolder_id > Ndex.max_id - recent
session.logfiles.each do |logfile|
# If present in filter, name var exists, and if so name var in logfile name
if filter[logfile.path.downcase] && !(name && !logfile.match_name?(name))
lines = logfile.find_lines(pattern)
matches[logfile] = lines unless lines.empty?
end
end
end
end
matches
end
def print_matching_logfiles(pattern, recent)
recent = recent || Ndex.max_id
Ndex.sessions.each do |session|
if session.subfolder_id > Ndex.max_id - recent
session.matching_logfiles(pattern).each { |lf| puts lf.pp }
end
end
end
def find_matching_logfiles(pattern)
Ndex.sessions.reduce([]) do |matches, session|
matches.concat(session.matching_logfiles(pattern))
end
end
end
end
def print_header(action, desc, min=nil, max=nil)
min = min || Ndex.min_id
max = max || Ndex.max_id
puts ">>>>> #{action} #{Ndex.subfolder_prefix} #{min} through #{max} #{desc}".cyan.on_black
end
def width
@width = @width || `tput cols`.to_i
end
# Overwrite no command error to assume "name" is the default command and call
# it with the correct argument. This maintains the existing CLI behavior from
# before using Thor
class Thor
module Base
module ClassMethods
def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
SrchCLI.start(ARGV.unshift("name"))
end
end
end
end
class SrchCLI < Thor
desc "exec COMMAND PATTERN", "execute shell command on all logfiles whose name matches PATTERN"
def exec(command, pattern)
results = Srch.find_matching_logfiles(pattern)
cont = yes?("Do you want to run '#{command}' on #{results.size} logfiles? (y/n)")
if cont
puts "Executing commands:"
results.each do |logfile|
puts " #{command} \"#{logfile.path}\""
ret = `#{command} \"#{logfile.path}\"`
puts ret if ret && ret != ""
end
end
end
desc "fulltext PATTERN", "full text search for logfile lines matching PATTERN"
option :recent, :type => :numeric, :aliases => :r
option :name, :type => :string, :aliases => :n
def fulltext(pattern)
recent = options[:recent] || Ndex.max_id
print_header(
"Full-text searching",
"for \"#{pattern}\"",
options[:recent] ? Ndex.max_id - recent : nil
)
matches = Srch.text(pattern, recent, options[:name]).each_pair do |logfile, lines|
puts logfile.pp.ljust(width).black.on_white
odd_line = true
lines.each do |line|
print_str = "#{line}\n\n"
if odd_line
puts print_str
else
puts print_str.on_black
end
odd_line = !odd_line
end
end
end
map "text" => :fulltext
map "ftext" => :fulltext
desc "name PATTERN", "list logfiles whose name matches PATTERN"
option :recent, :type => :numeric, :aliases => :r
def name(pattern)
recent = options[:recent] || Ndex.max_id
print_header(
"Searching",
"for filename \"#{pattern}\"",
options[:recent] ? Ndex.max_id - recent : nil
)
Srch.print_matching_logfiles(pattern, recent)
end
map "find" => :name
end
SrchCLI.start(ARGV)