Skip to content

Commit

Permalink
Moved converters into their own filw, added a AR converter
Browse files Browse the repository at this point in the history
  • Loading branch information
Peer Allan authored and jm committed Feb 18, 2011
1 parent 093aaed commit bc0f895
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 65 deletions.
53 changes: 53 additions & 0 deletions lib/active_record_finder_converter.rb
@@ -0,0 +1,53 @@
$:.unshift(File.dirname(__FILE__) + "/../../lib")
require 'converter_base'
require 'arel_converter'

module Rails
module Converter
class ActiveRecordFinder < Base

def run
Dir['app/**/*'].each do |file|
begin
parse_file(file) unless File.directory?(file)
rescue => e
alert(file, [], e.message)
end
end
end

def parse_file(file)
raw_ar_finders = ''
["find(:all", "find(:first", "find.*:conditions =>", ":joins =>"].each do |v|
raw_ar_finders += `grep -r '#{v}' #{file}`
end
ar_finders = raw_ar_finders.split("\n").uniq.reject {|l| l.include?('named_scope') }

unless ar_finders.empty?

failures = []
find_regex = /find\(:all,(.*)\)$/
embedded_find_regex = /find\(:all,(.*?)\)\./

new_ar_finders = ar_finders.map do |ar_finder|
ar_finder.strip!
begin
sexp = ParseTree.new.process(ar_finder)
processed = ArelConverter.new.process(sexp)
clean = /find\(:(all|first), (.*?)\)\)/.match(processed)
processed.gsub!(/find\(:(all|first), (.*?)\)\)/, "#{clean[1]}.#{clean[2]})")
[ar_finder,processed]
rescue SyntaxError => e
failures << "SyntaxError when evaluatiing options for #{ar_finder}"
nil
rescue => e
failures << "#{e.class} #{e.message} when evaluatiing options for #{ar_finder}\n#{e.backtrace.first}"
nil
end
end.compact
alert(file, new_ar_finders, failures) unless (new_ar_finders.nil? || new_ar_finders.empty?) && failures.empty?
end
end
end
end
end
75 changes: 75 additions & 0 deletions lib/arel_converter.rb
@@ -0,0 +1,75 @@
require "parse_tree"
require "parse_tree_extensions"
require "unified_ruby"
require 'ruby2ruby'

class ArelConverter < Ruby2Ruby
def process_hash(exp)
result = []

if @conditions_hash
result.push process_conditions_hash(exp)
@conditions_hash = false
else

until exp.empty?
lhs = process(exp.shift)
rhs = exp.shift
t = rhs.first

@conditions_hash = (lhs == ':conditions' && t == :hash)

rhs = process rhs
rhs = "#{rhs}" unless [:lit, :str].include? t # TODO: verify better!


result.push( hash_to_arel(lhs,rhs) )
end
end

return result.join('.')
end

def hash_to_arel(lhs, rhs)
case lhs
when ':conditions'
key = 'where'
when ':include'
key = 'includes'
else
key = lhs.sub(':','')
end
"#{key}(#{rhs})"
end


def process_conditions_hash(exp)
result = []
until exp.empty?
lhs = process(exp.shift)
rhs = exp.shift
t = rhs.first
rhs = process rhs
rhs = "(#{rhs})" unless [:lit, :str, :true, :false].include? t # TODO: verify better!

result << "#{lhs} => #{rhs}"
end

case self.context[1]
when :arglist, :argscat then
unless result.empty? then
# HACK - this will break w/ 2 hashes as args
if BINARY.include? @calls.last then
return "{ #{result.join(', ')} }"
else
return "#{result.join(', ')}"
end
else
return "{}"
end
else
return "{ #{result.join(', ')} }"
end
end

end
70 changes: 70 additions & 0 deletions lib/converter_base.rb
@@ -0,0 +1,70 @@
module Rails
module Converter
class Base

def contruct_for_arel(options)
options.map do |key,value|
case key
when :conditions, :where
key = 'where'
when :include
key = 'includes'
end
case
when value.is_a?(Array)
value = value.inspect
when value.is_a?(Hash)
value = value.inspect
when value.is_a?(Symbol)
value = ":#{value}"
when value.is_a?(String) && key != 'where'
value = %Q{"#{value}"}
end
"#{key}(#{value})"
end
end

