ワンクリックで
yard-documentation
// General YARD documentation rules and workflow for all Ruby source code. Use when writing or reviewing YARD doc comments, generating missing docs, updating examples, fixing doc errors, or checking documentation coverage.
// General YARD documentation rules and workflow for all Ruby source code. Use when writing or reviewing YARD doc comments, generating missing docs, updating examples, fixing doc errors, or checking documentation coverage.
Scaffolds new and reviews existing Git::Repository facade methods (organized into Git::Repository::* topic modules) with unit tests, integration tests, and YARD docs. Use when adding a new facade method to Git::Repository, updating an existing facade method, choosing or creating a topic module under lib/git/repository/, or reviewing a facade method for correctness.
Facade-specific YARD documentation rules for Git::Repository::* topic modules and their facade methods, overriding and extending the general yard-documentation skill. Use when writing or reviewing YARD docs for facade modules under lib/git/repository/.
Migrates a public method from Git::Base or Git::Lib to a Git::Repository facade method (under lib/git/repository/) as part of the v5.0.0 architectural redesign. Use when extracting a specific public method during the Strangler Fig migration of Git::Base / Git::Lib into Git::Repository.
Scaffolds new and reviews existing Git::Commands::* classes with unit tests, integration tests, and YARD docs using the Base architecture. Use when creating a new command class from scratch, updating an existing command class, or reviewing a command class for correctness.
Command-specific YARD documentation rules for Git::Commands::Base subclasses, overriding and extending the general yard-documentation skill. Use when writing or reviewing YARD docs for command classes.
Audits a command class's arguments DSL definition to verify it accurately maps Ruby call arguments to git CLI arguments in the correct order with correct DSL methods and modifiers.
| name | yard-documentation |
| description | General YARD documentation rules and workflow for all Ruby source code. Use when writing or reviewing YARD doc comments, generating missing docs, updating examples, fixing doc errors, or checking documentation coverage. |
General YARD documentation rules and workflow for all Ruby source code.
Attach this file to your Copilot Chat context, then invoke it with the source files that need YARD updates. Use it when adding new APIs, fixing doc warnings, or improving existing YARD quality and examples.
Git::Commands::Base subclassesruby-git uses YARD for API documentation:
All classes, modules, constants, attributes, and methods must have YARD
documentation. Methods with Ruby private visibility require a short description
and all applicable tags from the Methods rules — @param, @return,
@raise, @yield/@yieldparam/@yieldreturn, and @overload — with the
exception that @example may be omitted unless an example materially clarifies
the behavior. Private methods still need YARD docs for developer reference in
source, even though YARD excludes them from generated HTML by default.
Doc comments are rendered as markdown via the redcarpet gem. Write all free-text descriptions, tag values, and examples using markdown syntax. These rules apply to all documentation regardless of element type:
Named length limits
Three named limits govern line and description length throughout this document:
LINE_LIMIT (90 characters) — the preferred maximum length of any
physical YARD comment line, measured from column 1 and including every
character: indentation, #, tag metadata, and all text. Wrap prose at
this limit wherever possible.LINE_MAX (120 characters) — the hard ceiling for lines that cannot
be wrapped without breaking their meaning. The following content may
exceed LINE_LIMIT up to LINE_MAX; it must not exceed LINE_MAX:
@see tags or markdown links; a URL cannot be split`backtick` span whose content
alone approaches or exceeds LINE_LIMIT[Type] expressions — a type such as
[String, Pathname, Array<String, Pathname>] that fills the tag
metadata column before any description text begins@example code lines — real code inside an example block that
cannot be reflowed without changing its meaningSUMMARY_LIMIT (90 characters) — the maximum length of a tag's
description text, measured by concatenating the description from the first
tag line with all immediately following indented continuation lines
(stripping the leading # from each and joining with a single space).
Applies to the description text only — not the tag name, [Type], option
key, or (default).Doc comment placement
YARD doc comments must appear immediately above the element they document (class, module, method, constant, or attribute) with no intervening blank lines or non-comment code.
Blank lines around tags
Every individual YARD tag must be preceded by a blank comment line (#) unless it is the very first line of a doc comment.
A YARD tag is any comment token matching @!?[a-z_]+ — that is, @word (regular
tags such as @param, @return, @raise, @api, @abstract, @deprecated,
etc.) or @!word (directives such as @!attribute, @!method, @!scope, etc.).
Within the tag block there are no other exceptions: consecutive same-kind tags (e.g.
multiple @param lines) each require their own preceding blank line.
Never use raw blank lines inside a doc comment block
A raw blank line — an empty line with no leading # — terminates the YARD doc
comment block at that point. Any comment lines that follow the raw blank line are
treated as separate, unattached comments and will not appear in the generated
documentation. Always use a blank comment line (#) to separate paragraphs or
continuation text within a YARD block:
Correct — blank comment line keeps the block intact:
# @option options [Boolean, nil] :ipv4 (nil) use IPv4 addresses only
#
# Alias: :"4"
Incorrect — raw blank line silently drops the alias note:
# @option options [Boolean, nil] :ipv4 (nil) use IPv4 addresses only
# Alias: :"4"
Watch for editors that auto-strip trailing spaces from # lines, silently
creating raw blank lines.
Short descriptions
The short description (the first sentence of any doc comment, or the inline text of
a @param, @return, @raise, etc. tag) must:
., ?, !)Returns the commit count,
Represents a Git branch)@option, @param, @return, @raise, @yield,
@yieldparam, etc.) all start with a lowercase letter (e.g. @option options [Boolean, nil] :force (nil) overwrite existing files, @param name [String] the branch name, @return [String] the result, @raise [ArgumentError] when no name is provided)For tags, the summary text is the description that follows the tag
metadata (tag name, [Type], option key, and (default)). For example, in:
@option options [Boolean, nil] :ignore_case (nil) ignore case distinctions
the summary text is ignore case distinctions.
Tag line and summary length
Every physical YARD doc line should not exceed LINE_LIMIT. When a tag's
description would push a line past LINE_LIMIT, split it at a word boundary
onto a continuation line indented two extra spaces. For content that cannot
be wrapped (URLs, long inline code spans, long [Type] expressions,
@example code lines, markdown table rows), lines may extend up to
LINE_MAX but must not exceed it.
Additionally, the concatenated description — the description text from the
first tag line joined with all continuation lines — must not exceed
SUMMARY_LIMIT. If the concatenated description exceeds SUMMARY_LIMIT,
shorten it and move the excess detail into a paragraph after a blank # line.
For example, this tag has a description of 84 characters (within
SUMMARY_LIMIT), but the single physical line is 102 characters (exceeds
LINE_LIMIT) and must be split:
# @return [Array] a two-element tuple `[target, options]` containing the translated checkout arguments
Split so each physical line fits within LINE_LIMIT:
# @return [Array] a two-element tuple `[target, options]` containing the
# translated checkout arguments
If the tag metadata itself is long (e.g. a long [Type] or @option key),
start the description on an indented continuation line so only the metadata
appears on the first physical line.
If more explanation is needed, add continuation paragraphs after a blank
comment line (#). Every physical line — in the summary and in any
continuation paragraph — must independently fit within LINE_LIMIT
(or LINE_MAX for unwrappable content such as URLs, long inline code
spans, long [Type] expressions, @example code, or table rows).
These rules apply equally to tag text (@param, @return, etc.) — the first
sentence of a tag is its short description. The no-punctuation rule applies only to
short descriptions; continuation paragraphs use normal prose punctuation (periods).
Separate continuation paragraphs with a blank comment line.
Correct — tag title without punctuation, blank line before continuation:
# @option options [Boolean, nil] :ignore_case (nil) ignore case
# distinctions in both the pattern and the file contents
#
# Alias: :i
#
# @option options [String, Array<String>] :pattern the search pattern
# (required; must not be nil)
#
# Pass a String for a simple pattern (emitted as `-e <pattern>`).
# Pass an Array of raw CLI arguments for compound boolean
# expressions.
#
# @return [Git::CommandLineResult] the result of calling `git grep`
#
# Exit status 0 means matches were found; exit status 1 means no
# lines were selected (not an error).
Incorrect — trailing period on title, missing blank line before continuation, and @return concatenated summary exceeds SUMMARY_LIMIT (132 chars):
# @option options [Boolean, nil] :ignore_case (nil) ignore case
# distinctions in both the pattern and the file contents.
# Alias: :i
#
# @return [Git::CommandLineResult] the result of calling `git grep`.
# Exit status 0 means matches were found; exit status 1 means no
# lines were selected (not an error).
@return must always include a type
Every @return tag must include a [Type] specifier. @return the value is
incorrect; write @return [Object] the value (or a more specific type). If the
return value is the block's return value, use @return [Object].
No shell calls in @example blocks
Never use backtick shell calls (`true`, `git version`) or process-status
globals ($?, $CHILD_STATUS) in @example blocks. They are side-effecting,
environment-dependent, and confuse readers about the type of object being
demonstrated. Construct example objects directly in Ruby instead:
Incorrect:
# @example Incorrect shell call
# `true`
# result = Git::CommandLine::Result.new([], $?, '', '')
Correct:
# @example Constructing a result with a double
# status = instance_double(ProcessExecuter::Result)
# result = Git::CommandLine::Result.new([], status, '', '')
Blank lines within @example blocks
Within @example blocks, blank comment lines (#) render as literal blank lines in
the displayed code. Use them for readability between setup and assertions, but be
aware they are literal content, not tag separators.
@example titles are required
Every @example tag must include a title — the descriptive text on the same line
after @example. Write @example Basic usage, not bare @example. Titles appear
as headings in generated docs and help readers scan multiple examples.
Cross-reference links only resolve to objects included in generated docs
YARD renders {ClassName#method} as a hyperlink only when the target method is
included in the generated documentation. Public objects are included by default,
and objects marked with @api private remain included with a private annotation.
Ruby private methods are excluded by default. Do not write
{Git::Lib#some_private_method} — it will render as plain text and may generate
an unresolved reference warning.
If you need to refer to a private method, describe it in prose instead, or link to the public method that callers should use.
Inline code formatting
Use backtick code spans for inline code (`true`, `nil`, symbols, type
names, method calls). Do not use the RDoc +value+ style; it is inconsistent with
the project's markdown rendering via redcarpet.
Escaping { in descriptions
YARD treats { as the start of a cross-reference link. Because redcarpet consumes
one \ before YARD sees it, write \\{ (two backslashes) to produce a literal
{ — redcarpet reduces \\ to \, leaving \{ for YARD. For example, use
'stash@\\{0}' to render as stash@{0}. Using only \{ still triggers a YARD
unresolved link warning.
Cross-reference links
Link to other code objects anywhere in a doc comment using {ClassName},
{ClassName#method}, {#method_in_same_class}, or {Class::CONSTANT}. An
optional title follows the reference separated by a space:
{Git::Base#log the log method}. Do not use brace syntax inside @see tags —
@see links automatically without braces. @see accepts three target forms:
@see Git::Base#log@see https://git-scm.com/docs/git-log@see "Pro Git, Chapter 2"Type specifier conventions
The [Types] field in @param, @return, @raise, etc. supports:
[String], [Integer], [Git::Base][String, nil], [String, Array<String>][Array<String>], [Hash<Symbol, String>][#read], [#to_s][Boolean] — conventional meta-type for true or false (not a real Ruby class)[void] — for @return tags on methods whose return value must not be used@api private vs @private
Use @api private (not @private) to mark internal classes and modules. @api private includes the object in generated docs with a private annotation; YARD's
@private tag excludes the object from docs entirely.
@since — do not use
Do not add @since tags. The project has no historical @since annotations, and
retroactively tagging existing APIs is impractical at v4.x. Version introduction
history is tracked through git blame and the CHANGELOG instead.
@todo — do not use
Do not add @todo tags. Track incomplete work in GitHub Issues, not in source
comments. YARD renders @todo prominently in generated docs, and these annotations
go stale quickly.
@abstract
Use @abstract on classes or methods that must be subclassed or overridden before
use. Include guidance text describing what the subclass must implement:
@abstract Subclass and implement {#run}. Do not use @abstract on concrete
classes or fully implemented methods.
Classes
Wrapper around the git binary, Immutable value object for a branch delete result, Represents a git branchThis class wraps the git binary, Provides branch deletion,
Encapsulates branch state@api public or @api private tag to declare visibility — use @api public for
stable user-facing classes; use @api private for internal implementation classes
(e.g., Git::Lib, Git::Commands::*, parsers)@example showing typical instantiation or primary usage — this
applies to all classes including @api private classesRaised when branch deletion fails@deprecated explaining the migration path@example, @note,
@deprecated, @see, @api, @abstractModules
@api public or @api private — use @api public for stable user-facing modules;
use @api private for internal implementation modules@example required unless the module provides standalone methods@deprecated explaining the migration path@example, @note, @deprecated, @see, @apiConstants
# @return [Type] when the constant holds a collection, frozen structure, or
domain-specific type whose shape is not immediately obvious from the valueAttributes
attr_reader, attr_accessor, and attr_writer declarations,
place the documentation directly above the attribute; do not use the @!attribute
directiveData.define members, or Struct.new
members, you must use a # @!attribute [r/rw/w] name YARD directive@return [Type] description explaining the value and its units or
constraints if relevantattr_reader/attr_accessor/attr_writer, include a short
description paragraph above the attribute in addition to @return@!attribute directives (in Data.define / Struct.new), the @return
tag inside the directive block serves as the sole documentation — no separate
short description is needed@!attribute (and @!method) directive blocks must be indented
two extra spaces relative to the directive itselfDynamically defined methods (@!method)
Use the # @!method name(params) directive for methods created via
metaprogramming (define_method, method-generating DSLs, etc.) that have no
literal def. Place the directive and its doc comment where the method would
logically appear in the class body. Tags inside the directive block follow the
same indentation rule as @!attribute — indented two extra spaces relative to
the directive.
Data.define classes
Immutable value objects defined with Data.define use the following conventions
(see Git::BranchDeleteFailure for a canonical example):
@example, @see, @api@!attribute [r] directive per member with @return [Type] descriptionData.define lineData.define block follow standard method
rulesStruct.new classes
Document Struct.new classes using the same conventions as Data.define classes:
class-level doc with a noun-phrase short description, @example, @see, @api,
and one @!attribute directive per member with @return [Type] description.
# Immutable value object for a failed branch delete
#
# @example Create a failure object
# failure = Git::BranchDeleteFailure.new(name: 'feature', result: result)
# failure.name #=> "feature"
# failure.result #=> #<Git::CommandLineResult ...>
#
# @see Git::BranchDeleteResult
#
# @api public
#
# @!attribute [r] name
#
# @return [String] the branch name that failed to delete
#
# @!attribute [r] result
#
# @return [Git::CommandLineResult] the result of the failed delete
#
BranchDeleteFailure = Data.define(:name, :result)
Methods
Returns, Resets, Finds — not "The…" or "This method…")Finds the nearest tagged ancestor not
Iterates through commits checking tagsResets HEAD to the given ref rather than
relying solely on param tagsReturns true if the branch exists, false otherwise beats Returns a Boolean@param for each method parameter, in signature order; omit @param entirely
on zero-argument methods@return on every method; use [void] when the return value must not be used@raise for each caller-relevant exception the method can raise as part of its
contract; omit @raise when the method has no documented exceptional pathprivate visibility must have one or more @examples;
Ruby-private methods may omit @example unless usage would otherwise be unclear@yield [param_names], one
@yieldparam name [Type] per yielded parameter, and @yieldreturn [Type]; omit
all yield tags on methods that do not yield@overload when a method has distinct call signatures with different
parameters or return types — each overload gets its own full set of tags.
Methods that yield only when an optional block is given should use @overload
to document the with-block and without-block signatures separately**),
anonymous positional splat (*), or the argument forwarding
parameter (...) must document their call shapes with @overload blocks
that name the parameters. @param, @option, @yield, and @yieldparam
cannot bind to an anonymous splat or to ... — the named overload signature
is what gives YARD a parameter to attach the docs to. Do not introduce a
named splat (or expand ... into *args, **kwargs, &block) solely so the
tags will bind; that conflicts with RuboCop's Style/ArgumentsForwarding
cop, and the @overload form satisfies both@note for callouts that need visual emphasis: thread-safety warnings,
significant side effects, or platform-specific behaviour@deprecated explaining the migration path,
e.g. @deprecated Use {#new_method} instead@api is optional on methods — when omitted, the method inherits the containing
class's @api level. Use it only when the method's intended visibility differs
from the class's level (e.g. an @api private helper inside an @api public
class)# Find undocumented objects
bundle exec yard stats --list-undoc
# Check a specific file
bundle exec yard doc lib/git/base.rb --no-output
Follow the YARD documentation templates below. Use the standard template when a method has a single call signature. Use the overload template when a method has distinct call signatures with different parameters or return types.
When @overload blocks are present:
@param, @option, and @return inside overload blocks only@raise inside the relevant overload block@raise at top level only once (do not duplicate inside overloads)@note, @deprecated, @see, @api) at top levelAvoid duplicating the same @raise at both top level and overload level. This
causes conflicting or noisy generated docs.
Trigger: always use @overload when the signature contains *, **, or ...
Anonymous splats and the forwarding parameter give @param, @option, @yield,
and @yieldparam no named parameter to bind to. YARD silently drops or
mis-renders these tags when the signature is, for example, def foo(**) or
def foo(paths = '.', **) — even though paths is named, the keyword options
have no name so every @option is unbound. As soon as any parameter in the
signature is anonymous (*, **, or ...), switch to @overload for the entire
signature (see Documenting anonymous splats with @overload).
@overload)When present, tags must appear in the order shown. @param tags appear in
parameter order; @option tags appear immediately after the @param for the hash
they describe. Every @option tag must be preceded by a @param for the
options hash, and all @option tags under that @param must reference the same
parameter name. For keyword arguments (**options or **kwargs), use
@param options [Hash] (or the actual splat name) as the preceding @param:
# Short description of what the method does
#
# Longer description with more details about behavior,
# edge cases, or important notes.
#
# @example Basic usage
# git = Git.open('/path/to/repo')
# result = git.method_name('arg')
#
# @example With options
# git.method_name('arg', option: true)
#
# @param name [Type] description of parameter
#
# @param options [Hash] options hash description
#
# @option options [Type] :key description of option
#
# @param path [String] a parameter after the options hash
#
# @return [Type] description of return value
#
# @raise [ArgumentError] when invalid arguments are provided
#
# @raise [Git::FailedError] when git exits with a non-zero exit status
#
# @yield [commit] passes each commit to the block
#
# @yieldparam commit [Git::Object::Commit] a commit object
#
# @yieldreturn [void]
#
# @note This method is not thread-safe
#
# @deprecated Use {#new_method} instead
#
# @see #related_method
#
# @see Git::RelatedClass
#
# @see https://git-scm.com/docs/git-log
#
# @api public
#
def method_name(name, options = {})
end
Each @overload block carries its own @example, @param, @option, @return,
@raise, @yield, @yieldparam, and @yieldreturn tags. Tags that are
not call-signature-specific — @note, @deprecated, @see, @api — remain
at the top level:
# Short description of what the method does
#
# Longer description with more details about behavior,
# edge cases, or important notes.
#
# @overload method_name(arg)
#
# Single-argument form description
#
# @example Basic usage
# result = git.method_name('arg')
#
# @param arg [String] the argument
#
# @return [String] the result
#
# @overload method_name(arg, options)
#
# Two-argument form description
#
# @example With options
# result = git.method_name('arg', force: true)
#
# @param arg [String] the argument
#
# @param options [Hash] additional options
#
# @return [Array<String>] the results
#
# @note This method is not thread-safe
#
# @deprecated Use {#new_method} instead
#
# @see #related_method
#
# @see https://git-scm.com/docs/git-log
#
# @api public
#
def method_name(name, options = {})
end
Use this matrix to decide whether to use @overload and where to place tags:
| Method signature or behavior | Documentation form |
|---|---|
Single named signature, no */**/... | Standard template (no @overload) |
Uses anonymous *, **, or ... | @overload required |
| Multiple call shapes (different params and/or return types) | One @overload per shape |
| Shared errors across all call shapes | Top-level @raise once |
| Error only for specific call shape | @raise only in that overload |
For overload docs, keep @param/@option/@return in overload blocks. Use
top-level @raise only for errors that apply to every overload.
@overloadWhen the method signature uses an anonymous splat — def foo(*), def foo(**),
def foo(*, **) — or the argument forwarding parameter def foo(...) —
@param, @option, @yield, and @yieldparam tags have no parameter name
to bind to. RuboCop's Style/ArgumentsForwarding cop prefers these forms when
arguments are forwarded unchanged, so naming the splat (or expanding ...
into *args, **kwargs, &block) is not an acceptable workaround. Use
@overload blocks that introduce named parameters for documentation purposes
only:
# Update the index with the current content found in the working tree
#
# @overload add(paths = '.', **options)
#
# @example Stage a specific file
# git.add('README.md')
#
# @param paths [String, Array<String>] file(s) to add (relative to the
# worktree root); defaults to `'.'` (all files)
#
# @param options [Hash] command options
#
# @option options [Boolean, nil] :all (nil) add, modify, and remove index entries to
# match the worktree
#
# @option options [Boolean, nil] :force (nil) allow adding otherwise ignored files
#
# @return [String] the command output
#
# @raise [Git::FailedError] if `git add` exits with a non-zero status
#
def add(paths = '.', **)
Git::Commands::Add.new(@execution_context).call(*Array(paths), **).stdout
end
The same approach applies to .... The overload signature names the
parameters; the actual def keeps ... so RuboCop is satisfied:
# Run a command against the underlying execution context
#
# @overload run(command, *args, **options, &block)
#
# @example Run git status
# result = git.run('status')
#
# @param command [String] the git subcommand to run
#
# @param args [Array<String>] positional arguments forwarded to the command
#
# @param options [Hash] keyword options forwarded to the command
#
# @return [Git::CommandLineResult] the command result
#
# @yield [result] yields the command result, when a block is given
#
# @yieldparam result [Git::CommandLineResult] the command result
#
# @yieldreturn [void]
#
def run(command, ...)
Git::Commands::Run.new(@execution_context).call(command, ...)
end
When a method has multiple genuinely distinct call shapes, write one
@overload block per shape as in the Overload template
above.
Anonymous block parameter (&) is not covered by this rule.
@yield, @yieldparam, and @yieldreturn describe what is yielded to the
block, not the block parameter itself, so they bind correctly even with an
anonymous &. Use a named block parameter (&block) and a @param block [Proc] tag only in the rare case where the block is documented as a
first-class Proc value (stored, returned, or passed elsewhere) rather than
yielded to.
# Generate and review docs
bundle exec yard doc
open doc/index.html
# Check for warnings
bundle exec yard doc 2>&1 | grep -i "warn"
Verify @example code runs correctly in bundle exec bin/console.
Check that all @see references point to valid targets.
Review checklist — tag line length
For every @param, @return, @raise, @option, @yield, @yieldparam,
and @yieldreturn tag, check both limits:
LINE_LIMIT: Count every character from column 1 (indentation, #,
metadata, text) on each physical line. If any wrappable line exceeds
LINE_LIMIT, split at a word boundary onto a continuation line (indented
two extra spaces). Apply this check to every continuation line
independently. Lines containing URLs, long inline code spans, long [Type]
expressions, @example code, or markdown table rows may extend up to
LINE_MAX.SUMMARY_LIMIT: Strip # from each continuation line and join
with a single space. If the concatenated description exceeds
SUMMARY_LIMIT, shorten it and move the excess into a paragraph after
a blank # line.# Generate documentation
bundle exec yard doc
# Generate and serve locally
bundle exec yard server --reload
# Check documentation coverage
bundle exec yard stats
# List undocumented objects
bundle exec yard stats --list-undoc
# Generate docs for specific file
bundle exec yard doc lib/git/base.rb
# Check for YARD syntax errors
bundle exec yard doc --no-output 2>&1
# View documentation for specific class
bundle exec yard ri Git::Base