class ScheduleJob::Cron::Table
Public Class Methods
new(user = nil)
click to toggle source
# File lib/schedule_job/cron.rb, line 26 def initialize(user = nil) @user = user load(user) end
Public Instance Methods
add(job, dry_run = false)
click to toggle source
# File lib/schedule_job/cron.rb, line 78 def add(job, dry_run = false) if @dry_run puts "Would schedule: #{job.to_s}" else puts "Scheduling: #{job.to_s}" install_cron_job(job) end cron_parser = CronParser.new(job.schedule_spec) rescue nil if cron_parser puts "Next three runs:" first_run_time = cron_parser.next(Time.now) second_run_time = cron_parser.next(first_run_time) third_run_time = cron_parser.next(second_run_time) puts "1. #{first_run_time}" puts "2. #{second_run_time}" puts "3. #{third_run_time}" end end
empty?()
click to toggle source
# File lib/schedule_job/cron.rb, line 31 def empty? @environment_vars.empty? && @jobs.empty? end
install_cron_job(job)
click to toggle source
# File lib/schedule_job/cron.rb, line 99 def install_cron_job(job) job_spec = job.specification new_crontab = [read_crontab(@user).strip, job_spec.strip].reject(&:empty?).join("\n") new_crontab << "\n" # add a trailing newline write_crontab(new_crontab) end
load(user = @user)
click to toggle source
# File lib/schedule_job/cron.rb, line 35 def load(user = @user) @raw_crontab = read_crontab(user) @environment_vars, @jobs = parse_crontab(@raw_crontab) end
parse_crontab(user_crontab)
click to toggle source
returns lines that represent valid cron job specification lines
# File lib/schedule_job/cron.rb, line 57 def parse_crontab(user_crontab) parser = TableParser.new(user_crontab) return [], [] unless parser.valid? environment_vars = parser.environment_vars&.map do |env_directive| name = env_directive[:var].to_s expr = env_directive[:expr].to_s EnvironmentVar.new(name, expr) end || [] jobs = parser.job_specs&.map do |jobspec| schedule_spec = jobspec.capture(:schedule_spec).to_s command = jobspec.capture(:command).to_s line_number = parser.get_line_number(jobspec) Job.new(schedule_spec, command, line_number, jobspec.offset) end || [] [environment_vars, jobs] end
read_crontab(user = @user)
click to toggle source
# File lib/schedule_job/cron.rb, line 40 def read_crontab(user = @user) command = ["crontab", "-l"] command << "-u #{user}" if user command = command.join(" ") stdout, stderr, exit_status = Open3.capture3(command) crontab_output = stdout error_output = stderr no_crontab = !exit_status.success? && error_output =~ /no crontab/ raise("Unable to read crontab: #{error_output}") if !exit_status.success? && !no_crontab crontab_output end
remove(job_id, dry_run = false)
click to toggle source
because we print the table out with 1-based job IDs, job_id is a 1-based index into @jobs
# File lib/schedule_job/cron.rb, line 108 def remove(job_id, dry_run = false) job_index = job_id - 1 if job_index >= @jobs.size puts "The specified job ID does not exist." exit(1) end job = @jobs[job_index] if dry_run puts "Would remove: #{job}" else puts "Removing: #{job}" new_crontab = @raw_crontab.lines.reject.with_index{|line, line_index| line_index == job.line_number - 1 }.join write_crontab(new_crontab) end end
to_s()
click to toggle source
# File lib/schedule_job/cron.rb, line 143 def to_s s = StringIO.new if !@environment_vars.empty? s.puts "Environment" s.puts @environment_vars.join("\n") end if !@jobs.empty? s.puts "Jobs" @jobs.each_with_index do |job, i| s.puts "#{i + 1}. #{job}" end end s.string end
write_crontab(new_crontab, user = @user)
click to toggle source
# File lib/schedule_job/cron.rb, line 127 def write_crontab(new_crontab, user = @user) # overwrite crontab interactively, per https://stackoverflow.com/questions/610839/how-can-i-programmatically-create-a-new-cron-job command = ["crontab"] command << "-u #{user}" if user command << "-" command = command.join(" ") stdout, stderr, exit_status = Open3.capture3(command, stdin_data: new_crontab) crontab_output = stdout error_output = stderr load(user) raise("Unable to write to crontab: #{error_output}") unless exit_status.success? end