Commit 83cc7a7b by Alex Chaffee

--trace option to help debug "Unable to annotate" errors

parent 3e894485
......@@ -61,6 +61,7 @@
* Add --format=markdown option
* "Table name" annotation (if table name is different from model name)
* "Human name" annotation (enabling translation to non-English locales)
* --trace option to help debug "Unable to annotate" errors
== 2.4.2 2009-11-21
......
......@@ -101,7 +101,7 @@ anywhere in the file:
== OPTIONS
Usage: annotate_models [options] [model_file]*
Usage: annotate [options] [model_file]*
-d, --delete Remove annotations from all model files
-p, --position [before|after] Place the annotations at the top (before) or the bottom (after) of the model file
-r, --routes Annotate routes.rb with the output of 'rake routes'
......@@ -117,6 +117,7 @@ anywhere in the file:
-f [bare|rdoc|markdown], Render Schema Infomation as plain/RDoc/Markdown
--format
--force Force new annotations even if there are no changes.
--trace If unable to annotate a file, print the full stack trace, not just the exception message.
== SORTING
......
......@@ -44,6 +44,7 @@ task :default => :spec
require "rspec/core/rake_task" # RSpec 2.0
RSpec::Core::RakeTask.new(:spec) do |t|
t.pattern = ['spec/*_spec.rb', 'spec/**/*_spec.rb']
t.rspec_opts = ['--backtrace', '--format d']
end
require 'rdoc/task'
......
......@@ -13,7 +13,7 @@ end
task = :annotate_models
OptionParser.new do |opts|
opts.banner = "Usage: annotate_models [options] [model_file]*"
opts.banner = "Usage: annotate [options] [model_file]*"
opts.on('-d', '--delete',
"Remove annotations from all model files") do
......@@ -87,6 +87,11 @@ OptionParser.new do |opts|
ENV['force'] = 'yes'
end
opts.on('--trace', 'If unable to annotate a file, print the full stack trace, not just the exception message.') do |value|
ENV['trace'] = 'yes'
end
end.parse!
ENV['is_cli'] = '1'
......
......@@ -344,25 +344,11 @@ module AnnotateModels
end
end
if options[:model_dir]
self.model_dir = options[:model_dir]
end
self.model_dir = options[:model_dir] if options[:model_dir]
annotated = []
get_model_files(options).each do |file|
begin
klass = get_model_class(file)
if klass && klass < ActiveRecord::Base && !klass.abstract_class?
if annotate(klass, file, header, options)
annotated << klass
end
end
rescue Exception => e
# todo: check if all backtrace lines are in "gems" -- if so, it's an annotate bug, so print the whole stack trace.
puts "Unable to annotate #{file}: #{e.message} (#{e.backtrace.first})"
# todo: save this backtrace somewhere nice
# puts "\t" + e.backtrace.join("\n\t")
end
annotate_model_file(annotated, file, header, options)
end
if annotated.empty?
puts "Nothing annotated."
......@@ -370,12 +356,23 @@ module AnnotateModels
puts "Annotated (#{annotated.length}): #{annotated.join(', ')}"
end
end
def remove_annotations(options={})
if options[:model_dir]
puts "removing"
self.model_dir = options[:model_dir]
def annotate_model_file(annotated, file, header, options)
begin
klass = get_model_class(file)
if klass && klass < ActiveRecord::Base && !klass.abstract_class?
if annotate(klass, file, header, options)
annotated << klass
end
end
rescue Exception => e
puts "Unable to annotate #{file}: #{e.message}"
puts "\t" + e.backtrace.join("\n\t") if options[:trace]
end
end
def remove_annotations(options={})
self.model_dir = options[:model_dir] if options[:model_dir]
deannotated = []
get_model_files(options).each do |file|
begin
......@@ -406,7 +403,8 @@ module AnnotateModels
end
rescue Exception => e
puts "Unable to annotate #{file}: #{e.message}"
puts "Unable to deannotate #{file}: #{e.message}"
puts "\t" + e.backtrace.join("\n\t") if options[:trace]
end
end
puts "Removed annotation from: #{deannotated.join(', ')}"
......
......@@ -28,6 +28,7 @@ task :annotate_models => :environment do
options[:format_markdown] = ENV['format_markdown'] =~ true_re
options[:sort] = ENV['sort'] =~ true_re
options[:force] = ENV['force'] =~ true_re
options[:trace] = ENV['trace'] =~ true_re
AnnotateModels.do_annotations(options)
end
......
......@@ -223,7 +223,6 @@ EOS
check_class_name 'foo_with_known_macro.rb', 'FooWithKnownMacro'
end.should == ""
end
end
describe "#remove_annotation_of_file" do
......@@ -295,12 +294,12 @@ end
describe "annotating a file" do
before do
@file_name = File.join(Dir.mktmpdir('annotate_models'), "user.rb")
@file_content = <<-EOS
@model_dir = Dir.mktmpdir('annotate_models')
write_model "user.rb", <<-EOS
class User < ActiveRecord::Base
end
EOS
File.open(@file_name, "wb") { |f| f.write @file_content }
@klass = mock_class(:users, :id, [
mock_column(:id, :integer),
mock_column(:name, :string, :limit => 50)
......@@ -308,30 +307,97 @@ end
@schema_info = AnnotateModels.get_schema_info(@klass, "== Schema Info")
end
def write_model file_name, file_content
@model_file_name = File.join(@model_dir, file_name)
@file_content = file_content
File.open(@model_file_name, "wb") { |f| f.write @file_content }
end
def annotate_one_file options = {}
AnnotateModels.annotate_one_file(@model_file_name, @schema_info, options)
end
it "should annotate the file before the model if position == 'before'" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :position => "before")
File.read(@file_name).should == "#{@schema_info}#{@file_content}"
annotate_one_file :position => "before"
File.read(@model_file_name).should == "#{@schema_info}#{@file_content}"
end
it "should annotate before if given :position => :before" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :position => :before)
File.read(@file_name).should == "#{@schema_info}#{@file_content}"
annotate_one_file :position => :before
File.read(@model_file_name).should == "#{@schema_info}#{@file_content}"
end
it "should annotate before if given :position => :after" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :position => :after)
File.read(@file_name).should == "#{@file_content}\n#{@schema_info}"
annotate_one_file :position => :after
File.read(@model_file_name).should == "#{@file_content}\n#{@schema_info}"
end
it "should update annotate position" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :position => :before)
annotate_one_file :position => :before
another_schema_info = AnnotateModels.get_schema_info(mock_class(:users, :id, [mock_column(:id, :integer),]),
"== Schema Info")
AnnotateModels.annotate_one_file(@file_name, another_schema_info, :position => :after)
@schema_info = another_schema_info
annotate_one_file :position => :after
File.read(@model_file_name).should == "#{@file_content}\n#{another_schema_info}"
end
File.read(@file_name).should == "#{@file_content}\n#{another_schema_info}"
describe "if a file can't be annotated" do
before do
write_model('user.rb', <<-EOS)
class User < ActiveRecord::Base
raise "oops"
end
EOS
end
it "displays an error message" do
capturing(:stdout) {
AnnotateModels.do_annotations :model_dir => @model_dir, :is_rake => true
}.should include("Unable to annotate user.rb: oops")
end
it "displays the full stack trace with --trace" do
capturing(:stdout) {
AnnotateModels.do_annotations :model_dir => @model_dir, :trace => true, :is_rake => true
}.should include("/spec/annotate/annotate_models_spec.rb:")
end
it "omits the full stack trace without --trace" do
capturing(:stdout) {
AnnotateModels.do_annotations :model_dir => @model_dir, :trace => false, :is_rake => true
}.should_not include("/spec/annotate/annotate_models_spec.rb:")
end
end
describe "if a file can't be deannotated" do
before do
write_model('user.rb', <<-EOS)
class User < ActiveRecord::Base
raise "oops"
end
EOS
end
it "displays an error message" do
capturing(:stdout) {
AnnotateModels.remove_annotations :model_dir => @model_dir, :is_rake => true
}.should include("Unable to deannotate user.rb: oops")
end
it "displays the full stack trace" do
capturing(:stdout) {
AnnotateModels.remove_annotations :model_dir => @model_dir, :trace => true, :is_rake => true
}.should include("/user.rb:2:in `<class:User>'")
end
it "omits the full stack trace without --trace" do
capturing(:stdout) {
AnnotateModels.remove_annotations :model_dir => @model_dir, :trace => false, :is_rake => true
}.should_not include("/user.rb:2:in `<class:User>'")
end
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment