codestock 0.1.0

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.
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