annotaterb 4.22.0 → 4.24.0

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +83 -0
  3. data/README.md +156 -4
  4. data/VERSION +1 -1
  5. data/lib/annotate_rb/helper.rb +24 -1
  6. data/lib/annotate_rb/model_annotator/annotated_file/generator.rb +34 -12
  7. data/lib/annotate_rb/model_annotator/annotated_file/updater.rb +14 -1
  8. data/lib/annotate_rb/model_annotator/annotation/annotation_builder.rb +9 -1
  9. data/lib/annotate_rb/model_annotator/annotation_decider.rb +3 -0
  10. data/lib/annotate_rb/model_annotator/annotation_diff_generator.rb +9 -4
  11. data/lib/annotate_rb/model_annotator/column_annotation/attributes_builder.rb +7 -0
  12. data/lib/annotate_rb/model_annotator/column_annotation/column_component.rb +2 -2
  13. data/lib/annotate_rb/model_annotator/column_annotation/column_wrapper.rb +4 -0
  14. data/lib/annotate_rb/model_annotator/enum_annotation/annotation.rb +40 -0
  15. data/lib/annotate_rb/model_annotator/enum_annotation/annotation_builder.rb +38 -0
  16. data/lib/annotate_rb/model_annotator/enum_annotation/enum_component.rb +27 -0
  17. data/lib/annotate_rb/model_annotator/enum_annotation.rb +11 -0
  18. data/lib/annotate_rb/model_annotator/exclusion_constraint_annotation/annotation.rb +40 -0
  19. data/lib/annotate_rb/model_annotator/exclusion_constraint_annotation/annotation_builder.rb +38 -0
  20. data/lib/annotate_rb/model_annotator/exclusion_constraint_annotation/exclusion_constraint_component.rb +27 -0
  21. data/lib/annotate_rb/model_annotator/exclusion_constraint_annotation.rb +11 -0
  22. data/lib/annotate_rb/model_annotator/file_parser/annotation_finder.rb +75 -4
  23. data/lib/annotate_rb/model_annotator/file_parser/annotation_target.rb +31 -0
  24. data/lib/annotate_rb/model_annotator/file_parser/custom_parser.rb +11 -4
  25. data/lib/annotate_rb/model_annotator/file_parser/magic_comment.rb +32 -0
  26. data/lib/annotate_rb/model_annotator/file_parser/parsed_file.rb +5 -6
  27. data/lib/annotate_rb/model_annotator/file_parser/yml_parser.rb +43 -4
  28. data/lib/annotate_rb/model_annotator/file_parser.rb +2 -0
  29. data/lib/annotate_rb/model_annotator/foreign_key_annotation/foreign_key_component_builder.rb +6 -0
  30. data/lib/annotate_rb/model_annotator/index_annotation/annotation_builder.rb +29 -0
  31. data/lib/annotate_rb/model_annotator/index_annotation/index_component.rb +26 -4
  32. data/lib/annotate_rb/model_annotator/model_wrapper.rb +58 -2
  33. data/lib/annotate_rb/model_annotator/project_annotator.rb +2 -1
  34. data/lib/annotate_rb/model_annotator/single_file_annotation_remover.rb +1 -1
  35. data/lib/annotate_rb/model_annotator/single_file_annotator.rb +6 -6
  36. data/lib/annotate_rb/model_annotator/single_file_annotator_instruction.rb +3 -2
  37. data/lib/annotate_rb/model_annotator/unique_constraint_annotation/annotation.rb +40 -0
  38. data/lib/annotate_rb/model_annotator/unique_constraint_annotation/annotation_builder.rb +37 -0
  39. data/lib/annotate_rb/model_annotator/unique_constraint_annotation/unique_constraint_component.rb +27 -0
  40. data/lib/annotate_rb/model_annotator/unique_constraint_annotation.rb +11 -0
  41. data/lib/annotate_rb/model_annotator/zeitwerk_class_getter.rb +1 -1
  42. data/lib/annotate_rb/model_annotator.rb +3 -0
  43. data/lib/annotate_rb/options.rb +12 -2
  44. data/lib/annotate_rb/parser.rb +23 -6
  45. data/lib/annotate_rb/route_annotator/base_processor.rb +1 -1
  46. data/lib/annotate_rb/route_annotator/helper.rb +1 -1
  47. data/lib/annotate_rb/runner.rb +12 -6
  48. data/lib/annotate_rb/tasks/annotate_models_migrate.rake +8 -3
  49. data/lib/generators/annotate_rb/update_config/update_config_generator.rb +4 -1
  50. metadata +16 -2
@@ -42,13 +42,14 @@ module AnnotateRb
42
42
  klass.reset_column_information
43
43
  annotation = Annotation::AnnotationBuilder.new(klass, @options).build
44
44
  model_name = klass.name.underscore
45
+ model_class_name = klass.name.demodulize
45
46
 
46
47
  # In multi-database configurations, it is possible for different models to have the same table name but live
47
48
  # in different databases. Here we are opting to use the table name to find related files only when the model
48
49
  # is using the primary connection.
49
50
  table_name = klass.table_name if klass.connection_specification_name == ActiveRecord::Base.name
50
51
 
51
- model_instruction = SingleFileAnnotatorInstruction.new(file, annotation, :position_in_class, @options)
52
+ model_instruction = SingleFileAnnotatorInstruction.new(file, annotation, :position_in_class, @options, model_class_name: model_class_name)
52
53
  instructions << model_instruction
53
54
 
54
55
  related_files = RelatedFilesListBuilder.new(file, model_name, table_name, @options).build
@@ -18,7 +18,7 @@ module AnnotateRb
18
18
  parsed_file = FileParser::ParsedFile.new(old_content, "", parser_klass, options).parse
19
19
  rescue FileParser::AnnotationFinder::MalformedAnnotation => e
20
20
  warn "Unable to process #{file_name}: #{e.message}"
21
- warn "\t" + e.backtrace.join("\n\t") if @options[:trace]
21
+ warn "\t" + e.backtrace.join("\n\t") if options[:trace]
22
22
  return false
23
23
  end
24
24
 
@@ -5,7 +5,7 @@ module AnnotateRb
5
5
  class SingleFileAnnotator
6
6
  class << self
7
7
  def call_with_instructions(instruction)
8
- call(instruction.file, instruction.annotation, instruction.position, instruction.options)
8
+ call(instruction.file, instruction.annotation, instruction.position, instruction.options, model_class_name: instruction.model_class_name)
9
9
  end
10
10
 
11
11
  # Add a schema block to a file. If the file already contains
@@ -21,17 +21,17 @@ module AnnotateRb
21
21
  # :position_in_*<Symbol>:: where to place the annotated section in fixture or model file,
22
22
  # :before, :top, :after or :bottom. Default is :before.
23
23
  #
24
- def call(file_name, annotation, annotation_position, options)
24
+ def call(file_name, annotation, annotation_position, options, model_class_name: nil)
25
25
  return false unless File.exist?(file_name)
26
26
  old_content = File.read(file_name)
27
27
 
28
28
  parser_klass = FileToParserMapper.map(file_name)
29
29
 
30
30
  begin
31
- parsed_file = FileParser::ParsedFile.new(old_content, annotation, parser_klass, options).parse
31
+ parsed_file = FileParser::ParsedFile.new(old_content, annotation, parser_klass, options, model_class_name: model_class_name).parse
32
32
  rescue FileParser::AnnotationFinder::MalformedAnnotation => e
33
33
  warn "Unable to process #{file_name}: #{e.message}"
34
- warn "\t" + e.backtrace.join("\n\t") if @options[:trace]
34
+ warn "\t" + e.backtrace.join("\n\t") if options[:trace]
35
35
  return false
36
36
  end
37
37
 
@@ -41,9 +41,9 @@ module AnnotateRb
41
41
  abort "AnnotateRb error. #{file_name} needs to be updated, but annotaterb was run with `--frozen`." if options[:frozen]
42
42
 
43
43
  updated_file_content = if !parsed_file.has_annotations?
44
- AnnotatedFile::Generator.new(old_content, annotation, annotation_position, parser_klass, parsed_file, options).generate
44
+ AnnotatedFile::Generator.new(old_content, annotation, annotation_position, parser_klass, parsed_file, options, model_class_name: model_class_name).generate
45
45
  elsif options[:force]
46
- AnnotatedFile::Generator.new(old_content, annotation, annotation_position, parser_klass, parsed_file, options).generate
46
+ AnnotatedFile::Generator.new(old_content, annotation, annotation_position, parser_klass, parsed_file, options, model_class_name: model_class_name).generate
47
47
  else
48
48
  AnnotatedFile::Updater.new(old_content, annotation, annotation_position, parsed_file, options).update
49
49
  end
@@ -4,14 +4,15 @@ module AnnotateRb
4
4
  module ModelAnnotator
5
5
  # A plain old Ruby object (PORO) that contains all necessary information for SingleFileAnnotator
6
6
  class SingleFileAnnotatorInstruction
7
- def initialize(file, annotation, position, options)
7
+ def initialize(file, annotation, position, options, model_class_name: nil)
8
8
  @file = file # Path to file
9
9
  @annotation = annotation # Annotation string
10
10
  @position = position # Position in the file where to write the annotation to
11
11
  @options = options
12
+ @model_class_name = model_class_name # Short class name; set for the model file itself, nil for related files
12
13
  end
13
14
 
14
- attr_reader :file, :annotation, :position, :options
15
+ attr_reader :file, :annotation, :position, :options, :model_class_name
15
16
  end
16
17
  end
17
18
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnnotateRb
4
+ module ModelAnnotator
5
+ module UniqueConstraintAnnotation
6
+ class Annotation
7
+ HEADER_TEXT = "Unique Constraints"
8
+
9
+ def initialize(constraints)
10
+ @constraints = constraints
11
+ end
12
+
13
+ def body
14
+ [
15
+ Components::BlankCommentLine.new,
16
+ Components::Header.new(HEADER_TEXT),
17
+ Components::BlankCommentLine.new,
18
+ *@constraints
19
+ ]
20
+ end
21
+
22
+ def to_markdown
23
+ body.map(&:to_markdown).join("\n")
24
+ end
25
+
26
+ def to_rdoc
27
+ body.map(&:to_rdoc).join("\n")
28
+ end
29
+
30
+ def to_yard
31
+ body.map(&:to_yard).join("\n")
32
+ end
33
+
34
+ def to_default
35
+ body.map(&:to_default).join("\n")
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnnotateRb
4
+ module ModelAnnotator
5
+ module UniqueConstraintAnnotation
6
+ class AnnotationBuilder
7
+ def initialize(model, options)
8
+ @model = model
9
+ @options = options
10
+ end
11
+
12
+ def build
13
+ return Components::NilComponent.new if !@options[:show_unique_constraints]
14
+ return Components::NilComponent.new unless @model.connection.respond_to?(:supports_unique_constraints?) &&
15
+ @model.connection.supports_unique_constraints? && @model.connection.respond_to?(:unique_constraints)
16
+
17
+ unique_constraints = @model.connection.unique_constraints(@model.table_name)
18
+ return Components::NilComponent.new if unique_constraints.empty?
19
+
20
+ max_size = unique_constraints.map { |unique_constraint| unique_constraint.name.size }.max + 1
21
+
22
+ constraints = unique_constraints.sort_by(&:name).map do |unique_constraint|
23
+ columns = Array(unique_constraint.column)
24
+ details = "(#{columns.join(", ")})"
25
+ if unique_constraint.deferrable
26
+ details += " DEFERRABLE INITIALLY #{unique_constraint.deferrable.to_s.upcase}"
27
+ end
28
+
29
+ UniqueConstraintComponent.new(unique_constraint.name, details, max_size)
30
+ end
31
+
32
+ _annotation = Annotation.new(constraints)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnnotateRb
4
+ module ModelAnnotator
5
+ module UniqueConstraintAnnotation
6
+ class UniqueConstraintComponent < Components::Base
7
+ attr_reader :name, :details, :max_size
8
+
9
+ def initialize(name, details, max_size)
10
+ @name = name
11
+ @details = details
12
+ @max_size = max_size
13
+ end
14
+
15
+ def to_default
16
+ # standard:disable Lint/FormatParameterMismatch
17
+ sprintf("# %-#{max_size}.#{max_size}s %s", name, details).rstrip
18
+ # standard:enable Lint/FormatParameterMismatch
19
+ end
20
+
21
+ def to_markdown
22
+ sprintf("# * `%s`: `%s`", name, details)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnnotateRb
4
+ module ModelAnnotator
5
+ module UniqueConstraintAnnotation
6
+ autoload :AnnotationBuilder, "annotate_rb/model_annotator/unique_constraint_annotation/annotation_builder"
7
+ autoload :Annotation, "annotate_rb/model_annotator/unique_constraint_annotation/annotation"
8
+ autoload :UniqueConstraintComponent, "annotate_rb/model_annotator/unique_constraint_annotation/unique_constraint_component"
9
+ end
10
+ end
11
+ end
@@ -49,7 +49,7 @@ module AnnotateRb
49
49
 
50
50
  # once we have the filepath_relative_to_root_dir, we need to see if it
51
51
  # falls within one of our Zeitwerk "collapsed" paths.
52
- if loader.collapse.any? { |path| path.include?(root_dir) && file.include?(path.split(root_dir)[1]) }
52
+ if loader.collapse.any? { |path| path.include?(root_dir) && @file.include?(path.split(root_dir)[1]) }
53
53
  # if the file is within a collapsed path, we then need to, for each
54
54
  # collapsed path, remove the root dir
55
55
  collapsed = loader.collapse.map { |path| path.split(root_dir)[1].sub(/^\//, "") }.to_set
@@ -27,6 +27,9 @@ module AnnotateRb
27
27
  autoload :FileParser, "annotate_rb/model_annotator/file_parser"
28
28
  autoload :ZeitwerkClassGetter, "annotate_rb/model_annotator/zeitwerk_class_getter"
29
29
  autoload :CheckConstraintAnnotation, "annotate_rb/model_annotator/check_constraint_annotation"
30
+ autoload :UniqueConstraintAnnotation, "annotate_rb/model_annotator/unique_constraint_annotation"
31
+ autoload :ExclusionConstraintAnnotation, "annotate_rb/model_annotator/exclusion_constraint_annotation"
32
+ autoload :EnumAnnotation, "annotate_rb/model_annotator/enum_annotation"
30
33
  autoload :FileToParserMapper, "annotate_rb/model_annotator/file_to_parser_mapper"
31
34
  autoload :Components, "annotate_rb/model_annotator/components"
32
35
  autoload :Annotation, "annotate_rb/model_annotator/annotation"
@@ -42,13 +42,18 @@ module AnnotateRb
42
42
  format_yard: false, # ModelAnnotator
43
43
  frozen: false, # ModelAnnotator, but should be used by both
44
44
  grouped_polymorphic: false, # ModelAnnotator
45
+ ignore_database_name: false, # ModelAnnotator
45
46
  ignore_model_sub_dir: false, # ModelAnnotator
46
47
  ignore_unknown_models: false, # ModelAnnotator
47
48
  include_version: false, # ModelAnnotator
48
49
  show_complete_foreign_keys: false, # ModelAnnotator
49
50
  show_check_constraints: false, # ModelAnnotator
51
+ show_unique_constraints: false, # ModelAnnotator
52
+ show_exclusion_constraints: false, # ModelAnnotator
53
+ show_enums: false, # ModelAnnotator
50
54
  show_foreign_keys: true, # ModelAnnotator
51
55
  show_indexes: true, # ModelAnnotator
56
+ show_indexes_comments: false, # ModelAnnotator
52
57
  show_indexes_include: false, # ModelAnnotator
53
58
  show_virtual_columns: false, # ModelAnnotator
54
59
  simple_indexes: false, # ModelAnnotator
@@ -78,10 +83,10 @@ module AnnotateRb
78
83
  ignore_columns: nil, # ModelAnnotator
79
84
  ignore_multi_database_name: false, # ModelAnnotator
80
85
  ignore_routes: nil, # RouteAnnotator
81
- ignore_unknown_models: false, # ModelAnnotator
82
86
  models: true, # Core
83
87
  routes: false, # Core
84
88
  skip_on_db_migrate: false, # Core
89
+ auto_annotate_routes_after_migrate: false, # Core
85
90
  target_action: :do_annotations, # Core; Possible values: :do_annotations, :remove_annotations
86
91
  wrapper: nil, # ModelAnnotator, RouteAnnotator
87
92
  wrapper_close: nil, # ModelAnnotator, RouteAnnotator
@@ -116,13 +121,18 @@ module AnnotateRb
116
121
  :format_yard,
117
122
  :frozen,
118
123
  :grouped_polymorphic,
124
+ :ignore_database_name,
119
125
  :ignore_model_sub_dir,
120
126
  :ignore_unknown_models,
121
127
  :include_version,
122
128
  :show_check_constraints,
129
+ :show_unique_constraints,
130
+ :show_exclusion_constraints,
131
+ :show_enums,
123
132
  :show_complete_foreign_keys,
124
133
  :show_foreign_keys,
125
134
  :show_indexes,
135
+ :show_indexes_comments,
126
136
  :show_indexes_include,
127
137
  :simple_indexes,
128
138
  :sort,
@@ -143,11 +153,11 @@ module AnnotateRb
143
153
  :timestamp_columns,
144
154
  :ignore_columns,
145
155
  :ignore_routes,
146
- :ignore_unknown_models,
147
156
  :ignore_multi_database_name,
148
157
  :models,
149
158
  :routes,
150
159
  :skip_on_db_migrate,
160
+ :auto_annotate_routes_after_migrate,
151
161
  :target_action,
152
162
  :wrapper,
153
163
  :wrapper_close,
@@ -22,7 +22,9 @@ module AnnotateRb
22
22
  exit: false
23
23
  }.freeze
24
24
 
25
- ANNOTATION_POSITIONS = %w[before top after bottom].freeze
25
+ ANNOTATION_POSITIONS = %w[before top after bottom before_doc].freeze
26
+ AFTER_POSITIONS = %w[after bottom].freeze
27
+ DOC_AWARE_POSITIONS = %w[before_doc].freeze
26
28
  FILE_TYPE_POSITIONS = %w[position_in_class position_in_factory position_in_fixture position_in_test position_in_routes position_in_serializer].freeze
27
29
  EXCLUSION_LIST = %w[tests fixtures factories serializers].freeze
28
30
  FORMAT_TYPES = %w[bare rdoc yard markdown].freeze
@@ -205,6 +207,16 @@ module AnnotateRb
205
207
  @options[:show_check_constraints] = true
206
208
  end
207
209
 
210
+ option_parser.on("--show-unique-constraints",
211
+ "List the table's unique constraints in the annotation") do
212
+ @options[:show_unique_constraints] = true
213
+ end
214
+
215
+ option_parser.on("--show-exclusion-constraints",
216
+ "List the table's exclusion constraints in the annotation") do
217
+ @options[:show_exclusion_constraints] = true
218
+ end
219
+
208
220
  option_parser.on("--hide-limit-column-types VALUES",
209
221
  "don't show limit for given column types, separated by commas (i.e., `integer,boolean,text`)") do |values|
210
222
  @options[:hide_limit_column_types] = values.to_s
@@ -220,6 +232,11 @@ module AnnotateRb
220
232
  @options[:ignore_unknown_models] = true
221
233
  end
222
234
 
235
+ option_parser.on("--ignore-database-name",
236
+ "don't include the database name in the annotation") do
237
+ @options[:ignore_database_name] = true
238
+ end
239
+
223
240
  option_parser.on("-I",
224
241
  "--ignore-columns REGEX",
225
242
  "don't annotate columns that match a given REGEX (i.e., `annotate -I '^(id|updated_at|created_at)'`") do |regex|
@@ -232,7 +249,7 @@ module AnnotateRb
232
249
  end
233
250
 
234
251
  option_parser.on("--without-comment",
235
- "include database comments in model annotations") do
252
+ "exclude database comments in model annotations") do
236
253
  @options[:with_comment] = false
