gren 0.1.0 → 0.1.1

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