grepper 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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