237
254
  end
238
255
 
@@ -297,9 +314,9 @@ module AnnotateRb
297
314
  has_set_position = {}
298
315
 
299
316
  option_parser.on("-p",
300
- "--position [before|top|after|bottom]",
317
+ "--position [before|top|after|bottom|before_doc]",
301
318
  ANNOTATION_POSITIONS,
302
- "Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/route/serializer file(s)") do |position|
319
+ "Place the annotations at the top (before), bottom (after), or above the class documentation (before_doc) of the model/test/fixture/factory/route/serializer file(s)") do |position|
303
320
  @options[:position] = position
304
321
 
305
322
  FILE_TYPE_POSITIONS.each do |key|
@@ -308,9 +325,9 @@ module AnnotateRb
308
325
  end
309
326
 
310
327
  option_parser.on("--pc",
311
- "--position-in-class [before|top|after|bottom]",
328
+ "--position-in-class [before|top|after|bottom|before_doc]",
312
329
  ANNOTATION_POSITIONS,
313
- "Place the annotations at the top (before) or the bottom (after) of the model file") do |position_in_class|
330
+ "Place the annotations at the top (before), bottom (after), or above the class documentation (before_doc) of the model file") do |position_in_class|
314
331
  @options[:position_in_class] = position_in_class
315
332
  has_set_position["position_in_class"] = true
