Skip to content

Instantly share code, notes, and snippets.

@fabioyamate
Created March 12, 2010 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fabioyamate/330688 to your computer and use it in GitHub Desktop.
Save fabioyamate/330688 to your computer and use it in GitHub Desktop.
# Code based from Whenever::CommandLine removing the 'exit' calls and
# adding some helper methods like 'registerd?' and 'remove'
#
# Allows passing a string instead of a file as default.
#
# job = <<-JOB
# set :environment, Rails.env
# set :output, '/path/to/log'
#
# every #{frequency}, :at => '#{time}' do
# command ...
# runner ...
# rake ...
# end
# JOB
#
# options = {:string => job, :update => true, :identifier => identifier}
# Whenever::Register.execute(options)
#
# Whenever::Register.registered(identifier)
# Whenever::Register.remove(identifier)
#
module Whenever
class Register
def self.execute(options={})
new(options).run
end
def self.registered?(identifier, user=nil)
new(:identifier => identifier, :user => user).exists?
end
def self.remove(identifier, user=nil)
new(:identifier => identifier, :user => user).clear
end
def initialize(options={})
@options = options
unless @options[:identifier]
raise '[fail] Identifier not setted.'
end
end
def run
if @options[:update]
write_crontab(updated_crontab)
else
puts Whenever.cron(@options)
end
end
def exists?
read_crontab.index(comment_open) && read_crontab.index(comment_close) ? true : false
end
def clear
return unless exists?
contents = read_crontab.gsub(Regexp.new("#{comment_open}.+#{comment_close}", Regexp::MULTILINE), '').gsub(/\n{2,}/, "\n\n")
write_crontab(contents)
end
protected
def whenever_cron
@whenever_cron ||= [comment_open, Whenever.cron(@options), comment_close].join("\n") + "\n"
end
def read_crontab
return @current_crontab if @current_crontab
command = ['crontab -l']
command << "-u #{@options[:user]}" if @options[:user]
command_results = %x[#{command.join(' ')} 2> /dev/null]
@current_crontab = $?.exitstatus.zero? ? command_results : ''
end
def write_crontab(contents)
tmp_cron_file = Tempfile.new('whenever_tmp_cron').path
File.open(tmp_cron_file, File::WRONLY | File::APPEND) do |file|
file << contents
end
command = ['crontab']
command << "-u #{@options[:user]}" if @options[:user]
command << tmp_cron_file
if system(command.join(' '))
action = 'written' if @options[:write]
action = 'updated' if @options[:update]
puts "[write] crontab file #{action}"
else
raise "[fail] Couldn't write crontab; try running `whenever' with no options to ensure your schedule file is valid."
end
end
def updated_crontab
# Check for unopened or unclosed identifier blocks
if read_crontab.index(comment_open) && !read_crontab.index(comment_close)
raise "[fail] Unclosed indentifier; Your crontab file contains '#{comment_open}', but no '#{comment_close}'"
elsif !read_crontab.index(comment_open) && read_crontab.index(comment_close)
raise "[fail] Unopened indentifier; Your crontab file contains '#{comment_close}', but no '#{comment_open}'"
end
# If an existing identier block is found, replace it with the new cron entries
if read_crontab.index(comment_open) && read_crontab.index(comment_close)
read_crontab.gsub(Regexp.new("#{comment_open}.+#{comment_close}", Regexp::MULTILINE), whenever_cron.chomp)
else # Otherwise, append the new cron entries after any existing ones
[read_crontab, whenever_cron].join("\n\n")
end
end
def comment_base
"Whenever generated tasks for: #{@options[:identifier]}"
end
def comment_open
"# Begin #{comment_base}"
end
def comment_close
"# End #{comment_base}"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment