allow piping of crontab from stdin to stdout

This commit is contained in:
John Bintz 2011-08-19 11:40:23 -04:00
parent ace7f086a9
commit 919dbe09ef
3 changed files with 88 additions and 20 deletions

3
bin/whenever Normal file → Executable file
View File

@ -33,6 +33,9 @@ OptionParser.new do |opts|
opts.on('-k', '--cut [lines]', 'Cut lines from the top of the cronfile') do |lines|
options[:cut] = lines.to_i if lines
end
opts.on('-p', '--pipe', 'Pipe crontab from stdin, through whenever, and out to stdout') do
options[:pipe] = true
end
opts.on('-v', '--version') { puts "Whenever v#{Whenever::VERSION}"; exit(0) }
end.parse!

View File

@ -58,31 +58,50 @@ module Whenever
def read_crontab
return @current_crontab if @current_crontab
command = ['crontab -l']
command << "-u #{@options[:user]}" if @options[:user]
command_results = (
if @options[:pipe]
stdin.read
else
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) : ''
result = %x[#{command.join(' ')} 2> /dev/null]
$?.exitstatus.zero? ? result : ''
end
)
@current_crontab = prepare(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
target_fh = (
if @options[:pipe]
stdout
else
File.open(Tempfile.new('whenever_tmp_cron').path, File::WRONLY | File::APPEND)
end
)
command = ['crontab']
command << "-u #{@options[:user]}" if @options[:user]
command << tmp_cron_file
target_fh << contents
target_fh.close
if system(command.join(' '))
action = 'written' if @options[:write]
action = 'updated' if @options[:update]
puts "[write] crontab file #{action}"
if @options[:pipe]
exit(0)
else
warn "[fail] Couldn't write crontab; try running `whenever' with no options to ensure your schedule file is valid."
exit(1)
command = ['crontab']
command << "-u #{@options[:user]}" if @options[:user]
command << target_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
end
@ -129,5 +148,13 @@ module Whenever
def comment_close
"# End #{comment_base}"
end
def stdin
$stdin
end
def stdout
$stdout
end
end
end

View File

@ -319,4 +319,42 @@ EXISTING_CRON
end
end
context 'A command line update that reads the cron from stdin writes to stdout' do
setup do
@mock_stdin = StringIO.new(<<-EXISTING_CRON)
# Something
# Begin Whenever generated tasks for: My identifier
My whenever job that was already here
# End Whenever generated tasks for: My identifier
EXISTING_CRON
@mock_stdout = StringIO.new
File.expects(:exists?).with('config/schedule.rb').returns(true)
@command = Whenever::CommandLine.new(:update => true, :identifier => 'My identifier', :pipe => true)
@task = "#{two_hours} /my/command"
Whenever.expects(:cron).returns(@task)
@command.stubs(:stdin).returns(@mock_stdin)
@command.stubs(:stdout).returns(@mock_stdout)
end
should "update the file and write out a new file correctly" do
begin
@command.run
@mock_stdout.rewind
asset_equal @mock_stdout.read, <<-NEW_CRON
# Something
# Begin Whenever generated tasks for: My identifier
#{@task}
# End Whenever generated tasks for: My identifier
NEW_CRON
rescue SystemExit => e
assert_equal 0, e.status
end
end
end
end