gren 0.1.0 → 0.1.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.
data/History.txt CHANGED
@@ -1,6 +1,17 @@
1
+ === 0.2.0 2010/08/xx
2
+
3
+ !!!公開前に...
4
+ 英語にする
5
+ 文章を綺麗にする
6
+
7
+ * --depth, --this で探索する階層数を指定出来るように
8
+ * -sでサイレントモード、マッチした行のみを表示する
9
+ * -f, --if, --idオプションを何個でも設定出来るように
10
+ * -cで色付き表示
11
+
1
12
  === 0.1.0 2010/08/02
2
13
 
3
- * update README.rdoc.
14
+ * Update README.doc (to English).
4
15
 
5
16
  === 0.0.6 2010/07/29
6
17
 
data/Rakefile CHANGED
@@ -18,7 +18,9 @@ $hoe = Hoe.spec 'gren' do
18
18
  self.developer 'ongaeshi', 'ongaeshi0621@gmail.com'
19
19
  self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
20
20
  self.rubyforge_name = self.name # TODO this is default value
21
- # self.extra_deps = [['activesupport','>= 2.0.2']]
21
+
22
+ # 必要とするgem
23
+ self.extra_deps = [['termcolor','>= 1.2.0']]
22
24
 
23
25
  # 本来はnewgemの中で設定されるべき(後で報告した方がいいかも)
24
26
  self.extra_rdoc_files << "README.rdoc"
data/bin/gren CHANGED
@@ -7,5 +7,5 @@ require 'rubygems'
7
7
  require File.expand_path(File.dirname(__FILE__) + "/../lib/gren")
8
8
  require "gren/cli"
9
9
 
10
- Version = "0.0.5"
10
+ Version = "0.1.1"
11
11
  Gren::CLI.execute(STDOUT, ARGV)
data/lib/gren.rb CHANGED
@@ -2,5 +2,5 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  module Gren
5
- VERSION = '0.1.0'
5
+ VERSION = '0.1.1'
6
6
  end
data/lib/gren/cli.rb CHANGED
@@ -6,28 +6,25 @@ module Gren
6
6
  class CLI
7
7
  def self.execute(stdout, arguments=[])
8
8
  # オプション
9
- option = FindGrep::Option.new(false, false, ".", nil, nil)
9
+ option = FindGrep::Option.new(".", -1, false, false, false, false, [], [], [])
10
10
 
11
11
  # オプション解析
12
- opt = OptionParser.new("#{File.basename($0)} [option] pattern [dir]")
12
+ opt = OptionParser.new("#{File.basename($0)} [option] pattern")
13
+ opt.on('-d DIR', '--directory DIR', 'Start directory. (deafult:".")') {|v| option.directory = v}
14
+ opt.on('--depth DEPTH', 'Limit search depth. ') {|v| option.depth = v.to_i}
15
+ opt.on('--this', '"--depth 0"') {|v| option.depth = 0}
13
16
  opt.on('-i', '--ignore', 'Ignore case.') {|v| option.ignoreCase = true}
14
- opt.on('-l', '--listing', 'The searched file name is displayed.') {|v| option.fpathDisp = true}
15
- opt.on('-f REGEXP', '--file-regexp REGEXP', 'Search file regexp. (default: ".")') {|v| option.filePattern = v}
16
- opt.on('--if REGEXP', '--ignore-file REGEXP', 'Ignore file pattern.') {|v| option.ignoreFile = v}
17
- opt.on('--id REGEXP', '--ignore-dir REGEXP', 'Ignore dir pattern.') {|v| option.ignoreDir = v}
17
+ opt.on('-s', '--silent', 'Silent. Display match line only.') {|v| option.isSilent = true}
18
+ opt.on('--debug', 'Debug display.') {|v| option.debugMode = true}
19
+ opt.on('-c', 'Color highlight.') {|v| option.colorHighlight = true}
20
+ opt.on('-f REGEXP', '--file-regexp REGEXP', 'Search file regexp. (Enable multiple call)') {|v| option.filePatterns << v}
21
+ opt.on('--if REGEXP', '--ignore-file REGEXP', 'Ignore file pattern. (Enable multiple call)') {|v| option.ignoreFiles << v}
22
+ opt.on('--id REGEXP', '--ignore-dir REGEXP', 'Ignore dir pattern. (Enable multiple call)') {|v| option.ignoreDirs << v}
18
23
  opt.parse!(arguments)
19
24
 
20
25
  # 検索オブジェクトの生成
21
- findGrep = nil
22
-
23
- case ARGV.length
24
- when 1:
25
- findGrep = FindGrep.new(arguments[0], '.', option)
26
- when 2:
27
- findGrep = FindGrep.new(arguments[0], arguments[1], option)
28
- end
29
-
30
- if (findGrep)
26
+ if (ARGV.size > 0)
27
+ findGrep = FindGrep.new(arguments, option)
31
28
  findGrep.searchAndPrint(stdout)
32
29
  else
33
30
  stdout.print opt.help
data/lib/gren/findgrep.rb CHANGED
@@ -1,80 +1,122 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require 'find'
3
3
  require File.join(File.dirname(__FILE__), 'result')
4
+ require 'rubygems'
5
+ require 'termcolor'
4
6
 
5
7
  module Gren
6
8
  class FindGrep
7
9
  IGNORE_FILE = /(\A#.*#\Z)|(~\Z)|(\A\.#)/
8
10
  IGNORE_DIR = /(\A\.svn\Z)|(\A\.git\Z)|(\ACVS\Z)/
9
11
 
10
- Option = Struct.new(:ignoreCase, :fpathDisp, :filePattern, :ignoreFile, :ignoreDir)
12
+ Option = Struct.new(:directory,
13
+ :depth,
14
+ :ignoreCase,
15
+ :colorHighlight,
16
+ :isSilent,
17
+ :debugMode,
18
+ :filePatterns,
19
+ :ignoreFiles,
20
+ :ignoreDirs)
11
21
 
12
- def initialize(pattern, dir, option)
13
- @pattern = pattern
14
- @dir = dir
22
+ def initialize(patterns, option)
15
23
  @option = option
16
- @fileRegexp = Regexp.new(option.filePattern)
17
- @patternRegexp = makePattenRegexp
18
- @ignoreFile = Regexp.new(option.ignoreFile) if option.ignoreFile
19
- @ignoreDir = Regexp.new(option.ignoreDir) if option.ignoreDir
20
- @result = Result.new(@dir)
24
+ @patternRegexps = strs2regs(patterns, @option.ignoreCase)
25
+ @filePatterns = strs2regs(option.filePatterns)
26
+ @ignoreFiles = strs2regs(option.ignoreFiles)
27
+ @ignoreDirs = strs2regs(option.ignoreDirs)
28
+ @result = Result.new(option.directory)
21
29
  end
22
30
 
23
- def searchAndPrint(stdout)
24
- Find::find(@dir) { |fpath|
25
- fpath_disp = fpath.gsub(/^.\//, "")
26
-
27
- # 除外ディレクトリ
28
- if ignoreDir?(fpath)
29
- @result.prune_dirs << fpath_disp if (@option.fpathDisp)
30
- Find.prune
31
- end
31
+ def strs2regs(strs, ignore = false)
32
+ regs = []
32
33
 
33
- # ファイルでなければ探索しない
34
- next unless FileTest.file?(fpath)
34
+ strs.each do |v|
35
+ option = 0
36
+ option |= Regexp::IGNORECASE if (ignore)
37
+ regs << Regexp.new(v, option)
38
+ end
35
39
 
36
- @result.count += 1
37
-
38
- # 読み込み不可ならば探索しない
39
- unless FileTest.readable?(fpath)
40
- @result.unreadable_files << fpath_disp if (@option.fpathDisp)
41
- next
42
- end
43
-
44
- @result.size += FileTest.size(fpath)
40
+ regs
41
+ end
45
42
 
46
- # 除外ファイル
47
- if ignoreFile?(fpath)
48
- @result.ignore_files << fpath_disp if (@option.fpathDisp)
49
- next
50
- end
51
-
52
- @result.search_count += 1
53
- @result.search_size += FileTest.size(fpath)
43
+ def searchAndPrint(stdout)
44
+ searchAndPrintIN(stdout, @option.directory, 0)
54
45
 
55
- # 検索
56
- searchMain(stdout, fpath, fpath_disp)
57
- }
58
-
59
46
  @result.time_stop
60
47
 
61
- if (@option.fpathDisp)
62
- stdout.puts
63
- stdout.puts "--- search --------"
64
- print_fpaths stdout, @result.search_files
65
- stdout.puts "--- match --------"
66
- print_fpaths stdout, @result.match_files
67
- stdout.puts "--- ignore-file --------"
68
- print_fpaths stdout, @result.ignore_files
69
- stdout.puts "--- ignore-dir --------"
70
- print_fpaths stdout, @result.prune_dirs
71
- stdout.puts "--- unreadable --------"
72
- print_fpaths stdout, @result.unreadable_files
48
+ unless (@option.isSilent)
49
+ if (@option.debugMode)
50
+ stdout.puts
51
+ stdout.puts "--- search --------"
52
+ print_fpaths stdout, @result.search_files
53
+ stdout.puts "--- match --------"
54
+ print_fpaths stdout, @result.match_files
55
+ stdout.puts "--- ignore-file --------"
56
+ print_fpaths stdout, @result.ignore_files
57
+ stdout.puts "--- ignore-dir --------"
58
+ print_fpaths stdout, @result.prune_dirs
59
+ stdout.puts "--- unreadable --------"
60
+ print_fpaths stdout, @result.unreadable_files
61
+ end
62
+
63
+ unless (@option.colorHighlight)
64
+ stdout.puts
65
+ else
66
+ stdout.puts TermColor.parse("<7>------------------------------------------------------------</7>")
67
+ end
68
+
69
+ @result.print(stdout)
73
70
  end
71
+ end
74
72
 
75
- stdout.puts
76
- @result.print(stdout)
73
+ def searchAndPrintIN(stdout, dir, depth)
74
+ if (@option.depth == -1 || depth > @option.depth)
75
+ return
76
+ end
77
+
78
+ Dir.foreach(dir) do |name|
79
+ if name != '.' and name != '..' then
80
+ fpath = File.join(dir,name)
81
+ fpath_disp = fpath.gsub(/^.\//, "")
82
+
83
+ # 除外ディレクトリ
84
+ if ignoreDir?(fpath)
85
+ @result.prune_dirs << fpath_disp if (@option.debugMode)
86
+ next;
87
+ end
88
+
89
+ # ファイルでなければ次のディレクトリへ
90
+ unless FileTest.file?(fpath)
91
+ searchAndPrintIN(stdout, fpath, depth + 1)
92
+ next;
93
+ end
94
+
95
+ @result.count += 1
96
+
97
+ # 読み込み不可ならば探索しない
98
+ unless FileTest.readable?(fpath)
99
+ @result.unreadable_files << fpath_disp if (@option.debugMode)
100
+ next
101
+ end
102
+
103
+ @result.size += FileTest.size(fpath)
104
+
105
+ # 除外ファイル
106
+ if ignoreFile?(fpath)
107
+ @result.ignore_files << fpath_disp if (@option.debugMode)
108
+ next
109
+ end
110
+
111
+ @result.search_count += 1
112
+ @result.search_size += FileTest.size(fpath)
113
+
114
+ # 検索
115
+ searchMain(stdout, fpath, fpath_disp)
116
+ end
117
+ end
77
118
  end
119
+ private :searchAndPrintIN
78
120
 
79
121
  def print_fpaths(stdout, data)
80
122
  stdout.print data.join("\n")
@@ -84,46 +126,67 @@ module Gren
84
126
  end
85
127
  private :print_fpaths
86
128
 
87
- def makePattenRegexp
88
- option = 0
89
- option |= Regexp::IGNORECASE if (@option.ignoreCase)
90
- Regexp.new(@pattern, option)
91
- end
92
- private :makePattenRegexp
93
-
94
129
  def ignoreDir?(fpath)
95
130
  FileTest.directory?(fpath) &&
96
- (IGNORE_DIR.match(File.basename(fpath)) ||
97
- (@ignoreDir && @ignoreDir.match(File.basename(fpath))))
131
+ (IGNORE_DIR.match(File.basename(fpath)) || ignoreDirUser?(fpath))
98
132
  end
99
133
  private :ignoreDir?
100
134
 
135
+ def ignoreDirUser?(fpath)
136
+ @ignoreDirs.any? {|v| v.match File.basename(fpath) }
137
+ end
138
+ private :ignoreDirUser?
139
+
101
140
  def ignoreFile?(fpath)
102
- !@fileRegexp.match(fpath) ||
141
+ !correctFileUser?(fpath) ||
103
142
  IGNORE_FILE.match(File.basename(fpath)) ||
104
- (@ignoreFile && @ignoreFile.match(File.basename(fpath))) ||
143
+ ignoreFileUser?(fpath) ||
105
144
  binary?(fpath)
106
145
  end
107
146
  private :ignoreFile?
108
147
 
148
+ def correctFileUser?(fpath)
149
+ @filePatterns.empty? ||
150
+ @filePatterns.any? {|v| v.match File.basename(fpath) }
151
+ end
152
+ private :correctFileUser?
153
+
154
+ def ignoreFileUser?(fpath)
155
+ @ignoreFiles.any? {|v| v.match File.basename(fpath) }
156
+ end
157
+ private :ignoreFileUser?
158
+
109
159
  def binary?(file)
110
160
  s = File.read(file, 1024) or return false
111
161
  return s.index("\x00")
112
162
  end
113
163
 
114
164
  def searchMain(stdout, fpath, fpath_disp)
115
- @result.search_files << fpath_disp if (@option.fpathDisp)
165
+ @result.search_files << fpath_disp if (@option.debugMode)
116
166
 
117
167
  open(fpath, "r") { |file|
118
168
  match_file = false
119
169
  file.each() { |line|
120
170
  line.chomp!
121
- if (@patternRegexp.match(line))
122
- stdout.puts "#{fpath_disp}:#{file.lineno}:#{line}"
171
+
172
+ result, match_datas = match?(line)
173
+
174
+ if ( result )
175
+ unless (@option.colorHighlight)
176
+ stdout.puts "#{fpath_disp}:#{file.lineno}:#{line}"
177
+ else
178
+ header = "#{fpath_disp}:#{file.lineno}"
179
+
180
+ begin
181
+ stdout.puts TermColor.parse("<34>#{header}</34>:") + coloring(line, match_datas)
182
+ rescue REXML::ParseException
183
+ stdout.puts header + line
184
+ end
185
+ end
123
186
 
124
187
  unless match_file
125
188
  @result.match_file_count += 1
126
- @result.match_files << fpath_disp if (@option.fpathDisp)
189
+ @result.match_files << fpath_disp if (@option.debugMode)
127
190
  match_file = true
128
191
  end
129
192
 
@@ -134,5 +197,20 @@ module Gren
134
197
  end
135
198
  private :searchMain
136
199
 
200
+ def match?(line)
201
+ match_datas = []
202
+ @patternRegexps.each {|v| match_datas << v.match(line)}
203
+ return match_datas.all?, match_datas
204
+ end
205
+ private :match?
206
+
207
+ def coloring(line, match_datas)
208
+ match_datas.each do |m|
209
+ line = line.split(m[0]).join(TermColor.parse("<42>#{m[0]}</42>"))
210
+ end
211
+ line
212
+ end
213
+ private :coloring
214
+
137
215
  end
138
216
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - ongaeshi
@@ -14,13 +14,27 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-03 00:00:00 +09:00
17
+ date: 2010-08-05 00:00:00 +09:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: rubyforge
21
+ name: termcolor
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 0
31
+ version: 1.2.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rubyforge
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
24
38
  requirements:
25
39
  - - ">="
26
40
  - !ruby/object:Gem::Version
@@ -30,11 +44,11 @@ dependencies:
30
44
  - 4
31
45
  version: 2.0.4
32
46
  type: :development
33
- version_requirements: *id001
47
+ version_requirements: *id002
34
48
  - !ruby/object:Gem::Dependency
35
49
  name: hoe
36
50
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
51
+ requirement: &id003 !ruby/object:Gem::Requirement
38
52
  requirements:
39
53
  - - ">="
40
54
  - !ruby/object:Gem::Version
@@ -44,7 +58,7 @@ dependencies:
44
58
  - 1
45
59
  version: 2.6.1
46
60
  type: :development
47
- version_requirements: *id002
61
+ version_requirements: *id003
48
62
  description: gren is a next grep tool.
49
63
  email:
50
64
  - ongaeshi0621@gmail.com