Skip to content

Commit

Permalink
move capistrano integration into a module & add tests for it
Browse files Browse the repository at this point in the history
(cherry picked from commit 40b8035)

Conflicts:
	lib/whenever/capistrano/recipes.rb
  • Loading branch information
cap10morgan committed Dec 14, 2012
1 parent 300425e commit 133d722
Show file tree
Hide file tree
Showing 6 changed files with 315 additions and 53 deletions.
13 changes: 7 additions & 6 deletions lib/whenever.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@
require 'active_support/all'

module Whenever
autoload :JobList, 'whenever/job_list'
autoload :Job, 'whenever/job'
autoload :CommandLine, 'whenever/command_line'

autoload :JobList, 'whenever/job_list'
autoload :Job, 'whenever/job'
autoload :CommandLine, 'whenever/command_line'
autoload :CapistranoSupport, 'whenever/capistrano/support'

module Output
autoload :Cron, 'whenever/cron'
autoload :Redirection, 'whenever/output_redirection'
end

def self.cron(options)
Whenever::JobList.new(options).generate_cron_output
end

def self.path
Dir.pwd
end
Expand Down
42 changes: 21 additions & 21 deletions lib/whenever/capistrano/recipes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
Capistrano::Configuration.instance(:must_exist).load do
include Whenever::CapistranoSupport

_cset(:whenever_roles) { :db }
_cset(:whenever_options) { {:roles => fetch(:whenever_roles)} }
_cset(:whenever_command) { "whenever" }
Expand All @@ -23,30 +25,23 @@
which servers the crontab is updated on by setting the :whenever_roles variable.
DESC
task :update_crontab do
options = fetch(:whenever_options)
roles = Array(options[:roles])
args[:command] = fetch(:whenever_command)
args[:flags] = fetch(:whenever_update_flags)
args[:path] = fetch(:release_path)

if find_servers(options).any?
# make sure we go through the roles.each loop at least once
roles << :__none if roles.empty?
if servers.any?
run_whenever_commands(args)

roles.each do |role|
if role == :__none
role_arg = ''
on_rollback do
if fetch(:previous_release)
# rollback to the previous release's crontab
args[:path] = fetch(:previous_release)
else
options[:roles] = role
role_arg = " --roles #{role}"
end

on_rollback do
if fetch :previous_release
run "cd #{fetch :previous_release} && #{fetch :whenever_command} #{fetch :whenever_update_flags}#{role_arg}", options
else
run "cd #{fetch :release_path} && #{fetch :whenever_command} #{fetch :whenever_clear_flags}", options
end
# clear the crontab if no previous release
args[:flags] = fetch(:whenever_clear_flags)
end

run "cd #{fetch :latest_release} && #{fetch :whenever_command} #{fetch :whenever_update_flags}#{role_arg}", options
run_whenever_commands(args)
end
end
end
Expand All @@ -64,8 +59,13 @@
DESC

task :clear_crontab do
options = fetch(:whenever_options)
run "cd #{fetch :latest_release} && #{fetch :whenever_command} #{fetch :whenever_clear_flags}", options if find_servers(options).any?
if servers.any?
args[:command] = fetch(:whenever_command)
args[:flags] = fetch(:whenever_clear_flags)
args[:path] = fetch(:latest_release)

run_whenever_commands(args)
end
end
end
end
35 changes: 35 additions & 0 deletions lib/whenever/capistrano/support.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Whenever
module CapistranoSupport
def options
fetch(:whenever_options)
end

def roles
Array(options[:roles])
end

def servers
find_servers(options)
end

def server_roles
servers.inject({}) do |map, server|
map[server] = role_names_for_host(server) & roles
map
end
end

def run_whenever_commands(args)
unless [:command, :path, :flags].all? { |a| args.include?(a) }
raise ArgumentError, ":command, :path, & :flags are required"
end

server_roles.each do |server, roles|
roles_arg = roles.empty? ? "" : " --roles #{roles.join(',')}"

command = "cd #{args[:path]} && #{args[:command]} #{args[:flags]}#{roles_arg}"
run command, options.merge(:hosts => server.host)
end
end
end
end
52 changes: 26 additions & 26 deletions test/functional/command_line_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")

class CommandLineTest < Test::Unit::TestCase

context "A command line write" do
setup do
File.expects(:exists?).with('config/schedule.rb').returns(true)
Expand All @@ -16,16 +16,16 @@ class CommandLineTest < Test::Unit::TestCase
#{@task}
# End Whenever generated tasks for: My identifier
EXPECTED

assert_equal output, @command.send(:whenever_cron)
end

should "write the crontab when run" do
@command.expects(:write_crontab).returns(true)
assert @command.run
end
end

context "A command line update" do
setup do
File.expects(:exists?).with('config/schedule.rb').returns(true)
Expand All @@ -37,21 +37,21 @@ class CommandLineTest < Test::Unit::TestCase
should "add the cron to the end of the file if there is no existing identifier block" do
existing = '# Existing crontab'
@command.expects(:read_crontab).at_least_once.returns(existing)

new_cron = <<-EXPECTED
#{existing}
# Begin Whenever generated tasks for: My identifier
#{@task}
# End Whenever generated tasks for: My identifier
EXPECTED

assert_equal new_cron, @command.send(:updated_crontab)

@command.expects(:write_crontab).with(new_cron).returns(true)
assert @command.run
end

should "replace an existing block if the identifier matches" do
existing = <<-EXISTING_CRON
# Something
Expand All @@ -76,15 +76,15 @@ class CommandLineTest < Test::Unit::TestCase
This shouldn't get replaced
# End Whenever generated tasks for: Other identifier
NEW_CRON

@command.expects(:read_crontab).at_least_once.returns(existing)
assert_equal new_cron, @command.send(:updated_crontab)

@command.expects(:write_crontab).with(new_cron).returns(true)
assert @command.run
end
end

context "A command line update that contains backslashes" do
setup do
@existing = <<-EXISTING_CRON
Expand All @@ -97,12 +97,12 @@ class CommandLineTest < Test::Unit::TestCase
@command.expects(:read_crontab).at_least_once.returns(@existing)
@command.expects(:whenever_cron).returns(@existing)
end

should "replace the existing block with the backslashes in tact" do
assert_equal @existing, @command.send(:updated_crontab)
end
end

context "A command line update with an identifier similar to an existing one in the crontab already" do
setup do
@existing = <<-EXISTING_CRON
Expand All @@ -118,7 +118,7 @@ class CommandLineTest < Test::Unit::TestCase
@command.expects(:read_crontab).at_least_once.returns(@existing)
@command.expects(:whenever_cron).returns(@new)
end

should "append the similarly named command" do
assert_equal @existing + "\n" + @new, @command.send(:updated_crontab)
end
Expand Down Expand Up @@ -160,7 +160,7 @@ class CommandLineTest < Test::Unit::TestCase
assert @command.run
end
end

context "A command line update with no identifier" do
setup do
File.expects(:exists?).with('config/schedule.rb').returns(true)
Expand All @@ -183,7 +183,7 @@ class CommandLineTest < Test::Unit::TestCase
should "exit with write and clear" do
@command = Whenever::CommandLine.new(:write => true, :clear => true)
end

should "exit with write and update" do
@command = Whenever::CommandLine.new(:write => true, :update => true)
end
Expand All @@ -192,7 +192,7 @@ class CommandLineTest < Test::Unit::TestCase
@command = Whenever::CommandLine.new(:update => true, :clear => true)
end
end

context "A runner where the environment is overridden using the :set option" do
setup do
@output = Whenever.cron :set => 'environment=serious', :string => \
Expand All @@ -205,12 +205,12 @@ class CommandLineTest < Test::Unit::TestCase
end
file
end

should "output the runner using the override environment" do
assert_match two_hours + %( cd /my/path && script/runner -e serious 'blahblah'), @output
end
end

context "A runner where the environment and path are overridden using the :set option" do
setup do
@output = Whenever.cron :set => 'environment=serious&path=/serious/path', :string => \
Expand All @@ -223,12 +223,12 @@ class CommandLineTest < Test::Unit::TestCase
end
file
end

should "output the runner using the overridden path and environment" do
assert_match two_hours + %( cd /serious/path && script/runner -e serious 'blahblah'), @output
end
end

context "A runner where the environment and path are overridden using the :set option with spaces in the string" do
setup do
@output = Whenever.cron :set => ' environment = serious& path =/serious/path', :string => \
Expand All @@ -241,12 +241,12 @@ class CommandLineTest < Test::Unit::TestCase
end
file
end

should "output the runner using the overridden path and environment" do
assert_match two_hours + %( cd /serious/path && script/runner -e serious 'blahblah'), @output
end
end

context "A runner where the environment is overridden using the :set option but no value is given" do
setup do
@output = Whenever.cron :set => ' environment=', :string => \
Expand All @@ -259,7 +259,7 @@ class CommandLineTest < Test::Unit::TestCase
end
file
end

should "output the runner using the original environmnet" do
assert_match two_hours + %( cd /silly/path && script/runner -e silly 'blahblah'), @output
end
Expand All @@ -283,7 +283,7 @@ class CommandLineTest < Test::Unit::TestCase

assert_equal existing, @command.send(:prepare, existing)
end

should "trim off the top lines of the file" do
@command = Whenever::CommandLine.new(:update => true, :identifier => 'My identifier', :cut => '3')
existing = <<-EXISTING_CRON
Expand All @@ -303,7 +303,7 @@ class CommandLineTest < Test::Unit::TestCase

assert_equal new_cron, @command.send(:prepare, existing)
end

should "preserve terminating newlines in files" do
@command = Whenever::CommandLine.new(:update => true, :identifier => 'My identifier')
existing = <<-EXISTING_CRON
Expand Down
Loading

0 comments on commit 133d722

Please sign in to comment.