annotaterb 4.1.1 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +68 -0
- data/VERSION +1 -1
- data/exe/annotaterb +7 -7
- data/lib/annotate_rb/active_record_patch.rb +2 -0
- data/lib/annotate_rb/commands/annotate_models.rb +0 -1
- data/lib/annotate_rb/commands/annotate_routes.rb +0 -1
- data/lib/annotate_rb/commands/print_help.rb +0 -1
- data/lib/annotate_rb/commands/print_version.rb +0 -1
- data/lib/annotate_rb/commands.rb +4 -4
- data/lib/annotate_rb/config_finder.rb +1 -1
- data/lib/annotate_rb/config_loader.rb +2 -2
- data/lib/annotate_rb/core.rb +3 -3
- data/lib/annotate_rb/helper.rb +16 -0
- data/lib/annotate_rb/model_annotator/{annotation_generator.rb → annotation_builder.rb} +18 -14
- data/lib/annotate_rb/model_annotator/annotation_decider.rb +10 -12
- data/lib/annotate_rb/model_annotator/annotation_diff.rb +1 -1
- data/lib/annotate_rb/model_annotator/annotation_diff_generator.rb +9 -9
- data/lib/annotate_rb/model_annotator/annotation_pattern_generator.rb +3 -3
- data/lib/annotate_rb/model_annotator/annotator.rb +12 -53
- data/lib/annotate_rb/model_annotator/column_annotation/annotation_builder.rb +135 -0
- data/lib/annotate_rb/model_annotator/column_annotation/attributes_builder.rb +104 -0
- data/lib/annotate_rb/model_annotator/column_annotation/column_wrapper.rb +103 -0
- data/lib/annotate_rb/model_annotator/column_annotation/type_builder.rb +54 -0
- data/lib/annotate_rb/model_annotator/column_annotation.rb +12 -0
- data/lib/annotate_rb/model_annotator/file_builder.rb +58 -0
- data/lib/annotate_rb/model_annotator/file_components.rb +78 -0
- data/lib/annotate_rb/model_annotator/file_name_resolver.rb +3 -3
- data/lib/annotate_rb/model_annotator/foreign_key_annotation/annotation_builder.rb +57 -0
- data/lib/annotate_rb/model_annotator/foreign_key_annotation.rb +9 -0
- data/lib/annotate_rb/model_annotator/index_annotation/annotation_builder.rb +113 -0
- data/lib/annotate_rb/model_annotator/index_annotation.rb +9 -0
- data/lib/annotate_rb/model_annotator/magic_comment_parser.rb +32 -0
- data/lib/annotate_rb/model_annotator/model_class_getter.rb +6 -6
- data/lib/annotate_rb/model_annotator/model_files_getter.rb +12 -10
- data/lib/annotate_rb/model_annotator/model_wrapper.rb +44 -37
- data/lib/annotate_rb/model_annotator/pattern_getter.rb +142 -10
- data/lib/annotate_rb/model_annotator/project_annotation_remover.rb +65 -0
- data/lib/annotate_rb/model_annotator/project_annotator.rb +63 -0
- data/lib/annotate_rb/model_annotator/related_files_list_builder.rb +16 -18
- data/lib/annotate_rb/model_annotator/single_file_annotation_remover.rb +37 -0
- data/lib/annotate_rb/model_annotator/single_file_annotator.rb +49 -0
- data/lib/annotate_rb/model_annotator/{file_annotator_instruction.rb → single_file_annotator_instruction.rb} +2 -2
- data/lib/annotate_rb/model_annotator/single_file_remove_annotation_instruction.rb +15 -0
- data/lib/annotate_rb/model_annotator.rb +25 -26
- data/lib/annotate_rb/options.rb +20 -25
- data/lib/annotate_rb/parser.rb +150 -142
- data/lib/annotate_rb/rake_bootstrapper.rb +8 -8
- data/lib/annotate_rb/route_annotator/annotation_processor.rb +7 -8
- data/lib/annotate_rb/route_annotator/annotator.rb +2 -2
- data/lib/annotate_rb/route_annotator/base_processor.rb +3 -3
- data/lib/annotate_rb/route_annotator/header_generator.rb +15 -15
- data/lib/annotate_rb/route_annotator/helper.rb +9 -9
- data/lib/annotate_rb/route_annotator/removal_processor.rb +4 -4
- data/lib/annotate_rb/route_annotator.rb +6 -6
- data/lib/annotate_rb/runner.rb +0 -4
- data/lib/annotate_rb/tasks/annotate_models_migrate.rake +5 -5
- data/lib/annotate_rb.rb +19 -19
- data/lib/generators/annotate_rb/install/install_generator.rb +3 -2
- data/lib/generators/annotate_rb/install/templates/annotate_rb.rake +1 -1
- metadata +22 -16
- data/lib/annotate_rb/model_annotator/column_annotation_builder.rb +0 -92
- data/lib/annotate_rb/model_annotator/column_attributes_builder.rb +0 -102
- data/lib/annotate_rb/model_annotator/column_type_builder.rb +0 -51
- data/lib/annotate_rb/model_annotator/column_wrapper.rb +0 -84
- data/lib/annotate_rb/model_annotator/constants.rb +0 -22
- data/lib/annotate_rb/model_annotator/file_annotation_remover.rb +0 -25
- data/lib/annotate_rb/model_annotator/file_annotator.rb +0 -77
- data/lib/annotate_rb/model_annotator/file_patterns.rb +0 -129
- data/lib/annotate_rb/model_annotator/foreign_key_annotation_builder.rb +0 -55
- data/lib/annotate_rb/model_annotator/helper.rb +0 -107
- data/lib/annotate_rb/model_annotator/index_annotation_builder.rb +0 -74
- data/lib/annotate_rb/model_annotator/model_file_annotator.rb +0 -55
@@ -1,9 +1,9 @@
|
|
1
1
|
module AnnotateRb
|
2
2
|
module RouteAnnotator
|
3
3
|
class HeaderGenerator
|
4
|
-
PREFIX =
|
5
|
-
PREFIX_MD =
|
6
|
-
HEADER_ROW = [
|
4
|
+
PREFIX = "== Route Map".freeze
|
5
|
+
PREFIX_MD = "## Route Map".freeze
|
6
|
+
HEADER_ROW = ["Prefix", "Verb", "URI Pattern", "Controller#Action"].freeze
|
7
7
|
|
8
8
|
class << self
|
9
9
|
def generate(options = {})
|
@@ -20,7 +20,7 @@ module AnnotateRb
|
|
20
20
|
# In old versions of Rake, the first line of output was the cwd. Not so
|
21
21
|
# much in newer ones. We ditch that line if it exists, and if not, we
|
22
22
|
# keep the line around.
|
23
|
-
result.shift if
|
23
|
+
result.shift if %r{^\(in /}.match?(result.first)
|
24
24
|
|
25
25
|
ignore_routes = options[:ignore_routes]
|
26
26
|
regexp_for_ignoring_routes = ignore_routes ? /#{ignore_routes}/ : nil
|
@@ -48,7 +48,7 @@ module AnnotateRb
|
|
48
48
|
magic_comments_map.each do |magic_comment|
|
49
49
|
out << magic_comment
|
50
50
|
end
|
51
|
-
out <<
|
51
|
+
out << "" if magic_comments_map.any?
|
52
52
|
|
53
53
|
out << comment(options[:wrapper_open]) if options[:wrapper_open]
|
54
54
|
|
@@ -62,12 +62,12 @@ module AnnotateRb
|
|
62
62
|
max = maxs.map(&:max).compact.max
|
63
63
|
|
64
64
|
out << comment(content(HEADER_ROW, maxs))
|
65
|
-
out << comment(content([
|
65
|
+
out << comment(content(["-" * max, "-" * max, "-" * max, "-" * max], maxs))
|
66
66
|
else
|
67
67
|
out << comment(content(contents_without_magic_comments[0], maxs))
|
68
68
|
end
|
69
69
|
|
70
|
-
out += contents_without_magic_comments[1..-1].map { |line| comment(content(markdown? ? line.split(
|
70
|
+
out += contents_without_magic_comments[1..-1].map { |line| comment(content(markdown? ? line.split(" ") : line, maxs)) }
|
71
71
|
out << comment(options[:wrapper_close]) if options[:wrapper_close]
|
72
72
|
|
73
73
|
out
|
@@ -77,9 +77,9 @@ module AnnotateRb
|
|
77
77
|
|
78
78
|
attr_reader :options, :routes_map
|
79
79
|
|
80
|
-
def comment(row =
|
81
|
-
if row ==
|
82
|
-
|
80
|
+
def comment(row = "")
|
81
|
+
if row == ""
|
82
|
+
"#"
|
83
83
|
else
|
84
84
|
"# #{row}"
|
85
85
|
end
|
@@ -88,12 +88,12 @@ module AnnotateRb
|
|
88
88
|
def content(line, maxs)
|
89
89
|
return line.rstrip unless markdown?
|
90
90
|
|
91
|
-
line.each_with_index.map { |elem, index| format_line_element(elem, maxs, index) }.join(
|
91
|
+
line.each_with_index.map { |elem, index| format_line_element(elem, maxs, index) }.join(" | ")
|
92
92
|
end
|
93
93
|
|
94
94
|
def format_line_element(elem, maxs, index)
|
95
95
|
min_length = maxs.map { |arr| arr[index] }.max || 0
|
96
|
-
format("%-#{min_length}.#{min_length}s", elem.tr(
|
96
|
+
format("%-#{min_length}.#{min_length}s", elem.tr("|", "-"))
|
97
97
|
end
|
98
98
|
|
99
99
|
def markdown?
|
@@ -102,12 +102,12 @@ module AnnotateRb
|
|
102
102
|
|
103
103
|
def timestamp_if_required(time = Time.now)
|
104
104
|
if options[:timestamp]
|
105
|
-
time_formatted = time.strftime(
|
105
|
+
time_formatted = time.strftime("%Y-%m-%d %H:%M")
|
106
106
|
" (Updated #{time_formatted})"
|
107
107
|
else
|
108
|
-
|
108
|
+
""
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
113
|
-
end
|
113
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module AnnotateRb
|
4
4
|
module RouteAnnotator
|
5
5
|
module Helper
|
6
|
-
MAGIC_COMMENT_MATCHER =
|
6
|
+
MAGIC_COMMENT_MATCHER = /(^#\s*encoding:.*)|(^# coding:.*)|(^# -\*- coding:.*)|(^# -\*- encoding\s?:.*)|(^#\s*frozen_string_literal:.+)|(^# -\*- frozen_string_literal\s*:.+-\*-)/.freeze
|
7
7
|
|
8
8
|
class << self
|
9
9
|
def routes_file_exist?
|
@@ -11,18 +11,18 @@ module AnnotateRb
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def routes_file
|
14
|
-
@routes_rb ||= File.join(
|
14
|
+
@routes_rb ||= File.join("config", "routes.rb")
|
15
15
|
end
|
16
16
|
|
17
17
|
def strip_on_removal(content, header_position)
|
18
18
|
if header_position == :before
|
19
|
-
content.shift while content.first ==
|
19
|
+
content.shift while content.first == ""
|
20
20
|
elsif header_position == :after
|
21
|
-
content.pop while content.last ==
|
21
|
+
content.pop while content.last == ""
|
22
22
|
end
|
23
23
|
|
24
24
|
# Make sure we end on a trailing newline.
|
25
|
-
content <<
|
25
|
+
content << "" unless content.last == ""
|
26
26
|
|
27
27
|
# TODO: If the user buried it in the middle, we should probably see about
|
28
28
|
# TODO: preserving a single line of space between the content above and
|
@@ -34,7 +34,7 @@ module AnnotateRb
|
|
34
34
|
if existing_text == new_text
|
35
35
|
false
|
36
36
|
else
|
37
|
-
File.open(routes_file,
|
37
|
+
File.open(routes_file, "wb") { |f| f.puts(new_text) }
|
38
38
|
true
|
39
39
|
end
|
40
40
|
end
|
@@ -47,7 +47,7 @@ module AnnotateRb
|
|
47
47
|
new_content = []
|
48
48
|
|
49
49
|
content_array.each do |row|
|
50
|
-
if row
|
50
|
+
if MAGIC_COMMENT_MATCHER.match?(row)
|
51
51
|
magic_comments << row.strip
|
52
52
|
else
|
53
53
|
new_content << row
|
@@ -74,7 +74,7 @@ module AnnotateRb
|
|
74
74
|
mode = :content
|
75
75
|
real_content << line unless line.blank?
|
76
76
|
elsif mode == :content
|
77
|
-
if
|
77
|
+
if /^\s*#\s*== Route.*$/.match?(line)
|
78
78
|
header_position = line_number + 1 # index start's at 0
|
79
79
|
mode = :header
|
80
80
|
else
|
@@ -96,7 +96,7 @@ module AnnotateRb
|
|
96
96
|
return real_content, :after if header_position >= real_content.count
|
97
97
|
|
98
98
|
# and the default
|
99
|
-
|
99
|
+
[real_content, header_position]
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
@@ -22,13 +22,13 @@ module AnnotateRb
|
|
22
22
|
|
23
23
|
def generate_new_content_array(content, header_position)
|
24
24
|
if header_position == :before
|
25
|
-
content.shift while content.first ==
|
25
|
+
content.shift while content.first == ""
|
26
26
|
elsif header_position == :after
|
27
|
-
content.pop while content.last ==
|
27
|
+
content.pop while content.last == ""
|
28
28
|
end
|
29
29
|
|
30
30
|
# Make sure we end on a trailing newline.
|
31
|
-
content <<
|
31
|
+
content << "" unless content.last == ""
|
32
32
|
|
33
33
|
# TODO: If the user buried it in the middle, we should probably see about
|
34
34
|
# TODO: preserving a single line of space between the content above and
|
@@ -37,4 +37,4 @@ module AnnotateRb
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
|
-
end
|
40
|
+
end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module AnnotateRb
|
4
4
|
module RouteAnnotator
|
5
|
-
autoload :Annotator,
|
6
|
-
autoload :Helper,
|
7
|
-
autoload :HeaderGenerator,
|
8
|
-
autoload :BaseProcessor,
|
9
|
-
autoload :AnnotationProcessor,
|
10
|
-
autoload :RemovalProcessor,
|
5
|
+
autoload :Annotator, "annotate_rb/route_annotator/annotator"
|
6
|
+
autoload :Helper, "annotate_rb/route_annotator/helper"
|
7
|
+
autoload :HeaderGenerator, "annotate_rb/route_annotator/header_generator"
|
8
|
+
autoload :BaseProcessor, "annotate_rb/route_annotator/base_processor"
|
9
|
+
autoload :AnnotationProcessor, "annotate_rb/route_annotator/annotation_processor"
|
10
|
+
autoload :RemovalProcessor, "annotate_rb/route_annotator/removal_processor"
|
11
11
|
end
|
12
12
|
end
|
data/lib/annotate_rb/runner.rb
CHANGED
@@ -5,15 +5,15 @@
|
|
5
5
|
# run after doing db:migrate.
|
6
6
|
|
7
7
|
# Migration tasks are tasks that we'll "hook" into
|
8
|
-
migration_tasks = %w
|
9
|
-
if defined?(Rails::Application) && Rails.version.split(
|
10
|
-
require
|
8
|
+
migration_tasks = %w[db:migrate db:migrate:up db:migrate:down db:migrate:reset db:migrate:redo db:rollback]
|
9
|
+
if defined?(Rails::Application) && Rails.version.split(".").first.to_i >= 6
|
10
|
+
require "active_record"
|
11
11
|
|
12
12
|
databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
|
13
13
|
|
14
14
|
# If there's multiple databases, this appends database specific rake tasks to `migration_tasks`
|
15
15
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |database_name|
|
16
|
-
migration_tasks.concat(%w
|
16
|
+
migration_tasks.concat(%w[db:migrate db:migrate:up db:migrate:down].map { |task| "#{task}:#{database_name}" })
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -24,7 +24,7 @@ migration_tasks.each do |task|
|
|
24
24
|
task_name = Rake.application.top_level_tasks.last # The name of the task that was run, e.g. "db:migrate"
|
25
25
|
|
26
26
|
Rake::Task[task_name].enhance do
|
27
|
-
::AnnotateRb::Runner.run([
|
27
|
+
::AnnotateRb::Runner.run(["models"])
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
data/lib/annotate_rb.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "active_record"
|
4
|
+
require "active_support"
|
5
5
|
|
6
6
|
# Helper.fallback depends on this being required because it adds #present? to nil
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
7
|
+
require "active_support/core_ext/object/blank"
|
8
|
+
require "active_support/core_ext/class/subclasses"
|
9
|
+
require "active_support/core_ext/string/inflections"
|
10
10
|
|
11
|
-
require
|
11
|
+
require "rake"
|
12
12
|
|
13
|
-
require
|
13
|
+
require "annotate_rb/active_record_patch"
|
14
14
|
|
15
|
-
require_relative
|
16
|
-
require_relative
|
17
|
-
require_relative
|
18
|
-
require_relative
|
19
|
-
require_relative
|
20
|
-
require_relative
|
21
|
-
require_relative
|
22
|
-
require_relative
|
23
|
-
require_relative
|
24
|
-
require_relative
|
25
|
-
require_relative
|
15
|
+
require_relative "annotate_rb/helper"
|
16
|
+
require_relative "annotate_rb/core"
|
17
|
+
require_relative "annotate_rb/commands"
|
18
|
+
require_relative "annotate_rb/parser"
|
19
|
+
require_relative "annotate_rb/runner"
|
20
|
+
require_relative "annotate_rb/route_annotator"
|
21
|
+
require_relative "annotate_rb/model_annotator"
|
22
|
+
require_relative "annotate_rb/options"
|
23
|
+
require_relative "annotate_rb/eager_loader"
|
24
|
+
require_relative "annotate_rb/rake_bootstrapper"
|
25
|
+
require_relative "annotate_rb/config_finder"
|
26
|
+
require_relative "annotate_rb/config_loader"
|
26
27
|
|
27
28
|
module AnnotateRb
|
28
|
-
|
29
29
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "annotate_rb"
|
3
4
|
|
4
5
|
module AnnotateRb
|
5
6
|
module Generators
|
6
7
|
class InstallGenerator < ::Rails::Generators::Base
|
7
|
-
source_root File.expand_path(
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
8
9
|
|
9
10
|
def copy_task
|
10
11
|
copy_file "annotate_rb.rake", "lib/tasks/annotate_rb.rake"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: annotaterb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew W. Lee
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Annotates Rails/ActiveRecord Models, routes, fixtures, and others based
|
14
14
|
on the database schema.
|
@@ -35,33 +35,39 @@ files:
|
|
35
35
|
- lib/annotate_rb/config_loader.rb
|
36
36
|
- lib/annotate_rb/core.rb
|
37
37
|
- lib/annotate_rb/eager_loader.rb
|
38
|
+
- lib/annotate_rb/helper.rb
|
38
39
|
- lib/annotate_rb/model_annotator.rb
|
40
|
+
- lib/annotate_rb/model_annotator/annotation_builder.rb
|
39
41
|
- lib/annotate_rb/model_annotator/annotation_decider.rb
|
40
42
|
- lib/annotate_rb/model_annotator/annotation_diff.rb
|
41
43
|
- lib/annotate_rb/model_annotator/annotation_diff_generator.rb
|
42
|
-
- lib/annotate_rb/model_annotator/annotation_generator.rb
|
43
44
|
- lib/annotate_rb/model_annotator/annotation_pattern_generator.rb
|
44
45
|
- lib/annotate_rb/model_annotator/annotator.rb
|
45
46
|
- lib/annotate_rb/model_annotator/bad_model_file_error.rb
|
46
|
-
- lib/annotate_rb/model_annotator/
|
47
|
-
- lib/annotate_rb/model_annotator/
|
48
|
-
- lib/annotate_rb/model_annotator/
|
49
|
-
- lib/annotate_rb/model_annotator/column_wrapper.rb
|
50
|
-
- lib/annotate_rb/model_annotator/
|
51
|
-
- lib/annotate_rb/model_annotator/
|
52
|
-
- lib/annotate_rb/model_annotator/
|
53
|
-
- lib/annotate_rb/model_annotator/file_annotator_instruction.rb
|
47
|
+
- lib/annotate_rb/model_annotator/column_annotation.rb
|
48
|
+
- lib/annotate_rb/model_annotator/column_annotation/annotation_builder.rb
|
49
|
+
- lib/annotate_rb/model_annotator/column_annotation/attributes_builder.rb
|
50
|
+
- lib/annotate_rb/model_annotator/column_annotation/column_wrapper.rb
|
51
|
+
- lib/annotate_rb/model_annotator/column_annotation/type_builder.rb
|
52
|
+
- lib/annotate_rb/model_annotator/file_builder.rb
|
53
|
+
- lib/annotate_rb/model_annotator/file_components.rb
|
54
54
|
- lib/annotate_rb/model_annotator/file_name_resolver.rb
|
55
|
-
- lib/annotate_rb/model_annotator/
|
56
|
-
- lib/annotate_rb/model_annotator/
|
57
|
-
- lib/annotate_rb/model_annotator/
|
58
|
-
- lib/annotate_rb/model_annotator/
|
55
|
+
- lib/annotate_rb/model_annotator/foreign_key_annotation.rb
|
56
|
+
- lib/annotate_rb/model_annotator/foreign_key_annotation/annotation_builder.rb
|
57
|
+
- lib/annotate_rb/model_annotator/index_annotation.rb
|
58
|
+
- lib/annotate_rb/model_annotator/index_annotation/annotation_builder.rb
|
59
|
+
- lib/annotate_rb/model_annotator/magic_comment_parser.rb
|
59
60
|
- lib/annotate_rb/model_annotator/model_class_getter.rb
|
60
|
-
- lib/annotate_rb/model_annotator/model_file_annotator.rb
|
61
61
|
- lib/annotate_rb/model_annotator/model_files_getter.rb
|
62
62
|
- lib/annotate_rb/model_annotator/model_wrapper.rb
|
63
63
|
- lib/annotate_rb/model_annotator/pattern_getter.rb
|
64
|
+
- lib/annotate_rb/model_annotator/project_annotation_remover.rb
|
65
|
+
- lib/annotate_rb/model_annotator/project_annotator.rb
|
64
66
|
- lib/annotate_rb/model_annotator/related_files_list_builder.rb
|
67
|
+
- lib/annotate_rb/model_annotator/single_file_annotation_remover.rb
|
68
|
+
- lib/annotate_rb/model_annotator/single_file_annotator.rb
|
69
|
+
- lib/annotate_rb/model_annotator/single_file_annotator_instruction.rb
|
70
|
+
- lib/annotate_rb/model_annotator/single_file_remove_annotation_instruction.rb
|
65
71
|
- lib/annotate_rb/options.rb
|
66
72
|
- lib/annotate_rb/parser.rb
|
67
73
|
- lib/annotate_rb/rake_bootstrapper.rb
|
@@ -1,92 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AnnotateRb
|
4
|
-
module ModelAnnotator
|
5
|
-
class ColumnAnnotationBuilder
|
6
|
-
BARE_TYPE_ALLOWANCE = 16
|
7
|
-
MD_TYPE_ALLOWANCE = 18
|
8
|
-
|
9
|
-
def initialize(column, model, max_size, options)
|
10
|
-
@column = column
|
11
|
-
@model = model
|
12
|
-
@max_size = max_size
|
13
|
-
@options = options
|
14
|
-
end
|
15
|
-
|
16
|
-
def build
|
17
|
-
result = ''
|
18
|
-
|
19
|
-
is_primary_key = is_column_primary_key?(@model, @column.name)
|
20
|
-
|
21
|
-
table_indices = @model.retrieve_indexes_from_table
|
22
|
-
column_indices = table_indices.select { |ind| ind.columns.include?(@column.name) }
|
23
|
-
|
24
|
-
column_attributes = ColumnAttributesBuilder.new(@column, @options, is_primary_key, column_indices).build
|
25
|
-
formatted_column_type = ColumnTypeBuilder.new(@column, @options).build
|
26
|
-
|
27
|
-
col_name = if @model.with_comments? && @column.comment
|
28
|
-
"#{@column.name}(#{@column.comment.gsub(/\n/, '\\n')})"
|
29
|
-
else
|
30
|
-
@column.name
|
31
|
-
end
|
32
|
-
|
33
|
-
if @options[:format_rdoc]
|
34
|
-
result += format("# %-#{@max_size}.#{@max_size}s<tt>%s</tt>",
|
35
|
-
"*#{col_name}*::",
|
36
|
-
column_attributes.unshift(formatted_column_type).join(', ')).rstrip + "\n"
|
37
|
-
elsif @options[:format_yard]
|
38
|
-
result += sprintf("# @!attribute #{col_name}") + "\n"
|
39
|
-
|
40
|
-
if @column.respond_to?(:array) && @column.array
|
41
|
-
ruby_class = "Array<#{Helper.map_col_type_to_ruby_classes(formatted_column_type)}>"
|
42
|
-
else
|
43
|
-
ruby_class = Helper.map_col_type_to_ruby_classes(formatted_column_type)
|
44
|
-
end
|
45
|
-
|
46
|
-
result += sprintf("# @return [#{ruby_class}]") + "\n"
|
47
|
-
elsif @options[:format_markdown]
|
48
|
-
name_remainder = @max_size - col_name.length - Helper.non_ascii_length(col_name)
|
49
|
-
type_remainder = (MD_TYPE_ALLOWANCE - 2) - formatted_column_type.length
|
50
|
-
result += format("# **`%s`**%#{name_remainder}s | `%s`%#{type_remainder}s | `%s`",
|
51
|
-
col_name,
|
52
|
-
' ',
|
53
|
-
formatted_column_type,
|
54
|
-
' ',
|
55
|
-
column_attributes.join(', ').rstrip).gsub('``', ' ').rstrip + "\n"
|
56
|
-
else
|
57
|
-
result += format_default(col_name, @max_size, formatted_column_type, column_attributes)
|
58
|
-
end
|
59
|
-
|
60
|
-
result
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def format_default(col_name, max_size, col_type, attrs)
|
66
|
-
format('# %s:%s %s',
|
67
|
-
Helper.mb_chars_ljust(col_name, max_size),
|
68
|
-
Helper.mb_chars_ljust(col_type, BARE_TYPE_ALLOWANCE),
|
69
|
-
attrs.join(', ')).rstrip + "\n"
|
70
|
-
end
|
71
|
-
|
72
|
-
# TODO: Simplify this conditional
|
73
|
-
def is_column_primary_key?(model, column_name)
|
74
|
-
if model.primary_key
|
75
|
-
if model.primary_key.is_a?(Array)
|
76
|
-
# If the model has multiple primary keys, check if this column is one of them
|
77
|
-
if model.primary_key.collect(&:to_sym).include?(column_name.to_sym)
|
78
|
-
return true
|
79
|
-
end
|
80
|
-
else
|
81
|
-
# If model has 1 primary key, check if this column is it
|
82
|
-
if column_name.to_sym == model.primary_key.to_sym
|
83
|
-
return true
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
false
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AnnotateRb
|
4
|
-
module ModelAnnotator
|
5
|
-
class ColumnAttributesBuilder
|
6
|
-
# Don't show default value for these column types
|
7
|
-
NO_DEFAULT_COL_TYPES = %w[json jsonb hstore].freeze
|
8
|
-
|
9
|
-
def initialize(column, options, is_primary_key, column_indices)
|
10
|
-
@column = ColumnWrapper.new(column)
|
11
|
-
@options = options
|
12
|
-
@is_primary_key = is_primary_key
|
13
|
-
@column_indices = column_indices
|
14
|
-
end
|
15
|
-
|
16
|
-
# Get the list of attributes that should be included in the annotation for
|
17
|
-
# a given column.
|
18
|
-
def build
|
19
|
-
column_type = @column.column_type_string
|
20
|
-
attrs = []
|
21
|
-
|
22
|
-
unless @column.default.nil? || hide_default?
|
23
|
-
schema_default = "default(#{@column.default_string})"
|
24
|
-
|
25
|
-
attrs << schema_default
|
26
|
-
end
|
27
|
-
|
28
|
-
if @column.unsigned?
|
29
|
-
attrs << 'unsigned'
|
30
|
-
end
|
31
|
-
|
32
|
-
if !@column.null
|
33
|
-
attrs << 'not null'
|
34
|
-
end
|
35
|
-
|
36
|
-
if @is_primary_key
|
37
|
-
attrs << 'primary key'
|
38
|
-
end
|
39
|
-
|
40
|
-
is_special_type = %w[spatial geometry geography].include?(column_type)
|
41
|
-
is_decimal_type = column_type == 'decimal'
|
42
|
-
|
43
|
-
if !is_decimal_type && !is_special_type
|
44
|
-
if @column.limit && !@options[:format_yard]
|
45
|
-
if @column.limit.is_a?(Array)
|
46
|
-
attrs << "(#{@column.limit.join(', ')})"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Check out if we got an array column
|
52
|
-
if @column.array?
|
53
|
-
attrs << 'is an Array'
|
54
|
-
end
|
55
|
-
|
56
|
-
# Check out if we got a geometric column
|
57
|
-
# and print the type and SRID
|
58
|
-
if @column.geometry_type?
|
59
|
-
attrs << "#{@column.geometry_type}, #{@column.srid}"
|
60
|
-
elsif @column.geometric_type? && @column.geometric_type.present?
|
61
|
-
attrs << "#{@column.geometric_type.to_s.downcase}, #{@column.srid}"
|
62
|
-
end
|
63
|
-
|
64
|
-
# Check if the column has indices and print "indexed" if true
|
65
|
-
# If the index includes another column, print it too.
|
66
|
-
if @options[:simple_indexes]
|
67
|
-
# Note: there used to be a klass.table_exists? call here, but removed it as it seemed unnecessary.
|
68
|
-
|
69
|
-
sorted_column_indices&.each do |index|
|
70
|
-
indexed_columns = index.columns.reject { |i| i == @column.name }
|
71
|
-
|
72
|
-
if indexed_columns.empty?
|
73
|
-
attrs << 'indexed'
|
74
|
-
else
|
75
|
-
attrs << "indexed => [#{indexed_columns.join(', ')}]"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
attrs
|
81
|
-
end
|
82
|
-
|
83
|
-
def sorted_column_indices
|
84
|
-
# Not sure why there were & safe accessors here, but keeping in for time being.
|
85
|
-
sorted_indices = @column_indices&.sort_by(&:name)
|
86
|
-
|
87
|
-
_sorted_indices = sorted_indices.reject { |ind| ind.columns.is_a?(String) }
|
88
|
-
end
|
89
|
-
|
90
|
-
def hide_default?
|
91
|
-
excludes =
|
92
|
-
if @options[:hide_default_column_types].blank?
|
93
|
-
NO_DEFAULT_COL_TYPES
|
94
|
-
else
|
95
|
-
@options[:hide_default_column_types].split(',')
|
96
|
-
end
|
97
|
-
|
98
|
-
excludes.include?(@column.column_type_string)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AnnotateRb
|
4
|
-
module ModelAnnotator
|
5
|
-
class ColumnTypeBuilder
|
6
|
-
# Don't show limit (#) on these column types
|
7
|
-
# Example: show "integer" instead of "integer(4)"
|
8
|
-
NO_LIMIT_COL_TYPES = %w[integer bigint boolean].freeze
|
9
|
-
|
10
|
-
def initialize(column, options)
|
11
|
-
@column = ColumnWrapper.new(column)
|
12
|
-
@options = options
|
13
|
-
end
|
14
|
-
|
15
|
-
# Returns the formatted column type as a string.
|
16
|
-
def build
|
17
|
-
column_type = @column.column_type_string
|
18
|
-
|
19
|
-
formatted_column_type = column_type
|
20
|
-
|
21
|
-
is_special_type = %w[spatial geometry geography].include?(column_type)
|
22
|
-
is_decimal_type = column_type == 'decimal'
|
23
|
-
|
24
|
-
if is_decimal_type
|
25
|
-
formatted_column_type = "decimal(#{@column.precision}, #{@column.scale})"
|
26
|
-
elsif is_special_type
|
27
|
-
# Do nothing. Kept as a code fragment in case we need to do something here.
|
28
|
-
else
|
29
|
-
if @column.limit && !@options[:format_yard]
|
30
|
-
if !@column.limit.is_a?(Array) && !hide_limit?
|
31
|
-
formatted_column_type = column_type + "(#{@column.limit})"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
formatted_column_type
|
37
|
-
end
|
38
|
-
|
39
|
-
def hide_limit?
|
40
|
-
excludes =
|
41
|
-
if @options[:hide_limit_column_types].blank?
|
42
|
-
NO_LIMIT_COL_TYPES
|
43
|
-
else
|
44
|
-
@options[:hide_limit_column_types].split(',')
|
45
|
-
end
|
46
|
-
|
47
|
-
excludes.include?(@column.column_type_string)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|