# File lib/whenever/command_line.rb, line 6 def self.execute(options={}) new(options).run end
# 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
# 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
# File lib/whenever/command_line.rb, line 121 def comment_base "Whenever generated tasks for: #{@options[:identifier]}" end
# File lib/whenever/command_line.rb, line 129 def comment_close "# End #{comment_base}" end
# File lib/whenever/command_line.rb, line 125 def comment_open "# Begin #{comment_base}" end
# File lib/whenever/command_line.rb, line 49 def default_identifier File.expand_path(@options[:file]) end
# 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
# 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
# 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
# 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
# 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