Skip to content

Commit

Permalink
Support YARD notation (#724)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tvallois authored and drwl committed Jan 24, 2020
1 parent 9674923 commit 0625547
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 8 deletions.
8 changes: 4 additions & 4 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ Lint/ShadowingOuterLocalVariable:

# Offense count: 20
Metrics/AbcSize:
Max: 141
Max: 155

# Offense count: 31
# Configuration parameters: CountComments, ExcludedMethods.
Expand All @@ -423,16 +423,16 @@ Metrics/BlockNesting:

# Offense count: 10
Metrics/CyclomaticComplexity:
Max: 36
Max: 41

# Offense count: 30
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength:
Max: 75
Max: 80

# Offense count: 8
Metrics/PerceivedComplexity:
Max: 42
Max: 47

# Offense count: 1
Naming/AccessorMethodName:
Expand Down
19 changes: 18 additions & 1 deletion lib/annotate/annotate_models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def get_schema_info(klass, header, options = {})
if col_type == 'decimal'
col_type << "(#{col.precision}, #{col.scale})"
elsif !%w[spatial geometry geography].include?(col_type)
if col.limit
if col.limit && !options[:format_yard]
if col.limit.is_a? Array
attrs << "(#{col.limit.join(', ')})"
else
Expand Down Expand Up @@ -297,6 +297,10 @@ def get_schema_info(klass, header, options = {})
end
if options[:format_rdoc]
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]
name_remainder = max_size - col_name.length - non_ascii_length(col_name)
type_remainder = (md_type_allowance - 2) - col_type.length
Expand Down Expand Up @@ -931,6 +935,19 @@ def non_ascii_length(string)
string.to_s.chars.reject(&:ascii_only?).length
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)
cols = klass.columns
cols += translated_columns(klass)
Expand Down
2 changes: 1 addition & 1 deletion lib/annotate/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module Constants
FLAG_OPTIONS = [
:show_indexes, :simple_indexes, :include_version, :exclude_tests,
: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,
:show_foreign_keys, :show_complete_foreign_keys,
:exclude_scaffolds, :exclude_controllers, :exclude_helpers,
Expand Down
4 changes: 2 additions & 2 deletions lib/annotate/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def self.parse(args, env = {})
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
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)
@args = args
Expand Down Expand Up @@ -196,7 +196,7 @@ def add_options_to_parser(option_parser) # rubocop:disable Metrics/MethodLength
exclusions.each { |exclusion| env["exclude_#{exclusion}"] = 'yes' }
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'
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ if Rails.env.development?
'skip_on_db_migrate' => 'false',
'format_bare' => 'true',
'format_rdoc' => 'false',
'format_yard' => 'false',
'format_markdown' => 'false',
'sort' => 'false',
'force' => 'false',
Expand Down
1 change: 1 addition & 0 deletions lib/tasks/annotate_models.rake
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ task annotate_models: :environment do
options[:ignore_model_sub_dir] = Annotate::Helpers.true?(ENV['ignore_model_sub_dir'])
options[:format_bare] = Annotate::Helpers.true?(ENV['format_bare'])
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[:sort] = Annotate::Helpers.true?(ENV['sort'])
options[:force] = Annotate::Helpers.true?(ENV['force'])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ if Rails.env.development?
'skip_on_db_migrate' => "false",
'format_bare' => "true",
'format_rdoc' => "false",
'format_yard' => "false",
'format_markdown' => "false",
'sort' => "false",
'force' => "false",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ if Rails.env.development?
'skip_on_db_migrate' => "false",
'format_bare' => "true",
'format_rdoc' => "false",
'format_yard' => "false",
'format_markdown' => "false",
'sort' => "false",
'force' => "false",
Expand Down
20 changes: 20 additions & 0 deletions spec/lib/annotate/annotate_models_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,26 @@ def mock_column(name, type, options = {})
EOS
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
klass = mock_class(:users,
:id,
Expand Down

0 comments on commit 0625547

Please sign in to comment.