Commit 06255470 by tvallois Committed by Andrew W. Lee

Support YARD notation (#724)

The scope of this pull request is to allow annotate_models to generate models documentation using YARD. This is the first step, I'll add more features later.
parent 96749235
...@@ -408,7 +408,7 @@ Lint/ShadowingOuterLocalVariable: ...@@ -408,7 +408,7 @@ Lint/ShadowingOuterLocalVariable:
# Offense count: 20 # Offense count: 20
Metrics/AbcSize: Metrics/AbcSize:
Max: 141 Max: 155
# Offense count: 31 # Offense count: 31
# Configuration parameters: CountComments, ExcludedMethods. # Configuration parameters: CountComments, ExcludedMethods.
...@@ -423,16 +423,16 @@ Metrics/BlockNesting: ...@@ -423,16 +423,16 @@ Metrics/BlockNesting:
# Offense count: 10 # Offense count: 10
Metrics/CyclomaticComplexity: Metrics/CyclomaticComplexity:
Max: 36 Max: 41
# Offense count: 30 # Offense count: 30
# Configuration parameters: CountComments, ExcludedMethods. # Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength: Metrics/MethodLength:
Max: 75 Max: 80
# Offense count: 8 # Offense count: 8
Metrics/PerceivedComplexity: Metrics/PerceivedComplexity:
Max: 42 Max: 47
# Offense count: 1 # Offense count: 1
Naming/AccessorMethodName: Naming/AccessorMethodName:
......
...@@ -258,7 +258,7 @@ module AnnotateModels ...@@ -258,7 +258,7 @@ module AnnotateModels
if col_type == 'decimal' if col_type == 'decimal'
col_type << "(#{col.precision}, #{col.scale})" col_type << "(#{col.precision}, #{col.scale})"
elsif !%w[spatial geometry geography].include?(col_type) elsif !%w[spatial geometry geography].include?(col_type)
if col.limit if col.limit && !options[:format_yard]
if col.limit.is_a? Array if col.limit.is_a? Array
attrs << "(#{col.limit.join(', ')})" attrs << "(#{col.limit.join(', ')})"
else else
...@@ -297,6 +297,10 @@ module AnnotateModels ...@@ -297,6 +297,10 @@ module AnnotateModels
end end
if options[:format_rdoc] if options[:format_rdoc]
info << sprintf("# %-#{max_size}.#{max_size}s<tt>%s</tt>", "*#{col_name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n" info << sprintf("# %-#{max_size}.#{max_size}s<tt>%s</tt>", "*#{col_name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n"
elsif options[:format_yard]
info << sprintf("# @!attribute #{col_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] elsif options[:format_markdown]
name_remainder = max_size - col_name.length - non_ascii_length(col_name) name_remainder = max_size - col_name.length - non_ascii_length(col_name)
type_remainder = (md_type_allowance - 2) - col_type.length type_remainder = (md_type_allowance - 2) - col_type.length
...@@ -931,6 +935,19 @@ module AnnotateModels ...@@ -931,6 +935,19 @@ module AnnotateModels
string.to_s.chars.reject(&:ascii_only?).length string.to_s.chars.reject(&:ascii_only?).length
end end
def map_col_type_to_ruby_classes(col_type)
case col_type
when 'integer' then Integer.to_s
when 'float' then Float.to_s
when 'decimal' then BigDecimal.to_s
when 'datetime', 'timestamp', 'time' then Time.to_s
when 'date' then Date.to_s
when 'text', 'string', 'binary', 'inet', 'uuid' then String.to_s
when 'json', 'jsonb' then Hash.to_s
when 'boolean' then 'Boolean'
end
end
def columns(klass, options) def columns(klass, options)
cols = klass.columns cols = klass.columns
cols += translated_columns(klass) cols += translated_columns(klass)
......
...@@ -14,7 +14,7 @@ module Annotate ...@@ -14,7 +14,7 @@ module Annotate
FLAG_OPTIONS = [ FLAG_OPTIONS = [
:show_indexes, :simple_indexes, :include_version, :exclude_tests, :show_indexes, :simple_indexes, :include_version, :exclude_tests,
:exclude_fixtures, :exclude_factories, :ignore_model_sub_dir, :exclude_fixtures, :exclude_factories, :ignore_model_sub_dir,
:format_bare, :format_rdoc, :format_markdown, :sort, :force, :frozen, :format_bare, :format_rdoc, :format_yard, :format_markdown, :sort, :force, :frozen,
:trace, :timestamp, :exclude_serializers, :classified_sort, :trace, :timestamp, :exclude_serializers, :classified_sort,
:show_foreign_keys, :show_complete_foreign_keys, :show_foreign_keys, :show_complete_foreign_keys,
:exclude_scaffolds, :exclude_controllers, :exclude_helpers, :exclude_scaffolds, :exclude_controllers, :exclude_helpers,
......
...@@ -12,7 +12,7 @@ module Annotate ...@@ -12,7 +12,7 @@ module Annotate
ANNOTATION_POSITIONS = %w[before top after bottom].freeze ANNOTATION_POSITIONS = %w[before top after bottom].freeze
FILE_TYPE_POSITIONS = %w[position_in_class position_in_factory position_in_fixture position_in_test position_in_routes position_in_serializer].freeze FILE_TYPE_POSITIONS = %w[position_in_class position_in_factory position_in_fixture position_in_test position_in_routes position_in_serializer].freeze
EXCLUSION_LIST = %w[tests fixtures factories serializers].freeze EXCLUSION_LIST = %w[tests fixtures factories serializers].freeze
FORMAT_TYPES = %w[bare rdoc markdown].freeze FORMAT_TYPES = %w[bare rdoc yard markdown].freeze
def initialize(args, env) def initialize(args, env)
@args = args @args = args
...@@ -196,7 +196,7 @@ module Annotate ...@@ -196,7 +196,7 @@ module Annotate
exclusions.each { |exclusion| env["exclude_#{exclusion}"] = 'yes' } exclusions.each { |exclusion| env["exclude_#{exclusion}"] = 'yes' }
end end
option_parser.on('-f', '--format [bare|rdoc|markdown]', FORMAT_TYPES, 'Render Schema Infomation as plain/RDoc/Markdown') do |fmt| option_parser.on('-f', '--format [bare|rdoc|yard|markdown]', FORMAT_TYPES, 'Render Schema Infomation as plain/RDoc/Yard/Markdown') do |fmt|
env["format_#{fmt}"] = 'yes' env["format_#{fmt}"] = 'yes'
end end
......
...@@ -42,6 +42,7 @@ if Rails.env.development? ...@@ -42,6 +42,7 @@ if Rails.env.development?
'skip_on_db_migrate' => 'false', 'skip_on_db_migrate' => 'false',
'format_bare' => 'true', 'format_bare' => 'true',
'format_rdoc' => 'false', 'format_rdoc' => 'false',
'format_yard' => 'false',
'format_markdown' => 'false', 'format_markdown' => 'false',
'sort' => 'false', 'sort' => 'false',
'force' => 'false', 'force' => 'false',
......
...@@ -37,6 +37,7 @@ task annotate_models: :environment do ...@@ -37,6 +37,7 @@ task annotate_models: :environment do
options[:ignore_model_sub_dir] = Annotate::Helpers.true?(ENV['ignore_model_sub_dir']) options[:ignore_model_sub_dir] = Annotate::Helpers.true?(ENV['ignore_model_sub_dir'])
options[:format_bare] = Annotate::Helpers.true?(ENV['format_bare']) options[:format_bare] = Annotate::Helpers.true?(ENV['format_bare'])
options[:format_rdoc] = Annotate::Helpers.true?(ENV['format_rdoc']) options[:format_rdoc] = Annotate::Helpers.true?(ENV['format_rdoc'])
options[:format_yard] = Annotate::Helpers.true?(ENV['format_yard'])
options[:format_markdown] = Annotate::Helpers.true?(ENV['format_markdown']) options[:format_markdown] = Annotate::Helpers.true?(ENV['format_markdown'])
options[:sort] = Annotate::Helpers.true?(ENV['sort']) options[:sort] = Annotate::Helpers.true?(ENV['sort'])
options[:force] = Annotate::Helpers.true?(ENV['force']) options[:force] = Annotate::Helpers.true?(ENV['force'])
......
...@@ -24,6 +24,7 @@ if Rails.env.development? ...@@ -24,6 +24,7 @@ if Rails.env.development?
'skip_on_db_migrate' => "false", 'skip_on_db_migrate' => "false",
'format_bare' => "true", 'format_bare' => "true",
'format_rdoc' => "false", 'format_rdoc' => "false",
'format_yard' => "false",
'format_markdown' => "false", 'format_markdown' => "false",
'sort' => "false", 'sort' => "false",
'force' => "false", 'force' => "false",
......
...@@ -24,6 +24,7 @@ if Rails.env.development? ...@@ -24,6 +24,7 @@ if Rails.env.development?
'skip_on_db_migrate' => "false", 'skip_on_db_migrate' => "false",
'format_bare' => "true", 'format_bare' => "true",
'format_rdoc' => "false", 'format_rdoc' => "false",
'format_yard' => "false",
'format_markdown' => "false", 'format_markdown' => "false",
'sort' => "false", 'sort' => "false",
'force' => "false", 'force' => "false",
......
...@@ -632,6 +632,26 @@ EOS ...@@ -632,6 +632,26 @@ EOS
EOS EOS
end end
it 'should get schema info as YARD' do
klass = mock_class(:users,
:id,
[
mock_column(:id, :integer),
mock_column(:name, :string, limit: 50),
])
expect(AnnotateModels.get_schema_info(klass, AnnotateModels::PREFIX, format_yard: true)).to eql(<<-EOS)
# #{AnnotateModels::PREFIX}
#
# Table name: users
#
# @!attribute id
# @return [Integer]
# @!attribute name
# @return [String]
#
EOS
end
it 'should get schema info as Markdown' do it 'should get schema info as Markdown' do
klass = mock_class(:users, klass = mock_class(:users,
:id, :id,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment