codestock 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.document +5 -0
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +18 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +19 -0
  6. data/Rakefile +63 -0
  7. data/VERSION +1 -0
  8. data/bin/cdstk +12 -0
  9. data/bin/cdv +11 -0
  10. data/bin/cdview +11 -0
  11. data/bin/cdweb +11 -0
  12. data/codestock.gemspec +131 -0
  13. data/lib/codestock.rb +0 -0
  14. data/lib/common/dbdir.rb +37 -0
  15. data/lib/common/display_util.rb +62 -0
  16. data/lib/common/grenfiletest.rb +19 -0
  17. data/lib/common/grensnip.rb +37 -0
  18. data/lib/common/platform.rb +17 -0
  19. data/lib/common/string_snip.rb +61 -0
  20. data/lib/common/util.rb +98 -0
  21. data/lib/findgrep/findgrep.rb +408 -0
  22. data/lib/findgrep/result.rb +43 -0
  23. data/lib/gren/cli.rb +65 -0
  24. data/lib/gren.rb +6 -0
  25. data/lib/grendb/cli.rb +43 -0
  26. data/lib/grenweb/cli.rb +54 -0
  27. data/lib/grenweb/database.rb +182 -0
  28. data/lib/grenweb/grenweb.ru +35 -0
  29. data/lib/grenweb/grep.rb +52 -0
  30. data/lib/grenweb/help.rb +40 -0
  31. data/lib/grenweb/home.rb +40 -0
  32. data/lib/grenweb/html_renderer.rb +244 -0
  33. data/lib/grenweb/public/css/gren.css +63 -0
  34. data/lib/grenweb/public/images/gren-icon-mini.png +0 -0
  35. data/lib/grenweb/public/images/gren-icon.png +0 -0
  36. data/lib/grenweb/query.rb +82 -0
  37. data/lib/grenweb/searcher.rb +130 -0
  38. data/lib/grenweb/viewer.rb +52 -0
  39. data/lib/mkgrendb/cli.rb +89 -0
  40. data/lib/mkgrendb/cli_old.rb +49 -0
  41. data/lib/mkgrendb/grendbyaml.rb +76 -0
  42. data/lib/mkgrendb/mkgrendb.rb +296 -0
  43. data/test/file_test_utils.rb +59 -0
  44. data/test/runner.rb +11 -0
  45. data/test/test_dbdir.rb +59 -0
  46. data/test/test_gren.rb +10 -0
  47. data/test/test_gren_util.rb +34 -0
  48. data/test/test_grendbyaml.rb +109 -0
  49. data/test/test_grenweb_cli.rb +10 -0
  50. data/test/test_grenweb_database.rb +37 -0
  51. data/test/test_grenweb_html_renderer.rb +41 -0
  52. data/test/test_grenweb_query.rb +54 -0
  53. data/test/test_grenweb_searcher.rb +35 -0
  54. data/test/test_helper.rb +2 -0
  55. data/test/test_mkgrendb.rb +163 -0
  56. data/test/test_string_snip.rb +31 -0
  57. metadata +229 -0
@@ -0,0 +1,408 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'find'
3
+ require File.join(File.dirname(__FILE__), 'result')
4
+ require 'rubygems'
5
+ require 'termcolor'
6
+ require 'kconv'
7
+ require File.join(File.dirname(__FILE__), '../common/platform')
8
+ require File.join(File.dirname(__FILE__), '../common/grenfiletest')
9
+ require File.join(File.dirname(__FILE__), '../common/grensnip')
10
+ require 'groonga'
11
+ require File.join(File.dirname(__FILE__), '../common/util')
12
+ include Gren
13
+ require 'cgi'
14
+
15
+ module FindGrep
16
+ class FindGrep
17
+ Option = Struct.new(:keywordsNot,
18
+ :keywordsOr,
19
+ :directory,
20
+ :depth,
21
+ :ignoreCase,
22
+ :colorHighlight,
23
+ :isSilent,
24
+ :debugMode,
25
+ :filePatterns,
26
+ :suffixs,
27
+ :ignoreFiles,
28
+ :ignoreDirs,
29
+ :kcode,
30
+ :noSnip,
31
+ :dbFile,
32
+ :groongaOnly,
33
+ :isMatchFile,
34
+ :dispHtml)
35
+
36
+ DEFAULT_OPTION = Option.new([],
37
+ [],
38
+ ".",
39
+ -1,
40
+ false,
41
+ false,
42
+ false,
43
+ false,
44
+ [],
45
+ [],
46
+ [],
47
+ [],
48
+ Platform.get_shell_kcode,
49
+ false,
50
+ nil,
51
+ false,
52
+ false,
53
+ false)
54
+
55
+ attr_reader :documents
56
+
57
+ def initialize(patterns, option)
58
+ @patterns = patterns
59
+ @option = option
60
+ @patternRegexps = strs2regs(patterns, @option.ignoreCase)
61
+ @subRegexps = strs2regs(option.keywordsNot, @option.ignoreCase)
62
+ @orRegexps = strs2regs(option.keywordsOr, @option.ignoreCase)
63
+ @filePatterns = (!@option.dbFile) ? strs2regs(option.filePatterns) : []
64
+ @ignoreFiles = strs2regs(option.ignoreFiles)
65
+ @ignoreDirs = strs2regs(option.ignoreDirs)
66
+ @result = Result.new(option.directory)
67
+ open_database if (@option.dbFile)
68
+ end
69
+
70
+ def open_database()
71
+ # データベース開く
72
+ dbfile = Pathname(File.expand_path(@option.dbFile))
73
+
74
+ if dbfile.exist?
75
+ Groonga::Database.open(dbfile.to_s)
76
+ puts "open : #{dbfile} open."
77
+ else
78
+ raise "error : #{dbfile.to_s} not found!!"
79
+ end
80
+
81
+ # ドキュメントを取
82
+ @documents = Groonga::Context.default["documents"]
83
+ end
84
+
85
+ def strs2regs(strs, ignore = false)
86
+ regs = []
87
+
88
+ strs.each do |v|
89
+ option = 0
90
+ option |= Regexp::IGNORECASE if (ignore)
91
+ regs << Regexp.new(v, option)
92
+ end
93
+
94
+ regs
95
+ end
96
+
97
+ def searchAndPrint(stdout)
98
+ unless (@option.dbFile)
99
+ searchFromDir(stdout, @option.directory, 0)
100
+ else
101
+ searchFromDB(stdout, @option.directory)
102
+ end
103
+
104
+ @result.time_stop
105
+
106
+ if (!@option.isSilent && !@option.dispHtml)
107
+ if (@option.debugMode)
108
+ stdout.puts
109
+ stdout.puts "--- search --------"
110
+ print_fpaths stdout, @result.search_files
111
+ stdout.puts "--- match --------"
112
+ print_fpaths stdout, @result.match_files
113
+ stdout.puts "--- ignore-file --------"
114
+ print_fpaths stdout, @result.ignore_files
115
+ stdout.puts "--- ignore-dir --------"
116
+ print_fpaths stdout, @result.prune_dirs
117
+ stdout.puts "--- unreadable --------"
118
+ print_fpaths stdout, @result.unreadable_files
119
+ end
120
+
121
+ unless (@option.colorHighlight)
122
+ stdout.puts
123
+ else
124
+ stdout.puts HighLine::REVERSE + "------------------------------------------------------------" + HighLine::CLEAR
125
+ end
126
+
127
+ @result.print(stdout)
128
+ end
129
+ end
130
+
131
+ def searchFromDB(stdout, dir)
132
+ # 全てのパターンを検索
133
+ table = @documents.select do |record|
134
+ expression = nil
135
+
136
+ # キーワード
137
+ @patterns.each do |word|
138
+ sub_expression = record.content =~ word
139
+ if expression.nil?
140
+ expression = sub_expression
141
+ else
142
+ expression &= sub_expression
143
+ end
144
+ end
145
+
146
+ # パス
147
+ @option.filePatterns.each do |word|
148
+ sub_expression = record.path =~ word
149
+ if expression.nil?
150
+ expression = sub_expression
151
+ else
152
+ expression &= sub_expression
153
+ end
154
+ end
155
+
156
+ # 拡張子(OR)
157
+ se = suffix_expression(record)
158
+ expression &= se if (se)
159
+
160
+ # 検索式
161
+ expression
162
+ end
163
+
164
+ # タイムスタンプでソート
165
+ records = table.sort([{:key => "_score", :order => "descending"},
166
+ {:key => "timestamp", :order => "descending"}])
167
+
168
+ # データベースにヒット
169
+ stdout.puts "Found : #{records.size} records." unless (@option.dispHtml)
170
+
171
+ # 検索にヒットしたファイルを実際に検索
172
+ records.each do |record|
173
+ if (@option.groongaOnly)
174
+ searchGroongaOnly(stdout, record)
175
+ else
176
+ searchFile(stdout, record.path, record.path) if FileTest.exist?(record.path)
177
+ end
178
+ end
179
+ end
180
+
181
+ def and_expression(key, list)
182
+ sub = nil
183
+
184
+ list.each do |word|
185
+ e = key =~ word
186
+ if sub.nil?
187
+ sub = e
188
+ else
189
+ sub &= e
190
+ end
191
+ end
192
+
193
+ sub
194
+ end
195
+
196
+ def suffix_expression(record)
197
+ sub = nil
198
+
199
+ @option.suffixs.each do |word|
200
+ e = record.suffix =~ word
201
+ if sub.nil?
202
+ sub = e
203
+ else
204
+ sub |= e
205
+ end
206
+ end
207
+
208
+ sub
209
+ end
210
+ private :suffix_expression
211
+
212
+
213
+ def searchFromDir(stdout, dir, depth)
214
+ if (@option.depth != -1 && depth > @option.depth)
215
+ return
216
+ end
217
+
218
+ Dir.foreach(dir) do |name|
219
+ next if (name == '.' || name == '..')
220
+
221
+ fpath = File.join(dir,name)
222
+ fpath_disp = fpath.gsub(/^.\//, "")
223
+
224
+ # 除外ディレクトリならばパス
225
+ if ignoreDir?(fpath)
226
+ @result.prune_dirs << fpath_disp if (@option.debugMode)
227
+ next;
228
+ end
229
+
230
+ # 読み込み不可ならばパス
231
+ unless FileTest.readable?(fpath)
232
+ @result.unreadable_files << fpath_disp if (@option.debugMode)
233
+ next
234
+ end
235
+
236
+ # ファイルならば中身を探索、ディレクトリならば再帰
237
+ case File.ftype(fpath)
238
+ when "directory"
239
+ searchFromDir(stdout, fpath, depth + 1)
240
+ when "file"
241
+ searchFile(stdout, fpath, fpath_disp)
242
+ end
243
+ end
244
+ end
245
+ private :searchFromDir
246
+
247
+ def print_fpaths(stdout, data)
248
+ stdout.print data.join("\n")
249
+ stdout.puts if data.count > 0
250
+ stdout.puts "total: #{data.count}"
251
+ stdout.puts
252
+ end
253
+ private :print_fpaths
254
+
255
+ def ignoreDir?(fpath)
256
+ FileTest.directory?(fpath) &&
257
+ (GrenFileTest::ignoreDir?(File.basename(fpath)) || ignoreDirUser?(fpath))
258
+ end
259
+ private :ignoreDir?
260
+
261
+ def ignoreDirUser?(fpath)
262
+ @ignoreDirs.any? {|v| v.match File.basename(fpath) }
263
+ end
264
+ private :ignoreDirUser?
265
+
266
+ def ignoreFile?(fpath)
267
+ !correctFileUser?(fpath) ||
268
+ GrenFileTest::ignoreFile?(fpath) ||
269
+ ignoreFileUser?(fpath) ||
270
+ GrenFileTest::binary?(fpath)
271
+ end
272
+ private :ignoreFile?
273
+
274
+ def correctFileUser?(fpath)
275
+ @filePatterns.empty? ||
276
+ @filePatterns.any? {|v| v.match File.basename(fpath) }
277
+ end
278
+ private :correctFileUser?
279
+
280
+ def ignoreFileUser?(fpath)
281
+ @ignoreFiles.any? {|v| v.match File.basename(fpath) }
282
+ end
283
+ private :ignoreFileUser?
284
+
285
+ def searchFile(stdout, fpath, fpath_disp)
286
+ @result.count += 1
287
+ @result.size += FileTest.size(fpath)
288
+
289
+ # 除外ファイル
290
+ if ignoreFile?(fpath)
291
+ @result.ignore_files << fpath_disp if (@option.debugMode)
292
+ return
293
+ end
294
+
295
+ @result.search_count += 1
296
+ @result.search_size += FileTest.size(fpath)
297
+
298
+ @result.search_files << fpath_disp if (@option.debugMode)
299
+
300
+ open(fpath, "r") do |file|
301
+ searchData(stdout, file2data(file), fpath_disp)
302
+ end
303
+ end
304
+ private :searchFile
305
+
306
+ def searchGroongaOnly(stdout, record)
307
+ file_size = record.content.size
308
+
309
+ @result.count += 1
310
+ @result.size += file_size
311
+
312
+ @result.search_count += 1
313
+ @result.search_size += file_size
314
+
315
+ @result.search_files << record.path if (@option.debugMode)
316
+
317
+ searchData(stdout, record.content, record.path)
318
+ end
319
+ private :searchGroongaOnly
320
+
321
+ def searchData(stdout, data, path)
322
+ match_file = false
323
+
324
+ data.each_with_index { |line, index|
325
+ result, match_datas = match?(line)
326
+
327
+ if ( result )
328
+ unless (@option.dispHtml)
329
+ header = "#{path}:#{index + 1}:"
330
+ line = GrenSnip::snip(line, match_datas) unless (@option.noSnip)
331
+
332
+ unless (@option.colorHighlight)
333
+ stdout.puts header + line
334
+ else
335
+ stdout.puts HighLine::BLUE + header + HighLine::CLEAR + GrenSnip::coloring(line, match_datas)
336
+ end
337
+ else
338
+ line_no = index + 1
339
+ line = GrenSnip::snip(line, match_datas) unless (@option.noSnip)
340
+
341
+ stdout.puts <<EOF
342
+ <h2><a href="../::view#{path}">#{path}</a></h2>
343
+ <pre>
344
+ #{line_no} : #{CGI.escapeHTML(line)}
345
+ </pre>
346
+ EOF
347
+ end
348
+
349
+ unless match_file
350
+ @result.match_file_count += 1
351
+ @result.match_files << path if (@option.debugMode)
352
+ match_file = true
353
+ break if (@option.isMatchFile)
354
+ end
355
+
356
+ @result.match_count += 1
357
+ end
358
+ }
359
+ end
360
+ private :searchData
361
+
362
+ def file2data(file)
363
+ data = file.read
364
+
365
+ if (@option.kcode != Kconv::NOCONV)
366
+ file_kcode = Kconv::guess(data)
367
+
368
+ if (file_kcode != @option.kcode)
369
+ # puts "encode!! #{fpath} : #{@option.kcode} <- #{file_kcode}"
370
+ data = data.kconv(@option.kcode, file_kcode)
371
+ end
372
+ end
373
+
374
+ data = data.split("\n");
375
+ end
376
+ private :file2data
377
+
378
+ def match?(line)
379
+ match_datas = []
380
+ @patternRegexps.each {|v| match_datas << v.match(line)}
381
+
382
+ sub_matchs = []
383
+ @subRegexps.each {|v| sub_matchs << v.match(line)}
384
+
385
+ or_matchs = []
386
+ @orRegexps.each {|v| or_matchs << v.match(line)}
387
+
388
+ unless (@option.isMatchFile)
389
+ result = match_datas.all? && !sub_matchs.any? && (or_matchs.empty? || or_matchs.any?)
390
+ else
391
+ result = first_condition(match_datas, sub_matchs, or_matchs)
392
+ end
393
+ result_match = match_datas + or_matchs
394
+ result_match.delete(nil)
395
+
396
+ return result, result_match
397
+ end
398
+ private :match?
399
+
400
+ def first_condition(match_datas, sub_matchs, or_matchs)
401
+ unless match_datas.empty?
402
+ match_datas[0]
403
+ else
404
+ or_matchs[0]
405
+ end
406
+ end
407
+ end
408
+ end
@@ -0,0 +1,43 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'find'
3
+ require File.join(File.dirname(__FILE__), '../common/util')
4
+ include Gren
5
+
6
+ module FindGrep
7
+ class Result
8
+ attr_accessor :count
9
+ attr_accessor :search_count
10
+ attr_accessor :match_file_count
11
+ attr_accessor :match_count
12
+ attr_accessor :size
13
+ attr_accessor :search_size
14
+
15
+ attr_accessor :search_files
16
+ attr_accessor :match_files
17
+ attr_accessor :unreadable_files
18
+ attr_accessor :prune_dirs
19
+ attr_accessor :ignore_files
20
+
21
+ def initialize(start_dir)
22
+ @start_dir = File.expand_path(start_dir)
23
+ @count, @search_count, @match_file_count, @match_count, @size, @search_size = 0, 0, 0, 0, 0, 0
24
+ @start_time = Time.now
25
+ @search_files, @match_files, @unreadable_files, @prune_dirs, @ignore_files = [], [], [], [], []
26
+ end
27
+
28
+ def time_stop
29
+ @end_time = Time.now
30
+ end
31
+
32
+ def time
33
+ @end_time - @start_time
34
+ end
35
+
36
+ def print(stdout)
37
+ stdout.puts "dir : #{@start_dir} (#{Util::time_s(time)})"
38
+ stdout.puts "files : #{@search_count} in #{@count} (#{Util::size_s(@search_size)} in #{Util::size_s(@size)})"
39
+ stdout.puts "match : #{@match_file_count} files, #{match_count} hit"
40
+ end
41
+
42
+ end
43
+ end
data/lib/gren/cli.rb ADDED
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'optparse'
3
+ require File.join(File.dirname(__FILE__), '../findgrep/findgrep')
4
+
5
+ module Gren
6
+ class CLI
7
+ def self.execute(stdout, arguments=[])
8
+ # オプション
9
+ option = FindGrep::FindGrep::DEFAULT_OPTION
10
+
11
+ # オプション解析
12
+ opt = OptionParser.new("#{File.basename($0)} [option] pattern")
13
+ opt.on('--not PATTERN', 'Keyword is not included.') {|v| option.keywordsNot << v}
14
+ opt.on('--or PATTERN', 'Either of keyword is contained.') {|v| option.keywordsOr << v}
15
+ opt.on('-d DIR', '--directory DIR', 'Start directory. (deafult:".")') {|v| option.directory = v}
16
+ opt.on('--depth DEPTH', 'Limit search depth. ') {|v| option.depth = v.to_i}
17
+ opt.on('--this', '"--depth 0"') {|v| option.depth = 0}
18
+ opt.on('-i', '--ignore', 'Ignore case.') {|v| option.ignoreCase = true}
19
+ opt.on('-s', '--silent', 'Silent. Display match line only.') {|v| option.isSilent = true}
20
+ opt.on('--debug', 'Debug display.') {|v| option.debugMode = true}
21
+ opt.on('-c', '--color', 'Color highlight.') {|v| option.colorHighlight = true}
22
+ opt.on('-f REGEXP', '--file-regexp REGEXP', 'Search file regexp. (Enable multiple call)') {|v| option.filePatterns << v}
23
+ opt.on('--if REGEXP', '--ignore-file REGEXP', 'Ignore file pattern. (Enable multiple call)') {|v| option.ignoreFiles << v}
24
+ opt.on('--id REGEXP', '--ignore-dir REGEXP', 'Ignore dir pattern. (Enable multiple call)') {|v| option.ignoreDirs << v}
25
+ opt.on('-e ENCODE', '--encode ENCODE', 'Specify encode(none, auto, jis, sjis, euc, ascii, utf8, utf16). Default is "auto"') {|v| setupEncodeOption(option, v) }
26
+ opt.on('--no-snip', 'There being a long line, it does not snip.') {|v| option.noSnip = true }
27
+ opt.parse!(arguments)
28
+
29
+ # 検索オブジェクトの生成
30
+ if (arguments.size > 0 || option.keywordsOr.size > 0)
31
+ findGrep = FindGrep::FindGrep.new(arguments, option)
32
+ findGrep.searchAndPrint(stdout)
33
+ else
34
+ stdout.print opt.help
35
+ end
36
+
37
+ end
38
+
39
+ def self.setupEncodeOption(option, encode)
40
+ case encode.downcase
41
+ when 'none'
42
+ option.kcode = Kconv::NOCONV
43
+ when 'auto'
44
+ option.kcode = Platform.get_shell_kcode
45
+ when 'jis'
46
+ option.kcode = Kconv::JIS
47
+ when 'sjis'
48
+ option.kcode = Kconv::SJIS
49
+ when 'euc'
50
+ option.kcode = Kconv::EUC
51
+ when 'ascii'
52
+ option.kcode = Kconv::ASCII
53
+ when 'utf8'
54
+ option.kcode = Kconv::UTF8
55
+ when 'utf16'
56
+ option.kcode = Kconv::UTF16
57
+ else
58
+ puts "Invalid encode."
59
+ puts " none, auto, jis, sjis, euc, ascii, utf8, utf16"
60
+ exit(-1)
61
+ end
62
+ end
63
+
64
+ end
65
+ end
data/lib/gren.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Gren
5
+ VERSION = '0.3.2'
6
+ end
data/lib/grendb/cli.rb ADDED
@@ -0,0 +1,43 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'optparse'
3
+ require File.join(File.dirname(__FILE__), '../findgrep/findgrep')
4
+ require File.join(File.dirname(__FILE__), '../common/dbdir')
5
+ include CodeStock
6
+
7
+ module Grendb
8
+ class CLI
9
+ def self.execute(stdout, arguments=[])
10
+ # オプション
11
+ option = FindGrep::FindGrep::DEFAULT_OPTION
12
+ option.dbFile = db_groonga_path(db_default_dir)
13
+
14
+ # デフォルトのマッチモードは'File'
15
+ option.isMatchFile = true
16
+
17
+ # オプション解析
18
+ opt = OptionParser.new("#{File.basename($0)} [option] keyword1 [keyword2 ...]")
19
+ opt.on('--db [GREN_DB_FILE]', 'Search from the grendb database.') {|v| option.dbFile = db_groonga_path(v) }
20
+ opt.on('-f KEYWORD', '--file-keyword KEYWORD', 'Path keyword. (Enable multiple call)') {|v| option.filePatterns << v}
21
+ opt.on('-s SUFFIX', '--suffix SUFFIX', 'Search suffix.') {|v| option.suffixs << v }
22
+ opt.on('-i', '--ignore', 'Ignore case.') {|v| option.ignoreCase = true}
23
+ opt.on('-c', '--color', 'Color highlight.') {|v| option.colorHighlight = true}
24
+ opt.on('--no-snip', 'There being a long line, it does not snip.') {|v| option.noSnip = true }
25
+ opt.on('-g', '--groonga-only', 'Search only groonga db.') {|v| option.groongaOnly = true }
26
+ opt.on('--mf', '--match-file', 'Match file. (Default)') {|v| option.isMatchFile = true }
27
+ opt.on('-l', '--ml', '--match-line', 'Match line, same mode as "gren".') {|v| option.isMatchFile = false }
28
+
29
+ opt.parse!(arguments)
30
+
31
+ # 検索オブジェクトの生成
32
+ if (option.dbFile && (arguments.size > 0 || option.keywordsOr.size > 0))
33
+ findGrep = FindGrep::FindGrep.new(arguments, option)
34
+ findGrep.searchAndPrint(stdout)
35
+ else
36
+ stdout.print opt.help
37
+ stdout.puts
38
+ stdout.puts "please set GREN DATABSE FILE!! (--db option, or set ENV['GRENDB_DEFAULT_DB'].)" unless option.dbFile
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'optparse'
4
+ require 'fileutils'
5
+ require File.join(File.dirname(__FILE__), 'database')
6
+ require File.join(File.dirname(__FILE__), '../common/dbdir')
7
+ include CodeStock
8
+ require 'rack'
9
+ require 'launchy'
10
+
11
+ module Grenweb
12
+ class CLI
13
+ def self.execute(stdout, arguments=[])
14
+ option = {
15
+ :Port => 9292,
16
+ :DbDir => db_default_dir,
17
+ }
18
+
19
+ opt = OptionParser.new("#{File.basename($0)}")
20
+ opt.on('--db DB_DIR', 'Database dir (default : ~/.codestock)') {|v| option[:DbDir] = v }
21
+ opt.on('-p', '--port PORT', 'use PORT (default: 9292)') {|v| option[:Port] = v }
22
+ opt.on('--no-browser', 'No launch browser.') {|v| option[:NoBrowser] = true }
23
+ opt.parse!(arguments)
24
+
25
+ # webサーバー起動
26
+ stdout.puts <<EOF
27
+ Start up grenweb !!
28
+ URL : http://localhost:#{option[:Port]}
29
+ DB : #{option[:DbDir]}
30
+ ----------------------------------------
31
+ EOF
32
+
33
+ # 使用するデータベースの位置設定
34
+ Database.setup(option[:DbDir])
35
+
36
+ # サーバースクリプトのある場所へ移動
37
+ FileUtils.cd(File.dirname(__FILE__))
38
+
39
+ # ブラウザ起動
40
+ Launchy.open("http://localhost:#{option[:Port]}") unless (option[:NoBrowser])
41
+
42
+ # サーバー起動
43
+ Rack::Server.start(
44
+ :environment => "development",
45
+ :pid => nil,
46
+ :Port => option[:Port],
47
+ :Host => "0.0.0.0",
48
+ :AccessLog => [],
49
+ :config => "grenweb.ru"
50
+ )
51
+
52
+ end
53
+ end
54
+ end