Rake task for syntax checking a Ruby on Rails project
Here’s a quick rake file that will crawl through your Rails project and syntax check ruby, erb, and yml files. You should always run this before doing a “cap deploy” and it even doesn’t hurt to run it before a “svn commit”.
require 'erb' require 'open3' require 'yaml' task :check_syntax => [:check_ruby, :check_erb, :check_yaml] task :check_erb do (Dir["**/*.erb"] + Dir["**/*.rhtml"]).each do |file| next if file.match("vendor/rails") Open3.popen3('ruby -c') do |stdin, stdout, stderr| stdin.puts(ERB.new(File.read(file), nil, '-').src) stdin.close if error = ((stderr.readline rescue false)) puts file + error[1..-1] end stdout.close rescue false stderr.close rescue false end end end task :check_ruby do Dir['**/*.rb'].each do |file| next if file.match("vendor/rails") next if file.match("vendor/plugins/.*/generators/.*/templates") Open3.popen3("ruby -c #{file}") do |stdin, stdout, stderr| if error = ((stderr.readline rescue false)) puts error end stdin.close rescue false stdout.close rescue false stderr.close rescue false end end end task :check_yaml do Dir['**/*.yml'].each do |file| next if file.match("vendor/rails") begin YAML.load_file(file) rescue => e puts "#{file}:#{(e.message.match(/on line (\d+)/)[1] + ':') rescue nil} #{e.message}" end end end
And here’s what the output looks like:
warren:tmp_project$ rake check_syntax (in /Users/warren/tmp_project) app/controllers/application.rb:37: syntax error, unexpected '=' app/views/people/home.html.erb:60: syntax error, unexpected '<', expecting $end vendor/plugins/will_paginate/test/fixtures/users.yml:13: syntax error on line 13, col 0: `dev_<%= digit %>:'
This could probably be expanded to support lots of other types of files as well (css, javascripts, etc).
Updates:
- Exclude all files in vendor/rails (thanks szeryf)

Ooh, interesting.
How would this approach work for CSS though, since it’s not executed? Are you talking about using a W3C validator or the like?
Wouldn’t it be much better to use tests? At least for the .rb and .erb files.
Pretty cool. I ran it on my current project, which uses Edge Rails/Rails 2.1, and every single error it spit out was from vendor/rails
If you have Rails in vendor/rails, you might want to skip it in checking too. To do this, change the line 23 (3rd line of task :check_ruby) to:
next if file.match("vendor/.*/generators/.*/templates")
It also barfs on several Rails yml files, so I added the following before line 37 (3rd line of task :check_yml):
next if file.match("vendor/rails")
Other than that, it’s really cool!
Joe: I haven’t found one yet, but I would imagine that there is a regular expression that describes valid syntax for a CSS file. Syntax checking would simply be a matter of checking each .css file against this regexp. Hitting the W3C service would most likely be very slow.
Dan: Test don’t necessarily cover every single file in your project.
Chris/szeryf: I hadn’t thought of skipping vendor/rails… great idea! I’ve updated the post to reflect that! Skipping vendor/rails should also speed this task up significantly.
Using it now… Look at that, it’s already found some ugly. I set it up to ignore vendor/plugins as well as vendor/rails. Thanks guys, nice work!
Wouldn’t it be better to just use flog or heckle?
Thanks, on the first run I found an error in my project. Much better me than someone else. I’ll be using this all the time now.
RailsCheck (http://railscheck.rubyforge.org/) do all this and more.
Nice thing, I am going to use it…