class PuppetStrings::Yard::Handlers::Ruby::TypeHandler

Implements the handler for Puppet resource types written in Ruby.

Constants

DEFAULT_ENSURABLE_DOCSTRING

The default docstring when ensurable is used without given a docstring.

Private Instance Methods

create_parameter(name, node) click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/type_handler.rb, line 116
def create_parameter(name, node)
  parameter = PuppetStrings::Yard::CodeObjects::Type::Parameter.new(name, find_docstring(node, "Puppet resource parameter '#{name}'"))
  set_values(node, parameter)
  parameter
end
create_property(name, node) click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/type_handler.rb, line 122
def create_property(name, node)
  property = PuppetStrings::Yard::CodeObjects::Type::Property.new(name, find_docstring(node, "Puppet resource property '#{name}'"))
  set_values(node, property)
  property
end
find_docstring(node, kind) click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/type_handler.rb, line 44
def find_docstring(node, kind)
  # Walk the tree searching for assignments or calls to desc/doc=
  node.traverse do |child|
    if child.type == :assign
      ivar = child.jump(:ivar)
      next unless ivar != child && ivar.source == '@doc'
      docstring = node_as_string(child[1])
      log.error "Failed to parse docstring for #{kind} near #{child.file}:#{child.line}." and return nil unless docstring
      return Puppet::Util::Docs.scrub(docstring)
    elsif child.is_a?(YARD::Parser::Ruby::MethodCallNode)
      # Look for a call to a dispatch method with a block
      next unless child.method_name &&
                  (child.method_name.source == 'desc' || child.method_name.source == 'doc=') &&
                  child.parameters(false).count == 1

      docstring = node_as_string(child.parameters[0])
      log.error "Failed to parse docstring for #{kind} near #{child.file}:#{child.line}." and return nil unless docstring
      return Puppet::Util::Docs.scrub(docstring)
    end
  end
  log.warn "Missing a description for #{kind} at #{node.file}:#{node.line}."
  nil
end
get_name() click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/type_handler.rb, line 36
def get_name
  parameters = statement.parameters(false)
  raise YARD::Parser::UndocumentableError, "Expected at least one parameter to Puppet::Type.newtype 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
populate_type_data(object) click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/type_handler.rb, line 68
def populate_type_data(object)
  # Traverse the block looking for properties/parameters/features
  block = statement.block
  return unless block && block.count >= 2
  block[1].children.each do |node|
    next unless node.is_a?(YARD::Parser::Ruby::MethodCallNode) &&
                node.method_name

    method_name = node.method_name.source
    parameters = node.parameters(false)

    if method_name == 'newproperty'
      # Add a property to the object
      next unless parameters.count >= 1
      name = node_as_string(parameters[0])
      next unless name
      object.add_property(create_property(name, node))
    elsif method_name == 'newparam'
      # Add a parameter to the object
      next unless parameters.count >= 1
      name = node_as_string(parameters[0])
      next unless name
      object.add_parameter(create_parameter(name, node))
    elsif method_name == 'feature'
      # Add a feature to the object
      next unless parameters.count >= 2
      name = node_as_string(parameters[0])
      next unless name

      docstring = node_as_string(parameters[1])
      next unless docstring

      object.add_feature(PuppetStrings::Yard::CodeObjects::Type::Feature.new(name, docstring))
    elsif method_name == 'ensurable'
      if node.block
        property = create_property('ensure', node)
        property.docstring = DEFAULT_ENSURABLE_DOCSTRING if property.docstring.empty?
      else
        property = PuppetStrings::Yard::CodeObjects::Type::Property.new('ensure', DEFAULT_ENSURABLE_DOCSTRING)
        property.add('present')
        property.add('absent')
        property.default = 'present'
      end
      object.add_property property
    end
  end
end
set_default_namevar(object) click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/type_handler.rb, line 177
def set_default_namevar(object)
  return unless object.properties || object.parameters
  default = nil
  if object.properties
    object.properties.each do |property|
      return nil if property.isnamevar
      default = property if property.name == 'name'
    end
  end
  if object.parameters
    object.parameters.each do |parameter|
      return nil if parameter.isnamevar
      default ||= parameter if parameter.name == 'name'
    end
  end
  default.isnamevar = true if default
end
set_values(node, object) click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/type_handler.rb, line 128
def set_values(node, object)
  return unless node.block && node.block.count >= 2

  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
    parameters = child.parameters(false)

    if method_name == 'newvalue'
      next unless parameters.count >= 1
      object.add(node_as_string(parameters[0]) || parameters[0].source)
    elsif method_name == 'newvalues'
      parameters.each do |p|
        object.add(node_as_string(p) || p.source)
      end
    elsif method_name == 'aliasvalue'
      next unless parameters.count >= 2
      object.alias(node_as_string(parameters[0]) || parameters[0].source, node_as_string(parameters[1]) || parameters[1].source)
    elsif method_name == 'defaultto'
      next unless parameters.count >= 1
      object.default = node_as_string(parameters[0]) || parameters[0].source
    elsif method_name == 'isnamevar'
      object.isnamevar = true
    elsif method_name == 'defaultvalues' && object.name == 'ensure'
      object.add('present')
      object.add('absent')
      object.default = 'present'
    end
  end
  if object.is_a? PuppetStrings::Yard::CodeObjects::Type::Parameter
    # Process the options for parameter base types
    parameters = node.parameters(false)
    if parameters.count >= 2
      parameters[1].each do |kvp|
        next unless kvp.count == 2
        next unless node_as_string(kvp[0]) == 'parent'
        if kvp[1].source == 'Puppet::Parameter::Boolean'
          object.add('true') unless object.values.include? 'true'
          object.add('false') unless object.values.include? 'false'
          object.add('yes') unless object.values.include? 'yes'
          object.add('no') unless object.values.include? 'no'
        end
        break
      end
    end
  end
end