316
333
  end
@@ -75,7 +75,7 @@ module AnnotateRb
75
75
  header_position = 0
76
76
 
77
77
  content.split(/\n/, -1).each_with_index do |line, line_number|
78
- if mode == :header && line !~ /\s*#/
78
+ if mode == :header && line !~ /\A\s*#/
79
79
  mode = :content
80
80
  real_content << line unless line.blank?
81
81
  elsif mode == :content
@@ -70,7 +70,7 @@ module AnnotateRb
70
70
  header_position = 0
71
71
 
72
72
  content.split(/\n/, -1).each_with_index do |line, line_number|
73
- if mode == :header && line !~ /\s*#/
73
+ if mode == :header && line !~ /\A\s*#/
74
74
  mode = :content
75
75
  real_content << line unless line.blank?
76
76
  elsif mode == :content
@@ -5,10 +5,18 @@ module AnnotateRb
5
5
  class << self
6
6
  attr_reader :runner
7
7
 
8
- def run(args)
8
+ def run_after_migration
9
+ config_file_options = ConfigLoader.load_config
10
+ options = Options.from(config_file_options)
11
+
12
+ commands = ["models", *(options[:auto_annotate_routes_after_migrate] ? ["routes"] : [])]
13
+ commands.each { |cmd| run([cmd], config_file_options: config_file_options) }
14
+ end
15
+
16
+ def run(args, config_file_options: nil)
9
17
  self.runner = new
10
18
 
11
- runner.run(args)
19
+ runner.run(args, config_file_options: config_file_options)
12
20
 
13
21
  self.runner = nil
14
22
  end
@@ -22,14 +30,14 @@ module AnnotateRb
22
30
  attr_writer :runner
23
31
  end
24
32
 
25
- def run(args)
33
+ def run(args, config_file_options: nil)
26
34
  parser = Parser.new(args, {})
27
35
 
28
36
  parsed_options = parser.parse
29
37
  remaining_args = parser.remaining_args
30
38
 
31
39
  AnnotateRb::ConfigFinder.config_path = parsed_options[:config_path] if parsed_options[:config_path]
32
- config_file_options = ConfigLoader.load_config
40
+ config_file_options = ConfigLoader.load_config if config_file_options.nil?
33
41
  options = config_file_options.merge(parsed_options)
34
42
 
35
43
  @options = Options.from(options, {working_args: remaining_args})
@@ -38,8 +46,6 @@ module AnnotateRb
38
46
  raise "Didn't specify a command" unless @options[:command]
39
47
 
40
48
  @options[:command].call(@options)
41
-
42
- # TODO
43
49
  end
44
50
  end
45
51
  end
@@ -28,11 +28,16 @@ migration_tasks.each do |task|
28
28
  next unless Rake::Task.task_defined?(task)
29
29
  next if config[:skip_on_db_migrate]
30
30
 
31
- Rake::Task[task].enhance do # This block is ran after `task` completes
32
- task_name = Rake.application.top_level_tasks.last # The name of the task that was run, e.g. "db:migrate"
31
+ Rake::Task[task].enhance do |current_task| # This block is ran after `task` completes
32
+ # Prefer the top-level task (the one invoked from the CLI, e.g. "db:migrate") so that
33
+ # when sub-tasks chain (e.g. db:migrate:redo invokes db:rollback then db:migrate), we
34
+ # defer the annotation run to after everything completes. Fall back to the currently
35
+ # enhanced task when there is no top-level task (e.g. when the task is invoked
36
+ # programmatically from application code rather than from the Rake CLI).
37
+ task_name = Rake.application.top_level_tasks.last || current_task.name
33
38
 
34
39
  Rake::Task[task_name].enhance do
35
- ::AnnotateRb::Runner.run(["models"])
40
+ ::AnnotateRb::Runner.run_after_migration
36
41
  end
37
42
  end
38
43
  end
@@ -6,7 +6,10 @@ module AnnotateRb
6
6
  module Generators
7
7
  class UpdateConfigGenerator < ::Rails::Generators::Base
8
8
  def generate_config
9
- insert_into_file ::AnnotateRb::ConfigFinder::DOTFILE do
9
+ parsed_options = AnnotateRb::Parser.parse(ARGV, {})
10
+ AnnotateRb::ConfigFinder.config_path = parsed_options[:config_path] if parsed_options[:config_path]
11
+
12
+ insert_into_file ::AnnotateRb::ConfigFinder.find_project_dotfile do
10
13
  ::AnnotateRb::ConfigGenerator.unset_config_defaults
11
14
  end
12
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: annotaterb
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.22.0
4
+ version: 4.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew W. Lee
@@ -90,10 +90,20 @@ files:
90
90
  - lib/annotate_rb/model_annotator/column_annotation/default_value_builder.rb
91
91
  - lib/annotate_rb/model_annotator/column_annotation/type_builder.rb
92
92
  - lib/annotate_rb/model_annotator/components.rb
93
+ - lib/annotate_rb/model_annotator/enum_annotation.rb
94
+ - lib/annotate_rb/model_annotator/enum_annotation/annotation.rb
95
+ - lib/annotate_rb/model_annotator/enum_annotation/annotation_builder.rb
96
+ - lib/annotate_rb/model_annotator/enum_annotation/enum_component.rb
97
+ - lib/annotate_rb/model_annotator/exclusion_constraint_annotation.rb
98
+ - lib/annotate_rb/model_annotator/exclusion_constraint_annotation/annotation.rb
99
+ - lib/annotate_rb/model_annotator/exclusion_constraint_annotation/annotation_builder.rb
100
+ - lib/annotate_rb/model_annotator/exclusion_constraint_annotation/exclusion_constraint_component.rb
93
101
  - lib/annotate_rb/model_annotator/file_name_resolver.rb
94
102
  - lib/annotate_rb/model_annotator/file_parser.rb
95
103
  - lib/annotate_rb/model_annotator/file_parser/annotation_finder.rb
104
+ - lib/annotate_rb/model_annotator/file_parser/annotation_target.rb
96
105
  - lib/annotate_rb/model_annotator/file_parser/custom_parser.rb
106
+ - lib/annotate_rb/model_annotator/file_parser/magic_comment.rb
97
107
  - lib/annotate_rb/model_annotator/file_parser/parsed_file.rb
98
108
  - lib/annotate_rb/model_annotator/file_parser/parsed_file_result.rb
99
109
  - lib/annotate_rb/model_annotator/file_parser/yml_parser.rb
@@ -118,6 +128,10 @@ files:
118
128
  - lib/annotate_rb/model_annotator/single_file_annotator.rb
119
129
  - lib/annotate_rb/model_annotator/single_file_annotator_instruction.rb
120
130
  - lib/annotate_rb/model_annotator/single_file_remove_annotation_instruction.rb
131
+ - lib/annotate_rb/model_annotator/unique_constraint_annotation.rb
132
+ - lib/annotate_rb/model_annotator/unique_constraint_annotation/annotation.rb
133
+ - lib/annotate_rb/model_annotator/unique_constraint_annotation/annotation_builder.rb
134
+ - lib/annotate_rb/model_annotator/unique_constraint_annotation/unique_constraint_component.rb
121
135
  - lib/annotate_rb/model_annotator/zeitwerk_class_getter.rb
122
136
  - lib/annotate_rb/options.rb
123
137
  - lib/annotate_rb/parser.rb
@@ -164,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
178
  - !ruby/object:Gem::Version
165
179
  version: '0'
166
180
  requirements: []
167
- rubygems_version: 4.0.4
181
+ rubygems_version: 3.6.9
168
182
  specification_version: 4
169
183
  summary: A gem for generating annotations for Rails projects.
170
184
  test_files: []