grepper 0.9.1 → 0.9.2

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.
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