Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'develop'

  • Loading branch information...
commit ea23589303155b047370b605867ba4b53f108ae9 2 parents b4675d1 + d450ef6
@ongaeshi authored
Showing with 1,452 additions and 527 deletions.
  1. +1 −1  VERSION
  2. +1 −1  bin/gmilk
  3. +1 −1  bin/milk
  4. +337 −117 lib/milkode/cdstk/cdstk.rb
  5. +0 −140 lib/milkode/cdstk/cdstk_yaml.rb
  6. +27 −9 lib/milkode/cdstk/cli_cdstk.rb
  7. +44 −6 lib/milkode/cdstk/cli_cdstksub.rb
  8. +105 −0 lib/milkode/cdstk/milkode_yaml.rb
  9. +83 −0 lib/milkode/cdstk/package.rb
  10. +94 −0 lib/milkode/cdstk/yaml_file_wrapper.rb
  11. +6 −28 lib/milkode/cdweb/app.rb
  12. +6 −0 lib/milkode/cdweb/lib/database.rb
  13. +28 −0 lib/milkode/cdweb/lib/grep.rb
  14. +2 −0  lib/milkode/cdweb/lib/mkurl.rb
  15. +49 −10 lib/milkode/cdweb/lib/search_contents.rb
  16. +2 −6 lib/milkode/cdweb/views/filelist.haml
  17. +5 −0 lib/milkode/cdweb/views/header_menu.haml
  18. +4 −8 lib/milkode/cdweb/views/search.haml
  19. +22 −0 lib/milkode/cdweb/views/search_form.haml
  20. +2 −6 lib/milkode/cdweb/views/view.haml
  21. +34 −0 lib/milkode/common/ignore_checker.rb
  22. +62 −0 lib/milkode/common/ignore_setting.rb
  23. +10 −9 lib/milkode/grep/cli_grep.rb
  24. +42 −0 test/data/.gitignore
  25. +1 −0  test/data/no_auto_ignore/.gitignore
  26. +3 −0  test/data/no_auto_ignore/a.txt
  27. +2 −2 test/milkode_test_work.rb
  28. +17 −12 test/test_cdstk.rb
  29. +0 −167 test/test_cdstk_yaml.rb
  30. +4 −4 test/test_database.rb
  31. +26 −0 test/test_ignore_checker.rb
  32. +113 −0 test/test_ignore_setting.rb
  33. +149 −0 test/test_milkode_yaml.rb
  34. +73 −0 test/test_package.rb
  35. +97 −0 test/test_yaml_file_wrapper.rb
