Skip to content

Instantly share code, notes, and snippets.

@kascote
Forked from fstrube/Rakefile
Created August 9, 2014 22:34
Show Gist options
  • Save kascote/d437225aeffbbb3bf0f1 to your computer and use it in GitHub Desktop.
Save kascote/d437225aeffbbb3bf0f1 to your computer and use it in GitHub Desktop.
## -- Rake Tasks -- ##
desc "Deploy website via rsync (e.g. rake deploy [path=...] [options=<extra rsync options>])"
task :deploy do
# Run commands
puts "## Deploying website via Rsync"
puts "-----------\nCommand: #{rsync_command '--dry-run'}\n-----------"
system(rsync_command '--dry-run')
# Prompt for continuance
puts
proceed = get_stdin "The above actions will be taken. Continue? (This cannot be undone) [No]: "
# The real deal
if "y yes".split.include? proceed.downcase
ok_failed system(rsync_command)
if CONFIG["restart_apache"]
restart_apache, ssh_port, ssh_host = CONFIG.values_at "restart_apache", "ssh_port", "ssh_host"
puts
puts "## Restarting Apache server"
ok_failed system("ssh #{"-p "+ssh_port.to_s unless ssh_port == nil} #{ssh_host} '#{restart_apache}'")
end
else
puts "Deployment cancelled by user."
end
end
namespace :remote do
desc "Connect to the remote console"
task :console do
puts "## Initializing remote console"
puts "----------\nCommand: #{ssh_command}\n----------"
system(ssh_command)
end
desc "Show differences between local and remote files"
task :diff do
document_root, site_dir = CONFIG.values_at "document_root", "site_dir"
# Get the local path
local_path = ENV['path'] ? ENV['path'] : site_dir
if File.exists?(local_path)
local_path = File.expand_path(local_path)
local_path = local_path + '/' if File.directory?(local_path)
end
# Build the remote path
remote_path = "#{document_root}/#{local_path.sub(File.expand_path(site_dir), '')}".gsub(/\/+/, '/')
# Files get compared straight-up
if File.file?(local_path)
system(%Q:bash -c 'diff -Naur "#{local_path}" <(#{ssh_command "cat #{remote_path}"})':)
# Directories process each file
else
changes = `#{rsync_command '--dry-run'}`
num_changes = changes.lines.count
proceed = get_stdin "#{changes.lines.count} file(s) will be compared. Continue? [No]: " if num_changes > 10
if proceed == nil or "y yes".split.include? proceed.downcase
changes.each_line do |line|
action, file = line.chomp.split(' ', 2)
system %Q:bash -c 'diff -Naur "#{local_path + file}" <(#{ssh_command "cat #{remote_path + file}"})':
end
end
end
end
end
## -- Utility functions -- ##
def ssh_command(command=nil)
ssh_port, ssh_host = CONFIG.values_at "ssh_port", "ssh_host"
"ssh #{"-p "+ssh_port.to_s unless ssh_port == nil} #{ssh_host} #{%Q'"#{command}"' unless command == nil}"
end
def rsync_command(options=nil)
document_root, rsync_delete, site_dir, ssh_port, ssh_host =
CONFIG.values_at "document_root", "rsync_delete", "site_dir", "ssh_port", "ssh_host"
# Get the local path
local_path = ENV['path'] ? ENV['path'] : site_dir
if File.exists?(local_path)
local_path = File.expand_path(local_path)
local_path = local_path + '/' if File.directory?(local_path)
end
# Build the remote path
remote_path = "#{document_root}/#{local_path.sub(File.expand_path(site_dir), '')}".gsub(/\/+/, '/')
# Exclude file
exclude = ""
if File.exists?('./deploy-exclude')
exclude="--exclude-from '#{File.expand_path('./deploy-exclude')}'"
end
# Build rsync options
rsync_options =
"--archive --no-group --no-owner --no-perms --no-times --update " +
"--human-readable --compress --checksum " +
"--itemize-changes #{exclude} " +
"#{"--rsh='ssh -p #{ssh_port}' " unless ssh_port == nil}" +
"#{"--delete " unless rsync_delete == "no"}" +
"#{options} #{ENV['options']} " +
"#{local_path} #{ssh_host}:#{remote_path}"
return "rsync #{rsync_options}"
end
# Include all rake files in the tasks directory
Dir.glob('tasks/*.rake').each { |r| import r }
# Read configuration from tasks/config.yaml
require 'yaml'
CONFIG = YAML.load_file('tasks/config.yaml')[ENV['env'] || 'development']
# Default utility functions available in all tasks
def ok_failed(condition)
if (condition)
puts "OK"
else
puts "FAILED"
end
end
def get_stdin(message)
print message
STDIN.gets.chomp
end
def ask(message, valid_options)
if valid_options
answer = get_stdin("#{message} #{valid_options.to_s.gsub(/"/, '').gsub(/, /,'/')} ") while !valid_options.include?(answer)
else
answer = get_stdin(message)
end
answer
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment