annotate 3.1.1 → 3.2.0

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
  SHA256:
3
- metadata.gz: 14932a4a189792b68c9d85c63313d0d60322ca22fed18a7a4a00edd47348743a
4
- data.tar.gz: 351b61b7b3eac94f1ce6d8a86e1630bbbf6c0920cacfe46319163a86bc189887
3
+ metadata.gz: a49c914d3c2486e109b4a499b71fe905c8534e21b1d44cee15056a3066468e2e
4
+ data.tar.gz: 383445b9f5c13d02da7190a009ed974b5f88b41fe88f156814e743b4f7ec99d2
5
5
  SHA512:
6
- metadata.gz: a717f48aff793ea4566fca6919eb4fe85b1545fe93b0bece91c5a9507cbb87fe14aa35ac520e618e98f8db92fe11010a8fe8653802b25b83b24590467e5d64f1
7
- data.tar.gz: d13aab072e5e3901788f4aff809e08f3d28ac24cf0eed4187b0e5c0f98008f3c95a7553b58c4f50705f2f42729e96a05a57631356715953bb7d29531e4365fbd
6
+ metadata.gz: 70b926aba8e1ba91ccf506cfdabb94016efaaf788beaf6bdc0691fb6ad30edf57b794842f93f9860e1f82fa38c2934530e6fc0940f88ce4b47a909da8456ddd0
7
+ data.tar.gz: bf94c7d38b3a11ddc658947a7c1f2164854070a5707f56c148bcbdd5495b88c270ee0f0e587b07c0c421724b40059f110c808a8f3af90e68a86c5e249dfb1fa1
data/README.md CHANGED
@@ -104,8 +104,8 @@ Into environment gems from Github checkout:
104
104
 
105
105
  git clone https://github.com/ctran/annotate_models.git annotate_models
106
106
  cd annotate_models
107
- rake build
108
- gem install pkg/annotate-*.gem
107
+ rake gem
108
+ gem install dist/annotate-*.gem
109
109
 
110
110
  ## Usage
111
111
 
data/annotate.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.executables = ['annotate']
16
16
  s.extra_rdoc_files = ['README.md', 'CHANGELOG.md']
17
17
  s.files = `git ls-files -z LICENSE.txt *.md *.gemspec bin lib`.split("\x0")
18
- s.homepage = 'http://github.com/ctran/annotate_models'
18
+ s.homepage = 'https://github.com/ctran/annotate_models'
19
19
  s.licenses = ['Ruby']
20
20
  s.require_paths = ['lib']
21
21
  s.rubygems_version = '2.1.11'
@@ -23,7 +23,10 @@ Gem::Specification.new do |s|
23
23
 
24
24
  s.specification_version = 4 if s.respond_to? :specification_version
25
25
  s.add_runtime_dependency(%q<rake>, '>= 10.4', '< 14.0')
26
- s.add_runtime_dependency(%q<activerecord>, ['>= 3.2', '< 7.0'])
26
+ s.add_runtime_dependency(%q<activerecord>, ['>= 3.2', '< 8.0'])
27
27
 
28
- s.metadata = { "github_repo" => "ssh://github.com/ctran/annotate_models" }
28
+ s.metadata = {
29
+ "bug_tracker_uri" => "https://github.com/ctran/annotate_models/issues/",
30
+ "source_code_uri" => "https://github.com/ctran/annotate_models.git"
31
+ }
29
32
  end
