diff --git a/lib/whenever/job.rb b/lib/whenever/job.rb index 4466517a..cc843b68 100644 --- a/lib/whenever/job.rb +++ b/lib/whenever/job.rb @@ -1,7 +1,9 @@ +require 'shellwords' + module Whenever class Job attr_reader :at - + def initialize(options = {}) @options = options @at = options.delete(:at) @@ -9,9 +11,9 @@ def initialize(options = {}) @job_template = options.delete(:job_template) || ":job" @options[:output] = Whenever::Output::Redirection.new(options[:output]).to_s if options.has_key?(:output) @options[:environment] ||= :production - @options[:path] ||= Whenever.path + @options[:path] = Shellwords.shellescape(@options[:path] || Whenever.path) end - + def output job = process_template(@template, @options).strip out = process_template(@job_template, { :job => job }).strip @@ -20,9 +22,9 @@ def output end out.gsub(/%/, '\%') end - + protected - + def process_template(template, options) template.gsub(/:\w+/) do |key| before_and_after = [$`[-1..-1], $'[0..0]] @@ -41,7 +43,7 @@ def process_template(template, options) def escape_single_quotes(str) str.gsub(/'/) { "'\\''" } end - + def escape_double_quotes(str) str.gsub(/"/) { '\"' } end diff --git a/test/unit/job_test.rb b/test/unit/job_test.rb index 3c54d972..677671a6 100644 --- a/test/unit/job_test.rb +++ b/test/unit/job_test.rb @@ -1,26 +1,30 @@ require File.expand_path(File.dirname(__FILE__) + "/../test_helper") class JobTest < Test::Unit::TestCase - + context "A Job" do should "return the :at set when #at is called" do assert_equal 'foo', new_job(:at => 'foo').at end - + should "substitute the :task when #output is called" do job = new_job(:template => ":task", :task => 'abc123') assert_equal 'abc123', job.output end - + should "substitute the :path when #output is called" do assert_equal 'foo', new_job(:template => ':path', :path => 'foo').output end - + should "substitute the :path with the default Whenever.path if none is provided when #output is called" do Whenever.expects(:path).returns('/my/path') assert_equal '/my/path', new_job(:template => ':path').output end - + + should "escape the :path" do + assert_equal '/my/spacey\ path', new_job(:template => ':path', :path => '/my/spacey path').output + end + should "escape percent signs" do job = new_job( :template => "before :foo after", @@ -28,7 +32,7 @@ class JobTest < Test::Unit::TestCase ) assert_equal %q(before percent -> \% <- percent after), job.output end - + should "assume percent signs are not already escaped" do job = new_job( :template => "before :foo after", @@ -36,7 +40,7 @@ class JobTest < Test::Unit::TestCase ) assert_equal %q(before percent preceded by a backslash -> \\\% <- after), job.output end - + should "reject newlines" do job = new_job( :template => "before :foo after", @@ -48,18 +52,18 @@ class JobTest < Test::Unit::TestCase end end - + context "A Job with quotes" do should "output the :task if it's in single quotes" do job = new_job(:template => "':task'", :task => 'abc123') assert_equal %q('abc123'), job.output end - + should "output the :task if it's in double quotes" do job = new_job(:template => '":task"', :task => 'abc123') assert_equal %q("abc123"), job.output end - + should "output escaped single quotes in when it's wrapped in them" do job = new_job( :template => "before ':foo' after", @@ -67,7 +71,7 @@ class JobTest < Test::Unit::TestCase ) assert_equal %q(before 'quote -> '\'' <- quote' after), job.output end - + should "output escaped double quotes when it's wrapped in them" do job = new_job( :template => 'before ":foo" after', @@ -76,18 +80,18 @@ class JobTest < Test::Unit::TestCase assert_equal %q(before "quote -> \" <- quote" after), job.output end end - + context "A Job with a job_template" do should "use the job template" do job = new_job(:template => ':task', :task => 'abc123', :job_template => 'left :job right') assert_equal 'left abc123 right', job.output end - + should "escape single quotes" do job = new_job(:template => "before ':task' after", :task => "quote -> ' <- quote", :job_template => "left ':job' right") assert_equal %q(left 'before '\''quote -> '\\''\\'\\'''\\'' <- quote'\'' after' right), job.output end - + should "escape double quotes" do job = new_job(:template => 'before ":task" after', :task => 'quote -> " <- quote', :job_template => 'left ":job" right') assert_equal %q(left "before \"quote -> \\\" <- quote\" after" right), job.output @@ -99,5 +103,5 @@ class JobTest < Test::Unit::TestCase def new_job(options={}) Whenever::Job.new(options) end - + end