grepper 0.9.0 → 0.9.1

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.
@@ -4,3 +4,12 @@
4
4
 
5
5
  * First release
6
6
 
7
+ === 0.9.1 / 2008-12-23
8
+
9
+ * Added Formatter class to provide reasonably standard-ish output
10
+
11
+ * Added some logic to the Match class
12
+
13
+ * Fixed a line-counting bug that was making
14
+ Match#lineno work wrongly.
15
+
@@ -2,10 +2,13 @@ History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
+ lib/formatter.rb
5
6
  lib/grepper.rb
6
7
  test/input.1
7
8
  test/input.2
8
9
  test/input.3
9
10
  test/input.4
10
11
  test/input.6
12
+ test/test_formatter.rb
11
13
  test/test_grepper.rb
14
+ test/test_match.rb
data/README.txt CHANGED
@@ -1,20 +1,5 @@
1
1
  Grepper -- simple way to grep through files and save results
2
2
 
3
- == Version
4
-
5
- 0.9.0, December 21, 2008
6
-
7
- == Author
8
-
9
- David A. Black (dblack@rubypal.com)
10
-
11
- == Copyright and license
12
-
13
- Copyright (c) 2008, Ruby Power and Light, LLC
14
-
15
- Released under the Ruby license. No warranty of any kind. Use
16
- entirely at your own risk.
17
-
18
3
  == Description
19
4
 
20
5
  The Grepper class greps through files, and returns a result
@@ -25,7 +10,10 @@ line that matched) and before- and after-context arrays. If no before
25
10
  or after lines were requested, those context values will be nil.
26
11
 
27
12
  To use, you prepare a Grepper object; call <tt>run</tt> on it; and
28
- walk through the result set.
13
+ walk through the result set. This distribution comes with the
14
+ Grepper::Formatter class, which is built on top of Grepper and provides
15
+ fairly canonical-looking output by walking through Grepper objects.
16
+ (See <tt>lib/formatter.rb</tt>.) Meanwhile, here are the details.
29
17
 
30
18
  == Preparing a Grepper object
31
19
 
@@ -94,4 +82,19 @@ and
94
82
 
95
83
  matches.each_match do |match|
96
84
 
85
+ == Version
86
+
87
+ 0.9.1, December 23, 2008
88
+
89
+ == Author
90
+
91
+ David A. Black (dblack@rubypal.com)
92
+
93
+ == Copyright and license
94
+
95
+ Copyright (c) 2008, Ruby Power and Light, LLC
96
+
97
+ Released under the Ruby license. No warranty of any kind. Use
98
+ entirely at your own risk.
99
+
97
100
 
