Commit aafb09fc by Dmitry Lihachev

merge

parents d9a6fe27 7d4f2152
...@@ -4,3 +4,4 @@ rdoc/* ...@@ -4,3 +4,4 @@ rdoc/*
coverage/* coverage/*
spec/debug.log spec/debug.log
pkg/* pkg/*
.rvmrc
\ No newline at end of file
== 2.4.2 2009-11-21
* Annotates (spec|test)/factories/<model>_factory.rb files
== 2.4.1 2009-11-20
* Annotates thoughtbot's factory_girl factories (test/factories/<model>_factory.rb)
* Move default annotation position back to top
== 2.4.0 2009-12-13
* Incorporated lots of patches from the Github community, including support for Blueprints fixtures
* Several bug fixes
== 2.1 2009-10-18 == 2.1 2009-10-18
* New options * New options
......
...@@ -7,6 +7,7 @@ Add a comment summarizing the current schema to the top or bottom of each of you ...@@ -7,6 +7,7 @@ Add a comment summarizing the current schema to the top or bottom of each of you
* Tests and Specs * Tests and Specs
* Object Daddy exemplars * Object Daddy exemplars
* Machinist blueprints * Machinist blueprints
* Thoughtbot's factory_girl factories, i.e. the (spec|test)/factories/<model>_factory.rb files
The schema comment looks like this: The schema comment looks like this:
...@@ -46,8 +47,8 @@ From github: ...@@ -46,8 +47,8 @@ From github:
git clone git://github.com/ctran/annotate_models.git annotate git clone git://github.com/ctran/annotate_models.git annotate
cd annotate cd annotate
rake gem gem build annotate.gemspec
sudo gem install pkg/annotate-*.gem sudo gem install annotate-<version>.gem
== USAGE == USAGE
...@@ -77,6 +78,9 @@ adjust your <tt>rake db:migrate</tt> tasks so that they update the ...@@ -77,6 +78,9 @@ adjust your <tt>rake db:migrate</tt> tasks so that they update the
annotations in your model files for you once the migration is annotations in your model files for you once the migration is
completed. completed.
Warning: ImageMagick installs a tool called `annotate` too (if you're using MacPorts it's in `/opt/local/bin/annotate`. So if you see Usage: annotate imagein.jpg imageout.jpg then put `/usr/bin` ahead on the path and you'll get ours instead.
== OPTIONS == OPTIONS
Usage: annotate [options] [model_file]* Usage: annotate [options] [model_file]*
...@@ -89,7 +93,8 @@ completed. ...@@ -89,7 +93,8 @@ completed.
-s, --simple-indexes Concat the column's related indexes in the annotation -s, --simple-indexes Concat the column's related indexes in the annotation
--model-dir dir Annotate model files stored in dir rather than app/models --model-dir dir Annotate model files stored in dir rather than app/models
-R, --require path Additional files to require before loading models -R, --require path Additional files to require before loading models
-e, --exclude [tests,fixtures] Do not annotate fixtures, test files, or both -e [tests,fixtures,factories] Do not annotate fixtures, test files, and/or factories
--exclude
== WARNING == WARNING
...@@ -103,7 +108,7 @@ to an automatically created comment block. ...@@ -103,7 +108,7 @@ to an automatically created comment block.
== LINKS == LINKS
* Factory Girl => http://github.com/thoughtbot/factory_girl (NOT IMPLEMENTED) * Factory Girl => http://github.com/thoughtbot/factory_girl
* Object Daddy => http://github.com/flogic/object_daddy * Object Daddy => http://github.com/flogic/object_daddy
* SpatialAdapter => http://github.com/pdeffendol/spatial_adapter * SpatialAdapter => http://github.com/pdeffendol/spatial_adapter
* PostgisAdapter => http://github.com/nofxx/postgis_adapter * PostgisAdapter => http://github.com/nofxx/postgis_adapter
...@@ -118,6 +123,7 @@ Original code by: Dave Thomas -- Pragmatic Programmers, LLC ...@@ -118,6 +123,7 @@ Original code by: Dave Thomas -- Pragmatic Programmers, LLC
Overhauled by: Alex Chaffee Overhauled by: Alex Chaffee
Gemmed by: Cuong Tran Gemmed by: Cuong Tran
Maintained by: Alex Chaffee and Cuong Tran Maintained by: Alex Chaffee and Cuong Tran
Homepage: http://github.com/ctran/annotate_models
Modifications by: Modifications by:
...@@ -134,5 +140,6 @@ Modifications by: ...@@ -134,5 +140,6 @@ Modifications by:
- Bob Potter - http://github.com/bpot - Bob Potter - http://github.com/bpot
- Gavin Montague - http://github.com/govan/ - Gavin Montague - http://github.com/govan/
- Alexander Semyonov - http://github.com/rotuka/ - Alexander Semyonov - http://github.com/rotuka/
- Nathan Brazil - http://github.com/bitaxis/
and many others that I may have missed to add. and many others that I may have missed to add.
require 'rubygems' # require 'rubygems'
require 'rake' require 'rake'
require 'lib/annotate' require File.dirname(__FILE__) + '/lib/annotate'
# want other tests/tasks run by default? Add them to the list # want other tests/tasks run by default? Add them to the list
task :default => [:spec] task :default => [:spec]
...@@ -8,39 +8,43 @@ task :default => [:spec] ...@@ -8,39 +8,43 @@ task :default => [:spec]
begin begin
require 'jeweler' require 'jeweler'
Jeweler::Tasks.new do |gem| Jeweler::Tasks.new do |gem|
gem.name = "annotate" gem.name = "netsign-annotate"
gem.executables = "annotate" gem.executables = "annotate"
gem.summary = "Annotates Rails Models, routes, fixtures, and others based on the database schema." gem.summary = "Annotates Rails Models, routes, fixtures, and others based on the database schema."
gem.description = gem.summary gem.description = "Packaged for netSIGN, gem experimentation"
gem.email = ["alex@stinky.com", 'ctran@pragmaquest.com', "x@nofxx.com"] gem.email = ["alex@stinky.com", 'ctran@pragmaquest.com', "x@nofxx.com"]
gem.homepage = "http://github.com/ctran/annotate" gem.homepage = "https://github.com/miyucy/annotate_models"
gem.authors = ['Cuong Tran', "Alex Chaffee", "Marcos Piccinini"] gem.authors = ['Cuong Tran', "Alex Chaffee", "Marcos Piccinini"]
gem.files = FileList["[A-Z]*.*", "{bin,lib,tasks,spec}/**/*"] gem.files = FileList["[A-Z]*.*", "{bin,lib,tasks,spec}/**/*"]
gem.rubyforge_project = "annotate" gem.rubyforge_project = "netsign-annotate"
# note that Jeweler automatically reads the version from VERSION.yml # note that Jeweler automatically reads the version from VERSION.yml
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
end end
Jeweler::RubyforgeTasks.new do |rubyforge| # Jeweler::RubyforgeTasks.new do |rubyforge|
rubyforge.doc_task = "rdoc" # rubyforge.doc_task = "rdoc"
end # end
Jeweler::GemcutterTasks.new
rescue LoadError rescue LoadError
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler" puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
end end
require 'spec/rake/spectask' # Dir["#{File.dirname(__FILE)}/tasks/*.rake"].sort.each { |ext| load ext }
Spec::Rake::SpecTask.new(:spec) do |spec|
spec.libs << 'lib' << 'spec' # require 'spec/rake/spectask'
spec.spec_files = FileList['spec/**/*_spec.rb'] # Spec::Rake::SpecTask.new(:spec) do |spec|
end # spec.libs << 'lib' << 'spec'
# spec.spec_files = FileList['spec/**/*_spec.rb']
Spec::Rake::SpecTask.new(:rcov) do |spec| # end
spec.libs << 'lib' << 'spec' #
spec.pattern = 'spec/**/*_spec.rb' # Spec::Rake::SpecTask.new(:rcov) do |spec|
spec.rcov = true # spec.libs << 'lib' << 'spec'
end # spec.pattern = 'spec/**/*_spec.rb'
# spec.rcov = true
# end
require 'rake/rdoctask' require 'rake/rdoctask'
Rake::RDocTask.new do |rdoc| Rake::RDocTask.new do |rdoc|
......
--- ---
:major: 2 :major: 2
:minor: 4 :minor: 4
:patch: 0 :patch: 3
# Generated by jeweler # Generated by jeweler
# DO NOT EDIT THIS FILE # DO NOT EDIT THIS FILE DIRECTLY
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec` # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = %q{annotate} s.name = %q{annotate}
s.version = "2.4.0" s.version = "2.4.2"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Cuong Tran", "Alex Chaffee", "Marcos Piccinini"] s.authors = ["Cuong Tran", "Alex Chaffee", "Marcos Piccinini"]
s.date = %q{2009-10-23} s.date = %q{2011-01-29}
s.default_executable = %q{annotate} s.default_executable = %q{annotate}
s.description = %q{Annotates Rails Models, routes, fixtures, and others based on the database schema.} s.description = %q{Annotates Rails Models, routes, fixtures, and others based on the database schema.}
s.email = ["alex@stinky.com", "ctran@pragmaquest.com", "x@nofxx.com"] s.email = ["alex@stinky.com", "ctran@pragmaquest.com", "x@nofxx.com"]
...@@ -27,17 +27,18 @@ Gem::Specification.new do |s| ...@@ -27,17 +27,18 @@ Gem::Specification.new do |s|
"lib/annotate/annotate_routes.rb", "lib/annotate/annotate_routes.rb",
"lib/tasks/annotate_models.rake", "lib/tasks/annotate_models.rake",
"lib/tasks/annotate_routes.rake", "lib/tasks/annotate_routes.rake",
"lib/tasks/migrate.rake",
"spec/annotate/annotate_models_spec.rb", "spec/annotate/annotate_models_spec.rb",
"spec/annotate/annotate_routes_spec.rb", "spec/annotate/annotate_routes_spec.rb",
"spec/annotate_spec.rb", "spec/annotate_spec.rb",
"spec/spec.opts", "spec/spec.opts",
"spec/spec_helper.rb", "spec/spec_helper.rb"
"tasks/migrate.rake"
] ]
s.homepage = %q{http://github.com/ctran/annotate} s.homepage = %q{http://github.com/ctran/annotate}
s.rdoc_options = ["--charset=UTF-8"] s.rdoc_options = ["--charset=UTF-8"]
s.require_paths = ["lib"] s.require_paths = ["lib"]
s.rubygems_version = %q{1.3.5} s.rubyforge_project = %q{annotate}
s.rubygems_version = %q{1.3.7}
s.summary = %q{Annotates Rails Models, routes, fixtures, and others based on the database schema.} s.summary = %q{Annotates Rails Models, routes, fixtures, and others based on the database schema.}
s.test_files = [ s.test_files = [
"spec/annotate/annotate_models_spec.rb", "spec/annotate/annotate_models_spec.rb",
...@@ -50,9 +51,10 @@ Gem::Specification.new do |s| ...@@ -50,9 +51,10 @@ Gem::Specification.new do |s|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3 s.specification_version = 3
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
else else
end end
else else
end end
end end
...@@ -61,6 +61,10 @@ OptionParser.new do |opts| ...@@ -61,6 +61,10 @@ OptionParser.new do |opts|
exclusions.each { |exclusion| ENV["exclude_#{exclusion}"] = "yes" } exclusions.each { |exclusion| ENV["exclude_#{exclusion}"] = "yes" }
end end
opts.on('-f', '--format [bare|rdoc]', ['bare', 'rdoc'], 'rdoc: render Schema Infomation as RDoc') do |fmt|
ENV['format_#{fmt}'] = 'yes'
end
end.parse! end.parse!
if Annotate.load_tasks if Annotate.load_tasks
......
$:.unshift(File.dirname(__FILE__)) unless require 'yaml'
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
module Annotate module Annotate
def self.version def self.version
......
module AnnotateModels module AnnotateModels
class << self
# Annotate Models plugin use this header # Annotate Models plugin use this header
COMPAT_PREFIX = "== Schema Info" COMPAT_PREFIX = "== Schema Info"
PREFIX = "== Schema Information" PREFIX = "== Schema Information"
END_MARK = "== Schema Information End"
PATTERN = /^\n?# #{COMPAT_PREFIX}.*?\n(#.*\n)*\n/
FIXTURE_DIRS = ["test/fixtures","spec/fixtures"]
# File.join for windows reverse bar compat? # File.join for windows reverse bar compat?
# I dont use windows, can`t test # I dont use windows, can`t test
UNIT_TEST_DIR = File.join("test", "unit" ) UNIT_TEST_DIR = File.join("test", "unit" )
SPEC_MODEL_DIR = File.join("spec", "models") SPEC_MODEL_DIR = File.join("spec", "models")
FIXTURE_TEST_DIR = File.join("test", "fixtures")
FIXTURE_SPEC_DIR = File.join("spec", "fixtures")
# Object Daddy http://github.com/flogic/object_daddy/tree/master # Object Daddy http://github.com/flogic/object_daddy/tree/master
EXEMPLARS_TEST_DIR = File.join("test", "exemplars") EXEMPLARS_TEST_DIR = File.join("test", "exemplars")
EXEMPLARS_SPEC_DIR = File.join("spec", "exemplars") EXEMPLARS_SPEC_DIR = File.join("spec", "exemplars")
# Machinist http://github.com/notahat/machinist # Machinist http://github.com/notahat/machinist
BLUEPRINTS_DIR = File.join("test", "blueprints") BLUEPRINTS_TEST_DIR = File.join("test", "blueprints")
BLUEPRINTS_SPEC_DIR = File.join("spec", "blueprints")
# Factory Girl http://github.com/thoughtbot/factory_girl
FACTORY_GIRL_TEST_DIR = File.join("test", "factories")
FACTORY_GIRL_SPEC_DIR = File.join("spec", "factories")
# Don't show limit (#) on these column types
# Example: show "integer" instead of "integer(4)"
NO_LIMIT_COL_TYPES = ["integer", "boolean"]
class << self
def model_dir def model_dir
@model_dir || "app/models" @model_dir || "app/models"
end end
...@@ -47,19 +58,21 @@ module AnnotateModels ...@@ -47,19 +58,21 @@ module AnnotateModels
info << "# Human name: #{klass.model_name.human}\n" unless klass.model_name.human(:default => "").blank? info << "# Human name: #{klass.model_name.human}\n" unless klass.model_name.human(:default => "").blank?
info << "#\n" info << "#\n"
max_size = klass.column_names.collect{|name| name.size}.max + 1 max_size = klass.column_names.map{|name| name.size}.max + (ENV['format_rdoc'] ? 5 : 1)
klass.columns.each do |col| klass.columns.each do |col|
attrs = [] attrs = []
attrs << "'#{klass.human_attribute_name(col.name)}'" unless klass.human_attribute_name(col.name, :default => "").blank? attrs << "'#{klass.human_attribute_name(col.name)}'" unless klass.human_attribute_name(col.name, :default => "").blank?
attrs << "default(#{quote(col.default)})" unless col.default.nil? attrs << "default(#{quote(col.default)})" unless col.default.nil?
attrs << "not null" unless col.null attrs << "not null" unless col.null
attrs << "primary key" if col.name == klass.primary_key attrs << "primary key" if col.name.to_sym == klass.primary_key.to_sym
col_type = col.type.to_s col_type = col.type.to_s
if col_type == "decimal" if col_type == "decimal"
col_type << "(#{col.precision}, #{col.scale})" col_type << "(#{col.precision}, #{col.scale})"
else else
col_type << "(#{col.limit})" if col.limit if (col.limit)
col_type << "(#{col.limit})" unless NO_LIMIT_COL_TYPES.include?(col_type)
end
end end
# Check out if we got a geometric column # Check out if we got a geometric column
...@@ -80,15 +93,25 @@ module AnnotateModels ...@@ -80,15 +93,25 @@ module AnnotateModels
end end
end end
if ENV['format_rdoc']
info << sprintf("# %-#{max_size}.#{max_size}s<tt>%s</tt>", "*#{col.name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n"
else
info << sprintf("# %-#{max_size}.#{max_size}s:%-15.15s %s", col.name, col_type, attrs.join(", ")).rstrip + "\n" info << sprintf("# %-#{max_size}.#{max_size}s:%-15.15s %s", col.name, col_type, attrs.join(", ")).rstrip + "\n"
end end
end
if options[:show_indexes] if options[:show_indexes]
info << get_index_info(klass) info << get_index_info(klass)
end end
if ENV['format_rdoc']
info << "#--\n"
info << "# #{END_MARK}\n"
info << "#++\n\n"
else
info << "#\n\n" info << "#\n\n"
end end
end
def get_index_info(klass) def get_index_info(klass)
index_info = "#\n# Indexes\n#\n" index_info = "#\n# Indexes\n#\n"
...@@ -130,10 +153,10 @@ module AnnotateModels ...@@ -130,10 +153,10 @@ module AnnotateModels
false false
else else
# Remove old schema info # Remove old schema info
old_content.sub!(/^\n?# #{COMPAT_PREFIX}.*?\n(#.*\n)*\n/, '') old_content.sub!(PATTERN, '')
# Write it back # Write it back
new_content = options[:position] == 'before' ? (info_block + old_content) : (old_content + "\n" + info_block) new_content = options[:position].to_s == 'after' ? (old_content + "\n" + info_block) : (info_block + old_content)
File.open(file_name, "wb") { |f| f.puts new_content } File.open(file_name, "wb") { |f| f.puts new_content }
true true
...@@ -145,7 +168,7 @@ module AnnotateModels ...@@ -145,7 +168,7 @@ module AnnotateModels
if File.exist?(file_name) if File.exist?(file_name)
content = File.read(file_name) content = File.read(file_name)
content.sub!(/^\n?# #{COMPAT_PREFIX}.*?\n(#.*\n)*\n/, '') content.sub!(PATTERN, '')
File.open(file_name, "wb") { |f| f.puts content } File.open(file_name, "wb") { |f| f.puts content }
end end
...@@ -173,24 +196,22 @@ module AnnotateModels ...@@ -173,24 +196,22 @@ module AnnotateModels
File.join(SPEC_MODEL_DIR, "#{model_name}_spec.rb"), # spec File.join(SPEC_MODEL_DIR, "#{model_name}_spec.rb"), # spec
].each do |file| ].each do |file|
# todo: add an option "position_in_test" -- or maybe just ask if anyone ever wants different positions for model vs. test vs. fixture # todo: add an option "position_in_test" -- or maybe just ask if anyone ever wants different positions for model vs. test vs. fixture
annotate_one_file(file, info, options_with_position(options, :position_in_fixture)) annotate_one_file(file, info, options_with_position(options, :position_in_fixture)) if File.exist?(file)
end end
end end
unless options[:exclude_fixtures] unless options[:exclude_fixtures]
[ [
File.join(FIXTURE_TEST_DIR, "#{klass.table_name}.yml"), # fixture
File.join(FIXTURE_SPEC_DIR, "#{klass.table_name}.yml"), # fixture
File.join(EXEMPLARS_TEST_DIR, "#{model_name}_exemplar.rb"), # Object Daddy File.join(EXEMPLARS_TEST_DIR, "#{model_name}_exemplar.rb"), # Object Daddy
File.join(EXEMPLARS_SPEC_DIR, "#{model_name}_exemplar.rb"), # Object Daddy File.join(EXEMPLARS_SPEC_DIR, "#{model_name}_exemplar.rb"), # Object Daddy
File.join(BLUEPRINTS_DIR, "#{model_name}_blueprint.rb"), # Machinist Blueprints File.join(BLUEPRINTS_TEST_DIR, "#{model_name}_blueprint.rb"), # Machinist Blueprints
File.join(BLUEPRINTS_SPEC_DIR, "#{model_name}_blueprint.rb"), # Machinist Blueprints
File.join(FACTORY_GIRL_TEST_DIR, "#{model_name}_factory.rb"), # Factory Girl Factories
File.join(FACTORY_GIRL_SPEC_DIR, "#{model_name}_factory.rb"), # Factory Girl Factories
].each do |file| ].each do |file|
annotate_one_file(file, info, options_with_position(options, :position_in_fixture)) annotate_one_file(file, info, options_with_position(options, :position_in_fixture)) if File.exist?(file)
end
FIXTURE_DIRS.each do |dir|
fixture_file_name = File.join(dir,klass.table_name + ".yml")
if File.exist?(fixture_file_name)
annotate_one_file(fixture_file_name, info, options_with_position(options, :position_in_fixture))
end
end end
end end
...@@ -274,10 +295,7 @@ module AnnotateModels ...@@ -274,10 +295,7 @@ module AnnotateModels
end end
end end
rescue Exception => e rescue Exception => e
puts "Unable to annotate #{file}: #{e.inspect}" puts "Unable to annotate #{file}: #{e.message} (#{e.backtrace.first})"
puts ""
# todo: check if all backtrace lines are in "gems" -- if so, it's an annotate bug, so print the whole stack trace.
# puts e.backtrace.join("\n\t")
end end
end end
if annotated.empty? if annotated.empty?
...@@ -299,16 +317,22 @@ module AnnotateModels ...@@ -299,16 +317,22 @@ module AnnotateModels
if klass < ActiveRecord::Base && !klass.abstract_class? if klass < ActiveRecord::Base && !klass.abstract_class?
deannotated << klass deannotated << klass
model_name = klass.name.underscore
model_file_name = File.join(model_dir, file) model_file_name = File.join(model_dir, file)
remove_annotation_of_file(model_file_name) remove_annotation_of_file(model_file_name)
FIXTURE_DIRS.each do |dir| [
fixture_file_name = File.join(dir,klass.table_name + ".yml") File.join(UNIT_TEST_DIR, "#{model_name}_test.rb"),
remove_annotation_of_file(fixture_file_name) if File.exist?(fixture_file_name) File.join(SPEC_MODEL_DIR, "#{model_name}_spec.rb"),
end File.join(FIXTURE_TEST_DIR, "#{klass.table_name}.yml"), # fixture
File.join(FIXTURE_SPEC_DIR, "#{klass.table_name}.yml"), # fixture
[ File.join(UNIT_TEST_DIR, "#{klass.name.underscore}_test.rb"), File.join(EXEMPLARS_TEST_DIR, "#{model_name}_exemplar.rb"), # Object Daddy
File.join(SPEC_MODEL_DIR,"#{klass.name.underscore}_spec.rb")].each do |file| File.join(EXEMPLARS_SPEC_DIR, "#{model_name}_exemplar.rb"), # Object Daddy
File.join(BLUEPRINTS_TEST_DIR, "#{model_name}_blueprint.rb"), # Machinist Blueprints
File.join(BLUEPRINTS_SPEC_DIR, "#{model_name}_blueprint.rb"), # Machinist Blueprints
File.join(FACTORY_GIRL_TEST_DIR, "#{model_name}_factory.rb"), # Factory Girl Factories
File.join(FACTORY_GIRL_SPEC_DIR, "#{model_name}_factory.rb"), # Factory Girl Factories
].each do |file|
remove_annotation_of_file(file) if File.exist?(file) remove_annotation_of_file(file) if File.exist?(file)
end end
......
desc "Add schema information (as comments) to model and fixture files" desc "Add schema information (as comments) to model and fixture files"
task :annotate_models => :environment do task :annotate_models => :environment do
require 'annotate/annotate_models' require File.join(File.dirname(__FILE__), '..', 'annotate/annotate_models')
options={} options={}
options[:position_in_class] = ENV['position_in_class'] || ENV['position'] || :before options[:position_in_class] = ENV['position_in_class'] || ENV['position'] || :before
options[:position_in_factory] = ENV['position_in_factory'] || ENV['position'] || :before
options[:position_in_fixture] = ENV['position_in_fixture'] || ENV['position'] || :before options[:position_in_fixture] = ENV['position_in_fixture'] || ENV['position'] || :before
options[:show_indexes] = ENV['show_indexes'] options[:show_indexes] = ENV['show_indexes']
options[:simple_indexes] = ENV['simple_indexes'] options[:simple_indexes] = ENV['simple_indexes']
options[:model_dir] = ENV['model_dir'] options[:model_dir] = ENV['model_dir']
options[:include_version] = ENV['include_version'] options[:include_version] = ENV['include_version']
options[:require] = ENV['require'] ? ENV['require'].split(',') : [] options[:require] = ENV['require'] ? ENV['require'].split(', ') : []
options[:exclude_tests] = ENV['exclude_tests'] options[:exclude_tests] = ENV['exclude_tests']
options[:exclude_fixtures] = ENV['exclude_fixtures'] options[:exclude_fixtures] = ENV['exclude_fixtures']
AnnotateModels.do_annotations(options) AnnotateModels.do_annotations(options)
...@@ -16,7 +17,7 @@ end ...@@ -16,7 +17,7 @@ end
desc "Remove schema information from model and fixture files" desc "Remove schema information from model and fixture files"
task :remove_annotation => :environment do task :remove_annotation => :environment do
require 'annotate/annotate_models' require File.join(File.dirname(__FILE__), '..', 'annotate/annotate_models')
options={} options={}
options[:model_dir] = ENV['model_dir'] options[:model_dir] = ENV['model_dir']
AnnotateModels.remove_annotations(options) AnnotateModels.remove_annotations(options)
......
desc "Prepends the route map to the top of routes.rb" desc "Prepends the route map to the top of routes.rb"
task :annotate_routes do task :annotate_routes => :environment do
require 'annotate/annotate_routes' require 'annotate/annotate_routes'
AnnotateRoutes.do_annotate AnnotateRoutes.do_annotate
end end
...@@ -5,18 +5,35 @@ ...@@ -5,18 +5,35 @@
# run after doing db:migrate. # run after doing db:migrate.
# Unfortunately it relies on ENV for options; it'd be nice to be able to set options # Unfortunately it relies on ENV for options; it'd be nice to be able to set options
# in a per-project config file so this task can read them. # in a per-project config file so this task can read them.
def run_annotate_models?
update_on_migrate = true
(defined? ANNOTATE_MODELS_PREFS::UPDATE_ON_MIGRATE) &&
(!ANNOTATE_MODELS_PREFS::UPDATE_ON_MIGRATE.nil?) ?
ANNOTATE_MODELS_PREFS::UPDATE_ON_MIGRATE : true
end
namespace :db do namespace :db do
task :migrate do task :migrate do
if run_annotate_models?
Annotate::Migration.update_annotations
end
end
task :update => [:migrate] do
Annotate::Migration.update_annotations Annotate::Migration.update_annotations
end end
namespace :migrate do namespace :migrate do
[:up, :down, :reset, :redo].each do |t| [:up, :down, :reset, :redo].each do |t|
task t do task t do
if run_annotate_models?
Annotate::Migration.update_annotations Annotate::Migration.update_annotations
end end
end end
end end
end
end end
module Annotate module Annotate
......
# Generated by jeweler
# DO NOT EDIT THIS FILE DIRECTLY
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
# -*- encoding: utf-8 -*-
Gem::Specification.new do |s|
s.name = %q{netsign-annotate}
s.version = "2.4.3"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Cuong Tran", "Alex Chaffee", "Marcos Piccinini"]
s.date = %q{2011-01-30}
s.default_executable = %q{annotate}
s.description = %q{Packaged for netSIGN, gem experimentation}
s.email = ["alex@stinky.com", "ctran@pragmaquest.com", "x@nofxx.com"]
s.executables = ["annotate"]
s.extra_rdoc_files = [
"README.rdoc"
]
s.files = [
"History.txt",
"README.rdoc",
"VERSION.yml",
"bin/annotate",
"lib/annotate.rb",
"lib/annotate/annotate_models.rb",
"lib/annotate/annotate_routes.rb",
"lib/tasks/annotate_models.rake",
"lib/tasks/annotate_routes.rake",
"lib/tasks/migrate.rake",
"spec/annotate/annotate_models_spec.rb",
"spec/annotate/annotate_routes_spec.rb",
"spec/annotate_spec.rb",
"spec/spec.opts",
"spec/spec_helper.rb"
]
s.homepage = %q{https://github.com/miyucy/annotate_models}
s.require_paths = ["lib"]
s.rubyforge_project = %q{netsign-annotate}
s.rubygems_version = %q{1.3.7}
s.summary = %q{Annotates Rails Models, routes, fixtures, and others based on the database schema.}
s.test_files = [
"spec/annotate/annotate_models_spec.rb",
"spec/annotate/annotate_routes_spec.rb",
"spec/annotate_spec.rb",
"spec/spec_helper.rb"
]
if s.respond_to? :specification_version then
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
else
end
else
end
end
#encoding: utf-8
require File.dirname(__FILE__) + '/../spec_helper.rb' require File.dirname(__FILE__) + '/../spec_helper.rb'
require 'annotate/annotate_models' require 'annotate/annotate_models'
require 'rubygems' require 'active_support'
require 'activesupport' require 'fakefs/spec_helpers'
require 'tmpdir'
describe AnnotateModels do describe AnnotateModels do
include FakeFS::SpecHelpers
def mock_klass(stubs={}) def mock_class(table_name, primary_key, columns)
@mock_file ||= mock("Klass", stubs) options = {
:connection => mock("Conn", :indexes => []),
:table_name => table_name,
:primary_key => primary_key.to_s,
:column_names => columns.map { |col| col.name.to_s },
:columns => columns
}
mock("An ActiveRecord class", options)
end end
def mock_column(stubs={}) def mock_column(name, type, options={})
@mock_column ||= mock("Column", stubs) default_options = {
:limit => nil,
:null => false,
:default => nil
}
stubs = default_options.dup
stubs.merge!(options)
stubs.merge!(:name => name, :type => type)
mock("Column", stubs)
end end
it { AnnotateModels.quote(nil).should eql("NULL") } it { AnnotateModels.quote(nil).should eql("NULL") }
...@@ -21,45 +42,58 @@ describe AnnotateModels do ...@@ -21,45 +42,58 @@ describe AnnotateModels do
it { AnnotateModels.quote(1e-20).should eql("1.0e-20") } it { AnnotateModels.quote(1e-20).should eql("1.0e-20") }
it "should get schema info" do it "should get schema info" do
klass = mock_class(:users, :id, [
mock_column(:id, :integer),
mock_column(:name, :string, :limit => 50)
])
AnnotateModels.get_schema_info(mock_klass( AnnotateModels.get_schema_info(klass, "Schema Info").should eql(<<-EOS)
:connection => mock("Conn", :indexes => []),
:table_name => "users",
:primary_key => "id",
:column_names => ["id","login"],
:columns => [
mock_column(:type => "integer", :default => nil, :null => false, :name => "id", :limit => nil),
mock_column(:type => "string", :default => nil, :null => false, :name => "name", :limit => 50)
]), "Schema Info").should eql(<<-EOS)
# Schema Info # Schema Info
# #
# Table name: users # Table name: users
# #
# id :integer not null, primary key # id :integer not null, primary key
# id :integer not null, primary key # name :string(50) not null
# #
EOS EOS
end
it "should get schema info as RDoc" do
klass = mock_class(:users, :id, [
mock_column(:id, :integer),
mock_column(:name, :string, :limit => 50)
])
ENV.stub!(:[]).with('format_rdoc').and_return(true)
AnnotateModels.get_schema_info(klass, AnnotateModels::PREFIX).should eql(<<-EOS)
# #{AnnotateModels::PREFIX}
#
# Table name: users
#
# *id*:: <tt>integer, not null, primary key</tt>
# *name*:: <tt>string(50), not null</tt>
#--
# #{AnnotateModels::END_MARK}
#++
EOS
end end
describe "#get_model_class" do describe "#get_model_class" do
module ::ActiveRecord
class Base
end
end
def create(file, body="hi") def create(file, body="hi")
File.open(@dir + '/' + file, "w") do |f| path = @dir + '/' + file
File.open(path, "w") do |f|
f.puts(body) f.puts(body)
end end
path
end end
before :all do before :all do
require "tmpdir" @dir = File.join Dir.tmpdir, "annotate_models"
@dir = Dir.tmpdir + "/#{Time.now.to_i}" + "/annotate_models"
FileUtils.mkdir_p(@dir) FileUtils.mkdir_p(@dir)
AnnotateModels.model_dir = @dir AnnotateModels.model_dir = @dir
create('foo.rb', <<-EOS) create('foo.rb', <<-EOS)
class Foo < ActiveRecord::Base class Foo < ActiveRecord::Base
end end
...@@ -69,31 +103,42 @@ EOS ...@@ -69,31 +103,42 @@ EOS
acts_as_awesome :yah acts_as_awesome :yah
end end
EOS EOS
create('foo_with_utf8.rb', <<-EOS)
#encoding: utf-8
class FooWithUtf8 < ActiveRecord::Base
UTF8STRINGS = %w[résumé façon âge]
end
EOS
end end
it "should work" do it "should work" do
klass = AnnotateModels.get_model_class("foo.rb") klass = AnnotateModels.get_model_class("foo.rb")
klass.name.should == "Foo" klass.name.should == "Foo"
end end
it "should not care about unknown macros" do it "should not care about unknown macros" do
klass = AnnotateModels.get_model_class("foo_with_macro.rb") klass = AnnotateModels.get_model_class("foo_with_macro.rb")
klass.name.should == "FooWithMacro" klass.name.should == "FooWithMacro"
end end
it "should not complain of invalid multibyte char (USASCII)" do
klass = AnnotateModels.get_model_class("foo_with_utf8.rb")
klass.name.should == "FooWithUtf8"
end
end end
describe "#remove_annotation_of_file" do describe "#remove_annotation_of_file" do
def create(file, body="hi") def create(file, body="hi")
File.open(@dir + '/' + file, "w") do |f| File.open(file, "w") do |f|
f.puts(body) f.puts(body)
end end
end end
def content(file) def content(file)
File.read(@dir + '/' + file) File.read(file)
end end
before :all do it "should remove before annotate" do
require "tmpdir"
@dir = Dir.tmpdir + "/#{Time.now.to_i}" + "/annotate_models"
FileUtils.mkdir_p(@dir)
create("before.rb", <<-EOS) create("before.rb", <<-EOS)
# == Schema Information # == Schema Information
# #
...@@ -107,6 +152,16 @@ EOS ...@@ -107,6 +152,16 @@ EOS
class Foo < ActiveRecord::Base class Foo < ActiveRecord::Base
end end
EOS EOS
AnnotateModels.remove_annotation_of_file("before.rb")
content("before.rb").should == <<-EOS
class Foo < ActiveRecord::Base
end
EOS
end
it "should remove after annotate" do
create("after.rb", <<-EOS) create("after.rb", <<-EOS)
class Foo < ActiveRecord::Base class Foo < ActiveRecord::Base
end end
...@@ -121,21 +176,55 @@ end ...@@ -121,21 +176,55 @@ end
# #
EOS EOS
end
it "should remove before annotate" do AnnotateModels.remove_annotation_of_file("after.rb")
AnnotateModels.remove_annotation_of_file(@dir + '/' + "before.rb")
content("before.rb").should == <<-EOS content("after.rb").should == <<-EOS
class Foo < ActiveRecord::Base class Foo < ActiveRecord::Base
end end
EOS EOS
end end
it "should remove after annotate" do end
AnnotateModels.remove_annotation_of_file(@dir + '/' + "after.rb")
content("after.rb").should == <<-EOS describe "annotating a file" do
class Foo < ActiveRecord::Base before do
@file_name = "user.rb"
@file_content = <<-EOS
class User < ActiveRecord::Base
end end
EOS 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)
])
@schema_info = AnnotateModels.get_schema_info(@klass, "== Schema Info")
end 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}"
end 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}"
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}"
end
it "should update annotate position" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :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)
File.read(@file_name).should == "#{@file_content}\n#{another_schema_info}"
end
end
end end
--format=specdoc
--colour --colour
\ No newline at end of file
begin require 'rubygems'
require 'spec' require 'spec'
rescue LoadError
require 'rubygems'
gem 'rspec'
require 'spec'
end
$:.unshift(File.dirname(__FILE__) + '/../lib') $:.unshift(File.dirname(__FILE__) + '/../lib')
require 'annotate' require 'annotate'
TODO TODO
----- -----
change default position back to "top" for all
add "top" and "bottom" as synonyms for "before" and "after" add "top" and "bottom" as synonyms for "before" and "after"
change 'exclude' to 'only' (double negatives are not unconfusing) change 'exclude' to 'only' (double negatives are not unconfusing)
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