Skip to content

Commit 0625547

Browse files
tvalloisdrwl
authored andcommitted
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.
1 parent 9674923 commit 0625547

File tree

9 files changed

+49
-8
lines changed

9 files changed

+49
-8
lines changed

.rubocop_todo.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ Lint/ShadowingOuterLocalVariable:
408408

409409
# Offense count: 20
410410
Metrics/AbcSize:
411-
Max: 141
411+
Max: 155
412412

413413
# Offense count: 31
414414
# Configuration parameters: CountComments, ExcludedMethods.
@@ -423,16 +423,16 @@ Metrics/BlockNesting:
423423

424424
# Offense count: 10
425425
Metrics/CyclomaticComplexity:
426-
Max: 36
426+
Max: 41
427427

428428
# Offense count: 30
429429
# Configuration parameters: CountComments, ExcludedMethods.
430430
Metrics/MethodLength:
431-
Max: 75
431+
Max: 80
432432

433433
# Offense count: 8
434434
Metrics/PerceivedComplexity:
435-
Max: 42
435+
Max: 47
436436

437437
# Offense count: 1
438438
Naming/AccessorMethodName:

lib/annotate/annotate_models.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ def get_schema_info(klass, header, options = {})
258258
if col_type == 'decimal'
259259
col_type << "(#{col.precision}, #{col.scale})"
260260
elsif !%w[spatial geometry geography].include?(col_type)
261-
if col.limit
261+
if col.limit && !options[:format_yard]
262262
if col.limit.is_a? Array
263263
attrs << "(#{col.limit.join(', ')})"
264264
else
@@ -297,6 +297,10 @@ def get_schema_info(klass, header, options = {})
297297
end
298298
if options[:format_rdoc]
299299
info << sprintf("# %-#{max_size}.#{max_size}s<tt>%s</tt>", "*#{col_name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n"
300+
elsif options[:format_yard]
301+
info << sprintf("# @!attribute #{col_name}") + "\n"
302+
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)
303+
info << sprintf("# @return [#{ruby_class}]") + "\n"
300304
elsif options[:format_markdown]
301305
name_remainder = max_size - col_name.length - non_ascii_length(col_name)
302306
type_remainder = (md_type_allowance - 2) - col_type.length
@@ -931,6 +935,19 @@ def non_ascii_length(string)
931935
string.to_s.chars.reject(&:ascii_only?).length
932936
end
933937

938+
def map_col_type_to_ruby_classes(col_type)
939+
case col_type
940+
when 'integer' then Integer.to_s
941+
when 'float' then Float.to_s
942+
when 'decimal' then BigDecimal.to_s
943+
when 'datetime', 'timestamp', 'time' then Time.to_s
944+
when 'date' then Date.to_s
945+
when 'text', 'string', 'binary', 'inet', 'uuid' then String.to_s
946+
when 'json', 'jsonb' then Hash.to_s
947+
when 'boolean' then 'Boolean'
948+
end
949+
end
950+
934951
def columns(klass, options)
935952
cols = klass.columns
936953
cols += translated_columns(klass)

lib/annotate/constants.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module Constants
1414
FLAG_OPTIONS = [
1515
:show_indexes, :simple_indexes, :include_version, :exclude_tests,
1616
:exclude_fixtures, :exclude_factories, :ignore_model_sub_dir,
17-
:format_bare, :format_rdoc, :format_markdown, :sort, :force, :frozen,
17+
:format_bare, :format_rdoc, :format_yard, :format_markdown, :sort, :force, :frozen,
1818
:trace, :timestamp, :exclude_serializers, :classified_sort,
1919
:show_foreign_keys, :show_complete_foreign_keys,
2020
:exclude_scaffolds, :exclude_controllers, :exclude_helpers,

lib/annotate/parser.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def self.parse(args, env = {})
1212
ANNOTATION_POSITIONS = %w[before top after bottom].freeze
1313
FILE_TYPE_POSITIONS = %w[position_in_class position_in_factory position_in_fixture position_in_test position_in_routes position_in_serializer].freeze
1414
EXCLUSION_LIST = %w[tests fixtures factories serializers].freeze
15-
FORMAT_TYPES = %w[bare rdoc markdown].freeze
15+
FORMAT_TYPES = %w[bare rdoc yard markdown].freeze
1616

1717
def initialize(args, env)
1818
@args = args
@@ -196,7 +196,7 @@ def add_options_to_parser(option_parser) # rubocop:disable Metrics/MethodLength
196196
exclusions.each { |exclusion| env["exclude_#{exclusion}"] = 'yes' }
197197
end
198198

199-
option_parser.on('-f', '--format [bare|rdoc|markdown]', FORMAT_TYPES, 'Render Schema Infomation as plain/RDoc/Markdown') do |fmt|
199+
option_parser.on('-f', '--format [bare|rdoc|yard|markdown]', FORMAT_TYPES, 'Render Schema Infomation as plain/RDoc/Yard/Markdown') do |fmt|
200200
env["format_#{fmt}"] = 'yes'
201201
end
202202

lib/generators/annotate/templates/auto_annotate_models.rake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ if Rails.env.development?
4242
'skip_on_db_migrate' => 'false',
4343
'format_bare' => 'true',
4444
'format_rdoc' => 'false',
45+
'format_yard' => 'false',
4546
'format_markdown' => 'false',
4647
'sort' => 'false',
4748
'force' => 'false',

lib/tasks/annotate_models.rake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ task annotate_models: :environment do
3737
options[:ignore_model_sub_dir] = Annotate::Helpers.true?(ENV['ignore_model_sub_dir'])
3838
options[:format_bare] = Annotate::Helpers.true?(ENV['format_bare'])
3939
options[:format_rdoc] = Annotate::Helpers.true?(ENV['format_rdoc'])
40+
options[:format_yard] = Annotate::Helpers.true?(ENV['format_yard'])
4041
options[:format_markdown] = Annotate::Helpers.true?(ENV['format_markdown'])
4142
options[:sort] = Annotate::Helpers.true?(ENV['sort'])
4243
options[:force] = Annotate::Helpers.true?(ENV['force'])

spec/integration/rails_4.1.1/lib/tasks/auto_annotate_models.rake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ if Rails.env.development?
2424
'skip_on_db_migrate' => "false",
2525
'format_bare' => "true",
2626
'format_rdoc' => "false",
27+
'format_yard' => "false",
2728
'format_markdown' => "false",
2829
'sort' => "false",
2930
'force' => "false",

spec/integration/rails_4.2.0/lib/tasks/auto_annotate_models.rake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ if Rails.env.development?
2424
'skip_on_db_migrate' => "false",
2525
'format_bare' => "true",
2626
'format_rdoc' => "false",
27+
'format_yard' => "false",
2728
'format_markdown' => "false",
2829
'sort' => "false",
2930
'force' => "false",

spec/lib/annotate/annotate_models_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,26 @@ def mock_column(name, type, options = {})
632632
EOS
633633
end
634634

635+
it 'should get schema info as YARD' do
636+
klass = mock_class(:users,
637+
:id,
638+
[
639+
mock_column(:id, :integer),
640+
mock_column(:name, :string, limit: 50),
641+
])
642+
expect(AnnotateModels.get_schema_info(klass, AnnotateModels::PREFIX, format_yard: true)).to eql(<<-EOS)
643+
# #{AnnotateModels::PREFIX}
644+
#
645+
# Table name: users
646+
#
647+
# @!attribute id
648+
# @return [Integer]
649+
# @!attribute name
650+
# @return [String]
651+
#
652+
EOS
653+
end
654+
635655
it 'should get schema info as Markdown' do
636656
klass = mock_class(:users,
637657
:id,

0 commit comments

Comments
 (0)