@@ -0,0 +1,108 @@
1
+ require "rubygems"
2
+ require "grepper"
3
+
4
+ class Grepper
5
+
6
+ # == Description
7
+ #
8
+ # Grepper::Formatter provides output similar to GNU grep (and
9
+ # probably other greps.
10
+ #
11
+ # == Usage
12
+ #
13
+ # f = Grepper::Formatter.initialize(grepper)
14
+ # f.format
15
+ # puts f.output
16
+ #
17
+ # Output will show filenames if there are multiple files,
18
+ # and will show before- and after-context. The Formatter
19
+ # doesn't really do anything except format the information
20
+ # that the Grepper and its result set already have.
21
+ #
22
+ # For version and license information, see <tt>grepper.rb</tt>.
23
+ class Formatter
24
+
25
+ attr_reader :output
26
+ attr_accessor :options
27
+
28
+ def initialize(grepper)
29
+ @output = ""
30
+ @grepper = grepper
31
+ end
32
+
33
+ def matches_are_contiguous?(first,second)
34
+ first.absolute_end == second.absolute_start - 1
35
+ end
36
+
37
+ def multi?
38
+ @grepper.results.size > 1 &&! @options.include?('h')
39
+ end
40
+
41
+ def format
42
+ @output = process_grepper(@grepper)
43
+ end
44
+
45
+ def format_line(n,b,l,a)
46
+ case
47
+ when options.include?('n')
48
+ "#{n}:#{l}"
49
+ else
50
+ l.dup
51
+ end
52
+ end
53
+
54
+ def one_or_many(string, many_string)
55
+ multi? ? many_string + string : string
56
+ end
57
+
58
+ def context_lines(lines,file)
59
+ lines.map {|line| one_or_many(line,"#{file}-") }.join
60
+ end
61
+
62
+ def boundary_string_for(m1, m2, conditions_hash)
63
+ conditions = conditions_hash[:conditions]
64
+ return "" unless conditions
65
+ return "" if matches_are_contiguous?(m1, m2)
66
+ return "--\n"
67
+ end
68
+
69
+ def file_boundary_string_for(f1, f2)
70
+ f1 &&! (f1 == f2) ? "--\n" : ""
71
+ end
72
+
73
+ def process_grepper(grepper)
74
+ str = ""
75
+ last_file = nil
76
+ grepper.results.each do |file,matches|
77
+ if options.include?('l')
78
+ str << "#{file}\n"
79
+ elsif options.include?('c')
80
+ str << one_or_many("#{matches.size}\n", "#{file}:")
81
+ else
82
+ 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
+
89
+ if before
90
+ prev = matches[m-1]
91
+ str << boundary_string_for(prev, matches[m], :conditions => prev &&! m.zero?)
92
+ str << context_lines(before,file)
93
+ end
94
+
95
+ str << one_or_many(format_line(n,before,line,after), "#{file}:")
96
+
97
+ if after
98
+ str << context_lines(after,file)
99
+ succ = matches[m+1]
100
+ str << boundary_string_for(matches[m], succ, :conditions => succ)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ return str
106
+ end
107
+ end
108
+ end
@@ -1,20 +1,5 @@
1
1
  # Grepper -- simple way to grep through files and save results
2
2
  #
3
- # == Version
4
- #
5
- # 0.9.0, December 21, 2008
6
- #
7
- # == Author
8
- #
9
- # David A. Black (dblack@rubypal.com)
10
- #
11
- # == Copyright and license
12
- #
13
- # Copyright (c) 2008, Ruby Power and Light, LLC
14
- #
15
- # Released under the Ruby license. No warranty of any kind. Use
16
- # entirely at your own risk.
17
- #
18
3
  # == Description
19
4
  #
20
5
  # The Grepper class greps through files, and returns a result
@@ -25,7 +10,10 @@
25
10
  # or after lines were requested, those context values will be nil.
26
11
  #
27
12
  # To use, you prepare a Grepper object; call <tt>run</tt> on it; and
28
- # walk through the result set.
13
+ # walk through the result set. This distribution comes with the
14
+ # Grepper::Formatter class, which is built on top of Grepper and provides
15
+ # fairly canonical-looking output by walking through Grepper objects.
16
+ # (See <tt>lib/formatter.rb</tt>.) Meanwhile, here are the details.
29
17
  #
30
18
  # == Preparing a Grepper object
31
19
  #
@@ -94,9 +82,24 @@
94
82
  #
95
83
  # matches.each_match do |match|
96
84
  #
85
+ # == Version
86
+ #
87
+ # 0.9.1, December 23, 2008
88
+ #
89
+ # == Author
90
+ #
91
+ # David A. Black (dblack@rubypal.com)
92
+ #
93
+ # == Copyright and license
94
+ #
95
+ # Copyright (c) 2008, Ruby Power and Light, LLC
96
+ #
97
+ # Released under the Ruby license. No warranty of any kind. Use
98
+ # entirely at your own risk.
99
+ #
97
100
 
98
101
  class Grepper
99
- VERSION = '0.9.0'
102
+ VERSION = '0.9.1'
100
103
 
101
104
  attr_accessor :files, :pattern, :options
102
105
  attr_reader :results
@@ -111,10 +114,12 @@ class Grepper
111
114
  private
