~ brogers /.sake

The heart of the sake bomb from err.the_blog(http://errtheblog.com/post/6069)
desc 'Runs the following task in the development environment'
task 'development' do
  RAILS_ENV = ENV["RAILS_ENV"] = "development"
end

desc 'Runs the following task in the production environment'
task 'production' do
  RAILS_ENV = ENV["RAILS_ENV"] = "production"
end

desc 'Runs the following task in the test environment'
task 'testing' do
  RAILS_ENV = ENV["RAILS_ENV"] = "test"
end

task 'dev' do
  Rake::Task["development"].invoke
end

task 'prod' do
  Rake::Task["production"].invoke
end

desc 'Creates the databases defined in your config/database.yml (unless they already exist)'
task 'db:create' => [ 'environment' ] do
  ActiveRecord::Base.configurations.each_value do |config|
    begin
      ActiveRecord::Base.establish_connection(config)
      ActiveRecord::Base.connection
    rescue
      case config["adapter"]
      when "mysql" then
        ActiveRecord::Base.establish_connection(config.merge({ "database" => nil }))
        ActiveRecord::Base.connection.create_database(config["database"])
        ActiveRecord::Base.establish_connection(config)
      when "postgresql" then
        `createdb \"#{config["database"]}\" -E utf8`
      else
        # do nothing
      end
    end
  end
  ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[(RAILS_ENV or "development")])
end

desc 'Drops the database for your currenet RAILS_ENV as defined in config/database.yml'
task 'db:drop' => [ 'environment' ] do
  config = ActiveRecord::Base.configurations[(RAILS_ENV or "development")]
  case config["adapter"]
  when "mysql" then
    begin
      ActiveRecord::Base.establish_connection(config)
      ActiveRecord::Base.connection.current_database
      ActiveRecord::Base.connection.drop_database(config["database"])
    rescue
      # do nothing
    end
  when "sqlite3" then
    FileUtils.rm_f(File.join(RAILS_ROOT, config["database"]))
  when "postgresql" then
    `dropdb \"#{config["database"]}\"`
  else
    # do nothing
  end
end

desc 'Drops, creates and then migrates the database for your current RAILS_ENV. Target specific version with VERSION=x'
task 'db:reset' => [ 'db:drop', 'db:create', 'db:migrate' ] do
  # do nothing
end

desc 'Launches the database shell using the values defined in config/database.yml'
task 'db:shell' => [ 'environment' ] do
  config = ActiveRecord::Base.configurations[(RAILS_ENV or "development")]
  command = ""
  case config["adapter"]
  when "mysql" then
    (command << "mysql ")
    (command << "--host=#{(config["host"] or "localhost")} ")
    (command << "--port=#{(config["port"] or 3306)} ")
    (command << "--user=#{(config["username"] or "root")} ")
    (command << "--password=#{(config["password"] or "")} ")
    (command << config["database"])
  when "postgresql" then
    puts("You should consider switching to MySQL or get off your butt and submit a patch")
  else
    (command << "echo Unsupported database adapter: #{config["adapter"]}")
  end
  system(command)
end

desc 'Apply a patch directly from Pastie'
task 'pastie:patch' do
  require("open-uri")
  pastie_url = "http://pastie.caboo.se/%s.txt"
  patch_id = ENV["PASTE"].gsub(/\D/, "")
  patch = open((pastie_url % patch_id)).read
  File.open("patch.diff", "w+") { |f| f.puts(patch) }
  `patch -p0 < patch.diff && rm patch.diff`
  puts("Patched with pastie ##{patch_id}.")
end

desc 'Sends STDIN or FILE=file to Pastie; USAGE: cat some_tasks.rake | sake pastie:send OR sake pastie:send FILE=some_tasks.rake'
task 'pastie:send' do
  require("tempfile")
  PASTE_URL = (ENV["SAKE_PASTIE_URL"] or (ENV["PASTIE_URL"] or "http://pastie.caboo.se/pastes/create"))
  if ENV["FILE"] then
    text = File.open(File.expand_path(ENV["FILE"]), "r") { |f| f.read }
  end
  text ||= STDIN.read
  text_file = Tempfile.open("w+")
  (text_file << text)
  text_file.flush
  cmd = "    curl #{PASTE_URL}     -s -L -o /dev/null -w \"%{url_effective}\"     -H \"Expect:\"     -F \"paste[parser]=ruby\"     -F \"paste[restricted]=0\"     -F \"paste[authorization]=burger\"     -F \"paste[body]=<#{text_file.path}\"     -F \"key=\"     -F \"x=27\"     -F \"y=27\"\n"
  out = `\n      #{cmd}\n    `
  text_file.close(true)
  print(out)
end

desc 'Returns the current schema version'
task 'db:version' => [ 'environment' ] do
  puts(("Current version: " + ActiveRecord::Migrator.current_version.to_s))
end

desc 'Show specs when testing'
task 'spec' do
  ENV["TESTOPTS"] = "--runner=s"
  Rake::Task[:test].invoke
end

desc 'Return path to a gem in cache; e.g. sake gems:find activerecord | xargs mate'
task 'gems:find' do
  if ARGV.last then
    gem_path = Gem.source_index.find_name(ARGV.last).last.full_gem_path
  else
    gem_path = Gem.source_index.find_name("sources").last.full_gem_path.split("sources").first
  end
  print(gem_path)
end

