プラガブルなデータ加工ツールのなにか
自分なりに使いやすいようにやった方がやっぱり楽。
基本的な sort・uniq・grep などは自前で持つようにする。
あと、引きずりまわすデータの型は、ハッシュを配列にいれたものにする。
ハッシュのキーはシンボルのみを扱う。
コンフィグ
define_task do |ctx| call_plugin 'Fetch::file_stat', :path => 'D:/home/develop/plugin' sort :key => 'size' sort :key => 'name', :order => 'desc' require 'pp' pp ctx.data end
データダンプ例
[ { :name=>"D:/home/develop/plugin/test.rb", :ftype=>"file", :size=>93, }, { :name=>"D:/home/develop/plugin/inline_ruby.rb", :ftype=>"file", :size=>424, }, { :name=>"D:/home/develop/plugin/Publish", :ftype=>"directory", :size=>0, }, { :name=>"D:/home/develop/plugin/Foo.rb", :ftype=>"file", :size=>308, }, { :name=>"D:/home/develop/plugin/Filter", :ftype=>"directory", :size=>0, }, ]
ソースコード
まだまだこれから。
module Xry class DSL def initialize(dsl_file='xry.dsl', plugin_dir = './plugin') @plugin_dir = plugin_dir @plugin = Xry::Plugin.new.load(@plugin_dir) instance_eval(File::open(dsl_file, "r").read, dsl_file, 1) end def define_task(&block) return nil if block.nil? context = Xry::Context.new(@plugin) context.instance_eval(&block) context end end class Plugin def initialize @methods = {} end def load(dir) Dir::glob("#{dir}/**/*.rb") {|file| key = file.sub(%r{^#{dir}/(.+?)\.rb}, "\\1").gsub(%r{/}, "::") @methods[key] = Xry::Plugin::Method.new(file) # $stderr.puts "load plugin: #{key}" } self end def send(name, *argv) unless @methods.key?(name) $stderr.puts "not found plugin method: name=[#{name}]" return end @methods[name].send(name.sub(/.*::/, ""), *argv) end class Method def initialize(filename) instance_eval(File::open(filename, "r").read, filename, 1) end end end class Context attr_accessor :data def initialize(plugin) @data = [] @plugin = plugin end def call_plugin(*argv, &block) return self if argv.size == 0 if argv.size == 1 config = {} else config = argv[1] end name = argv[0] self.instance_eval(&block) unless block.nil? puts "execute plugin: #{name}" @data = @plugin.send(name, config, @data.clone) self end def sort(option, &block) # argv -> (key, order, &block) return @data unless option.key?(:key) if !block.nil? @data = @data.instance_eval(&block) elsif option.key?(:order) && option[:order].to_s == 'asc' # ascending: 昇順 @data = @data.sort {|a, b| a[option[:key].to_sym] <=> b[option[:key].to_sym]} else # descending: 降順 @data = @data.sort {|a, b| b[option[:key].to_sym] <=> a[option[:key].to_sym]} end end def grep # argv -> (key, pattern, option) @data end def reverse # argv -> () @data end def head # argv -> (n) @data end def tail # argv -> (n) @data end def concat # argv -> (&block) @data end def branch # argv -> (&block) @data end def delete # argv -> (key, pattern, option) @data end def print # argv -> (&block) @data end end end if $0 == __FILE__ xry = Xry::DSL.new() end