require "find" require "fileutils" module Skele SKELETON_ROOT = ENV['HOME'] + File::SEPARATOR + ".skele" + File::SEPARATOR INDENTATION = " " class Skeleton attr_reader :skeleton, :skeleton_dir, :destination def initialize(skeleton, destination, root=SKELETON_ROOT) @skeleton = skeleton @skeleton_dir = root + @skeleton @destination = destination + File::SEPARATOR @ignore = [".git", ".hg"] end def relative_path(abspath,relativeto) path = abspath.split(File::SEPARATOR) rel = relativeto.split(File::SEPARATOR) while (path.length > 0) && (path.first == rel.first) path.shift rel.shift end path.join(File::SEPARATOR) end def summon copy_files bundle_install end def copy_files if File.directory? @skeleton_dir result = Array.new Find.find(@skeleton_dir) do |file| relative_path = relative_path file, @skeleton_dir # skip the containing directory next if relative_path.empty? # skip .git directory next if @ignore.include? relative_path.split(File::SEPARATOR)[0] # copy files if(File.directory? file) if File.exists?(@destination + relative_path) result.push({:action => "exists", :file => relative_path}) else Dir::mkdir(@destination + relative_path) result.push({:action => "mkdir", :file => relative_path}) end else if File.exists?(@destination + relative_path) result.push({:action => "exists", :file => relative_path}) else FileUtils::copy(file, @destination + relative_path) result.push({:action => "create", :file => relative_path}) end end end end return result end def bundler_installed? # make sure bundler is installed bundler_list = `gem list bundler` bundler_list.split("\n").each do |line| if (/^bundler/i).match(line) return true end end return false end def bundle_install if File.exists? @destination + "Gemfile" bundler_result = "" unless bundler_installed? bundler_result += "Bundler wasn't found, so we're installing it\n\n" bundler_result += `gem install bundler` bundler_result += "\n\n" end bundler_result += `bundle install --path=vendor/bundle` return bundler_result end return nil end end class Runner def initialize(skeleton, destination, root=SKELETON_ROOT) @skeleton = Skeleton.new(skeleton, destination, root) end def summon STDOUT.puts "\nSummoning skeleton '#{@skeleton.skeleton}' from '#{@skeleton.destination}'" copy_files bundle_install STDOUT.puts "\nSkeleton complete. Enjoy!\n\n" end def bundle_install STDOUT.puts "\nRunning bundle install\n\n" bundle = @skeleton.bundle_install unless bundle.nil? STDOUT.puts indent bundle end end def copy_files STDOUT.puts "\nCopying files\n\n" file_result = @skeleton.copy_files if file_result.nil? STDOUT.puts indent(red("Error:") + "Skeleton '#{@skeleton.skeleton}' does not exist or is not a directory") else file_result.each do |result| case result[:action] when "mkdir" STDOUT.puts indent(" " + green(result[:action]) + " " + result[:file]) when "create" STDOUT.puts indent(green(result[:action]) + " " + result[:file]) when "exists" STDOUT.puts indent(red(result[:action]) + " " + result[:file]) end end end end def indent(string) indented = "" string.split("\n").each do |line| indented += INDENTATION + line + "\n" end return indented end def colorize(text, color_code) "\e[#{color_code}m#{text}\e[0m" end def red(text) colorize text, 31 end def green(text) colorize text, 32 end def blue(text) colorize text, 34 end end end