diff --git a/lib/annotate/annotate_models.rb b/lib/annotate/annotate_models.rb
index 1b9911ee3..53fa72fb2 100644
--- a/lib/annotate/annotate_models.rb
+++ b/lib/annotate/annotate_models.rb
@@ -138,7 +138,6 @@ def get_schema_info(klass, header, options = {})
max_size = max_schema_info_width(klass, options)
md_names_overhead = 6
md_type_allowance = 18
- bare_type_allowance = 16
if options[:format_markdown]
info << sprintf( "# %-#{max_size + md_names_overhead}.#{max_size + md_names_overhead}s | %-#{md_type_allowance}.#{md_type_allowance}s | %s\n", 'Name', 'Type', 'Attributes' )
@@ -149,24 +148,23 @@ def get_schema_info(klass, header, options = {})
cols.each do |col|
col_type = get_col_type(col)
attrs = get_attributes(col, col_type, klass, options)
- col_name = if with_comments?(klass, options) && col.comment
- "#{col.name}(#{col.comment.gsub(/\n/, "\\n")})"
- else
- col.name
- end
+ comment = if with_comments?(klass, options) && col.comment
+ col.comment.gsub(/\n/, "\\n")
+ end
+ commented_name = comment ? "#{col.name}(#{comment})" : col.name
if options[:format_rdoc]
- info << sprintf("# %-#{max_size}.#{max_size}s%s", "*#{col_name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n"
+ info << sprintf("# %-#{max_size}.#{max_size}s%s", "*#{commented_name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n"
elsif options[:format_yard]
- info << sprintf("# @!attribute #{col_name}") + "\n"
+ info << sprintf("# @!attribute #{commented_name}") + "\n"
ruby_class = col.respond_to?(:array) && col.array ? "Array<#{map_col_type_to_ruby_classes(col_type)}>": map_col_type_to_ruby_classes(col_type)
info << sprintf("# @return [#{ruby_class}]") + "\n"
elsif options[:format_markdown]
- name_remainder = max_size - col_name.length - non_ascii_length(col_name)
+ name_remainder = max_size - commented_name.length - non_ascii_length(commented_name)
type_remainder = (md_type_allowance - 2) - col_type.length
- info << (sprintf("# **`%s`**%#{name_remainder}s | `%s`%#{type_remainder}s | `%s`", col_name, " ", col_type, " ", attrs.join(", ").rstrip)).gsub('``', ' ').rstrip + "\n"
+ info << (sprintf("# **`%s`**%#{name_remainder}s | `%s`%#{type_remainder}s | `%s`", commented_name, " ", col_type, " ", attrs.join(", ").rstrip)).gsub('``', ' ').rstrip + "\n"
else
- info << format_default(col_name, max_size, col_type, bare_type_allowance, attrs)
+ info << format_default(col.name, max_size, col_type, comment, attrs)
end
end
@@ -765,7 +763,9 @@ def with_comments?(klass, options)
def max_schema_info_width(klass, options)
cols = columns(klass, options)
- if with_comments?(klass, options)
+ if with_comments?(klass, options) && [
+ :format_rdoc, :format_markdown, :format_yard
+ ].any? { |f| options[f] }
max_size = cols.map do |column|
column.name.size + (column.comment ? width(column.comment) : 0)
end.max || 0
@@ -778,8 +778,21 @@ def max_schema_info_width(klass, options)
max_size
end
- def format_default(col_name, max_size, col_type, bare_type_allowance, attrs)
- sprintf("# %s:%s %s", mb_chars_ljust(col_name, max_size), mb_chars_ljust(col_type, bare_type_allowance), attrs.join(", ")).rstrip + "\n"
+ def format_default(col_name, max_size, col_type, comment, attrs)
+ output = sprintf(
+ "# %s:%s %s",
+ mb_chars_ljust(col_name, max_size),
+ mb_chars_ljust(col_type, 16),
+ attrs.join(", ")
+ ).rstrip + "\n"
+ if comment
+ # Limit comment line length to 73 characters with padding
+ comment.scan(/.{1,73}(?: |$)/).each_with_index do |comment_part, idx|
+ template = idx == 0 ? '# ^ %s' : '# %s'
+ output += sprintf(template, comment_part).rstrip + "\n"
+ end
+ end
+ output
end
def width(string)
diff --git a/spec/lib/annotate/annotate_models_spec.rb b/spec/lib/annotate/annotate_models_spec.rb
index e2d6f41ab..66e4de40d 100644
--- a/spec/lib/annotate/annotate_models_spec.rb
+++ b/spec/lib/annotate/annotate_models_spec.rb
@@ -1078,11 +1078,15 @@ def mock_column(name, type, options = {})
#
# Table name: users
#
- # id(ID) :integer not null, primary key
- # active(Active) :boolean not null
- # name(Name) :string(50) not null
- # notes(Notes) :text(55) not null
- # no_comment :text(20) not null
+ # id :integer not null, primary key
+ # ^ ID
+ # active :boolean not null
+ # ^ Active
+ # name :string(50) not null
+ # ^ Name
+ # notes :text(55) not null
+ # ^ Notes
+ # no_comment :text(20) not null
#
EOS
end
@@ -1113,15 +1117,22 @@ def mock_column(name, type, options = {})
#
# Table name: users
#
- # id(ID) :integer not null, primary key
- # active(ACTIVE) :boolean not null
- # name(NAME) :string(50) not null
- # notes(NOTES) :text(55) not null
- # cyrillic(Кириллица) :text(30) not null
- # japanese(熊本大学 イタリア 宝島) :text(60) not null
- # arabic(لغة) :text(20) not null
- # no_comment :text(20) not null
- # location :geometry_collect not null
+ # id :integer not null, primary key
+ # ^ ID
+ # active :boolean not null
+ # ^ ACTIVE
+ # name :string(50) not null
+ # ^ NAME
+ # notes :text(55) not null
+ # ^ NOTES
+ # cyrillic :text(30) not null
+ # ^ Кириллица
+ # japanese :text(60) not null
+ # ^ 熊本大学 イタリア 宝島
+ # arabic :text(20) not null
+ # ^ لغة
+ # no_comment :text(20) not null
+ # location :geometry_collect not null
#
EOS
end
@@ -1146,9 +1157,11 @@ def mock_column(name, type, options = {})
#
# Table name: users
#
- # id(ID) :integer not null, primary key
- # notes(Notes.\\nMay include things like notes.):text(55) not null
- # no_comment :text(20) not null
+ # id :integer not null, primary key
+ # ^ ID
+ # notes :text(55) not null
+ # ^ Notes.\\nMay include things like notes.
+ # no_comment :text(20) not null
#
EOS
end