Commit 5f37a974 by cuong.tran

Merge branch 'release/v2.7.2'

parents 0b054562 edd17864
!/spec/integration/*/log/.gitkeep
!/spec/integration/*/tmp/.gitkeep
*.gem
.DS_Store .DS_Store
.bundle
.gems
.rbenv-version
.ruby-*
/.idea/
/.rbx
/.rvmrc
/.yardoc/* /.yardoc/*
/doc/* /Gemfile.lock
/coverage/* /coverage/*
/spec/debug.log
/pkg/*
/dist /dist
/Gemfile.lock /doc/*
*.gem /pkg/*
/.idea/ /spec/debug.log
/.rvmrc
.bundle
/.rbx
/spec/integration/*/bin/ /spec/integration/*/bin/
/spec/integration/*/db/test.*
/spec/integration/*/log/* /spec/integration/*/log/*
!/spec/integration/*/log/.gitkeep
/spec/integration/*/tmp/* /spec/integration/*/tmp/*
!/spec/integration/*/tmp/.gitkeep .byebug_history
/spec/integration/*/db/test.*
.rbenv-version
\ No newline at end of file
# Use this file to configure the Overcommit hooks you wish to use. This will
# extend the default configuration defined in:
# https://github.com/brigade/overcommit/blob/master/config/default.yml
#
# At the topmost level of this YAML file is a key representing type of hook
# being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
# customize each hook, such as whether to only run it on certain files (via
# `include`), whether to only display output if it fails (via `quiet`), etc.
#
# For a complete list of hooks, see:
# https://github.com/brigade/overcommit/tree/master/lib/overcommit/hook
#
# For a complete list of options that you can use to customize hooks, see:
# https://github.com/brigade/overcommit#configuration
#
# Uncomment the following lines to make the configuration take effect.
PreCommit:
RuboCop:
enabled: true
on_warn: fail # Treat all warnings as failures
PrePush:
RSpec:
enabled: true
on_warn: fail # Treat all warnings as failures
#
# TrailingWhitespace:
# enabled: true
# exclude:
# - '**/db/structure.sql' # Ignore trailing whitespace in generated files
#
#PostCheckout:
# ALL: # Special hook name that customizes all hooks of this type
# quiet: true # Change all post-checkout hooks to only display output on failure
#
# IndexTags:
# enabled: true # Generate a tags file with `ctags` each time HEAD changes
inherit_from: ./.rubocop_todo.yml
AllCops:
Exclude:
- 'vendor/**/*'
- 'spec/fixtures/**/*'
- 'tmp/**/*'
...@@ -4,7 +4,16 @@ rvm: ...@@ -4,7 +4,16 @@ rvm:
- 1.9.3 - 1.9.3
- 2.0 - 2.0
- 2.1 - 2.1
- 2.2 - 2.2.5
- 2.3.0-preview1 - 2.3.0
- 2.4.0
- ruby-head
matrix:
allow_failures:
- rvm: ruby-head
- rvm: 1.9.3
before_install: before_install:
- rvm @global do gem install bundler - gem update --system
- gem update bundler
script:
- bundle exec rubocop && bundle exec rspec
...@@ -29,5 +29,6 @@ With help from: ...@@ -29,5 +29,6 @@ With help from:
- Paul Alexander - Paul Alexander
- Dmitry Lihachev - Dmitry Lihachev
- qichunren - qichunren
- Guillermo Guerrero - http://github.com/ryanfox1985
and many others that I may have forgotten to add. and many others that I may have forgotten to add.
== 2.7.2
See https://github.com/ctran/annotate_models/releases/tag/v2.7.2
== 2.7.1
See https://github.com/ctran/annotate_models/releases/tag/v2.7.1
== 2.7.0 == 2.7.0
See https://github.com/ctran/annotate_models/releases/tag/v2.7.0 See https://github.com/ctran/annotate_models/releases/tag/v2.7.0
......
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'rake', '>= 10.4.2', :require => false gem 'activerecord', '>= 4.2.5', require: false
gem 'activerecord', '>= 4.2.5', :require => false gem 'rake', require: false
group :development do group :development do
gem 'mg', :require => false
gem 'bump' gem 'bump'
platforms :mri do gem 'mg', require: false
gem 'yard', :require => false platforms :mri, :mingw do
gem 'yard', require: false
end end
end end
group :development, :test do group :development, :test do
gem 'rspec', :require => false gem 'byebug'
gem 'guard-rspec', :require => false gem 'guard-rspec', require: false
gem 'terminal-notifier-guard', :require => false gem 'rspec', require: false
platforms :mri do gem 'rubocop', '~> 0.46.0', require: false unless RUBY_VERSION =~ /^1.8/
gem 'pry', :require => false gem 'simplecov', require: false
gem 'pry-coolline', :require => false gem 'terminal-notifier-guard', require: false
gem 'codeclimate-test-reporter'
gem 'coveralls'
gem 'overcommit'
gem 'ruby_dep', '1.3.1'
platforms :mri, :mingw do
gem 'pry', require: false
gem 'pry-coolline', require: false
end end
end end
group :test do group :test do
gem 'wrong', :require => false gem 'files', require: false
gem 'files', :require => false gem 'wrong', require: false
end end
# Note: The cmd option is now required due to the increasing number of ways # Note: The cmd option is now required due to the increasing number of ways
# rspec may be run, below are examples of the most common uses. # rspec may be run, below are examples of the most common uses.
# * bundler: 'bundle exec rspec' # * bundler: 'bundle exec rspec'
...@@ -11,16 +9,16 @@ ...@@ -11,16 +9,16 @@
guard :rspec, cmd: 'bundle exec rspec' do guard :rspec, cmd: 'bundle exec rspec' do
watch(%r{^spec/.+_spec\.rb$}) watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" } watch('spec/spec_helper.rb') { 'spec' }
# Rails example # Rails example
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" } watch(%r{^spec/support/(.+)\.rb$}) { 'spec' }
watch('config/routes.rb') { "spec/routing" } watch('config/routes.rb') { 'spec/routing' }
watch('app/controllers/application_controller.rb') { "spec/controllers" } watch('app/controllers/application_controller.rb') { 'spec/controllers' }
watch('spec/rails_helper.rb') { "spec" } watch('spec/rails_helper.rb') { 'spec' }
# Capybara features specs # Capybara features specs
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" } watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
...@@ -29,4 +27,3 @@ guard :rspec, cmd: 'bundle exec rspec' do ...@@ -29,4 +27,3 @@ guard :rspec, cmd: 'bundle exec rspec' do
watch(%r{^spec/acceptance/(.+)\.feature$}) watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end end
== Annotate (aka AnnotateModels) == Annotate (aka AnnotateModels)
{<img src="https://badge.fury.io/rb/annotate.svg" alt="Gem Version" />}[http://badge.fury.io/rb/annotate] {<img src="https://badge.fury.io/rb/annotate.svg" alt="Gem Version" />}[http://badge.fury.io/rb/annotate]
{<img src="https://travis-ci.org/ctran/annotate_models.png" />}[https://travis-ci.org/ctran/annotate_models] {<img src="https://img.shields.io/gem/dt/annotate.svg?style=flat" />}[https://rubygems.org/gems/annotate]
{<img src="https://travis-ci.org/ctran/annotate_models.svg?branch=develop" />}[https://travis-ci.org/ctran/annotate_models]
{<img src="https://coveralls.io/repos/ctran/annotate_models/badge.svg?branch=develop" />}[https://coveralls.io/r/ctran/annotate_models?branch=develop]
{<img src="https://codeclimate.com/github/ctran/annotate_models/badges/gpa.svg" />}[https://codeclimate.com/github/ctran/annotate_models]
{<img src="http://inch-ci.org/github/ctran/annotate_models.svg?branch=develop" alt="Inline docs" />}[http://inch-ci.org/github/ctran/annotate_models]
{<img src="https://gemnasium.com/ctran/annotate_models.png" />}[https://gemnasium.com/ctran/annotate_models] {<img src="https://gemnasium.com/ctran/annotate_models.png" />}[https://gemnasium.com/ctran/annotate_models]
Add a comment summarizing the current schema to the top or bottom of each of Add a comment summarizing the current schema to the top or bottom of each of
...@@ -44,7 +48,7 @@ It also annotates geometrical columns, geom type and srid, when using ...@@ -44,7 +48,7 @@ It also annotates geometrical columns, geom type and srid, when using
# path :geometry line_string, 4326 # path :geometry line_string, 4326
Also, if you pass the -r option, it'll annotate routes.rb with the output of Also, if you pass the -r option, it'll annotate routes.rb with the output of
+rake routes+. <code>rake routes</code>.
== Install == Install
...@@ -55,7 +59,7 @@ Into Gemfile from rubygems.org: ...@@ -55,7 +59,7 @@ Into Gemfile from rubygems.org:
Into Gemfile from Github: Into Gemfile from Github:
gem 'annotate', github: 'ctran/annotate_models' gem 'annotate', git: 'https://github.com/ctran/annotate_models.git'
Into environment gems from rubygems.org: Into environment gems from rubygems.org:
...@@ -63,7 +67,7 @@ Into environment gems from rubygems.org: ...@@ -63,7 +67,7 @@ Into environment gems from rubygems.org:
Into environment gems from Github checkout: Into environment gems from Github checkout:
git clone git://github.com/ctran/annotate_models.git annotate_models git clone https://github.com/ctran/annotate_models.git annotate_models
cd annotate_models cd annotate_models
rake build rake build
gem install pkg/annotate-*.gem gem install pkg/annotate-*.gem
...@@ -71,7 +75,7 @@ Into environment gems from Github checkout: ...@@ -71,7 +75,7 @@ Into environment gems from Github checkout:
== Usage == Usage
(If you used the Gemfile install, prefix the below commands with +bundle exec+.) (If you used the Gemfile install, prefix the below commands with <code>bundle exec</code>.)
=== Usage in Rails === Usage in Rails
...@@ -100,7 +104,7 @@ To remove routes.rb annotations: ...@@ -100,7 +104,7 @@ To remove routes.rb annotations:
annotate --routes --delete annotate --routes --delete
To automatically annotate every time you run +db:migrate+, either run +rails g annotate:install+ or add +Annotate.load_tasks+ to your `Rakefile`. See the [configuration in Rails](#configuration-in-rails) section for more info. To automatically annotate every time you run <code>db:migrate</code>, either run <code>rails g annotate:install</code> or add +Annotate.load_tasks+ to your `Rakefile`. See the {configuration in Rails}[link:README.rdoc#configuration-in-rails] section for more info.
=== Usage Outside of Rails === Usage Outside of Rails
...@@ -136,7 +140,7 @@ functionality: ...@@ -136,7 +140,7 @@ functionality:
rake remove_annotation # Remove schema information from model and fixture files rake remove_annotation # Remove schema information from model and fixture files
By default, once you've generated a configuration file, annotate will be By default, once you've generated a configuration file, annotate will be
executed whenever you run +rake db:migrate+ (but only in development mode). executed whenever you run <code>rake db:migrate</code> (but only in development mode).
If you want to disable this behavior permanently, edit the +.rake+ file and If you want to disable this behavior permanently, edit the +.rake+ file and
change: change:
...@@ -146,7 +150,7 @@ To: ...@@ -146,7 +150,7 @@ To:
'skip_on_db_migrate' => 'true', 'skip_on_db_migrate' => 'true',
If you want to run +rake db:migrate+ as a one-off without running annotate, If you want to run <code>rake db:migrate</code> as a one-off without running annotate,
you can do so with a simple environment variable, instead of editing the you can do so with a simple environment variable, instead of editing the
+.rake+ file: +.rake+ file:
...@@ -175,12 +179,13 @@ you can do so with a simple environment variable, instead of editing the ...@@ -175,12 +179,13 @@ you can do so with a simple environment variable, instead of editing the
--wo, --wrapper-open STR Annotation wrapper opening. --wo, --wrapper-open STR Annotation wrapper opening.
--wc, --wrapper-close STR Annotation wrapper closing --wc, --wrapper-close STR Annotation wrapper closing
-r, --routes Annotate routes.rb with the output of 'rake routes' -r, --routes Annotate routes.rb with the output of 'rake routes'
-aa, --active-admin Annotate all activeadmin models
-v, --version Show the current version of this gem -v, --version Show the current version of this gem
-m, --show-migration Include the migration version number in the annotation -m, --show-migration Include the migration version number in the annotation
-i, --show-indexes List the table's database indexes in the annotation -i, --show-indexes List the table's database indexes in the annotation
-k, --show-foreign-keys List the table's foreign key constraints in the annotation -k, --show-foreign-keys List the table's foreign key constraints in the annotation
-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, separate multiple dirs with comas --model-dir dir Annotate model files stored in dir rather than app/models, separate multiple dirs with commas
--ignore-model-subdirects Ignore subdirectories of the models directory --ignore-model-subdirects Ignore subdirectories of the models directory
--sort Sort columns alphabetically, rather than in creation order --sort Sort columns alphabetically, rather than in creation order
-R, --require path Additional file to require before loading models, may be used multiple times -R, --require path Additional file to require before loading models, may be used multiple times
......
...@@ -4,36 +4,45 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) ...@@ -4,36 +4,45 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'annotate/version' require 'annotate/version'
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = "annotate" s.name = 'annotate'
s.version = Annotate.version s.version = Annotate.version
s.required_ruby_version = '>= 1.9.3' s.required_ruby_version = '>= 1.9.3'
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 = ["Alex Chaffee", "Cuong Tran", "Marcos Piccinini", "Turadg Aleahmad", "Jon Frisby"] s.authors = ['Alex Chaffee', 'Cuong Tran', 'Marcos Piccinini', 'Turadg Aleahmad', 'Jon Frisby']
s.description = "Annotates Rails/ActiveRecord Models, routes, fixtures, and others based on the database schema." s.description = 'Annotates Rails/ActiveRecord Models, routes, fixtures, and others based on the database schema.'
s.email = ["alex@stinky.com", "cuong.tran@gmail.com", "x@nofxx.com", "turadg@aleahmad.net", "jon@cloudability.com"] s.email = ['alex@stinky.com', 'cuong.tran@gmail.com', 'x@nofxx.com', 'turadg@aleahmad.net', 'jon@cloudability.com']
s.executables = ["annotate"] s.executables = ['annotate']
s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "TODO.rdoc"] s.extra_rdoc_files = ['README.rdoc', 'CHANGELOG.rdoc', 'TODO.rdoc']
s.files = ["AUTHORS.rdoc", "CHANGELOG.rdoc", "LICENSE.txt", "README.rdoc", "TODO.rdoc", "annotate.gemspec", "bin/annotate", "lib/annotate.rb", "lib/annotate/active_record_patch.rb", "lib/annotate/annotate_models.rb", "lib/annotate/annotate_routes.rb", "lib/annotate/tasks.rb", "lib/annotate/version.rb", "lib/generators/annotate/USAGE", "lib/generators/annotate/install_generator.rb", "lib/generators/annotate/templates/auto_annotate_models.rake", "lib/tasks/annotate_models.rake", "lib/tasks/annotate_routes.rake", "lib/tasks/migrate.rake"] s.files = [
s.homepage = "http://github.com/ctran/annotate_models" 'AUTHORS.rdoc',
s.licenses = ["Ruby"] 'CHANGELOG.rdoc',
s.require_paths = ["lib"] 'LICENSE.txt',
s.rubyforge_project = "annotate" 'README.rdoc',
s.rubygems_version = "2.1.11" 'TODO.rdoc',
s.summary = "Annotates Rails Models, routes, fixtures, and others based on the database schema." 'annotate.gemspec',
'bin/annotate',
'lib/annotate.rb',
'lib/annotate/active_record_patch.rb',
'lib/annotate/annotate_models.rb',
'lib/annotate/annotate_routes.rb',
'lib/annotate/tasks.rb',
'lib/annotate/version.rb',
'lib/generators/annotate/USAGE',
'lib/generators/annotate/install_generator.rb',
'lib/generators/annotate/templates/auto_annotate_models.rake',
'lib/tasks/annotate_models.rake',
'lib/tasks/annotate_routes.rake',
'lib/tasks/annotate_models_migrate.rake'
]
s.homepage = 'http://github.com/ctran/annotate_models'
s.licenses = ['Ruby']
s.require_paths = ['lib']
s.rubyforge_project = 'annotate'
s.rubygems_version = '2.1.11'
s.summary = 'Annotates Rails Models, routes, fixtures, and others based on the database schema.'
if s.respond_to? :specification_version then s.specification_version = 4 if s.respond_to? :specification_version
s.specification_version = 4 s.add_runtime_dependency(%q<rake>, ['>= 10.4', '< 13.0'])
s.add_runtime_dependency(%q<activerecord>, ['>= 3.2', '< 6.0'])
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<rake>, ["~> 10.4"])
s.add_runtime_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
else
s.add_dependency(%q<rake>, ["~> 10.4"])
s.add_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
end
else
s.add_dependency(%q<rake>, [">= 0.8.7"])
s.add_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
end
end end
machine:
ruby:
version: 2.2.6
test:
override:
- bundle exec rubocop && bundle exec rspec
$:.unshift(File.dirname(__FILE__)) # rubocop:disable Metrics/ModuleLength
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'annotate/version' require 'annotate/version'
require 'annotate/annotate_models' require 'annotate/annotate_models'
require 'annotate/annotate_routes' require 'annotate/annotate_routes'
...@@ -7,60 +9,70 @@ begin ...@@ -7,60 +9,70 @@ begin
# ActiveSupport 3.x... # ActiveSupport 3.x...
require 'active_support/hash_with_indifferent_access' require 'active_support/hash_with_indifferent_access'
require 'active_support/core_ext/object/blank' require 'active_support/core_ext/object/blank'
rescue Exception rescue StandardError
# ActiveSupport 2.x... # ActiveSupport 2.x...
require 'active_support/core_ext/hash/indifferent_access' require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/blank' require 'active_support/core_ext/blank'
end end
module Annotate module Annotate
TRUE_RE = /^(true|t|yes|y|1)$/i
## ##
# The set of available options to customize the behavior of Annotate. # The set of available options to customize the behavior of Annotate.
# #
POSITION_OPTIONS=[ POSITION_OPTIONS = [
:position_in_routes, :position_in_class, :position_in_test, :position_in_routes, :position_in_class, :position_in_test,
:position_in_fixture, :position_in_factory, :position, :position_in_fixture, :position_in_factory, :position,
:position_in_serializer :position_in_serializer
] ].freeze
FLAG_OPTIONS=[ FLAG_OPTIONS = [
:show_indexes, :simple_indexes, :include_version, :exclude_tests, :show_indexes, :simple_indexes, :include_version, :exclude_tests,
:exclude_fixtures, :exclude_factories, :ignore_model_sub_dir, :exclude_fixtures, :exclude_factories, :ignore_model_sub_dir,
:format_bare, :format_rdoc, :format_markdown, :sort, :force, :trace, :format_bare, :format_rdoc, :format_markdown, :sort, :force, :trace,
:timestamp, :exclude_serializers, :classified_sort, :show_foreign_keys, :timestamp, :exclude_serializers, :classified_sort, :show_foreign_keys,
:exclude_scaffolds, :exclude_controllers, :exclude_helpers, :ignore_unknown_models, :exclude_scaffolds, :exclude_controllers, :exclude_helpers,
] :exclude_sti_subclasses, :ignore_unknown_models
OTHER_OPTIONS=[ ].freeze
:ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close, :wrapper, :routes, OTHER_OPTIONS = [
:hide_limit_column_types, :ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close,
] :wrapper, :routes, :hide_limit_column_types, :hide_default_column_types,
PATH_OPTIONS=[ :ignore_routes, :active_admin
].freeze
PATH_OPTIONS = [
:require, :model_dir, :root_dir :require, :model_dir, :root_dir
] ].freeze
def self.all_options
[POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS]
end
## ##
# Set default values that can be overridden via environment variables. # Set default values that can be overridden via environment variables.
# #
def self.set_defaults(options = {}) def self.set_defaults(options = {})
return if(@has_set_defaults) return if @has_set_defaults
@has_set_defaults = true @has_set_defaults = true
options = HashWithIndifferentAccess.new(options) options = HashWithIndifferentAccess.new(options)
[POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key| all_options.flatten.each do |key|
if options.has_key?(key) if options.key?(key)
default_value = if options[key].is_a?(Array) default_value = if options[key].is_a?(Array)
options[key].join(",") options[key].join(',')
else else
options[key] options[key]
end end
end end
default_value = ENV[key.to_s] if !ENV[key.to_s].blank? default_value = ENV[key.to_s] unless ENV[key.to_s].blank?
ENV[key.to_s] = default_value.nil? ? nil : default_value.to_s ENV[key.to_s] = default_value.nil? ? nil : default_value.to_s
end end
end end
TRUE_RE = /^(true|t|yes|y|1)$/i ##
# TODO: what is the difference between this and set_defaults?
#
def self.setup_options(options = {}) def self.setup_options(options = {})
POSITION_OPTIONS.each do |key| POSITION_OPTIONS.each do |key|
options[key] = fallback(ENV[key.to_s], ENV['position'], 'before') options[key] = fallback(ENV[key.to_s], ENV['position'], 'before')
...@@ -69,30 +81,27 @@ module Annotate ...@@ -69,30 +81,27 @@ module Annotate
options[key] = true?(ENV[key.to_s]) options[key] = true?(ENV[key.to_s])
end end
OTHER_OPTIONS.each do |key| OTHER_OPTIONS.each do |key|
options[key] = (!ENV[key.to_s].blank?) ? ENV[key.to_s] : nil options[key] = !ENV[key.to_s].blank? ? ENV[key.to_s] : nil
end end
PATH_OPTIONS.each do |key| PATH_OPTIONS.each do |key|
options[key] = (!ENV[key.to_s].blank?) ? ENV[key.to_s].split(',') : [] options[key] = !ENV[key.to_s].blank? ? ENV[key.to_s].split(',') : []
end end
if(options[:model_dir].empty?) options[:model_dir] = ['app/models'] if options[:model_dir].empty?
options[:model_dir] = ['app/models']
end
if(options[:root_dir].empty?)
options[:root_dir] = ['']
end
options[:wrapper_open] ||= options[:wrapper] options[:wrapper_open] ||= options[:wrapper]
options[:wrapper_close] ||= options[:wrapper] options[:wrapper_close] ||= options[:wrapper]
return options # These were added in 2.7.0 but so this is to revert to old behavior by default
options[:exclude_scaffolds] = Annotate.true?(ENV.fetch('exclude_scaffolds', 'true'))
options[:exclude_controllers] = Annotate.true?(ENV.fetch('exclude_controllers', 'true'))
options[:exclude_helpers] = Annotate.true?(ENV.fetch('exclude_helpers', 'true'))
options
end end
def self.reset_options def self.reset_options
[POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key| all_options.flatten.each { |key| ENV[key.to_s] = nil }
ENV[key.to_s] = nil
end
end end
def self.skip_on_migration? def self.skip_on_migration?
...@@ -107,26 +116,34 @@ module Annotate ...@@ -107,26 +116,34 @@ module Annotate
true true
end end
def self.loaded_tasks=(val); @loaded_tasks = val; end def self.loaded_tasks=(val)
def self.loaded_tasks; return @loaded_tasks; end @loaded_tasks = val
end
def self.loaded_tasks
@loaded_tasks
end
def self.load_tasks def self.load_tasks
return if(self.loaded_tasks) return if loaded_tasks
self.loaded_tasks = true self.loaded_tasks = true
Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each { |rake| load rake } Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each do |rake|
load rake
end
end end
def self.load_requires(options) def self.load_requires(options)
options[:require].each { |path| require path } if options[:require].count > 0 options[:require].count > 0 &&
options[:require].each { |path| require path }
end end
def self.eager_load(options) def self.eager_load(options)
self.load_requires(options) load_requires(options)
require "annotate/active_record_patch" require 'annotate/active_record_patch'
if(defined?(Rails)) if defined?(Rails::Application)
if(Rails.version.split('.').first.to_i < 3) if Rails.version.split('.').first.to_i < 3
Rails.configuration.eager_load_paths.each do |load_path| Rails.configuration.eager_load_paths.each do |load_path|
matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/ matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
Dir.glob("#{load_path}/**/*.rb").sort.each do |file| Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
...@@ -149,33 +166,38 @@ module Annotate ...@@ -149,33 +166,38 @@ module Annotate
def self.bootstrap_rake def self.bootstrap_rake
begin begin
require 'rake/dsl_definition' require 'rake/dsl_definition'
rescue Exception rescue StandardError => e
# We might just be on an old version of Rake... # We might just be on an old version of Rake...
puts e.message
exit e.status_code
end end
require 'rake' require 'rake'
if File.exists?('./Rakefile') load './Rakefile' if File.exist?('./Rakefile')
load './Rakefile' begin
Rake::Task[:environment].invoke
rescue
nil
end end
Rake::Task[:environment].invoke rescue nil unless defined?(Rails)
if(!defined?(Rails))
# Not in a Rails project, so time to load up the parts of # Not in a Rails project, so time to load up the parts of
# ActiveSupport we need. # ActiveSupport we need.
require 'active_support' require 'active_support'
require 'active_support/core_ext/class/subclasses' require 'active_support/core_ext/class/subclasses'
require 'active_support/core_ext/string/inflections' require 'active_support/core_ext/string/inflections'
end end
self.load_tasks
load_tasks
Rake::Task[:set_annotation_options].invoke Rake::Task[:set_annotation_options].invoke
end end
def self.fallback(*args) def self.fallback(*args)
return args.detect { |arg| !arg.blank? } args.detect { |arg| !arg.blank? }
end end
def self.true?(val) def self.true?(val)
return false if(val.blank?) return false if val.blank?
return false unless(val =~ TRUE_RE) return false unless val =~ TRUE_RE
return true true
end end
end end
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
module ::ActiveRecord module ::ActiveRecord
class Base class Base
def self.method_missing(name, *args) def self.method_missing(_name, *_args)
# ignore this, so unknown/unloaded macros won't cause parsing to fail # ignore this, so unknown/unloaded macros won't cause parsing to fail
end end
end end
......
...@@ -18,139 +18,181 @@ ...@@ -18,139 +18,181 @@
# Released under the same license as Ruby. No Support. No Warranty. # Released under the same license as Ruby. No Support. No Warranty.
# #
module AnnotateRoutes module AnnotateRoutes
PREFIX = "# == Route Map" PREFIX = '== Route Map'.freeze
PREFIX_MD = '## Route Map'.freeze
HEADER_ROW = ['Prefix', 'Verb', 'URI Pattern', 'Controller#Action']
def self.do_annotations(options={}) class << self
return unless(routes_exists?) def content(line, maxs, options = {})
return line.rstrip unless options[:format_markdown]
position_after = ! %w(before top).include?(options[:position_in_routes]) line.each_with_index.map do |elem, index|
min_length = maxs.map { |arr| arr[index] }.max || 0
routes_map = `rake routes`.split(/\n/, -1) sprintf("%-#{min_length}.#{min_length}s", elem.tr('|', '-'))
end.join(' | ')
end
# In old versions of Rake, the first line of output was the cwd. Not so def header(options = {})
# much in newer ones. We ditch that line if it exists, and if not, we routes_map = app_routes_map(options)
# keep the line around.
routes_map.shift if(routes_map.first =~ /^\(in \//)
header = [
"#{PREFIX}" + (options[:timestamp] ? " (Updated #{Time.now.strftime("%Y-%m-%d %H:%M")})" : ""),
"#"
] + routes_map.map { |line| "# #{line}".rstrip }
existing_text = File.read(routes_file)
(content, where_header_found) = strip_annotations(existing_text)
changed = where_header_found != 0 # This will either be :before, :after, or
# a number. If the number is > 0, the
# annotation was found somewhere in the
# middle of the file. If the number is
# zero, no annotation was found.
if(position_after)
# Ensure we have adequate trailing newlines at the end of the file to
# ensure a blank line separating the content from the annotation.
content << '' if(content.last != '')
# We're moving something from the top of the file to the bottom, so ditch out = ["# #{options[:format_markdown] ? PREFIX_MD : PREFIX}" + (options[:timestamp] ? " (Updated #{Time.now.strftime('%Y-%m-%d %H:%M')})" : '')]
# the spacer we put in the first time around. out += ['#']
if(changed && where_header_found == :before) return out if routes_map.size.zero?
content.shift if(content.first == '')
maxs = [HEADER_ROW.map(&:size)] + routes_map[1..-1].map { |line| line.split.map(&:size) }
if options[:format_markdown]
max = maxs.map(&:max).compact.max
out += ["# #{content(HEADER_ROW, maxs, options)}"]
out += ["# #{content(['-' * max, '-' * max, '-' * max, '-' * max], maxs, options)}"]
else
out += ["# #{content(routes_map[0], maxs, options)}"]
end end
else
header = header << '' if(content.first != '' || changed) out + routes_map[1..-1].map { |line| "# #{content(options[:format_markdown] ? line.split(' ') : line, maxs, options)}" }
end end
content = position_after ? (content + header) : header + content def do_annotations(options = {})
return unless routes_exists?
existing_text = File.read(routes_file)
if write_contents(existing_text, content) if write_contents(existing_text, header(options), options)
puts "#{routes_file} annotated." puts "#{routes_file} annotated."
else end
puts "#{routes_file} unchanged."
end end
end
def self.remove_annotations(options={}) def remove_annotations(options={})
return unless(routes_exists?) return unless routes_exists?
existing_text = File.read(routes_file) existing_text = File.read(routes_file)
(content, where_header_found) = strip_annotations(existing_text) content, where_header_found = strip_annotations(existing_text)
content = strip_on_removal(content, where_header_found) content = strip_on_removal(content, where_header_found)
if write_contents(existing_text, content) if write_contents(existing_text, content, options)
puts "Removed annotations from #{routes_file}." puts "Removed annotations from #{routes_file}."
else end
puts "#{routes_file} unchanged."
end end
end end
protected private
def self.app_routes_map(options)
routes_map = `rake routes`.split(/\n/, -1)
# In old versions of Rake, the first line of output was the cwd. Not so
# much in newer ones. We ditch that line if it exists, and if not, we
# keep the line around.
routes_map.shift if routes_map.first =~ /^\(in \//
# Skip routes which match given regex
# Note: it matches the complete line (route_name, path, controller/action)
if options[:ignore_routes]
routes_map.reject! { |line| line =~ /#{options[:ignore_routes]}/ }
end
routes_map
end
def self.routes_file def self.routes_file
@routes_rb ||= File.join("config", "routes.rb") @routes_rb ||= File.join('config', 'routes.rb')
end end
def self.routes_exists? def self.routes_exists?
routes_exists = File.exists?(routes_file) routes_exists = File.exists?(routes_file)
puts "Can`t find routes.rb" if(!routes_exists) puts "Can't find routes.rb" unless routes_exists
return routes_exists
routes_exists
end end
def self.write_contents(existing_text, new_content) def self.write_contents(existing_text, header, options = {})
content, where_header_found = strip_annotations(existing_text)
new_content = annotate_routes(header, content, where_header_found, options)
# Make sure we end on a trailing newline. # Make sure we end on a trailing newline.
new_content << '' unless(new_content.last == '') new_content << '' unless new_content.last == ''
new_text = new_content.join("\n") new_text = new_content.join("\n")
return false if existing_text == new_text if existing_text == new_text
puts "#{routes_file} unchanged."
false
else
File.open(routes_file, 'wb') { |f| f.puts(new_text) }
true
end
end
def self.annotate_routes(header, content, where_header_found, options = {})
if %w(before top).include?(options[:position_in_routes])
header = header << '' if content.first != ''
new_content = header + content
else
# Ensure we have adequate trailing newlines at the end of the file to
# ensure a blank line separating the content from the annotation.
content << '' unless content.last == ''
# We're moving something from the top of the file to the bottom, so ditch
# the spacer we put in the first time around.
content.shift if where_header_found == :before && content.first == ''
new_content = content + header
end
File.open(routes_file, "wb") { |f| f.puts(new_text) } new_content
return true
end end
# TODO: write the method doc using ruby rdoc formats
# where_header_found => This will either be :before, :after, or
# a number. If the number is > 0, the
# annotation was found somewhere in the
# middle of the file. If the number is
# zero, no annotation was found.
def self.strip_annotations(content) def self.strip_annotations(content)
real_content = [] real_content = []
mode = :content mode = :content
line_number = 0
header_found_at = 0 header_found_at = 0
content.split(/\n/, -1).each do |line|
line_number += 1 content.split(/\n/, -1).each_with_index do |line, line_number|
begin if mode == :header && line !~ /\s*#/
if(mode == :header) mode = :content
if(line !~ /\s*#/) next unless line == ''
mode = :content elsif mode == :content
raise unless (line == '') if line =~ /^\s*#\s*== Route.*$/
end header_found_at = line_number + 1 # index start's at 0
elsif(mode == :content) mode = :header
if(line =~ /^\s*#\s*== Route.*$/) else
header_found_at = line_number real_content << line
mode = :header
else
real_content << line
end
end end
rescue
retry
end end
end end
content_lines = real_content.count
# By default assume the annotation was found in the middle of the file... where_header_found(real_content, header_found_at)
where_header_found = header_found_at end
def self.where_header_found(real_content, header_found_at)
# By default assume the annotation was found in the middle of the file
# ... unless we have evidence it was at the beginning ... # ... unless we have evidence it was at the beginning ...
where_header_found = :before if(header_found_at == 1) return real_content, :before if header_found_at == 1
# ... or that it was at the end. # ... or that it was at the end.
where_header_found = :after if(header_found_at >= content_lines) return real_content, :after if header_found_at >= real_content.count
return real_content, where_header_found # and the default
return real_content, header_found_at
end end
def self.strip_on_removal(content, where_header_found) def self.strip_on_removal(content, where_header_found)
if(where_header_found == :before) if where_header_found == :before
content.shift while(content.first == '') content.shift while content.first == ''
elsif(where_header_found == :after) elsif where_header_found == :after
content.pop while(content.last == '') content.pop while content.last == ''
end end
# TODO: If the user buried it in the middle, we should probably see about # TODO: If the user buried it in the middle, we should probably see about
# TODO: preserving a single line of space between the content above and # TODO: preserving a single line of space between the content above and
# TODO: below... # TODO: below...
return content content
end end
end end
module Annotate module Annotate
def self.version def self.version
'2.7.0' '2.7.2'
end end
end end
module Annotate module Annotate
module Generators module Generators
class InstallGenerator < Rails::Generators::Base class InstallGenerator < Rails::Generators::Base
desc "Copy annotate_models rakefiles for automatic annotation" desc 'Copy annotate_models rakefiles for automatic annotation'
source_root File.expand_path('../templates', __FILE__) source_root File.expand_path('../templates', __FILE__)
# copy rake tasks # copy rake tasks
def copy_tasks def copy_tasks
template "auto_annotate_models.rake", "lib/tasks/auto_annotate_models.rake" template 'auto_annotate_models.rake', 'lib/tasks/auto_annotate_models.rake'
end end
end end
end end
end end
...@@ -2,44 +2,50 @@ ...@@ -2,44 +2,50 @@
# NOTE: are sensitive to local FS writes, and besides -- it's just not proper # NOTE: are sensitive to local FS writes, and besides -- it's just not proper
# NOTE: to have a dev-mode tool do its thing in production. # NOTE: to have a dev-mode tool do its thing in production.
if Rails.env.development? if Rails.env.development?
require 'annotate'
task :set_annotation_options do task :set_annotation_options do
# You can override any of these by setting an environment variable of the # You can override any of these by setting an environment variable of the
# same name. # same name.
Annotate.set_defaults( Annotate.set_defaults(
'routes' => 'false', 'routes' => 'false',
'position_in_routes' => 'before', 'position_in_routes' => 'before',
'position_in_class' => 'before', 'position_in_class' => 'before',
'position_in_test' => 'before', 'position_in_test' => 'before',
'position_in_fixture' => 'before', 'position_in_fixture' => 'before',
'position_in_factory' => 'before', 'position_in_factory' => 'before',
'position_in_serializer' => 'before', 'position_in_serializer' => 'before',
'show_foreign_keys' => 'true', 'show_foreign_keys' => 'true',
'show_indexes' => 'true', 'show_complete_foreign_keys' => 'false',
'simple_indexes' => 'false', 'show_indexes' => 'true',
'model_dir' => 'app/models', 'simple_indexes' => 'false',
'root_dir' => '', 'model_dir' => 'app/models',
'include_version' => 'false', 'root_dir' => '',
'require' => '', 'include_version' => 'false',
'exclude_tests' => 'false', 'require' => '',
'exclude_fixtures' => 'false', 'exclude_tests' => 'false',
'exclude_factories' => 'false', 'exclude_fixtures' => 'false',
'exclude_serializers' => 'false', 'exclude_factories' => 'false',
'exclude_scaffolds' => 'false', 'exclude_serializers' => 'false',
'exclude_controllers' => 'false', 'exclude_scaffolds' => 'true',
'exclude_helpers' => 'false', 'exclude_controllers' => 'true',
'ignore_model_sub_dir' => 'false', 'exclude_helpers' => 'true',
'ignore_columns' => nil, 'exclude_sti_subclasses' => 'false',
'ignore_unknown_models' => 'false', 'ignore_model_sub_dir' => 'false',
'hide_limit_column_types' => '<%= AnnotateModels::NO_LIMIT_COL_TYPES.join(',') %>', 'ignore_columns' => nil,
'skip_on_db_migrate' => 'false', 'ignore_routes' => nil,
'format_bare' => 'true', 'ignore_unknown_models' => 'false',
'format_rdoc' => 'false', 'hide_limit_column_types' => '<%= AnnotateModels::NO_LIMIT_COL_TYPES.join(",") %>',
'format_markdown' => 'false', 'hide_default_column_types' => '<%= AnnotateModels::NO_DEFAULT_COL_TYPES.join(",") %>',
'sort' => 'false', 'skip_on_db_migrate' => 'false',
'force' => 'false', 'format_bare' => 'true',
'trace' => 'false', 'format_rdoc' => 'false',
'wrapper_open' => nil, 'format_markdown' => 'false',
'wrapper_close' => nil, 'sort' => 'false',
'force' => 'false',
'trace' => 'false',
'wrapper_open' => nil,
'wrapper_close' => nil,
'with_comment' => true
) )
end end
......
annotate_lib = File.expand_path(File.dirname(File.dirname(__FILE__))) annotate_lib = File.expand_path(File.dirname(File.dirname(__FILE__)))
if !ENV['is_cli'] unless ENV['is_cli']
task :set_annotation_options task :set_annotation_options
task :annotate_models => :set_annotation_options task annotate_models: :set_annotation_options
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_lib}/annotate/annotate_models" require "#{annotate_lib}/annotate/annotate_models"
require "#{annotate_lib}/annotate/active_record_patch" require "#{annotate_lib}/annotate/active_record_patch"
options={ :is_rake => true } options = {is_rake: true}
ENV['position'] = options[:position] = Annotate.fallback(ENV['position'], 'before') ENV['position'] = options[:position] = Annotate.fallback(ENV['position'], 'before')
options[:position_in_class] = Annotate.fallback(ENV['position_in_class'], ENV['position']) options[:position_in_class] = Annotate.fallback(ENV['position_in_class'], ENV['position'])
options[:position_in_fixture] = Annotate.fallback(ENV['position_in_fixture'], ENV['position']) options[:position_in_fixture] = Annotate.fallback(ENV['position_in_fixture'], ENV['position'])
...@@ -18,10 +18,11 @@ task :annotate_models => :environment do ...@@ -18,10 +18,11 @@ task :annotate_models => :environment do
options[:position_in_test] = Annotate.fallback(ENV['position_in_test'], ENV['position']) options[:position_in_test] = Annotate.fallback(ENV['position_in_test'], ENV['position'])
options[:position_in_serializer] = Annotate.fallback(ENV['position_in_serializer'], ENV['position']) options[:position_in_serializer] = Annotate.fallback(ENV['position_in_serializer'], ENV['position'])
options[:show_foreign_keys] = Annotate.true?(ENV['show_foreign_keys']) options[:show_foreign_keys] = Annotate.true?(ENV['show_foreign_keys'])
options[:show_complete_foreign_keys] = Annotate.true?(ENV['show_complete_foreign_keys'])
options[:show_indexes] = Annotate.true?(ENV['show_indexes']) options[:show_indexes] = Annotate.true?(ENV['show_indexes'])
options[:simple_indexes] = Annotate.true?(ENV['simple_indexes']) options[:simple_indexes] = Annotate.true?(ENV['simple_indexes'])
options[:model_dir] = ENV['model_dir'] ? ENV['model_dir'].split(',') : ['app/models'] options[:model_dir] = ENV['model_dir'] ? ENV['model_dir'].split(',') : ['app/models']
options[:root_dir] = ENV['root_dir'] ? ENV['root_dir'].split(',') : [''] options[:root_dir] = ENV['root_dir']
options[:include_version] = Annotate.true?(ENV['include_version']) options[:include_version] = Annotate.true?(ENV['include_version'])
options[:require] = ENV['require'] ? ENV['require'].split(',') : [] options[:require] = ENV['require'] ? ENV['require'].split(',') : []
options[:exclude_tests] = Annotate.true?(ENV['exclude_tests']) options[:exclude_tests] = Annotate.true?(ENV['exclude_tests'])
...@@ -29,8 +30,9 @@ task :annotate_models => :environment do ...@@ -29,8 +30,9 @@ task :annotate_models => :environment do
options[:exclude_fixtures] = Annotate.true?(ENV['exclude_fixtures']) options[:exclude_fixtures] = Annotate.true?(ENV['exclude_fixtures'])
options[:exclude_serializers] = Annotate.true?(ENV['exclude_serializers']) options[:exclude_serializers] = Annotate.true?(ENV['exclude_serializers'])
options[:exclude_scaffolds] = Annotate.true?(ENV['exclude_scaffolds']) options[:exclude_scaffolds] = Annotate.true?(ENV['exclude_scaffolds'])
options[:exclude_controllers] = Annotate.true?(ENV['exclude_controllers']) options[:exclude_controllers] = Annotate.true?(ENV.fetch('exclude_controllers', 'true'))
options[:exclude_helpers] = Annotate.true?(ENV['exclude_helpers']) options[:exclude_helpers] = Annotate.true?(ENV.fetch('exclude_helpers', 'true'))
options[:exclude_sti_subclasses] = Annotate.true?(ENV['exclude_sti_subclasses'])
options[:ignore_model_sub_dir] = Annotate.true?(ENV['ignore_model_sub_dir']) options[:ignore_model_sub_dir] = Annotate.true?(ENV['ignore_model_sub_dir'])
options[:format_bare] = Annotate.true?(ENV['format_bare']) options[:format_bare] = Annotate.true?(ENV['format_bare'])
options[:format_rdoc] = Annotate.true?(ENV['format_rdoc']) options[:format_rdoc] = Annotate.true?(ENV['format_rdoc'])
...@@ -42,16 +44,19 @@ task :annotate_models => :environment do ...@@ -42,16 +44,19 @@ task :annotate_models => :environment do
options[:wrapper_open] = Annotate.fallback(ENV['wrapper_open'], ENV['wrapper']) options[:wrapper_open] = Annotate.fallback(ENV['wrapper_open'], ENV['wrapper'])
options[:wrapper_close] = Annotate.fallback(ENV['wrapper_close'], ENV['wrapper']) options[:wrapper_close] = Annotate.fallback(ENV['wrapper_close'], ENV['wrapper'])
options[:ignore_columns] = ENV.fetch('ignore_columns', nil) options[:ignore_columns] = ENV.fetch('ignore_columns', nil)
options[:ignore_routes] = ENV.fetch('ignore_routes', nil)
options[:hide_limit_column_types] = Annotate.fallback(ENV['hide_limit_column_types'], '')
options[:hide_default_column_types] = Annotate.fallback(ENV['hide_default_column_types'], '')
AnnotateModels.do_annotations(options) AnnotateModels.do_annotations(options)
end 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_lib}/annotate/annotate_models" require "#{annotate_lib}/annotate/annotate_models"
require "#{annotate_lib}/annotate/active_record_patch" require "#{annotate_lib}/annotate/active_record_patch"
options={ :is_rake => true } options = {is_rake: true}
options[:model_dir] = ENV['model_dir'] options[:model_dir] = ENV['model_dir']
options[:root_dir] = ENV['root_dir'] options[:root_dir] = ENV['root_dir']
options[:require] = ENV['require'] ? ENV['require'].split(',') : [] options[:require] = ENV['require'] ? ENV['require'].split(',') : []
......
...@@ -6,6 +6,7 @@ task :annotate_routes => :environment do ...@@ -6,6 +6,7 @@ task :annotate_routes => :environment do
options={} options={}
ENV['position'] = options[:position] = Annotate.fallback(ENV['position'], 'before') ENV['position'] = options[:position] = Annotate.fallback(ENV['position'], 'before')
options[:position_in_routes] = Annotate.fallback(ENV['position_in_routes'], ENV['position']) options[:position_in_routes] = Annotate.fallback(ENV['position_in_routes'], ENV['position'])
options[:ignore_routes] = Annotate.fallback(ENV['ignore_routes'], nil)
options[:require] = ENV['require'] ? ENV['require'].split(',') : [] options[:require] = ENV['require'] ? ENV['require'].split(',') : []
AnnotateRoutes.do_annotations(options) AnnotateRoutes.do_annotations(options)
end end
......
Colons can be used to align columns.
| Tables | Are | Cool |
| ------------- |:-------------:| -----:|
| col 3 is | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
There must be at least 3 dashes separating each header cell.
The outer pipes (|) are optional, and you don't need to make the
raw Markdown line up prettily. You can also use inline Markdown.
Markdown | Less | Pretty
--- | --- | ---
*Still* | `renders` | **nicely**
1 | 2 | 3
## Route Map
 Prefix | Verb | URI Pattern | Controller#Action
--------- | ---------- | --------------- | --------------------
myaction1 | GET | /url1(.:format) | mycontroller1#action
myaction2 | POST | /url2(.:format) | mycontroller2#action
 myaction3 | DELETE-GET | /url3(.:format) | mycontroller3#action \n")
Table name: `users`
### Columns
Name | Type | Attributes
----------------------- | ------------------ | ---------------------------
**`id`** | `integer` | `not null, primary key`
**`foreign_thing_id`** | `integer` | `not null`
### Foreign Keys
* `fk_rails_...` (_ON DELETE => on_delete_value ON UPDATE => on_update_value_):
* **`foreign_thing_id => foreign_things.id`**
require File.dirname(__FILE__) + '/spec_helper.rb' require File.dirname(__FILE__) + '/spec_helper.rb'
describe Annotate do describe Annotate do
it 'should have a version' do
it "should have a version" do
expect(Annotate.version).to be_instance_of(String) expect(Annotate.version).to be_instance_of(String)
end end
end end
...@@ -12,11 +12,9 @@ ...@@ -12,11 +12,9 @@
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20120816164927) do ActiveRecord::Schema.define(:version => 20120816164927) do
create_table "tasks", :force => true do |t| create_table "tasks", :force => true do |t|
t.string "content" t.string "content"
t.datetime "created_at", :null => false t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
end end
end end
...@@ -2,10 +2,7 @@ module Annotate ...@@ -2,10 +2,7 @@ module Annotate
module Validations module Validations
module Common module Common
def self.test_commands def self.test_commands
return %q{ 'bin/annotate && bin/annotate --routes'
bin/annotate &&
bin/annotate --routes
}
end end
def self.verify_output(output) def self.verify_output(output)
...@@ -13,54 +10,52 @@ module Annotate ...@@ -13,54 +10,52 @@ module Annotate
output.should =~ /Route file annotated./ output.should =~ /Route file annotated./
end end
def self.verify_files(which_files, test_rig, schema_annotation, routes_annotation, place_before=true) def self.verify_files(which_files, test_rig, schema_annotation, routes_annotation, place_before = true)
check_task_model(test_rig, schema_annotation, place_before) if(which_files[:model]) check_task_model(test_rig, schema_annotation, place_before) if which_files[:model]
check_task_unittest(test_rig, schema_annotation, place_before) if(which_files[:test]) check_task_unittest(test_rig, schema_annotation, place_before) if which_files[:test]
check_task_fixture(test_rig, schema_annotation, place_before) if(which_files[:fixture]) check_task_fixture(test_rig, schema_annotation, place_before) if which_files[:fixture]
check_task_factory(test_rig, schema_annotation, place_before) if(which_files[:factory]) check_task_factory(test_rig, schema_annotation, place_before) if which_files[:factory]
check_routes(test_rig, routes_annotation, place_before) if(which_files[:routes]) check_routes(test_rig, routes_annotation, place_before) if which_files[:routes]
end end
def self.check_task_model(test_rig, annotation, place_before=true) def self.check_task_model(test_rig, annotation, place_before = true)
model = apply_annotation(test_rig, "app/models/task.rb", annotation, place_before) model = apply_annotation(test_rig, 'app/models/task.rb', annotation, place_before)
File.read("app/models/task.rb").should == model File.read('app/models/task.rb').should == model
end end
def self.check_routes(test_rig, annotation, place_before=true) def self.check_routes(test_rig, annotation, place_before = true)
routes = apply_annotation(test_rig, "config/routes.rb", annotation, place_before) routes = apply_annotation(test_rig, 'config/routes.rb', annotation, place_before)
File.read("config/routes.rb"). File.read('config/routes.rb')
sub(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}/, 'YYYY-MM-DD HH:MM'). .sub(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}/, 'YYYY-MM-DD HH:MM')
should == routes .should == routes
end end
def self.check_task_unittest(test_rig, annotation, place_before=true) def self.check_task_unittest(test_rig, annotation, place_before = true)
unittest = apply_annotation(test_rig, "test/unit/task_test.rb", annotation, place_before) unittest = apply_annotation(test_rig, 'test/unit/task_test.rb', annotation, place_before)
File.read("test/unit/task_test.rb").should == unittest File.read('test/unit/task_test.rb').should == unittest
end end
def self.check_task_modeltest(test_rig, annotation, place_before=true) def self.check_task_modeltest(test_rig, annotation, place_before=true)
unittest = apply_annotation(test_rig, "test/models/task_test.rb", annotation, place_before) unittest = apply_annotation(test_rig, 'test/models/task_test.rb', annotation, place_before)
File.read("test/models/task_test.rb").should == unittest File.read('test/models/task_test.rb').should == unittest
end end
def self.check_task_factory(test_rig, annotation, place_before=true) def self.check_task_factory(test_rig, annotation, place_before=true)
fixture = apply_annotation(test_rig, "test/factories/tasks.rb", annotation, place_before) fixture = apply_annotation(test_rig, 'test/factories/tasks.rb', annotation, place_before)
File.read("test/factories/tasks.rb").should == fixture File.read('test/factories/tasks.rb').should == fixture
end end
def self.check_task_fixture(test_rig, annotation, place_before=true) def self.check_task_fixture(test_rig, annotation, place_before = true)
fixture = apply_annotation(test_rig, "test/fixtures/tasks.yml", annotation, place_before) fixture = apply_annotation(test_rig, 'test/fixtures/tasks.yml', annotation, place_before)
File.read("test/fixtures/tasks.yml").should == fixture File.read('test/fixtures/tasks.yml').should == fixture
end end
protected def self.apply_annotation(test_rig, fname, annotation, place_before = true)
def self.apply_annotation(test_rig, fname, annotation, place_before=true)
corpus = File.read(File.join(test_rig, fname)) corpus = File.read(File.join(test_rig, fname))
if(place_before) if place_before
corpus = annotation + "\n" + corpus annotation + "\n" + corpus
else else
corpus = corpus + "\n" + annotation corpus + "\n" + annotation
end end
end end
end end
...@@ -71,27 +66,28 @@ module Annotate ...@@ -71,27 +66,28 @@ module Annotate
module Validations module Validations
class Base class Base
def self.test_commands def self.test_commands
return Annotate::Validations::Common.test_commands Annotate::Validations::Common.test_commands
end end
def self.verify_output(output) def self.verify_output(output)
return Annotate::Validations::Common.verify_output(output) Annotate::Validations::Common.verify_output(output)
end end
def self.verify_files(test_rig) def self.verify_files(test_rig)
return Annotate::Validations::Common.verify_files({ Annotate::Validations::Common.verify_files(
:model => true, {
:test => true, model: true,
:fixture => true, test: true,
:factory => false, fixture: true,
:routes => true factory: false,
}, test_rig, self.schema_annotation, self.route_annotation, true) routes: true
}, test_rig, schema_annotation, route_annotation, true
)
end end
def self.foo def self.foo
require 'pry' require 'pry'
require 'pry-coolline' require 'pry-coolline'
binding.pry
end end
end end
end end
......
# Smoke test to assure basic functionality works on a variety of Rails versions. # Smoke test to assure basic functionality works on a variety of Rails versions.
$:.unshift(File.dirname(__FILE__)) $LOAD_PATH.unshift(File.dirname(__FILE__))
require 'spec_helper' require 'spec_helper'
require 'files' require 'files'
require 'wrong' require 'wrong'
...@@ -7,7 +7,7 @@ require 'rake' ...@@ -7,7 +7,7 @@ require 'rake'
include Files include Files
include Wrong::D include Wrong::D
BASEDIR=File.expand_path(File.join(File.dirname(__FILE__), '..', '..')) BASEDIR = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
RVM_BIN = `which rvm`.chomp RVM_BIN = `which rvm`.chomp
USING_RVM = (RVM_BIN != '') USING_RVM = (RVM_BIN != '')
...@@ -16,25 +16,24 @@ ENV['rvm_pretty_print_flag'] = '0' ...@@ -16,25 +16,24 @@ ENV['rvm_pretty_print_flag'] = '0'
ENV['BUNDLE_GEMFILE'] = './Gemfile' ENV['BUNDLE_GEMFILE'] = './Gemfile'
describe "annotate inside Rails, using #{CURRENT_RUBY}" do describe "annotate inside Rails, using #{CURRENT_RUBY}" do
here = File.expand_path('..', __FILE__)
chosen_scenario = nil chosen_scenario = nil
if(!ENV['SCENARIO'].blank?) unless ENV['SCENARIO'].blank?
chosen_scenario = File.expand_path(ENV['SCENARIO']) chosen_scenario = File.expand_path(ENV['SCENARIO'])
raise "Can't find specified scenario '#{chosen_scenario}'!" unless(File.directory?(chosen_scenario)) raise "Can't find specified scenario '#{chosen_scenario}'!" unless File.directory?(chosen_scenario)
end end
Annotate::Integration::SCENARIOS.each do |test_rig, base_dir, test_name| Annotate::Integration::SCENARIOS.each do |test_rig, base_dir, test_name|
next if(chosen_scenario && chosen_scenario != test_rig) next if chosen_scenario && chosen_scenario != test_rig
it "works under #{test_name}" do it "works under #{test_name}" do
if(!USING_RVM) unless USING_RVM
skip "Must have RVM installed." skip 'Must have RVM installed.'
next next
end end
# Don't proceed if the working copy is dirty! # Don't proceed if the working copy is dirty!
expect(Annotate::Integration.is_clean?(test_rig)).to eq(true) expect(Annotate::Integration.clean?(test_rig)).to eq(true)
skip "temporarily ignored until Travis can run them" skip 'temporarily ignored until Travis can run them'
Bundler.with_clean_env do Bundler.with_clean_env do
dir base_dir do dir base_dir do
...@@ -53,10 +52,10 @@ describe "annotate inside Rails, using #{CURRENT_RUBY}" do ...@@ -53,10 +52,10 @@ describe "annotate inside Rails, using #{CURRENT_RUBY}" do
# By default, rvm_ruby_string isn't inherited over properly, so let's # By default, rvm_ruby_string isn't inherited over properly, so let's
# make sure it's there so our .rvmrc will work. # make sure it's there so our .rvmrc will work.
ENV['rvm_ruby_string']=CURRENT_RUBY ENV['rvm_ruby_string'] = CURRENT_RUBY
require "#{base_dir}" # Will get "#{base_dir}.rb"... require base_dir.to_s # Will get "#{base_dir}.rb"...
klass = "Annotate::Validations::#{base_dir.gsub('.', '_').classify}".constantize klass = "Annotate::Validations::#{base_dir.tr('.', '_').classify}".constantize
Dir.chdir(temp_dir) do Dir.chdir(temp_dir) do
# bash is required by rvm # bash is required by rvm
......
...@@ -4,7 +4,7 @@ module Annotate ...@@ -4,7 +4,7 @@ module Annotate
module Validations module Validations
class Rails23WithBundler < Base class Rails23WithBundler < Base
def self.schema_annotation def self.schema_annotation
return <<-RUBY <<-RUBY
# == Schema Information # == Schema Information
# #
# Table name: tasks # Table name: tasks
...@@ -18,7 +18,7 @@ RUBY ...@@ -18,7 +18,7 @@ RUBY
end end
def self.route_annotation def self.route_annotation
return <<-RUBY <<-RUBY
# == Route Map (Updated YYYY-MM-DD HH:MM) # == Route Map (Updated YYYY-MM-DD HH:MM)
# #
# tasks GET /tasks(.:format) {:controller=>"tasks", :action=>"index"} # tasks GET /tasks(.:format) {:controller=>"tasks", :action=>"index"}
......
...@@ -4,7 +4,7 @@ module Annotate ...@@ -4,7 +4,7 @@ module Annotate
module Validations module Validations
class Rails322 < Base class Rails322 < Base
def self.schema_annotation def self.schema_annotation
return <<-RUBY <<-RUBY
# == Schema Information # == Schema Information
# #
# Table name: tasks # Table name: tasks
...@@ -18,7 +18,7 @@ RUBY ...@@ -18,7 +18,7 @@ RUBY
end end
def self.route_annotation def self.route_annotation
return <<-RUBY <<-RUBY
# == Route Map (Updated YYYY-MM-DD HH:MM) # == Route Map (Updated YYYY-MM-DD HH:MM)
# #
# tasks GET /tasks(.:format) tasks#index # tasks GET /tasks(.:format) tasks#index
......
...@@ -4,7 +4,7 @@ module Annotate ...@@ -4,7 +4,7 @@ module Annotate
module Validations module Validations
class Rails328 < Base class Rails328 < Base
def self.schema_annotation def self.schema_annotation
return <<-RUBY <<-RUBY
# == Schema Information # == Schema Information
# #
# Table name: tasks # Table name: tasks
...@@ -18,7 +18,7 @@ RUBY ...@@ -18,7 +18,7 @@ RUBY
end end
def self.route_annotation def self.route_annotation
return <<-RUBY <<-RUBY
# == Route Map (Updated YYYY-MM-DD HH:MM) # == Route Map (Updated YYYY-MM-DD HH:MM)
# #
# tasks GET /tasks(.:format) tasks#index # tasks GET /tasks(.:format) tasks#index
......
...@@ -4,7 +4,7 @@ module Annotate ...@@ -4,7 +4,7 @@ module Annotate
module Validations module Validations
class Rails32AutoloadingFactoryGirl < Base class Rails32AutoloadingFactoryGirl < Base
def self.schema_annotation def self.schema_annotation
return <<-RUBY <<-RUBY
# == Schema Information # == Schema Information
# #
# Table name: tasks # Table name: tasks
...@@ -18,7 +18,7 @@ RUBY ...@@ -18,7 +18,7 @@ RUBY
end end
def self.route_annotation def self.route_annotation
return <<-RUBY <<-RUBY
# == Route Map (Updated YYYY-MM-DD HH:MM) # == Route Map (Updated YYYY-MM-DD HH:MM)
# #
# tasks GET /tasks(.:format) tasks#index # tasks GET /tasks(.:format) tasks#index
...@@ -33,13 +33,15 @@ RUBY ...@@ -33,13 +33,15 @@ RUBY
end end
def self.verify_files(test_rig) def self.verify_files(test_rig)
return Annotate::Validations::Common.verify_files({ Annotate::Validations::Common.verify_files(
:model => true, {
:test => true, model: true,
:fixture => false, test: true,
:factory => true, fixture: false,
:routes => true factory: true,
}, test_rig, self.schema_annotation, self.route_annotation, true) routes: true
}, test_rig, schema_annotation, route_annotation, true
)
end end
end end
end end
......
...@@ -4,7 +4,7 @@ module Annotate ...@@ -4,7 +4,7 @@ module Annotate
module Validations module Validations
class Rails32CustomInflection < Base class Rails32CustomInflection < Base
def self.schema_annotation def self.schema_annotation
return <<-RUBY <<-RUBY
# == Schema Information # == Schema Information
# #
# Table name: tasks # Table name: tasks
...@@ -18,7 +18,7 @@ RUBY ...@@ -18,7 +18,7 @@ RUBY
end end
def self.route_annotation def self.route_annotation
return <<-RUBY <<-RUBY
# == Route Map (Updated YYYY-MM-DD HH:MM) # == Route Map (Updated YYYY-MM-DD HH:MM)
# #
# tasks GET /tasks(.:format) tasks#index # tasks GET /tasks(.:format) tasks#index
......
...@@ -4,7 +4,7 @@ module Annotate ...@@ -4,7 +4,7 @@ module Annotate
module Validations module Validations
class Rails32WithAssetPipeline < Base class Rails32WithAssetPipeline < Base
def self.schema_annotation def self.schema_annotation
return <<-RUBY <<-RUBY
# == Schema Information # == Schema Information
# #
# Table name: tasks # Table name: tasks
...@@ -18,7 +18,7 @@ RUBY ...@@ -18,7 +18,7 @@ RUBY
end end
def self.route_annotation def self.route_annotation
return <<-RUBY <<-RUBY
# == Route Map (Updated YYYY-MM-DD HH:MM) # == Route Map (Updated YYYY-MM-DD HH:MM)
# #
# tasks GET /tasks(.:format) tasks#index # tasks GET /tasks(.:format) tasks#index
......
...@@ -4,7 +4,7 @@ module Annotate ...@@ -4,7 +4,7 @@ module Annotate
module Validations module Validations
class Standalone < Base class Standalone < Base
def self.schema_annotation def self.schema_annotation
return <<-RUBY <<-RUBY
# == Schema Information # == Schema Information
# #
# Table name: tasks # Table name: tasks
...@@ -18,9 +18,7 @@ RUBY ...@@ -18,9 +18,7 @@ RUBY
end end
def self.test_commands def self.test_commands
return %q{ 'bin/annotate --require ./config/init.rb'
bin/annotate --require ./config/init.rb
}
end end
def self.verify_output(output) def self.verify_output(output)
...@@ -28,13 +26,15 @@ RUBY ...@@ -28,13 +26,15 @@ RUBY
end end
def self.verify_files(test_rig) def self.verify_files(test_rig)
return Annotate::Validations::Common.verify_files({ Annotate::Validations::Common.verify_files(
:model => true, {
:test => false, model: true,
:fixture => false, test: false,
:factory => false, fixture: false,
:routes => false factory: false,
}, test_rig, self.schema_annotation, nil, true) routes: false
}, test_rig, schema_annotation, nil, true
)
end end
end end
end end
......
require 'coveralls'
require 'codeclimate-test-reporter'
require 'simplecov'
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
[
Coveralls::SimpleCov::Formatter,
SimpleCov::Formatter::HTMLFormatter,
CodeClimate::TestReporter::Formatter
]
)
SimpleCov.start
require 'rubygems' require 'rubygems'
require 'bundler' require 'bundler'
Bundler.setup Bundler.setup
require 'rake'
require 'rspec' require 'rspec'
require 'wrong/adapters/rspec' require 'wrong/adapters/rspec'
$:.unshift(File.join(File.dirname(__FILE__), '../lib')) $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../lib'))
$:.unshift(File.dirname(__FILE__)) $LOAD_PATH.unshift(File.dirname(__FILE__))
require 'active_support' require 'active_support'
require 'active_support/core_ext/object/blank' require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/class/subclasses' require 'active_support/core_ext/class/subclasses'
require 'active_support/core_ext/string/inflections' require 'active_support/core_ext/string/inflections'
require 'annotate' require 'annotate'
require 'byebug'
module Annotate module Annotate
module Integration module Integration
ABSOLUTE_GEM_ROOT=File.expand_path('../../', __FILE__) ABSOLUTE_GEM_ROOT = File.expand_path('../../', __FILE__)
CRUFT_PATTERNS=[ CRUFT_PATTERNS = %w(
"%SCENARIO%/bin/*", "%SCENARIO%/log/*", "%SCENARIO%/tmp/*", %SCENARIO%/bin/*
"%SCENARIO%/.bundle" %SCENARIO%/log/*
] %SCENARIO%/tmp/*
SCENARIO_HOME=File.join(File.dirname(__FILE__), 'integration') %SCENARIO%/.bundle
SCENARIOS=Dir.glob("#{SCENARIO_HOME}/*"). ).freeze
select { |candidate| File.directory?(candidate) }.
map do |test_rig| SCENARIO_HOME = File.join(File.dirname(__FILE__), 'integration')
base_dir = File.basename(test_rig) SCENARIOS = Dir.glob("#{SCENARIO_HOME}/*").select do |candidate|
[test_rig, base_dir, base_dir.titlecase] File.directory?(candidate)
end end.map do |test_rig|
base_dir = File.basename(test_rig)
[test_rig, base_dir, base_dir.titlecase]
end
def self.nuke_cruft(test_rig) def self.nuke_cruft(test_rig)
FileList[ FileList[
Annotate::Integration::CRUFT_PATTERNS. Annotate::Integration::CRUFT_PATTERNS.map do |pattern|
map { |pattern| pattern.sub('%SCENARIO%', test_rig) } pattern.sub('%SCENARIO%', test_rig)
end
].each do |fname| ].each do |fname|
FileUtils.rm_rf(fname) FileUtils.rm_rf(fname)
end end
end end
def self.nuke_all_cruft def self.nuke_all_cruft
SCENARIOS.each do |test_rig, base_dir, test_name| SCENARIOS.each do |test_rig, _base_dir, _test_name|
nuke_cruft(test_rig) nuke_cruft(test_rig)
end end
end end
def self.empty_gemset(test_rig) def self.empty_gemset(test_rig)
Dir.chdir(test_rig) do Dir.chdir(test_rig) do
system(%q{ system('
( (
export SKIP_BUNDLER=1 export SKIP_BUNDLER=1
source .rvmrc && source .rvmrc &&
rvm --force gemset empty rvm --force gemset empty
) 2>&1 ) 2>&1
}) ')
end end
end end
...@@ -65,8 +85,8 @@ module Annotate ...@@ -65,8 +85,8 @@ module Annotate
system("git clean -dfx #{SCENARIO_HOME}/*/") system("git clean -dfx #{SCENARIO_HOME}/*/")
end end
def self.is_clean?(test_rig) def self.clean?(test_rig)
return `git status --porcelain #{test_rig}/ | wc -l`.strip.to_i == 0 `git status --porcelain #{test_rig}/ | wc -l`.strip.to_i.zero?
end end
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