# Terminal colors, borrowed from Thor
CLEAR = "\e[0m"
BOLD = "\e[1m"
RED = "\e[31m"
YELLOW = "\e[33m"
CYAN = "\e[36m"
WHITE = "\e[37m"

# Show an upgrade alert to the user
def alert(title, culprits, errors=nil)
if Config::CONFIG['host_os'].downcase =~ /mswin|windows|mingw/
basic_alert(title, culprits, errors)
else
color_alert(title, culprits, errors)
end
end

# Show an upgrade alert to the user. If we're on Windows, we can't
# use terminal colors, hence this method.
def basic_alert(title, culprits, errors=nil)
puts "** " + title
puts "\t** " + error if error
Array(culprits).each do |c|
puts "\t- #{c}"
end
puts
end

# Show a colorful alert to the user
def color_alert(file, culprits, errors=nil)
puts "#{RED}#{BOLD}#{file}#{CLEAR}"
Array(errors).each do |error|
puts "#{CYAN}#{BOLD}\t- #{error}#{CLEAR}"
end
Array(culprits).each do |c|
puts c.is_a?(Array) ? "#{YELLOW}\tFROM: #{c[0]}\n\t TO: #{c[1]}" : "#{YELLOW}\t#{c[0]}"
end
ensure
puts "#{CLEAR}"
end

end
end
end
70 changes: 5 additions & 65 deletions lib/named_scope_converter.rb
@@ -1,6 +1,9 @@
$:.unshift(File.dirname(__FILE__) + "/../../lib")
require 'converter_base'

module Rails
module Converter
class NamedScope
class NamedScope < Base

def run
Dir['app/models/**/*'].each do |file|
Expand Down Expand Up @@ -67,70 +70,7 @@ def parse_normal(scope)
options = %Q{{#{options}}} unless options =~ /^\{.*\}$/
contruct_for_arel(eval(options)).join('.')
end

def contruct_for_arel(options)
options.map do |key,value|
case key
when :conditions, :where
key = 'where'
when :include
key = 'includes'
end
case
when value.is_a?(Array)
value = value.inspect
when value.is_a?(Hash)
value = value.inspect
when value.is_a?(Symbol)
value = ":#{value}"
when value.is_a?(String) && key != 'where'
value = %Q{"#{value}"}
end
"#{key}(#{value})"
end
end

# Terminal colors, borrowed from Thor
CLEAR = "\e[0m"
BOLD = "\e[1m"
RED = "\e[31m"
YELLOW = "\e[33m"
CYAN = "\e[36m"
WHITE = "\e[37m"

# Show an upgrade alert to the user
def alert(title, culprits, errors=nil)
if Config::CONFIG['host_os'].downcase =~ /mswin|windows|mingw/
basic_alert(title, culprits, errors)
else
color_alert(title, culprits, errors)
end
end

# Show an upgrade alert to the user. If we're on Windows, we can't
# use terminal colors, hence this method.
def basic_alert(title, culprits, errors=nil)
puts "** " + title
puts "\t** " + error if error
Array(culprits).each do |c|
puts "\t- #{c}"
end
puts
end

# Show a colorful alert to the user
def color_alert(file, culprits, errors=nil)
puts "#{RED}#{BOLD}#{file}#{CLEAR}"
Array(errors).each do |error|
puts "#{CYAN}#{BOLD}\t- #{error}#{CLEAR}"
end
Array(culprits).each do |c|
puts "#{YELLOW}\t#{c}"
end
ensure
puts "#{CLEAR}"
end


end
end
end
7 changes: 7 additions & 0 deletions lib/tasks/rails_upgrade_tasks.rake
Expand Up @@ -4,6 +4,7 @@ require 'gemfile_generator'
require 'application_checker'
require 'new_configuration_generator'
require 'named_scope_converter'
require 'active_record_finder_converter'

require 'fileutils'

Expand All @@ -14,6 +15,12 @@ namespace :rails do
converter = Rails::Converter::NamedScope.new
converter.run
end

task :finders do
converter = Rails::Converter::ActiveRecordFinder.new
converter.run
end

end

namespace :upgrade do
Expand Down

0 comments on commit bc0f895

Please sign in to comment.