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
data/bin/glark CHANGED
@@ -12,9 +12,9 @@ dir = File.dirname(File.dirname(File.expand_path(__FILE__)))
12
12
  libpath = dir + "/lib"
13
13
  $:.unshift libpath
14
14
 
15
- require 'glark/glark'
15
+ require 'glark/app/app'
16
16
 
17
- Glark.main
17
+ Glark::App.new
18
18
 
19
19
  __END__
20
20
  # prototype of forthcoming feature:
data/lib/glark.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
- require 'glark/glark'
4
+ require 'glark/app/app'
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/ruby -w
2
+ #!ruby -w
3
+ # vim: set filetype=ruby : set sw=2
4
+
5
+ # An extended grep, with extended functionality including full regular
6
+ # expressions, contextual output, highlighting, detection and exclusion of
7
+ # nontext files, and complex matching criteria.
8
+
9
+ require 'glark/app/options'
10
+ require 'glark/app/runner'
11
+
12
+ module Glark
13
+ class App
14
+ def initialize
15
+ begin
16
+ Log.set_widths(-15, -40, -40)
17
+
18
+ opts = AppOptions.new
19
+ opts.run ARGV
20
+
21
+ # To get rid of the annoying stack trace on ctrl-C:
22
+ trap("INT") { abort }
23
+
24
+ if opts.info_options.explain
25
+ puts opts.match_spec.expr.explain
26
+ end
27
+
28
+ files = ARGV.size > 0 ? ARGV : [ '-' ]
29
+ runner = Runner.new opts, files
30
+
31
+ exit runner.exit_status
32
+ rescue => e
33
+ # show the message, and the stack trace only if verbose:
34
+ $stderr.puts "error: #{e}"
35
+ if Log.verbose
36
+ $stderr.puts e.backtrace
37
+ raise
38
+ else
39
+ exit 2
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ if __FILE__ == $0
47
+ Glark::App.new
48
+ end
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ module Glark
5
+ class Help
6
+ def show_usage
7
+ puts "Usage: glark [options] expression file..."
8
+ puts "Search for expression in each file or standard input."
9
+ puts "Example: glark --and=3 'try' 'catch' *.java"
10
+ puts ""
11
+
12
+ puts "Input:"
13
+ puts " -0[nnn] Use \\nnn as the input record separator"
14
+ puts " --before NUM[%] Restrict the search to the top % or lines"
15
+ puts " --after NUM[%] Restrict the search to after the given location"
16
+ puts " -d, --directories=ACTION Process directories as list, skip, or find (recurse)"
17
+ puts " --binary-files=TYPE Treat binary files as TYPE"
18
+ puts " --split-as-path Treat file arguments as paths, to be split into directories and files"
19
+ puts " --match-name EXPR Search only files with names (base names) matching EXPR"
20
+ puts " --not-name EXPR Ignore files with names matching EXPR"
21
+ puts " --match-path EXPR Search only files with paths (full names) matching EXPR"
22
+ puts " --not-path EXPR Ignore files with paths matching EXPR"
23
+ puts " --match-dirname EXPR Search only directories with base names matching EXPR"
24
+ puts " --not-dirname EXPR Ignore directories with names matching EXPR"
25
+ puts " --match-dirpath EXPR Search only directories with full paths matching EXPR"
26
+ puts " --not-dirpath EXPR Ignore directories with full paths matching EXPR"
27
+ puts " -M, --exclude-matching Ignore files with names matching the expression"
28
+ puts " -R, --range NUM[%],NUM[%] Restrict the search to the given range of lines per file."
29
+ puts " -r, --recurse Recurse through directories"
30
+ puts " --size-limit=SIZE Search only files no larger than SIZE"
31
+ puts ""
32
+
33
+ puts "Matching:"
34
+ puts " -a, --and=NUM EXPR1 EXPR2 Match both expressions, within NUM lines"
35
+ puts " --extended Use the given regular expression as extended"
36
+ puts " -f, --file=FILE Use the lines in the given file as expressions"
37
+ puts " -i, --ignore-case Ignore case for matching regular expressions"
38
+ puts " -o, --or EXPR1 EXPR2 Match either of the two expressions"
39
+ puts " -w, --word Match the pattern(s) with word boundaries added"
40
+ puts " -x, --line-regexp Select entire line matching pattern"
41
+ puts " --xor EXPR1 EXPR2 Match either expression, but not both"
42
+ puts ""
43
+
44
+ puts "Output:"
45
+ puts " -A, --after-context=NUM Print NUM lines of trailing context"
46
+ puts " -B, --before-context=NUM Print NUM lines of leading context"
47
+ puts " -C, -NUM, --context[=NUM] Output NUM lines of context"
48
+ puts " -c, --count Display only the match count per file"
49
+ puts " --file-color COLOR Specify the highlight color for file names"
50
+ puts " --no-filter Display the entire file, not only the matching lines"
51
+ puts " -g, --grep Produce output like the grep default"
52
+ puts " -h, --no-filename Do not display the names of matching files"
53
+ puts " -H, --with-filename Display the names of matching files"
54
+ puts " -l, --files-with-matches Print only names of matching file"
55
+ puts " -L, --files-without-match Print only names of file not matching"
56
+ puts " --label=NAME Use NAME as output file name"
57
+ puts " -n, --line-number Display line numbers"
58
+ puts " -N, --no-line-number Do not display line numbers"
59
+ puts " --line-number-color COLOR Specify the highlight color for line numbers"
60
+ puts " -m, --match-limit=NUM Find only the first NUM matches in each file"
61
+ puts " --text-color COLOR Specify the highlight color for text"
62
+ puts " -u, --highlight[=FORMAT] Enable highlighting. Format is single or multi"
63
+ puts " -U, --no-highlight Disable highlighting"
64
+ puts " -v, --invert-match Show lines not matching the expression"
65
+ puts " -y, --extract-matches Display only the matching region, not the entire line"
66
+ puts " -Z, --null In --files-with-matches mode, write file names followed by NULL"
67
+ puts ""
68
+
69
+ puts "Debugging/Errors:"
70
+ puts " --conf Write the current options in RC file format"
71
+ puts " --dump Write all options and expressions"
72
+ puts " --explain Write the expression in a more legible format"
73
+ puts " -q, --quiet Suppress warnings"
74
+ puts " -Q, --no-quiet Enable warnings"
75
+ puts " -s, --no-messages Suppress warnings"
76
+ puts " -V, --version Display version information"
77
+ puts " --verbose Display normally suppressed output"
78
+
79
+ puts ""
80
+ puts "Run gem man glark for more information. That requires the installation of the gem-man gem."
81
+ end
82
+
83
+ def show_man
84
+ pn = Pathname.new __FILE__
85
+
86
+ dir = pn
87
+ 0.upto(3) do
88
+ break unless dir
89
+ dir = dir.parent
90
+ end
91
+
92
+ if dir
93
+ manfile = dir + "man/glark.1"
94
+ cmd = "gem man glark"
95
+ ::IO.popen(cmd) do |io|
96
+ puts io.readlines
97
+ end
98
+ else
99
+ puts "no doc directory"
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/ruby -w
2
+ #!ruby -w
3
+ # vim: set filetype=ruby : set sw=2
4
+
5
+ require 'glark/app/help'
6
+ require 'glark/util/options'
7
+
8
+ module Glark
9
+ PACKAGE = 'glark'
10
+ VERSION = '1.10.0'
11
+
12
+ class InfoOptions < Options
13
+ attr_reader :colors
14
+ attr_reader :explain
15
+
16
+ def initialize colors, optdata
17
+ @colors = colors
18
+ @explain = false # display a legible version of the expression
19
+
20
+ add_as_options optdata
21
+ end
22
+
23
+ def config_fields
24
+ fields = {
25
+ "known-nontext-files" => FileType.nontext_extensions.sort.join(' '),
26
+ "known-text-files" => FileType.text_extensions.sort.join(' '),
27
+ "quiet" => Log.quiet,
28
+ "verbose" => Log.verbose,
29
+ }
30
+ end
31
+
32
+ def dump_fields
33
+ fields = {
34
+ "explain" => @explain,
35
+ "known_nontext_files" => FileType.nontext_extensions.join(", "),
36
+ "known_text_files" => FileType.text_extensions.join(", "),
37
+ "quiet" => Log.quiet,
38
+ "ruby version" => RUBY_VERSION,
39
+ "verbose" => Log.verbose,
40
+ "version" => Glark::VERSION,
41
+ }
42
+ end
43
+
44
+ def update_fields fields
45
+ fields.each do |name, values|
46
+ case name
47
+ when "known-nontext-files"
48
+ values.last.split.each do |ext|
49
+ FileType.set_nontext ext
50
+ end
51
+ when "known-text-files"
52
+ values.last.split.each do |ext|
53
+ FileType.set_text ext
54
+ end
55
+ when "quiet"
56
+ Log.quiet = to_boolean(values.last)
57
+ when "verbose"
58
+ Log.verbose = to_boolean(values.last) ? 1 : nil
59
+ when "verbosity"
60
+ Log.verbose = values.last.to_i
61
+ end
62
+ end
63
+ end
64
+
65
+ def add_as_options optdata
66
+ add_opt_blk(optdata, %w{ -V --version }) { show_version }
67
+ add_opt_blk(optdata, %w{ --verbose }) { Log.verbose = true }
68
+ add_opt_blk(optdata, %w{ -? --help }) { Help.new.show_usage; exit 0 }
69
+ add_opt_blk(optdata, %w{ --man }) { Help.new.show_man; exit 0 }
70
+
71
+ add_opt_true optdata, :explain, %w{ --explain }
72
+
73
+ add_opt_blk(optdata, %w{ -q -s --quiet --messages }) { Log.quiet = true }
74
+ add_opt_blk(optdata, %w{ -Q -S --no-quiet --no-messages }) { Log.quiet = false }
75
+ end
76
+
77
+ def show_version
78
+ puts Glark::PACKAGE + ", version " + Glark::VERSION
79
+ puts "Written by Jeff Pace (jeugenepace@gmail.com)."
80
+ puts "Released under the Lesser GNU Public License."
81
+ exit 0
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel/dir'
6
+ require 'riel/optproc'
7
+ require 'glark/app/info/options'
8
+ require 'glark/app/rcfile'
9
+ require 'glark/app/spec'
10
+ require 'glark/input/options'
11
+ require 'glark/match/options'
12
+ require 'glark/output/options'
13
+ require 'glark/util/colors/options'
14
+ require 'glark/util/options'
15
+ require 'glark/util/optutil'
16
+
17
+ module Glark
18
+ class AppOptions < AppSpec
19
+ include OptionUtil
20
+
21
+ attr_reader :colors
22
+ attr_reader :fileset
23
+ attr_reader :info_options
24
+ attr_reader :output_options
25
+
26
+ def initialize
27
+ optdata = Array.new
28
+
29
+ @colors = ColorOptions.new
30
+
31
+ @input_options = InputOptions.new optdata
32
+ @match_options = MatchOptions.new @colors, optdata
33
+ @output_options = OutputOptions.new @colors, optdata
34
+
35
+ @info_options = InfoOptions.new @colors, optdata
36
+
37
+ add_opt_blk(optdata, %w{ --config }) { write_configuration; exit }
38
+ add_opt_blk(optdata, %w{ --dump }) { dump_all_fields; exit 0 }
39
+
40
+ super @input_options, @match_options, @output_options
41
+
42
+ @optset = OptProc::OptionSet.new optdata
43
+ end
44
+
45
+ def run args
46
+ @args = args
47
+
48
+ read_home_rcfile
49
+
50
+ if @local_config_files
51
+ read_local_rcfiles
52
+ end
53
+
54
+ read_environment_variable
55
+
56
+ # honor thy EMACS; go to grep mode
57
+ if ENV["EMACS"]
58
+ @output_options.style = "grep"
59
+ end
60
+
61
+ read_options
62
+
63
+ validate!
64
+
65
+ @fileset = @input_options.create_fileset @args
66
+
67
+ if @output_options.show_file_names.nil?
68
+ @output_options.show_file_names = @output_options.label || !one_file?
69
+ end
70
+ end
71
+
72
+ def one_file?
73
+ return false if @fileset.size > 1
74
+ first = @fileset.files.first
75
+ first.to_s != '-' && first.file?
76
+ end
77
+
78
+ def read_home_rcfile
79
+ return unless hdir = Dir.home
80
+ hdpn = Pathname.new hdir
81
+ homerc = hdpn + '.glarkrc'
82
+ read_rcfile homerc
83
+ end
84
+
85
+ def read_local_rcfiles
86
+ hdir = Dir.home
87
+ dir = Pathname.new('.').expand_path
88
+ while !dir.root? && dir != hdir
89
+ rcfile = dir + '.glarkrc'
90
+ return if read_rcfile rcfile
91
+ dir = dir.dirname
92
+ end
93
+ end
94
+
95
+ def all_option_sets
96
+ [ @colors, @match_options, @output_options, @info_options, @input_options ]
97
+ end
98
+
99
+ def read_rcfile rcfname
100
+ return nil unless rcfname.exist?
101
+ rcfile = RCFile.new rcfname
102
+ rcvalues = rcfile.names.collect { |name| [ name, rcfile.values(name) ] }
103
+
104
+ all_option_sets.each do |opts|
105
+ opts.update_fields rcvalues
106
+ end
107
+ update_fields rcvalues
108
+ true
109
+ end
110
+
111
+ def config_fields
112
+ fields = {
113
+ "local-config-files" => @local_config_files,
114
+ }
115
+ end
116
+
117
+ def dump_fields
118
+ config_fields
119
+ end
120
+
121
+ def update_fields fields
122
+ fields.each do |name, values|
123
+ case name
124
+ when "local-config-files"
125
+ @local_config_files = to_boolean values.last
126
+ end
127
+ end
128
+ end
129
+
130
+ def read_environment_variable
131
+ options = Env.split "GLARKOPTS"
132
+ while options.size > 0
133
+ @optset.process_option options
134
+ end
135
+ end
136
+
137
+ def read_expression
138
+ if @args.size > 0
139
+ known_end = false
140
+ if @args[0] == "--"
141
+ @args.shift
142
+ known_end = true
143
+ end
144
+
145
+ if @args && @args.size > 0
146
+ return @match_options.read_expression @args, !known_end
147
+ end
148
+ end
149
+
150
+ if @args.size > 0
151
+ raise "No expression provided."
152
+ end
153
+
154
+ $stderr.puts "Usage: glark [options] expression file..."
155
+ $stderr.puts "Try `glark --help' for more information."
156
+ exit 1
157
+ end
158
+
159
+ def read_options
160
+ # solitary "-v" means "--version", not --invert-match
161
+ @info_options.show_version if @args.size == 1 && @args.first == "-v"
162
+
163
+ @match_options.expr = nil
164
+
165
+ nil while @args.size > 0 && @optset.process_option(@args)
166
+
167
+ unless @match_options.expr
168
+ read_expression
169
+ end
170
+ end
171
+
172
+ def write_configuration
173
+ fields = config_fields
174
+ all_option_sets.each do |opts|
175
+ fields.merge! opts.config_fields
176
+ end
177
+
178
+ fields.keys.sort.each do |fname|
179
+ puts "#{fname}: #{fields[fname]}"
180
+ end
181
+ end
182
+
183
+ def dump_all_fields
184
+ fields = dump_fields
185
+ all_option_sets.each do |opts|
186
+ fields.merge! opts.dump_fields
187
+ end
188
+
189
+ len = fields.keys.collect { |f| f.length }.max
190
+
191
+ fields.keys.sort.each do |field|
192
+ printf "%*s : %s\n", len, field, fields[field]
193
+ end
194
+ end
195
+
196
+ # check options for collisions/data validity
197
+ def validate!
198
+ @input_options.range.validate!
199
+ end
200
+ end
201
+ end