annotate 2.7.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/RELEASE.md ADDED
@@ -0,0 +1,19 @@
1
+ ## Prerequisite
2
+
3
+ - Install "git-flow" (`brew install git-flow`)
4
+ - Install "bump" gem (`gem install bump`)
5
+
6
+
7
+ ## Perform a release
8
+
9
+ - `git flow release start <release>`
10
+ - Update the `CHANGELOG.md` file
11
+ - `bump current`
12
+ - `bump patch`
13
+ - `rm -rf dist`
14
+ - `rake spec`
15
+ - `rake gem`
16
+ - `git flow release finish <release>`
17
+
18
+ - `rake gem:publish`
19
+
data/annotate.gemspec CHANGED
@@ -4,36 +4,26 @@ $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
- 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."
10
+ s.required_ruby_version = '>= 2.4.0'
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.md', 'CHANGELOG.md']
17
+ s.files = `git ls-files -z LICENSE.txt *.md *.gemspec bin lib`.split("\x0")
18
+ s.homepage = 'http://github.com/ctran/annotate_models'
19
+ s.licenses = ['Ruby']
20
+ s.require_paths = ['lib']
21
+ s.rubygems_version = '2.1.11'
22
+ s.summary = 'Annotates Rails Models, routes, fixtures, and others based on the database schema.'
24
23
 
25
- if s.respond_to? :specification_version then
26
- s.specification_version = 4
24
+ s.specification_version = 4 if s.respond_to? :specification_version
25
+ s.add_runtime_dependency(%q<rake>, '>= 10.4', '< 14.0')
26
+ s.add_runtime_dependency(%q<activerecord>, ['>= 3.2', '< 7.0'])
27
27
 
28
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
29
- s.add_runtime_dependency(%q<rake>, ["~> 10.4"])
30
- s.add_runtime_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
31
- else
32
- s.add_dependency(%q<rake>, ["~> 10.4"])
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
28
+ s.metadata = { "github_repo" => "ssh://github.com/ctran/annotate_models" }
39
29
  end
data/bin/annotate CHANGED
@@ -1,195 +1,32 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- unless File.exists?('./Rakefile') || File.exists?('./Gemfile')
4
- abort "Please run annotate from the root of the project."
3
+ unless File.exist?('./Rakefile') || File.exist?('./Gemfile')
4
+ abort 'Please run annotate from the root of the project.'
5
5
  end
6
6
 
7
7
  require 'rubygems'
8
8
  begin
9
9
  require 'bundler'
10
10
  Bundler.setup
11
- rescue Exception => e
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
- require 'optparse'
18
17
  require 'annotate'
19
- Annotate.bootstrap_rake
20
-
21
- has_set_position = {}
22
- target_action = :do_annotations
23
-
24
- OptionParser.new do |opts|
25
- opts.banner = "Usage: annotate [options] [model_file]*"
26
-
27
- opts.on('-d', '--delete',
28
- "Remove annotations from all model files or the routes.rb file") do
29
-
30
- target_action = :remove_annotations
31
- end
32
-
33
- opts.on('-p', '--position [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
34
- "Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/route/serializer file(s)") do |p|
35
- ENV['position'] = p
36
- [
37
- 'position_in_class','position_in_factory','position_in_fixture','position_in_test', 'position_in_routes', 'position_in_serializer'
38
- ].each do |key|
39
- ENV[key] = p unless(has_set_position[key])
40
- end
41
- end
42
-
43
- opts.on('--pc', '--position-in-class [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
44
- "Place the annotations at the top (before) or the bottom (after) of the model file") do |p|
45
- ENV['position_in_class'] = p
46
- has_set_position['position_in_class'] = true
47
- end
48
-
49
- opts.on('--pf', '--position-in-factory [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
50
- "Place the annotations at the top (before) or the bottom (after) of any factory files") do |p|
51
- ENV['position_in_factory'] = p
52
- has_set_position['position_in_factory'] = true
53
- end
54
-
55
- opts.on('--px', '--position-in-fixture [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
56
- "Place the annotations at the top (before) or the bottom (after) of any fixture files") do |p|
57
- ENV['position_in_fixture'] = p
58
- has_set_position['position_in_fixture'] = true
59
- end
60
-
61
- opts.on('--pt', '--position-in-test [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
62
- "Place the annotations at the top (before) or the bottom (after) of any test files") do |p|
63
- ENV['position_in_test'] = p
64
- has_set_position['position_in_test'] = true
65
- end
66
-
67
- opts.on('--pr', '--position-in-routes [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
68
- "Place the annotations at the top (before) or the bottom (after) of the routes.rb file") do |p|
69
- ENV['position_in_routes'] = p
70
- has_set_position['position_in_routes'] = true
71
- end
72
-
73
- opts.on('--ps', '--position-in-serializer [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
74
- "Place the annotations at the top (before) or the bottom (after) of the serializer files") do |p|
75
- ENV['position_in_serializer'] = p
76
- has_set_position['position_in_serializer'] = true
77
- end
78
-
79
- opts.on('--w', '--wrapper STR', 'Wrap annotation with the text passed as parameter.',
80
- 'If --w option is used, the same text will be used as opening and closing') do |p|
81
- ENV['wrapper'] = p
82
- end
83
-
84
- opts.on('--wo', '--wrapper-open STR', 'Annotation wrapper opening.') do |p|
85
- ENV['wrapper_open'] = p
86
- end
87
-
88
- opts.on('--wc', '--wrapper-close STR', 'Annotation wrapper closing') do |p|
89
- ENV['wrapper_close'] = p
90
- end
91
-
92
- opts.on('-r', '--routes',
93
- "Annotate routes.rb with the output of 'rake routes'") do
94
- ENV['routes'] = 'true'
95
- end
96
-
97
- opts.on('-v', '--version',
98
- "Show the current version of this gem") do
99
- puts "annotate v#{Annotate.version}"; exit
100
- end
18
+ require 'annotate/parser'
101
19
 
