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 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
@@ -2,8 +2,9 @@ History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
- lib/formatter.rb
5
+ bin/grep.rb
6
6
  lib/grepper.rb
7
+ lib/grepper/formatter.rb
7
8
  test/input.1
8
9
  test/input.2
9
10
  test/input.3
data/README.txt CHANGED
@@ -84,7 +84,7 @@ and
84
84
 
85
85
  == Version
86
86
 
87
- 0.9.1, December 23, 2008
87
+ 0.9.2, December 24, 2008
88
88
 
89
89
  == Author
90
90
 
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
- lines.map {|line| one_or_many(line,"#{file}-") }.join
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
- def file_boundary_string_for(f1, f2)
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 << context_lines(before,file)
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 << context_lines(after,file)
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.1, December 23, 2008
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.1'
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.
@@ -1,4 +1,6 @@
1
- require 'lib/formatter'
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, options=grepper.options)
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
@@ -1,3 +1,5 @@
1
+ # Tests of the basic functioning of the grepper.
2
+
1
3
  require "test/unit"
2
4
  require "lib/grepper.rb"
3
5
 
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.1
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-23 00:00:00 -05:00
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
- - lib/formatter.rb
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