@@ -0,0 +1,127 @@
1
+ module AnnotateModels
2
+ # This module provides module method to get file paths.
3
+ module FilePatterns
4
+ # Controller files
5
+ CONTROLLER_DIR = File.join('app', 'controllers')
6
+
7
+ # Active admin registry files
8
+ ACTIVEADMIN_DIR = File.join('app', 'admin')
9
+
10
+ # Helper files
11
+ HELPER_DIR = File.join('app', 'helpers')
12
+
13
+ # File.join for windows reverse bar compat?
14
+ # I dont use windows, can`t test
15
+ UNIT_TEST_DIR = File.join('test', 'unit')
16
+ MODEL_TEST_DIR = File.join('test', 'models') # since rails 4.0
17
+ SPEC_MODEL_DIR = File.join('spec', 'models')
18
+
19
+ FIXTURE_TEST_DIR = File.join('test', 'fixtures')
20
+ FIXTURE_SPEC_DIR = File.join('spec', 'fixtures')
21
+
22
+ # Other test files
23
+ CONTROLLER_TEST_DIR = File.join('test', 'controllers')
24
+ CONTROLLER_SPEC_DIR = File.join('spec', 'controllers')
25
+ REQUEST_SPEC_DIR = File.join('spec', 'requests')
26
+ ROUTING_SPEC_DIR = File.join('spec', 'routing')
27
+
28
+ # Object Daddy http://github.com/flogic/object_daddy/tree/master
29
+ EXEMPLARS_TEST_DIR = File.join('test', 'exemplars')
30
+ EXEMPLARS_SPEC_DIR = File.join('spec', 'exemplars')
31
+
32
+ # Machinist http://github.com/notahat/machinist
33
+ BLUEPRINTS_TEST_DIR = File.join('test', 'blueprints')
34
+ BLUEPRINTS_SPEC_DIR = File.join('spec', 'blueprints')
35
+
36
+ # Factory Bot https://github.com/thoughtbot/factory_bot
37
+ FACTORY_BOT_TEST_DIR = File.join('test', 'factories')
38
+ FACTORY_BOT_SPEC_DIR = File.join('spec', 'factories')
39
+
40
+ # Fabrication https://github.com/paulelliott/fabrication.git
41
+ FABRICATORS_TEST_DIR = File.join('test', 'fabricators')
42
+ FABRICATORS_SPEC_DIR = File.join('spec', 'fabricators')
43
+
44
+ # Serializers https://github.com/rails-api/active_model_serializers
45
+ SERIALIZERS_DIR = File.join('app', 'serializers')
46
+ SERIALIZERS_TEST_DIR = File.join('test', 'serializers')
47
+ SERIALIZERS_SPEC_DIR = File.join('spec', 'serializers')
48
+
49
+ class << self
50
+ def generate(root_directory, pattern_type, options)
51
+ case pattern_type
52
+ when 'test' then test_files(root_directory)
53
+ when 'fixture' then fixture_files(root_directory)
54
+ when 'scaffold' then scaffold_files(root_directory)
55
+ when 'factory' then factory_files(root_directory)
56
+ when 'serializer' then serialize_files(root_directory)
57
+ when 'additional_file_patterns'
58
+ [options[:additional_file_patterns] || []].flatten
59
+ when 'controller'
60
+ [File.join(root_directory, CONTROLLER_DIR, '%PLURALIZED_MODEL_NAME%_controller.rb')]
61
+ when 'admin'
62
+ [
63
+ File.join(root_directory, ACTIVEADMIN_DIR, '%MODEL_NAME%.rb'),
64
+ File.join(root_directory, ACTIVEADMIN_DIR, '%PLURALIZED_MODEL_NAME%.rb')
65
+ ]
66
+ when 'helper'
67
+ [File.join(root_directory, HELPER_DIR, '%PLURALIZED_MODEL_NAME%_helper.rb')]
68
+ else
69
+ []
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def test_files(root_directory)
76
+ [
77
+ File.join(root_directory, UNIT_TEST_DIR, '%MODEL_NAME%_test.rb'),
78
+ File.join(root_directory, MODEL_TEST_DIR, '%MODEL_NAME%_test.rb'),
79
+ File.join(root_directory, SPEC_MODEL_DIR, '%MODEL_NAME%_spec.rb')
80
+ ]
81
+ end
82
+
83
+ def fixture_files(root_directory)
84
+ [
85
+ File.join(root_directory, FIXTURE_TEST_DIR, '%TABLE_NAME%.yml'),
86
+ File.join(root_directory, FIXTURE_SPEC_DIR, '%TABLE_NAME%.yml'),
87
+ File.join(root_directory, FIXTURE_TEST_DIR, '%PLURALIZED_MODEL_NAME%.yml'),
88
+ File.join(root_directory, FIXTURE_SPEC_DIR, '%PLURALIZED_MODEL_NAME%.yml')
89
+ ]
90
+ end
91
+
92
+ def scaffold_files(root_directory)
93
+ [
94
+ File.join(root_directory, CONTROLLER_TEST_DIR, '%PLURALIZED_MODEL_NAME%_controller_test.rb'),
95
+ File.join(root_directory, CONTROLLER_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_controller_spec.rb'),
96
+ File.join(root_directory, REQUEST_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_spec.rb'),
97
+ File.join(root_directory, ROUTING_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_routing_spec.rb')
98
+ ]
99
+ end
100
+
101
+ def factory_files(root_directory)
102
+ [
103
+ File.join(root_directory, EXEMPLARS_TEST_DIR, '%MODEL_NAME%_exemplar.rb'),
104
+ File.join(root_directory, EXEMPLARS_SPEC_DIR, '%MODEL_NAME%_exemplar.rb'),
105
+ File.join(root_directory, BLUEPRINTS_TEST_DIR, '%MODEL_NAME%_blueprint.rb'),
106
+ File.join(root_directory, BLUEPRINTS_SPEC_DIR, '%MODEL_NAME%_blueprint.rb'),
107
+ File.join(root_directory, FACTORY_BOT_TEST_DIR, '%MODEL_NAME%_factory.rb'), # (old style)
108
+ File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%MODEL_NAME%_factory.rb'), # (old style)
109
+ File.join(root_directory, FACTORY_BOT_TEST_DIR, '%TABLE_NAME%.rb'), # (new style)
110
+ File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%TABLE_NAME%.rb'), # (new style)
111
+ File.join(root_directory, FACTORY_BOT_TEST_DIR, '%PLURALIZED_MODEL_NAME%.rb'), # (new style)
112
+ File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%PLURALIZED_MODEL_NAME%.rb'), # (new style)
113
+ File.join(root_directory, FABRICATORS_TEST_DIR, '%MODEL_NAME%_fabricator.rb'),
114
+ File.join(root_directory, FABRICATORS_SPEC_DIR, '%MODEL_NAME%_fabricator.rb')
115
+ ]
116
+ end
117
+
118
+ def serialize_files(root_directory)
119
+ [
120
+ File.join(root_directory, SERIALIZERS_DIR, '%MODEL_NAME%_serializer.rb'),
121
+ File.join(root_directory, SERIALIZERS_TEST_DIR, '%MODEL_NAME%_serializer_test.rb'),
122
+ File.join(root_directory, SERIALIZERS_SPEC_DIR, '%MODEL_NAME%_serializer_spec.rb')
123
+ ]
124
+ end
125
+ end
126
+ end
127
+ end
@@ -3,6 +3,7 @@
3
3
  require 'bigdecimal'
4
4
 
5
5
  require 'annotate/constants'
6
+ require_relative 'annotate_models/file_patterns'
6
7
 
7
8
  module AnnotateModels
8
9
  # Annotate Models plugin use this header
@@ -16,50 +17,6 @@ module AnnotateModels
16
17
 
17
18
  MATCHED_TYPES = %w(test fixture factory serializer scaffold controller helper).freeze
18
19
 
19
- # File.join for windows reverse bar compat?
20
- # I dont use windows, can`t test
21
- UNIT_TEST_DIR = File.join('test', "unit")
22
- MODEL_TEST_DIR = File.join('test', "models") # since rails 4.0
23
- SPEC_MODEL_DIR = File.join('spec', "models")
24
- FIXTURE_TEST_DIR = File.join('test', "fixtures")
25
- FIXTURE_SPEC_DIR = File.join('spec', "fixtures")
26
-
27
- # Other test files
28
- CONTROLLER_TEST_DIR = File.join('test', "controllers")
29
- CONTROLLER_SPEC_DIR = File.join('spec', "controllers")
30
- REQUEST_SPEC_DIR = File.join('spec', "requests")
31
- ROUTING_SPEC_DIR = File.join('spec', "routing")
32
-
33
- # Object Daddy http://github.com/flogic/object_daddy/tree/master
34
- EXEMPLARS_TEST_DIR = File.join('test', "exemplars")
35
- EXEMPLARS_SPEC_DIR = File.join('spec', "exemplars")
36
-
37
- # Machinist http://github.com/notahat/machinist
38
- BLUEPRINTS_TEST_DIR = File.join('test', "blueprints")
39
- BLUEPRINTS_SPEC_DIR = File.join('spec', "blueprints")
40
-
41
- # Factory Bot https://github.com/thoughtbot/factory_bot
42
- FACTORY_BOT_TEST_DIR = File.join('test', "factories")
43
- FACTORY_BOT_SPEC_DIR = File.join('spec', "factories")
44
-
45
- # Fabrication https://github.com/paulelliott/fabrication.git
46
- FABRICATORS_TEST_DIR = File.join('test', "fabricators")
47
- FABRICATORS_SPEC_DIR = File.join('spec', "fabricators")
48
-
49
- # Serializers https://github.com/rails-api/active_model_serializers
50
- SERIALIZERS_DIR = File.join('app', "serializers")
51
- SERIALIZERS_TEST_DIR = File.join('test', "serializers")
52
- SERIALIZERS_SPEC_DIR = File.join('spec', "serializers")
53
-
54
- # Controller files
55
- CONTROLLER_DIR = File.join('app', "controllers")
56
-
57
- # Active admin registry files
58
- ACTIVEADMIN_DIR = File.join('app', "admin")
59
-
60
- # Helper files
61
- HELPER_DIR = File.join('app', "helpers")
62
-
63
20
  # Don't show limit (#) on these column types
64
21
  # Example: show "integer" instead of "integer(4)"
65
22
  NO_LIMIT_COL_TYPES = %w(integer bigint boolean).freeze
@@ -110,82 +67,24 @@ module AnnotateModels
110
67
 
111
68
  attr_writer :root_dir
112
69
 
113
- def test_files(root_directory)
114
- [
115
- File.join(root_directory, UNIT_TEST_DIR, "%MODEL_NAME%_test.rb"),
116
- File.join(root_directory, MODEL_TEST_DIR, "%MODEL_NAME%_test.rb"),
117
- File.join(root_directory, SPEC_MODEL_DIR, "%MODEL_NAME%_spec.rb")
118
- ]
119
- end
120
-
121
- def fixture_files(root_directory)
122
- [
123
- File.join(root_directory, FIXTURE_TEST_DIR, "%TABLE_NAME%.yml"),
124
- File.join(root_directory, FIXTURE_SPEC_DIR, "%TABLE_NAME%.yml"),
125
- File.join(root_directory, FIXTURE_TEST_DIR, "%PLURALIZED_MODEL_NAME%.yml"),
126
- File.join(root_directory, FIXTURE_SPEC_DIR, "%PLURALIZED_MODEL_NAME%.yml")
127
- ]
128
- end
129
-
130
- def scaffold_files(root_directory)
131
- [
132
- File.join(root_directory, CONTROLLER_TEST_DIR, "%PLURALIZED_MODEL_NAME%_controller_test.rb"),
133
- File.join(root_directory, CONTROLLER_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_controller_spec.rb"),
134
- File.join(root_directory, REQUEST_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_spec.rb"),
135
- File.join(root_directory, ROUTING_SPEC_DIR, "%PLURALIZED_MODEL_NAME%_routing_spec.rb")
136
- ]
137
- end
138
-
139
- def factory_files(root_directory)
140
- [
141
- File.join(root_directory, EXEMPLARS_TEST_DIR, "%MODEL_NAME%_exemplar.rb"),
142
- File.join(root_directory, EXEMPLARS_SPEC_DIR, "%MODEL_NAME%_exemplar.rb"),
143
- File.join(root_directory, BLUEPRINTS_TEST_DIR, "%MODEL_NAME%_blueprint.rb"),
144
- File.join(root_directory, BLUEPRINTS_SPEC_DIR, "%MODEL_NAME%_blueprint.rb"),
145
- File.join(root_directory, FACTORY_BOT_TEST_DIR, "%MODEL_NAME%_factory.rb"), # (old style)
146
- File.join(root_directory, FACTORY_BOT_SPEC_DIR, "%MODEL_NAME%_factory.rb"), # (old style)
147
- File.join(root_directory, FACTORY_BOT_TEST_DIR, "%TABLE_NAME%.rb"), # (new style)
148
- File.join(root_directory, FACTORY_BOT_SPEC_DIR, "%TABLE_NAME%.rb"), # (new style)
149
- File.join(root_directory, FACTORY_BOT_TEST_DIR, "%PLURALIZED_MODEL_NAME%.rb"), # (new style)
150
- File.join(root_directory, FACTORY_BOT_SPEC_DIR, "%PLURALIZED_MODEL_NAME%.rb"), # (new style)
151
- File.join(root_directory, FABRICATORS_TEST_DIR, "%MODEL_NAME%_fabricator.rb"),
152
- File.join(root_directory, FABRICATORS_SPEC_DIR, "%MODEL_NAME%_fabricator.rb")
153
- ]
154
- end
155
-
156
- def serialize_files(root_directory)
157
- [
158
- File.join(root_directory, SERIALIZERS_DIR, "%MODEL_NAME%_serializer.rb"),
159
- File.join(root_directory, SERIALIZERS_TEST_DIR, "%MODEL_NAME%_serializer_test.rb"),
160
- File.join(root_directory, SERIALIZERS_SPEC_DIR, "%MODEL_NAME%_serializer_spec.rb")
161
- ]
162
- end
70
+ def skip_subdirectory_model_load
71
+ # This option is set in options[:skip_subdirectory_model_load]
72
+ # and stops the get_loaded_model method from loading a model from a subdir
163
73
 
164
- def files_by_pattern(root_directory, pattern_type, options)
165
- case pattern_type
166
- when 'test' then test_files(root_directory)
167
- when 'fixture' then fixture_files(root_directory)
168
- when 'scaffold' then scaffold_files(root_directory)
169
- when 'factory' then factory_files(root_directory)
170
- when 'serializer' then serialize_files(root_directory)
171
- when 'additional_file_patterns'
172
- [options[:additional_file_patterns] || []].flatten
173
- when 'controller'
174
- [File.join(root_directory, CONTROLLER_DIR, "%PLURALIZED_MODEL_NAME%_controller.rb")]
175
- when 'admin'
176
- [File.join(root_directory, ACTIVEADMIN_DIR, "%MODEL_NAME%.rb")]
177
- when 'helper'
178
- [File.join(root_directory, HELPER_DIR, "%PLURALIZED_MODEL_NAME%_helper.rb")]
74
+ if @skip_subdirectory_model_load.blank?
75
+ false
179
76
  else
180
- []
77
+ @skip_subdirectory_model_load
181
78
  end
182
79
  end
183
80
 
81
+ attr_writer :skip_subdirectory_model_load
82
+
184
83
  def get_patterns(options, pattern_types = [])
185
84
  current_patterns = []
186
85
  root_dir.each do |root_directory|
187
86
  Array(pattern_types).each do |pattern_type|
188
- patterns = files_by_pattern(root_directory, pattern_type, options)
87
+ patterns = FilePatterns.generate(root_directory, pattern_type, options)
189
88
 
190
89
  current_patterns += if pattern_type.to_sym == :additional_file_patterns
191
90
  patterns
@@ -249,52 +148,13 @@ module AnnotateModels
249
148
  cols = columns(klass, options)
250
149
  cols.each do |col|
251
150
  col_type = get_col_type(col)
252
- attrs = []
253
- attrs << "default(#{schema_default(klass, col)})" unless col.default.nil? || hide_default?(col_type, options)
254
- attrs << 'unsigned' if col.respond_to?(:unsigned?) && col.unsigned?
255
- attrs << 'not null' unless col.null
256
- 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)
257
-
258
- if col_type == 'decimal'
259
- col_type << "(#{col.precision}, #{col.scale})"
260
- elsif !%w[spatial geometry geography].include?(col_type)
261
- if col.limit && !options[:format_yard]
262
- if col.limit.is_a? Array
263
- attrs << "(#{col.limit.join(', ')})"
264
- else
265
- col_type << "(#{col.limit})" unless hide_limit?(col_type, options)
266
- end
267
- end
268
- end
269
-
270
- # Check out if we got an array column
271
- attrs << 'is an Array' if col.respond_to?(:array) && col.array
272
-
273
- # Check out if we got a geometric column
274
- # and print the type and SRID
275
- if col.respond_to?(:geometry_type)
276
- attrs << "#{col.geometry_type}, #{col.srid}"
277
- elsif col.respond_to?(:geometric_type) && col.geometric_type.present?
278
- attrs << "#{col.geometric_type.to_s.downcase}, #{col.srid}"
279
- end
280
-
281
- # Check if the column has indices and print "indexed" if true
282
- # If the index includes another column, print it too.
283
- if options[:simple_indexes] && klass.table_exists?# Check out if this column is indexed
284
- indices = retrieve_indexes_from_table(klass)
285
- if indices = indices.select { |ind| ind.columns.include? col.name }
286
- indices.sort_by(&:name).each do |ind|
287
- next if ind.columns.is_a?(String)
288
- ind = ind.columns.reject! { |i| i == col.name }
289
- attrs << (ind.empty? ? "indexed" : "indexed => [#{ind.join(", ")}]")
290
- end
291
- end
292
- end
151
+ attrs = get_attributes(col, col_type, klass, options)
293
152
  col_name = if with_comments?(klass, options) && col.comment
294
- "#{col.name}(#{col.comment})"
153
+ "#{col.name}(#{col.comment.gsub(/\n/, "\\n")})"
295
154
  else
296
155
  col.name
297
156
  end
157
+
298
158
  if options[:format_rdoc]
299
159
  info << sprintf("# %-#{max_size}.#{max_size}s<tt>%s</tt>", "*#{col_name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n"
300
160
  elsif options[:format_yard]
@@ -739,14 +599,17 @@ module AnnotateModels
739
599
 
740
600
  # Retrieve loaded model class
741
601
  def get_loaded_model(model_path, file)
742
- loaded_model_class = get_loaded_model_by_path(model_path)
743
- return loaded_model_class if loaded_model_class
602
+ unless skip_subdirectory_model_load
603
+ loaded_model_class = get_loaded_model_by_path(model_path)
604
+ return loaded_model_class if loaded_model_class
605
+ end
744
606
 
745
607
  # We cannot get loaded model when `model_path` is loaded by Rails
746
608
  # auto_load/eager_load paths. Try all possible model paths one by one.
747
609
  absolute_file = File.expand_path(file)
748
610
  model_paths =
749
- $LOAD_PATH.select { |path| absolute_file.include?(path) }
611
+ $LOAD_PATH.map(&:to_s)
612
+ .select { |path| absolute_file.include?(path) }
750
613
  .map { |path| absolute_file.sub(path, '').sub(/\.rb$/, '').sub(/^\//, '') }
751
614
  model_paths
752
615
  .map { |path| get_loaded_model_by_path(path) }
@@ -769,6 +632,7 @@ module AnnotateModels
769
632
  def parse_options(options = {})
770
633
  self.model_dir = split_model_dir(options[:model_dir]) if options[:model_dir]
771
634
  self.root_dir = options[:root_dir] if options[:root_dir]
635
+ self.skip_subdirectory_model_load = options[:skip_subdirectory_model_load].present?
772
636
  end
773
637
 
774
638
  def split_model_dir(option_value)
@@ -809,7 +673,7 @@ module AnnotateModels
809
673
  begin
810
674
  return false if /#{SKIP_ANNOTATION_PREFIX}.*/ =~ (File.exist?(file) ? File.read(file) : '')
811
675
  klass = get_model_class(file)
812
- do_annotate = klass &&
676
+ do_annotate = klass.is_a?(Class) &&
813
677
  klass < ActiveRecord::Base &&
814
678
  (!options[:exclude_sti_subclasses] || !(klass.superclass < ActiveRecord::Base && klass.table_name == klass.superclass.table_name)) &&
815
679
  !klass.abstract_class? &&
@@ -982,9 +846,7 @@ module AnnotateModels
982
846
  # Construct the foreign column name in the translations table
983
847
  # eg. Model: Car, foreign column name: car_id
984
848
  foreign_column_name = [
985
- klass.translation_class.to_s
986
- .gsub('::Translation', '').gsub('::', '_')
987
- .downcase,
849
+ klass.table_name.to_s.singularize,
988
850
  '_id'
989
851
  ].join.to_sym
990
852
 
@@ -996,6 +858,55 @@ module AnnotateModels
996
858
  foreign_column_name
997
859
  ]
998
860
  end
861
+
862
+ ##
863
+ # Get the list of attributes that should be included in the annotation for
864
+ # a given column.
865
+ def get_attributes(column, column_type, klass, options)
866
+ attrs = []
867
+ attrs << "default(#{schema_default(klass, column)})" unless column.default.nil? || hide_default?(column_type, options)
868
+ attrs << 'unsigned' if column.respond_to?(:unsigned?) && column.unsigned?
869
+ attrs << 'not null' unless column.null
870
+ attrs << 'primary key' if klass.primary_key && (klass.primary_key.is_a?(Array) ? klass.primary_key.collect(&:to_sym).include?(column.name.to_sym) : column.name.to_sym == klass.primary_key.to_sym)
871
+
872
+ if column_type == 'decimal'
873
+ column_type << "(#{column.precision}, #{column.scale})"
874
+ elsif !%w[spatial geometry geography].include?(column_type)
875
+ if column.limit && !options[:format_yard]
876
+ if column.limit.is_a? Array
877
+ attrs << "(#{column.limit.join(', ')})"
878
+ else
879
+ column_type << "(#{column.limit})" unless hide_limit?(column_type, options)
880
+ end
881
+ end
882
+ end
883
+
884
+ # Check out if we got an array column
885
+ attrs << 'is an Array' if column.respond_to?(:array) && column.array
886
+
887
+ # Check out if we got a geometric column
888
+ # and print the type and SRID
889
+ if column.respond_to?(:geometry_type)
890
+ attrs << [column.geometry_type, column.try(:srid)].compact.join(', ')
891
+ elsif column.respond_to?(:geometric_type) && column.geometric_type.present?
892
+ attrs << [column.geometric_type.to_s.downcase, column.try(:srid)].compact.join(', ')
893
+ end
894
+
895
+ # Check if the column has indices and print "indexed" if true
896
+ # If the index includes another column, print it too.
897
+ if options[:simple_indexes] && klass.table_exists?# Check out if this column is indexed
898
+ indices = retrieve_indexes_from_table(klass)
899
+ if indices = indices.select { |ind| ind.columns.include? column.name }
900
+ indices.sort_by(&:name).each do |ind|
901
+ next if ind.columns.is_a?(String)
902
+ ind = ind.columns.reject! { |i| i == column.name }
903
+ attrs << (ind.empty? ? "indexed" : "indexed => [#{ind.join(", ")}]")
904
+ end
905
+ end
906
+ end
907
+
908
+ attrs
909
+ end
999
910
  end
1000
911
 
1001
912
  class BadModelFileError < LoadError
@@ -0,0 +1,113 @@
1
+ require_relative './helpers'
2
+
3
+ module AnnotateRoutes
4
+ class HeaderGenerator
5
+ PREFIX = '== Route Map'.freeze
6
+ PREFIX_MD = '## Route Map'.freeze
7
+ HEADER_ROW = ['Prefix', 'Verb', 'URI Pattern', 'Controller#Action'].freeze
8
+
9
+ class << self
10
+ def generate(options = {})
11
+ new(options, routes_map(options)).generate
12
+ end
13
+
14
+ private :new
15
+
16
+ private
17
+
18
+ def routes_map(options)
19
+ result = `rake routes`.chomp("\n").split(/\n/, -1)
20
+
21
+ # In old versions of Rake, the first line of output was the cwd. Not so
22
+ # much in newer ones. We ditch that line if it exists, and if not, we
23
+ # keep the line around.
24
+ result.shift if result.first =~ %r{^\(in \/}
25
+
26
+ ignore_routes = options[:ignore_routes]
27
+ regexp_for_ignoring_routes = ignore_routes ? /#{ignore_routes}/ : nil
28
+
29
+ # Skip routes which match given regex
30
+ # Note: it matches the complete line (route_name, path, controller/action)
31
+ if regexp_for_ignoring_routes
32
+ result.reject { |line| line =~ regexp_for_ignoring_routes }
33
+ else
34
+ result
35
+ end
36
+ end
37
+ end
38
+
39
+ def initialize(options, routes_map)
40
+ @options = options
41
+ @routes_map = routes_map
42
+ end
43
+
44
+ def generate
45
+ magic_comments_map, contents_without_magic_comments = Helpers.extract_magic_comments_from_array(routes_map)
46
+
47
+ out = []
48
+
49
+ magic_comments_map.each do |magic_comment|
50
+ out << magic_comment
51
+ end
52
+ out << '' if magic_comments_map.any?
53
+
54
+ out << comment(options[:wrapper_open]) if options[:wrapper_open]
55
+
56
+ out << comment(markdown? ? PREFIX_MD : PREFIX) + timestamp_if_required
57
+ out << comment
58
+ return out if contents_without_magic_comments.size.zero?
59
+
60
+ maxs = [HEADER_ROW.map(&:size)] + contents_without_magic_comments[1..-1].map { |line| line.split.map(&:size) }
61
+
62
+ if markdown?
63
+ max = maxs.map(&:max).compact.max
64
+
65
+ out << comment(content(HEADER_ROW, maxs))
66
+ out << comment(content(['-' * max, '-' * max, '-' * max, '-' * max], maxs))
67
+ else
68
+ out << comment(content(contents_without_magic_comments[0], maxs))
69
+ end
70
+
71
+ out += contents_without_magic_comments[1..-1].map { |line| comment(content(markdown? ? line.split(' ') : line, maxs)) }
72
+ out << comment(options[:wrapper_close]) if options[:wrapper_close]
73
+
74
+ out
75
+ end
76
+
77
+ private
78
+
79
+ attr_reader :options, :routes_map
80
+
81
+ def comment(row = '')
82
+ if row == ''
83
+ '#'
84
+ else
85
+ "# #{row}"
86
+ end
87
+ end
88
+
89
+ def content(line, maxs)
90
+ return line.rstrip unless markdown?
91
+
92
+ line.each_with_index.map { |elem, index| format_line_element(elem, maxs, index) }.join(' | ')
93
+ end
94
+
95
+ def format_line_element(elem, maxs, index)
96
+ min_length = maxs.map { |arr| arr[index] }.max || 0
97
+ format("%-#{min_length}.#{min_length}s", elem.tr('|', '-'))
98
+ end
99
+
100
+ def markdown?
101
+ options[:format_markdown]
102
+ end
103
+
104
+ def timestamp_if_required(time = Time.now)
105
+ if options[:timestamp]
106
+ time_formatted = time.strftime('%Y-%m-%d %H:%M')
107
+ " (Updated #{time_formatted})"
108
+ else
109
+ ''
110
+ end
111
+ end
112
+ end
113
+ end
@@ -1,5 +1,3 @@
1
- # rubocop:disable Metrics/ModuleLength
2
-
3
1
  # == Annotate Routes
4
2
  #
5
3
  # Based on:
@@ -21,18 +19,15 @@
21
19
  #
22
20
 
23
21
  require_relative './annotate_routes/helpers'
22
+ require_relative './annotate_routes/header_generator'
24
23
 
25
24
  module AnnotateRoutes
26
- PREFIX = '== Route Map'.freeze
27
- PREFIX_MD = '## Route Map'.freeze
28
- HEADER_ROW = ['Prefix', 'Verb', 'URI Pattern', 'Controller#Action'].freeze
29
-
30
25
  class << self
31
26
  def do_annotations(options = {})
32
27
  if routes_file_exist?
33
28
  existing_text = File.read(routes_file)
34
29
  content, header_position = Helpers.strip_annotations(existing_text)
35
- new_content = annotate_routes(header(options), content, header_position, options)
30
+ new_content = annotate_routes(HeaderGenerator.generate(options), content, header_position, options)
36
31
  new_text = new_content.join("\n")
37
32
 
38
33
  if rewrite_contents(existing_text, new_text)
@@ -71,49 +66,6 @@ module AnnotateRoutes
71
66
  @routes_rb ||= File.join('config', 'routes.rb')
72
67
  end
73
68
 
74
- def header(options = {})
75
- routes_map = app_routes_map(options)
76
-
77
- magic_comments_map, routes_map = Helpers.extract_magic_comments_from_array(routes_map)
78
-
79
- out = []
80
-
81
- magic_comments_map.each do |magic_comment|
82
- out << magic_comment
83
- end
84
- out << '' if magic_comments_map.any?
85
-
86
- out << comment(options[:wrapper_open]) if options[:wrapper_open]
87
-
88
- out << comment(options[:format_markdown] ? PREFIX_MD : PREFIX) + (options[:timestamp] ? " (Updated #{Time.now.strftime('%Y-%m-%d %H:%M')})" : '')
89
- out << comment
90
- return out if routes_map.size.zero?
91
-
92
- maxs = [HEADER_ROW.map(&:size)] + routes_map[1..-1].map { |line| line.split.map(&:size) }
93
-
94
- if options[:format_markdown]
95
- max = maxs.map(&:max).compact.max
96
-
97
- out << comment(content(HEADER_ROW, maxs, options))
98
- out << comment(content(['-' * max, '-' * max, '-' * max, '-' * max], maxs, options))
99
- else
100
- out << comment(content(routes_map[0], maxs, options))
101
- end
102
-
103
- out += routes_map[1..-1].map { |line| comment(content(options[:format_markdown] ? line.split(' ') : line, maxs, options)) }
104
- out << comment(options[:wrapper_close]) if options[:wrapper_close]
105
-
106
- out
107
- end
108
-
109
- def comment(row = '')
110
- if row == ''
111
- '#'
112
- else
113
- "# #{row}"
114
- end
115
- end
116
-
117
69
  def strip_on_removal(content, header_position)
118
70
  if header_position == :before
119
71
  content.shift while content.first == ''
@@ -162,32 +114,5 @@ module AnnotateRoutes
162
114
 
163
115
  new_content
164
116
  end
165
-
166
- def app_routes_map(options)
167
- routes_map = `rake routes`.chomp("\n").split(/\n/, -1)
168
-
169
- # In old versions of Rake, the first line of output was the cwd. Not so
170
- # much in newer ones. We ditch that line if it exists, and if not, we
171
- # keep the line around.
172
- routes_map.shift if routes_map.first =~ /^\(in \//
173
-
174
- # Skip routes which match given regex
175
- # Note: it matches the complete line (route_name, path, controller/action)
176
- if options[:ignore_routes]
177
- routes_map.reject! { |line| line =~ /#{options[:ignore_routes]}/ }
178
- end
179
-
180
- routes_map
181
- end
182
-
183
- def content(line, maxs, options = {})
184
- return line.rstrip unless options[:format_markdown]
185
-
186
- line.each_with_index.map do |elem, index|
187
- min_length = maxs.map { |arr| arr[index] }.max || 0
188
-
189
- sprintf("%-#{min_length}.#{min_length}s", elem.tr('|', '-'))
190
- end.join(' | ')
191
- end
192
117
  end
193
118
  end
@@ -1,5 +1,5 @@
1
1
  module Annotate
2
2
  def self.version
3
- '3.1.1'
3
+ '3.2.0'
4
4
  end
5
5
  end
@@ -4,7 +4,20 @@
4
4
  # Append annotations to Rake tasks for ActiveRecord, so annotate automatically gets
5
5
  # run after doing db:migrate.
6
6
 
7
- %w(db:migrate db:migrate:up db:migrate:down db:migrate:reset db:migrate:redo db:rollback).each do |task|
7
+ migration_tasks = %w(db:migrate db:migrate:up db:migrate:down db:migrate:reset db:migrate:redo db:rollback)
8
+ if defined?(Rails::Application) && Rails.version.split('.').first.to_i >= 6
9
+ require 'active_record'
10
+
11
+ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
12
+
13
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
14
+ migration_tasks.concat(%w(db:migrate db:migrate:up db:migrate:down).map { |task| "#{task}:#{spec_name}" })
15
+ end
16
+ end
17
+
18
+ migration_tasks.each do |task|
19
+ next unless Rake::Task.task_defined?(task)
20
+
8
21
  Rake::Task[task].enhance do
9
22
  Rake::Task[Rake.application.top_level_tasks.last].enhance do
10
23
  annotation_options_task = if Rake::Task.task_defined?('app:set_annotation_options')
@@ -1,6 +1,12 @@
1
+ annotate_lib = File.expand_path(File.dirname(File.dirname(__FILE__)))
2
+
3
+ unless ENV['is_cli']
4
+ task :set_annotation_options
5
+ task annotate_routes: :set_annotation_options
6
+ end
7
+
1
8
  desc "Adds the route map to routes.rb"
2
9
  task :annotate_routes => :environment do
3
- annotate_lib = File.expand_path(File.dirname(File.dirname(__FILE__)))
4
10
  require "#{annotate_lib}/annotate/annotate_routes"
5
11
 
6
12
  options={}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: annotate
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Chaffee
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2020-03-24 00:00:00.000000000 Z
15
+ date: 2022-02-10 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rake
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '3.2'
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: '7.0'
46
+ version: '8.0'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
@@ -53,7 +53,7 @@ dependencies:
53
53
  version: '3.2'
54
54
  - - "<"
55
55
  - !ruby/object:Gem::Version
56
- version: '7.0'
56
+ version: '8.0'
57
57
  description: Annotates Rails/ActiveRecord Models, routes, fixtures, and others based
58
58
  on the database schema.
59
59
  email:
@@ -79,7 +79,9 @@ files:
79
79
  - lib/annotate.rb
80
80
  - lib/annotate/active_record_patch.rb
81
81
  - lib/annotate/annotate_models.rb
82
+ - lib/annotate/annotate_models/file_patterns.rb
82
83
  - lib/annotate/annotate_routes.rb
84
+ - lib/annotate/annotate_routes/header_generator.rb
83
85
  - lib/annotate/annotate_routes/helpers.rb
84
86
  - lib/annotate/constants.rb
85
87
  - lib/annotate/helpers.rb
@@ -93,11 +95,12 @@ files:
93
95
  - lib/tasks/annotate_models_migrate.rake
94
96
  - lib/tasks/annotate_routes.rake
95
97
  - potato.md
96
- homepage: http://github.com/ctran/annotate_models
98
+ homepage: https://github.com/ctran/annotate_models
97
99
  licenses:
98
100
  - Ruby
99
101
  metadata:
100
- github_repo: ssh://github.com/ctran/annotate_models
102
+ bug_tracker_uri: https://github.com/ctran/annotate_models/issues/
103
+ source_code_uri: https://github.com/ctran/annotate_models.git
101
104
  post_install_message:
102
105
  rdoc_options: []
103
106
  require_paths:
@@ -113,8 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
116
  - !ruby/object:Gem::Version
114
117
  version: '0'
115
118
  requirements: []
116
- rubyforge_project:
117
- rubygems_version: 2.7.7
119
+ rubygems_version: 3.3.7
118
120
  signing_key:
119
121
  specification_version: 4
120
122
  summary: Annotates Rails Models, routes, fixtures, and others based on the database