If you use YARD to document a Ruby project, it's handy to know what is not yet documented.
Documentation can be of various types, there are class descriptions, parameter definitions, return type definitions and so on.
I'm concentrating on documenting the public interface to my code, so I'd like to list everything with public visibility that's not covered.
yard stats
YARD has a stats
command
> yard stats
Files: 77
Modules: 8 ( 8 undocumented)
Classes: 77 ( 76 undocumented)
Constants: 32 ( 32 undocumented)
Attributes: 60 ( 0 undocumented)
Methods: 259 ( 176 undocumented)
33.03% documented
That gives you an idea of documentation coverage, but doesn't tell you what needs documenting.
By the way, I'm running these examples on various versions of the imap-backup gem.
Yardstick
There is a gem called yardstick which measures YARD documentation coverage.
> yardstick 'lib/**/*.rb'
...
lib/imap/backup/account/folder.rb:173: Imap::Backup::Account::Folder#utf7_encoded_name: The @api tag should be specified
lib/imap/backup/account/folder.rb:173: Imap::Backup::Account::Folder#utf7_encoded_name: The @api tag must be either public, semipublic or private
lib/imap/backup/account/folder.rb:173: Imap::Backup::Account::Folder#utf7_encoded_name: A method with private visibility must have an @api tag of private
lib/imap/backup/account/folder.rb:173: Imap::Backup::Account::Folder#utf7_encoded_name: The public/semipublic method should have an example specified
lib/imap/backup/account/folder.rb:173: Imap::Backup::Account::Folder#utf7_encoded_name: The method summary should be specified
lib/imap/backup/account/folder.rb:173: Imap::Backup::Account::Folder#utf7_encoded_name: The @return tag should be specified
...
YARD-Coverage: 48.6% Success: 2820 Failed: 2980 Total: 5800
It indicates that everything that does not have documentation coverage, regardless of public/protected/private visibility.
If, by default, you want to document everything, yardstick will work fine for you.
In my case, I'm most interested in documenting public methods/classes/etc.
As far as I can see, the only way to make Yardstick ignore private code is by adding the @api private
tag, which for me would be unnecessarily cumbersome.
YARD queries
My solution to this problem is to use YARD's --query
system.
The query you supply is Ruby code that can access each code item as YARD scans your project.
For example, to list just methods, you do this:
> yard list --query 'object.is_a?(YARD::CodeObjects::MethodObject)'
...
lib/imap/backup/account/folder.rb:26: Imap::Backup::Account::Folder#client
...
object
is the item in your project, wrapped in a YARD::CodeObjects
instance.
YARD::CodeObjects
can be methods, classes, constants etc.
This become useful when you filter on an aspect of the code and it's relative coverage.
For example
yard list \
--query 'object.is_a?(YARD::CodeObjects::MethodObject) && object.parameters.any? && !object.tag(:param)
That's rather long, but can be shortened. YARD uses a method_missing
trick to allow you to omit object
(as long as the method you are calling is not implemented by its Verifier class).
So the example above can be shortened to
yard list --query 'object.is_a?(CodeObjects::MethodObject) && parameters.any? && !tag(:param)'
The Queries I Use
Methods without parameter documentation
yard list --query 'object.is_a?(CodeObjects::MethodObject) && parameters.any? && !tag(:param)'
Methods without a documented return type
yard list --query 'object.is_a?(CodeObjects::MethodObject) && !constructor? && !tag(:return)'
Classes without a description
yard list --query 'object.is_a?(CodeObjects::ClassObject) && !tag(:private) && docstring.empty?'
Public constants without a description
yard list --query 'object.is_a?(CodeObjects::ConstantObject) && !tag(:private) && docstring.empty?'
Conclusion
These queries provide a fast and flexible was of finding undocumented code.