glark 1.9.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/bin/glark +2 -2
  2. data/lib/glark.rb +1 -1
  3. data/lib/glark/app/app.rb +48 -0
  4. data/lib/glark/app/help.rb +103 -0
  5. data/lib/glark/app/info/options.rb +84 -0
  6. data/lib/glark/app/options.rb +201 -0
  7. data/lib/glark/app/rcfile.rb +49 -0
  8. data/lib/glark/app/runner.rb +140 -0
  9. data/lib/glark/app/spec.rb +19 -0
  10. data/lib/glark/input/filter/criteria_opts.rb +41 -0
  11. data/lib/glark/input/filter/dir_criteria_opts.rb +37 -0
  12. data/lib/glark/input/filter/file_criteria_opts.rb +33 -0
  13. data/lib/glark/input/filter/filter.rb +59 -0
  14. data/lib/glark/input/filter/options.rb +171 -0
  15. data/lib/glark/input/options.rb +120 -0
  16. data/lib/glark/input/range.rb +104 -0
  17. data/lib/glark/input/spec.rb +39 -0
  18. data/lib/glark/io/file/archive_file.rb +64 -0
  19. data/lib/glark/io/file/binary_file.rb +19 -0
  20. data/lib/glark/io/file/file.rb +57 -0
  21. data/lib/glark/io/file/gz_file.rb +21 -0
  22. data/lib/glark/io/file/tar_file.rb +35 -0
  23. data/lib/glark/io/file/tar_gz_file.rb +52 -0
  24. data/lib/glark/io/file/zip_file.rb +39 -0
  25. data/lib/glark/match/and.rb +83 -0
  26. data/lib/glark/match/and_distance.rb +58 -0
  27. data/lib/glark/match/compound.rb +34 -0
  28. data/lib/glark/match/expression.rb +63 -0
  29. data/lib/glark/match/factory.rb +173 -0
  30. data/lib/glark/match/ior.rb +20 -0
  31. data/lib/glark/match/options.rb +74 -0
  32. data/lib/glark/match/or.rb +41 -0
  33. data/lib/glark/match/re.rb +81 -0
  34. data/lib/glark/match/re_factory.rb +44 -0
  35. data/lib/glark/match/spec.rb +59 -0
  36. data/lib/glark/match/xor.rb +20 -0
  37. data/lib/glark/output/binary_file_summary.rb +17 -0
  38. data/lib/glark/output/common.rb +43 -0
  39. data/lib/glark/output/context.rb +57 -0
  40. data/lib/glark/output/count.rb +26 -0
  41. data/lib/glark/output/file_header.rb +20 -0
  42. data/lib/glark/output/file_name_only.rb +35 -0
  43. data/lib/glark/output/formatted.rb +22 -0
  44. data/lib/glark/output/glark_count.rb +23 -0
  45. data/lib/glark/output/glark_format.rb +62 -0
  46. data/lib/glark/output/glark_lines.rb +36 -0
  47. data/lib/glark/output/grep_count.rb +18 -0
  48. data/lib/glark/output/grep_lines.rb +42 -0
  49. data/lib/glark/output/line_status.rb +46 -0
  50. data/lib/glark/output/lines.rb +100 -0
  51. data/lib/glark/output/match_list.rb +15 -0
  52. data/lib/glark/output/options.rb +103 -0
  53. data/lib/glark/output/results.rb +23 -0
  54. data/lib/glark/output/spec.rb +105 -0
  55. data/lib/glark/output/unfiltered_lines.rb +28 -0
  56. data/lib/glark/util/colors/options.rb +143 -0
  57. data/lib/glark/util/colors/spec.rb +21 -0
  58. data/lib/glark/util/highlight.rb +108 -0
  59. data/lib/glark/util/io/depth.rb +29 -0
  60. data/lib/glark/util/io/fileset.rb +162 -0
  61. data/lib/glark/util/io/filter/criteria.rb +49 -0
  62. data/lib/glark/util/io/filter/filter.rb +10 -0
  63. data/lib/glark/util/io/lines.rb +117 -0
  64. data/lib/glark/util/option.rb +34 -0
  65. data/lib/glark/util/options.rb +12 -0
  66. data/lib/glark/util/optutil.rb +69 -0
  67. data/lib/glark/util/timestamper.rb +18 -0
  68. data/man/glark.1 +1134 -0
  69. data/test/glark/app/and_test.rb +82 -0
  70. data/test/glark/app/compound_test.rb +33 -0
  71. data/test/glark/app/context_test.rb +43 -0
  72. data/test/glark/app/count_test.rb +89 -0
  73. data/test/glark/app/dump_test.rb +16 -0
  74. data/test/glark/app/expression_file_test.rb +22 -0
  75. data/test/glark/app/extended_regexp_test.rb +17 -0
  76. data/test/glark/app/extract_matches_test.rb +27 -0
  77. data/test/glark/app/files_with_match_test.rb +32 -0
  78. data/test/glark/app/files_without_match_test.rb +26 -0
  79. data/test/glark/app/filter_test.rb +118 -0
  80. data/test/glark/app/highlight_test.rb +78 -0
  81. data/test/glark/app/ignore_case_test.rb +22 -0
  82. data/test/glark/app/invert_test.rb +49 -0
  83. data/test/glark/app/ior_test.rb +21 -0
  84. data/test/glark/app/label_test.rb +28 -0
  85. data/test/glark/app/line_number_color_test.rb +42 -0
  86. data/test/glark/app/line_numbers_test.rb +42 -0
  87. data/test/glark/app/match_limit_test.rb +49 -0
  88. data/test/glark/app/options_test.rb +722 -0
  89. data/test/glark/app/range_test.rb +101 -0
  90. data/test/glark/app/rcfile_test.rb +113 -0
  91. data/test/glark/app/record_separator_test.rb +32 -0
  92. data/test/glark/app/regexp_test.rb +48 -0
  93. data/test/glark/app/tc.rb +92 -0
  94. data/test/glark/app/text_color_test.rb +31 -0
  95. data/test/glark/app/whole_lines_test.rb +17 -0
  96. data/test/glark/app/whole_words_test.rb +42 -0
  97. data/test/glark/app/xor_test.rb +19 -0
  98. data/test/glark/input/binary_file_test.rb +0 -0
  99. data/test/glark/input/directory_test.rb +202 -0
  100. data/test/glark/input/dirname_test.rb +69 -0
  101. data/test/glark/input/exclude_matching_test.rb +20 -0
  102. data/test/glark/input/ext_test.rb +65 -0
  103. data/test/glark/input/filter/criteria_test.rb +91 -0
  104. data/test/glark/input/filter/filter_spec_test.rb +27 -0
  105. data/test/glark/input/filter/filter_test.rb +21 -0
  106. data/test/glark/input/name_test.rb +75 -0
  107. data/test/glark/input/path_test.rb +72 -0
  108. data/test/glark/input/range_test.rb +82 -0
  109. data/test/glark/input/size_limit_test.rb +51 -0
  110. data/test/glark/input/split_as_path_test.rb +28 -0
  111. data/test/glark/match_test.rb +192 -0
  112. data/test/glark/resources.rb +21 -0
  113. data/test/glark/tc.rb +37 -0
  114. data/test/resources/add.rb +10 -0
  115. data/test/resources/echo.rb +2 -0
  116. data/test/resources/greet.rb +13 -0
  117. metadata +198 -28
  118. data/README +0 -0
  119. data/bin/jlark +0 -63
  120. data/lib/glark/expression.rb +0 -440
  121. data/lib/glark/exprfactory.rb +0 -248
  122. data/lib/glark/glark.rb +0 -297
  123. data/lib/glark/help.rb +0 -85
  124. data/lib/glark/input.rb +0 -183
  125. data/lib/glark/options.rb +0 -757
  126. data/lib/glark/output.rb +0 -266
  127. data/test/lib/glark/glark_test.rb +0 -317
  128. data/test/lib/glark/options_test.rb +0 -891
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/ruby -w
2
+ #!ruby -w
3
+ # vim: set filetype=ruby : set sw=2
4
+
5
+ # Options for input.
6
+
7
+ require 'rubygems'
8
+ require 'glark/input/spec'
9
+ require 'glark/util/io/fileset'
10
+ require 'glark/util/options'
11
+
12
+ module Glark
13
+ class InputOptions < InputSpec
14
+ include OptionUtil, Loggable
15
+
16
+ def initialize optdata
17
+ super()
18
+ add_as_options optdata
19
+ end
20
+
21
+ def create_fileset files
22
+ fsargs = Hash.new
23
+ fsargs[:max_depth] = @max_depth
24
+ fsargs[:binary_files] = @binary_files
25
+ fsargs[:dir_criteria] = @dir_criteria
26
+ fsargs[:file_criteria] = @file_criteria
27
+ fsargs[:split_as_path] = @split_as_path
28
+
29
+ FileSet.new files, fsargs
30
+ end
31
+
32
+ def set_record_separator sep
33
+ $/ = if sep && sep.to_i > 0
34
+ begin
35
+ sep.oct.chr
36
+ rescue RangeError => e
37
+ # out of range (e.g., 777) means nil:
38
+ nil
39
+ end
40
+ else
41
+ "\n\n"
42
+ end
43
+ end
44
+
45
+ def config_fields
46
+ fields = {
47
+ "binary-files" => binary_files,
48
+ "split-as-path" => @split_as_path,
49
+ }
50
+ fields.merge! @dir_criteria.config_fields
51
+ fields.merge! @file_criteria.config_fields
52
+ end
53
+
54
+ def dump_fields
55
+ fields = {
56
+ "binary_files" => binary_files,
57
+ "directory" => @directory,
58
+ "exclude_matching" => @exclude_matching,
59
+ "split-as-path" => @split_as_path,
60
+ }
61
+ fields.merge! @dir_criteria.dump_fields
62
+ fields.merge! @file_criteria.dump_fields
63
+ fields
64
+ end
65
+
66
+ def update_fields fields
67
+ @dir_criteria.update_fields fields
68
+ @file_criteria.update_fields fields
69
+
70
+ fields.each do |name, value|
71
+ case name
72
+ when 'split-as-path'
73
+ @split_as_path = to_boolean value
74
+ end
75
+ end
76
+ end
77
+
78
+ def set_directory val
79
+ @max_depth = val == 'list' ? 0 : nil
80
+ @dir_criteria.skip_all = val == 'skip'
81
+ # otherwise, it's recurse
82
+ end
83
+
84
+ def add_as_options optdata
85
+ optdata << record_separator_option = {
86
+ :res => [ Regexp.new('^ -0 (\d{1,3})? $ ', Regexp::EXTENDED) ],
87
+ :set => Proc.new { |md| rs = md ? md[1] : 0; set_record_separator rs }
88
+ }
89
+
90
+ @range.add_as_option optdata
91
+
92
+ optdata << recurse_option = {
93
+ :tags => %w{ -r --recurse },
94
+ :set => Proc.new { set_directory("recurse") }
95
+ }
96
+
97
+ optdata << directories_option = {
98
+ :tags => %w{ --directories -d },
99
+ :arg => [ :string ],
100
+ :set => Proc.new { |val| set_directory val },
101
+ }
102
+
103
+ re = Regexp.new '^[\'\"]?(' + VALID_BINARY_FILE_TYPES.join('|') + ')[\'\"]?$'
104
+ optdata << binary_files_option = {
105
+ :tags => %w{ --binary-files },
106
+ :arg => [ :required, :regexp, re ],
107
+ :set => Proc.new { |md| @binary_files = md[1] },
108
+ :rc => %w{ binary-files },
109
+ }
110
+
111
+ @file_criteria.add_as_options optdata
112
+ @dir_criteria.add_as_options optdata
113
+
114
+ add_opt_true optdata, :exclude_matching, %w{ -M --exclude-matching }
115
+
116
+ add_opt_false optdata, :split_as_path, %w{ --no-split-as-path }
117
+ add_opt_true optdata, :split_as_path, %w{ --split-as-path }
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ module Glark
5
+ class RangeError < RuntimeError
6
+ end
7
+
8
+ class Range
9
+ include Loggable, Comparable
10
+
11
+ PCT_RE = Regexp.new '([\.\d]+)%'
12
+
13
+ attr_accessor :from
14
+ attr_accessor :to
15
+
16
+ def initialize from = nil, to = nil
17
+ @from = from
18
+ @to = to
19
+ end
20
+
21
+ def bound?
22
+ @from.nil? && @to.nil?
23
+ end
24
+
25
+ def to_line var, linecount
26
+ return nil unless var
27
+
28
+ if pct = as_pct(var)
29
+ count = linecount
30
+ count * pct.to_f / 100
31
+ else
32
+ var.to_f
33
+ end
34
+ end
35
+
36
+ def as_pct val
37
+ (md = PCT_RE.match(val)) && md[1]
38
+ end
39
+
40
+ def validate!
41
+ return true if @from.nil? || @to.nil?
42
+
43
+ frompct, topct = [ @from, @to ].collect { |val| as_pct val }
44
+
45
+ # both or neither are percentages:
46
+ return true if frompct.nil? != topct.nil?
47
+
48
+ if frompct
49
+ check_range! frompct, topct
50
+ else
51
+ check_range! @from, @to
52
+ end
53
+ true
54
+ end
55
+
56
+ def check_range! from, to
57
+ if from.to_f > to.to_f
58
+ raise RangeError.new "error: range start (#{@from}) follows range end (#{@to})"
59
+ end
60
+ end
61
+
62
+ # there is no nil <=> nil in Ruby
63
+ def compare x, y
64
+ x.nil? && y.nil? ? nil : (x <=> y).nonzero?
65
+ end
66
+
67
+ def <=> other
68
+ compare(from, other.from) || compare(to, other.to) || 0
69
+ end
70
+
71
+ def clear
72
+ @from = nil
73
+ @to = nil
74
+ end
75
+
76
+ def add_as_option optdata
77
+ optdata << range_after_option = {
78
+ :tags => %w{ --after },
79
+ :arg => [ :required, :regexp, %r{ (\d+%?) $ }x ],
80
+ :set => Proc.new { |md| @from = md[1] }
81
+ }
82
+
83
+ optdata << range_before_option = {
84
+ :tags => %w{ --before },
85
+ :arg => [ :required, :regexp, %r{ (\d+%?) $ }x ],
86
+ :set => Proc.new { |md| @to = md[1] }
87
+ }
88
+
89
+ optdata << range_option = {
90
+ :tags => %w{ -R --range },
91
+ :arg => [ :required, :regexp, Regexp.new('(\d+%?),(\d+%?)') ],
92
+ :set => Proc.new do |md, opt, args|
93
+ if md && md[1] && md[2]
94
+ @from = md[1]
95
+ @to = md[2]
96
+ else
97
+ @from = args.shift
98
+ @to = args.shift
99
+ end
100
+ end
101
+ }
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/ruby -w
2
+ #!ruby -w
3
+ # vim: set filetype=ruby : set sw=2
4
+
5
+ require 'glark/input/range'
6
+ require 'glark/input/filter/dir_criteria_opts'
7
+ require 'glark/input/filter/file_criteria_opts'
8
+
9
+ module Glark
10
+ class InputSpec
11
+ VALID_BINARY_FILE_TYPES = [ 'text', 'without-match', 'skip', 'binary', 'list', 'decompress', 'read' ]
12
+
13
+ attr_accessor :binary_files # how to handle binary files
14
+ attr_accessor :directory # read, skip, or recurse, a la grep
15
+ attr_accessor :exclude_matching # exclude files whose names match the expression
16
+ attr_accessor :range # range to start and stop searching; nil => the entire file
17
+ attr_accessor :split_as_path # use file arguments as path elements
18
+
19
+ attr_accessor :dir_criteria
20
+ attr_accessor :file_criteria
21
+ attr_accessor :max_depth
22
+
23
+ def initialize
24
+ @binary_files = 'skip'
25
+ @directory = 'list'
26
+ @exclude_matching = false
27
+
28
+ @range = Range.new
29
+ @split_as_path = true
30
+
31
+ @file_criteria = FileCriteriaOpts.new
32
+ @dir_criteria = DirCriteriaOpts.new nil
33
+
34
+ @max_depth = 0 # list directories
35
+
36
+ $/ = "\n"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'glark/io/file/file'
5
+
6
+ module Glark
7
+ class ArchiveFile
8
+ def initialize fname, range
9
+ @fname = fname
10
+ @range = range
11
+ end
12
+
13
+ def search_list expr, output_cls, output_opts
14
+ contents = StringIO.new list.collect { |x| x + "\n" }.join('')
15
+ contents.rewind
16
+
17
+ file = Glark::File.new @fname, contents, @range
18
+ output_type = output_cls.new file, output_opts
19
+ file.search expr, output_type
20
+ end
21
+
22
+ def list
23
+ contents = Array.new
24
+ each do |entry|
25
+ contents << entry_name(entry)
26
+ end
27
+ contents
28
+ end
29
+
30
+ def each &blk
31
+ reader = get_reader
32
+ reader.each do |entry|
33
+ blk.call entry
34
+ end
35
+ reader.close
36
+ end
37
+
38
+ def search_archive_file expr, entry, output_type_cls, output_opts
39
+ name = entry_name entry
40
+ data = read entry
41
+ contents = StringIO.new data
42
+
43
+ file = Glark::File.new name + " (in #{@fname})", contents, @range
44
+ output = output_type_cls.new file, output_opts
45
+ file.search expr, output
46
+ end
47
+
48
+ def read entry
49
+ entry.read
50
+ end
51
+
52
+ def search expr, output_type_cls, output_opts
53
+ matched = nil
54
+ each do |entry|
55
+ # a glitch with zlib doesn't seem to recognize some tarball entries
56
+ # (with entry.header.typeflag == "") as being a file, so we test for
57
+ # directory:
58
+ next if entry.directory?
59
+ matched = search_archive_file(expr, entry, output_type_cls, output_opts) || matched
60
+ end
61
+ matched
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'glark/io/file/file'
5
+
6
+ module Glark
7
+ class BinaryFile < Glark::File
8
+ def initialize fname
9
+ file = ::File.new fname
10
+ file.binmode # for MSDOS/WinWhatever
11
+ super fname, file, nil
12
+ end
13
+
14
+ def search_as_binary expr, output_opts
15
+ output_type = BinaryFileSummary.new self, output_opts
16
+ search expr, output_type
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/ruby -w
2
+ #!ruby -w
3
+ # vim: set filetype=ruby : set sw=2
4
+
5
+ require 'glark/util/io/lines'
6
+
7
+ module Glark
8
+ # A thing that can be grepped (er, glarked).
9
+ class File
10
+ attr_reader :fname
11
+
12
+ def initialize fname, io, range
13
+ @fname = fname
14
+ @range = range
15
+
16
+ linescls = $/ == "\n" ? Glark::IO::LinesCR : Glark::IO::LinesNonCR
17
+ @lines = linescls.new fname, io
18
+ end
19
+
20
+ def linecount
21
+ @lines.count
22
+ end
23
+
24
+ def each_line &blk
25
+ @lines.each_line(&blk)
26
+ end
27
+
28
+ # Returns the lines for this file, separated by end of line sequences.
29
+ def get_lines
30
+ @lines.get_lines
31
+ end
32
+
33
+ # Returns the given line for this file. For this method, a line ends with a
34
+ # CR, as opposed to the "lines" method, which ends with $/.
35
+ def get_line lnum
36
+ @lines.get_line lnum
37
+ end
38
+
39
+ # Returns the region/range that is represented by the region number.
40
+ def get_region rnum
41
+ @lines.get_region rnum
42
+ end
43
+
44
+ def get_range_start
45
+ @range && @range.from && @range.to_line(@range.from, linecount)
46
+ end
47
+
48
+ def get_range_end
49
+ @range && @range.to && @range.to_line(@range.to, linecount)
50
+ end
51
+
52
+ def search expr, output
53
+ expr.process self, output
54
+ output.matched?
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'glark/io/file/file'
5
+ require 'zlib'
6
+
7
+ module Glark
8
+ class GzFile < Glark::File
9
+ def initialize fname, range, &blk
10
+ if blk
11
+ Zlib::GzipReader.open(fname) do |gz|
12
+ super fname, gz, range
13
+ blk.call [ self, gz ]
14
+ end
15
+ else
16
+ gz = Zlib::GzipReader.new fname
17
+ super fname, gz, range
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'glark/io/file/file'
5
+ require 'glark/io/file/archive_file'
6
+
7
+ module Glark
8
+ class TarFile < ArchiveFile
9
+ def initialize fname, range, io = nil, &blk
10
+ super fname, range
11
+
12
+ # Given that this is a gem, I'm not sure if it is installed with other
13
+ # package managers. So the require is down here, used only if needed.
14
+
15
+ # module Gem::Package is declared in 'rubygems/package', not in
16
+ # .../tar_reader.
17
+ require 'rubygems/package'
18
+ require 'rubygems/package/tar_reader'
19
+ @io = io
20
+ end
21
+
22
+ def get_reader
23
+ io = @io || ::File.new(@fname)
24
+ Gem::Package::TarReader.new io
25
+ end
26
+
27
+ def entry_name entry
28
+ entry.full_name
29
+ end
30
+
31
+ def read entry
32
+ entry.read
33
+ end
34
+ end
35
+ end