142 lines
4.5 KiB
Ruby
142 lines
4.5 KiB
Ruby
require 'puppet-strings/yard/handlers/helpers'
|
|
require 'puppet-strings/yard/handlers/ruby/base'
|
|
require 'puppet-strings/yard/code_objects'
|
|
require 'puppet-strings/yard/util'
|
|
|
|
# Implements the handler for Puppet resource types written in Ruby.
|
|
class PuppetStrings::Yard::Handlers::Ruby::RsapiHandler < PuppetStrings::Yard::Handlers::Ruby::Base
|
|
# The default docstring when ensurable is used without given a docstring.
|
|
DEFAULT_ENSURABLE_DOCSTRING = 'The basic property that the resource should be in.'.freeze
|
|
|
|
namespace_only
|
|
handles method_call(:register_type)
|
|
|
|
process do
|
|
# Only accept calls to Puppet::ResourceApi
|
|
return unless statement.count > 1
|
|
module_name = statement[0].source
|
|
return unless [ 'Puppet::ResourceApi' ].include? module_name
|
|
|
|
schema = extract_schema
|
|
|
|
# puts "Schema: #{schema.inspect}"
|
|
|
|
object = PuppetStrings::Yard::CodeObjects::Type.new(schema['name'])
|
|
register object
|
|
|
|
docstring = schema['docs']
|
|
if docstring
|
|
register_docstring(object, PuppetStrings::Yard::Util.scrub_string(docstring.to_s), nil)
|
|
else
|
|
log.warn "Missing a description for Puppet resource type '#{object.name}' at #{statement.file}:#{statement.line}."
|
|
end
|
|
|
|
# Populate the parameters/properties/features to the type
|
|
populate_type_data(object, schema)
|
|
|
|
# Mark the type 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
|
|
|
|
# Warn if a summary longer than 140 characters was provided
|
|
PuppetStrings::Yard::Handlers::Helpers.validate_summary_tag(object) if object.has_tag? :summary
|
|
end
|
|
|
|
private
|
|
|
|
def raise_parse_error(msg, location = statement)
|
|
raise YARD::Parser::UndocumentableError, "#{msg} at #{location.file}:#{location.line}." if parameters.empty?
|
|
end
|
|
|
|
# check that the params of the register_type call are key/value pairs.
|
|
def kv_arg_list?(params)
|
|
params.type == :list && params.children.count > 0 && params.children.first.type == :list && params.children.first.children.count > 0 && statement.parameters.children.first.children.first.type == :assoc
|
|
end
|
|
|
|
def extract_schema
|
|
raise_parse_error("Expected list of key/value pairs as argument") unless kv_arg_list?(statement.parameters)
|
|
hash_from_node(statement.parameters.children.first)
|
|
end
|
|
|
|
def value_from_node(node)
|
|
return nil unless node
|
|
|
|
# puts "value from #{node.inspect}"
|
|
|
|
case node.type
|
|
when :int
|
|
node.source.to_i
|
|
when :hash
|
|
hash_from_node(node)
|
|
when :var_ref
|
|
var_ref_from_node(node)
|
|
when :symbol, :symbol_literal, :label, :dyna_symbol, :string_literal
|
|
node_as_string(node)
|
|
else
|
|
raise_parse_error("unexpected construct #{node.type}")
|
|
end
|
|
end
|
|
|
|
def hash_from_node(node)
|
|
return nil unless node
|
|
|
|
# puts "hash from #{node.inspect}"
|
|
|
|
kv_pairs = node.children.collect do |assoc|
|
|
[ value_from_node(assoc.children[0]), value_from_node(assoc.children[1]) ]
|
|
end
|
|
Hash[kv_pairs]
|
|
end
|
|
|
|
def var_ref_from_node(node)
|
|
return nil unless node
|
|
|
|
# puts "var_ref from #{node.inspect}"
|
|
|
|
if node.children.first.type == :kw
|
|
case node.children.first.source
|
|
when "false"
|
|
return false
|
|
when "true"
|
|
return true
|
|
when "nil"
|
|
return nil
|
|
else
|
|
raise_parse_error("unexpected keyword '#{node.children.first.source}'")
|
|
end
|
|
end
|
|
raise_parse_error("unexpected variable")
|
|
end
|
|
|
|
|
|
def populate_type_data(object, schema)
|
|
return if schema['attributes'].nil?
|
|
|
|
schema['attributes'].each do |name, definition|
|
|
# puts "Processing #{name}: #{definition.inspect}"
|
|
if ['parameter', 'namevar'].include? definition['behaviour']
|
|
object.add_parameter(create_parameter(name, definition))
|
|
else
|
|
object.add_property(create_property(name, definition))
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_parameter(name, definition)
|
|
parameter = PuppetStrings::Yard::CodeObjects::Type::Parameter.new(name, definition['desc'])
|
|
set_values(definition, parameter)
|
|
parameter
|
|
end
|
|
|
|
def create_property(name, definition)
|
|
property = PuppetStrings::Yard::CodeObjects::Type::Property.new(name, definition['desc'])
|
|
set_values(definition, property)
|
|
property
|
|
end
|
|
|
|
def set_values(definition, object)
|
|
object.data_type = definition['type'] if definition.key? 'type'
|
|
object.default = definition['default'] if definition.key? 'default'
|
|
object.isnamevar = definition.key?('behaviour') && definition['behaviour'] == 'namevar'
|
|
end
|
|
end
|