(PDOC-37) Attach params to Puppet 4.x code object
Traverse the ruby AST to get method arguments and attach them to the code object. * Fixes spurious warnings issued by yard. * Obviates the need for ugly regex code in the templates to retrieve parameters from the source code.
This commit is contained in:
parent
49171c92b9
commit
463d4e0a1f
|
@ -50,6 +50,7 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
# For now, assume the remaining positional args are a list of manifest
|
||||
# and ruby files to parse.
|
||||
yard_args = (args.empty? ? MODULE_SOURCEFILES : args)
|
||||
class YARD::Logger; def progress(*args); end; end
|
||||
|
||||
yardoc_actions.generate_documentation(*yard_args)
|
||||
end
|
||||
|
|
|
@ -26,7 +26,30 @@ class Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
|||
process do
|
||||
name = process_parameters
|
||||
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
method_arguments = []
|
||||
|
||||
# To attach the method parameters to the new code object, traverse the
|
||||
# ruby AST until a node is found which defines a list of parameters.
|
||||
# Then, traverse the children of the parameters, storing each identifier
|
||||
# in the list of method arguments.
|
||||
obj = MethodObject.new(function_namespace, name) do |o|
|
||||
statement.traverse do |node|
|
||||
if node.type == :params
|
||||
node.traverse do |params|
|
||||
if params.type == :ident
|
||||
# FIXME: Replace nil with parameter types
|
||||
method_arguments << [params[0], nil]
|
||||
end
|
||||
end
|
||||
|
||||
# Now that the parameters have been found, break out of the traversal
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
obj.parameters = method_arguments
|
||||
|
||||
obj['puppet_4x_function'] = true
|
||||
|
||||
register obj
|
||||
|
@ -78,7 +101,7 @@ class Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
|||
#
|
||||
# @return [(String, Hash{String => String})]
|
||||
def process_parameters
|
||||
# Passing `false` to prameters excludes the block param from the returned
|
||||
# Passing `false` to parameters excludes the block param from the returned
|
||||
# list.
|
||||
name, _ = statement.parameters(false).compact
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ def parameter_details
|
|||
|
||||
@param_details = []
|
||||
|
||||
@param_details = @template_helper.extract_param_details(params, param_tags, object.files, true)
|
||||
@param_details = @template_helper.extract_param_details(params, param_tags, true)
|
||||
@template_helper.check_parameters_match_docs object
|
||||
|
||||
erb(:parameter_details)
|
||||
end
|
||||
|
|
|
@ -3,6 +3,9 @@ include T('default/definedtype')
|
|||
def init
|
||||
super
|
||||
sections.push :subclasses
|
||||
|
||||
@template_helper = TemplateHelper.new
|
||||
@template_helper.check_parameters_match_docs object
|
||||
end
|
||||
|
||||
def subclasses
|
||||
|
@ -18,3 +21,4 @@ def subclasses
|
|||
return if @subclasses.nil? || @subclasses.empty?
|
||||
erb(:subclasses)
|
||||
end
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ def method_details_list
|
|||
# Convert the matched string into an array of strings
|
||||
params = parameters.nil? ? nil : parameters[1].split(/\s*,\s*/)
|
||||
|
||||
param_details = @template_helper.extract_param_details(params, param_tags, object.files) unless params.nil?
|
||||
param_details = @template_helper.extract_param_details(params, param_tags) unless params.nil?
|
||||
else
|
||||
param_details = @template_helper.comment_only_param_details(param_tags)
|
||||
end
|
||||
|
|
|
@ -36,7 +36,7 @@ class TemplateHelper
|
|||
# :desc => [String] The description provided in the comment
|
||||
# :types => [Array] The parameter type(s) specified in the comment
|
||||
# :exists => [Boolean] True only if the parameter exists in the documented logic and not just in a comment}
|
||||
def extract_param_details(parameters, tags_hash, locations, fq_name = false)
|
||||
def extract_param_details(parameters, tags_hash, fq_name = false)
|
||||
parameter_info = []
|
||||
|
||||
# Extract the information for parameters that exist
|
||||
|
@ -73,13 +73,6 @@ class TemplateHelper
|
|||
end
|
||||
if !param_exists
|
||||
parameter_info.push({:name => tag.name, :desc => tag.text, :types => tag.types, :exists? => false})
|
||||
if locations.length >= 1 and locations[0].length == 2
|
||||
file_name = locations[0][0]
|
||||
line_number = locations[0][1]
|
||||
$stderr.puts "[warn]: The parameter #{tag.name} is documented, but doesn't exist in your code, in file #{file_name} near line #{line_number}"
|
||||
else
|
||||
$stderr.puts "[warn]: The parameter #{tag.name} is documented, but doesn't exist in your code. Sorry, the file and line number could not be determined."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -111,4 +104,26 @@ class TemplateHelper
|
|||
|
||||
parameter_info
|
||||
end
|
||||
|
||||
# Check that the actual function parameters match what is stated in the docs.
|
||||
# If there is a mismatch, print a warning to stderr.
|
||||
# This is necessary for puppet classes and defined types. This type of
|
||||
# warning will be issued for ruby code by the ruby docstring parser.
|
||||
# @param object the code object to examine for parameters names
|
||||
def check_parameters_match_docs(object)
|
||||
param_tags = object.tags.find_all{ |tag| tag.tag_name == "param"}
|
||||
names = object.parameters.map {|l| l.first.gsub(/\W/, '') }
|
||||
locations = object.files
|
||||
param_tags.each do |tag|
|
||||
if not names.include?(tag.name)
|
||||
if locations.length >= 1 and locations[0].length == 2
|
||||
file_name = locations[0][0]
|
||||
line_number = locations[0][1]
|
||||
$stderr.puts "[warn]: The parameter #{tag.name} is documented, but doesn't exist in your code, in file #{file_name} near line #{line_number}"
|
||||
else
|
||||
$stderr.puts "[warn]: The parameter #{tag.name} is documented, but doesn't exist in your code. Sorry, the file and line number could not be determined."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue