Commit 5b3d4459 by Alex Chaffee

Merge remote branch 'nofxx/master'

* nofxx/master: add simple_indexes option added blueprints/* dir annotate exemplars with unit tests added lil fix and v bump defaults to after the code jeweler!! merge IPGlider nice patches Now -p option also have effect on test, spec and Object Daddy files. Write default(FALSE) when the default value for a column is false. dont add whitespace on routes, and some minor stuff handle errors when not in a rails folder Organize the code better/adds some tests clean up hoe stuff forgot gemspec More lil fixes some fixes big commit.. * Now using jeweler * Rev version to 2.4 and get ready for big release
parents ed2cf5ec ffceca9b
......@@ -35,4 +35,3 @@
* spec/fixtures now also get annotated
* added a task to remove the annotations
* these options can be specified from command line as -d and -p [before|after]
History.txt
README.rdoc
Rakefile
annotate_models.gemspec
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
\ No newline at end of file
== Annotate (aka AnnotateModels)
Add a comment summarizing the relevant portion of the current schema to the top or bottom of your...
Add a comment summarizing the current schema to the top or bottom of each of your...
* ActiveRecord models
* Fixture files
* Tests and Specs
* Object Daddy exemplars
* Machinist blueprints
The schema comment looks like this:
......@@ -35,16 +36,7 @@ It also annotates geometrical columns, geom type and srid, when using SpatialAda
Also, if you pass the -r option, it'll annotate routes.rb with the output of "rake routes".
== Warning
Note that this code will blow away the initial/final comment
block in your models if it looks like it was previously added
by annotate models, so you don't want to add additional text
to an automatically created comment block.
* * Back up your model files before using... * *
== Install
== INSTALL
From rubyforge:
......@@ -57,7 +49,7 @@ From github:
rake gem
sudo gem install pkg/annotate-*.gem
== Usage
== USAGE
To annotate all your models, tests, fixtures, etc.:
......@@ -76,9 +68,13 @@ To annotate routes.rb:
annotate -r
More options:
To automatically annotate after running 'rake db:migrate':
Usage: annotate [options]
[needs more clarity] unpack the gem into vendor/plugins, or maybe vendor/gems, or maybe just require tasks/migrate.rake.
== OPTIONS
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'
......@@ -89,10 +85,27 @@ More options:
-R, --require path Additional files to require before loading models
-e, --exclude [tests,fixtures] Do not annotate fixtures, test files, or both
If you install annotate_models as a plugin, it will automatically
adjust your <tt>rake db:migrate</tt> tasks so that they update the
annotations in your model files for you once the migration is
completed.
If you install annotate_models as a plugin, it will automatically
adjust your <tt>rake db:migrate</tt> tasks so that they update the
annotations in your model files for you once the migration is
completed.
== WARNING
Note that this code will blow away the initial/final comment
block in your models if it looks like it was previously added
by annotate models, so you don't want to add additional text
to an automatically created comment block.
* * Back up your model files before using... * *
== LINKS
* Factory Girl => http://github.com/thoughtbot/factory_girl (NOT IMPLEMENTED)
* Object Daddy => http://github.com/flogic/object_daddy
* SpatialAdapter => http://github.com/pdeffendol/spatial_adapter
* PostgisAdapter => http://github.com/nofxx/postgis_adapter
== LICENSE:
......@@ -104,6 +117,23 @@ Original code by:
Dave Thomas -- Pragmatic Programmers, LLC
AnnotateModels mods by:
Alexander Semyonov ( http://github.com/rotuka/annotate_models )
AnnotateRoutes originally by:
Gavin Montague ( http://github.com/govan/annotate-routes )
== Forked from:
http://github.com/ctran/annotate_models
== Modifications
- alex@pivotallabs.com
=======
Modifications by:
- Alex Chaffee - http://github.com/alexch - alex@pivotallabs.com
......@@ -118,4 +148,10 @@ Modifications by:
and many others that I may have missed to add.
<<<<<<< HEAD
Primary maintainers: Cuong Tran and Alex Chaffee
=======
== This fork
Marcos Piccinini ( http://github.com/nofxx/annotate )
>>>>>>> nofxx/master
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
require File.dirname(__FILE__) + '/lib/annotate'
# Generate all the Rake tasks
# Run 'rake -T' to see list of generated tasks (from gem root directory)
$hoe = Hoe.new('annotate', Annotate::VERSION) do |p|
p.developer('Cuong Tran', 'ctran@pragmaquest.com')
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
p.rubyforge_name = 'annotate-models'
p.url = "http://github.com/ctran/annotate_models"
p.summary = "Annotates Rails Models, routes, and others"
p.description = "Annotates Rails Models, routes, and others"
p.extra_dev_deps = [
['newgem', ">= #{::Newgem::VERSION}"]
]
p.clean_globs |= %w[**/.DS_Store tmp *.log]
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
p.rsync_args = '-av --delete --ignore-errors'
require 'rubygems'
require 'rake'
require 'lib/annotate'
# want other tests/tasks run by default? Add them to the list
task :default => [:spec]
begin
require 'jeweler'
Jeweler::Tasks.new do |gem|
gem.name = "annotate"
gem.executables = "annotate"
gem.summary = "Annotates Rails Models, routes, fixtures, and others based on the database schema."
gem.description = gem.summary
gem.email = ["alex@stinky.com", 'ctran@pragmaquest.com', "x@nofxx.com"]
gem.homepage = "http://github.com/ctran/annotate"
gem.authors = ['Cuong Tran', "Alex Chaffee", "Marcos Piccinini"]
gem.files = FileList["[A-Z]*.*", "{bin,lib,tasks,spec}/**/*"]
gem.rubyforge_project = "annotate"
# 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
end
Jeweler::RubyforgeTasks.new do |rubyforge|
rubyforge.doc_task = "rdoc"
end
rescue LoadError
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
end
require 'newgem/tasks' # load /tasks/*.rake
Dir['tasks/**/*.rake'].each { |t| load t }
require 'spec/rake/spectask'
Spec::Rake::SpecTask.new(:spec) do |spec|
spec.libs << 'lib' << 'spec'
spec.spec_files = FileList['spec/**/*_spec.rb']
end
Spec::Rake::SpecTask.new(:rcov) do |spec|
spec.libs << 'lib' << 'spec'
spec.pattern = 'spec/**/*_spec.rb'
spec.rcov = true
end
# TODO - want other tests/tasks run by default? Add them to the list
task :default => [:spec, :features]
require 'rake/rdoctask'
Rake::RDocTask.new do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = "annotate #{Annotate.version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('lib/**/*.rb')
end
---
:major: 2
:minor: 4
:patch: 0
# Generated by jeweler
# DO NOT EDIT THIS FILE
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
# -*- encoding: utf-8 -*-
Gem::Specification.new do |s|
s.name = %q{annotate}
s.version = "2.1"
s.version = "2.4.0"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Cuong Tran"]
s.date = %q{2009-05-06}
s.authors = ["Cuong Tran", "Alex Chaffee", "Marcos Piccinini"]
s.date = %q{2009-10-23}
s.default_executable = %q{annotate}
s.description = %q{Annotates Rails Models, routes, and others}
s.email = ["ctran@pragmaquest.com"]
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.executables = ["annotate"]
s.extra_rdoc_files = ["History.txt", "README.rdoc"]
s.files = ["History.txt", "README.rdoc", "Rakefile", "annotate_models.gemspec", "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"]
s.has_rdoc = true
s.homepage = %q{http://github.com/ctran/annotate_models}
s.rdoc_options = ["--main", "README.rdoc"]
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",
"spec/annotate/annotate_models_spec.rb",
"spec/annotate/annotate_routes_spec.rb",
"spec/annotate_spec.rb",
"spec/spec.opts",
"spec/spec_helper.rb",
"tasks/migrate.rake"
]
s.homepage = %q{http://github.com/ctran/annotate}
s.rdoc_options = ["--charset=UTF-8"]
s.require_paths = ["lib"]
s.rubyforge_project = %q{annotate-models}
s.rubygems_version = %q{1.3.1}
s.summary = %q{Annotates Rails Models, routes, and others}
s.rubygems_version = %q{1.3.5}
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 = 2
s.specification_version = 3
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
s.add_development_dependency(%q<newgem>, [">= 1.4.1"])
s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
else
s.add_dependency(%q<newgem>, [">= 1.4.1"])
s.add_dependency(%q<hoe>, [">= 1.8.0"])
end
else
s.add_dependency(%q<newgem>, [">= 1.4.1"])
s.add_dependency(%q<hoe>, [">= 1.8.0"])
end
end
./annotate.gemspec
\ No newline at end of file
......@@ -25,7 +25,7 @@ OptionParser.new do |opts|
opts.on('-v', '--version',
"Show the current version of this gem") do
puts "annotate v#{Annotate::VERSION}"; exit
puts "annotate v#{Annotate.version}"; exit
end
opts.on('-m', '--show-migration',
......@@ -38,6 +38,11 @@ OptionParser.new do |opts|
ENV['show_indexes'] = "yes"
end
opts.on('-s', '--simple-indexes',
"Concat the column's related indexes in the annotation") do
ENV['simple_indexes'] = "yes"
end
opts.on('--model-dir dir',
"Annotate model files stored in dir rather than app/models") do |dir|
ENV['model_dir'] = dir
......
......@@ -2,7 +2,15 @@ $:.unshift(File.dirname(__FILE__)) unless
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
module Annotate
VERSION = '2.1'
def self.version
version_file = File.dirname(__FILE__) + "/../VERSION.yml"
if File.exist?(version_file)
config = YAML.load(File.read(version_file))
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
else
version = "0.0.0"
end
end
def self.load_tasks
if File.exists?('Rakefile')
......
......@@ -10,7 +10,10 @@ module AnnotateModels
UNIT_TEST_DIR = File.join("test", "unit" )
SPEC_MODEL_DIR = File.join("spec", "models")
# Object Daddy http://github.com/flogic/object_daddy/tree/master
EXEMPLARS_DIR = File.join("spec", "exemplars")
EXEMPLARS_TEST_DIR = File.join("test", "exemplars")
EXEMPLARS_SPEC_DIR = File.join("spec", "exemplars")
# Machinist http://github.com/notahat/machinist
BLUEPRINTS_DIR = File.join("test", "blueprints")
def model_dir
@model_dir || "app/models"
......@@ -45,7 +48,7 @@ module AnnotateModels
max_size = klass.column_names.collect{|name| name.size}.max + 1
klass.columns.each do |col|
attrs = []
attrs << "default(#{quote(col.default)})" if col.default
attrs << "default(#{quote(col.default)})" unless col.default.nil?
attrs << "not null" unless col.null
attrs << "primary key" if col.name == klass.primary_key
......@@ -62,6 +65,18 @@ module AnnotateModels
attrs << "#{col.geometry_type}, #{col.srid}"
end
# Check if the column has indices and print "indexed" if true
# If the indice include another colum, print it too.
if options[:simple_indexes] # Check out if this column is indexed
indices = klass.connection.indexes(klass.table_name)
if indices = indices.select { |ind| ind.columns.include? col.name }
indices.each do |ind|
ind = ind.columns.reject! { |i| i == col.name }
attrs << (ind.length == 0 ? "indexed" : "indexed => [#{ind.join(", ")}]")
end
end
end
info << sprintf("# %-#{max_size}.#{max_size}s:%-15.15s %s", col.name, col_type, attrs.join(", ")).rstrip + "\n"
end
......@@ -96,6 +111,8 @@ module AnnotateModels
# "before" or "after". Default is "before".
# :position_in_class<Symbol>:: where to place the annotated section in model file
# :position_in_fixture<Symbol>:: where to place the annotated section in fixture file
# :position_in_others<Symbol>:: where to place the annotated section in the rest of
# supported files
#
def annotate_one_file(file_name, info_block, options={})
if File.exist?(file_name)
......@@ -106,7 +123,6 @@ module AnnotateModels
old_header = old_content.match(header).to_s
new_header = info_block.match(header).to_s
old_header = ""
if old_header == new_header
false
else
......@@ -114,7 +130,7 @@ module AnnotateModels
old_content.sub!(/^# #{COMPAT_PREFIX}.*?\n(#.*\n)*\n/, '')
# Write it back
new_content = ((options[:position] || :before).to_sym == :before) ? (info_block + old_content) : (old_content + "\n" + info_block)
new_content = options[:position] == 'before' ? (info_block + old_content) : (old_content + "\n" + info_block)
File.open(file_name, "wb") { |f| f.puts new_content }
true
......@@ -144,7 +160,7 @@ module AnnotateModels
model_name = klass.name.underscore
model_file_name = File.join(model_dir, file)
if annotate_one_file(model_file_name, info, options_with_position(:position_in_class))
if annotate_one_file(model_file_name, info, options_with_position(options, :position_in_class))
annotated = true
end
......@@ -153,18 +169,24 @@ module AnnotateModels
File.join(UNIT_TEST_DIR, "#{model_name}_test.rb"), # test
File.join(SPEC_MODEL_DIR, "#{model_name}_spec.rb"), # spec
].each do |file|
annotate_one_file(file, info, options_with_position(:position_in_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))
end
end
unless ENV['exclude_fixtures']
file = File.join(EXEMPLARS_DIR, "#{model_name}_exemplar.rb") # Object Daddy
annotate_one_file(file, info, options_with_position(:position_in_fixture))
[
File.join(EXEMPLARS_TEST_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
].each do |file|
annotate_one_file(file, info, options_with_position(options, :position_in_fixture))
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(:position_in_fixture))
annotate_one_file(fixture_file_name, info, options_with_position(options, :position_in_fixture))
end
end
end
......@@ -173,7 +195,7 @@ module AnnotateModels
end
# position = :position_in_fixture or :position_in_class
def options_with_position(position_in)
def options_with_position(options, position_in)
options.merge(:position=>(options[position_in] || options[:position]))
end
......@@ -251,6 +273,7 @@ module AnnotateModels
rescue Exception => e
puts "Unable to annotate #{file}: #{e.inspect}"
puts ""
puts e.backtrace.join("\n\t")
end
end
if annotated.empty?
......
......@@ -5,9 +5,10 @@ task :annotate_models => :environment do
options[:position_in_class] = ENV['position_in_class'] || ENV['position'] || :before
options[:position_in_fixture] = ENV['position_in_fixture'] || ENV['position'] || :before
options[:show_indexes] = ENV['show_indexes']
options[:simple_indexes] = ENV['simple_indexes']
options[:model_dir] = ENV['model_dir']
options[:include_version] = ENV['include_version']
options[:require] = ENV['require'] ? ENV['require'].split(',') : nil
options[:require] = ENV['require'] ? ENV['require'].split(',') : []
AnnotateModels.do_annotations(options)
end
......
#!/usr/bin/env ruby
# File: script/console
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
libs = " -r irb/completion"
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
libs << " -r #{File.dirname(__FILE__) + '/../lib/annotate_models.rb'}"
puts "Loading annotate_models gem"
exec "#{irb} #{libs} --simple-prompt"
\ No newline at end of file
#!/usr/bin/env ruby
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
begin
require 'rubigen'
rescue LoadError
require 'rubygems'
require 'rubigen'
end
require 'rubigen/scripts/destroy'
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
RubiGen::Scripts::Destroy.new.run(ARGV)
#!/usr/bin/env ruby
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
begin
require 'rubigen'
rescue LoadError
require 'rubygems'
require 'rubigen'
end
require 'rubigen/scripts/generate'
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
RubiGen::Scripts::Generate.new.run(ARGV)
......@@ -23,6 +23,7 @@ describe AnnotateModels do
it "should get schema info" do
AnnotateModels.get_schema_info(mock_klass(
:connection => mock("Conn", :indexes => []),
:table_name => "users",
:primary_key => "id",
:column_names => ["id","login"],
......
......@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
describe Annotate do
it "should have a version" do
Annotate::VERSION.should be_instance_of(String)
Annotate.version.should be_instance_of(String)
end
end
# append annotations to Rake tasks (for ActiveRecord)
# These tasks are added to the project if you install annotate as a Rails plugin.
# (They are not used to build annotate itself.)
# Append annotations to Rake tasks for ActiveRecord, so annotate automatically gets
# run after doing db:migrate.
# 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.
namespace :db do
task :migrate do
Annotate::Migration.update_annotations
......
begin
require 'spec'
rescue LoadError
require 'rubygems'
require 'spec'
end
begin
require 'spec/rake/spectask'
rescue LoadError
puts <<-EOS
To use rspec for testing you must install rspec gem:
gem install rspec
EOS
exit(0)
end
desc "Run the specs under spec/models"
Spec::Rake::SpecTask.new do |t|
t.spec_opts = ['--options', "spec/spec.opts"]
t.spec_files = FileList['spec/**/*_spec.rb']
end
TODO
-----
change default position back to "top" for all
add "top" and "bottom" as synonyms for "before" and "after"
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