class Whenever::CommandLine

Public Class Methods

execute(options={}) click to toggle source
# File lib/whenever/command_line.rb, line 6
def self.execute(options={})
  new(options).run
end
new(options={}) click to toggle source
# File lib/whenever/command_line.rb, line 10
def initialize(options={})
  @options = options
  
  @options[:file]       ||= 'config/schedule.rb'
  @options[:cut]        ||= 0
  @options[:identifier] ||= default_identifier
  
  unless File.exists?(@options[:file])
    warn("[fail] Can't find file: #{@options[:file]}")
    exit(1)
  end

  if [@options[:update], @options[:write], @options[:clear]].compact.length > 1
    warn("[fail] Can only update, write or clear. Choose one.")
    exit(1)
  end

  unless @options[:cut].to_s =~ %r[0-9]*/
    warn("[fail] Can't cut negative lines from the crontab #{options[:cut]}")
    exit(1)
  end
  @options[:cut] = @options[:cut].to_i
end

Public Instance Methods

run() click to toggle source
# File lib/whenever/command_line.rb, line 34
def run
  if @options[:update] || @options[:clear]
    write_crontab(updated_crontab)
  elsif @options[:write]
    write_crontab(whenever_cron)
  else
    puts Whenever.cron(@options)
    puts "## [message] Above is your schedule file converted to cron syntax; your crontab file was not updated."
    puts "## [message] Run `whenever --help' for more options."
    exit(0)
  end
end

Protected Instance Methods

comment_base() click to toggle source
# File lib/whenever/command_line.rb, line 121
def comment_base
  "Whenever generated tasks for: #{@options[:identifier]}"
end
comment_close() click to toggle source
# File lib/whenever/command_line.rb, line 129
def comment_close
  "# End #{comment_base}"
end
comment_open() click to toggle source
# File lib/whenever/command_line.rb, line 125
def comment_open
  "# Begin #{comment_base}"
end
default_identifier() click to toggle source
# File lib/whenever/command_line.rb, line 49
def default_identifier
  File.expand_path(@options[:file])
end
prepare(contents) click to toggle source
# File lib/whenever/command_line.rb, line 109
def prepare(contents)
  # Strip n lines from the top of the file as specified by the :cut option.
  # Use split with a -1 limit option to ensure the join is able to rebuild
  # the file with all of the original seperators in-tact.
  stripped_contents = contents.split($/,-1)[@options[:cut]..-1].join($/)

  # Some cron implementations require all non-comment lines to be newline-
  # terminated. (issue #95) Strip all newlines and replace with the default 
  # platform record seperator ($/)
  stripped_contents.gsub!(%r\s+$/, $/)
end
read_crontab() click to toggle source
# File lib/whenever/command_line.rb, line 58
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? ? prepare(command_results) : ''
end
updated_crontab() click to toggle source
# File lib/whenever/command_line.rb, line 89
def updated_crontab   
  # Check for unopened or unclosed identifier blocks
  if read_crontab =~ Regexp.new("^#{comment_open}\s*$") && (read_crontab =~ Regexp.new("^#{comment_close}\s*$")).nil?
    warn "[fail] Unclosed indentifier; Your crontab file contains '#{comment_open}', but no '#{comment_close}'"
    exit(1)
  elsif (read_crontab =~ Regexp.new("^#{comment_open}\s*$")).nil? && read_crontab =~ Regexp.new("^#{comment_close}\s*$")
    warn "[fail] Unopened indentifier; Your crontab file contains '#{comment_close}', but no '#{comment_open}'"
    exit(1)
  end
  
  # If an existing identier block is found, replace it with the new cron entries
  if read_crontab =~ Regexp.new("^#{comment_open}\s*$") && read_crontab =~ Regexp.new("^#{comment_close}\s*$")
    # If the existing crontab file contains backslashes they get lost going through gsub.
    # .gsub('\\', '\\\\\\') preserves them. Go figure.
    read_crontab.gsub(Regexp.new("^#{comment_open}\s*$.+^#{comment_close}\s*$", Regexp::MULTILINE), whenever_cron.chomp.gsub('\', '\\\'))
  else # Otherwise, append the new cron entries after any existing ones
    [read_crontab, whenever_cron].join("\n\n")
  end.gsub(%r\n{3,}/, "\n\n") # More than two newlines becomes just two.
end
whenever_cron() click to toggle source
# File lib/whenever/command_line.rb, line 53
def whenever_cron
  return '' if @options[:clear]
  @whenever_cron ||= [comment_open, Whenever.cron(@options), comment_close].compact.join("\n") + "\n"
end
write_crontab(contents) click to toggle source
# File lib/whenever/command_line.rb, line 68
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}"
    exit(0)
  else
    warn "[fail] Couldn't write crontab; try running `whenever' with no options to ensure your schedule file is valid."
    exit(1)
  end
end