annotaterb 4.1.1 → 4.2.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -0
  3. data/VERSION +1 -1
  4. data/exe/annotaterb +7 -7
  5. data/lib/annotate_rb/active_record_patch.rb +2 -0
  6. data/lib/annotate_rb/commands/annotate_models.rb +0 -1
  7. data/lib/annotate_rb/commands/annotate_routes.rb +0 -1
  8. data/lib/annotate_rb/commands/print_help.rb +0 -1
  9. data/lib/annotate_rb/commands/print_version.rb +0 -1
  10. data/lib/annotate_rb/commands.rb +4 -4
  11. data/lib/annotate_rb/config_finder.rb +1 -1
  12. data/lib/annotate_rb/config_loader.rb +2 -2
  13. data/lib/annotate_rb/core.rb +3 -3
  14. data/lib/annotate_rb/helper.rb +16 -0
  15. data/lib/annotate_rb/model_annotator/{annotation_generator.rb → annotation_builder.rb} +18 -14
  16. data/lib/annotate_rb/model_annotator/annotation_decider.rb +10 -12
  17. data/lib/annotate_rb/model_annotator/annotation_diff.rb +1 -1
  18. data/lib/annotate_rb/model_annotator/annotation_diff_generator.rb +9 -9
  19. data/lib/annotate_rb/model_annotator/annotation_pattern_generator.rb +3 -3
  20. data/lib/annotate_rb/model_annotator/annotator.rb +12 -53
  21. data/lib/annotate_rb/model_annotator/column_annotation/annotation_builder.rb +135 -0
  22. data/lib/annotate_rb/model_annotator/column_annotation/attributes_builder.rb +104 -0
  23. data/lib/annotate_rb/model_annotator/column_annotation/column_wrapper.rb +103 -0
  24. data/lib/annotate_rb/model_annotator/column_annotation/type_builder.rb +54 -0
  25. data/lib/annotate_rb/model_annotator/column_annotation.rb +12 -0
  26. data/lib/annotate_rb/model_annotator/file_builder.rb +58 -0
  27. data/lib/annotate_rb/model_annotator/file_components.rb +78 -0
  28. data/lib/annotate_rb/model_annotator/file_name_resolver.rb +3 -3
  29. data/lib/annotate_rb/model_annotator/foreign_key_annotation/annotation_builder.rb +57 -0
  30. data/lib/annotate_rb/model_annotator/foreign_key_annotation.rb +9 -0
  31. data/lib/annotate_rb/model_annotator/index_annotation/annotation_builder.rb +113 -0
  32. data/lib/annotate_rb/model_annotator/index_annotation.rb +9 -0
  33. data/lib/annotate_rb/model_annotator/magic_comment_parser.rb +32 -0
  34. data/lib/annotate_rb/model_annotator/model_class_getter.rb +6 -6
  35. data/lib/annotate_rb/model_annotator/model_files_getter.rb +12 -10
  36. data/lib/annotate_rb/model_annotator/model_wrapper.rb +44 -37
  37. data/lib/annotate_rb/model_annotator/pattern_getter.rb +142 -10
  38. data/lib/annotate_rb/model_annotator/project_annotation_remover.rb +65 -0
  39. data/lib/annotate_rb/model_annotator/project_annotator.rb +63 -0
  40. data/lib/annotate_rb/model_annotator/related_files_list_builder.rb +16 -18
  41. data/lib/annotate_rb/model_annotator/single_file_annotation_remover.rb +37 -0
  42. data/lib/annotate_rb/model_annotator/single_file_annotator.rb +49 -0
  43. data/lib/annotate_rb/model_annotator/{file_annotator_instruction.rb → single_file_annotator_instruction.rb} +2 -2
  44. data/lib/annotate_rb/model_annotator/single_file_remove_annotation_instruction.rb +15 -0
  45. data/lib/annotate_rb/model_annotator.rb +25 -26
  46. data/lib/annotate_rb/options.rb +20 -25
  47. data/lib/annotate_rb/parser.rb +150 -142
  48. data/lib/annotate_rb/rake_bootstrapper.rb +8 -8
  49. data/lib/annotate_rb/route_annotator/annotation_processor.rb +7 -8
  50. data/lib/annotate_rb/route_annotator/annotator.rb +2 -2
  51. data/lib/annotate_rb/route_annotator/base_processor.rb +3 -3
  52. data/lib/annotate_rb/route_annotator/header_generator.rb +15 -15
  53. data/lib/annotate_rb/route_annotator/helper.rb +9 -9
  54. data/lib/annotate_rb/route_annotator/removal_processor.rb +4 -4
  55. data/lib/annotate_rb/route_annotator.rb +6 -6
  56. data/lib/annotate_rb/runner.rb +0 -4
  57. data/lib/annotate_rb/tasks/annotate_models_migrate.rake +5 -5
  58. data/lib/annotate_rb.rb +19 -19
  59. data/lib/generators/annotate_rb/install/install_generator.rb +3 -2
  60. data/lib/generators/annotate_rb/install/templates/annotate_rb.rake +1 -1
  61. metadata +22 -16
  62. data/lib/annotate_rb/model_annotator/column_annotation_builder.rb +0 -92
  63. data/lib/annotate_rb/model_annotator/column_attributes_builder.rb +0 -102
  64. data/lib/annotate_rb/model_annotator/column_type_builder.rb +0 -51
  65. data/lib/annotate_rb/model_annotator/column_wrapper.rb +0 -84
  66. data/lib/annotate_rb/model_annotator/constants.rb +0 -22
  67. data/lib/annotate_rb/model_annotator/file_annotation_remover.rb +0 -25
  68. data/lib/annotate_rb/model_annotator/file_annotator.rb +0 -77
  69. data/lib/annotate_rb/model_annotator/file_patterns.rb +0 -129
  70. data/lib/annotate_rb/model_annotator/foreign_key_annotation_builder.rb +0 -55
  71. data/lib/annotate_rb/model_annotator/helper.rb +0 -107
  72. data/lib/annotate_rb/model_annotator/index_annotation_builder.rb +0 -74
  73. data/lib/annotate_rb/model_annotator/model_file_annotator.rb +0 -55
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnnotateRb
4
- module ModelAnnotator
5
- class ColumnWrapper
6
- def initialize(column)
7
- @column = column
8
- end
9
-
10
- def default
11
- # Note: Used to be klass.column_defaults[name], where name is the column name.
12
- # Looks to be identical, but keeping note here in case there are differences.
13
- _column_default = @column.default
14
- end
15
-
16
- def default_string
17
- Helper.quote(@column.default)
18
- end
19
-
20
- def type
21
- @column.type
22
- end
23
-
24
- def column_type_string
25
- if (@column.respond_to?(:bigint?) && @column.bigint?) || /\Abigint\b/ =~ @column.sql_type
26
- 'bigint'
27
- else
28
- (@column.type || @column.sql_type).to_s
29
- end
30
- end
31
-
32
- def unsigned?
33
- @column.respond_to?(:unsigned?) && @column.unsigned?
34
- end
35
-
36
- def null
37
- @column.null
38
- end
39
-
40
- def precision
41
- @column.precision
42
- end
43
-
44
- def scale
45
- @column.scale
46
- end
47
-
48
- def limit
49
- @column.limit
50
- end
51
-
52
- def geometry_type?
53
- @column.respond_to?(:geometry_type)
54
- end
55
-
56
- def geometry_type
57
- # TODO: Check if we need to check if it responds before accessing the geometry type
58
- @column.geometry_type
59
- end
60
-
61
- def geometric_type?
62
- @column.respond_to?(:geometric_type)
63
- end
64
-
65
- def geometric_type
66
- # TODO: Check if we need to check if it responds before accessing the geometric type
67
- @column.geometric_type
68
- end
69
-
70
- def srid
71
- # TODO: Check if we need to check if it responds before accessing the srid
72
- @column.srid
73
- end
74
-
75
- def array?
76
- @column.respond_to?(:array) && @column.array
77
- end
78
-
79
- def name
80
- @column.name
81
- end
82
- end
83
- end
84
- end
@@ -1,22 +0,0 @@
1
- module AnnotateRb
2
- module ModelAnnotator
3
- module Constants
4
- ##
5
- # The set of available options to customize the behavior of Annotate.
6
- #
7
- POSITION_OPTIONS = ::AnnotateRb::Options::POSITION_OPTION_KEYS
8
-
9
- FLAG_OPTIONS = ::AnnotateRb::Options::FLAG_OPTION_KEYS
10
-
11
- OTHER_OPTIONS = ::AnnotateRb::Options::OTHER_OPTION_KEYS
12
-
13
- PATH_OPTIONS = ::AnnotateRb::Options::PATH_OPTION_KEYS
14
-
15
- ALL_ANNOTATE_OPTIONS = ::AnnotateRb::Options::ALL_OPTION_KEYS
16
-
17
- SKIP_ANNOTATION_PREFIX = '# -\*- SkipSchemaAnnotations'.freeze
18
-
19
- MAGIC_COMMENT_MATCHER = Regexp.new(/(^#\s*encoding:.*(?:\n|r\n))|(^# coding:.*(?:\n|\r\n))|(^# -\*- coding:.*(?:\n|\r\n))|(^# -\*- encoding\s?:.*(?:\n|\r\n))|(^#\s*frozen_string_literal:.+(?:\n|\r\n))|(^# -\*- frozen_string_literal\s*:.+-\*-(?:\n|\r\n))/).freeze
20
- end
21
- end
22
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnnotateRb
4
- module ModelAnnotator
5
- class FileAnnotationRemover
6
- class << self
7
- def call(file_name, options = Options.from({}))
8
- if File.exist?(file_name)
9
- content = File.read(file_name)
10
- return false if content =~ /#{Constants::SKIP_ANNOTATION_PREFIX}.*\n/
11
-
12
- wrapper_open = options[:wrapper_open] ? "# #{options[:wrapper_open]}\n" : ''
13
- content.sub!(/(#{wrapper_open})?#{AnnotationPatternGenerator.call(options)}/, '')
14
-
15
- File.open(file_name, 'wb') { |f| f.puts content }
16
-
17
- true
18
- else
19
- false
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnnotateRb
4
- module ModelAnnotator
5
- class FileAnnotator
6
- class << self
7
- def call_with_instructions(instruction)
8
- call(instruction.file, instruction.annotation, instruction.position, instruction.options)
9
- end
10
-
11
- # Add a schema block to a file. If the file already contains
12
- # a schema info block (a comment starting with "== Schema Information"),
13
- # check if it matches the block that is already there. If so, leave it be.
14
- # If not, remove the old info block and write a new one.
15
- #
16
- # == Returns:
17
- # true or false depending on whether the file was modified.
18
- #
19
- # === Options (opts)
20
- # :force<Symbol>:: whether to update the file even if it doesn't seem to need it.
21
- # :position_in_*<Symbol>:: where to place the annotated section in fixture or model file,
22
- # :before, :top, :after or :bottom. Default is :before.
23
- #
24
- def call(file_name, info_block, position, options = {})
25
- return false unless File.exist?(file_name)
26
- old_content = File.read(file_name)
27
-
28
- return false if old_content =~ /#{Constants::SKIP_ANNOTATION_PREFIX}.*\n/
29
-
30
- diff = AnnotationDiffGenerator.new(old_content, info_block).generate
31
-
32
- return false if !diff.changed? && !options[:force]
33
-
34
- abort "AnnotateRb error. #{file_name} needs to be updated, but annotaterb was run with `--frozen`." if options[:frozen]
35
-
36
- # Replace inline the old schema info with the new schema info
37
- wrapper_open = options[:wrapper_open] ? "# #{options[:wrapper_open]}\n" : ""
38
- wrapper_close = options[:wrapper_close] ? "# #{options[:wrapper_close]}\n" : ""
39
- wrapped_info_block = "#{wrapper_open}#{info_block}#{wrapper_close}"
40
-
41
- annotation_pattern = AnnotationPatternGenerator.call(options)
42
- old_annotation = old_content.match(annotation_pattern).to_s
43
-
44
- # if there *was* no old schema info or :force was passed, we simply
45
- # need to insert it in correct position
46
- if old_annotation.empty? || options[:force]
47
- magic_comments_block = Helper.magic_comments_as_string(old_content)
48
- old_content.gsub!(Constants::MAGIC_COMMENT_MATCHER, '')
49
-
50
- annotation_pattern = AnnotationPatternGenerator.call(options)
51
- old_content.sub!(annotation_pattern, '')
52
-
53
- new_content = if %w(after bottom).include?(options[position].to_s)
54
- magic_comments_block + (old_content.rstrip + "\n\n" + wrapped_info_block)
55
- elsif magic_comments_block.empty?
56
- magic_comments_block + wrapped_info_block + old_content.lstrip
57
- else
58
- magic_comments_block + "\n" + wrapped_info_block + old_content.lstrip
59
- end
60
- else
61
- # replace the old annotation with the new one
62
-
63
- # keep the surrounding whitespace the same
64
- space_match = old_annotation.match(/\A(?<start>\s*).*?\n(?<end>\s*)\z/m)
65
- new_annotation = space_match[:start] + wrapped_info_block + space_match[:end]
66
-
67
- annotation_pattern = AnnotationPatternGenerator.call(options)
68
- new_content = old_content.sub(annotation_pattern, new_annotation)
69
- end
70
-
71
- File.open(file_name, 'wb') { |f| f.puts new_content }
72
- true
73
- end
74
- end
75
- end
76
- end
77
- end
@@ -1,129 +0,0 @@
1
- module AnnotateRb
2
- module ModelAnnotator
3
- # This module provides module method to get file paths.
4
- module FilePatterns
5
- # Controller files
6
- CONTROLLER_DIR = File.join('app', 'controllers')
7
-
8
- # Active admin registry files
9
- ACTIVEADMIN_DIR = File.join('app', 'admin')
10
-
11
- # Helper files
12
- HELPER_DIR = File.join('app', 'helpers')
13
-
14
- # File.join for windows reverse bar compat?
15
- # I dont use windows, can`t test
16
- UNIT_TEST_DIR = File.join('test', 'unit')
17
- MODEL_TEST_DIR = File.join('test', 'models') # since rails 4.0
18
- SPEC_MODEL_DIR = File.join('spec', 'models')
19
-
20
- FIXTURE_TEST_DIR = File.join('test', 'fixtures')
21
- FIXTURE_SPEC_DIR = File.join('spec', 'fixtures')
22
-
23
- # 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')
28
-
29
- # 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
-
33
- # Machinist http://github.com/notahat/machinist
34
- BLUEPRINTS_TEST_DIR = File.join('test', 'blueprints')
35
- BLUEPRINTS_SPEC_DIR = File.join('spec', 'blueprints')
36
-
37
- # Factory Bot https://github.com/thoughtbot/factory_bot
38
- FACTORY_BOT_TEST_DIR = File.join('test', 'factories')
39
- FACTORY_BOT_SPEC_DIR = File.join('spec', 'factories')
40
-
41
- # Fabrication https://github.com/paulelliott/fabrication.git
42
- FABRICATORS_TEST_DIR = File.join('test', 'fabricators')
43
- FABRICATORS_SPEC_DIR = File.join('spec', 'fabricators')
44
-
45
- # 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')
49
-
50
- class << self
51
- def generate(root_directory, pattern_type, options)
52
- case pattern_type
53
- when 'test' then test_files(root_directory)
54
- when 'fixture' then fixture_files(root_directory)
55
- when 'scaffold' then scaffold_files(root_directory)
56
- when 'factory' then factory_files(root_directory)
57
- when 'serializer' then serialize_files(root_directory)
58
- when 'additional_file_patterns'
59
- [options[:additional_file_patterns] || []].flatten
60
- when 'controller'
61
- [File.join(root_directory, CONTROLLER_DIR, '%PLURALIZED_MODEL_NAME%_controller.rb')]
62
- when 'admin'
63
- [
64
- File.join(root_directory, ACTIVEADMIN_DIR, '%MODEL_NAME%.rb'),
65
- File.join(root_directory, ACTIVEADMIN_DIR, '%PLURALIZED_MODEL_NAME%.rb')
66
- ]
67
- when 'helper'
68
- [File.join(root_directory, HELPER_DIR, '%PLURALIZED_MODEL_NAME%_helper.rb')]
69
- else
70
- []
71
- end
72
- end
73
-
74
- private
75
-
76
- def test_files(root_directory)
77
- [
78
- File.join(root_directory, UNIT_TEST_DIR, '%MODEL_NAME%_test.rb'),
79
- File.join(root_directory, MODEL_TEST_DIR, '%MODEL_NAME%_test.rb'),
80
- File.join(root_directory, SPEC_MODEL_DIR, '%MODEL_NAME%_spec.rb')
81
- ]
82
- end
83
-
84
- def fixture_files(root_directory)
85
- [
86
- File.join(root_directory, FIXTURE_TEST_DIR, '%TABLE_NAME%.yml'),
87
- File.join(root_directory, FIXTURE_SPEC_DIR, '%TABLE_NAME%.yml'),
88
- File.join(root_directory, FIXTURE_TEST_DIR, '%PLURALIZED_MODEL_NAME%.yml'),
89
- File.join(root_directory, FIXTURE_SPEC_DIR, '%PLURALIZED_MODEL_NAME%.yml')
90
- ]
91
- end
92
-
93
- def scaffold_files(root_directory)
94
- [
95
- File.join(root_directory, CONTROLLER_TEST_DIR, '%PLURALIZED_MODEL_NAME%_controller_test.rb'),
96
- File.join(root_directory, CONTROLLER_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_controller_spec.rb'),
97
- File.join(root_directory, REQUEST_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_spec.rb'),
98
- File.join(root_directory, ROUTING_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_routing_spec.rb')
99
- ]
100
- end
101
-
102
- def factory_files(root_directory)
103
- [
104
- File.join(root_directory, EXEMPLARS_TEST_DIR, '%MODEL_NAME%_exemplar.rb'),
105
- File.join(root_directory, EXEMPLARS_SPEC_DIR, '%MODEL_NAME%_exemplar.rb'),
106
- File.join(root_directory, BLUEPRINTS_TEST_DIR, '%MODEL_NAME%_blueprint.rb'),
107
- File.join(root_directory, BLUEPRINTS_SPEC_DIR, '%MODEL_NAME%_blueprint.rb'),
108
- File.join(root_directory, FACTORY_BOT_TEST_DIR, '%MODEL_NAME%_factory.rb'), # (old style)
109
- File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%MODEL_NAME%_factory.rb'), # (old style)
110
- File.join(root_directory, FACTORY_BOT_TEST_DIR, '%TABLE_NAME%.rb'), # (new style)
111
- File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%TABLE_NAME%.rb'), # (new style)
112
- File.join(root_directory, FACTORY_BOT_TEST_DIR, '%PLURALIZED_MODEL_NAME%.rb'), # (new style)
113
- File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%PLURALIZED_MODEL_NAME%.rb'), # (new style)
114
- File.join(root_directory, FABRICATORS_TEST_DIR, '%MODEL_NAME%_fabricator.rb'),
115
- File.join(root_directory, FABRICATORS_SPEC_DIR, '%MODEL_NAME%_fabricator.rb')
116
- ]
117
- end
118
-
119
- def serialize_files(root_directory)
120
- [
121
- File.join(root_directory, SERIALIZERS_DIR, '%MODEL_NAME%_serializer.rb'),
122
- File.join(root_directory, SERIALIZERS_TEST_DIR, '%MODEL_NAME%_serializer_test.rb'),
123
- File.join(root_directory, SERIALIZERS_SPEC_DIR, '%MODEL_NAME%_serializer_spec.rb')
124
- ]
125
- end
126
- end
127
- end
128
- end
129
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnnotateRb
4
- module ModelAnnotator
5
- class ForeignKeyAnnotationBuilder
6
- def initialize(model, options)
7
- @model = model
8
- @options = options
9
- end
10
-
11
- def build
12
- fk_info = if @options[:format_markdown]
13
- "#\n# ### Foreign Keys\n#\n"
14
- else
15
- "#\n# Foreign Keys\n#\n"
16
- end
17
-
18
- return '' unless @model.connection.respond_to?(:supports_foreign_keys?) &&
19
- @model.connection.supports_foreign_keys? && @model.connection.respond_to?(:foreign_keys)
20
-
21
- foreign_keys = @model.connection.foreign_keys(@model.table_name)
22
- return '' if foreign_keys.empty?
23
-
24
- format_name = lambda do |fk|
25
- return fk.options[:column] if fk.name.blank?
26
-
27
- @options[:show_complete_foreign_keys] ? fk.name : fk.name.gsub(/(?<=^fk_rails_)[0-9a-f]{10}$/, '...')
28
- end
29
-
30
- max_size = foreign_keys.map(&format_name).map(&:size).max + 1
31
- foreign_keys.sort_by { |fk| [format_name.call(fk), fk.column] }.each do |fk|
32
- ref_info = "#{fk.column} => #{fk.to_table}.#{fk.primary_key}"
33
- constraints_info = ''
34
- constraints_info += "ON DELETE => #{fk.on_delete} " if fk.on_delete
35
- constraints_info += "ON UPDATE => #{fk.on_update} " if fk.on_update
36
- constraints_info = constraints_info.strip
37
-
38
- fk_info += if @options[:format_markdown]
39
- format("# * `%s`%s:\n# * **`%s`**\n",
40
- format_name.call(fk),
41
- constraints_info.blank? ? '' : " (_#{constraints_info}_)",
42
- ref_info)
43
- else
44
- format("# %-#{max_size}.#{max_size}s %s %s",
45
- format_name.call(fk),
46
- "(#{ref_info})",
47
- constraints_info).rstrip + "\n"
48
- end
49
- end
50
-
51
- fk_info
52
- end
53
- end
54
- end
55
- end
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnnotateRb
4
- module ModelAnnotator
5
- module Helper
6
- INDEX_CLAUSES = {
7
- unique: {
8
- default: 'UNIQUE',
9
- markdown: '_unique_'
10
- },
11
- where: {
12
- default: 'WHERE',
13
- markdown: '_where_'
14
- },
15
- using: {
16
- default: 'USING',
17
- markdown: '_using_'
18
- }
19
- }.freeze
20
-
21
- class << self
22
- def mb_chars_ljust(string, length)
23
- string = string.to_s
24
- padding = length - Helper.width(string)
25
- if padding.positive?
26
- string + (' ' * padding)
27
- else
28
- string[0..(length - 1)]
29
- end
30
- end
31
-
32
- def index_unique_info(index, format = :default)
33
- index.unique ? " #{INDEX_CLAUSES[:unique][format]}" : ''
34
- end
35
-
36
- def index_where_info(index, format = :default)
37
- value = index.try(:where).try(:to_s)
38
- if value.blank?
39
- ''
40
- else
41
- " #{INDEX_CLAUSES[:where][format]} #{value}"
42
- end
43
- end
44
-
45
- def index_using_info(index, format = :default)
46
- value = index.try(:using) && index.using.try(:to_sym)
47
- if !value.blank? && value != :btree
48
- " #{INDEX_CLAUSES[:using][format]} #{value}"
49
- else
50
- ''
51
- end
52
- end
53
-
54
- def map_col_type_to_ruby_classes(col_type)
55
- case col_type
56
- when 'integer' then Integer.to_s
57
- when 'float' then Float.to_s
58
- when 'decimal' then BigDecimal.to_s
59
- when 'datetime', 'timestamp', 'time' then Time.to_s
60
- when 'date' then Date.to_s
61
- when 'text', 'string', 'binary', 'inet', 'uuid' then String.to_s
62
- when 'json', 'jsonb' then Hash.to_s
63
- when 'boolean' then 'Boolean'
64
- end
65
- end
66
-
67
- def non_ascii_length(string)
68
- string.to_s.chars.reject(&:ascii_only?).length
69
- end
70
-
71
- # Simple quoting for the default column value
72
- def quote(value)
73
- case value
74
- when NilClass then 'NULL'
75
- when TrueClass then 'TRUE'
76
- when FalseClass then 'FALSE'
77
- when Float, Integer then value.to_s
78
- # BigDecimals need to be output in a non-normalized form and quoted.
79
- when BigDecimal then value.to_s('F')
80
- when Array then value.map { |v| quote(v) }
81
- else
82
- value.inspect
83
- end
84
- end
85
-
86
- def width(string)
87
- string.chars.inject(0) { |acc, elem| acc + (elem.bytesize == 3 ? 2 : 1) }
88
- end
89
-
90
- def magic_comments_as_string(content)
91
- magic_comments = content.scan(Constants::MAGIC_COMMENT_MATCHER).flatten.compact
92
-
93
- if magic_comments.any?
94
- magic_comments.join
95
- else
96
- ''
97
- end
98
- end
99
-
100
- # TODO: Find another implementation that doesn't depend on ActiveSupport
101
- def fallback(*args)
102
- args.compact.detect(&:present?)
103
- end
104
- end
105
- end
106
- end
107
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnnotateRb
4
- module ModelAnnotator
5
- class IndexAnnotationBuilder
6
- def initialize(model, options)
7
- @model = model
8
- @options = options
9
- end
10
-
11
- def build
12
- index_info = if @options[:format_markdown]
13
- "#\n# ### Indexes\n#\n"
14
- else
15
- "#\n# Indexes\n#\n"
16
- end
17
-
18
- indexes = @model.retrieve_indexes_from_table
19
- return '' if indexes.empty?
20
-
21
- max_size = indexes.collect { |index| index.name.size }.max + 1
22
- indexes.sort_by(&:name).each do |index|
23
- index_info += if @options[:format_markdown]
24
- final_index_string_in_markdown(index)
25
- else
26
- final_index_string(index, max_size)
27
- end
28
- end
29
-
30
- index_info
31
- end
32
-
33
- private
34
-
35
- def final_index_string_in_markdown(index)
36
- details = format(
37
- '%s%s%s',
38
- Helper.index_unique_info(index, :markdown),
39
- Helper.index_where_info(index, :markdown),
40
- Helper.index_using_info(index, :markdown)
41
- ).strip
42
- details = " (#{details})" unless details.blank?
43
-
44
- format(
45
- "# * `%s`%s:\n# * **`%s`**\n",
46
- index.name,
47
- details,
48
- index_columns_info(index).join("`**\n# * **`")
49
- )
50
- end
51
-
52
- def final_index_string(index, max_size)
53
- format(
54
- "# %-#{max_size}.#{max_size}s %s%s%s%s",
55
- index.name,
56
- "(#{index_columns_info(index).join(',')})",
57
- Helper.index_unique_info(index),
58
- Helper.index_where_info(index),
59
- Helper.index_using_info(index)
60
- ).rstrip + "\n"
61
- end
62
-
63
- def index_columns_info(index)
64
- Array(index.columns).map do |col|
65
- if index.try(:orders) && index.orders[col.to_s]
66
- "#{col} #{index.orders[col.to_s].upcase}"
67
- else
68
- col.to_s.gsub("\r", '\r').gsub("\n", '\n')
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnnotateRb
4
- module ModelAnnotator
5
- # Annotates a model file and its related files (controllers, factories, etc)
6
- class ModelFileAnnotator
7
- class << self
8
- def call(annotated, file, options)
9
- begin
10
- klass = ModelClassGetter.call(file, options)
11
-
12
- instructions = build_instructions(klass, file, options)
13
- instructions.each do |instruction|
14
- if FileAnnotator.call_with_instructions(instruction)
15
- annotated << instruction.file
16
- end
17
- end
18
-
19
- annotated
20
- rescue BadModelFileError => e
21
- unless options[:ignore_unknown_models]
22
- $stderr.puts "Unable to annotate #{file}: #{e.message}"
23
- $stderr.puts "\t" + e.backtrace.join("\n\t") if options[:trace]
24
- end
25
- rescue StandardError => e
26
- $stderr.puts "Unable to annotate #{file}: #{e.message}"
27
- $stderr.puts "\t" + e.backtrace.join("\n\t") if options[:trace]
28
- end
29
- end
30
-
31
- private
32
-
33
- def build_instructions(klass, file, options = {})
34
- instructions = []
35
-
36
- klass.reset_column_information
37
- annotation = AnnotationGenerator.new(klass, options).generate
38
- model_name = klass.name.underscore
39
- table_name = klass.table_name
40
-
41
- model_instruction = FileAnnotatorInstruction.new(file, annotation, :position_in_class, options)
42
- instructions << model_instruction
43
-
44
- related_files = RelatedFilesListBuilder.new(file, model_name, table_name, options).build
45
- related_file_instructions = related_files.map do |f, position_key|
46
- _instruction = FileAnnotatorInstruction.new(f, annotation, position_key, options)
47
- end
48
- instructions.concat(related_file_instructions)
49
-
50
- instructions
51
- end
52
- end
53
- end
54
- end
55
- end