102
- opts.on('-m', '--show-migration',
103
- "Include the migration version number in the annotation") do
104
- ENV['include_version'] = "yes"
105
- end
106
-
107
- opts.on('-k', '--show-foreign-keys',
108
- "List the table's foreign key constraints in the annotation") do
109
- ENV['show_foreign_keys'] = "yes"
110
- end
111
-
112
- opts.on('-i', '--show-indexes',
113
- "List the table's database indexes in the annotation") do
114
- ENV['show_indexes'] = "yes"
115
- end
116
-
117
- opts.on('-s', '--simple-indexes',
118
- "Concat the column's related indexes in the annotation") do
119
- ENV['simple_indexes'] = "yes"
120
- end
121
-
122
- opts.on('--model-dir dir',
123
- "Annotate model files stored in dir rather than app/models, separate multiple dirs with comas") do |dir|
124
- ENV['model_dir'] = dir
125
- end
126
-
127
- opts.on('--root-dir dir',
128
- "Annotate files stored within root dir projects, separate multiple dirs with comas") do |dir|
129
- ENV['root_dir'] = dir
130
- end
131
-
132
- opts.on('--ignore-model-subdirects',
133
- "Ignore subdirectories of the models directory") do |dir|
134
- ENV['ignore_model_sub_dir'] = "yes"
135
- end
136
-
137
- opts.on('--sort',
138
- "Sort columns alphabetically, rather than in creation order") do |dir|
139
- ENV['sort'] = "yes"
140
- end
141
-
142
- opts.on('--classified-sort',
143
- "Sort columns alphabetically, but first goes id, then the rest columns, then the timestamp columns and then the association columns") do |dir|
144
- ENV['classified_sort'] = "yes"
145
- end
146
-
147
- opts.on('-R', '--require path',
148
- "Additional file to require before loading models, may be used multiple times") do |path|
149
- if !ENV['require'].blank?
150
- ENV['require'] = ENV['require'] + ",#{path}"
151
- else
152
- ENV['require'] = path
153
- end
154
- end
155
-
156
- opts.on('-e', '--exclude [tests,fixtures,factories,serializers]', Array, "Do not annotate fixtures, test files, factories, and/or serializers") do |exclusions|
157
- exclusions ||= %w(tests fixtures factories)
158
- exclusions.each { |exclusion| ENV["exclude_#{exclusion}"] = "yes" }
159
- end
160
-
161
- opts.on('-f', '--format [bare|rdoc|markdown]', ['bare', 'rdoc', 'markdown'], 'Render Schema Infomation as plain/RDoc/Markdown') do |fmt|
162
- ENV["format_#{fmt}"] = 'yes'
163
- end
164
-
165
- opts.on('--force', 'Force new annotations even if there are no changes.') do |force|
166
- ENV['force'] = 'yes'
167
- end
168
-
169
- opts.on('--timestamp', 'Include timestamp in (routes) annotation') do
170
- ENV['timestamp'] = 'true'
171
- end
172
-
173
- opts.on('--trace', 'If unable to annotate a file, print the full stack trace, not just the exception message.') do |value|
174
- ENV['trace'] = 'yes'
175
- end
176
-
177
- opts.on('-I', '--ignore-columns REGEX', "don't annotate columns that match a given REGEX (i.e., `annotate -I '^(id|updated_at|created_at)'`" ) do |regex|
178
- ENV['ignore_columns'] = regex
179
- end
180
-
181
- 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|
182
- ENV['hide_limit_column_types'] = "#{values}"
183
- end
20
+ Annotate.bootstrap_rake
184
21
 
185
- opts.on('--ignore-unknown-models', "don't display warnings for bad model files" ) do |values|
186
- ENV['ignore_unknown_models'] = "true"
187
- end
22
+ options_result = Annotate::Parser.parse(ARGV)
188
23
 
189
- end.parse!
24
+ exit if options_result[:exit]
190
25
 
191
- options = Annotate.setup_options({ :is_rake => ENV['is_rake'] && !ENV['is_rake'].empty? })
192
- Annotate.eager_load(options)
26
+ options = Annotate.setup_options(
27
+ is_rake: ENV['is_rake'] && !ENV['is_rake'].empty?
28
+ )
29
+ Annotate.eager_load(options) if Annotate::Helpers.include_models?
193
30
 
194
- AnnotateModels.send(target_action, options) if Annotate.include_models?
195
- AnnotateRoutes.send(target_action, options) if Annotate.include_routes?
31
+ AnnotateModels.send(options_result[:target_action], options) if Annotate::Helpers.include_models?
32
+ AnnotateRoutes.send(options_result[:target_action], options) if Annotate::Helpers.include_routes?
data/lib/annotate.rb CHANGED
@@ -1,132 +1,92 @@
1
- $:.unshift(File.dirname(__FILE__))
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  require 'annotate/version'
3
3
  require 'annotate/annotate_models'
4
4
  require 'annotate/annotate_routes'
5
+ require 'annotate/constants'
6
+ require 'annotate/helpers'
5
7
 
6
8
  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'
14
16
  end
15
17
 
16
18
  module Annotate
17
- ##
18
- # The set of available options to customize the behavior of Annotate.
19
- #
20
- POSITION_OPTIONS=[
21
- :position_in_routes, :position_in_class, :position_in_test,
22
- :position_in_fixture, :position_in_factory, :position,
23
- :position_in_serializer
24
- ]
25
- FLAG_OPTIONS=[
26
- :show_indexes, :simple_indexes, :include_version, :exclude_tests,
27
- :exclude_fixtures, :exclude_factories, :ignore_model_sub_dir,
28
- :format_bare, :format_rdoc, :format_markdown, :sort, :force, :trace,
29
- :timestamp, :exclude_serializers, :classified_sort, :show_foreign_keys,
30
- :exclude_scaffolds, :exclude_controllers, :exclude_helpers, :ignore_unknown_models,
31
- ]
32
- OTHER_OPTIONS=[
33
- :ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close, :wrapper, :routes,
34
- :hide_limit_column_types,
35
- ]
36
- PATH_OPTIONS=[
37
- :require, :model_dir, :root_dir
38
- ]
39
-
40
19
  ##
41
20
  # Set default values that can be overridden via environment variables.
42
21
  #
43
22
  def self.set_defaults(options = {})
44
- return if(@has_set_defaults)
23
+ return if @has_set_defaults
45
24
  @has_set_defaults = true
46
25
 
47
- options = HashWithIndifferentAccess.new(options)
26
+ options = ActiveSupport::HashWithIndifferentAccess.new(options)
48
27
 
49
- [POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key|
50
- if options.has_key?(key)
28
+ Constants::ALL_ANNOTATE_OPTIONS.flatten.each do |key|
29
+ if options.key?(key)
51
30
  default_value = if options[key].is_a?(Array)
52
- options[key].join(",")
53
- else
54
- options[key]
55
- end
31
+ options[key].join(',')
32
+ else
33
+ options[key]
34
+ end
56
35
  end
57
36
 
58
- default_value = ENV[key.to_s] if !ENV[key.to_s].blank?
37
+ default_value = ENV[key.to_s] unless ENV[key.to_s].blank?
59
38
  ENV[key.to_s] = default_value.nil? ? nil : default_value.to_s
60
39
  end
61
40
  end
62
41
 
63
- TRUE_RE = /^(true|t|yes|y|1)$/i
42
+ ##
43
+ # TODO: what is the difference between this and set_defaults?
44
+ #
64
45
  def self.setup_options(options = {})
65
- POSITION_OPTIONS.each do |key|
66
- options[key] = fallback(ENV[key.to_s], ENV['position'], 'before')
46
+ Constants::POSITION_OPTIONS.each do |key|
47
+ options[key] = Annotate::Helpers.fallback(ENV[key.to_s], ENV['position'], 'before')
67
48
  end
68
- FLAG_OPTIONS.each do |key|
69
- options[key] = true?(ENV[key.to_s])
49
+ Constants::FLAG_OPTIONS.each do |key|
50
+ options[key] = Annotate::Helpers.true?(ENV[key.to_s])
70
51
  end
71
- OTHER_OPTIONS.each do |key|
72
- options[key] = (!ENV[key.to_s].blank?) ? ENV[key.to_s] : nil
52
+ Constants::OTHER_OPTIONS.each do |key|
53
+ options[key] = !ENV[key.to_s].blank? ? ENV[key.to_s] : nil
73
54
  end
74
- PATH_OPTIONS.each do |key|
75
- options[key] = (!ENV[key.to_s].blank?) ? ENV[key.to_s].split(',') : []
55
+ Constants::PATH_OPTIONS.each do |key|
56
+ options[key] = !ENV[key.to_s].blank? ? ENV[key.to_s].split(',') : []
76
57
  end
77
58
 
78
- if(options[:model_dir].empty?)
79
- options[:model_dir] = ['app/models']
80
- end
81
-
82
- if(options[:root_dir].empty?)
83
- options[:root_dir] = ['']
84
- end
59
+ options[:additional_file_patterns] ||= []
60
+ options[:additional_file_patterns] = options[:additional_file_patterns].split(',') if options[:additional_file_patterns].is_a?(String)
61
+ options[:model_dir] = ['app/models'] if options[:model_dir].empty?
85
62
 
86
63
  options[:wrapper_open] ||= options[:wrapper]
87
64
  options[:wrapper_close] ||= options[:wrapper]
88
65
 
89
- return options
90
- end
91
-
92
- def self.reset_options
93
- [POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key|
94
- ENV[key.to_s] = nil
95
- end
96
- end
97
-
98
- def self.skip_on_migration?
99
- ENV['skip_on_db_migrate'] =~ TRUE_RE
100
- end
101
-
102
- def self.include_routes?
103
- ENV['routes'] =~ TRUE_RE
104
- end
66
+ # These were added in 2.7.0 but so this is to revert to old behavior by default
67
+ options[:exclude_scaffolds] = Annotate::Helpers.true?(ENV.fetch('exclude_scaffolds', 'true'))
68
+ options[:exclude_controllers] = Annotate::Helpers.true?(ENV.fetch('exclude_controllers', 'true'))
69
+ options[:exclude_helpers] = Annotate::Helpers.true?(ENV.fetch('exclude_helpers', 'true'))
105
70
 
106
- def self.include_models?
107
- true
71
+ options
108
72
  end
109
73
 
110
- def self.loaded_tasks=(val); @loaded_tasks = val; end
111
- def self.loaded_tasks; return @loaded_tasks; end
112
-
113
74
  def self.load_tasks
114
- return if(self.loaded_tasks)
115
- self.loaded_tasks = true
75
+ return if @tasks_loaded
116
76
 
117
- Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each { |rake| load rake }
118
- end
77
+ Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each do |rake|
78
+ load rake
79
+ end
119
80
 
120
- def self.load_requires(options)
121
- options[:require].each { |path| require path } if options[:require].count > 0
81
+ @tasks_loaded = true
122
82
  end
123
83
 
124
84
  def self.eager_load(options)
125
- self.load_requires(options)
126
- require "annotate/active_record_patch"
85
+ load_requires(options)
86
+ require 'annotate/active_record_patch'
127
87
 
128
- if(defined?(Rails))
129
- if(Rails.version.split('.').first.to_i < 3)
88
+ if defined?(Rails::Application)
89
+ if Rails.version.split('.').first.to_i < 3
130
90
  Rails.configuration.eager_load_paths.each do |load_path|
131
91
  matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
132
92
  Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
@@ -149,33 +109,37 @@ module Annotate
149
109
  def self.bootstrap_rake
150
110
  begin
151
111
  require 'rake/dsl_definition'
152
- rescue Exception
112
+ rescue StandardError => e
153
113
  # We might just be on an old version of Rake...
114
+ $stderr.puts e.message
115
+ exit e.status_code
154
116
  end
155
117
  require 'rake'
156
118
 
157
- if File.exists?('./Rakefile')
158
- load './Rakefile'
119
+ load './Rakefile' if File.exist?('./Rakefile')
120
+ begin
121
+ Rake::Task[:environment].invoke
122
+ rescue
123
+ nil
159
124
  end
160
- Rake::Task[:environment].invoke rescue nil
161
- if(!defined?(Rails))
125
+ unless defined?(Rails)
162
126
  # Not in a Rails project, so time to load up the parts of
163
127
  # ActiveSupport we need.
164
128
  require 'active_support'
165
129
  require 'active_support/core_ext/class/subclasses'
166
130
  require 'active_support/core_ext/string/inflections'
167
131
  end
168
- self.load_tasks
132
+
133
+ load_tasks
169
134
  Rake::Task[:set_annotation_options].invoke
170
135
  end
171
136
 
172
- def self.fallback(*args)
173
- return args.detect { |arg| !arg.blank? }
174
- end
137
+ class << self
138
+ private
175
139
 
176
- def self.true?(val)
177
- return false if(val.blank?)
178
- return false unless(val =~ TRUE_RE)
179
- return true
140
+ def load_requires(options)
141
+ options[:require].count > 0 &&
142
+ options[:require].each { |path| require path }
143
+ end
180
144
  end
181
145
  end