Merge pull request #46 from iankronquist/defined-types-and-providers-pdoc-35
(PDOC-35) Support types and providers
This commit is contained in:
commit
623011fd4a
|
@ -1,4 +1,5 @@
|
||||||
require 'puppet/face'
|
require 'puppet/face'
|
||||||
|
require 'puppet_x/puppetlabs/strings/yard/tags/directives'
|
||||||
|
|
||||||
Puppet::Face.define(:strings, '0.0.1') do
|
Puppet::Face.define(:strings, '0.0.1') do
|
||||||
summary "Generate Puppet documentation with YARD."
|
summary "Generate Puppet documentation with YARD."
|
||||||
|
@ -55,6 +56,9 @@ Puppet::Face.define(:strings, '0.0.1') do
|
||||||
# all over the terminal. This should definitely not be in real code, but
|
# all over the terminal. This should definitely not be in real code, but
|
||||||
# it's very handy for debugging with pry
|
# it's very handy for debugging with pry
|
||||||
#class YARD::Logger; def progress(*args); end; end
|
#class YARD::Logger; def progress(*args); end; end
|
||||||
|
YARD::Tags::Library.define_directive("puppet.type.param",
|
||||||
|
:with_types_and_name,
|
||||||
|
PuppetX::PuppetLabs::Strings::YARD::Tags::PuppetTypeParameterDirective)
|
||||||
|
|
||||||
yardoc_actions.generate_documentation(*yard_args)
|
yardoc_actions.generate_documentation(*yard_args)
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,18 @@ module PuppetX::PuppetLabs
|
||||||
require 'puppet_x/puppetlabs/strings/yard/monkey_patches'
|
require 'puppet_x/puppetlabs/strings/yard/monkey_patches'
|
||||||
require 'puppet_x/puppetlabs/strings/yard/parser'
|
require 'puppet_x/puppetlabs/strings/yard/parser'
|
||||||
|
|
||||||
|
module Tags
|
||||||
|
require 'puppet_x/puppetlabs/strings/yard/tags/directives'
|
||||||
|
end
|
||||||
|
|
||||||
# This submodule contains code objects which are used to represent relevant
|
# This submodule contains code objects which are used to represent relevant
|
||||||
# aspects of puppet code in YARD's Registry
|
# aspects of puppet code in YARD's Registry
|
||||||
module CodeObjects
|
module CodeObjects
|
||||||
require 'puppet_x/puppetlabs/strings/yard/code_objects/puppet_namespace_object'
|
require 'puppet_x/puppetlabs/strings/yard/code_objects/puppet_namespace_object'
|
||||||
require 'puppet_x/puppetlabs/strings/yard/code_objects/defined_type_object'
|
require 'puppet_x/puppetlabs/strings/yard/code_objects/defined_type_object'
|
||||||
require 'puppet_x/puppetlabs/strings/yard/code_objects/host_class_object'
|
require 'puppet_x/puppetlabs/strings/yard/code_objects/host_class_object'
|
||||||
|
require 'puppet_x/puppetlabs/strings/yard/code_objects/type_object'
|
||||||
|
require 'puppet_x/puppetlabs/strings/yard/code_objects/provider_object'
|
||||||
end
|
end
|
||||||
|
|
||||||
# This submodule contains handlers which are used to extract relevant data about
|
# This submodule contains handlers which are used to extract relevant data about
|
||||||
|
@ -38,6 +44,8 @@ module PuppetX::PuppetLabs
|
||||||
require 'puppet_x/puppetlabs/strings/yard/handlers/host_class_handler'
|
require 'puppet_x/puppetlabs/strings/yard/handlers/host_class_handler'
|
||||||
require 'puppet_x/puppetlabs/strings/yard/handlers/puppet_3x_function_handler'
|
require 'puppet_x/puppetlabs/strings/yard/handlers/puppet_3x_function_handler'
|
||||||
require 'puppet_x/puppetlabs/strings/yard/handlers/puppet_4x_function_handler'
|
require 'puppet_x/puppetlabs/strings/yard/handlers/puppet_4x_function_handler'
|
||||||
|
require 'puppet_x/puppetlabs/strings/yard/handlers/type_handler'
|
||||||
|
require 'puppet_x/puppetlabs/strings/yard/handlers/provider_handler'
|
||||||
end
|
end
|
||||||
|
|
||||||
::YARD::Parser::SourceParser.register_parser_type(:puppet,
|
::YARD::Parser::SourceParser.register_parser_type(:puppet,
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class PuppetX::PuppetLabs::Strings::YARD::CodeObjects::ProviderObject < PuppetX::PuppetLabs::Strings::YARD::CodeObjects::PuppetNamespaceObject
|
||||||
|
# A list of parameters attached to this class.
|
||||||
|
# @return [Array<Array(String, String)>]
|
||||||
|
attr_accessor :parameters
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class PuppetX::PuppetLabs::Strings::YARD::CodeObjects::TypeObject < PuppetX::PuppetLabs::Strings::YARD::CodeObjects::PuppetNamespaceObject
|
||||||
|
# A list of parameters attached to this class.
|
||||||
|
# @return [Array<Array(String, String)>]
|
||||||
|
attr_accessor :parameters
|
||||||
|
end
|
|
@ -0,0 +1,80 @@
|
||||||
|
class HereDocHelper
|
||||||
|
# NOTE: The following methods duplicate functionality from
|
||||||
|
# Puppet::Util::Reference and Puppet::Parser::Functions.functiondocs
|
||||||
|
#
|
||||||
|
# However, implementing this natively in YARD is a good test for the
|
||||||
|
# feasibility of extracting custom Ruby documentation. In the end, the
|
||||||
|
# existing approach taken by Puppet::Util::Reference may be the best due to
|
||||||
|
# the heavy use of metaprogramming in Types and Providers.
|
||||||
|
|
||||||
|
# Extracts the Puppet function name and options hash from the parsed
|
||||||
|
# definition.
|
||||||
|
#
|
||||||
|
# @return [(String, Hash{String => String})]
|
||||||
|
def process_parameters(statement)
|
||||||
|
# Passing `false` to prameters excludes the block param from the returned
|
||||||
|
# list.
|
||||||
|
name, opts = statement.parameters(false).compact
|
||||||
|
|
||||||
|
name = process_element(name)
|
||||||
|
|
||||||
|
# Don't try to process options if we don't have any
|
||||||
|
if !opts.nil?
|
||||||
|
opts = opts.map do |tuple|
|
||||||
|
# Jump down into the S-Expression that represents a hashrocket, `=>`,
|
||||||
|
# and the values on either side of it.
|
||||||
|
tuple.jump(:assoc).map{|e| process_element(e)}
|
||||||
|
end
|
||||||
|
|
||||||
|
options = Hash[opts]
|
||||||
|
else
|
||||||
|
options = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
[name, options]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sometimes the YARD parser returns Heredoc strings that start with `<-`
|
||||||
|
# instead of `<<-`.
|
||||||
|
HEREDOC_START = /^<?<-/
|
||||||
|
|
||||||
|
def is_heredoc?(str)
|
||||||
|
HEREDOC_START.match(str)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Turns an entry in the method parameter list into a string.
|
||||||
|
#
|
||||||
|
# @param ele [YARD::Parser::Ruby::AstNode]
|
||||||
|
# @return [String]
|
||||||
|
def process_element(ele)
|
||||||
|
ele = ele.jump(:ident, :string_content)
|
||||||
|
|
||||||
|
case ele.type
|
||||||
|
when :ident
|
||||||
|
ele.source
|
||||||
|
when :string_content
|
||||||
|
source = ele.source
|
||||||
|
if is_heredoc? source
|
||||||
|
process_heredoc(source)
|
||||||
|
else
|
||||||
|
source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Cleans up and formats Heredoc contents parsed by YARD.
|
||||||
|
#
|
||||||
|
# @param source [String]
|
||||||
|
# @return [String]
|
||||||
|
def process_heredoc(source)
|
||||||
|
source = source.lines.to_a
|
||||||
|
|
||||||
|
# YARD adds a line of source context on either side of the Heredoc
|
||||||
|
# contents.
|
||||||
|
source.shift
|
||||||
|
source.pop
|
||||||
|
|
||||||
|
# This utility method normalizes indentation and trims whitespace.
|
||||||
|
Puppet::Util::Docs.scrub(source.join)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,94 @@
|
||||||
|
# Handles `dispatch` calls within a future parser function declaration. For
|
||||||
|
# now, it just treats any docstring as an `@overlaod` tag and attaches the
|
||||||
|
# overload to the parent function.
|
||||||
|
class PuppetX::PuppetLabs::Strings::YARD::Handlers::PuppetProviderHandler < YARD::Handlers::Ruby::Base
|
||||||
|
include PuppetX::PuppetLabs::Strings::YARD::CodeObjects
|
||||||
|
|
||||||
|
handles :command_call, :call
|
||||||
|
|
||||||
|
process do
|
||||||
|
@heredoc_helper = HereDocHelper.new
|
||||||
|
# Puppet types always begin with:
|
||||||
|
# Puppet::Types.newtype...
|
||||||
|
# Therefore, we match the corresponding trees which look like this:
|
||||||
|
# s(:call,
|
||||||
|
# s(:const_path_ref,
|
||||||
|
# s(:var_ref, s(:const, "Puppet", ...), ...),
|
||||||
|
# s(:const, "Type", ...),
|
||||||
|
# You think this is ugly? It's better than the alternative.
|
||||||
|
return unless statement.children.length > 2
|
||||||
|
first = statement.children.first.first
|
||||||
|
return unless (first.source == 'Puppet::Type') ||
|
||||||
|
(first.type == :var_ref &&
|
||||||
|
first.source == 'Type') &&
|
||||||
|
statement[2].source == 'provide'
|
||||||
|
i = statement.index { |s| YARD::Parser::Ruby::AstNode === s && s.type == :ident && s.source == 'provide' }
|
||||||
|
provider_name = statement[i+1].jump(:ident).source
|
||||||
|
type_name = statement.jump(:symbol).first.source
|
||||||
|
|
||||||
|
obj = ProviderObject.new(:root, provider_name)
|
||||||
|
|
||||||
|
docstring = nil
|
||||||
|
features = []
|
||||||
|
commands = []
|
||||||
|
confines = {}
|
||||||
|
defaults = {}
|
||||||
|
do_block = statement.jump(:do_block)
|
||||||
|
do_block.traverse do |node|
|
||||||
|
if is_a_func_call_named?('desc', node)
|
||||||
|
content = node.jump(:tstring_content)
|
||||||
|
# if we found the string content extract its source
|
||||||
|
if content != node
|
||||||
|
# The docstring is either the source stripped of heredoc
|
||||||
|
# annotations or the raw source.
|
||||||
|
if @heredoc_helper.is_heredoc?(content.source)
|
||||||
|
docstring = @heredoc_helper.process_heredoc content.source
|
||||||
|
else
|
||||||
|
docstring = content.source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif is_a_func_call_named?('confine', node)
|
||||||
|
node.traverse do |s|
|
||||||
|
if s.type == :assoc
|
||||||
|
k = s.first.jump(:ident).source
|
||||||
|
v = s[1].first.source
|
||||||
|
confines[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif is_a_func_call_named?('has_feature', node)
|
||||||
|
list = node.jump :list
|
||||||
|
if list != nil && list != node
|
||||||
|
features += list.map { |s| s.source if YARD::Parser::Ruby::AstNode === s }.compact
|
||||||
|
end
|
||||||
|
elsif is_a_func_call_named?('commands', node)
|
||||||
|
assoc = node.jump(:assoc)
|
||||||
|
if assoc && assoc != node
|
||||||
|
ident = assoc.jump(:ident)
|
||||||
|
if ident && ident != assoc
|
||||||
|
commands << ident.source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif is_a_func_call_named?('defaultfor', node)
|
||||||
|
node.traverse do |s|
|
||||||
|
if s.type == :assoc
|
||||||
|
k = s.first.jump(:ident).source
|
||||||
|
v = s[1].first.source
|
||||||
|
defaults[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
obj.features = features
|
||||||
|
obj.commands = commands
|
||||||
|
obj.confines = confines
|
||||||
|
obj.defaults = defaults
|
||||||
|
obj.type_name = type_name
|
||||||
|
|
||||||
|
register_docstring(obj, docstring, nil)
|
||||||
|
register obj
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_a_func_call_named?(name, node)
|
||||||
|
(node.type == :fcall || node.type == :command || node.type == :vcall) && node.children.first.source == name
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,10 +1,13 @@
|
||||||
|
require File.join(File.dirname(__FILE__),'./heredoc_helper')
|
||||||
|
|
||||||
class PuppetX::PuppetLabs::Strings::YARD::Handlers::Puppet3xFunctionHandler < YARD::Handlers::Ruby::Base
|
class PuppetX::PuppetLabs::Strings::YARD::Handlers::Puppet3xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||||
include PuppetX::PuppetLabs::Strings::YARD::CodeObjects
|
include PuppetX::PuppetLabs::Strings::YARD::CodeObjects
|
||||||
|
|
||||||
handles method_call(:newfunction)
|
handles method_call(:newfunction)
|
||||||
|
|
||||||
process do
|
process do
|
||||||
name, options = process_parameters
|
@heredoc_helper = HereDocHelper.new
|
||||||
|
name, options = @heredoc_helper.process_parameters statement
|
||||||
|
|
||||||
obj = MethodObject.new(function_namespace, name)
|
obj = MethodObject.new(function_namespace, name)
|
||||||
|
|
||||||
|
@ -47,78 +50,4 @@ class PuppetX::PuppetLabs::Strings::YARD::Handlers::Puppet3xFunctionHandler < YA
|
||||||
obj
|
obj
|
||||||
end
|
end
|
||||||
|
|
||||||
# NOTE: The following methods duplicate functionality from
|
|
||||||
# Puppet::Util::Reference and Puppet::Parser::Functions.functiondocs
|
|
||||||
#
|
|
||||||
# However, implementing this natively in YARD is a good test for the
|
|
||||||
# feasibility of extracting custom Ruby documentation. In the end, the
|
|
||||||
# existing approach taken by Puppet::Util::Reference may be the best due to
|
|
||||||
# the heavy use of metaprogramming in Types and Providers.
|
|
||||||
|
|
||||||
# Extracts the Puppet function name and options hash from the parsed
|
|
||||||
# definition.
|
|
||||||
#
|
|
||||||
# @return [(String, Hash{String => String})]
|
|
||||||
def process_parameters
|
|
||||||
# Passing `false` to prameters excludes the block param from the returned
|
|
||||||
# list.
|
|
||||||
name, opts = statement.parameters(false).compact
|
|
||||||
|
|
||||||
name = process_element(name)
|
|
||||||
|
|
||||||
# Don't try to process options if we don't have any
|
|
||||||
if !opts.nil?
|
|
||||||
opts = opts.map do |tuple|
|
|
||||||
# Jump down into the S-Expression that represents a hashrocket, `=>`,
|
|
||||||
# and the values on either side of it.
|
|
||||||
tuple.jump(:assoc).map{|e| process_element(e)}
|
|
||||||
end
|
|
||||||
|
|
||||||
options = Hash[opts]
|
|
||||||
else
|
|
||||||
options = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
[name, options]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sometimes the YARD parser returns Heredoc strings that start with `<-`
|
|
||||||
# instead of `<<-`.
|
|
||||||
HEREDOC_START = /^<?<-/
|
|
||||||
|
|
||||||
# Turns an entry in the method parameter list into a string.
|
|
||||||
#
|
|
||||||
# @param ele [YARD::Parser::Ruby::AstNode]
|
|
||||||
# @return [String]
|
|
||||||
def process_element(ele)
|
|
||||||
ele = ele.jump(:ident, :string_content)
|
|
||||||
|
|
||||||
case ele.type
|
|
||||||
when :ident
|
|
||||||
ele.source
|
|
||||||
when :string_content
|
|
||||||
source = ele.source
|
|
||||||
if HEREDOC_START.match(source)
|
|
||||||
process_heredoc(source)
|
|
||||||
else
|
|
||||||
source
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Cleans up and formats Heredoc contents parsed by YARD.
|
|
||||||
#
|
|
||||||
# @param source [String]
|
|
||||||
# @return [String]
|
|
||||||
def process_heredoc(source)
|
|
||||||
source = source.lines.to_a
|
|
||||||
|
|
||||||
# YARD adds a line of source context on either side of the Heredoc
|
|
||||||
# contents.
|
|
||||||
source.shift
|
|
||||||
source.pop
|
|
||||||
|
|
||||||
# This utility method normalizes indentation and trims whitespace.
|
|
||||||
Puppet::Util::Docs.scrub(source.join)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,283 @@
|
||||||
|
# Handles `dispatch` calls within a future parser function declaration. For
|
||||||
|
# now, it just treats any docstring as an `@overlaod` tag and attaches the
|
||||||
|
# overload to the parent function.
|
||||||
|
class PuppetX::PuppetLabs::Strings::YARD::Handlers::PuppetTypeHandler < YARD::Handlers::Ruby::Base
|
||||||
|
include PuppetX::PuppetLabs::Strings::YARD::CodeObjects
|
||||||
|
|
||||||
|
handles :call
|
||||||
|
|
||||||
|
process do
|
||||||
|
@heredoc_helper = HereDocHelper.new
|
||||||
|
# Puppet types always begin with:
|
||||||
|
# Puppet::Types.newtype...
|
||||||
|
# Therefore, we match the corresponding trees which look like this:
|
||||||
|
# s(:call,
|
||||||
|
# s(:const_path_ref,
|
||||||
|
# s(:var_ref, s(:const, "Puppet", ...), ...),
|
||||||
|
# s(:const, "Type", ...),
|
||||||
|
# You think this is ugly? It's better than the alternative.
|
||||||
|
return unless statement.children.length > 2
|
||||||
|
first = statement.children.first
|
||||||
|
return unless (first.type == :const_path_ref and
|
||||||
|
first.source == 'Puppet::Type') or
|
||||||
|
(first.type == :var_ref and
|
||||||
|
first.source == 'Type') and
|
||||||
|
statement.children[1].source == "newtype"
|
||||||
|
|
||||||
|
# Fetch the docstring for the types. The docstring is the string literal
|
||||||
|
# assigned to the @doc parameter or absent, like this:
|
||||||
|
# @doc "docstring goes here"
|
||||||
|
# We assume that docstrings nodes have the following shape in the source
|
||||||
|
# code:
|
||||||
|
# ...
|
||||||
|
# s(s(:assign,
|
||||||
|
# s(:..., s(:ivar, "@doc", ...), ...),
|
||||||
|
# s(:...,
|
||||||
|
# s(:...,
|
||||||
|
# s(:tstring_content,
|
||||||
|
# "Manages files, including their content, etc.", ...
|
||||||
|
# Initialize the docstring to nil, the default value if we don't find
|
||||||
|
# anything
|
||||||
|
docstring = nil
|
||||||
|
# Walk the tree searching for assignments
|
||||||
|
statement.traverse do |node|
|
||||||
|
if node.type == :assign
|
||||||
|
# Once we have found and assignment, jump to the first ivar
|
||||||
|
# (the l-value)
|
||||||
|
# If we can't find an ivar return the node.
|
||||||
|
ivar = node.jump(:ivar)
|
||||||
|
# If we found and ivar and its source reads '@doc' then...
|
||||||
|
if ivar != node and ivar.source == '@doc'
|
||||||
|
# find the next string content
|
||||||
|
content = node.jump(:tstring_content)
|
||||||
|
# if we found the string content extract its source
|
||||||
|
if content != node
|
||||||
|
# The docstring is either the source stripped of heredoc
|
||||||
|
# annotations or the raw source.
|
||||||
|
if @heredoc_helper.is_heredoc? content.source
|
||||||
|
docstring = @heredoc_helper.process_heredoc content.source
|
||||||
|
else
|
||||||
|
docstring = content.source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Since we found the @doc parameter (regardless of whether we
|
||||||
|
# successfully extracted its source), we're done.
|
||||||
|
break
|
||||||
|
# But if we didn't find the ivar loop around again.
|
||||||
|
else
|
||||||
|
next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# The types begin with:
|
||||||
|
# Puppet::Types.newtype(:symbol)
|
||||||
|
# Jump to the first identifier (':symbol') after the third argument
|
||||||
|
# ('(:symbol)') to the current statement
|
||||||
|
name = statement.children[2].jump(:ident).source
|
||||||
|
parameter_details = []
|
||||||
|
property_details = []
|
||||||
|
features = []
|
||||||
|
obj = TypeObject.new(:root, name) do |o|
|
||||||
|
# FIXME: This block gets yielded twice for whatever reason
|
||||||
|
parameter_details = []
|
||||||
|
property_details = []
|
||||||
|
o.parameters = []
|
||||||
|
# Find the do block following the Type.
|
||||||
|
do_block = statement.jump(:do_block)
|
||||||
|
# traverse the do block's children searching for function calls whose
|
||||||
|
# identifier is newparam (we're calling the newparam function)
|
||||||
|
do_block.traverse do |node|
|
||||||
|
if is_param? node
|
||||||
|
# The first member of the parameter tuple is the parameter name.
|
||||||
|
# Find the second identifier node under the fcall tree. The first one
|
||||||
|
# is 'newparam', the second one is the function name.
|
||||||
|
# Get its source.
|
||||||
|
# The second parameter is nil because we cannot infer types for these
|
||||||
|
# functions. In fact, that's a silly thing to ask because ruby
|
||||||
|
# types were deprecated with puppet 4 at the same time the type
|
||||||
|
# system was created.
|
||||||
|
|
||||||
|
# Because of a ripper bug a symbol identifier is sometimes incorrectly parsed as a keyword.
|
||||||
|
# That is, the symbol `:true` will be represented as s(:symbol s(:kw, true...
|
||||||
|
param_name = node.children[1].jump(:ident)
|
||||||
|
if param_name == node.children[1]
|
||||||
|
param_name = node.children[1].jump(:kw)
|
||||||
|
end
|
||||||
|
param_name = param_name.source
|
||||||
|
o.parameters << [param_name, nil]
|
||||||
|
parameter_details << {:name => param_name,
|
||||||
|
:desc => fetch_description(node), :exists? => true,
|
||||||
|
:puppet_type => true,
|
||||||
|
:default => fetch_default(node),
|
||||||
|
:namevar => is_namevar?(node, param_name, name),
|
||||||
|
:parameter => true,
|
||||||
|
:allowed_values => get_parameter_allowed_values(node),
|
||||||
|
}
|
||||||
|
elsif is_prop? node
|
||||||
|
# Because of a ripper bug a symbol identifier is sometimes incorrectly parsed as a keyword.
|
||||||
|
# That is, the symbol `:true` will be represented as s(:symbol s(:kw, true...
|
||||||
|
prop_name = node.children[1].jump(:ident)
|
||||||
|
if prop_name == node.children[1]
|
||||||
|
prop_name = node.children[1].jump(:kw)
|
||||||
|
end
|
||||||
|
prop_name = prop_name.source
|
||||||
|
property_details << {:name => prop_name,
|
||||||
|
:desc => fetch_description(node), :exists? => true,
|
||||||
|
:default => fetch_default(node),
|
||||||
|
:puppet_type => true,
|
||||||
|
:property => true,
|
||||||
|
:allowed_values => get_property_allowed_values(node),
|
||||||
|
}
|
||||||
|
elsif is_feature? node
|
||||||
|
features << get_feature(node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
obj.parameter_details = parameter_details
|
||||||
|
obj.property_details = property_details
|
||||||
|
obj.features = features
|
||||||
|
|
||||||
|
register_docstring(obj, docstring, nil)
|
||||||
|
|
||||||
|
register obj
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# See:
|
||||||
|
# https://docs.puppetlabs.com/guides/custom_types.html#namevar
|
||||||
|
# node should be a parameter
|
||||||
|
def is_namevar? node, param_name, type_name
|
||||||
|
# Option 1:
|
||||||
|
# Puppet::Type.newtype(:name) do
|
||||||
|
# ...
|
||||||
|
# newparam(:name) do
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
if type_name == param_name
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
# Option 2:
|
||||||
|
# newparam(:path, :namevar => true) do
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
if node.children.length >= 2
|
||||||
|
node.traverse do |s|
|
||||||
|
if s.type == :assoc and s.jump(:ident).source == 'namevar' and s.jump(:kw).source == 'true'
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Option 3:
|
||||||
|
# newparam(:path) do
|
||||||
|
# isnamevar
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
do_block = node.jump(:do_block).traverse do |s|
|
||||||
|
if is_a_func_call_named? 'isnamevar', s
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Crazy implementations of types may just call #isnamevar directly on the object.
|
||||||
|
# We don't handle this today.
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_param? node
|
||||||
|
is_a_func_call_named? 'newparam', node
|
||||||
|
end
|
||||||
|
def is_prop? node
|
||||||
|
is_a_func_call_named? 'newproperty', node
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_feature? node
|
||||||
|
is_a_func_call_named? 'feature', node
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_a_func_call_named? name, node
|
||||||
|
(node.type == :fcall or node.type == :command or node.type == :vcall) and node.children.first.source == name
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_feature node
|
||||||
|
name = node[1].jump(:ident).source
|
||||||
|
desc = node[1].jump(:tstring_content).source
|
||||||
|
methods = []
|
||||||
|
if node[1].length == 4 and node.children[1][2].jump(:ident).source == 'methods'
|
||||||
|
arr = node[1][2].jump(:array)
|
||||||
|
if arr != node[1][2]
|
||||||
|
arr.traverse do |s|
|
||||||
|
if s.type == :ident
|
||||||
|
methods << s.source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
{
|
||||||
|
:name => name,
|
||||||
|
:desc => desc,
|
||||||
|
:methods => methods != [] ? methods : nil,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_parameter_allowed_values node
|
||||||
|
vals = []
|
||||||
|
node.traverse do |s|
|
||||||
|
if is_a_func_call_named? 'newvalues', s
|
||||||
|
list = s.jump(:list)
|
||||||
|
if list != s
|
||||||
|
vals += list.map { |item| [item.source] if YARD::Parser::Ruby::AstNode === item }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
vals.compact
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calls to newvalue only apply to properties, according to Dan & Nan's
|
||||||
|
# "Puppet Types and Providers", page 30.
|
||||||
|
def get_property_allowed_values node
|
||||||
|
vals = get_parameter_allowed_values node
|
||||||
|
node.traverse do |s|
|
||||||
|
if is_a_func_call_named? 'newvalue', s
|
||||||
|
required_features = nil
|
||||||
|
s.traverse do |ss|
|
||||||
|
if ss.type == :assoc and ss[0].source == ':required_features'
|
||||||
|
required_features = ss[1].source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
list = s.jump(:list)
|
||||||
|
if list != s
|
||||||
|
vals << [list[0].source, required_features].compact
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
vals
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_default node
|
||||||
|
do_block = node.jump(:do_block)
|
||||||
|
do_block.traverse do |s|
|
||||||
|
if is_a_func_call_named? 'defaultto', s
|
||||||
|
return s[-1].source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_description(fcall)
|
||||||
|
fcall.traverse do |node|
|
||||||
|
if is_a_func_call_named? 'desc', node
|
||||||
|
content = node.jump(:string_content)
|
||||||
|
if content != node
|
||||||
|
@heredoc_helper = HereDocHelper.new
|
||||||
|
if @heredoc_helper.is_heredoc? content.source
|
||||||
|
docstring = @heredoc_helper.process_heredoc content.source
|
||||||
|
else
|
||||||
|
docstring = content.source
|
||||||
|
end
|
||||||
|
return docstring
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,7 +6,7 @@ require 'yard'
|
||||||
|
|
||||||
class YARD::CLI::Yardoc
|
class YARD::CLI::Yardoc
|
||||||
def all_objects
|
def all_objects
|
||||||
YARD::Registry.all(:root, :module, :class, :puppetnamespace, :hostclass, :definedtype)
|
YARD::Registry.all(:root, :module, :class, :type, :provider, :puppetnamespace, :hostclass, :definedtype)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -16,7 +16,15 @@ class YARD::CLI::Stats
|
||||||
end
|
end
|
||||||
|
|
||||||
def stats_for_definedtypes
|
def stats_for_definedtypes
|
||||||
output 'Puppet Types', *type_statistics(:definedtype)
|
output 'Puppet Defined Types', *type_statistics(:definedtype)
|
||||||
|
end
|
||||||
|
|
||||||
|
def stats_for_puppet_types
|
||||||
|
output 'Puppet Types', *type_statistics(:type)
|
||||||
|
end
|
||||||
|
|
||||||
|
def stats_for_puppet_provider
|
||||||
|
output 'Puppet Providers', *type_statistics(:provider)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
require 'puppet_x/puppetlabs/strings/yard/core_ext/yard'
|
||||||
|
# Creates a new code object based on the directive
|
||||||
|
class PuppetX::PuppetLabs::Strings::YARD::Tags::PuppetTypeParameterDirective < YARD::Tags::Directive
|
||||||
|
def call
|
||||||
|
return if object.nil?
|
||||||
|
object.parameters << ([tag.text] + tag.types)
|
||||||
|
object.parameter_details << {:name => tag.name, :desc => tag.text, :exists? => true, :puppet_type => true}
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
<%= namespace_list(:namespace_types => [:provider]) %>
|
|
@ -0,0 +1 @@
|
||||||
|
<%= namespace_list(:namespace_types => [:type]) %>
|
|
@ -27,6 +27,20 @@ def generate_puppet_plugin_list
|
||||||
generate_list_contents
|
generate_list_contents
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_puppet_type_list
|
||||||
|
@items = options.objects.select{|o| [:type].include? o.type} if options.objects
|
||||||
|
@list_title = "Puppet Type List"
|
||||||
|
@list_type = "puppet_type"
|
||||||
|
generate_list_contents
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_puppet_provider_list
|
||||||
|
@items = options.objects.select{|o| [:provider].include? o.type} if options.objects
|
||||||
|
@list_title = "Puppet Provider List"
|
||||||
|
@list_type = "puppet_provider"
|
||||||
|
generate_list_contents
|
||||||
|
end
|
||||||
|
|
||||||
# A hacked version of class_list that can be instructed to only display certain
|
# A hacked version of class_list that can be instructed to only display certain
|
||||||
# namespace types. This allows us to separate Puppet bits from Ruby bits.
|
# namespace types. This allows us to separate Puppet bits from Ruby bits.
|
||||||
def namespace_list(opts = {})
|
def namespace_list(opts = {})
|
||||||
|
|
|
@ -15,6 +15,30 @@ class HTMLHelper
|
||||||
result.join
|
result.join
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_features features, object
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if features
|
||||||
|
features.each do |feat|
|
||||||
|
result << "<li>"
|
||||||
|
result << "<span class=\"name\">#{feat[:name]} </span>"
|
||||||
|
if feat[:desc]
|
||||||
|
result << "- <br/><div class=\"inline\"><p> #{feat[:desc]} </p></div>"
|
||||||
|
end
|
||||||
|
if feat[:methods]
|
||||||
|
result << "<h3> Methods </h3>"
|
||||||
|
result << "<ul>"
|
||||||
|
feat[:methods].each do |method|
|
||||||
|
result << "<li> <tt>" << method << "</tt> </li>"
|
||||||
|
end
|
||||||
|
result << "</ul>"
|
||||||
|
end
|
||||||
|
result << "</li>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
result.join
|
||||||
|
end
|
||||||
|
|
||||||
# Generates the HTML to format the relevant data about parameters
|
# Generates the HTML to format the relevant data about parameters
|
||||||
def generate_parameters(params, object)
|
def generate_parameters(params, object)
|
||||||
result = []
|
result = []
|
||||||
|
@ -59,9 +83,21 @@ class HTMLHelper
|
||||||
result << "(" << "<tt>" << possible_types.join(", ") << "</tt>" << ")"
|
result << "(" << "<tt>" << possible_types.join(", ") << "</tt>" << ")"
|
||||||
end
|
end
|
||||||
# Give up. It can probably be anything.
|
# Give up. It can probably be anything.
|
||||||
elsif !param[:puppet_3_func]
|
elsif not (param[:puppet_3_func] or param[:puppet_type])
|
||||||
result << "(<tt>Unknown</tt>)"
|
result << "(<tt>Unknown</tt>)"
|
||||||
end
|
end
|
||||||
|
if param[:puppet_type] and param[:parameter]
|
||||||
|
result << "(Parameter) "
|
||||||
|
elsif param[:puppet_type] and param[:property]
|
||||||
|
result << "(Property) "
|
||||||
|
end
|
||||||
|
|
||||||
|
if param[:namevar]
|
||||||
|
result << "(Namevar) "
|
||||||
|
end
|
||||||
|
if param[:default]
|
||||||
|
result << " Default value: <tt>" << param[:default] << "</tt> "
|
||||||
|
end
|
||||||
|
|
||||||
result << "</span>"
|
result << "</span>"
|
||||||
|
|
||||||
|
@ -81,6 +117,20 @@ class HTMLHelper
|
||||||
result << "</strike>"
|
result << "</strike>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if param[:allowed_values] and param[:allowed_values] != []
|
||||||
|
result << "<b> Allowed Values: </b>"
|
||||||
|
result << "<ul>"
|
||||||
|
param[:allowed_values].each do |value_thing|
|
||||||
|
result << "<li>"
|
||||||
|
result << "<tt>" << value_thing.first << "</tt>"
|
||||||
|
if value_thing[1]
|
||||||
|
result << " only available if " << "<tt>" << value_thing[1] << "</tt>"
|
||||||
|
end
|
||||||
|
result << "</li>"
|
||||||
|
end
|
||||||
|
result << "</ul>"
|
||||||
|
end
|
||||||
|
|
||||||
result << "</li>"
|
result << "</li>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# @objects_by_letter prevents that. Submit a pull request.
|
# @objects_by_letter prevents that. Submit a pull request.
|
||||||
def index
|
def index
|
||||||
@objects_by_letter = {}
|
@objects_by_letter = {}
|
||||||
objects = Registry.all(:class, :module, :puppetnamespace, :hostclass, :definedtype).sort_by {|o| o.name.to_s }
|
objects = Registry.all(:class, :module, :type, :puppetnamespace, :hostclass, :definedtype, :provider).sort_by {|o| o.name.to_s }
|
||||||
objects = run_verifier(objects)
|
objects = run_verifier(objects)
|
||||||
objects.each {|o| (@objects_by_letter[o.name.to_s[0,1].upcase] ||= []) << o }
|
objects.each {|o| (@objects_by_letter[o.name.to_s[0,1].upcase] ||= []) << o }
|
||||||
erb(:index)
|
erb(:index)
|
||||||
|
@ -11,6 +11,8 @@ end
|
||||||
def menu_lists
|
def menu_lists
|
||||||
[
|
[
|
||||||
{:type => 'puppet_manifest', :title => 'Puppet Manifests', :search_title => "Puppet Manifest List"},
|
{:type => 'puppet_manifest', :title => 'Puppet Manifests', :search_title => "Puppet Manifest List"},
|
||||||
{:type => 'puppet_plugin', :title => 'Puppet Plugins', :search_title => "Puppet Plugin List"}
|
{:type => 'puppet_plugin', :title => 'Puppet Plugins', :search_title => "Puppet Plugin List"},
|
||||||
|
{:type => 'puppet_type', :title => 'Puppet Types', :search_title => "Puppet Type List"},
|
||||||
|
{:type => 'puppet_provider', :title => 'Puppet Providers', :search_title => "Puppet Provider List"},
|
||||||
] + super
|
] + super
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<h2>Commands Summary</h2>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="command">
|
||||||
|
<% @command_details.each do |command| %>
|
||||||
|
<li><tt><%= command %></tt></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<h2>Parameter Summary</h2>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="param">
|
||||||
|
<%= @html_helper.generate_parameters(@param_details, object) %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<h2>Features</h2>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="feature">
|
||||||
|
<%= @html_helper.generate_features(@feature_details, object) %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h2>Confines</h2>
|
||||||
|
<% if @confine_details != {} %>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="command">
|
||||||
|
<% @confine_details.each_pair do |key, value| %>
|
||||||
|
<li><tt><%= key %> - <%= value %></tt></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h2>Defaults</h2>
|
||||||
|
<% if @default_details != {} %>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="command">
|
||||||
|
<% @default_details.each_pair do |key, value| %>
|
||||||
|
<li><tt><%= key %> - <%= value %></tt></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<div class="docstring">
|
||||||
|
<div class="discussion">
|
||||||
|
<p><%= htmlify(Puppet::Util::Docs::scrub(@class_details[:desc])) %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tags">
|
||||||
|
<% if @class_details[:examples] != {}%>
|
||||||
|
<div class="examples">
|
||||||
|
<p class="tag_title">Examples:</p>
|
||||||
|
<% @class_details[:examples].each do |title, text| %>
|
||||||
|
<div class="inline"><p><%= title %></p></div>
|
||||||
|
<pre class="example code"><code><span><%= text %></span></code></pre>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% if @class_details[:since] %>
|
||||||
|
<p class="tag_title">Since:</p>
|
||||||
|
<ul class="since">
|
||||||
|
<li>
|
||||||
|
<div class="inline">
|
||||||
|
<p><%= @class_details[:since] %></p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
<% if @class_details[:return] %>
|
||||||
|
<p class="tag_title">Return:</p>
|
||||||
|
<ul class="return">
|
||||||
|
<li>
|
||||||
|
<%= @html_helper.generate_return_types(@class_details[:return][1], @class_details[:return][0]) %>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h2>Features</h2>
|
||||||
|
<% if @feature_details != [] %>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="command">
|
||||||
|
<% @feature_details.each do |feature| %>
|
||||||
|
<li><tt><%= feature %></tt></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class='module_header'>
|
||||||
|
<h1>
|
||||||
|
<%= @header_text %>
|
||||||
|
</h1>
|
||||||
|
</div>
|
|
@ -0,0 +1 @@
|
||||||
|
include T('default/module/html')
|
|
@ -0,0 +1,44 @@
|
||||||
|
include T('default/module')
|
||||||
|
|
||||||
|
require File.join(File.dirname(__FILE__),'../html_helper')
|
||||||
|
require File.join(File.dirname(__FILE__),'../template_helper')
|
||||||
|
|
||||||
|
def init
|
||||||
|
sections :header, :box_info, :pre_docstring, :docstring, :command_details, :confine_details, :default_details, :feature_details
|
||||||
|
|
||||||
|
@template_helper = TemplateHelper.new
|
||||||
|
@html_helper = HTMLHelper.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def command_details
|
||||||
|
@command_details = object.commands
|
||||||
|
erb(:command_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def confine_details
|
||||||
|
@confine_details = object.confines
|
||||||
|
erb(:confine_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_details
|
||||||
|
@default_details = object.defaults
|
||||||
|
erb(:default_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def feature_details
|
||||||
|
@feature_details = object.features
|
||||||
|
erb(:feature_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def header
|
||||||
|
@header_text = "Puppet Provider: #{object.name}"
|
||||||
|
|
||||||
|
erb(:header)
|
||||||
|
end
|
||||||
|
|
||||||
|
def docstring
|
||||||
|
|
||||||
|
@class_details = @template_helper.extract_tag_data(object)
|
||||||
|
|
||||||
|
erb(:docstring)
|
||||||
|
end
|
|
@ -0,0 +1,34 @@
|
||||||
|
<div class="docstring">
|
||||||
|
<div class="discussion">
|
||||||
|
<p><%= htmlify(Puppet::Util::Docs::scrub(@class_details[:desc])) %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tags">
|
||||||
|
<% if @class_details[:examples] != {}%>
|
||||||
|
<div class="examples">
|
||||||
|
<p class="tag_title">Examples:</p>
|
||||||
|
<% @class_details[:examples].each do |title, text| %>
|
||||||
|
<div class="inline"><p><%= title %></p></div>
|
||||||
|
<pre class="example code"><code><span><%= text %></span></code></pre>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% if @class_details[:since] %>
|
||||||
|
<p class="tag_title">Since:</p>
|
||||||
|
<ul class="since">
|
||||||
|
<li>
|
||||||
|
<div class="inline">
|
||||||
|
<p><%= @class_details[:since] %></p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
<% if @class_details[:return] %>
|
||||||
|
<p class="tag_title">Return:</p>
|
||||||
|
<ul class="return">
|
||||||
|
<li>
|
||||||
|
<%= @html_helper.generate_return_types(@class_details[:return][1], @class_details[:return][0]) %>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class='module_header'>
|
||||||
|
<h1>
|
||||||
|
<%= @header_text %>
|
||||||
|
</h1>
|
||||||
|
</div>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<h2>Parameter Summary</h2>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="param">
|
||||||
|
<%= @html_helper.generate_parameters(@param_details, object) %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<h2>Features</h2>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="feature">
|
||||||
|
<%= @html_helper.generate_features(@feature_details, object) %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h2>Available Providers</h2>
|
||||||
|
<% if @providers != [] %>
|
||||||
|
<div class="tags">
|
||||||
|
<ul class="command">
|
||||||
|
<% @providers.each do |provider| %>
|
||||||
|
<li><a href="<%= provider.name.to_s %>.html"><tt><%= provider.name.to_s %></tt></a></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
|
@ -0,0 +1 @@
|
||||||
|
include T('default/module/html')
|
|
@ -0,0 +1,49 @@
|
||||||
|
include T('default/module')
|
||||||
|
|
||||||
|
require File.join(File.dirname(__FILE__),'../html_helper')
|
||||||
|
require File.join(File.dirname(__FILE__),'../template_helper')
|
||||||
|
|
||||||
|
def init
|
||||||
|
sections :header, :box_info, :pre_docstring, :docstring, :parameter_details, :provider_details
|
||||||
|
|
||||||
|
@template_helper = TemplateHelper.new
|
||||||
|
@html_helper = HTMLHelper.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def provider_details
|
||||||
|
type_name = object.name.to_s
|
||||||
|
@providers = YARD::Registry.all(:provider).select { |t| t.type_name == type_name }
|
||||||
|
|
||||||
|
erb(:provider_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def parameter_details
|
||||||
|
params = object.parameter_details.map { |h| h[:name] }
|
||||||
|
# Put properties and parameters in one big list where the descriptions are
|
||||||
|
# scrubbed and htmlified and the namevar is the first element, the ensure
|
||||||
|
# property the second, and the rest are alphabetized.
|
||||||
|
@param_details = (object.parameter_details + object.property_details).each {
|
||||||
|
|h| h[:desc] = htmlify(Puppet::Util::Docs::scrub(h[:desc])) if h[:desc]
|
||||||
|
}.sort { |a, b| a[:name] <=> b[:name] }
|
||||||
|
# Float ensurable and namevars to the top of the list
|
||||||
|
@param_details = @param_details.partition{|a| a[:name] == 'ensure'}.flatten
|
||||||
|
@param_details = @param_details.partition{|a| a[:namevar]}.flatten
|
||||||
|
|
||||||
|
@feature_details = object.features
|
||||||
|
@template_helper.check_parameters_match_docs object
|
||||||
|
|
||||||
|
erb(:parameter_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def header
|
||||||
|
@header_text = "Puppet Type: #{object.name}"
|
||||||
|
|
||||||
|
erb(:header)
|
||||||
|
end
|
||||||
|
|
||||||
|
def docstring
|
||||||
|
|
||||||
|
@class_details = @template_helper.extract_tag_data(object)
|
||||||
|
|
||||||
|
erb(:docstring)
|
||||||
|
end
|
|
@ -74,7 +74,9 @@ Classes: 0 ( 0 undocumented)
|
||||||
Constants: 0 ( 0 undocumented)
|
Constants: 0 ( 0 undocumented)
|
||||||
Methods: 0 ( 0 undocumented)
|
Methods: 0 ( 0 undocumented)
|
||||||
Puppet Classes: 1 ( 0 undocumented)
|
Puppet Classes: 1 ( 0 undocumented)
|
||||||
|
Puppet Defined Types: 0 ( 0 undocumented)
|
||||||
Puppet Types: 0 ( 0 undocumented)
|
Puppet Types: 0 ( 0 undocumented)
|
||||||
|
Puppet Providers: 0 ( 0 undocumented)
|
||||||
100.00% documented
|
100.00% documented
|
||||||
output
|
output
|
||||||
expected_stderr = "@param tag types do not match the code. The ident parameter is declared as types [\"Float\"] in the docstring, but the code specifies the types [Puppet::Pops::Types::PStringType] in file manifests/init.pp near line 2\n"
|
expected_stderr = "@param tag types do not match the code. The ident parameter is declared as types [\"Float\"] in the docstring, but the code specifies the types [Puppet::Pops::Types::PStringType] in file manifests/init.pp near line 2\n"
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
require 'puppet_x/puppetlabs/strings/yard/handlers/type_handler'
|
||||||
|
require 'strings_spec/parsing'
|
||||||
|
|
||||||
|
|
||||||
|
describe PuppetX::PuppetLabs::Strings::YARD::Handlers::PuppetTypeHandler do
|
||||||
|
include StringsSpec::Parsing
|
||||||
|
|
||||||
|
def the_type()
|
||||||
|
YARD::Registry.at("file")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should have the proper docstring" do
|
||||||
|
parse <<-RUBY
|
||||||
|
Puppet::Type.newtype(:file) do
|
||||||
|
@doc = "Manages files, including their content, ownership, and perms."
|
||||||
|
newparam(:path) do
|
||||||
|
desc <<-'EOT'
|
||||||
|
The path to the file to manage. Must be fully qualified.
|
||||||
|
EOT
|
||||||
|
end
|
||||||
|
isnamevar
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
expect(the_type.docstring).to eq("Manages files, including their " +
|
||||||
|
"content, ownership, and perms.")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should have the proper parameter details" do
|
||||||
|
parse <<-RUBY
|
||||||
|
Puppet::Type.newtype(:file) do
|
||||||
|
@doc = "Manages files, including their content, ownership, and perms."
|
||||||
|
newparam(:file) do
|
||||||
|
desc <<-'EOT'
|
||||||
|
The path to the file to manage. Must be fully qualified.
|
||||||
|
EOT
|
||||||
|
end
|
||||||
|
isnamevar
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
expect(the_type.parameter_details).to eq([{ :name => "file",
|
||||||
|
:desc => "The path to the file to manage. Must be fully qualified.",
|
||||||
|
:exists? => true, :puppet_type => true, :namevar => true,
|
||||||
|
:default => nil,
|
||||||
|
:parameter=>true,
|
||||||
|
:allowed_values=>[],
|
||||||
|
}])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should have the proper parameters" do
|
||||||
|
parse <<-RUBY
|
||||||
|
Puppet::Type.newtype(:file) do
|
||||||
|
@doc = "Manages files, including their content, ownership, and perms."
|
||||||
|
newparam(:path) do
|
||||||
|
desc <<-'EOT'
|
||||||
|
The path to the file to manage. Must be fully qualified.
|
||||||
|
EOT
|
||||||
|
end
|
||||||
|
isnamevar
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
expect(the_type.parameters).to eq([["path", nil]])
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue