escape quotes for bash, furrealz this time

Any parameter in a job type template which is surrounded by quotes
will now be auto-escaped.

Examples:

job_type :foo, :template => "/my/cool/bin ':bar'"

every :day do
  foo %(single quote! -> ' <-)
end

will render to

@daily /my/cool/bin 'single quote! -> '\'' <-'
This commit is contained in:
Jay Adkisson 2010-07-03 13:15:59 +08:00 committed by Javan Makhmali
parent df9590e6a5
commit dd15137e41
5 changed files with 49 additions and 34 deletions

View File

@ -16,12 +16,21 @@ module Whenever
template = @options[:template].dup template = @options[:template].dup
template.gsub(/:\w+/) do |key| template.gsub(/:\w+/) do |key|
if key == ':task' && template.index("':task'")
escape_single_quotes(@options[:task]) single_quote = "'"
elsif key == ':task' && template.index('":task"') double_quote = '"'
escape_double_quotes(@options[:task])
char_before = $`[-1..-1]
char_after = $'[0..0]
option = @options[key.sub(':', '').to_sym]
if char_before == single_quote && char_after == single_quote
escape_single_quotes(option)
elsif char_after == double_quote && char_after == double_quote
escape_double_quotes(option)
else else
@options[key.sub(':', '').to_sym] option
end end
end end
end end
@ -29,11 +38,11 @@ module Whenever
protected protected
def escape_single_quotes(str) def escape_single_quotes(str)
str.gsub(/'/, %q('\'')) str.gsub(/'/) { "'\\''" }
end end
def escape_double_quotes(str) def escape_double_quotes(str)
str.gsub(/"/, %q(\")) str.gsub(/"/) { '\"' }
end end
end end

View File

@ -1,3 +1,3 @@
job_type :command, ':task' job_type :command, %(:task)
job_type :runner, 'cd :path && script/runner -e :environment ":task"' job_type :runner, %(cd :path && script/runner -e :environment ':task')
job_type :rake, 'cd :path && RAILS_ENV=:environment /usr/bin/env rake :task' job_type :rake, %(cd :path && RAILS_ENV=:environment /usr/bin/env rake :task)

View File

@ -18,14 +18,20 @@ class JobTest < Test::Unit::TestCase
assert_equal %q("abc123"), job.output assert_equal %q("abc123"), job.output
end end
should "output escaped single quotes in :task when it's wrapped in them" do should "output escaped single quotes in when it's wrapped in them" do
job = new_job(:template => "outside ':task' outside", :task => "'inside'") job = new_job(
assert_equal %q(outside ''\''inside'\''' outside), job.output :template => "before ':foo' after",
:foo => "quote -> ' <- quote"
)
assert_equal %q(before 'quote -> '\'' <- quote' after), job.output
end end
should "output escaped double quotes in :task when it's wrapped in them" do should "output escaped double quotes when it's wrapped in them" do
job = new_job(:template => 'outside ":task" outside', :task => '"inside"') job = new_job(
assert_equal %q(outside "\"inside"\" outside), job.output :template => 'before ":foo" after',
:foo => 'quote -> " <- quote'
)
assert_equal %q(before "quote -> \" <- quote" after), job.output
end end
end end

View File

@ -91,7 +91,7 @@ class OutputAtTest < Test::Unit::TestCase
end end
should "output the runner using one entry because the times are aligned" do should "output the runner using one entry because the times are aligned" do
assert_match '2 5,15 * * 1,3,5 cd /your/path && script/runner -e production "blahblah"', @output assert_match %(2 5,15 * * 1,3,5 cd /your/path && script/runner -e production 'blahblah'), @output
end end
end end
@ -168,9 +168,9 @@ class OutputAtTest < Test::Unit::TestCase
should "output all of the commands @daily" do should "output all of the commands @daily" do
assert_match '@daily cd /your/path && RAILS_ENV=production /usr/bin/env rake blah:blah', @output assert_match '@daily cd /your/path && RAILS_ENV=production /usr/bin/env rake blah:blah', @output
assert_match '@daily cd /your/path && script/runner -e production "runner_1"', @output assert_match %(@daily cd /your/path && script/runner -e production 'runner_1'), @output
assert_match '@daily command_1', @output assert_match '@daily command_1', @output
assert_match '@daily cd /your/path && script/runner -e production "runner_2"', @output assert_match %(@daily cd /your/path && script/runner -e production 'runner_2'), @output
assert_match '@daily command_2', @output assert_match '@daily command_2', @output
end end
end end

View File

@ -8,13 +8,13 @@ class OutputRunnerTest < Test::Unit::TestCase
<<-file <<-file
set :path, '/my/path' set :path, '/my/path'
every 2.hours do every 2.hours do
runner "blahblah" runner 'blahblah'
end end
file file
end end
should "output the runner using that path" do should "output the runner using that path" do
assert_match two_hours + ' cd /my/path && script/runner -e production "blahblah"', @output assert_match two_hours + %( cd /my/path && script/runner -e production 'blahblah'), @output
end end
end end
@ -30,7 +30,7 @@ class OutputRunnerTest < Test::Unit::TestCase
end end
should "output the runner using that path" do should "output the runner using that path" do
assert_match two_hours + ' cd /some/other/path && script/runner -e production "blahblah"', @output assert_match two_hours + %( cd /some/other/path && script/runner -e production 'blahblah'), @output
end end
end end
@ -41,13 +41,13 @@ class OutputRunnerTest < Test::Unit::TestCase
@output = Whenever.cron \ @output = Whenever.cron \
<<-file <<-file
every 2.hours do every 2.hours do
runner "blahblah" runner 'blahblah'
end end
file file
end end
should "output the runner using that path" do should "output the runner using that path" do
assert_match two_hours + ' cd /my/path && script/runner -e production "blahblah"', @output assert_match two_hours + %( cd /my/path && script/runner -e production 'blahblah'), @output
end end
end end
@ -65,7 +65,7 @@ class OutputRunnerTest < Test::Unit::TestCase
end end
should "use the path" do should "use the path" do
assert_match two_hours + ' cd /my/path && script/runner -e production "blahblah"', @output assert_match two_hours + %( cd /my/path && script/runner -e production 'blahblah'), @output
assert_no_match /\/rails\/path/, @output assert_no_match /\/rails\/path/, @output
end end
end end
@ -83,7 +83,7 @@ class OutputRunnerTest < Test::Unit::TestCase
end end
should "output the runner using that environment" do should "output the runner using that environment" do
assert_match two_hours + ' cd /my/path && script/runner -e silly "blahblah"', @output assert_match two_hours + %( cd /my/path && script/runner -e silly 'blahblah'), @output
end end
end end
@ -100,7 +100,7 @@ class OutputRunnerTest < Test::Unit::TestCase
end end
should "output the runner using that environment" do should "output the runner using that environment" do
assert_match two_hours + ' cd /my/path && script/runner -e serious "blahblah"', @output assert_match two_hours + %( cd /my/path && script/runner -e serious 'blahblah'), @output
end end
end end
@ -117,7 +117,7 @@ class OutputRunnerTest < Test::Unit::TestCase
end end
should "output the runner using the override environment" do should "output the runner using the override environment" do
assert_match two_hours + ' cd /my/path && script/runner -e serious "blahblah"', @output assert_match two_hours + %( cd /my/path && script/runner -e serious 'blahblah'), @output
end end
end end
@ -134,7 +134,7 @@ class OutputRunnerTest < Test::Unit::TestCase
end end
should "output the runner using the overridden path and environment" do should "output the runner using the overridden path and environment" do
assert_match two_hours + ' cd /serious/path && script/runner -e serious "blahblah"', @output assert_match two_hours + %( cd /serious/path && script/runner -e serious 'blahblah'), @output
end end
end end
@ -151,7 +151,7 @@ class OutputRunnerTest < Test::Unit::TestCase
end end
should "output the runner using the overridden path and environment" do should "output the runner using the overridden path and environment" do
assert_match two_hours + ' cd /serious/path && script/runner -e serious "blahblah"', @output assert_match two_hours + %( cd /serious/path && script/runner -e serious 'blahblah'), @output
end end
end end
@ -168,7 +168,7 @@ class OutputRunnerTest < Test::Unit::TestCase
end end
should "output the runner using the original environmnet" do should "output the runner using the original environmnet" do
assert_match two_hours + ' cd /silly/path && script/runner -e silly "blahblah"', @output assert_match two_hours + %( cd /silly/path && script/runner -e silly 'blahblah'), @output
end end
end end