desc 'Routes listed in a browser.'
task 'routes_page' => [ 'environment' ] do
  require("erb")
  include(ERB::Util)
  @routes = ActionController::Routing::Routes.routes.collect do |route|
    name = ActionController::Routing::Routes.named_routes.routes.index(route).to_s
    verb = route.conditions[:method].to_s.upcase
    segs = route.segments.inject("") { |str, s| (str << s.to_s) }
    reqs = route.requirements.inspect
    { :name => name, :verb => verb, :segs => segs, :reqs => reqs }
  end
  template = "<html><head><title>Rails Routes</title></head>\n<body>\n<table>\n<% @routes.each do |r| %>\n  <tr<%= r[:name] =~ /^formatted_/ ? ' style=\"color: gray\"' : \"\" %>>\n    <td style=\"padding-right: 1em\" align=\"right\"><%= h r[:name] %></td>\n    <td style=\"padding-right: 1em\"><%= h r[:verb] %></td>\n    <td style=\"padding-right: 1em\"><%= h r[:segs] %></td>\n    <td><%= h r[:reqs] %></td>\n  </tr>\n<% end %>\n</table>\n</body></html>\n"
  ERB.new(template).run(binding)
end

desc 'Print out all defined routes in match order, with names.'
task 'routes' => [ 'environment' ] do
  routes = ActionController::Routing::Routes.routes.collect do |route|
    name = ActionController::Routing::Routes.named_routes.routes.index(route).to_s
    verb = route.conditions[:method].to_s.upcase
    segs = route.segments.inject("") { |str, s| (str << s.to_s) }
    reqs = if route.requirements.empty? then
      ""
    else
      route.requirements.inspect
    end
    { :name => name, :verb => verb, :segs => segs, :reqs => reqs }
  end
  name_width = routes.collect { |r| r[:name] }.collect { |n| n.length }.max
  verb_width = routes.collect { |r| r[:verb] }.collect { |v| v.length }.max
  segs_width = routes.collect { |r| r[:segs] }.collect { |s| s.length }.max
  routes.each do |r|
    puts("#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:segs].ljust(segs_width)} #{r[:reqs]}")
  end
end

desc 'remove and ignore log files and tmp from subversion'
task 'svn:remove_log_and_tmp' do
  puts("removing log directory contents from svn")
  system("svn remove log/*")
  puts("ignoring log directory")
  system("svn propset svn:ignore '*.log' log/")
  system("svn update log/")
  puts("removing contents of tmp sub-directorys from svn")
  system("svn remove tmp/cache/*")
  system("svn remove tmp/pids/*")
  system("svn remove tmp/sessions/*")
  system("svn remove tmp/sockets/*")
  puts("ignoring tmp directory")
  system("svn propset svn:ignore '*' tmp/cache")
  system("svn propset svn:ignore '*' tmp/pids")
  system("svn propset svn:ignore '*' tmp/sessions")
  system("svn propset svn:ignore '*' tmp/sockets")
  system("svn update tmp/")
  puts("committing changes")
  system("svn commit -m 'Removed and ignored log files and tmp'")
end

desc 'Add new files to subversion'
task 'svn:add' do
  system("svn status | grep '^?' | sed -e 's/? *//' | sed -e 's/ / /g' | xargs svn add")
end

desc 'Create common validation formats'
task 'app:copy_formats' do
  format_class = "class Format\n  @@regex={\n          :alpha => /^[A-Za-z ]+$/,\n          :numeric => /^[0-9 ]+$/,\n          :alpha_numeric => /^[A-Za-z0-9 ]+$/,\n          :email => /A([^@ ]+)@((?:[-a-z0-9]+.)+[a-z]{2,})Z/i,\n          :username => /^[A-Za-z]+$/,\n          :password => /^(?=.*d)(?=.*([a-z]|[A-Z]))([ -~]){8,40}$/,\n          :phone => /(+)?([-._() ]?[d]{3,20}[-._() ]?){2,10}/,\n          :zip => /^d{5}$/,\n          :city => /^[A-Za-z ]+$/,\n          :state => /^[A-Z]{2}$/,\n          :url => /^(ftp|https?)://((?:[-a-z0-9]+.)+[a-z]{2,})/,\n          :ip => /^(d{1,3}.d{1,3}.d{1,3}.d{1,3})?$/,\n          :cc => /^((67d{2})|(4d{3})|(5[1-5]d{2})|(6011))(-? ?d{4}){3}|(3[4,7])d{2}-? ?d{6}-? ?d{5}$/,\n          :ccv => /^d{3}$/,\n  }\n\n  def self.method_missing(method, *args)\n          r=@@regex[method]\n          raise NoMethodError if r.nil?\n          r\n  end\nend\n"
  File.open(File.join("lib", "format.rb"), "w") do |file|
    file.write(format_class)
  end
end

desc 'Clears rake completions cache'
task 'rake:cache:clear' do
  system("~/bin/clear_rake_completion_cache")
end

desc 'Clears sake completions cache'
task 'sake:cache:clear' do
  system("~/bin/clear_sake_completion_cache")
end

desc 'Clears cap completions cache'
task 'cap:cache:clear' do
  system("~/bin/clear_cap_completion_cache")
end

desc 'Print plugins managed by Piston.'
task 'pistoned' do
  width = 0
  Dir["vendor/plugins/*"].each{|file| new_length = file.split("/").last.length; width =  new_length > width ? new_length : width}
  Dir["vendor/plugins/*"].each do |file|
    revision = `svn propget piston:remote-revision #{file}`.strip
    unless revision.empty? then
      puts("#{file.split("/").last.ljust(width)}: r#{revision.ljust(6)} [#{`svn propget piston:root #{file}`.strip}]")
    end
  end
  Dir["vendor/*"].each do |file|
    unless revision = `svn propget piston:remote-revision #{file}`.strip.empty? then
      puts("#{file.split("/").last.ljust(30)}: r#{revision.rjust(6)} [#{`svn propget piston:root #{file}`.strip}]")
    end
  end
end