112
115
 
113
116
  def get_after_context(fh, after_count)
117
+
114
118
  res = []
115
119
  after_count.times do |i|
116
120
  line = fh.gets
117
121
  break unless line
122
+
118
123
  if match?(line)
119
124
  fh.pos -= line.size
120
125
  break
@@ -144,12 +149,17 @@ class Grepper
144
149
  results << result
145
150
  buffer = []
146
151
  File.open(file) do |fh|
147
- fh.each_with_index do |line,i|
152
+ i = 0
153
+ while line = fh.gets
154
+ i += 1
155
+
148
156
  if match?(line)
149
157
  match = Match.new(line)
150
- match.lineno = i + 1
158
+ match.lineno = i
159
+
151
160
  if after_count
152
161
  match.after = get_after_context(fh, after_count)
162
+ i += match.after.to_s.scan(/\n/).size
153
163
  end
154
164
 
155
165
  if before_count
@@ -175,13 +185,27 @@ class Grepper
175
185
  #
176
186
  # Match instances are created automatically by the Grepper
177
187
  # object when you run it.
178
- class Match
179
- attr_accessor :before, :line, :after, :lineno
180
- def initialize(line)
181
- @before = @after = nil
182
- @line = line
188
+ class Match
189
+ attr_accessor :before, :line, :after, :lineno
190
+ def initialize(line)
191
+ @before = @after = nil
192
+ @line = line
193
+ end
194
+
195
+ def total_line_count
196
+ before.to_s.scan(/\n/).size +
197
+ after.to_s.scan(/\n/).size +
198
+ 1
199
+ end
200
+
201
+ def absolute_start
202
+ lineno - before.to_s.scan(/\n/).size
203
+ end
204
+
205
+ def absolute_end
206
+ lineno + after.to_s.scan(/\n/).size
207
+ end
183
208
  end
184
- end
185
209
 
186
210
  # Grepper::Result represents the matches from a single file. It
187
211
  # connects the filename (the <tt>file</tt> attribute) with a
@@ -199,12 +223,13 @@ end
199
223
 
200
224
  # Provides the iteration intelligence for result sets.
201
225
  module ResultsExtension
202
- def each(&block)
226
+ def each
203
227
  (0...size).each do |i|
204
228
  yield(self[i].file, self[i].matches)
205
229
  end
206
230
  end
207
- def each_result(&block)
231
+
232
+ def each_result
208
233
  (0...size).each do |i|
209
234
  yield self[i]
210
235
  end
@@ -0,0 +1,149 @@
1
+ require 'lib/formatter'
2
+ require 'test/unit'
3
+
4
+ class FormatterTest < Test::Unit::TestCase
5
+ def setup
6
+ @g = Grepper.new
7
+ @g.files = %w{ test/input.1 test/input.2 test/input.3 }
8
+ @g.pattern = /abc/
9
+ end
10
+
11
+ def run_with_files(grepper,*files)
12
+ grepper.files = *files
13
+ grepper.run
14
+ end
15
+
16
+ def formatter_for(grepper, options=grepper.options)
17
+ f = Grepper::Formatter.new(grepper)
18
+ f.options = options
19
+ f.format
20
+ f
21
+ end
22
+
23
+ def test_one_file
24
+ run_with_files(@g,%w{ test/input.1 })
25
+ f = formatter_for(@g)
26
+ assert_equal("This matches abc.\n", f.output)
27
+ end
28
+
29
+ def test_one_file_with_line_numbers
30
+ run_with_files(@g,%w{ test/input.1 })
31
+ f = formatter_for(@g, %w{n})
32
+ assert_equal("2:This matches abc.\n", f.output)
33
+ end
34
+
35
+ def test_one_file_with_count
36
+ run_with_files(@g,%w{ test/input.6 })
37
+ f = formatter_for(@g, %w{c})
38
+ assert_equal("3\n", f.output)
39
+ end
40
+
41
+ def test_one_file_name_only
42
+ run_with_files(@g,%w{ test/input.1 })
43
+ f = formatter_for(@g, %w{l})
44
+ assert_equal("test/input.1\n", f.output)
45
+ end
46
+
47
+ def test_multiple_files_name_only
48
+ run_with_files(@g, %w{ test/input.1 test/input.2 test/input.4 })
49
+ f = formatter_for(@g, %w{l})
50
+ assert_equal("test/input.1\ntest/input.2\ntest/input.4\n", f.output)
51
+ end
52
+
53
+ def test_multiple_files_with_count
54
+ run_with_files(@g, %w{ test/input.1 test/input.6 })
55
+ f = formatter_for(@g, %w{c})
56
+ assert_equal("test/input.1:1\ntest/input.6:3\n", f.output)
57
+ end
58
+
59
+ def test_multiple_files_with_line_numbers
60
+ run_with_files(@g,%w{ test/input.1 test/input.2 })
61
+ f = formatter_for(@g, %w{n})
62
+ assert_equal("test/input.1:2:This matches abc.\ntest/input.2:3:So does this abc.\n", f.output)
63
+ end
64
+
65
+ def test_after_context_single_file
66
+ @g.options = ["A2"]
67
+ run_with_files(@g,%w{ test/input.6 })
68
+ f = formatter_for(@g)
69
+ assert_equal(<<EOM, f.output)
70
+ abc
71
+ three
72
+ four
73
+ abc
74
+ five
75
+ six
76
+ abc
77
+ EOM
78
+ end
79
+ def test_after_context_single_file_with_separator
80
+ @g.options = ["A1"]
81
+ run_with_files(@g,%w{ test/input.6 })
82
+ f = formatter_for(@g)
83
+ assert_equal(<<EOM, f.output)
84
+ abc
85
+ three
86
+ --
87
+ abc
88
+ five
89
+ --
90
+ abc
91
+ EOM
92
+ end
93
+
94
+
95
+ def test_before_context_single_file
96
+ @g.options = ["B1"]
97
+ run_with_files(@g, %w{ test/input.6 })
98
+ f = formatter_for(@g)
99
+ assert_equal(<<EOM, f.output)
100
+ two
101
+ abc
102
+ --
103
+ four
104
+ abc
105
+ --
106
+ six
107
+ abc
108
+ EOM
109
+ end
110
+
111
+ def test_before_context_multiple_files
112
+ @g.options = ["B1"]
113
+ run_with_files(@g, %w{ test/input.1 test/input.6 })
114
+ f = formatter_for(@g)
115
+ assert_equal(<<EOM, f.output)
116
+ test/input.1-This is a file
117
+ test/input.1:This matches abc.
118
+ --
119
+ test/input.6-two
120
+ test/input.6:abc
121
+ --
122
+ test/input.6-four
123
+ test/input.6:abc
124
+ --
125
+ test/input.6-six
126
+ test/input.6:abc
127
+ EOM
128
+ end
129
+
130
+ def test_after_context_multiple_files
131
+ @g.options = ["A1"]
132
+ run_with_files(@g, %w{ test/input.1 test/input.6 })
133
+ f = formatter_for(@g)
134
+ assert_equal(<<EOM, f.output)
135
+ test/input.1:This matches abc.
136
+ test/input.1-This doesn't.
137
+ --
138
+ test/input.6:abc
139
+ test/input.6-three
140
+ --
141
+ test/input.6:abc
142
+ test/input.6-five
143
+ --
144
+ test/input.6:abc
145
+ EOM
146
+ end
147
+
148
+ end
149
+
@@ -1,5 +1,4 @@
1
- require 'test/unit'
2
- require 'English'
1
+ require "test/unit"
3
2
  require "lib/grepper.rb"
4
3
 
5
4
  class GrepTest < Test::Unit::TestCase
@@ -132,6 +131,14 @@ EOM
132
131
  assert_equal(2, @g.results[0].matches[0].lineno)
133
132
  end
134
133
 
134
+ def test_multiple_line_numbers_one_file
135
+ @g.files = ["test/input.6"]
136
+ @g.options = ["A1"]
137
+ @g.run
138
+ assert_equal(3, @g.results[0].matches[0].lineno)
139
+ assert_equal(6, @g.results[0].matches[1].lineno)
140
+ end
141
+
135
142
  def test_line_numbering_in_multiple_files
136
143
  test_basic_lines_from_multiple_files
137
144
  assert_equal(3, @g.results[1].matches[0].lineno)
@@ -0,0 +1,54 @@
1
+ # Tests for the match statistic logic.
2
+
3
+ require "test/unit"
4
+ require "lib/grepper.rb"
5
+
6
+ class Grepper::MatchTest < Test::Unit::TestCase
7
+ def setup
8
+ @g = Grepper.new
9
+ @g.pattern = /abc/
10
+ @g.files = %w{ test/input.6 }
11
+ end
12
+
13
+ def assert_match_stats(match, lineno, abs_start, abs_end)
14
+ assert_equal(lineno, match.lineno)
15
+ assert_equal(abs_start, match.absolute_start)
16
+ assert_equal(abs_end, match.absolute_end)
17
+ end
18
+
19
+ def test_basic_match_location_data
20
+ @g.run
21
+ m = @g.results[0].matches[0]
22
+ assert_match_stats(m,3,3,3)
23
+ end
24
+
25
+ def test_before_context
26
+ @g.options = "B2"
27
+ @g.run
28
+ matches = @g.results[0].matches
29
+ assert_match_stats(matches[0], 3,1,3)
30
+ assert_match_stats(matches[1], 6,4,6)
31
+ assert_match_stats(matches[2], 9,7,9)
32
+ end
33
+
34
+ def test_after_context
35
+ @g.options = "A2"
36
+ @g.run
37
+ matches = @g.results[0].matches
38
+ assert_match_stats(matches[0], 3,3,5)
39
+ assert_match_stats(matches[1], 6,6,8)
40
+ assert_match_stats(matches[2], 9,9,9)
41
+ end
42
+
43
+ def test_both_contexts
44
+ @g.options = "A1B1"
45
+ @g.run
46
+ matches = @g.results[0].matches
47
+ assert_match_stats(matches[0], 3,2,4)
48
+ assert_match_stats(matches[1], 6,5,7)
49
+ assert_match_stats(matches[2], 9,8,9)
50
+ end
51
+
52
+ end
53
+
54
+
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.0
4
+ version: 0.9.1
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-22 00:00:00 -05:00
12
+ date: 2008-12-23 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,7 +22,7 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.8.2
24
24
  version:
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.
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
28
  executables: []
@@ -38,15 +38,18 @@ files:
38
38
  - Manifest.txt
39
39
  - README.txt
40
40
  - Rakefile
41
+ - lib/formatter.rb
41
42
  - lib/grepper.rb
42
43
  - test/input.1
43
44
  - test/input.2
44
45
  - test/input.3
45
46
  - test/input.4
46
47
  - test/input.6
48
+ - test/test_formatter.rb
47
49
  - test/test_grepper.rb
50
+ - test/test_match.rb
48
51
  has_rdoc: true
49
- homepage: 0.9.0, December 21, 2008
52
+ homepage: The Grepper class greps through files, and returns a result
50
53
  post_install_message:
51
54
  rdoc_options:
52
55
  - --main
@@ -68,9 +71,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
71
  requirements: []
69
72
 
70
73
  rubyforge_project: grepper
71
- rubygems_version: 1.2.0
74
+ rubygems_version: 1.3.1
72
75
  signing_key:
73
76
  specification_version: 2
74
77
  summary: The Grepper class greps through files, and returns a result set of Grepper::Result objects
75
78
  test_files:
79
+ - test/test_formatter.rb
76
80
  - test/test_grepper.rb
81
+ - test/test_match.rb