annotate 2.7.1 → 2.7.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e6c2484a81d38c69c86e48305ae0a1b8724e5b1
4
- data.tar.gz: 7463f0ee24a0023b105dc5e48fc9eec49559de0e
3
+ metadata.gz: 365398d9352685a831b09fe60f460131a0fbe2ab
4
+ data.tar.gz: ba3fce8c6c97125af42c90310adac5272c6ef78c
5
5
  SHA512:
6
- metadata.gz: d4dd08320d2fa1b85c21afdeb1fd5daa4ec6cd39877d70a0681b04ce7453f6fd204da258b0a9d20fe22d4eb4649d44c086383a20db3fe4c6b183ac35a8e1171c
7
- data.tar.gz: 25101a0b978d74579bd47e2dba28a3b89fc738fe19966c50a78aaa43543748c5cd523ff7c7be3b708caa80925092a553a28f4dc6b55b6e91547d9ec5fdbb810f
6
+ metadata.gz: 2f219cec844284bd213ca826a12553b862a9ec6dcfb2ccc271a2821576989dba630e5ad86951ab2fba2d6df02b77c5468b6f1a9b60ff14cf71b23c90779e9a78
7
+ data.tar.gz: 9fdc058f6de547f0e3fa13f0b7ddaa931b4be5ad9ba4e041fb95002b6d9bd46631d0f3df5c1428e71774b089f7899d1e3332b5af00f0db8d1fe56dc249044bc3
@@ -1,3 +1,6 @@
1
+ == 2.7.2
2
+ See https://github.com/ctran/annotate_models/releases/tag/v2.7.2
3
+
1
4
  == 2.7.1
2
5
  See https://github.com/ctran/annotate_models/releases/tag/v2.7.1
3
6
 
@@ -2,9 +2,10 @@
2
2
 
3
3
  {<img src="https://badge.fury.io/rb/annotate.svg" alt="Gem Version" />}[http://badge.fury.io/rb/annotate]
4
4
  {<img src="https://img.shields.io/gem/dt/annotate.svg?style=flat" />}[https://rubygems.org/gems/annotate]
5
- {<img src="https://travis-ci.org/ctran/annotate_models.png" />}[https://travis-ci.org/ctran/annotate_models]
5
+ {<img src="https://travis-ci.org/ctran/annotate_models.svg?branch=develop" />}[https://travis-ci.org/ctran/annotate_models]
6
6
  {<img src="https://coveralls.io/repos/ctran/annotate_models/badge.svg?branch=develop" />}[https://coveralls.io/r/ctran/annotate_models?branch=develop]
7
7
  {<img src="https://codeclimate.com/github/ctran/annotate_models/badges/gpa.svg" />}[https://codeclimate.com/github/ctran/annotate_models]
8
+ {<img src="http://inch-ci.org/github/ctran/annotate_models.svg?branch=develop" alt="Inline docs" />}[http://inch-ci.org/github/ctran/annotate_models]
8
9
  {<img src="https://gemnasium.com/ctran/annotate_models.png" />}[https://gemnasium.com/ctran/annotate_models]
9
10
 
10
11
  Add a comment summarizing the current schema to the top or bottom of each of
@@ -58,7 +59,7 @@ Into Gemfile from rubygems.org:
58
59
 
59
60
  Into Gemfile from Github:
60
61
 
61
- gem 'annotate', github: 'ctran/annotate_models'
62
+ gem 'annotate', git: 'https://github.com/ctran/annotate_models.git'
62
63
 
63
64
  Into environment gems from rubygems.org:
64
65
 
@@ -66,7 +67,7 @@ Into environment gems from rubygems.org:
66
67
 
67
68
  Into environment gems from Github checkout:
68
69
 
69
- git clone git://github.com/ctran/annotate_models.git annotate_models
70
+ git clone https://github.com/ctran/annotate_models.git annotate_models
70
71
  cd annotate_models
71
72
  rake build
72
73
  gem install pkg/annotate-*.gem
@@ -184,7 +185,7 @@ you can do so with a simple environment variable, instead of editing the
184
185
  -i, --show-indexes List the table's database indexes in the annotation
185
186
  -k, --show-foreign-keys List the table's foreign key constraints in the annotation
186
187
  -s, --simple-indexes Concat the column's related indexes in the annotation
187
- --model-dir dir Annotate model files stored in dir rather than app/models, separate multiple dirs with comas
188
+ --model-dir dir Annotate model files stored in dir rather than app/models, separate multiple dirs with commas
188
189
  --ignore-model-subdirects Ignore subdirectories of the models directory
189
190
  --sort Sort columns alphabetically, rather than in creation order
190
191
  -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
4
  require 'annotate/version'
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = "annotate"
7
+ s.name = 'annotate'
8
8
  s.version = Annotate.version
9
9
 
10
10
  s.required_ruby_version = '>= 1.9.3'
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
- s.authors = ["Alex Chaffee", "Cuong Tran", "Marcos Piccinini", "Turadg Aleahmad", "Jon Frisby"]
13
- s.description = "Annotates Rails/ActiveRecord Models, routes, fixtures, and others based on the database schema."
14
- s.email = ["alex@stinky.com", "cuong.tran@gmail.com", "x@nofxx.com", "turadg@aleahmad.net", "jon@cloudability.com"]
15
- s.executables = ["annotate"]
16
- s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "TODO.rdoc"]
17
- 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"]
18
- s.homepage = "http://github.com/ctran/annotate_models"
19
- s.licenses = ["Ruby"]
20
- s.require_paths = ["lib"]
21
- s.rubyforge_project = "annotate"
22
- s.rubygems_version = "2.1.11"
23
- s.summary = "Annotates Rails Models, routes, fixtures, and others based on the database schema."
11
+ s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
12
+ s.authors = ['Alex Chaffee', 'Cuong Tran', 'Marcos Piccinini', 'Turadg Aleahmad', 'Jon Frisby']
13
+ s.description = 'Annotates Rails/ActiveRecord Models, routes, fixtures, and others based on the database schema.'
14
+ s.email = ['alex@stinky.com', 'cuong.tran@gmail.com', 'x@nofxx.com', 'turadg@aleahmad.net', 'jon@cloudability.com']
15
+ s.executables = ['annotate']
16
+ s.extra_rdoc_files = ['README.rdoc', 'CHANGELOG.rdoc', 'TODO.rdoc']
17
+ s.files = [
18
+ 'AUTHORS.rdoc',
19
+ 'CHANGELOG.rdoc',
20
+ 'LICENSE.txt',
21
+ 'README.rdoc',
22
+ 'TODO.rdoc',
23
+ 'annotate.gemspec',
24
+ 'bin/annotate',
25
+ 'lib/annotate.rb',
26
+ 'lib/annotate/active_record_patch.rb',
27
+ 'lib/annotate/annotate_models.rb',
28
+ 'lib/annotate/annotate_routes.rb',
29
+ 'lib/annotate/tasks.rb',
30
+ 'lib/annotate/version.rb',
31
+ 'lib/generators/annotate/USAGE',
32
+ 'lib/generators/annotate/install_generator.rb',
33
+ 'lib/generators/annotate/templates/auto_annotate_models.rake',
34
+ 'lib/tasks/annotate_models.rake',
35
+ 'lib/tasks/annotate_routes.rake',
36
+ 'lib/tasks/annotate_models_migrate.rake'
37
+ ]
38
+ s.homepage = 'http://github.com/ctran/annotate_models'
39
+ s.licenses = ['Ruby']
40
+ s.require_paths = ['lib']
41
+ s.rubyforge_project = 'annotate'
42
+ s.rubygems_version = '2.1.11'
43
+ s.summary = 'Annotates Rails Models, routes, fixtures, and others based on the database schema.'
24
44
 
25
- if s.respond_to? :specification_version then
26
- s.specification_version = 4
27
-
28
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
29
- s.add_runtime_dependency(%q<rake>, [">= 10.4", "< 12.0"])
30
- s.add_runtime_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
31
- else
32
- s.add_dependency(%q<rake>, [">= 10.4", "< 12.0"])
33
- s.add_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
34
- end
35
- else
36
- s.add_dependency(%q<rake>, [">= 0.8.7"])
37
- s.add_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
38
- end
45
+ s.specification_version = 4 if s.respond_to? :specification_version
46
+ s.add_runtime_dependency(%q<rake>, ['>= 10.4', '< 13.0'])
47
+ s.add_runtime_dependency(%q<activerecord>, ['>= 3.2', '< 6.0'])
39
48
  end
@@ -8,11 +8,11 @@ require 'rubygems'
8
8
  begin
9
9
  require 'bundler'
10
10
  Bundler.setup
11
- rescue Exception
11
+ rescue StandardError
12
12
  end
13
13
 
14
14
  here = File.expand_path(File.dirname __FILE__)
15
- $:<< "#{here}/../lib"
15
+ $LOAD_PATH << "#{here}/../lib"
16
16
 
17
17
  require 'optparse'
18
18
  require 'annotate'
@@ -33,7 +33,7 @@ OptionParser.new do |opts|
33
33
  'Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/route/serializer file(s)') do |p|
34
34
  ENV['position'] = p
35
35
  %w(position_in_class position_in_factory position_in_fixture position_in_test position_in_routes position_in_serializer).each do |key|
36
- ENV[key] = p unless (has_set_position[key])
36
+ ENV[key] = p unless has_set_position[key]
37
37
  end
38
38
  end
39
39
 
@@ -90,12 +90,11 @@ OptionParser.new do |opts|
90
90
  ENV['routes'] = 'true'
91
91
  end
92
92
 
93
- opts.on('-aa', '--active-admin', 'Annotate active_admin models') do |p|
94
- ENV['active_admin'] = p
93
+ opts.on('-aa', '--active-admin', 'Annotate active_admin models') do
94
+ ENV['active_admin'] = 'true'
95
95
  end
96
96
 
97
- opts.on('-v', '--version',
98
- 'Show the current version of this gem') do
97
+ opts.on('-v', '--version', 'Show the current version of this gem') do
99
98
  puts "annotate v#{Annotate.version}"; exit
100
99
  end
101
100
 
@@ -119,12 +118,12 @@ OptionParser.new do |opts|
119
118
  end
120
119
 
121
120
  opts.on('--model-dir dir',
122
- "Annotate model files stored in dir rather than app/models, separate multiple dirs with comas") do |dir|
121
+ "Annotate model files stored in dir rather than app/models, separate multiple dirs with commas") do |dir|
123
122
  ENV['model_dir'] = dir
124
123
  end
125
124
 
126
125
  opts.on('--root-dir dir',
127
- "Annotate files stored within root dir projects, separate multiple dirs with comas") do |dir|
126
+ "Annotate files stored within root dir projects, separate multiple dirs with commas") do |dir|
128
127
  ENV['root_dir'] = dir
129
128
  end
130
129
 
@@ -181,17 +180,22 @@ OptionParser.new do |opts|
181
180
  ENV['ignore_routes'] = regex
182
181
  end
183
182
 
184
- opts.on('--hide-limit-column-types VALUES', "don't show limit for given column types, separated by comas (i.e., `integer,boolean,text`)") do |values|
183
+ opts.on('--hide-limit-column-types VALUES', "don't show limit for given column types, separated by commas (i.e., `integer,boolean,text`)") do |values|
185
184
  ENV['hide_limit_column_types'] = "#{values}"
186
185
  end
187
186
 
187
+ opts.on('--hide-default-column-types VALUES', "don't show default for given column types, separated by commas (i.e., `json,jsonb,hstore`)") do |values|
188
+ ENV['hide_default_column_types'] = "#{values}"
189
+ end
190
+
188
191
  opts.on('--ignore-unknown-models', "don't display warnings for bad model files") do |values|
189
192
  ENV['ignore_unknown_models'] = 'true'
190
193
  end
191
-
192
194
  end.parse!
193
195
 
194
- options = Annotate.setup_options({is_rake: ENV['is_rake'] && !ENV['is_rake'].empty?})
196
+ options = Annotate.setup_options(
197
+ is_rake: ENV['is_rake'] && !ENV['is_rake'].empty?
198
+ )
195
199
  Annotate.eager_load(options)
196
200
 
197
201
  AnnotateModels.send(target_action, options) if Annotate.include_models?
@@ -1,3 +1,5 @@
1
+ # rubocop:disable Metrics/ModuleLength
2
+
1
3
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
4
  require 'annotate/version'
3
5
  require 'annotate/annotate_models'
@@ -7,7 +9,7 @@ begin
7
9
  # ActiveSupport 3.x...
8
10
  require 'active_support/hash_with_indifferent_access'
9
11
  require 'active_support/core_ext/object/blank'
10
- rescue Exception
12
+ rescue StandardError
11
13
  # ActiveSupport 2.x...
12
14
  require 'active_support/core_ext/hash/indifferent_access'
13
15
  require 'active_support/core_ext/blank'
@@ -29,16 +31,22 @@ module Annotate
29
31
  :exclude_fixtures, :exclude_factories, :ignore_model_sub_dir,
30
32
  :format_bare, :format_rdoc, :format_markdown, :sort, :force, :trace,
31
33
  :timestamp, :exclude_serializers, :classified_sort, :show_foreign_keys,
32
- :exclude_scaffolds, :exclude_controllers, :exclude_helpers, :ignore_unknown_models
34
+ :exclude_scaffolds, :exclude_controllers, :exclude_helpers,
35
+ :exclude_sti_subclasses, :ignore_unknown_models
33
36
  ].freeze
34
37
  OTHER_OPTIONS = [
35
- :ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close, :wrapper, :routes,
36
- :hide_limit_column_types, :ignore_routes, :active_admin
38
+ :ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close,
39
+ :wrapper, :routes, :hide_limit_column_types, :hide_default_column_types,
40
+ :ignore_routes, :active_admin
37
41
  ].freeze
38
42
  PATH_OPTIONS = [
39
43
  :require, :model_dir, :root_dir
40
44
  ].freeze
41
45
 
46
+ def self.all_options
47
+ [POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS]
48
+ end
49
+
42
50
  ##
43
51
  # Set default values that can be overridden via environment variables.
44
52
  #
@@ -48,13 +56,13 @@ module Annotate
48
56
 
49
57
  options = HashWithIndifferentAccess.new(options)
50
58
 
51
- [POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key|
59
+ all_options.flatten.each do |key|
52
60
  if options.key?(key)
53
61
  default_value = if options[key].is_a?(Array)
54
62
  options[key].join(',')
55
63
  else
56
64
  options[key]
57
- end
65
+ end
58
66
  end
59
67
 
60
68
  default_value = ENV[key.to_s] unless ENV[key.to_s].blank?
@@ -80,7 +88,6 @@ module Annotate
80
88
  end
81
89
 
82
90
  options[:model_dir] = ['app/models'] if options[:model_dir].empty?
83
- options[:root_dir] = [''] if options[:root_dir].empty?
84
91
 
85
92
  options[:wrapper_open] ||= options[:wrapper]
86
93
  options[:wrapper_close] ||= options[:wrapper]
@@ -94,9 +101,7 @@ module Annotate
94
101
  end
95
102
 
96
103
  def self.reset_options
97
- [POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key|
98
- ENV[key.to_s] = nil
99
- end
104
+ all_options.flatten.each { |key| ENV[key.to_s] = nil }
100
105
  end
101
106
 
102
107
  def self.skip_on_migration?
@@ -123,18 +128,21 @@ module Annotate
123
128
  return if loaded_tasks
124
129
  self.loaded_tasks = true
125
130
 
126
- Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each { |rake| load rake }
131
+ Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each do |rake|
132
+ load rake
133
+ end
127
134
  end
128
135
 
129
136
  def self.load_requires(options)
130
- options[:require].each { |path| require path } if options[:require].count > 0
137
+ options[:require].count > 0 &&
138
+ options[:require].each { |path| require path }
131
139
  end
132
140
 
133
141
  def self.eager_load(options)
134
142
  load_requires(options)
135
143
  require 'annotate/active_record_patch'
136
144
 
137
- if defined?(Rails)
145
+ if defined?(Rails::Application)
138
146
  if Rails.version.split('.').first.to_i < 3
139
147
  Rails.configuration.eager_load_paths.each do |load_path|
140
148
  matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
@@ -158,7 +166,7 @@ module Annotate
158
166
  def self.bootstrap_rake
159
167
  begin
160
168
  require 'rake/dsl_definition'
161
- rescue Exception => e
169
+ rescue StandardError => e
162
170
  # We might just be on an old version of Rake...
163
171
  puts e.message
164
172
  exit e.status_code
@@ -1,67 +1,69 @@
1
+ # rubocop:disable Metrics/ModuleLength
2
+
1
3
  require 'bigdecimal'
2
4
 
3
5
  module AnnotateModels
4
6
  TRUE_RE = /^(true|t|yes|y|1)$/i
5
7
 
6
8
  # Annotate Models plugin use this header
7
- COMPAT_PREFIX = "== Schema Info"
8
- COMPAT_PREFIX_MD = "## Schema Info"
9
- PREFIX = "== Schema Information"
10
- PREFIX_MD = "## Schema Information"
11
- END_MARK = "== Schema Information End"
9
+ COMPAT_PREFIX = '== Schema Info'.freeze
10
+ COMPAT_PREFIX_MD = '## Schema Info'.freeze
11
+ PREFIX = '== Schema Information'.freeze
12
+ PREFIX_MD = '## Schema Information'.freeze
13
+ END_MARK = '== Schema Information End'.freeze
12
14
 
13
- MATCHED_TYPES = %w(test fixture factory serializer scaffold controller helper)
15
+ MATCHED_TYPES = %w(test fixture factory serializer scaffold controller helper).freeze
14
16
 
15
17
  # File.join for windows reverse bar compat?
16
18
  # I dont use windows, can`t test
17
- UNIT_TEST_DIR = File.join("test", "unit")
18
- MODEL_TEST_DIR = File.join("test", "models") # since rails 4.0
19
- SPEC_MODEL_DIR = File.join("spec", "models")
20
- FIXTURE_TEST_DIR = File.join("test", "fixtures")
21
- FIXTURE_SPEC_DIR = File.join("spec", "fixtures")
19
+ UNIT_TEST_DIR = File.join('test', "unit")
20
+ MODEL_TEST_DIR = File.join('test', "models") # since rails 4.0
21
+ SPEC_MODEL_DIR = File.join('spec', "models")
22
+ FIXTURE_TEST_DIR = File.join('test', "fixtures")
23
+ FIXTURE_SPEC_DIR = File.join('spec', "fixtures")
22
24
 
23
25
  # Other test files
24
- CONTROLLER_TEST_DIR = File.join("test", "controllers")
25
- CONTROLLER_SPEC_DIR = File.join("spec", "controllers")
26
- REQUEST_SPEC_DIR = File.join("spec", "requests")
27
- ROUTING_SPEC_DIR = File.join("spec", "routing")
26
+ CONTROLLER_TEST_DIR = File.join('test', "controllers")
27
+ CONTROLLER_SPEC_DIR = File.join('spec', "controllers")
28
+ REQUEST_SPEC_DIR = File.join('spec', "requests")
29
+ ROUTING_SPEC_DIR = File.join('spec', "routing")
28
30
 
29
31
  # Object Daddy http://github.com/flogic/object_daddy/tree/master
30
- EXEMPLARS_TEST_DIR = File.join("test", "exemplars")
31
- EXEMPLARS_SPEC_DIR = File.join("spec", "exemplars")
32
+ EXEMPLARS_TEST_DIR = File.join('test', "exemplars")
33
+ EXEMPLARS_SPEC_DIR = File.join('spec', "exemplars")
32
34
 
33
35
  # Machinist http://github.com/notahat/machinist
34
- BLUEPRINTS_TEST_DIR = File.join("test", "blueprints")
35
- BLUEPRINTS_SPEC_DIR = File.join("spec", "blueprints")
36
+ BLUEPRINTS_TEST_DIR = File.join('test', "blueprints")
37
+ BLUEPRINTS_SPEC_DIR = File.join('spec', "blueprints")
36
38
 
37
39
  # Factory Girl http://github.com/thoughtbot/factory_girl
38
- FACTORY_GIRL_TEST_DIR = File.join("test", "factories")
39
- FACTORY_GIRL_SPEC_DIR = File.join("spec", "factories")
40
+ FACTORY_GIRL_TEST_DIR = File.join('test', "factories")
41
+ FACTORY_GIRL_SPEC_DIR = File.join('spec', "factories")
40
42
 
41
43
  # Fabrication https://github.com/paulelliott/fabrication.git
42
- FABRICATORS_TEST_DIR = File.join("test", "fabricators")
43
- FABRICATORS_SPEC_DIR = File.join("spec", "fabricators")
44
+ FABRICATORS_TEST_DIR = File.join('test', "fabricators")
45
+ FABRICATORS_SPEC_DIR = File.join('spec', "fabricators")
44
46
 
45
47
  # Serializers https://github.com/rails-api/active_model_serializers
46
- SERIALIZERS_DIR = File.join("app", "serializers")
47
- SERIALIZERS_TEST_DIR = File.join("test", "serializers")
48
- SERIALIZERS_SPEC_DIR = File.join("spec", "serializers")
48
+ SERIALIZERS_DIR = File.join('app', "serializers")
49
+ SERIALIZERS_TEST_DIR = File.join('test', "serializers")
50
+ SERIALIZERS_SPEC_DIR = File.join('spec', "serializers")
49
51
 
50
52
  # Controller files
51
- CONTROLLER_DIR = File.join("app", "controllers")
53
+ CONTROLLER_DIR = File.join('app', "controllers")
52
54
 
53
55
  # Active admin registry files
54
- ACTIVEADMIN_DIR = File.join("app", "admin")
56
+ ACTIVEADMIN_DIR = File.join('app', "admin")
55
57
 
56
58
  # Helper files
57
- HELPER_DIR = File.join("app", "helpers")
59
+ HELPER_DIR = File.join('app', "helpers")
58
60
 
59
61
  # Don't show limit (#) on these column types
60
62
  # Example: show "integer" instead of "integer(4)"
61
- NO_LIMIT_COL_TYPES = %w(integer boolean)
63
+ NO_LIMIT_COL_TYPES = %w(integer boolean).freeze
62
64
 
63
65
  # Don't show default value for these column types
64
- NO_DEFAULT_COL_TYPES = %w(json jsonb)
66
+ NO_DEFAULT_COL_TYPES = %w(json jsonb hstore).freeze
65
67
 
66
68
  class << self
67
69
  def annotate_pattern(options = {})
@@ -78,86 +80,92 @@ module AnnotateModels
78
80
  attr_writer :model_dir
79
81
 
80
82
  def root_dir
81
- @root_dir.is_a?(Array) ? @root_dir : [@root_dir || '']
83
+ if @root_dir.blank?
84
+ ['']
85
+ elsif @root_dir.is_a?(String)
86
+ @root_dir.split(',')
87
+ else
88
+ @root_dir
89
+ end
82
90
  end
83
91
 
84
92
  attr_writer :root_dir
85
93
 
86
94
  def test_files(root_directory)
87
95
  [
88
- File.join(root_directory, UNIT_TEST_DIR, "%MODEL_NAME%_test.rb"),
89
- File.join(root_directory, MODEL_TEST_DIR, "%MODEL_NAME%_test.rb"),
90
- File.join(root_directory, SPEC_MODEL_DIR, "%MODEL_NAME%_spec.rb")
96
+ File.join(root_directory, UNIT_TEST_DIR, "%MODEL_NAME%_test.rb"),
97
+ File.join(root_directory, MODEL_TEST_DIR, "%MODEL_NAME%_test.rb"),
98
+ File.join(root_directory, SPEC_MODEL_DIR, "%MODEL_NAME%_spec.rb")
91
99
  ]
92
100
  end
93
101
 
94
102
  def fixture_files(root_directory)
95
103
  [
96
- File.join(root_directory, FIXTURE_TEST_DIR, "%TABLE_NAME%.yml"),
97
- File.join(root_directory, FIXTURE_SPEC_DIR, "%TABLE_NAME%.yml"),
98
- File.join(root_directory, FIXTURE_TEST_DIR, "%PLURALIZED_MODEL_NAME%.yml"),
99
- File.join(root_directory, FIXTURE_SPEC_DIR, "%PLURALIZED_MODEL_NAME%.yml")
104
+ File.join(root_directory, FIXTURE_TEST_DIR, "%TABLE_NAME%.yml"),
105
+ File.join(root_directory, FIXTURE_SPEC_DIR, "%TABLE_NAME%.yml"),
106
+ File.join(root_directory, FIXTURE_TEST_DIR, "%PLURALIZED_MODEL_NAME%.yml"),
107
+ File.join(root_directory, FIXTURE_SPEC_DIR, "%PLURALIZED_MODEL_NAME%.yml")
100
108
  ]
101
109
  end
102
110
 
103
111
  def scaffold_files(root_directory)
104
112
  [
105
- File.join(root_directory, CONTROLLER_TEST_DIR, "%PLURALIZED_MODEL_NAME%_controller_test.rb"),
106
- File.join(root_directory, CONTROLLER_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_controller_spec.rb"),
107
- File.join(root_directory, REQUEST_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_spec.rb"),
108
- File.join(root_directory, ROUTING_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_routing_spec.rb")
113
+ File.join(root_directory, CONTROLLER_TEST_DIR, "%PLURALIZED_MODEL_NAME%_controller_test.rb"),
114
+ File.join(root_directory, CONTROLLER_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_controller_spec.rb"),
115
+ File.join(root_directory, REQUEST_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_spec.rb"),
116
+ File.join(root_directory, ROUTING_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_routing_spec.rb")
109
117
  ]
110
118
  end
111
119
 
112
120
  def factory_files(root_directory)
113
121
  [
114
- File.join(root_directory, EXEMPLARS_TEST_DIR, "%MODEL_NAME%_exemplar.rb"),
115
- File.join(root_directory, EXEMPLARS_SPEC_DIR, "%MODEL_NAME%_exemplar.rb"),
116
- File.join(root_directory, BLUEPRINTS_TEST_DIR, "%MODEL_NAME%_blueprint.rb"),
117
- File.join(root_directory, BLUEPRINTS_SPEC_DIR, "%MODEL_NAME%_blueprint.rb"),
118
- File.join(root_directory, FACTORY_GIRL_TEST_DIR, "%MODEL_NAME%_factory.rb"), # (old style)
119
- File.join(root_directory, FACTORY_GIRL_SPEC_DIR, "%MODEL_NAME%_factory.rb"), # (old style)
120
- File.join(root_directory, FACTORY_GIRL_TEST_DIR, "%TABLE_NAME%.rb"), # (new style)
121
- File.join(root_directory, FACTORY_GIRL_SPEC_DIR, "%TABLE_NAME%.rb"), # (new style)
122
- File.join(root_directory, FABRICATORS_TEST_DIR, "%MODEL_NAME%_fabricator.rb"),
123
- File.join(root_directory, FABRICATORS_SPEC_DIR, "%MODEL_NAME%_fabricator.rb")
122
+ File.join(root_directory, EXEMPLARS_TEST_DIR, "%MODEL_NAME%_exemplar.rb"),
123
+ File.join(root_directory, EXEMPLARS_SPEC_DIR, "%MODEL_NAME%_exemplar.rb"),
124
+ File.join(root_directory, BLUEPRINTS_TEST_DIR, "%MODEL_NAME%_blueprint.rb"),
125
+ File.join(root_directory, BLUEPRINTS_SPEC_DIR, "%MODEL_NAME%_blueprint.rb"),
126
+ File.join(root_directory, FACTORY_GIRL_TEST_DIR, "%MODEL_NAME%_factory.rb"), # (old style)
127
+ File.join(root_directory, FACTORY_GIRL_SPEC_DIR, "%MODEL_NAME%_factory.rb"), # (old style)
128
+ File.join(root_directory, FACTORY_GIRL_TEST_DIR, "%TABLE_NAME%.rb"), # (new style)
129
+ File.join(root_directory, FACTORY_GIRL_SPEC_DIR, "%TABLE_NAME%.rb"), # (new style)
130
+ File.join(root_directory, FABRICATORS_TEST_DIR, "%MODEL_NAME%_fabricator.rb"),
131
+ File.join(root_directory, FABRICATORS_SPEC_DIR, "%MODEL_NAME%_fabricator.rb")
124
132
  ]
125
133
  end
126
134
 
127
135
  def serialize_files(root_directory)
128
136
  [
129
- File.join(root_directory, SERIALIZERS_DIR, "%MODEL_NAME%_serializer.rb"),
130
- File.join(root_directory, SERIALIZERS_TEST_DIR, "%MODEL_NAME%_serializer_spec.rb"),
131
- File.join(root_directory, SERIALIZERS_SPEC_DIR, "%MODEL_NAME%_serializer_spec.rb")
137
+ File.join(root_directory, SERIALIZERS_DIR, "%MODEL_NAME%_serializer.rb"),
138
+ File.join(root_directory, SERIALIZERS_TEST_DIR, "%MODEL_NAME%_serializer_spec.rb"),
139
+ File.join(root_directory, SERIALIZERS_SPEC_DIR, "%MODEL_NAME%_serializer_spec.rb")
132
140
  ]
133
141
  end
134
142
 
135
143
  def files_by_pattern(root_directory, pattern_type)
136
144
  case pattern_type
137
- when 'test' then test_files(root_directory)
138
- when 'fixture' then fixture_files(root_directory)
139
- when 'scaffold' then scaffold_files(root_directory)
140
- when 'factory' then factory_files(root_directory)
141
- when 'serializer' then serialize_files(root_directory)
142
- when 'controller'
143
- [File.join(root_directory, CONTROLLER_DIR, "%PLURALIZED_MODEL_NAME%_controller.rb")]
144
- when 'admin'
145
- [File.join(root_directory, ACTIVEADMIN_DIR, "%MODEL_NAME%.rb")]
146
- when 'helper'
147
- [File.join(root_directory, HELPER_DIR, "%PLURALIZED_MODEL_NAME%_helper.rb")]
148
- else
149
- []
145
+ when 'test' then test_files(root_directory)
146
+ when 'fixture' then fixture_files(root_directory)
147
+ when 'scaffold' then scaffold_files(root_directory)
148
+ when 'factory' then factory_files(root_directory)
149
+ when 'serializer' then serialize_files(root_directory)
150
+ when 'controller'
151
+ [File.join(root_directory, CONTROLLER_DIR, "%PLURALIZED_MODEL_NAME%_controller.rb")]
152
+ when 'admin'
153
+ [File.join(root_directory, ACTIVEADMIN_DIR, "%MODEL_NAME%.rb")]
154
+ when 'helper'
155
+ [File.join(root_directory, HELPER_DIR, "%PLURALIZED_MODEL_NAME%_helper.rb")]
156
+ else
157
+ []
150
158
  end
151
159
  end
152
160
 
153
- def get_patterns(pattern_types=[])
161
+ def get_patterns(pattern_types = [])
154
162
  current_patterns = []
155
163
  root_dir.each do |root_directory|
156
164
  Array(pattern_types).each do |pattern_type|
157
165
  current_patterns += files_by_pattern(root_directory, pattern_type)
158
166
  end
159
167
  end
160
- current_patterns.map{ |p| p.sub(/^[\/]*/, '') }
168
+ current_patterns.map { |p| p.sub(/^[\/]*/, '') }
161
169
  end
162
170
 
163
171
  # Simple quoting for the default column value
@@ -166,10 +174,10 @@ module AnnotateModels
166
174
  when NilClass then 'NULL'
167
175
  when TrueClass then 'TRUE'
168
176
  when FalseClass then 'FALSE'
169
- when Float, Fixnum, Bignum then value.to_s
177
+ when Float, Integer then value.to_s
170
178
  # BigDecimals need to be output in a non-normalized form and quoted.
171
179
  when BigDecimal then value.to_s('F')
172
- when Array then value.map {|v| quote(v)}
180
+ when Array then value.map { |v| quote(v) }
173
181
  else
174
182
  value.inspect
175
183
  end
@@ -179,31 +187,38 @@ module AnnotateModels
179
187
  quote(klass.column_defaults[column.name])
180
188
  end
181
189
 
190
+ def retrieve_indexes_from_table(klass)
191
+ table_name = klass.table_name
192
+ return [] unless table_name
193
+
194
+ indexes = klass.connection.indexes(table_name)
195
+ return indexes if indexes.any? || !klass.table_name_prefix
196
+
197
+ # Try to search the table without prefix
198
+ table_name.to_s.slice!(klass.table_name_prefix)
199
+ klass.connection.indexes(table_name)
200
+ end
201
+
182
202
  # Use the column information in an ActiveRecord class
183
203
  # to create a comment block containing a line for
184
204
  # each column. The line contains the column name,
185
205
  # the type (and length), and any optional attributes
186
206
  def get_schema_info(klass, header, options = {})
187
207
  info = "# #{header}\n"
188
- info<< "#\n"
189
- if options[:format_markdown]
190
- info<< "# Table name: `#{klass.table_name}`\n"
191
- info<< "#\n"
192
- info<< "# ### Columns\n"
193
- else
194
- info<< "# Table name: #{klass.table_name}\n"
195
- end
196
- info<< "#\n"
208
+ info << get_schema_header_text(klass, options)
197
209
 
198
210
  max_size = klass.column_names.map(&:size).max || 0
211
+ with_comment = options[:with_comment] && klass.columns.first.respond_to?(:comment)
212
+ max_size = klass.columns.map{|col| col.name.size + col.comment.size }.max || 0 if with_comment
213
+ max_size += 2 if with_comment
199
214
  max_size += options[:format_rdoc] ? 5 : 1
200
215
  md_names_overhead = 6
201
216
  md_type_allowance = 18
202
217
  bare_type_allowance = 16
203
218
 
204
219
  if options[:format_markdown]
205
- info<< sprintf( "# %-#{max_size + md_names_overhead}.#{max_size + md_names_overhead}s | %-#{md_type_allowance}.#{md_type_allowance}s | %s\n", 'Name', 'Type', 'Attributes' )
206
- info<< "# #{ '-' * ( max_size + md_names_overhead ) } | #{'-' * md_type_allowance} | #{ '-' * 27 }\n"
220
+ info << sprintf( "# %-#{max_size + md_names_overhead}.#{max_size + md_names_overhead}s | %-#{md_type_allowance}.#{md_type_allowance}s | %s\n", 'Name', 'Type', 'Attributes' )
221
+ info << "# #{ '-' * ( max_size + md_names_overhead ) } | #{'-' * md_type_allowance} | #{ '-' * 27 }\n"
207
222
  end
208
223
 
209
224
  cols = if ignore_columns = options[:ignore_columns]
@@ -218,9 +233,9 @@ module AnnotateModels
218
233
  cols = classified_sort(cols) if options[:classified_sort]
219
234
  cols.each do |col|
220
235
  col_type = (col.type || col.sql_type).to_s
221
-
222
236
  attrs = []
223
- attrs << "default(#{schema_default(klass, col)})" unless col.default.nil? || NO_DEFAULT_COL_TYPES.include?(col_type)
237
+ attrs << "default(#{schema_default(klass, col)})" unless col.default.nil? || hide_default?(col_type, options)
238
+ attrs << 'unsigned' if col.respond_to?(:unsigned?) && col.unsigned?
224
239
  attrs << 'not null' unless col.null
225
240
  attrs << 'primary key' if klass.primary_key && (klass.primary_key.is_a?(Array) ? klass.primary_key.collect(&:to_sym).include?(col.name.to_sym) : col.name.to_sym == klass.primary_key.to_sym)
226
241
 
@@ -250,23 +265,28 @@ module AnnotateModels
250
265
  # Check if the column has indices and print "indexed" if true
251
266
  # If the index includes another column, print it too.
252
267
  if options[:simple_indexes] && klass.table_exists?# Check out if this column is indexed
253
- indices = klass.connection.indexes(klass.table_name)
268
+ indices = retrieve_indexes_from_table(klass)
254
269
  if indices = indices.select { |ind| ind.columns.include? col.name }
255
270
  indices.sort_by(&:name).each do |ind|
271
+ next if ind.columns.is_a?(String)
256
272
  ind = ind.columns.reject! { |i| i == col.name }
257
273
  attrs << (ind.empty? ? "indexed" : "indexed => [#{ind.join(", ")}]")
258
274
  end
259
275
  end
260
276
  end
261
-
277
+ col_name = if with_comment
278
+ "#{col.name}(#{col.comment})"
279
+ else
280
+ col.name
281
+ end
262
282
  if options[:format_rdoc]
263
- info << sprintf("# %-#{max_size}.#{max_size}s<tt>%s</tt>", "*#{col.name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n"
283
+ info << sprintf("# %-#{max_size}.#{max_size}s<tt>%s</tt>", "*#{col_name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n"
264
284
  elsif options[:format_markdown]
265
- name_remainder = max_size - col.name.length
285
+ name_remainder = max_size - col_name.length
266
286
  type_remainder = (md_type_allowance - 2) - col_type.length
267
- info << (sprintf("# **`%s`**%#{name_remainder}s | `%s`%#{type_remainder}s | `%s`", col.name, " ", col_type, " ", attrs.join(", ").rstrip)).gsub('``', ' ').rstrip + "\n"
287
+ info << (sprintf("# **`%s`**%#{name_remainder}s | `%s`%#{type_remainder}s | `%s`", col_name, " ", col_type, " ", attrs.join(", ").rstrip)).gsub('``', ' ').rstrip + "\n"
268
288
  else
269
- info << sprintf("# %-#{max_size}.#{max_size}s:%-#{bare_type_allowance}.#{bare_type_allowance}s %s", col.name, col_type, attrs.join(", ")).rstrip + "\n"
289
+ info << sprintf("# %-#{max_size}.#{max_size}s:%-#{bare_type_allowance}.#{bare_type_allowance}s %s", col_name, col_type, attrs.join(", ")).rstrip + "\n"
270
290
  end
271
291
  end
272
292
 
@@ -278,6 +298,23 @@ module AnnotateModels
278
298
  info << get_foreign_key_info(klass, options)
279
299
  end
280
300
 
301
+ info << get_schema_footer_text(klass, options)
302
+ end
303
+
304
+ def get_schema_header_text(klass, options = {})
305
+ info = "#\n"
306
+ if options[:format_markdown]
307
+ info << "# Table name: `#{klass.table_name}`\n"
308
+ info << "#\n"
309
+ info << "# ### Columns\n"
310
+ else
311
+ info << "# Table name: #{klass.table_name}\n"
312
+ end
313
+ info << "#\n"
314
+ end
315
+
316
+ def get_schema_footer_text(_klass, options = {})
317
+ info = ''
281
318
  if options[:format_rdoc]
282
319
  info << "#--\n"
283
320
  info << "# #{END_MARK}\n"
@@ -287,23 +324,23 @@ module AnnotateModels
287
324
  end
288
325
  end
289
326
 
290
- def get_index_info(klass, options={})
291
- if options[:format_markdown]
292
- index_info = "#\n# ### Indexes\n#\n"
293
- else
294
- index_info = "#\n# Indexes\n#\n"
295
- end
327
+ def get_index_info(klass, options = {})
328
+ index_info = if options[:format_markdown]
329
+ "#\n# ### Indexes\n#\n"
330
+ else
331
+ "#\n# Indexes\n#\n"
332
+ end
296
333
 
297
- indexes = klass.connection.indexes(klass.table_name)
334
+ indexes = retrieve_indexes_from_table(klass)
298
335
  return '' if indexes.empty?
299
336
 
300
337
  max_size = indexes.collect{|index| index.name.size}.max + 1
301
338
  indexes.sort_by(&:name).each do |index|
302
- if options[:format_markdown]
303
- index_info << sprintf("# * `%s`%s:\n# * **`%s`**\n", index.name, index.unique ? " (_unique_)" : "", index.columns.join("`**\n# * **`"))
304
- else
305
- index_info << sprintf("# %-#{max_size}.#{max_size}s %s %s", index.name, "(#{index.columns.join(",")})", index.unique ? "UNIQUE" : "").rstrip + "\n"
306
- end
339
+ index_info << if options[:format_markdown]
340
+ sprintf("# * `%s`%s:\n# * **`%s`**\n", index.name, index.unique ? " (_unique_)" : "", Array(index.columns).join("`**\n# * **`"))
341
+ else
342
+ sprintf("# %-#{max_size}.#{max_size}s %s %s", index.name, "(#{Array(index.columns).join(",")})", index.unique ? "UNIQUE" : "").rstrip + "\n"
343
+ end
307
344
  end
308
345
 
309
346
  index_info
@@ -320,12 +357,23 @@ module AnnotateModels
320
357
  excludes.include?(col_type)
321
358
  end
322
359
 
323
- def get_foreign_key_info(klass, options={})
324
- if options[:format_markdown]
325
- fk_info = "#\n# ### Foreign Keys\n#\n"
326
- else
327
- fk_info = "#\n# Foreign Keys\n#\n"
328
- end
360
+ def hide_default?(col_type, options)
361
+ excludes =
362
+ if options[:hide_default_column_types].blank?
363
+ NO_DEFAULT_COL_TYPES
364
+ else
365
+ options[:hide_default_column_types].split(',')
366
+ end
367
+
368
+ excludes.include?(col_type)
369
+ end
370
+
371
+ def get_foreign_key_info(klass, options = {})
372
+ fk_info = if options[:format_markdown]
373
+ "#\n# ### Foreign Keys\n#\n"
374
+ else
375
+ "#\n# Foreign Keys\n#\n"
376
+ end
329
377
 
330
378
  return '' unless klass.connection.respond_to?(:supports_foreign_keys?) &&
331
379
  klass.connection.supports_foreign_keys? && klass.connection.respond_to?(:foreign_keys)
@@ -333,27 +381,30 @@ module AnnotateModels
333
381
  foreign_keys = klass.connection.foreign_keys(klass.table_name)
334
382
  return '' if foreign_keys.empty?
335
383
 
336
- max_size = foreign_keys.collect{|fk| fk.name.size}.max + 1
337
- foreign_keys.sort_by(&:name).each do |fk|
384
+ format_name = ->(fk) { options[:show_complete_foreign_keys] ? fk.name : fk.name.gsub(/(?<=^fk_rails_)[0-9a-f]{10}$/, '...') }
385
+
386
+ max_size = foreign_keys.map(&format_name).map(&:size).max + 1
387
+ foreign_keys.sort_by {|fk| [format_name.call(fk), fk.column]}.each do |fk|
338
388
  ref_info = "#{fk.column} => #{fk.to_table}.#{fk.primary_key}"
339
389
  constraints_info = ''
340
390
  constraints_info += "ON DELETE => #{fk.on_delete} " if fk.on_delete
341
391
  constraints_info += "ON UPDATE => #{fk.on_update} " if fk.on_update
342
392
  constraints_info.strip!
343
- if options[:format_markdown]
344
- fk_info << sprintf("# * `%s`%s:\n# * **`%s`**\n", fk.name, constraints_info.blank? ? '' : " (_#{constraints_info}_)", ref_info)
345
- else
346
- fk_info << sprintf("# %-#{max_size}.#{max_size}s %s %s", fk.name, "(#{ref_info})", constraints_info).rstrip + "\n"
347
- end
393
+
394
+ fk_info << if options[:format_markdown]
395
+ sprintf("# * `%s`%s:\n# * **`%s`**\n", format_name.call(fk), constraints_info.blank? ? '' : " (_#{constraints_info}_)", ref_info)
396
+ else
397
+ sprintf("# %-#{max_size}.#{max_size}s %s %s", format_name.call(fk), "(#{ref_info})", constraints_info).rstrip + "\n"
398
+ end
348
399
  end
349
400
 
350
401
  fk_info
351
402
  end
352
403
 
353
404
  # Add a schema block to a file. If the file already contains
354
- # a schema info block (a comment starting with "== Schema Information"), check if it
355
- # matches the block that is already there. If so, leave it be. If not, remove the old
356
- # info block and write a new one.
405
+ # a schema info block (a comment starting with "== Schema Information"),
406
+ # check if it matches the block that is already there. If so, leave it be.
407
+ # If not, remove the old info block and write a new one.
357
408
  #
358
409
  # == Returns:
359
410
  # true or false depending on whether the file was modified.
@@ -363,7 +414,7 @@ module AnnotateModels
363
414
  # :position_in_*<Symbol>:: where to place the annotated section in fixture or model file,
364
415
  # :before, :top, :after or :bottom. Default is :before.
365
416
  #
366
- def annotate_one_file(file_name, info_block, position, options={})
417
+ def annotate_one_file(file_name, info_block, position, options = {})
367
418
  if File.exist?(file_name)
368
419
  old_content = File.read(file_name)
369
420
  return false if old_content =~ /# -\*- SkipSchemaAnnotations.*\n/
@@ -377,8 +428,8 @@ module AnnotateModels
377
428
  old_columns = old_header && old_header.scan(column_pattern).sort
378
429
  new_columns = new_header && new_header.scan(column_pattern).sort
379
430
 
380
- magic_comment_matcher= Regexp.new(/(^#\s*encoding:.*\n)|(^# coding:.*\n)|(^# -\*- coding:.*\n)|(^# -\*- encoding\s?:.*\n)|(^#\s*frozen_string_literal:.+\n)|(^# -\*- frozen_string_literal\s*:.+-\*-\n)/)
381
- magic_comments= old_content.scan(magic_comment_matcher).flatten.compact
431
+ magic_comment_matcher = Regexp.new(/(^#\s*encoding:.*\n)|(^# coding:.*\n)|(^# -\*- coding:.*\n)|(^# -\*- encoding\s?:.*\n)|(^#\s*frozen_string_literal:.+\n)|(^# -\*- frozen_string_literal\s*:.+-\*-\n)/)
432
+ magic_comments = old_content.scan(magic_comment_matcher).flatten.compact
382
433
 
383
434
  if old_columns == new_columns && !options[:force]
384
435
  return false
@@ -399,11 +450,11 @@ module AnnotateModels
399
450
  old_content.sub!(magic_comment_matcher, '')
400
451
  old_content.sub!(annotate_pattern(options), '')
401
452
 
402
- if %w(after bottom).include?(options[position].to_s)
403
- new_content = magic_comments.join + (old_content.rstrip + "\n\n" + wrapped_info_block)
404
- else
405
- new_content = magic_comments.join + wrapped_info_block + "\n" + old_content
406
- end
453
+ new_content = if %w(after bottom).include?(options[position].to_s)
454
+ magic_comments.join + (old_content.rstrip + "\n\n" + wrapped_info_block)
455
+ else
456
+ magic_comments.join + wrapped_info_block + "\n" + old_content
457
+ end
407
458
  end
408
459
 
409
460
  File.open(file_name, 'wb') { |f| f.puts new_content }
@@ -414,10 +465,10 @@ module AnnotateModels
414
465
  end
415
466
  end
416
467
 
417
- def remove_annotation_of_file(file_name, options={})
468
+ def remove_annotation_of_file(file_name, options = {})
418
469
  if File.exist?(file_name)
419
470
  content = File.read(file_name)
420
- wrapper_open = options[:wrapper_open] ? "# #{options[:wrapper_open]}\n" : ""
471
+ wrapper_open = options[:wrapper_open] ? "# #{options[:wrapper_open]}\n" : ''
421
472
  content.sub!(/(#{wrapper_open})?#{annotate_pattern(options)}/, '')
422
473
 
423
474
  File.open(file_name, 'wb') { |f| f.puts content }
@@ -453,11 +504,12 @@ module AnnotateModels
453
504
  # :exclude_scaffolds<Symbol>:: whether to skip modification of scaffold files
454
505
  # :exclude_controllers<Symbol>:: whether to skip modification of controller files
455
506
  # :exclude_helpers<Symbol>:: whether to skip modification of helper files
507
+ # :exclude_sti_subclasses<Symbol>:: whether to skip modification of files for STI subclasses
456
508
  #
457
509
  # == Returns:
458
510
  # an array of file names that were annotated.
459
511
  #
460
- def annotate(klass, file, header, options={})
512
+ def annotate(klass, file, header, options = {})
461
513
  begin
462
514
  klass.reset_column_information
463
515
  info = get_schema_info(klass, header, options)
@@ -480,17 +532,16 @@ module AnnotateModels
480
532
  position_key = 'position_in_class'.to_sym
481
533
  end
482
534
 
483
- unless options[exclusion_key]
484
- self.get_patterns(key).
485
- map { |f| resolve_filename(f, model_name, table_name) }.
486
- each { |f|
487
- if annotate_one_file(f, info, position_key, options_with_position(options, position_key))
488
- annotated << f
489
- end
490
- }
491
- end
535
+ next if options[exclusion_key]
536
+ get_patterns(key)
537
+ .map { |f| resolve_filename(f, model_name, table_name) }
538
+ .each do |f|
539
+ if annotate_one_file(f, info, position_key, options_with_position(options, position_key))
540
+ annotated << f
541
+ end
542
+ end
492
543
  end
493
- rescue Exception => e
544
+ rescue StandardError => e
494
545
  puts "Unable to annotate #{file}: #{e.message}"
495
546
  puts "\t" + e.backtrace.join("\n\t") if options[:trace]
496
547
  end
@@ -509,8 +560,8 @@ module AnnotateModels
509
560
  # in the model_dir directory.
510
561
  def get_model_files(options)
511
562
  models = []
512
- if !options[:is_rake]
513
- models = ARGV.dup.reject{|m| m.match(/^(.*)=/)}
563
+ unless options[:is_rake]
564
+ models = ARGV.dup.reject { |m| m.match(/^(.*)=/) }
514
565
  end
515
566
 
516
567
  if models.empty?
@@ -561,21 +612,18 @@ module AnnotateModels
561
612
 
562
613
  # Retrieve loaded model class by path to the file where it's supposed to be defined.
563
614
  def get_loaded_model(model_path)
564
- begin
565
- ActiveSupport::Inflector.constantize(ActiveSupport::Inflector.camelize(model_path))
566
- rescue
567
- # Revert to the old way but it is not really robust
568
- ObjectSpace.each_object(::Class).
569
- select do |c|
570
- Class === c && # note: we use === to avoid a bug in activesupport 2.3.14 OptionMerger vs. is_a?
571
- c.ancestors.respond_to?(:include?) && # to fix FactoryGirl bug, see https://github.com/ctran/annotate_models/pull/82
572
- c.ancestors.include?(ActiveRecord::Base)
573
- end.
574
- detect { |c| ActiveSupport::Inflector.underscore(c.to_s) == model_path }
575
- end
576
- end
577
-
578
- def parse_options(options={})
615
+ ActiveSupport::Inflector.constantize(ActiveSupport::Inflector.camelize(model_path))
616
+ rescue
617
+ # Revert to the old way but it is not really robust
618
+ ObjectSpace.each_object(::Class)
619
+ .select do |c|
620
+ Class === c && # note: we use === to avoid a bug in activesupport 2.3.14 OptionMerger vs. is_a?
621
+ c.ancestors.respond_to?(:include?) && # to fix FactoryGirl bug, see https://github.com/ctran/annotate_models/pull/82
622
+ c.ancestors.include?(ActiveRecord::Base)
623
+ end.detect { |c| ActiveSupport::Inflector.underscore(c.to_s) == model_path }
624
+ end
625
+
626
+ def parse_options(options = {})
579
627
  self.model_dir = options[:model_dir] if options[:model_dir]
580
628
  self.root_dir = options[:root_dir] if options[:root_dir]
581
629
  end
@@ -584,7 +632,7 @@ module AnnotateModels
584
632
  # ActiveRecord models. If we can find the class, and
585
633
  # if its a subclass of ActiveRecord::Base,
586
634
  # then pass it to the associated block
587
- def do_annotations(options={})
635
+ def do_annotations(options = {})
588
636
  parse_options(options)
589
637
 
590
638
  header = options[:format_markdown] ? PREFIX_MD.dup : PREFIX.dup
@@ -609,21 +657,25 @@ module AnnotateModels
609
657
  begin
610
658
  return false if /# -\*- SkipSchemaAnnotations.*/ =~ (File.exist?(file) ? File.read(file) : '')
611
659
  klass = get_model_class(file)
612
- if klass && klass < ActiveRecord::Base && !klass.abstract_class? && klass.table_exists?
613
- annotated.concat(annotate(klass, file, header, options))
614
- end
660
+ do_annotate = klass &&
661
+ klass < ActiveRecord::Base &&
662
+ (!options[:exclude_sti_subclasses] || !(klass.superclass < ActiveRecord::Base && klass.table_name == klass.superclass.table_name)) &&
663
+ !klass.abstract_class? &&
664
+ klass.table_exists?
665
+
666
+ annotated.concat(annotate(klass, file, header, options)) if do_annotate
615
667
  rescue BadModelFileError => e
616
668
  unless options[:ignore_unknown_models]
617
669
  puts "Unable to annotate #{file}: #{e.message}"
618
670
  puts "\t" + e.backtrace.join("\n\t") if options[:trace]
619
671
  end
620
- rescue Exception => e
672
+ rescue StandardError => e
621
673
  puts "Unable to annotate #{file}: #{e.message}"
622
674
  puts "\t" + e.backtrace.join("\n\t") if options[:trace]
623
675
  end
624
676
  end
625
677
 
626
- def remove_annotations(options={})
678
+ def remove_annotations(options = {})
627
679
  parse_options(options)
628
680
 
629
681
  deannotated = []
@@ -638,9 +690,9 @@ module AnnotateModels
638
690
  model_file_name = file
639
691
  deannotated_klass = true if remove_annotation_of_file(model_file_name, options)
640
692
 
641
- get_patterns(matched_types(options)).
642
- map { |f| resolve_filename(f, model_name, table_name) }.
643
- each do |f|
693
+ get_patterns(matched_types(options))
694
+ .map { |f| resolve_filename(f, model_name, table_name) }
695
+ .each do |f|
644
696
  if File.exist?(f)
645
697
  remove_annotation_of_file(f, options)
646
698
  deannotated_klass = true
@@ -648,7 +700,7 @@ module AnnotateModels
648
700
  end
649
701
  end
650
702
  deannotated << klass if deannotated_klass
651
- rescue Exception => e
703
+ rescue StandardError => e
652
704
  puts "Unable to deannotate #{File.join(file)}: #{e.message}"
653
705
  puts "\t" + e.backtrace.join("\n\t") if options[:trace]
654
706
  end
@@ -657,10 +709,10 @@ module AnnotateModels
657
709
  end
658
710
 
659
711
  def resolve_filename(filename_template, model_name, table_name)
660
- filename_template.
661
- gsub('%MODEL_NAME%', model_name).
662
- gsub('%PLURALIZED_MODEL_NAME%', model_name.pluralize).
663
- gsub('%TABLE_NAME%', table_name || model_name.pluralize)
712
+ filename_template
713
+ .gsub('%MODEL_NAME%', model_name)
714
+ .gsub('%PLURALIZED_MODEL_NAME%', model_name.pluralize)
715
+ .gsub('%TABLE_NAME%', table_name || model_name.pluralize)
664
716
  end
665
717
 
666
718
  def classified_sort(cols)
@@ -674,20 +726,21 @@ module AnnotateModels
674
726
  id = c
675
727
  elsif c.name.eql?('created_at') || c.name.eql?('updated_at')
676
728
  timestamps << c
677
- elsif c.name[-3,3].eql?('_id')
729
+ elsif c.name[-3, 3].eql?('_id')
678
730
  associations << c
679
731
  else
680
732
  rest_cols << c
681
733
  end
682
734
  end
683
- [rest_cols, timestamps, associations].each {|a| a.sort_by!(&:name) }
735
+ [rest_cols, timestamps, associations].each { |a| a.sort_by!(&:name) }
684
736
 
685
- return ([id] << rest_cols << timestamps << associations).flatten.compact
737
+ ([id] << rest_cols << timestamps << associations).flatten.compact
686
738
  end
687
739
 
688
740
  # Ignore warnings for the duration of the block ()
689
741
  def silence_warnings
690
- old_verbose, $VERBOSE = $VERBOSE, nil
742
+ old_verbose = $VERBOSE
743
+ $VERBOSE = nil
691
744
  yield
692
745
  ensure
693
746
  $VERBOSE = old_verbose