From 919dbe09ef4eb75d0f588718e6db1109abcd4fae Mon Sep 17 00:00:00 2001 From: John Bintz Date: Fri, 19 Aug 2011 11:40:23 -0400 Subject: [PATCH] allow piping of crontab from stdin to stdout --- bin/whenever | 3 ++ lib/whenever/command_line.rb | 67 +++++++++++++++++++--------- test/functional/command_line_test.rb | 38 ++++++++++++++++ 3 files changed, 88 insertions(+), 20 deletions(-) mode change 100644 => 100755 bin/whenever diff --git a/bin/whenever b/bin/whenever old mode 100644 new mode 100755 index c2bd54c..bfb43f6 --- a/bin/whenever +++ b/bin/whenever @@ -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! diff --git a/lib/whenever/command_line.rb b/lib/whenever/command_line.rb index c52067d..07dfca7 100644 --- a/lib/whenever/command_line.rb +++ b/lib/whenever/command_line.rb @@ -57,32 +57,51 @@ module Whenever 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) : '' + + command_results = ( + if @options[:pipe] + stdin.read + else + command = ['crontab -l'] + command << "-u #{@options[:user]}" if @options[:user] + + 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 + ) + + target_fh << contents + target_fh.close - 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}" + 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 diff --git a/test/functional/command_line_test.rb b/test/functional/command_line_test.rb index 48f1e9e..ed75d60 100644 --- a/test/functional/command_line_test.rb +++ b/test/functional/command_line_test.rb @@ -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