grepper 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -0
- data/Manifest.txt +2 -1
- data/README.txt +1 -1
- data/bin/grep.rb +48 -0
- data/lib/{formatter.rb → grepper/formatter.rb} +61 -13
- data/lib/grepper.rb +8 -4
- data/test/test_formatter.rb +64 -3
- data/test/test_grepper.rb +2 -0
- metadata +6 -5
data/History.txt
CHANGED
@@ -13,3 +13,12 @@
|
|
13
13
|
* Fixed a line-counting bug that was making
|
14
14
|
Match#lineno work wrongly.
|
15
15
|
|
16
|
+
=== 0.9.2 / 2008-12-24
|
17
|
+
|
18
|
+
* Added bin/grep.rb, simple grep commandline tool
|
19
|
+
|
20
|
+
* Fixed some separator problems in formatter output
|
21
|
+
|
22
|
+
* Added some logic to the Match and Result classes
|
23
|
+
|
24
|
+
* Refactoring
|
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
data/bin/grep.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
$: << '../lib'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'grepper'
|
4
|
+
require 'grepper/formatter'
|
5
|
+
|
6
|
+
require 'getoptlong'
|
7
|
+
|
8
|
+
|
9
|
+
opts = GetoptLong.new(
|
10
|
+
['--help', '-h', GetoptLong::NO_ARGUMENT],
|
11
|
+
['--line-number', '-n', GetoptLong::NO_ARGUMENT],
|
12
|
+
['--before-context', '-B', GetoptLong::REQUIRED_ARGUMENT],
|
13
|
+
['--after-context', '-A', GetoptLong::REQUIRED_ARGUMENT],
|
14
|
+
['--invert-match', '-v', GetoptLong::NO_ARGUMENT]
|
15
|
+
)
|
16
|
+
|
17
|
+
grepper = Grepper.new
|
18
|
+
formatter = Grepper::Formatter.new(grepper)
|
19
|
+
|
20
|
+
opts.each do |opt,arg|
|
21
|
+
case opt
|
22
|
+
when '--line-number'
|
23
|
+
formatter.options << "n"
|
24
|
+
when '--before-context'
|
25
|
+
grepper.options << "B#{arg}"
|
26
|
+
when '--after-context'
|
27
|
+
grepper.options << "A#{arg}"
|
28
|
+
when '--invert-match'
|
29
|
+
grepper.options << "v"
|
30
|
+
when '--help'
|
31
|
+
puts "Help"
|
32
|
+
exit 0
|
33
|
+
else
|
34
|
+
puts "Unknown option #{opt}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
if ARGV.size < 2
|
39
|
+
puts "Sorry"
|
40
|
+
exit 0
|
41
|
+
end
|
42
|
+
|
43
|
+
grepper.pattern = Regexp.new(ARGV.shift)
|
44
|
+
grepper.files = ARGV.dup
|
45
|
+
|
46
|
+
grepper.run
|
47
|
+
formatter.format
|
48
|
+
puts formatter.output
|
@@ -12,6 +12,7 @@ class Grepper
|
|
12
12
|
#
|
13
13
|
# f = Grepper::Formatter.initialize(grepper)
|
14
14
|
# f.format
|
15
|
+
# f.options = ['...'] # see below
|
15
16
|
# puts f.output
|
16
17
|
#
|
17
18
|
# Output will show filenames if there are multiple files,
|
@@ -20,6 +21,25 @@ class Grepper
|
|
20
21
|
# that the Grepper and its result set already have.
|
21
22
|
#
|
22
23
|
# For version and license information, see <tt>grepper.rb</tt>.
|
24
|
+
#
|
25
|
+
# == Options
|
26
|
+
#
|
27
|
+
# Formatters have an options array which you can set and
|
28
|
+
# add to. It's empty by default.
|
29
|
+
#
|
30
|
+
# Available options:
|
31
|
+
#
|
32
|
+
# * <tt>l</tt> -- show matching filenames only
|
33
|
+
# * <tt>c</tt> -- show match count only
|
34
|
+
# * <tt>n</tt> -- show the line number of the match
|
35
|
+
#
|
36
|
+
# Note that Grepper objects also have options ('v', 'A1', etc.).
|
37
|
+
# Both the Formatter options and the Grepper options are pulled
|
38
|
+
# from the canon of grep(1) options. Some make more sense for the
|
39
|
+
# grep operation itself (like inverting the sense of the match with
|
40
|
+
# 'v'), while some are purely a formatting thing (like including the
|
41
|
+
# filename).
|
42
|
+
|
23
43
|
class Formatter
|
24
44
|
|
25
45
|
attr_reader :output
|
@@ -28,6 +48,7 @@ class Grepper
|
|
28
48
|
def initialize(grepper)
|
29
49
|
@output = ""
|
30
50
|
@grepper = grepper
|
51
|
+
@options = []
|
31
52
|
end
|
32
53
|
|
33
54
|
def matches_are_contiguous?(first,second)
|
@@ -42,6 +63,8 @@ class Grepper
|
|
42
63
|
@output = process_grepper(@grepper)
|
43
64
|
end
|
44
65
|
|
66
|
+
private
|
67
|
+
|
45
68
|
def format_line(n,b,l,a)
|
46
69
|
case
|
47
70
|
when options.include?('n')
|
@@ -55,10 +78,28 @@ class Grepper
|
|
55
78
|
multi? ? many_string + string : string
|
56
79
|
end
|
57
80
|
|
58
|
-
def context_lines(lines,file)
|
59
|
-
|
81
|
+
def context_lines(lines,file,n,position)
|
82
|
+
str = ""
|
83
|
+
i = case position
|
84
|
+
when :before then n - lines.size
|
85
|
+
when :after then n + 1
|
86
|
+
end
|
87
|
+
lines.each do |line|
|
88
|
+
count = options.include?('n') ? "#{i}-" : ""
|
89
|
+
str << one_or_many("#{count}#{line}","#{file}-")
|
90
|
+
i += 1
|
91
|
+
end
|
92
|
+
str
|
60
93
|
end
|
61
94
|
|
95
|
+
def before_lines(*args)
|
96
|
+
context_lines(*args << :before)
|
97
|
+
end
|
98
|
+
|
99
|
+
def after_lines(*args)
|
100
|
+
context_lines(*args << :after)
|
101
|
+
end
|
102
|
+
|
62
103
|
def boundary_string_for(m1, m2, conditions_hash)
|
63
104
|
conditions = conditions_hash[:conditions]
|
64
105
|
return "" unless conditions
|
@@ -66,36 +107,43 @@ class Grepper
|
|
66
107
|
return "--\n"
|
67
108
|
end
|
68
109
|
|
69
|
-
|
70
|
-
f1 &&! (f1 == f2) ? "--\n" : ""
|
71
|
-
end
|
110
|
+
public
|
72
111
|
|
73
112
|
def process_grepper(grepper)
|
74
113
|
str = ""
|
75
114
|
last_file = nil
|
115
|
+
context = grepper.results.context?
|
116
|
+
|
76
117
|
grepper.results.each do |file,matches|
|
118
|
+
|
119
|
+
# Put in a -- boundary if this is a new file and
|
120
|
+
# there's a before- or after-context
|
121
|
+
if context && last_file &&! (file == last_file)
|
122
|
+
str << "--\n"
|
123
|
+
end
|
124
|
+
|
125
|
+
last_file = file
|
126
|
+
|
127
|
+
# 'l' -- filenames only
|
77
128
|
if options.include?('l')
|
78
129
|
str << "#{file}\n"
|
130
|
+
|
131
|
+
# 'c' -- match count only
|
79
132
|
elsif options.include?('c')
|
80
133
|
str << one_or_many("#{matches.size}\n", "#{file}:")
|
81
134
|
else
|
82
135
|
matches.each_with_index do |(n,before,line,after),m|
|
83
|
-
if (after || before)
|
84
|
-
str << file_boundary_string_for(last_file, file)
|
85
|
-
end
|
86
|
-
|
87
|
-
last_file = file
|
88
136
|
|
89
137
|
if before
|
90
138
|
prev = matches[m-1]
|
91
139
|
str << boundary_string_for(prev, matches[m], :conditions => prev &&! m.zero?)
|
92
|
-
str <<
|
140
|
+
str << before_lines(before,file,n)
|
93
141
|
end
|
94
142
|
|
95
143
|
str << one_or_many(format_line(n,before,line,after), "#{file}:")
|
96
144
|
|
97
145
|
if after
|
98
|
-
str <<
|
146
|
+
str << after_lines(after,file,n)
|
99
147
|
succ = matches[m+1]
|
100
148
|
str << boundary_string_for(matches[m], succ, :conditions => succ)
|
101
149
|
end
|
@@ -105,4 +153,4 @@ class Grepper
|
|
105
153
|
return str
|
106
154
|
end
|
107
155
|
end
|
108
|
-
end
|
156
|
+
end
|
data/lib/grepper.rb
CHANGED
@@ -84,7 +84,7 @@
|
|
84
84
|
#
|
85
85
|
# == Version
|
86
86
|
#
|
87
|
-
# 0.9.
|
87
|
+
# 0.9.2, December 24, 2008
|
88
88
|
#
|
89
89
|
# == Author
|
90
90
|
#
|
@@ -99,7 +99,7 @@
|
|
99
99
|
#
|
100
100
|
|
101
101
|
class Grepper
|
102
|
-
VERSION = '0.9.
|
102
|
+
VERSION = '0.9.2'
|
103
103
|
|
104
104
|
attr_accessor :files, :pattern, :options
|
105
105
|
attr_reader :results
|
@@ -141,8 +141,8 @@ class Grepper
|
|
141
141
|
def run
|
142
142
|
@negate = true if options.include?('v')
|
143
143
|
|
144
|
-
after_count = $1.to_i if options.find {|o| /A(\d)/.match(o) }
|
145
|
-
before_count = $1.to_i if options.find {|o| /B(\d)/.match(o) }
|
144
|
+
after_count = $1.to_i if options.find {|o| /A(\d+)/.match(o) }
|
145
|
+
before_count = $1.to_i if options.find {|o| /B(\d+)/.match(o) }
|
146
146
|
|
147
147
|
files.each do |file|
|
148
148
|
result = Result.new(file)
|
@@ -234,6 +234,10 @@ class Grepper
|
|
234
234
|
yield self[i]
|
235
235
|
end
|
236
236
|
end
|
237
|
+
|
238
|
+
def context?
|
239
|
+
any? {|f,matches| matches.any? {|n,b,l,a| b || a } }
|
240
|
+
end
|
237
241
|
end
|
238
242
|
|
239
243
|
# Provides the iteration intelligence for match sets.
|
data/test/test_formatter.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# Tests of the output of the formatter.
|
2
|
+
|
3
|
+
require 'grepper/formatter'
|
2
4
|
require 'test/unit'
|
3
5
|
|
4
6
|
class FormatterTest < Test::Unit::TestCase
|
@@ -13,7 +15,7 @@ class FormatterTest < Test::Unit::TestCase
|
|
13
15
|
grepper.run
|
14
16
|
end
|
15
17
|
|
16
|
-
def formatter_for(grepper,
|
18
|
+
def formatter_for(grepper,options = [])
|
17
19
|
f = Grepper::Formatter.new(grepper)
|
18
20
|
f.options = options
|
19
21
|
f.format
|
@@ -145,5 +147,64 @@ test/input.6:abc
|
|
145
147
|
EOM
|
146
148
|
end
|
147
149
|
|
150
|
+
def test_before_context_with_line_numbers
|
151
|
+
@g.options = ["B2"]
|
152
|
+
run_with_files(@g, %w{ test/input.6 })
|
153
|
+
f = formatter_for(@g,["n"])
|
154
|
+
assert_equal(<<EOM, f.output)
|
155
|
+
1-one
|
156
|
+
2-two
|
157
|
+
3:abc
|
158
|
+
4-three
|
159
|
+
5-four
|
160
|
+
6:abc
|
161
|
+
7-five
|
162
|
+
8-six
|
163
|
+
9:abc
|
164
|
+
EOM
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_after_context_with_line_numbers
|
168
|
+
@g.options = ["A2"]
|
169
|
+
run_with_files(@g, %w{ test/input.6 })
|
170
|
+
f = formatter_for(@g,["n"])
|
171
|
+
assert_equal(<<EOM, f.output)
|
172
|
+
3:abc
|
173
|
+
4-three
|
174
|
+
5-four
|
175
|
+
6:abc
|
176
|
+
7-five
|
177
|
+
8-six
|
178
|
+
9:abc
|
179
|
+
EOM
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_before_context_line_numbers_multiple_files
|
183
|
+
@g.options = ["B2"]
|
184
|
+
run_with_files(@g, %w{ test/input.1 test/input.2 })
|
185
|
+
f = formatter_for(@g,["n"])
|
186
|
+
assert_equal(<<EOM, f.output)
|
187
|
+
test/input.1-1-This is a file
|
188
|
+
test/input.1:2:This matches abc.
|
189
|
+
--
|
190
|
+
test/input.2-1-This doesn't match.
|
191
|
+
test/input.2-2-However, this:
|
192
|
+
test/input.2:3:So does this abc.
|
193
|
+
EOM
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_after_context_line_numbers_multiple_files
|
197
|
+
@g.options = ["A2"]
|
198
|
+
run_with_files(@g, %w{ test/input.1 test/input.2 })
|
199
|
+
f = formatter_for(@g,["n"])
|
200
|
+
assert_equal(<<EOM, f.output)
|
201
|
+
test/input.1:2:This matches abc.
|
202
|
+
test/input.1-3-This doesn't.
|
203
|
+
--
|
204
|
+
test/input.2:3:So does this abc.
|
205
|
+
test/input.2-4-does.
|
206
|
+
EOM
|
207
|
+
end
|
148
208
|
end
|
149
|
-
|
209
|
+
|
210
|
+
|
data/test/test_grepper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grepper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David A. Black
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-12-
|
12
|
+
date: 2008-12-24 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -25,8 +25,8 @@ dependencies:
|
|
25
25
|
description: The Grepper class greps through files, and returns a result set of Grepper::Result objects. Each Result object represents the matches found in a single file. The Result contains a set of Grepper::Match objects. Each Match object represents a line (the line that matched) and before- and after-context arrays. If no before or after lines were requested, those context values will be nil. To use, you prepare a Grepper object; call <tt>run</tt> on it; and walk through the result set. This distribution comes with the Grepper::Formatter class, which is built on top of Grepper and provides fairly canonical-looking output by walking through Grepper objects. (See <tt>lib/formatter.rb</tt>.) Meanwhile, here are the details.
|
26
26
|
email:
|
27
27
|
- dblack@rubypal.com
|
28
|
-
executables:
|
29
|
-
|
28
|
+
executables:
|
29
|
+
- grep.rb
|
30
30
|
extensions: []
|
31
31
|
|
32
32
|
extra_rdoc_files:
|
@@ -38,8 +38,9 @@ files:
|
|
38
38
|
- Manifest.txt
|
39
39
|
- README.txt
|
40
40
|
- Rakefile
|
41
|
-
-
|
41
|
+
- bin/grep.rb
|
42
42
|
- lib/grepper.rb
|
43
|
+
- lib/grepper/formatter.rb
|
43
44
|
- test/input.1
|
44
45
|
- test/input.2
|
45
46
|
- test/input.3
|