#!/usr/bin/env ruby require 'rubygems' require 'active_record' require 'config/environment' # Print error message, ask for response def error( msg ) STDERR.puts "Error: #{msg}" STDERR.print "Contine? (y/n) " STDERR.flush answer = STDIN.gets return answer[0,1].downcase == "y" end def copy_file( source_file_name, destination_file_name ) sfn = File.open( source_file_name ) dfn = File.open( destination_file_name, "w+" ) dfn << sfn.read sfn.close dfn.close true end # Prints usage def usage() "Usage: ruby script/console [install|remove] modulename\n\n" end # Crawl modules/views, document which templates are already modded def current_modded_templates() dirs = Dir["modules/views/[_a-z]*"] files = Hash.new{ |hh,kk| hh[kk] = Array.new } dirs.each{ |ii| Dir.entries("#{ii}/").each{ |kk| files["views#{ii.split("views").last}"] << kk unless kk=="." || kk==".."} } files end # Returns a hash of directories => [template files ] of module named "name" def module_templates( name ) dirs = Dir["modules/#{name}/views/[_a-z]*"] files = Hash.new{ |hh,kk| hh[kk] = Array.new } dirs.each{ |ii| Dir.entries("#{ii}/").each{ |kk| files["views#{ii.split("views").last}"] << kk unless kk=="." || kk==".."} } files end # Install (aka copy) all template for module "module_name" into modules/views/ def install_templates( module_name ) hsh = module_templates( module_name ) hsh.each_key do |key| hsh[key].each do |file| # First, we need to make sure the destination directory exists unless FileTest.exists?( "modules/#{key}") Dir.mkdir( "modules/#{key}" ) end # If this template already exists, make a backup if FileTest.exists?( "modules/#{key}/#{file}" ) copy_file( "modules/#{key}/#{file}", "modules/#{key}/#{file}.old" ) end copy_file( "modules/#{module_name}/#{key}/#{file}", "modules/#{key}/#{file}") STDOUT.puts "...\tCopied modules/#{module_name}/#{key}/#{file} to modules/#{key}/#{file}" end end end # Reverts all templates for module_name in modules/views/, replacing them with their filename.old counterpart def revert_templates( module_name ) # Get a list of all files ending in ".old" hsh = module_templates( module_name ) hsh.each_key do |key| hsh[key].each do |file| if FileTest.exists?( "modules/#{key}/#{file}.old" ) copy_file( "modules/#{key}/#{file}.old", "modules/#{key}/#{file}" ) File.delete( "modules/#{key}/#{file}.old" ) else # Else, we should just remove the template File.delete( "modules/#{key}/#{file}" ) if FileTest.exists?("modules/#{key}/#{file}") end STDOUT.puts "...\tReverted template modules/#{key}/#{file}" end end end def add_module_to_modules_config( module_name ) arr = [] File.open( "modules/modules.rb" ){ |f| f.each_line{ |line| arr.push line.strip } } arr.uniq! File.open( "modules/modules.rb", "w+" ) do |f| f << arr.join("\n") f << "\nrequire '#{module_name}/#{module_name}'" end end def remove_module_from_modules_config( module_name ) arr = [] File.open( "modules/modules.rb" ){ |f| f.each_line{ |line| arr.push line.strip if line.strip.size > 0 } } arr.uniq! arr.delete_if{ |ii| ii.include?( "require '#{module_name}/#{module_name}'" ) } File.open( "modules/modules.rb", "w+" ){ |f| f << arr.join("\n") } end #------------------------------------------------------------------------------- # Main routine #------------------------------------------------------------------------------- todo = ARGV[0] mname = ARGV[1] # Check to make sure correct arguments were provided if todo.nil? || mname.nil? STDERR.puts usage() exit end # Crawl modules/views, document which templates are already modded modded_templates = current_modded_templates case todo when "install" # Compare module to be installed against modded_templates to detect conflicts templates_to_install = module_templates( mname ) templates_to_install.each_key{ |key| tmp = (modded_templates[key] & templates_to_install[key]) if tmp.size > 0 exit unless error( "There is a conflict with a previously installed module. Conflicted templates for #{key}:\n\t#{tmp.join("\n\t")}" ) # If they said continue, lets make backup of their old templates, save as .old end } # Install all views for this module. begin install_templates( mname ) # Perform necessary DB migrations if FileTest.exists?( "modules/#{mname}/migrate.rb" ) begin # Try out migrations require "modules/#{mname}/migrate.rb" klass = instance_eval( "#{mname.capitalize}Migration" ) klass.up rescue => e STDERR.puts "ERROR! Migration Failed!" raise e end end # Add line to modules.rb add_module_to_modules_config( mname ) rescue => e STDERR.puts "ERROR! Installation failed! Undoing install..." # Back out of installation # Revert templates to old versions revert_templates( mname ) # Remove modules.rb config remove_module_from_modules_config( mname ) raise e end when "remove" # Check to make sure no other mods need the templates from this mod # Remove template files revert_templates( mname ) # Perform necessary DB migrations if FileTest.exists?( "modules/#{mname}/migrate.rb" ) begin require "modules/#{mname}/migrate.rb" STDOUT.puts "...\tPerforming Migration.down" klass = instance_eval( "#{mname.capitalize}Migration" ) klass.down rescue => e STDERR.puts "ERROR: There was a problem migrating down from this mod install. Please refer to the modules manual removal instructions." raise e end end # remove line from modules.rb remove_module_from_modules_config( mname ) # remove entire mod directory structure STDERR.puts "Please delete modules/#{mname}" else STDERR.puts usage() end # end case statement