Skip to content

Commit

Permalink
Fix POSIX shell argument quoting in Rcov::RcovTask
Browse files Browse the repository at this point in the history
This fixes arguments with spaces, quotes, backslashes, and other shell
metacharacters, like in this example Rakefile snippet:

  require 'rcov/rcovtask'
  Rcov::RcovTask.new do |t|
    t.ruby_opts << '-I/path/with spaces/lib'
    t.rcov_opts += [ '--exclude', %q!(\A|/)(test_.*|.*_spec)\.rb\Z! ]
  end

This would have been easier if rake provided a FileUtils#ruby method that took
a list of program arguments, rather than a string that gets parsed by a shell.
  • Loading branch information
dlitz committed Oct 29, 2009
1 parent 4c18ed5 commit bf75a46
Showing 1 changed file with 25 additions and 11 deletions.
36 changes: 25 additions & 11 deletions lib/rcov/rcovtask.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,21 +103,20 @@ def define
(@name==:rcov ? "" : " for #{actual_name}")
end
task @name do
run_code = ''
RakeFileUtils.verbose(@verbose) do
run_code =
ruby_opts = @ruby_opts.clone
ruby_opts.push( "-I#{lib_path}" )
case rcov_path
when nil, ''
"-S rcov"
else %!"#{rcov_path}"!
ruby_opts.push "-S"
ruby_opts.push "rcov"
else
ruby_opts.push rcov_path
end
ruby_opts = @ruby_opts.clone
ruby_opts.push( "-I#{lib_path}" )
ruby_opts.push run_code
ruby_opts.push( "-w" ) if @warning
ruby ruby_opts.join(" ") + " " + option_list +
%[ -o "#{@output_dir}" ] +
file_list.collect { |fn| %["#{fn}"] }.join(' ')
ruby shellquote_args(ruby_opts) + " " + option_list +
" " + shellquote_args(['-o', @output_dir]) + " " +
shellquote_args(file_list)
end
end

Expand All @@ -138,7 +137,7 @@ def rcov_path # :nodoc:
end

def option_list # :nodoc:
ENV['RCOVOPTS'] || @rcov_opts.join(" ") || ""
ENV['RCOVOPTS'] || shellquote_args(@rcov_opts) || ""
end

def file_list # :nodoc:
Expand All @@ -151,5 +150,20 @@ def file_list # :nodoc:
FileList[result]
end
end

private

def shellquote_arg(arg) # :nodoc:
# Shell-quote an argument, by surrounding it in single-quotes, and
# replacing internal single-quotes by '\'' (closing quote,
# backslash-quote, opening quote)
"'"+arg.gsub(/'/, "'\\\\''")+"'"
end

def shellquote_args(args) # :nodoc:
# Shell-quote a list of arguments
return nil unless args
args.map{ |arg| shellquote_arg(arg) }.join(' ')
end
end
end

0 comments on commit bf75a46

Please sign in to comment.