View
2  VERSION
@@ -1 +1 @@
-0.4.0
+0.5.0
View
2  bin/gmilk
@@ -6,5 +6,5 @@
require 'rubygems'
require 'milkode/grep/cli_grep'
-Version = "0.4.0"
+Version = "0.5.0"
Milkode::CLI_Grep.execute(STDOUT, ARGV)
View
2  bin/milk
@@ -6,5 +6,5 @@
require 'rubygems'
require 'milkode/cdstk/cli_cdstk'
-Version = "0.4.0"
+Version = "0.5.0"
Milkode::CLI_Cdstk.execute(STDOUT, ARGV)
View
454 lib/milkode/cdstk/cdstk.rb
@@ -6,7 +6,6 @@
require 'groonga'
require 'fileutils'
require 'pathname'
-require 'milkode/cdstk/cdstk_yaml'
require 'milkode/common/grenfiletest'
require 'milkode/common/util'
require 'milkode/common/dir'
@@ -19,9 +18,16 @@
end
require 'milkode/cdweb/lib/database'
require 'open-uri'
+
require 'milkode/cdstk/cdstk_command'
+require 'milkode/cdstk/yaml_file_wrapper'
+require 'milkode/cdstk/package'
+require 'milkode/common/ignore_checker'
+
module Milkode
+ class IgnoreError < RuntimeError ; end
+
class Cdstk
# バイグラムでトークナイズする。連続する記号・アルファベット・数字は一語として扱う。
# DEFAULT_TOKENIZER = "TokenBigram"
@@ -36,7 +42,9 @@ def initialize(io = $stdout, db_dir = ".")
Database.setup(@db_dir)
@out = io
# @out = $stdout # 強制出力
+ @is_display_info = false # alert_info の表示
clear_count
+ @yaml = YamlFileWrapper.load_if(@db_dir)
end
def clear_count
@@ -47,11 +55,12 @@ def clear_count
@start_time = Time.now
end
- def init
+ def init(options)
if Dir.emptydir?(@db_dir)
- CdstkYaml.create(@db_dir)
+ @yaml = YamlFileWrapper.create(@db_dir)
@out.puts "create : #{yaml_file}"
db_create(db_file)
+ setdb([@db_dir], {}) if (options[:setdb])
else
@out.puts "Can't create milkode db (Because not empty in #{db_dir_expand})"
end
@@ -63,38 +72,43 @@ def compatible?
def update_all
print_result do
- yaml = yaml_load
-
db_open(db_file)
- yaml.list.each do |content|
- update_dir_in(content["directory"])
+ @yaml.contents.each do |package|
+ update_dir_in(package.directory)
end
end
end
def update(args, options)
+ update_display_info(options)
+
if (options[:all])
update_all
else
if (args.empty?)
path = File.expand_path('.')
- package = yaml_load.package_root( path )
+ package = @yaml.package_root(path)
if (package)
print_result do
db_open(db_file)
- update_dir_in(package["directory"])
+ update_dir_in(package.directory)
end
else
@out.puts "Not registered. If you want to add, 'milk add #{path}'."
end
else
print_result do
- update_list = yaml_load.list CdstkYaml::Query.new(args)
db_open(db_file)
- update_list.each do |content|
- update_dir_in(content["directory"])
+ args.each do |name|
+ package = @yaml.find_name(name)
+ if (package)
+ update_dir_in(package.directory)
+ else
+ @out.puts "Not found package '#{name}'."
+ return
+ end
end
end
end
@@ -110,45 +124,81 @@ def update_dir(dir)
update_dir_in(dir)
end
- def add(contents)
- # YAMLを読み込み
- yaml = yaml_load
+ def add(dirs, options)
+ update_display_info(options)
- # コンテンツを読み込める形に変換
- begin
- contents.map!{|v|convert_content(v)}
- rescue ConvetError
- return
- end
+ print_result do
+ # データベースを開く
+ db_open(db_file)
- # 存在しないコンテンツがあった場合はその場で終了
- contents.each do |v|
- shortname = File.basename v
+ # メイン処理
+ begin
+ dirs.each do |v|
+ # コンテンツを読み込める形に変換
+ dir = convert_content(v)
- if (yaml.cant_add_directory? v)
- error_alert("already exist '#{shortname}'.")
- return
- end
-
- unless (File.exist? v)
- error_alert("not found '#{v}'.")
+ # YAMLに追加
+ package = Package.create(dir, options[:ignore])
+ add_yaml(package)
+ set_yaml_options(package, options)
+
+ # アップデート
+ update_dir(dir)
+ end
+ rescue ConvetError
return
end
end
+ end
- # YAML更新
- yaml.add(contents)
- yaml.save
+ def set_yaml_options(package, src)
+ is_dirty = false
+
+ if src[:no_auto_ignore]
+ dst = package.options
+ dst[:no_auto_ignore] = true
+ package.set_options(dst)
+ is_dirty = true
+ end
- # 部分アップデート
- print_result do
- db_open(db_file)
- contents.each do |dir|
- update_dir(dir)
- end
+ if src[:name]
+ dst = package.options
+ dst[:name] = src[:name]
+ package.set_options(dst)
+ is_dirty = true
+ end
+
+ if is_dirty
+ @yaml.update(package)
+ @yaml.save
end
end
+ def add_dir(dir, no_yaml = false)
+ add_yaml(Package.create(dir)) unless no_yaml
+ db_open(db_file)
+ update_dir(dir)
+ end
+
+ # yamlにパッケージを追加
+ def add_yaml(package)
+ # すでに同名パッケージがある
+ if @yaml.find_name(package.name)
+ error_alert("already exist '#{package.name}'.")
+ return
+ end
+
+ # ファイルが存在しない
+ unless File.exist?(package.directory)
+ error_alert("not found '#{package.directory}'.")
+ return
+ end
+
+ # YAML更新
+ @yaml.add(package)
+ @yaml.save
+ end
+
def convert_content(src)
# httpファイルならダウンロード
begin
@@ -208,34 +258,51 @@ def download_file_in(url)
filename
end
- def remove(args, options)
- print_result do
- db_open(db_file)
-
- yaml = yaml_load
- query = CdstkYaml::Query.new(args)
-
- remove_list = yaml_load.list(query)
- return if remove_list.empty?
+ def remove_all
+ print_result do
+ list([], {:verbose => true})
- list(args, {:verbose => true})
-
- if options[:force] or yes_or_no("Remove #{remove_list.size} contents? (yes/no)")
- # yamlから削除
- yaml.remove(query)
- yaml.save
-
- # データベースからも削除
- packages = remove_list.map{|v| File.basename v['directory']}
+ if yes_or_no("Remove #{@yaml.contents.size} contents? (yes/no)")
+ db_open(db_file)
- # 本当はパッケージの配列をまとめて渡した方が効率が良いのだが、表示を綺麗にするため
- packages.each do |package|
- alert("rm_package", package)
- @package_count += 1
-
- Database.instance.remove([package]) do |record|
- alert("rm_record", record.path)
- @file_count += 1
+ @yaml.contents.each do |package|
+ remove_dir(package.directory)
+ end
+ else
+ return
+ end
+ end
+ end
+
+ def remove(args, options)
+ update_display_info(options)
+
+ if (options[:all])
+ remove_all
+ else
+ if (args.empty?)
+ path = File.expand_path('.')
+ package = @yaml.package_root(path)
+
+ if (package)
+ print_result do
+ db_open(db_file)
+ remove_dir(package.directory)
+ end
+ else
+ @out.puts "Not registered. '#{path}'."
+ end
+ else
+ print_result do
+ db_open(db_file)
+ args.each do |name|
+ package = @yaml.find_name(name)
+ if (package)
+ remove_dir(package.directory)
+ else
+ @out.puts "Not found package '#{name}'."
+ return
+ end
end
end
end
@@ -261,17 +328,20 @@ def yes_or_no(msg)
end
def list(args, options)
- query = (args.empty?) ? nil : CdstkYaml::Query.new(args)
- a = yaml_load.list(query).map {|v| [File.basename(v['directory']), v['directory']] }
- max = a.map{|v|v[0].length}.max
- str = a.sort_by {|v|
- v[0]
- }.map {|v|
- h = File.exist?(v[1]) ? '' : '? '
+ match_p = @yaml.contents.find_all do |p|
+ args.all? {|k| p.name.include? k }
+ end
+
+ max = match_p.map{|p| p.name.length}.max
+
+ str = match_p.sort_by {|p|
+ p.name
+ }.map {|p|
+ h = File.exist?(p.directory) ? '' : '? '
if (options[:verbose])
- "#{(h + v[0]).ljust(max+2)} #{v[1]}"
+ "#{(h + p.name).ljust(max+2)} #{p.directory}"
else
- "#{h}#{v[0]}"
+ "#{h}#{p.name}"
end
}.join("\n")
@@ -281,7 +351,7 @@ def list(args, options)
if args.empty?
milkode_info
else
- list_info(a) unless a.empty?
+ list_info(match_p) unless match_p.empty?
end
end
@@ -289,7 +359,13 @@ def pwd(options)
dir = options[:default] ? Dbdir.default_dir : db_dir_expand
if File.exist? dir
- @out.puts dir
+ if options[:default]
+ @out.puts dir
+ else
+ package = @yaml.package_root(File.expand_path('.'))
+ name = package ? package.name : "'not_package_dir'"
+ @out.puts "#{name} in #{dir}"
+ end
else
@out.puts "Not found db in #{Dir.pwd}"
end
@@ -303,14 +379,12 @@ def cleanup(options)
if (options[:force] or yes_or_no("cleanup contents? (yes/no)"))
print_result do
# yamlファイルのクリーンアップ
- yaml = yaml_load
-
- yaml.cleanup do |v|
- alert("rm_package", v['directory'])
+ @yaml.contents.find_all {|v| !File.exist? v.directory }.each do |p|
+ @yaml.remove(p)
+ alert("rm_package", p.directory)
@package_count += 1
end
-
- yaml.save
+ @yaml.save
# データベースのクリーンアップ
Database.instance.cleanup do |record|
@@ -321,10 +395,43 @@ def cleanup(options)
end
end
- def rebuild
- db_delete(db_file)
- db_create(db_file)
- update_all
+ def rebuild(args, options)
+ update_display_info(options)
+
+ if (options[:all])
+ db_delete(db_file)
+ db_create(db_file)
+ update_all
+ else
+ if (args.empty?)
+ path = File.expand_path('.')
+ package = @yaml.package_root(path)
+
+ if (package)
+ print_result do
+ db_open(db_file)
+ remove_dir(package.directory, true)
+ add_dir(package.directory, true)
+ end
+ else
+ @out.puts "Not registered. '#{path}'."
+ end
+ else
+ print_result do
+ args.each do |name|
+ package = @yaml.find_name(name)
+ if (package)
+ db_open(db_file)
+ remove_dir(package.directory, true)
+ add_dir(package.directory, true)
+ else
+ @out.puts "Not found package '#{name}'."
+ return
+ end
+ end
+ end
+ end
+ end
end
def dump
@@ -345,20 +452,22 @@ def dump
end
def dir(args, options)
- yaml = yaml_load
-
if args.empty?
path = File.expand_path('.')
- package = yaml.package_root(path)
+ package = @yaml.package_root(path)
if (package)
- @out.print package['directory'] + (options[:top] ? "" : "\n")
+ @out.print package.directory + (options[:top] ? "" : "\n")
else
# Use mcd.
@out.print "Not registered." + (options[:top] ? "" : "\n")
end
else
- dirs = yaml.list(CdstkYaml::Query.new(args)).map{|v|v['directory']}.reverse
+ match_p = @yaml.contents.find_all do |p|
+ args.all? {|k| p.name.include? k }
+ end
+
+ dirs = match_p.map{|v|v.directory}.reverse
if options[:top]
unless (dirs.empty?)
@@ -427,6 +536,61 @@ def info(args, options)
milkode_info
end
+ def ignore(args, options)
+ current_dir = File.expand_path('.')
+
+ if (options[:package])
+ package = @yaml.find_name(options[:package])
+ raise IgnoreError, "Not found package '#{options[:package]}'." unless package
+ else
+ package = @yaml.package_root(current_dir)
+ raise IgnoreError, "Not a package dir: '#{current_dir}'" unless package
+ end
+
+ if options[:test]
+ # Test mode
+ db_open(db_file)
+ @is_display_info = true
+ @is_silent = true
+ update_dir(package.directory)
+ elsif options[:delete_all]
+ # Delete all
+ package.set_ignore([])
+ @yaml.update(package)
+ @yaml.save
+ elsif args.empty?
+ # Display ignore settting
+ @out.puts package.ignore
+ else
+ # Add or Delete
+ if options[:package]
+ add_ignore = args.map {|v| v.sub(/^.\//, "") }
+ else
+ path = Util::relative_path(File.expand_path('.'), package.directory).to_s
+ add_ignore = args.map {|v| File.join(path, v).sub(/^.\//, "") }
+ end
+
+ ignore = package.ignore
+
+ if options[:delete]
+ ignore -= add_ignore
+ else
+ ignore += add_ignore
+ end
+ ignore.uniq!
+ package.set_ignore(ignore)
+
+ @yaml.update(package)
+ @yaml.save
+
+ if options[:delete]
+ @out.puts add_ignore.map{|v| "Delete : #{v}"}
+ else
+ @out.puts add_ignore.map{|v| "Add : #{v}"}
+ end
+ end
+ end
+
private
def db_file
@@ -446,11 +610,7 @@ def custom_db?
end
def yaml_file
- CdstkYaml.yaml_file @db_dir
- end
-
- def yaml_load
- CdstkYaml.load(@db_dir)
+ YamlFileWrapper.yaml_file @db_dir
end
def update_dir_in(dir)
@@ -468,6 +628,25 @@ def update_dir_in(dir)
end
end
+ def remove_dir(dir, no_yaml = false)
+ # yamlから削除
+ unless (no_yaml)
+ @yaml.remove(@yaml.find_dir(dir))
+ @yaml.save
+ end
+
+ # データベースからも削除
+ dir = File.expand_path(dir)
+
+ alert("rm_package", dir)
+ @package_count += 1
+
+ Database.instance.remove([File.basename(dir)]) do |record|
+ alert_info("rm_record", record.path)
+ @file_count += 1
+ end
+ end
+
def time
@end_time - @start_time
end
@@ -492,7 +671,7 @@ def result_info
end
def milkode_info
- alert('*milkode*', "#{yaml_load.package_num} packages, #{Database.instance.totalRecords} records in #{db_file}.")
+ alert('*milkode*', "#{@yaml.contents.size} packages, #{Database.instance.totalRecords} records in #{db_file}.")
end
def db_create(filename)
@@ -513,7 +692,7 @@ def list_info(packages)
option = FindGrep::FindGrep::DEFAULT_OPTION.dup
option.dbFile = Dbdir.groonga_path(Dbdir.default_dir)
option.isSilent = true
- option.packages = packages.map{|v| v[1]}
+ option.packages = packages.map{|p| p.directory}
findGrep = FindGrep::FindGrep.new([], option)
records = findGrep.pickupRecords
@@ -565,12 +744,18 @@ def db_delete(filename)
end
private :db_delete
- def db_add_dir(dirname)
- searchDirectory(STDOUT, dirname, File.basename(dirname), 0)
+ def db_add_dir(dir)
+ @current_package = @yaml.package_root(dir)
+ @current_ignore = IgnoreChecker.new
+ @current_ignore.add IgnoreSetting.new("/", @current_package.ignore) # 手動設定
+ searchDirectory(STDOUT, dir, @current_package.name, "/", 0)
end
private :db_add_dir
def db_add_file(stdout, filename, shortpath)
+ # サイレントモード
+ return if @is_silent
+
# ファイル名を全てUTF-8に変換
filename_utf8 = Util::filename_to_utf8(filename)
shortpath_utf8 = Util::filename_to_utf8(shortpath)
@@ -610,27 +795,31 @@ def db_add_file(stdout, filename, shortpath)
if (key == :path)
if (isNewFile)
@add_count += 1
- alert("add_record", value)
+ alert_info("add_record", value)
else
@update_count += 1
- alert("update", value)
+ alert_info("update", value)
end
end
document[key] = value
end
end
-
end
- def searchDirectory(stdout, dir, shortdir, depth)
- Dir.foreach(dir) do |name|
+ def searchDirectory(stdout, dirname, packname, path, depth)
+ # 現在位置に.gitignoreがあれば無視設定に加える
+ add_current_gitignore(dirname, path) unless @current_package.options[:no_auto_ignore]
+
+ # 子の要素を追加
+ Dir.foreach(File.join(dirname, path)) do |name|
next if (name == '.' || name == '..')
-
- fpath = File.join(dir,name)
- shortpath = File.join(shortdir,name)
-
+
+ next_path = File.join(path, name)
+ fpath = File.join(dirname, next_path)
+ shortpath = File.join(packname, next_path)
+
# 除外ディレクトリならばパス
- next if ignoreDir?(fpath)
+ next if ignoreDir?(fpath, next_path)
# 読み込み不可ならばパス
next unless FileTest.readable?(fpath)
@@ -638,9 +827,9 @@ def searchDirectory(stdout, dir, shortdir, depth)
# ファイルならば中身を探索、ディレクトリならば再帰
case File.ftype(fpath)
when "directory"
- searchDirectory(stdout, fpath, shortpath, depth + 1)
+ searchDirectory(stdout, dirname, packname, next_path, depth + 1)
when "file"
- unless ignoreFile?(fpath)
+ unless ignoreFile?(fpath, next_path)
db_add_file(stdout, fpath, shortpath)
@file_count += 1
# @out.puts "file_count : #{@file_count}" if (@file_count % 100 == 0)
@@ -649,15 +838,38 @@ def searchDirectory(stdout, dir, shortdir, depth)
end
end
- def ignoreDir?(fpath)
+ def add_current_gitignore(dirname, path)
+ git_ignore = File.join(dirname, path, ".gitignore")
+
+ if File.exist? git_ignore
+ alert_info("add_ignore", git_ignore)
+
+ open(git_ignore) do |f|
+ @current_ignore.add IgnoreSetting.create_from_gitignore(path, f.read)
+ end
+ end
+ end
+
+ def package_ignore?(fpath, mini_path)
+ if @current_ignore.ignore?(mini_path)
+ alert_info("ignore", fpath)
+ true
+ else
+ false
+ end
+ end
+
+ def ignoreDir?(fpath, mini_path)
FileTest.directory?(fpath) &&
- GrenFileTest::ignoreDir?(fpath)
+ (GrenFileTest::ignoreDir?(fpath) ||
+ package_ignore?(fpath, mini_path))
end
private :ignoreDir?
- def ignoreFile?(fpath)
+ def ignoreFile?(fpath, mini_path)
GrenFileTest::ignoreFile?(fpath) ||
- GrenFileTest::binary?(fpath)
+ GrenFileTest::binary?(fpath) ||
+ package_ignore?(fpath, mini_path)
end
private :ignoreFile?
@@ -669,6 +881,10 @@ def alert(title, msg)
end
end
+ def alert_info(title, msg)
+ alert(title, msg) if @is_display_info
+ end
+
def error_alert(msg)
@out.puts "[fatal] #{msg}"
end
@@ -688,5 +904,9 @@ def db_compatible?
exit -1
end
end
+
+ def update_display_info(options)
+ @is_display_info = true if (options[:verbose])
+ end
end
end
View
140 lib/milkode/cdstk/cdstk_yaml.rb
@@ -1,140 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# @file
-# @brief
-# @author ongaeshi
-# @date 2011/02/20
-
-require 'yaml'
-require 'pathname'
-require 'milkode/common/dbdir'
-
-module Milkode
- class CdstkYaml
- class YAMLAlreadyExist < RuntimeError
- end
-
- class YAMLNotExist < RuntimeError
- end
-
- def self.create(path = ".")
- yf = yaml_file(path)
- raise YAMLAlreadyExist.new if FileTest.exist? yf
- obj = CdstkYaml.new(yf, {'contents' => [], 'version' => 0.1})
- obj.save
- return obj
- end
-
- def self.load(path = ".")
- yf = yaml_file(path)
- raise YAMLNotExist.new unless FileTest.exist? yf
- open(yf) do |f|
- return CdstkYaml.new(yf, YAML.load(f.read()))
- end
- end
-
- def initialize(yaml_file, data)
- @yaml_file = yaml_file
- @data = data
- normalize
- end
-
- def normalize
- if (Util::platform_win?)
- contents.each do |v|
- v['directory'] = Util::normalize_filename v['directory']
- end
- end
- end
-
- def add(dirs)
- contents.concat(dirs.map{|v|{'directory' => v}})
- contents.uniq!
- end
-
- def remove(query)
- r = query.select_any?(contents)
- r.each {|v| contents.delete v}
- end
-
- def save
- open(@yaml_file, "w") { |f| YAML.dump(@data, f) }
- end
-
- def contents
- @data['contents']
- end
-
- def package_num
- @data['contents'].size
- end
-
- def directorys
- contents.map{|v|v['directory']}
- end
-
- def version
- @data['version']
- end
-
- def list(query = nil)
- query ? query.select_all?(contents) : contents
- end
-
- def exist?(shortname)
- @data['contents'].find {|v| File.basename(v['directory']) == shortname }
- end
-
- def cant_add_directory?(dir)
- @data['contents'].find {|v|
- v['directory'] != File.expand_path(dir) &&
- File.basename(v['directory']) == File.basename(dir)
- }
- end
-
- def cleanup
- contents.delete_if do |v|
- if (!File.exist? v['directory'])
- yield v if block_given?
- true
- else
- false
- end
- end
- end
-
- def package_root(dir)
- nd = Util::normalize_filename dir
- @data['contents'].find do |v|
- v if nd =~ /^#{v['directory']}/
- end
- end
-
- def package_root_dir(dir)
- package = package_root(dir)
- (package) ? package['directory'] : nil
- end
-
- def self.yaml_file(path)
- Dbdir.yaml_path(path)
- end
-
- class Query
- def initialize(keywords)
- @keywords = keywords
- end
-
- def select_any?(contents)
- contents.find_all do |v|
- @keywords.any? {|s| File.basename(v['directory']).include? s }
- end
- end
-
- def select_all?(contents)
- contents.find_all do |v|
- @keywords.all? {|s| File.basename(v['directory']).include? s }
- end
- end
- end
- end
-end
View
36 lib/milkode/cdstk/cli_cdstk.rb
@@ -19,6 +19,7 @@ def self.execute(stdout, arguments=[])
dir Disp package dir.
dump Dump records.
grep Print lines matching a pattern
+ ignore Ignore setting.
info Disp information.
init Init db.
list List packages.
@@ -49,35 +50,40 @@ def self.subcommand_default(stdout, opt, subcommand, arguments)
suboptions = Hash.new
subopt['init'], suboptions['init'] = CLI_Cdstksub.setup_init
- subopt['add'] = CLI_Cdstksub.setup_add
+ subopt['add'], suboptions['add'] = CLI_Cdstksub.setup_add
subopt['update'], suboptions['update'] = CLI_Cdstksub.setup_update
subopt['remove'], suboptions['remove'] = CLI_Cdstksub.setup_remove
subopt['list'], suboptions['list'] = CLI_Cdstksub.setup_list
subopt['pwd'], suboptions['pwd'] = CLI_Cdstksub.setup_pwd
subopt['cleanup'], suboptions['cleanup'] = CLI_Cdstksub.setup_cleanup
- subopt['rebuild'] = OptionParser.new("#{File.basename($0)} rebuild")
+ subopt['rebuild'], suboptions['rebuild'] = CLI_Cdstksub.setup_rebuild
subopt['dump'] = OptionParser.new("#{File.basename($0)} dump")
subopt['web'], suboptions['web'] = CLI_Cdstksub.setup_web
subopt['dir'], suboptions['dir'] = CLI_Cdstksub.setup_dir
subopt['setdb'], suboptions['setdb'] = CLI_Cdstksub.setup_setdb
subopt['mcd'], suboptions['mcd'] = CLI_Cdstksub.setup_mcd
subopt['info'], suboptions['info'] = CLI_Cdstksub.setup_info
+ subopt['ignore'], suboptions['ignore'] = CLI_Cdstksub.setup_ignore
if (subopt[subcommand])
subopt[subcommand].parse!(arguments) unless arguments.empty?
init_default = suboptions['init'][:init_default]
- db_dir = select_dbdir(subcommand, init_default)
+ db_dir = select_dbdir(subcommand, init_default, arguments)
obj = Cdstk.new(stdout, db_dir)
case subcommand
when 'init'
- FileUtils.mkdir_p db_dir if (init_default)
- obj.init
+ if (arguments.size <= 1)
+ FileUtils.mkdir_p db_dir if (init_default || init_specify_dbddir?(arguments))
+ obj.init(suboptions[subcommand])
+ else
+ $stderr.puts "milk init [db_dir] (Cannot specify two 'db_dir')"
+ end
when 'update'
obj.update(arguments, suboptions[subcommand])
when 'add'
- obj.add(arguments)
+ obj.add(arguments, suboptions[subcommand])
when 'remove'
obj.remove(arguments, suboptions[subcommand])
when 'list'
@@ -87,7 +93,7 @@ def self.subcommand_default(stdout, opt, subcommand, arguments)
when 'cleanup'
obj.cleanup(suboptions[subcommand])
when 'rebuild'
- obj.rebuild
+ obj.rebuild(arguments, suboptions[subcommand])
when 'dump'
obj.dump
when 'web'
@@ -101,6 +107,12 @@ def self.subcommand_default(stdout, opt, subcommand, arguments)
obj.mcd(arguments, suboptions[subcommand])
when 'info'
obj.info(arguments, suboptions[subcommand])
+ when 'ignore'
+ begin
+ obj.ignore(arguments, suboptions[subcommand])
+ rescue IgnoreError => e
+ stdout.puts e.message
+ end
end
else
if subcommand
@@ -111,9 +123,11 @@ def self.subcommand_default(stdout, opt, subcommand, arguments)
end
end
- def self.select_dbdir(subcommand, init_default)
+ def self.select_dbdir(subcommand, init_default, arguments)
if (subcommand == 'init')
- if (init_default)
+ if (init_specify_dbddir?(arguments))
+ arguments[0]
+ elsif (init_default)
Dbdir.default_dir
else
'.'
@@ -126,6 +140,10 @@ def self.select_dbdir(subcommand, init_default)
end
end
end
+
+ def self.init_specify_dbddir?(arguments)
+ arguments.size == 1
+ end
end
end
View
50 lib/milkode/cdstk/cli_cdstksub.rb
@@ -10,8 +10,9 @@ class CLI_Cdstksub
def self.setup_init
options = {:init_default => false}
- opt = OptionParser.new("#{File.basename($0)} init")
+ opt = OptionParser.new("#{File.basename($0)} init [db_dir]")
opt.on('--default', 'Init default db, ENV[\'MILKODE_DEFAULT_DIR\'] or ~/.milkode.') { options[:init_default] = true }
+ opt.on('-s', '--setdb', 'With setdb.') { options[:setdb] = true }
return opt, options
end
@@ -19,8 +20,10 @@ def self.setup_init
def self.setup_add
bin = File.basename($0)
+ options = {:ignore => []}
+
opt = OptionParser.new(<<EOF)
-#{bin} add package1 [package2 ...]
+#{bin} add dir1 [dir2 ...]
usage:
#{bin} add /path/to/dir1
#{bin} add /path/to/dir2 /path/to/dir3
@@ -28,9 +31,15 @@ def self.setup_add
#{bin} add /path/to/zipfile.zip
#{bin} add /path/to/addon.xpi
#{bin} add http://example.com/urlfile.zip
+
+option:
EOF
+ # opt.on('-n NAME', '--name NAME', 'Specify name (default: File.basename(dir))') {|v| options[:name] = v }
+ opt.on('-i PATH', '--ignore PATH', 'Ignore path.') {|v| options[:ignore] << v }
+ opt.on('--no-auto-ignore', 'Disable auto ignore (.gitignore)') { options[:no_auto_ignore] = true }
+ opt.on('-v', '--verbose', 'Be verbose.') { options[:verbose] = true }
- opt
+ return opt, options
end
def self.setup_update
@@ -38,6 +47,7 @@ def self.setup_update
opt = OptionParser.new("#{File.basename($0)} update [keyword1 keyword2 ...]")
opt.on('--all', 'Update all.') { options[:all] = true }
+ opt.on('-v', '--verbose', 'Be verbose.') { options[:verbose] = true }
return opt, options
end
@@ -45,8 +55,10 @@ def self.setup_update
def self.setup_remove
options = {:force => false}
- opt = OptionParser.new("#{File.basename($0)} remove package1 [package2 ...]")
- opt.on('-f', '--force', 'Force remove.') { options[:force] = true }
+ opt = OptionParser.new("#{File.basename($0)} remove keyword1 [keyword2 ...]")
+ opt.on('--all', 'Update all.') { options[:all] = true }
+ opt.on('-f', '--force', 'Force remove.') { options[:force] = true }
+ opt.on('-v', '--verbose', 'Be verbose.') { options[:verbose] = true }
return opt, options
end
@@ -78,6 +90,16 @@ def self.setup_cleanup
return opt, options
end
+ def self.setup_rebuild
+ options = {}
+
+ opt = OptionParser.new("#{File.basename($0)} keyword1 [keyword2 ...]")
+ opt.on('--all', 'Rebuild all.') { options[:all] = true}
+ opt.on('-v', '--verbose', 'Be verbose.') { options[:verbose] = true }
+
+ return opt, options
+ end
+
def self.setup_web
options = {
:environment => ENV['RACK_ENV'] || "development",
@@ -121,7 +143,7 @@ def self.setup_setdb
options = {}
opt = OptionParser.new("#{File.basename($0)} setdb")
- opt.on('--reset', 'Reset default db.') {|v| options[:reset] = true }
+ opt.on('--default', '--reset', 'Reset default db.') {|v| options[:reset] = true }
return opt, options
end
@@ -141,5 +163,21 @@ def self.setup_info
return opt, options
end
+
+ def self.setup_ignore
+ bin = File.basename($0)
+
+ options = {}
+
+ opt = OptionParser.new("#{File.basename($0)} ignore [path ...]")
+ opt.on('-p PACKAGE', '--package PACKAGE', 'Specify ignore package.') {|v| options[:package] = v }
+ opt.on('-d', '--delete', 'Delete ignore') { options[:delete] = true }
+ opt.on('--delete-all', 'Delete all') { options[:delete_all] = true }
+ opt.on('--test', 'Ignore test, Display complete list') { options[:test] = true }
+
+ return opt, options
+ end
+
+
end
end
View
105 lib/milkode/cdstk/milkode_yaml.rb
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+#
+# @file
+# @brief
+# @author ongaeshi
+# @date 2012/02/21
+
+require 'yaml'
+require 'milkode/cdstk/package'
+require 'milkode/common/util'
+
+module Milkode
+ class MilkodeYaml
+ MILKODE_YAML_VERSION = '0.2'
+
+ EMPTY_YAML = <<EOF
+---
+version: '#{MILKODE_YAML_VERSION}'
+contents: []
+EOF
+
+ attr_reader :contents
+
+ def initialize(str = nil)
+ @data = YAML.load(str || EMPTY_YAML)
+ @contents = parse_contents
+ end
+
+ def dump
+ YAML.dump(@data)
+ end
+
+ def version
+ @data['version']
+ end
+
+ # パッケージを追加
+ def add(package)
+ @contents.push package
+ update_contents
+ end
+
+ # 同名パッケージの内容を置き換え
+ def update(package)
+ i = @contents.find_index {|v| v.same_name?(package.name) }
+ raise unless i
+ @contents[i] = package
+ update_contents
+ end
+
+ # パッケージを削除
+ def remove(package)
+ @contents.delete(package)
+ update_contents
+ end
+
+ # 名前が同じパッケージを検索
+ def find_name(name)
+ @contents.find {|v| v.same_name?(name)}
+ end
+
+ # ディレクトリ名が同じパッケージを検索
+ def find_dir(directory)
+ @contents.find {|v| v.directory == directory}
+ end
+
+ # 指定ディレクトリの所属するパッケージのルートディレクトリを得る。
+ # 見つからない場合はnilを返す。
+ def package_root(dir)
+ nd = Util::normalize_filename dir
+ @contents.find do |v|
+ v if nd =~ /^#{v.directory}/
+ end
+ end
+
+ # マイグレーション
+ def migrate
+ if (version != MILKODE_YAML_VERSION)
+ # バージョン番号
+ @data['version'] = MILKODE_YAML_VERSION
+
+ # パッケージ
+ contents.each{|v| v.migrate}
+
+ # migrateが起きた
+ true
+ else
+ false
+ end
+ end
+
+ private
+
+ def parse_contents
+ @data['contents'].map do |v|
+ Package.new(v)
+ end
+ end
+
+ def update_contents
+ @data['contents'] = @contents.map{|v| v.hash }
+ end
+ end
+end
+
View
83 lib/milkode/cdstk/package.rb
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+#
+# @file
+# @brief
+# @author ongaeshi
+# @date 2012/02/21
+
+require 'milkode/common/util'
+
+module Milkode
+ class Package
+ def self.create(dir, ignore=nil)
+ if ignore && ignore.size > 0
+ Package.new({"directory" => dir, "ignore" => ignore})
+ else
+ Package.new({"directory" => dir})
+ end
+ end
+
+ def initialize(hash)
+ @hash = hash
+ normalize
+ end
+
+ def name
+ if options[:name]
+ options[:name]
+ else
+ File.basename(directory)
+ end
+ end
+
+ def directory
+ @hash['directory']
+ end
+
+ def ignore
+ @hash['ignore'] || []
+ end
+
+ def set_ignore(ignore)
+ @hash['ignore'] = ignore
+ end
+
+ def options
+ @hash['options'] || {}
+ end
+
+ def set_options(options)
+ @hash['options'] = options
+ end
+
+ def hash
+ @hash
+ end
+
+ def migrate
+ # 色々あって、ignore値はデフォルトで設定しないようにした
+ # @hash['ignore'] = [] unless ignore
+ end
+
+ # 同名パッケージか?
+ def same_name?(a_name)
+ name == a_name
+ end
+
+ # 同値検査
+ def ==(rhs)
+ name == rhs.name && directory == rhs.directory && ignore == rhs.ignore
+ end
+
+ private
+
+ def normalize
+ if (Util::platform_win?)
+ @hash['directory'] = Util::normalize_filename(directory)
+ end
+ end
+
+ end
+end
+
+
View
94 lib/milkode/cdstk/yaml_file_wrapper.rb
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+#
+# @file
+# @brief
+# @author ongaeshi
+# @date 2011/02/20
+
+require 'yaml'
+require 'milkode/common/dbdir'
+require 'milkode/cdstk/milkode_yaml'
+
+module Milkode
+ class YamlFileWrapper
+ class YAMLAlreadyExist < RuntimeError ; end
+ class YAMLNotExist < RuntimeError ; end
+
+ def self.yaml_file(path)
+ Dbdir.yaml_path(path)
+ end
+
+ def self.create(path = ".")
+ yf = yaml_file(path)
+ raise YAMLAlreadyExist.new if FileTest.exist? yf
+ obj = YamlFileWrapper.new(yf, MilkodeYaml.new)
+ obj.save
+ return obj
+ end
+
+ def self.load(path = ".")
+ yf = yaml_file(path)
+ raise YAMLNotExist.new unless FileTest.exist? yf
+ open(yf) do |f|
+ return YamlFileWrapper.new(yf, MilkodeYaml.new(f.read()))
+ end
+ end
+
+ def self.load_if(path = ".")
+ begin
+ load(path)
+ rescue YAMLNotExist
+ nil
+ end
+ end
+
+ def initialize(yaml_file, data)
+ @yaml_file = yaml_file
+ @data = data
+ migrate
+ end
+
+ def contents
+ @data.contents
+ end
+
+ def find_name(name)
+ @data.find_name(name)
+ end
+
+ def find_dir(dir)
+ @data.find_dir(dir)
+ end
+
+ def add(package)
+ @data.add package
+ end
+
+ def update(package)
+ @data.update package
+ end
+
+ def remove(package)
+ @data.remove package
+ end
+
+ def package_root(dir)
+ @data.package_root(dir)
+ end
+
+ def save
+ open(@yaml_file, "w") { |f| f.write(@data.dump) }
+ end
+
+ def version
+ @data.version
+ end
+
+ def migrate
+ if (@data.migrate)
+ puts "milkode.yaml is old '#{version}'. Convert to '#{MilkodeYaml::MILKODE_YAML_VERSION}'."
+ save
+ end
+ end
+ end
+end
View
34 lib/milkode/cdweb/app.rb
@@ -18,7 +18,7 @@
set :haml, :format => :html5
get '/' do
- @version = "0.4.0"
+ @version = "0.5.0"
@package_num = Database.instance.fileList('').size
@file_num = Database.instance.fileNum
haml :index
@@ -73,38 +73,16 @@ def link(query)
"<a href='#{'/home?query=' + escape_url(query)}'>#{query}</a>"
end
- def create_form(path, query, shead)
- shead = shead || 'directory'
-
- # こっちにすると'検索'ボタンを押した時に新しくウィンドウが開く
- # <form action='' target='_blank' method='post'>
- <<EOF
- <script type="text/javascript">
- function set_pathname() {
- document.searchform.pathname.value = location.pathname;
- }
- </script>
- <form name="searchform" action='/search' method='post'>
- <p>
- <input name='query' size='60' type='text' value='#{query}' />
- <input type='submit' value='検索' onclick='set_pathname()'><br></input>
- #{create_radio('all', shead)}
- <label>全体を検索</label>
- #{create_radio('package', shead)}
- <label> #{package_name(path)} 以下</label>
- #{create_radio('directory', shead)}
- <label> #{current_name(path)} 以下</label>
- <input name='pathname' type='hidden' value=''></input>
- </p>
- </form>
-EOF
- end
-
def create_radio(value, shead)
str = (value == shead) ? 'checked' : ''
"<input name='shead' type='radio' value='#{value}' #{str}/>"
end
+ def create_checkbox(name, value)
+ str = (value) ? 'checked' : ''
+ "<input type='checkbox' name='#{name}' value='on' #{str}/>"
+ end
+
def create_headmenu(path, query, flistpath = '')
href = Mkurl.new('/home/' + path, params).inherit_query_shead
flist = File.join("/home/#{path}", flistpath)
View
6 lib/milkode/cdweb/lib/database.rb
@@ -212,6 +212,12 @@ def searchMain(patterns, packages, fpaths, suffixs, offset, limit)
:offset => offset,
:limit => limit)
+ # ファイル名でソート
+ # @todo 本当はこっちが望ましい
+ # records = table.sort([{:key => "shortpath", :order => "ascending"}],
+ # :offset => offset,
+ # :limit => limit)
+
# パッケージの条件追加
if (packages.size > 0)
records.delete_if do |record|
View
28 lib/milkode/cdweb/lib/grep.rb
@@ -12,6 +12,34 @@ def initialize(content)
end
MatchLineResult = Struct.new(:index, :match_datas)
+
+ def match_lines_stopover(patterns, max_match, start_index)
+ result = []
+ patternRegexps = strs2regs(patterns, true)
+ index = start_index
+
+ lines = @content.split($/)
+
+ while (index < lines.size) do
+ line = lines[index]
+
+ match_datas = []
+ patternRegexps.each {|v| match_datas << v.match(line)}
+
+ if (match_datas.all?)
+ result << MatchLineResult.new(index, match_datas)
+ if result.size >= max_match
+ index += 1
+ break
+ end
+ end
+
+ index += 1
+ end
+
+ index = 0 if (index >= lines.size)
+ {:result => result, :next_line => index}
+ end
def match_lines_and(patterns)
result = []
View
2  lib/milkode/cdweb/lib/mkurl.rb
@@ -46,7 +46,9 @@ def query_param(query_inherit, shead_inherit, offset_inherit)
qparam = []
qparam << "query=#{escape(@params[:query])}" if (query_inherit and @params[:query])
qparam << "shead=#{escape(@params[:shead])}" if (shead_inherit and @params[:shead])
+ qparam << "onematch=#{escape(@params[:onematch])}" if (shead_inherit and @params[:onematch])
qparam << "offset=#{escape(@params[:offset])}" if (offset_inherit and @params[:offset])
+ qparam << "line=#{escape(@params[:line])}" if (offset_inherit and @params[:line])
qparam.join('&')
end
end
View
59 lib/milkode/cdweb/lib/search_contents.rb
@@ -32,6 +32,8 @@ def initialize(path, params, query)
@q = query
@page = params[:page].to_i || 0
@offset = params[:offset].to_i
+ @line = params[:line].to_i
+ @is_onematch = params[:onematch]
fpaths = @q.fpaths
fpaths << path + "/" unless path == ""
@records, @total_records, @elapsed = Database.instance.search(@q.keywords, @q.packages, fpaths, @q.suffixs, @offset, LIMIT_NUM)
@@ -47,7 +49,7 @@ def next_offset
end
def data_range
- @offset..(next_offset - 1)
+ @offset..(@offset + @end_index)
end
def html_contents
@@ -60,7 +62,7 @@ def html_pagination
return <<EOF
<div class='pagination'>
-#{pagination_link(next_offset, "next >>")}
+#{pagination_link(next_offset, @next_line, "next >>")}
</div>
EOF
end
@@ -75,22 +77,58 @@ def match_num
def grep_contents
@match_records = []
- @next_index = @records.size
-
+ @end_index = @next_index = @records.size
+ @next_line = nil
+
@records.each_with_index do |record, index|
if (Util::larger_than_oneline(record.content))
- grep = Grep.new(record.content)
- match_line = grep.one_match_and(@q.keywords)
- @match_records << MatchRecord.new(record, match_line) if match_line
+
+ if @is_onematch
+ grep = Grep.new(record.content)
+ match_line = grep.one_match_and(@q.keywords)
+ @match_records << MatchRecord.new(record, match_line) if match_line
+
+ if @match_records.size >= DISP_NUM
+ @end_index = index
+ @next_index = index + 1
+ break
+ end
+ else
+ break if grep_match_lines_stopover(record, index)
+ end
else
@match_records << MatchRecord.new(record, Grep::MatchLineResult.new(0, nil))
+
+ if @match_records.size >= DISP_NUM
+ @end_index = index
+ @next_index = index + 1
+ break
+ end
end
+ end
+ end
- if @match_records.size >= DISP_NUM
+ def grep_match_lines_stopover(record, index)
+ grep = Grep.new(record.content)
+ r = grep.match_lines_stopover(@q.keywords, DISP_NUM - @match_records.size, (index == 0) ? @line : 0)
+
+ r[:result].each do |match_line|
+ @match_records << MatchRecord.new(record, match_line) if match_line
+ end
+
+ if @match_records.size >= DISP_NUM
+ if (r[:next_line] == 0)
+ @end_index = index
@next_index = index + 1
- break
+ else
+ @end_index = index
+ @next_index = index
+ @next_line = r[:next_line]
end
+ return true
end
+
+ return false
end
def result_match_record(match_record)
@@ -112,9 +150,10 @@ def result_match_record(match_record)
EOS
end
- def pagination_link(offset, label)
+ def pagination_link(offset, line, label)
tmpp = @params
tmpp[:offset] = offset.to_s
+ tmpp[:line] = line.to_s
href = Mkurl.new("", tmpp).inherit_query_shead_offset
pagination_span("<a href='#{href}' rel='next'>#{label}</a>")
end
View
8 lib/milkode/cdweb/views/filelist.haml
@@ -1,11 +1,7 @@
-.header
- %h1
- <a href="/"><img src="/images/MilkodeIcon135.png" alt="milkode-icon-mini" border="0" height="75px"/></a>
- Milkode
- = create_headmenu(@path, params)
+= haml :header_menu
.content
- = create_form(@path, params[:query], params[:shead])
+ = haml :search_form
.search-summary
<span class="keyword">#{topic_path(@path, params)}</span> <span class="total-entries">#{@total_records}</span>件(#{@elapsed}秒)
View
5 lib/milkode/cdweb/views/header_menu.haml
@@ -0,0 +1,5 @@
+.header
+ %h1
+ <a href="/"><img src="/images/MilkodeIcon135.png" alt="milkode-icon-mini" border="0" height="75px"/></a>
+ Milkode
+ = create_headmenu(@path, params, defined?(flistpath) ? flistpath : '')
View
12 lib/milkode/cdweb/views/search.haml
@@ -1,16 +1,12 @@
-.header
- %h1
- <a href="/"><img src="/images/MilkodeIcon135.png" alt="milkode-icon-mini" border="0" height="75px"/></a>
- Milkode
- = create_headmenu(@path, params)
+= haml :header_menu
.content
- = create_form(@path, params[:query], params[:shead])
+ = haml :search_form
.search-summary
<span class="keyword">#{topic_path(@path, params)}</span>
- <span class="hit-num">#{@total_records}</span>件ヒット中</span>
- <span class="search-range">#{@range.first}番から#{@range.last - @range.first + 1}件を検索</span>
+ <span class="hit-num">#{@total_records}</span>ファイル中</span>
+ <span class="search-range">#{@range.first} - #{@range.last}ファイルを検索</span>
<span class="match-num">#{@match_num}</span>件マッチ</span>
(#{@elapsed}秒)
View
22 lib/milkode/cdweb/views/search_form.haml
@@ -0,0 +1,22 @@
+:javascript
+ function set_pathname() {
+ document.searchform.pathname.value = location.pathname;
+ }
+%form(name="searchform" action="/search" method="post")
+ %p
+ %input(name="query" size="60" type="text"){:value => params[:query]}
+ %input(type="submit" value="検索" onclick="set_pathname()")
+ %br
+ %label
+ = create_radio('all', params[:shead])
+ 全体を検索
+ %label
+ = create_radio('package', params[:shead])
+ = package_name(@path) + '以下'
+ %label
+ = create_radio('directory', params[:shead])
+ = current_name(@path) + '以下'
+ %label
+ = create_checkbox('onematch', params[:onematch])
+ = '1ファイル1マッチ'
+ %input(name="pathname" type="hidden" value="")
View
8 lib/milkode/cdweb/views/view.haml
@@ -1,11 +1,7 @@
-.header
- %h1
- <a href="/"><img src="/images/MilkodeIcon135.png" alt="milkode-icon-mini" border="0" height="75px"/></a>
- Milkode
- = create_headmenu(@path, params, '..')
+= haml :header_menu, locals => {:flistpath => '..'}
.content
- = create_form(@path, params[:query], params[:shead])
+ = haml :search_form
.search-summary
<span class="keyword">#{topic_path(@path, params)}</span>(#{@elapsed}秒)
View
34 lib/milkode/common/ignore_checker.rb
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+#
+# @file
+# @brief
+# @author ongaeshi
+# @date 2012/03/02
+
+require 'milkode/common/ignore_setting.rb'
+
+module Milkode
+ #
+ # Sample:
+ # c = IgnoreChecker.new
+ # c.add IgnoreSetting.new("/", ["/rdoc", "/test/data", "*.lock"])
+ # c.add IgnoreSetting.new("/pkg", ["*.gem"])
+ # c.ignore?('/lib/test.rb') #=> false
+ # c.ignore?('/pkg/hoge.gem') #=> true
+ #
+ class IgnoreChecker
+ attr_reader :settings
+
+ def initialize
+ @settings = []
+ end
+
+ def add(setting)
+ @settings << setting
+ end
+
+ def ignore?(path)
+ @settings.any?{|s| s.ignore? path }
+ end
+ end
+end
View
62 lib/milkode/common/ignore_setting.rb
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+#
+# @file
+# @brief
+# @author ongaeshi
+# @date 2012/03/02
+
+module Milkode
+ class IgnoreSetting
+ attr_reader :path
+ attr_reader :ignores
+
+ def self.create_from_gitignore(path, str)
+ IgnoreSetting.new(path, parse_gitignore(str))
+ end
+
+ def self.parse_gitignore(str)
+ ignores = str.split($/)
+ ignores.delete_if{|v| v =~ /(\A#.*)|(\A\Z)/}
+ ignores
+ end
+
+ def initialize(path, ignores)
+ @path = path
+ @ignores = ignores.map{|v| v.sub(/\/\Z/, "")}
+
+ @regexp = @ignores.map do |v|
+ v = "(\/|\\A)" + Regexp.escape(v).gsub('\\*', "[^/]*") + "(\/|\\Z)"
+ Regexp.new(v)
+ end
+ end
+
+ def ignore?(path)
+ return false unless path.start_with?(@path)
+
+ if (path.size == @path.size)
+ false
+ else
+ if (@path == '/')
+ ignore_in?(path)
+ else
+ ignore_in?(path[@path.size..-1])
+ end
+ end
+ end
+
+ private
+
+ def ignore_in?(path)
+ @regexp.each_with_index do |value, index|
+ match = path.match(value)
+ is_match_start_pos = @ignores[index].start_with?('/')
+
+ if match && (!is_match_start_pos || match.begin(0) == 0)
+ return true
+ end
+ end
+
+ return false
+ end
+ end
+end
View
19 lib/milkode/grep/cli_grep.rb
@@ -3,8 +3,9 @@
require 'optparse'
require 'milkode/findgrep/findgrep'
require 'milkode/common/dbdir'
-require 'milkode/cdstk/cdstk_yaml'
require 'milkode/cdstk/cdstk'
+require 'milkode/cdstk/yaml_file_wrapper'
+require 'milkode/cdstk/package'
module Milkode
class CLI_Grep
@@ -142,28 +143,28 @@ def self.execute(stdout, arguments=[])
private
def self.setup_package(option, my_option, keyword)
- packages = yaml_load.list( CdstkYaml::Query.new([keyword]) ).map{|v| v['directory']}
- raise NotFoundPackage.new keyword if (packages.empty?)
- option.packages += packages
- my_option[:packages] += packages
+ dirs = yaml_load.contents.find_all {|p| p.name.include? keyword }.map{|p| p.directory}
+ raise NotFoundPackage.new keyword if (dirs.empty?)
+ option.packages += dirs
+ my_option[:packages] += dirs
end
def self.package_dir_in?(dir)
- yaml_load.package_root_dir(dir)
+ yaml_load.package_root(dir)
end
def self.package_root_dir(dir)
- package_root = yaml_load.package_root_dir(dir)
+ package_root = yaml_load.package_root(dir)
if (package_root)
- package_root
+ package_root.directory
else
raise NotFoundPackage.new dir
end
end
def self.yaml_load
- CdstkYaml.load(Dbdir.select_dbdir)
+ YamlFileWrapper.load(Dbdir.select_dbdir)
end
class ArgumentParser
View
42 test/data/.gitignore
@@ -0,0 +1,42 @@
+# rcov generated
+coverage
+
+# rdoc generated
+rdoc
+
+# yard generated
+doc
+.yardoc
+
+# bundler
+.bundle
+
+# jeweler generated
+pkg
+
+# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
+#
+# * Create a file at ~/.gitignore
+# * Include files you want ignored
+# * Run: git config --global core.excludesfile ~/.gitignore
+#
+# After doing this, these files will be ignored in all your git projects,
+# saving you from having to 'pollute' every project you touch with them
+#
+# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
+#
+# For MacOS:
+#
+#.DS_Store
+#
+# For TextMate
+#*.tmproj
+#tmtags
+#
+# For emacs:
+#*~
+#\#*
+#.\#*
+#
+# For vim:
+#*.swp
View
1  test/data/no_auto_ignore/.gitignore
@@ -0,0 +1 @@
+*.bak
View
3  test/data/no_auto_ignore/a.txt
@@ -0,0 +1,3 @@
+a
+b
+c
View
4 test/milkode_test_work.rb
@@ -32,14 +32,14 @@ def initialize(option = nil)
def init_db(name)
dbdir = expand_path(name)
FileUtils.mkdir_p dbdir
- Dir.chdir(dbdir) { cdstk.init }
+ Dir.chdir(dbdir) { cdstk.init({}) }
end
def add_package(name, package_path)
dbdir = expand_path(name)
Dir.chdir(dbdir) do
- cdstk.add [package_path]
+ cdstk.add [package_path], {}
end
end
View
29 test/test_cdstk.rb
@@ -30,25 +30,26 @@ def test_basic
obj = Cdstk.new(io)
io.puts('--- init ---')
- obj.init
+ obj.init({})
io.puts('--- add ---')
- obj.add(['../../lib/milkode/findgrep', '../../lib/milkode/common'])
- obj.add(['../../lib/milkode/findgrep'])
- obj.add(['../data/abc.zip'])
- obj.add(['../data/nodir_abc.zip'])
- obj.add(['../data/nodir_abc_xpi.xpi'])
- obj.add(['http://ongaeshi.me/test_data/http_nodir_abc.zip'])
- assert_raise(OpenURI::HTTPError) { obj.add(['http://ongaeshi.me/test_data/not_found.zip']) }
+ obj.add(['../../lib/milkode/findgrep', '../../lib/milkode/common'], {})
+ obj.add(['../../lib/milkode/findgrep'], {})
+ obj.add(['../data/abc.zip'], {})
+ obj.add(['../data/nodir_abc.zip'], {})
+ obj.add(['../data/nodir_abc_xpi.xpi'], {})
+ obj.add(['http://ongaeshi.me/test_data/http_nodir_abc.zip'], {})
+ assert_raise(OpenURI::HTTPError) { obj.add(['http://ongaeshi.me/test_data/not_found.zip'], {}) }
+ obj.add(['../data/no_auto_ignore'], {:no_auto_ignore => true})
FileUtils.touch('last1.txt')
- obj.add(['last1.txt'])
+ obj.add(['last1.txt'], {})
FileUtils.touch('atodekesu.txt')
- obj.add(['atodekesu.txt'])
+ obj.add(['atodekesu.txt'], {})
FileUtils.rm('atodekesu.txt')
io.puts('--- add notfound ---')
- obj.add(['notfound.html'])
+ obj.add(['notfound.html'], {})
io.puts('--- update_all ---')
FileUtils.touch('packages/zip/abc/c.txt')
@@ -79,8 +80,12 @@ def test_basic
# obj.cleanup({:force=>true})
io.puts('--- rebuild ---')
- obj.rebuild
+ obj.rebuild([], {:all => true})
+ io.puts('--- ignore ---')
+ obj.ignore(['dir*', '*snip*'], {:package => "common"})
+ obj.ignore([], {:package => "common", :test => true})
+
io.puts('--- remove ---')
obj.remove(['findgrep', 'common'], {:force => true})
View
167 test/test_cdstk_yaml.rb
@@ -1,167 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# @file
-# @brief
-# @author ongaeshi
-# @date 2011/02/20
-
-require 'test_helper'
-require 'milkode/cdstk/cdstk_yaml.rb'
-require 'fileutils'
-
-class TestCdstkYaml < Test::Unit::TestCase
- include Milkode
-
- def setup
- @prev_dir = Dir.pwd
- @tmp_dir = Pathname(File.dirname(__FILE__)) + "tmp"
- FileUtils.rm_rf(@tmp_dir.to_s)
- FileUtils.mkdir_p(@tmp_dir.to_s)
- FileUtils.cd(@tmp_dir.to_s)
- end
-
- def test_000
- # create
- yaml = CdstkYaml.create
- assert_equal yaml.contents, []
- assert_equal yaml.version, 0.1
- assert_raise(CdstkYaml::YAMLAlreadyExist) { CdstkYaml.create }
-
- # load
- yaml = CdstkYaml.load
- assert_equal yaml.contents, []
- assert_equal yaml.version, 0.1
-
- # load fail
- FileUtils.mkdir 'loadtest'
- FileUtils.cd 'loadtest' do
- assert_raise(CdstkYaml::YAMLNotExist) { CdstkYaml.load }
- end
-
- # add
- yaml.add(['dir1'])
- yaml.add(['dir2', 'dir3'])
- assert_equal ['dir1', 'dir2', 'dir3'], yaml.directorys
-
- # remove
- yaml.add(['dir2', 'dir4', 'dir5'])
- yaml.remove(CdstkYaml::Query.new ['dir5'])
- yaml.remove(CdstkYaml::Query.new ['dir2', 'dir3'])
- assert_equal ['dir1', 'dir4'], yaml.directorys
-
- # save
- yaml.save
- r = YAML.load(open('milkode.yaml').read)
- assert_equal 0.1, r['version']
- assert_equal([{'directory'=>'dir1'}, {'directory' => 'dir4'}], r['contents'])
- end
-
- def test_001
- FileUtils.mkdir 'otherpath'
- yaml = CdstkYaml.create('otherpath')
- yaml.save
-
- # save
- r = YAML.load(open('otherpath/milkode.yaml').read)
- assert_equal 0.1, r['version']
- assert_equal([], r['contents'])
- end
-
- def test_query
- d = 'directory'
-
- contents = [{d => 'key'}, {d => 'keyword'}, {d => 'not'}]
-
- query = CdstkYaml::Query.new(['key'])
- assert_equal [{d => 'key'}, {d => 'keyword'}], query.select_any?(contents)
-
- query = CdstkYaml::Query.new(['word'])
- assert_equal [{d => 'keyword'}], query.select_any?(contents)
-
- contents = [{d => 'a/dir'}, {d => 'b/dia'}]
- query = CdstkYaml::Query.new(['a'])
- assert_equal [{d => 'b/dia'}], query.select_any?(contents) # ディレクトリ名は含めない
- end
-
- def test_list
- src = <<EOF
-version: 0.1
-contents:
-- directory: /a/dir1
-- directory: /b/dir4
-EOF
-
- yaml = CdstkYaml.new('dummy.yaml', YAML.load(src))
- assert_equal [{"directory"=>"/a/dir1"}, {"directory"=>"/b/dir4"}], yaml.list
- assert_equal [{"directory"=>"/b/dir4"}], yaml.list(CdstkYaml::Query.new(['4']))
- assert_equal [], yaml.list(CdstkYaml::Query.new(['a']))
- assert_equal [{"directory"=>"/a/dir1"}, {"directory"=>"/b/dir4"}], yaml.list(nil)
- end
-
- def test_remove
- src = <<EOF
-version: 0.1
-contents:
-- directory: /a/dir1
-- directory: /b/dir4
-EOF
-
- yaml = CdstkYaml.new('dummy.yaml', YAML.load(src))
-
- yaml.remove(CdstkYaml::Query.new(['dir4']))
- assert_equal [{"directory"=>"/a/dir1"}], yaml.list
-
- yaml.remove(CdstkYaml::Query.new(['dir1']))
- assert_equal [], yaml.list
-
- # ---
-
- yaml = CdstkYaml.new('dummy.yaml', YAML.load(src))
-
- yaml.remove(CdstkYaml::Query.new(['dir1']))
- assert_equal [{"directory"=>"/b/dir4"}], yaml.list
-
- yaml.remove(CdstkYaml::Query.new([]))
- assert_equal [{"directory"=>"/b/dir4"}], yaml.list
-
- end
-
- def test_exist
- src = <<EOF
-version: 0.1
-contents:
-- directory: /a/dir1
-- directory: /b/dir12
-- directory: /b/dir4
-EOF
-
- yaml = CdstkYaml.new('dummy.yaml', YAML.load(src))
-
- assert_not_nil yaml.exist?('dir1')
- assert_not_nil yaml.exist?('dir12')
- assert_nil yaml.exist?('dir123')
- assert_nil yaml.exist?('dir')
- end
-
- def test_package_root
- src = <<EOF
-version: 0.1
-contents:
-- directory: /a/dir1
-- directory: /path/to/dir
-- directory: /a/b/c
-EOF
-
- yaml = CdstkYaml.new('dummy.yaml', YAML.load(src))
-
- assert_equal nil , yaml.package_root_dir('/not_dir')
- assert_equal "/a/dir1" , yaml.package_root_dir('/a/dir1/dir3')
- assert_equal nil , yaml.package_root_dir('/hoge/a/dir1/dir3')
- assert_equal '/path/to/dir', yaml.package_root_dir('/path/to/dir')
- end
-
- def teardown
- FileUtils.cd(@prev_dir)
- FileUtils.rm_rf(@tmp_dir.to_s)
- end
-end
View
8 test/test_database.rb
@@ -21,12 +21,12 @@ def setup_db
# データベース作成
io = StringIO.new
@obj = Cdstk.new(io)
- @obj.init
- @obj.add(['../../test'])
- @obj.add(['../../lib'])
+ @obj.init({})
+ @obj.add(['../../test'], {})
+ @obj.add(['../../lib'], {})
FileUtils.touch('notfound.file')
- @obj.add(['notfound.file'])
+ @obj.add(['notfound.file'], {})
FileUtils.rm('notfound.file')
# puts io.string
View
26 test/test_ignore_checker.rb
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+#
+# @file
+# @brief
+# @author ongaeshi
+# @date 2012/03/02
+
+require 'milkode/common/ignore_checker.rb'
+require 'test_helper'
+
+class TestIgnoreChecker < Test::Unit::TestCase
+ include Milkode
+
+ def test_basic
+ c = IgnoreChecker.new
+ c.add IgnoreSetting.new("/", ["/rdoc", "/test/data", "*.lock"])
+ c.add IgnoreSetting.new("/pkg", ["*.gem"])
+
+ assert_equal false, c.ignore?("/lib/test.rb")
+ assert_equal true, c.ignore?("/pkg/hoge.gem")