(PDOC-63) Implement a Puppet function YARD handler.
This commit implements a YARD handler for Puppet functions and the associated code object and templates.
This commit is contained in:
parent
b1a15bd43a
commit
f025efe557
|
@ -26,6 +26,7 @@ module PuppetStrings::Yard
|
|||
|
||||
# Ignore documentation on Puppet DSL calls
|
||||
# This prevents the YARD DSL parser from emitting warnings for Puppet's Ruby DSL
|
||||
YARD::Handlers::Ruby::DSLHandlerMethods::IGNORE_METHODS['create_function'] = true
|
||||
YARD::Handlers::Ruby::DSLHandlerMethods::IGNORE_METHODS['newtype'] = true
|
||||
end
|
||||
end
|
||||
|
@ -42,6 +43,7 @@ class YARD::CLI::Yardoc
|
|||
:puppet_defined_type,
|
||||
:puppet_type,
|
||||
:puppet_provider,
|
||||
:puppet_function,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -66,6 +68,10 @@ class YARD::CLI::Stats
|
|||
output 'Puppet Providers', *type_statistics_all(:puppet_provider)
|
||||
end
|
||||
|
||||
def stats_for_puppet_functions
|
||||
output 'Puppet Functions', *type_statistics_all(:puppet_function)
|
||||
end
|
||||
|
||||
def output(name, data, undoc = nil)
|
||||
# Monkey patch output to accommodate our larger header widths
|
||||
@total += data if data.is_a?(Integer) && undoc
|
||||
|
|
|
@ -4,4 +4,5 @@ module PuppetStrings::Yard::CodeObjects
|
|||
require 'puppet-strings/yard/code_objects/defined_type'
|
||||
require 'puppet-strings/yard/code_objects/type'
|
||||
require 'puppet-strings/yard/code_objects/provider'
|
||||
require 'puppet-strings/yard/code_objects/function'
|
||||
end
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
require 'puppet-strings/yard/code_objects/group'
|
||||
|
||||
# Implements the group for Puppet functions.
|
||||
class PuppetStrings::Yard::CodeObjects::Functions < PuppetStrings::Yard::CodeObjects::Group
|
||||
# Gets the singleton instance of the group.
|
||||
# @param [Symbol] type The function type to get the group for.
|
||||
# @return Returns the singleton instance of the group.
|
||||
def self.instance(type)
|
||||
super("puppet_functions_#{type}".intern)
|
||||
end
|
||||
|
||||
# Gets the display name of the group.
|
||||
# @param [Boolean] prefix whether to show a prefix. Ignored for Puppet group namespaces.
|
||||
# @return [String] Returns the display name of the group.
|
||||
def name(prefix = false)
|
||||
'Puppet Functions'
|
||||
end
|
||||
end
|
||||
|
||||
# Implements the Puppet function code object.
|
||||
class PuppetStrings::Yard::CodeObjects::Function < PuppetStrings::Yard::CodeObjects::Base
|
||||
# Identifier for 3.x Ruby API functions
|
||||
RUBY_3X = :ruby3x
|
||||
# Identifier for 4.x Ruby API functions
|
||||
RUBY_4X = :ruby4x
|
||||
# Identifier for Puppet language functions
|
||||
PUPPET = :puppet
|
||||
|
||||
attr_accessor :parameters
|
||||
|
||||
# Initializes a Puppet function code object.
|
||||
# @param [String] name The name of the function.
|
||||
# @param [Symbol] function_type The type of function (e.g. :ruby3x, :ruby4x, :puppet)
|
||||
# @return [void]
|
||||
def initialize(name, function_type)
|
||||
super(PuppetStrings::Yard::CodeObjects::Functions.instance(function_type), name)
|
||||
@parameters = []
|
||||
@function_type = function_type
|
||||
end
|
||||
|
||||
# Gets the type of the code object.
|
||||
# @return Returns the type of the code object.
|
||||
def type
|
||||
:puppet_function
|
||||
end
|
||||
|
||||
# Gets the function type display string.
|
||||
# @return Returns the function type display string.
|
||||
def function_type
|
||||
case @function_type
|
||||
when RUBY_3X
|
||||
'Ruby 3.x API'
|
||||
when RUBY_4X
|
||||
'Ruby 4.x API'
|
||||
else
|
||||
'Puppet Language'
|
||||
end
|
||||
end
|
||||
|
||||
# Gets the Puppet signature of the function.
|
||||
# @return [String] Returns the Puppet signature of the function.
|
||||
def signature
|
||||
tags = self.tags(:param)
|
||||
args = @parameters.map do |parameter|
|
||||
name, default = parameter
|
||||
tag = tags.find { |tag| tag.name == name } if tags
|
||||
type = tag && tag.types ? "#{tag.type} " : 'Any '
|
||||
prefix = "#{name[0]}" if name.start_with?('*', '&')
|
||||
name = name[1..-1] if prefix
|
||||
default = " = #{default}" if default
|
||||
"#{type}#{prefix}$#{name}#{default}"
|
||||
end.join(', ')
|
||||
@name.to_s + '(' + args + ')'
|
||||
end
|
||||
end
|
|
@ -4,11 +4,13 @@ module PuppetStrings::Yard::Handlers
|
|||
module Ruby
|
||||
require 'puppet-strings/yard/handlers/ruby/type_handler'
|
||||
require 'puppet-strings/yard/handlers/ruby/provider_handler'
|
||||
require 'puppet-strings/yard/handlers/ruby/function_handler'
|
||||
end
|
||||
|
||||
# The module for custom Puppet YARD handlers.
|
||||
module Puppet
|
||||
require 'puppet-strings/yard/handlers/puppet/class_handler'
|
||||
require 'puppet-strings/yard/handlers/puppet/defined_type_handler'
|
||||
require 'puppet-strings/yard/handlers/puppet/function_handler'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
require 'puppet-strings/yard/handlers/puppet/base'
|
||||
require 'puppet-strings/yard/parsers'
|
||||
require 'puppet-strings/yard/code_objects'
|
||||
|
||||
# Implements the handler for Puppet classes.
|
||||
class PuppetStrings::Yard::Handlers::Puppet::FunctionHandler < PuppetStrings::Yard::Handlers::Puppet::Base
|
||||
handles PuppetStrings::Yard::Parsers::Puppet::FunctionStatement
|
||||
|
||||
process do
|
||||
# Register the object
|
||||
object = PuppetStrings::Yard::CodeObjects::Function.new(statement.name, PuppetStrings::Yard::CodeObjects::Function::PUPPET)
|
||||
object.source = statement.source
|
||||
object.source_type = parser.parser_type
|
||||
register object
|
||||
|
||||
# Log a warning if missing documentation
|
||||
log.warn "Missing documentation for Puppet function '#{object.name}' at #{statement.file}:#{statement.line}." if object.docstring.empty?
|
||||
|
||||
# Set the parameter tag types
|
||||
set_parameter_types(object)
|
||||
|
||||
# Add a return tag
|
||||
add_return_tag(object)
|
||||
|
||||
# Set the parameters on the object
|
||||
object.parameters = statement.parameters.map { |p| [p.name, p.value] }
|
||||
|
||||
# Mark the class as public if it doesn't already have an api tag
|
||||
object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
|
||||
end
|
||||
|
||||
private
|
||||
def add_return_tag(object)
|
||||
tag = object.tag(:return)
|
||||
if tag
|
||||
tag.types = ['Any'] unless tag.types
|
||||
return
|
||||
end
|
||||
log.warn "Missing @return tag near #{statement.file}:#{statement.line}."
|
||||
object.add_tag YARD::Tags::Tag.new(:return, '', 'Any')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,357 @@
|
|||
require 'puppet-strings/yard/handlers/ruby/base'
|
||||
require 'puppet-strings/yard/code_objects'
|
||||
require 'puppet/util/docs'
|
||||
|
||||
# Implements the handler for Puppet functions written in Ruby.
|
||||
class PuppetStrings::Yard::Handlers::Ruby::FunctionHandler < PuppetStrings::Yard::Handlers::Ruby::Base
|
||||
# Represents the list of Puppet 4.x function API methods to support.
|
||||
DISPATCH_METHOD_NAMES = %w(
|
||||
param
|
||||
required_param
|
||||
optional_param
|
||||
repeated_param
|
||||
optional_repeated_param
|
||||
required_repeated_param
|
||||
block_param
|
||||
required_block_param
|
||||
optional_block_param
|
||||
).freeze
|
||||
|
||||
namespace_only
|
||||
handles method_call(:create_function)
|
||||
handles method_call(:newfunction)
|
||||
|
||||
process do
|
||||
# Only accept calls to Puppet::Functions (4.x) or Puppet::Parser::Functions (3.x)
|
||||
return unless statement.count > 1
|
||||
module_name = statement[0].source
|
||||
return unless module_name == 'Puppet::Functions' || module_name == 'Puppet::Parser::Functions'
|
||||
|
||||
# Create and register the function object
|
||||
is_3x = module_name == 'Puppet::Parser::Functions'
|
||||
object = PuppetStrings::Yard::CodeObjects::Function.new(
|
||||
get_name,
|
||||
is_3x ? PuppetStrings::Yard::CodeObjects::Function::RUBY_3X : PuppetStrings::Yard::CodeObjects::Function::RUBY_4X
|
||||
)
|
||||
object.source = statement
|
||||
register object
|
||||
|
||||
# For 3x, parse the doc parameter for the docstring
|
||||
# This must be done after the `register` call above because `register` always uses the statement's docstring
|
||||
if is_3x
|
||||
docstring = get_3x_docstring(object.name)
|
||||
register_docstring(object, docstring, nil) if docstring
|
||||
|
||||
# Default any typeless param tag to 'Any'
|
||||
object.tags(:param).each do |tag|
|
||||
tag.types = ['Any'] unless tag.types && !tag.types.empty?
|
||||
end
|
||||
|
||||
# Populate the parameters and the return tag
|
||||
object.parameters = object.tags(:param).map{ |p| [p.name, nil] }
|
||||
add_return_tag(object, statement.file, statement.line)
|
||||
else
|
||||
# For 4x, auto generate tags based on dispatch docstrings
|
||||
add_tags(object)
|
||||
end
|
||||
|
||||
# Mark the function as public if it doesn't already have an api tag
|
||||
object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
|
||||
end
|
||||
|
||||
private
|
||||
def get_name
|
||||
parameters = statement.parameters(false)
|
||||
raise YARD::Parser::UndocumentableError, "Expected at least one parameter to Puppet::Functions.create_function at #{statement.file}:#{statement.line}." if parameters.empty?
|
||||
name = node_as_string(parameters.first)
|
||||
raise YARD::Parser::UndocumentableError, "Expected a symbol or string literal for first parameter but found '#{parameters.first.type}' at #{statement.file}:#{statement.line}." unless name
|
||||
name
|
||||
end
|
||||
|
||||
def add_tags(object)
|
||||
log.warn "Missing documentation for Puppet function '#{object.name}' at #{statement.file}:#{statement.line}." if object.docstring.empty?
|
||||
log.warn "The docstring for Puppet 4.x function '#{object.name}' contains @param tags near #{object.file}:#{object.line}: parameter documentation should be made on the dispatch call." unless object.tags(:param).empty?
|
||||
log.warn "The docstring for Puppet 4.x function '#{object.name}' contains @return tags near #{object.file}:#{object.line}: return value documentation should be made on the dispatch call." unless object.tags(:return).empty?
|
||||
log.warn "The docstring for Puppet 4.x function '#{object.name}' contains @overload tags near #{object.file}:#{object.line}: overload tags are automatically generated from the dispatch calls." unless object.tags(:overload).empty?
|
||||
|
||||
# Delete any existing param/return/overload tags
|
||||
object.docstring.delete_tags(:param)
|
||||
object.docstring.delete_tags(:return)
|
||||
object.docstring.delete_tags(:overload)
|
||||
|
||||
block = statement.block
|
||||
return unless block && block.count >= 2
|
||||
|
||||
# Get the unqualified name of the Puppet function
|
||||
unqualified_name = object.name.to_s.split('::').last
|
||||
|
||||
# Walk the block statements looking for dispatch calls and methods with the same name as the Puppet function
|
||||
default = nil
|
||||
block[1].children.each do |node|
|
||||
if node.is_a?(YARD::Parser::Ruby::MethodCallNode)
|
||||
add_overload_tag(object, node)
|
||||
elsif node.is_a?(YARD::Parser::Ruby::MethodDefinitionNode)
|
||||
default = node if node.method_name && node.method_name.source == unqualified_name
|
||||
end
|
||||
end
|
||||
|
||||
# Create an overload for the default method if there is one
|
||||
overloads = object.tags(:overload)
|
||||
if overloads.empty? && default
|
||||
add_method_overload(object, default)
|
||||
overloads = object.tags(:overload)
|
||||
end
|
||||
|
||||
# If there's only one overload, move the tags to the object itself
|
||||
if overloads.count == 1
|
||||
overload = overloads.first
|
||||
object.parameters = overload.parameters
|
||||
object.add_tag(*overload.tags)
|
||||
object.docstring.delete_tags(:overload)
|
||||
end
|
||||
end
|
||||
|
||||
def add_overload_tag(object, node)
|
||||
# Look for a call to a dispatch method with a block
|
||||
return unless node.is_a?(YARD::Parser::Ruby::MethodCallNode) &&
|
||||
node.method_name &&
|
||||
node.method_name.source == 'dispatch' &&
|
||||
node.parameters(false).count == 1 &&
|
||||
node.block &&
|
||||
node.block.count >= 2
|
||||
|
||||
overload_tag = PuppetStrings::Yard::Tags::OverloadTag.new(object.name, node.docstring || '')
|
||||
param_tags = overload_tag.tags(:param)
|
||||
|
||||
block = nil
|
||||
node.block[1].children.each do |child|
|
||||
next unless child.is_a?(YARD::Parser::Ruby::MethodCallNode) && child.method_name
|
||||
|
||||
method_name = child.method_name.source
|
||||
next unless DISPATCH_METHOD_NAMES.include?(method_name)
|
||||
|
||||
# Check for block
|
||||
if method_name.include?('block')
|
||||
if block
|
||||
log.warn "A duplicate block parameter was found for Puppet function '#{object.name}' at #{child.file}:#{child.line}."
|
||||
next
|
||||
end
|
||||
|
||||
# Store the block; needs to be appended last
|
||||
block = child
|
||||
next
|
||||
end
|
||||
|
||||
# Ensure two parameters to parameter definition
|
||||
parameters = child.parameters(false)
|
||||
unless parameters.count == 2
|
||||
log.warn "Expected 2 arguments to '#{method_name}' call at #{child.file}:#{child.line}: parameter information may not be correct."
|
||||
next
|
||||
end
|
||||
|
||||
add_param_tag(
|
||||
overload_tag,
|
||||
param_tags,
|
||||
node_as_string(parameters[1]),
|
||||
child.file,
|
||||
child.line,
|
||||
node_as_string(parameters[0]),
|
||||
nil, # TODO: determine default from corresponding Ruby method signature?
|
||||
method_name.include?('optional'),
|
||||
method_name.include?('repeated')
|
||||
)
|
||||
end
|
||||
|
||||
# Handle the block parameter after others so it appears last in the list
|
||||
if block
|
||||
parameters = block.parameters(false)
|
||||
if parameters.empty?
|
||||
name = 'block'
|
||||
type = 'Callable'
|
||||
elsif parameters.count == 1
|
||||
name = node_as_string(parameters[0])
|
||||
type = 'Callable'
|
||||
elsif parameters.count == 2
|
||||
type = node_as_string(parameters[0])
|
||||
name = node_as_string(parameters[1])
|
||||
else
|
||||
log.warn "Unexpected number of arguments to block definition at #{block.file}:#{block.line}."
|
||||
end
|
||||
|
||||
if name && type
|
||||
add_param_tag(
|
||||
overload_tag,
|
||||
param_tags,
|
||||
name,
|
||||
block.file,
|
||||
block.line,
|
||||
type,
|
||||
nil, # TODO: determine default from corresponding Ruby method signature?
|
||||
block.method_name.source.include?('optional'),
|
||||
false, # Not repeated
|
||||
true # Is block
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Add a return tag if missing
|
||||
add_return_tag(overload_tag, node.file, node.line)
|
||||
|
||||
# Validate that tags have parameters
|
||||
validate_overload(overload_tag, node.file, node.line)
|
||||
|
||||
object.add_tag overload_tag
|
||||
end
|
||||
|
||||
def add_method_overload(object, node)
|
||||
overload_tag = PuppetStrings::Yard::Tags::OverloadTag.new(object.name, node.docstring || '')
|
||||
param_tags = overload_tag.tags(:param)
|
||||
|
||||
parameters = node.parameters
|
||||
|
||||
# Populate the required parameters
|
||||
params = parameters.unnamed_required_params
|
||||
if params
|
||||
params.each do |parameter|
|
||||
add_param_tag(
|
||||
overload_tag,
|
||||
param_tags,
|
||||
parameter.source,
|
||||
parameter.file,
|
||||
parameter.line
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Populate the optional parameters
|
||||
params = parameters.unnamed_optional_params
|
||||
if params
|
||||
params.each do |parameter|
|
||||
add_param_tag(
|
||||
overload_tag,
|
||||
param_tags,
|
||||
parameter[0].source,
|
||||
parameter.file,
|
||||
parameter.line,
|
||||
nil,
|
||||
parameter[1].source,
|
||||
true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Populate the splat parameter
|
||||
param = parameters.splat_param
|
||||
if param
|
||||
add_param_tag(
|
||||
overload_tag,
|
||||
param_tags,
|
||||
param.source,
|
||||
param.file,
|
||||
param.line,
|
||||
nil,
|
||||
nil,
|
||||
false,
|
||||
true
|
||||
)
|
||||
end
|
||||
|
||||
# Populate the block parameter
|
||||
param = parameters.block_param
|
||||
if param
|
||||
add_param_tag(
|
||||
overload_tag,
|
||||
param_tags,
|
||||
param.source,
|
||||
param.file,
|
||||
param.line,
|
||||
nil,
|
||||
nil,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
)
|
||||
end
|
||||
|
||||
# Add a return tag if missing
|
||||
add_return_tag(overload_tag, node.file, node.line)
|
||||
|
||||
# Validate that tags have parameters
|
||||
validate_overload(overload_tag, node.file, node.line)
|
||||
|
||||
object.add_tag overload_tag
|
||||
end
|
||||
|
||||
def add_param_tag(object, tags, name, file, line, type = nil, default = nil, optional = false, repeated = false, block = false)
|
||||
tag = tags.find { |tag| tag.name == name } if tags
|
||||
log.warn "Missing @param tag for parameter '#{name}' near #{file}:#{line}." unless tag || object.docstring.all.empty?
|
||||
log.warn "The @param tag for parameter '#{name}' should not contain a type specification near #{file}:#{line}: ignoring in favor of dispatch type information." if type && tag && tag.types && !tag.types.empty?
|
||||
|
||||
if repeated
|
||||
name = '*' + name
|
||||
elsif block
|
||||
name = '&' + name
|
||||
end
|
||||
|
||||
unless type
|
||||
type = tag && tag.types ? tag.type : 'Any'
|
||||
end
|
||||
type = optional ? "Optional[#{type}]" : type
|
||||
|
||||
object.parameters << [name, to_puppet_literal(default)]
|
||||
|
||||
if tag
|
||||
tag.name = name
|
||||
tag.types = [type]
|
||||
else
|
||||
object.add_tag YARD::Tags::Tag.new(:param, '', type, name)
|
||||
end
|
||||
end
|
||||
|
||||
def add_return_tag(object, file, line)
|
||||
tag = object.tag(:return)
|
||||
if tag
|
||||
tag.types = ['Any'] unless tag.types
|
||||
return
|
||||
end
|
||||
log.warn "Missing @return tag near #{file}:#{line}."
|
||||
object.add_tag YARD::Tags::Tag.new(:return, '', 'Any')
|
||||
end
|
||||
|
||||
def validate_overload(overload, file, line)
|
||||
# Validate that tags have matching parameters
|
||||
overload.tags(:param).each do |tag|
|
||||
next if overload.parameters.find { |p| tag.name == p[0] }
|
||||
log.warn "The @param tag for parameter '#{tag.name}' has no matching parameter at #{file}:#{line}."
|
||||
end
|
||||
end
|
||||
|
||||
def get_3x_docstring(name)
|
||||
parameters = statement.parameters(false)
|
||||
if parameters.count >= 2
|
||||
parameters[1].each do |kvp|
|
||||
next unless kvp.count == 2
|
||||
next unless node_as_string(kvp[0]) == 'doc'
|
||||
docstring = node_as_string(kvp[1])
|
||||
|
||||
log.error "Failed to parse docstring for 3.x Puppet function '#{name}' near #{statement.file}:#{statement.line}." and return nil unless docstring
|
||||
return Puppet::Util::Docs.scrub(docstring)
|
||||
end
|
||||
end
|
||||
|
||||
# Log a warning for missing docstring
|
||||
log.warn "Missing documentation for Puppet function '#{name}' at #{statement.file}:#{statement.line}."
|
||||
nil
|
||||
end
|
||||
|
||||
def to_puppet_literal(literal)
|
||||
case literal
|
||||
when 'nil'
|
||||
'undef'
|
||||
when ':default'
|
||||
'default'
|
||||
else
|
||||
literal
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,4 +2,5 @@
|
|||
module PuppetStrings::Yard::Tags
|
||||
require 'puppet-strings/yard/tags/parameter_directive'
|
||||
require 'puppet-strings/yard/tags/property_directive'
|
||||
require 'puppet-strings/yard/tags/overload_tag'
|
||||
end
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
# Implements an overload tag for Puppet functions
|
||||
#
|
||||
# This differs from Yard's overload tag in that the signatures are formatted according to Puppet language rules.
|
||||
class PuppetStrings::Yard::Tags::OverloadTag < YARD::Tags::Tag
|
||||
attr_reader :parameters, :docstring
|
||||
|
||||
# Initializes the overload tag.
|
||||
# @param [String, Symbol] name The name of the function being overloaded.
|
||||
# @param [String] docstring The docstring for the overload.
|
||||
# @return [void]
|
||||
def initialize(name, docstring)
|
||||
super(:overload, nil)
|
||||
@name = name.to_s
|
||||
@parameters = []
|
||||
@docstring = YARD::Docstring.new(docstring)
|
||||
end
|
||||
|
||||
# Gets the signature of the overload.
|
||||
# @return [String] Returns the signature of the overload.
|
||||
def signature
|
||||
tags = self.tags(:param)
|
||||
args = @parameters.map do |parameter|
|
||||
name, default = parameter
|
||||
tag = tags.find { |tag| tag.name == name } if tags
|
||||
type = tag && tag.types ? "#{tag.type} " : 'Any '
|
||||
prefix = "#{name[0]}" if name.start_with?('*', '&')
|
||||
name = name[1..-1] if prefix
|
||||
default = " = #{default}" if default
|
||||
"#{type}#{prefix}$#{name}#{default}"
|
||||
end.join(', ')
|
||||
@name + '(' + args + ')'
|
||||
end
|
||||
|
||||
# Adds a tag to the overload's docstring.
|
||||
# @param [YARD::Tag] tag The tag to add to the overload's docstring.
|
||||
# @return [void]
|
||||
def add_tag(tag)
|
||||
@docstring.add_tag(tag)
|
||||
end
|
||||
|
||||
# Gets the first tag of the given name.
|
||||
# @param [String, Symbol] name The name of the tag.
|
||||
# @return [YARD::Tag] Returns the first tag if found or nil if not found.
|
||||
def tag(name)
|
||||
@docstring.tag(name)
|
||||
end
|
||||
|
||||
# Gets all tags or tags of a given name.
|
||||
# @param [String, Symbol] name The name of the tag to get or nil for all tags.
|
||||
# @return [Array<Yard::Tag>] Returns an array of tags.
|
||||
def tags(name = nil)
|
||||
@docstring.tags(name)
|
||||
end
|
||||
|
||||
# Determines if a tag with the given name is present.
|
||||
# @param [String, Symbol] name The tag name.
|
||||
# @return [Boolean] Returns true if there is at least one tag with the given name or false if not.
|
||||
def has_tag?(name)
|
||||
@docstring.has_tag?(name)
|
||||
end
|
||||
|
||||
# Sets the object associated with this tag.
|
||||
# @param [Object] value The object to associate with this tag.
|
||||
# @return [void]
|
||||
def object=(value)
|
||||
super(value)
|
||||
@docstring.object = value
|
||||
@docstring.tags.each {|tag| tag.object = value }
|
||||
end
|
||||
|
||||
# Responsible for forwarding method calls to the associated object.
|
||||
# @param [Symbol] method_name The method being invoked.
|
||||
# @param [Array] args The args passed to the method.
|
||||
# @param block The block passed to the method.
|
||||
# @return Returns what the method call on the object would return.
|
||||
def method_missing(method_name, *args, &block)
|
||||
return object.send(method_name, *args, &block) if object.respond_to? method_name
|
||||
super
|
||||
end
|
||||
|
||||
# Determines if the associated object responds to the give missing method name.
|
||||
# @param [Symbol, String] method_name The name of the method to check.
|
||||
# @param [Boolean] include_all True to include all methods in the check or false for only public methods.
|
||||
# @return [Boolean] Returns true if the object responds to the method or false if not.
|
||||
def respond_to_missing?(method_name, include_all = false)
|
||||
object.respond_to?(method_name, include_all) || super
|
||||
end
|
||||
|
||||
# Gets the type of the object associated with this tag.
|
||||
# @return [Symbol] Returns the type of the object associated with this tag.
|
||||
def type
|
||||
object.type
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
<% even = false %>
|
||||
<% @items.each do |item| %>
|
||||
<li id="object_<%=item.path%>" class="<%= even ? 'even' : 'odd' %>">
|
||||
<div class="item">
|
||||
<%= linkify item, h(item.name(false)) %>
|
||||
<small><%= item.function_type %></small>
|
||||
</div>
|
||||
</li>
|
||||
<% even = !even %>
|
||||
<% end %>
|
|
@ -34,6 +34,15 @@ def generate_puppet_provider_list
|
|||
generate_list_contents
|
||||
end
|
||||
|
||||
# Generates the searchable Puppet function list.
|
||||
# @return [void]
|
||||
def generate_puppet_function_list
|
||||
@items = Registry.all(:puppet_function).sort_by {|f| f.name.to_s }
|
||||
@list_title = 'Puppet Function List'
|
||||
@list_type = 'puppet_function'
|
||||
generate_list_contents
|
||||
end
|
||||
|
||||
# Generates the searchable Ruby method list.
|
||||
# @return [void]
|
||||
def generate_method_list
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
<small>(<%= obj.namespace.path %>)</small>
|
||||
<% elsif obj.type == :puppet_provider %>
|
||||
<small>(Resource type: <%= obj.type_name %>)</small>
|
||||
<% elsif obj.type == :puppet_function %>
|
||||
<small>(<%= obj.function_type %>)</small>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
@ -4,7 +4,7 @@ def init
|
|||
case object
|
||||
when '_index.html'
|
||||
@page_title = options.title
|
||||
sections :layout, [:index, [:listing, [:classes, :defined_types, :types, :providers, :files, :objects]]]
|
||||
sections :layout, [:index, [:listing, [:classes, :defined_types, :types, :providers, :functions, :files, :objects]]]
|
||||
else
|
||||
super
|
||||
end
|
||||
|
@ -42,6 +42,10 @@ def layout
|
|||
@nav_url = url_for_list('puppet_provider')
|
||||
@page_title = "Provider: #{object.name}"
|
||||
@path = object.path
|
||||
when PuppetStrings::Yard::CodeObjects::Function
|
||||
@nav_url = url_for_list('puppet_function')
|
||||
@page_title = "Puppet Function: #{object.name} (#{object.function_type})"
|
||||
@path = object.path
|
||||
else
|
||||
@path = object.path
|
||||
end
|
||||
|
@ -73,6 +77,11 @@ def create_menu_lists
|
|||
title: 'Providers',
|
||||
search_title: 'Providers'
|
||||
},
|
||||
{
|
||||
type: 'puppet_function',
|
||||
title: 'Puppet Functions',
|
||||
search_title: 'Puppet Functions'
|
||||
},
|
||||
{
|
||||
type: 'class',
|
||||
title: 'Ruby Classes',
|
||||
|
@ -146,6 +155,14 @@ def providers
|
|||
erb(:objects)
|
||||
end
|
||||
|
||||
# Renders the functions section.
|
||||
# @return [String] Returns the rendered section.
|
||||
def functions
|
||||
@title = 'Puppet Function Listing A-Z'
|
||||
@objects_by_letter = objects_by_letter(:puppet_function)
|
||||
erb(:objects)
|
||||
end
|
||||
|
||||
# Renders the objects section.
|
||||
# @return [String] Returns the rendered section.
|
||||
def objects
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<div class="box_info">
|
||||
<dl>
|
||||
<dt>Defined in:</dt>
|
||||
<dd>
|
||||
<%= object.file %><% if object.files.size > 1 %><span class="defines">,<br />
|
||||
<%= object.files[1..-1].map {|f| f.first }.join(",<br /> ") %></div>
|
||||
<% end %>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Function type:</dt>
|
||||
<dd><%= object.function_type %></dd>
|
||||
</dl>
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
<h1>Puppet Function: <%= object.name %></h1>
|
|
@ -0,0 +1,18 @@
|
|||
<h2>Overview</h2>
|
||||
<div class="method_details first">
|
||||
<% unless object.has_tag? :overload %>
|
||||
<div class="tags overload overload_item">
|
||||
<span class="overload">
|
||||
<span class="overload_item">
|
||||
<span class="signature first" style="margin-left: 0px;"><%= "<strong>#{h(object.signature)}</strong> ⇒ #{signature_types(object, false)}" %></span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="docstring">
|
||||
<div class="discussion">
|
||||
<%= htmlify(object.docstring) %>
|
||||
</div>
|
||||
</div>
|
||||
<%= yieldall %>
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
# Initializes the template.
|
||||
# @return [void]
|
||||
def init
|
||||
sections :header, :box_info, :overview, [T('tags'), :source]
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
<div class="method_details_list">
|
||||
<table class="source_code">
|
||||
<tr>
|
||||
<td>
|
||||
<pre class="lines"><%= "\n\n\n" %><%= h format_lines(object) %></pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre class="code"><span class="info file"># File '<%= h object.file %>'<% if object.line %>, line <%= object.line %><% end %></span><%= "\n\n" %><%= html_syntax_highlight object.source %></pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,12 @@
|
|||
<% if object.has_tag?(:overload) && object.tags(:overload).any? {|o| !o.docstring.blank? } %>
|
||||
<p class="tag_title">Overloads:</p>
|
||||
<ul class="overload">
|
||||
<% object.tags(:overload).each_with_index do |overload, index| %>
|
||||
<% next if overload.docstring.blank? %>
|
||||
<li class="overload_item">
|
||||
<span class="signature"><%= "<strong>#{h(overload.signature)}</strong> ⇒ #{signature_types(overload, false)}" %></span>
|
||||
<%= yieldall :object => overload %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
|
@ -4,5 +4,12 @@ def param
|
|||
tag(:param) if
|
||||
object.type == :method ||
|
||||
object.type == :puppet_class ||
|
||||
object.type == :puppet_defined_type
|
||||
object.type == :puppet_defined_type ||
|
||||
object.type == :puppet_function
|
||||
end
|
||||
|
||||
# Renders the overload section.
|
||||
# @return [String] Returns the rendered section.
|
||||
def overload
|
||||
erb(if object.type == :puppet_function then :puppet_overload else :overload end)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue