#!/usr/bin/env ratch # Generate core method redirects. # # This tool generates libraries files for each # method in the every facets library. $LOAD_PATH.unshift(File.expand_path('lib/methods')) $LOAD_PATH.unshift(File.expand_path('lib/core')) $LOAD_PATH.unshift(File.expand_path('lib/more')) require 'facets/kernel/op_esc' require 'facets/module/require' # Read configuration config = configuration['methods'] p config source = config['source'] # from where output = config['output'] # to where ignore = config['ignore'] # classes/modules to ignore REDIRECT_WRITE = [] # Build method redirection files. main :methods => [ :generate_redirects, :remove_redirects ] do #Dir.chdir('lib') do REDIRECT_WRITE.each do |file, klass, meth| meth = meth.chomp('!').chomp('=').chomp('?') meth = op_esc(meth) meth_file = "#{output}/#{klass.to_s.downcase}/#{meth}.rb" # if the the redirect has the same name as the original, don't botther. next if file == "facets/#{klass.to_s.downcase}/#{meth}.rb" # create redirection file meth_dir = File.dirname(meth_file) mkdir_p(meth_dir) unless File.directory?(meth_dir) if noharm? puts %[echo "require '#{file}'" > #{meth_file}] else File.open(meth_file, 'w') do |mf| mf << "require '#{file}'" end end end #end end # Remove previous redirection directory. task :remove_redirects do dst = File.join('lib', output) rm_r(dst) if dir?(dst) #File.directory?(dst) end # Generneate list of method files to be created. task :generate_redirects => [ :neuter_module ] do $:.unshift('.') redirect_libs = Dir.glob(File.join(source, '**', '*')) redirect_libs.each do |file| next if dir?(file) #File.directory?(file) puts "#{file}" mod = Module.new mod.module_eval do module_require(file) end req = file.sub(source, 'facets') mod.constants.each do |klass_name| next if ignore.include?(klass_name) klass = mod.const_get(klass_name) inst_methods(klass).each do |meth| REDIRECT_WRITE << [req, klass_name, meth] end meta_methods(klass).each do |meth| REDIRECT_WRITE << [req, klass_name, meth] end end end end # We have to alter alias and remove methods # to get through this. (tricky!) task :neuter_module do ::Module.module_eval do def alias_method(name,orig) define_method(name){orig} end def remove_method(*args) end end end # # Support Methods # # Get instance methods of class/module. def inst_methods(klass) klass.public_instance_methods(false) + klass.protected_instance_methods(false) + klass.private_instance_methods(false) end # Get module methods of calss/module. # # Module::public_methods has cruft in it, # Module::methods does not. But so does # Module::private_methods. Why? def meta_methods(klass) klass.methods(false) - # klass.protected_methods(false) + # klass.private_methods(false) - # THIS IS BROKEN IN RUBY!!! ['initialize', 'initialize_copy', 'inherited'] end