Merge pull request #7 from hkenney/PDOC-3_refactor-prototype-code
(PDOC-3) Refactor prototype code to make it more readable
This commit is contained in:
commit
970b60481f
|
@ -3,6 +3,7 @@ require 'puppet/face'
|
|||
Puppet::Face.define(:strings, '0.0.1') do
|
||||
summary "Generate Puppet documentation with YARD."
|
||||
|
||||
# Ensures that the user has the needed features to use puppet strings
|
||||
def check_required_features
|
||||
unless Puppet.features.yard?
|
||||
raise RuntimeError, "The 'yard' gem must be installed in order to use this face."
|
||||
|
@ -17,14 +18,6 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
end
|
||||
end
|
||||
|
||||
# Maps things like the Puppet `--debug` flag to YARD options.
|
||||
def merge_puppet_args!(yard_args)
|
||||
yard_args.unshift '--debug' if Puppet[:debug]
|
||||
yard_args.unshift '--backtrace' if Puppet[:trace]
|
||||
|
||||
yard_args
|
||||
end
|
||||
|
||||
# A list of globs that generates the default list of module files from which
|
||||
# documentation can be extracted.
|
||||
#
|
||||
|
@ -40,6 +33,9 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
|
||||
when_invoked do |*args|
|
||||
check_required_features
|
||||
require 'puppetx/puppetlabs/strings/actions'
|
||||
|
||||
yardoc_actions = Puppetx::PuppetLabs::Strings::Actions.new(Puppet[:debug], Puppet[:trace])
|
||||
|
||||
# The last element of the argument array should be the options hash.
|
||||
#
|
||||
|
@ -52,12 +48,8 @@ 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)
|
||||
merge_puppet_args!(yard_args)
|
||||
|
||||
require 'puppetx/puppetlabs/strings/yard/plugin'
|
||||
|
||||
# Hand off to YARD for further processing.
|
||||
YARD::CLI::Yardoc.run(*yard_args)
|
||||
yardoc_actions.generate_documentation(*yard_args)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -65,59 +57,29 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
# (.yardoc directories) for Ruby Gems. Currently lacks the fine-grained
|
||||
# control over where these indicies are created and just dumps them in the
|
||||
# module roots.
|
||||
action(:modules) do
|
||||
summary "Generate YARD indices for a list of modules."
|
||||
arguments "[module-name ...]"
|
||||
|
||||
when_invoked do |*args|
|
||||
check_required_features
|
||||
require 'puppetx/puppetlabs/strings/yard/plugin'
|
||||
opts = args.pop
|
||||
|
||||
# NOTE: The retrun value of the `module` Face seems to have changed in
|
||||
# 3.6.x. This part of the code will blow up if run under an earlier
|
||||
# version of Puppet.
|
||||
modules = Puppet::Face[:module, :current].list
|
||||
module_list = modules[:modules_by_path].values.flatten
|
||||
|
||||
# TODO: Can use select! if Ruby 1.8.7 support is dropped.
|
||||
module_list = module_list.select {|m| args.include? m.name} unless args.empty?
|
||||
|
||||
# Invoke `yardoc` with -n so that it doesn't generate any HTML output but
|
||||
# does build a `.yardoc` index that other tools can generate output from.
|
||||
yard_args = %w[--no-stats -n] + MODULE_SOURCEFILES
|
||||
merge_puppet_args!(yard_args)
|
||||
|
||||
module_list.each do |m|
|
||||
Dir.chdir(m.path) do
|
||||
YARD::CLI::Yardoc.run(*yard_args)
|
||||
|
||||
# Cear the global Registry so that objects from one module don't
|
||||
# bleed into the next.
|
||||
YARD::Registry.clear
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
action(:server) do
|
||||
summary "Serve YARD documentation for modules."
|
||||
|
||||
when_invoked do |*args|
|
||||
check_required_features
|
||||
require 'puppetx/puppetlabs/strings/yard/plugin'
|
||||
require 'puppetx/puppetlabs/strings/actions'
|
||||
|
||||
server_actions = Puppetx::PuppetLabs::Strings::Actions.new(Puppet[:debug], Puppet[:trace])
|
||||
|
||||
opts = args.pop
|
||||
|
||||
module_names = args
|
||||
|
||||
# FIXME: This is pretty inefficient as it forcibly re-generates the YARD
|
||||
# indicies each time the server is started. However, it ensures things are
|
||||
# generated properly.
|
||||
module_list = Puppet::Face[:strings, :current].modules
|
||||
module_list = server_actions.index_documentation_for_modules(module_names, MODULE_SOURCEFILES)
|
||||
|
||||
module_tuples = module_list.map do |mod|
|
||||
name = (mod.forge_name || mod.name).gsub('/', '-')
|
||||
yard_index = File.join(mod.path, '.yardoc')
|
||||
module_tuples = server_actions.generate_module_tuples(module_list)
|
||||
|
||||
[name, yard_index]
|
||||
module_tuples.map! do |mod|
|
||||
[mod[:name], mod[:index_path]]
|
||||
end
|
||||
|
||||
# The `-m` flag means a list of name/path pairs will follow. The name is
|
||||
|
@ -126,7 +88,8 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
yard_args = %w[-m -q] + module_tuples.flatten
|
||||
merge_puppet_args!(yard_args)
|
||||
|
||||
YARD::CLI::Server.run(*yard_args)
|
||||
server_actions.serve_documentation(*yard_args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
require 'puppet/util/feature'
|
||||
|
||||
# Support require_relative under Ruby 1.8.7.
|
||||
Puppet.features.add(:require_relative, :libs => ['backports/1.9.1/kernel/require_relative'])
|
|
@ -1,16 +1,53 @@
|
|||
require 'puppet'
|
||||
require 'puppetx'
|
||||
require 'puppet/pops'
|
||||
require 'puppet/util/docs'
|
||||
require 'yard'
|
||||
|
||||
# Nothing to see here except forward declarations.
|
||||
module Puppetx::PuppetLabs
|
||||
module Strings
|
||||
|
||||
# This submodule contains bits that interface with the YARD plugin system.
|
||||
module YARD
|
||||
end
|
||||
|
||||
# This submodule contains bits that operate on the Pops module produced by
|
||||
# the Future parser.
|
||||
module Pops
|
||||
require 'puppetx/puppetlabs/strings/pops/yard_statement'
|
||||
require 'puppetx/puppetlabs/strings/pops/yard_transformer'
|
||||
end
|
||||
|
||||
# This submodule contains bits that interface with the YARD plugin system.
|
||||
module YARD
|
||||
require 'puppetx/puppetlabs/strings/yard/monkey_patches'
|
||||
require 'puppetx/puppetlabs/strings/yard/parser'
|
||||
|
||||
# This submodule contains code objects which are used to represent relevant
|
||||
# aspects of puppet code in YARD's Registry
|
||||
module CodeObjects
|
||||
require 'puppetx/puppetlabs/strings/yard/code_objects/puppet_namespace_object'
|
||||
require 'puppetx/puppetlabs/strings/yard/code_objects/defined_type_object'
|
||||
require 'puppetx/puppetlabs/strings/yard/code_objects/host_class_object'
|
||||
end
|
||||
|
||||
# This submodule contains handlers which are used to extract relevant data about
|
||||
# puppet code from the ASTs produced by the Ruby and Puppet parsers
|
||||
module Handlers
|
||||
# This utility library contains some tools for working with Puppet docstrings
|
||||
require 'puppetx/puppetlabs/strings/yard/handlers/base'
|
||||
require 'puppetx/puppetlabs/strings/yard/handlers/defined_type_handler'
|
||||
require 'puppetx/puppetlabs/strings/yard/handlers/host_class_handler'
|
||||
require 'puppetx/puppetlabs/strings/yard/handlers/puppet_3x_function_handler'
|
||||
require 'puppetx/puppetlabs/strings/yard/handlers/puppet_4x_function_handler'
|
||||
end
|
||||
|
||||
::YARD::Parser::SourceParser.register_parser_type(:puppet,
|
||||
Puppetx::PuppetLabs::Strings::YARD::PuppetParser,
|
||||
['pp'])
|
||||
::YARD::Handlers::Processor.register_handler_namespace(:puppet,
|
||||
Puppetx::PuppetLabs::Strings::YARD::Handlers)
|
||||
|
||||
# FIXME: Might not be the best idea to have the template code on the Ruby
|
||||
# LOAD_PATH as the contents of this directory really aren't library code.
|
||||
::YARD::Templates::Engine.register_template_path(
|
||||
File.join(File.dirname(__FILE__), 'strings', 'yard', 'templates'))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
require 'puppetx/puppetlabs/strings'
|
||||
|
||||
class Puppetx::PuppetLabs::Strings::Actions
|
||||
|
||||
# Creates a new instance of the Actions class by determining
|
||||
# whether or not debug and backtrace arguments should be sent
|
||||
# to YARD
|
||||
def initialize(puppet_debug, puppet_backtrace)
|
||||
@debug = puppet_debug
|
||||
@backtrace = puppet_backtrace
|
||||
end
|
||||
|
||||
# Holds the name of a module and the file path to its YARD index
|
||||
ModuleIndex = Struct.new(:name, :index_path)
|
||||
|
||||
|
||||
# Maps things like the Puppet `--debug` flag to YARD options.
|
||||
def merge_puppet_args!(yard_args)
|
||||
yard_args.unshift '--debug' if @debug
|
||||
yard_args.unshift '--backtrace' if @backtrace
|
||||
|
||||
yard_args
|
||||
end
|
||||
|
||||
# Builds doc indices (.yardoc directories) for modules.
|
||||
# Currently lacks the fine-grained control over where these
|
||||
# indices are created and just dumps them in the module roots.
|
||||
#
|
||||
# @return [Array<Module>] the modules to be documented
|
||||
#
|
||||
# @param [Array<String>] module_names a list of the module source files
|
||||
# @param [Array<String>] module_sourcefiles default list of module files
|
||||
def index_documentation_for_modules(module_names, module_sourcefiles)
|
||||
# NOTE: The return value of the `module` Face seems to have changed in
|
||||
# 3.6.x. This part of the code will blow up if run under an earlier
|
||||
# version of Puppet.
|
||||
modules = Puppet::Face[:module, :current].list
|
||||
module_list = modules[:modules_by_path].values.flatten
|
||||
|
||||
module_list.select! {|m| module_names.include? m.name} unless module_names.empty?
|
||||
|
||||
# Invoke `yardoc` with -n so that it doesn't generate any HTML output but
|
||||
# does build a `.yardoc` index that other tools can generate output from.
|
||||
yard_args = %w[--no-stats -n] + module_sourcefiles
|
||||
merge_puppet_args!(yard_args)
|
||||
|
||||
module_list.each do |m|
|
||||
Dir.chdir(m.path) do
|
||||
YARD::CLI::Yardoc.run(*yard_args)
|
||||
|
||||
# Clear the global Registry so that objects from one module don't
|
||||
# bleed into the next.
|
||||
YARD::Registry.clear
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Extracts the needed information of the modules we're documenting
|
||||
#
|
||||
# @return [Array<ModuleIndex>] An array of representation of the modules
|
||||
# to produce documentation for. Each ModuleIndex contains the module name
|
||||
# and the path to its YARD index
|
||||
#
|
||||
# @param [Array<String>] module_list a list of the module source files
|
||||
def generate_module_tuples(module_list)
|
||||
module_list.map do |mod|
|
||||
name = (mod.forge_name || mod.name).gsub('/', '-')
|
||||
yard_index = File.join(mod.path, '.yardoc')
|
||||
|
||||
ModuleIndex.new(name, yard_index)
|
||||
end
|
||||
end
|
||||
|
||||
# Hands off the needed information to YARD so it may
|
||||
# serve the documentation
|
||||
#
|
||||
# @param [Array<String>] yard_args a list of all the arguments to pass to YARD
|
||||
def serve_documentation(*yard_args)
|
||||
merge_puppet_args!(yard_args)
|
||||
YARD::CLI::Server.run(*yard_args)
|
||||
end
|
||||
|
||||
# Hands off the needed information to YARD so it may
|
||||
# generate the documentation
|
||||
#
|
||||
# @param [Array<String>] yard_args a list of all the arguments to pass to YARD
|
||||
def generate_documentation(*yard_args)
|
||||
merge_puppet_args!(yard_args)
|
||||
YARD::CLI::Yardoc.run(*yard_args)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,78 +1,72 @@
|
|||
require 'ostruct'
|
||||
require 'puppet/pops'
|
||||
|
||||
require_relative '../../strings'
|
||||
# An adapter class that conforms a Pops model instance + adapters to the
|
||||
# interface expected by YARD handlers.
|
||||
#
|
||||
# FIXME: Inhertiting from OpenStruct is a bit of a hack. It allows attributes
|
||||
# to be declared as needed but in the long run understandibility of the code
|
||||
# would be improved by having a concrete model.
|
||||
class Puppetx::PuppetLabs::Strings::Pops::YARDStatement < OpenStruct
|
||||
attr_reader :pops_obj, :comments
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::Pops
|
||||
# An adapter class that conforms a Pops model instance + adapters to the
|
||||
# interface expected by YARD handlers.
|
||||
#
|
||||
# FIXME: Inhertiting from OpenStruct is a bit of a hack. It allows attributes
|
||||
# to be declared as needed but in the long run understandibility of the code
|
||||
# would be improved by having a concrete model.
|
||||
class YARDStatement < OpenStruct
|
||||
attr_reader :pops_obj, :comments
|
||||
def initialize(pops_obj)
|
||||
# Initialize OpenStruct
|
||||
super({})
|
||||
|
||||
def initialize(pops_obj)
|
||||
# Initialize OpenStruct
|
||||
super({})
|
||||
unless pops_obj.is_a? Puppet::Pops::Model::PopsObject
|
||||
raise ArgumentError, "A YARDStatement can only be initialized from a PopsObject. Got a: #{pops_obj.class}"
|
||||
end
|
||||
|
||||
unless pops_obj.is_a? Puppet::Pops::Model::PopsObject
|
||||
raise ArgumentError, "A YARDStatement can only be initialized from a PopsObject. Got a: #{pops_obj.class}"
|
||||
@pops_obj = pops_obj
|
||||
@pos_adapter = Puppet::Pops::Adapters::SourcePosAdapter.adapt(@pops_obj)
|
||||
# FIXME: Perhaps this should be a seperate adapter?
|
||||
@comments = extract_comments
|
||||
end
|
||||
|
||||
def type
|
||||
pops_obj.class
|
||||
end
|
||||
|
||||
def line
|
||||
@line ||= @pos_adapter.line
|
||||
end
|
||||
|
||||
def source
|
||||
@source ||= @pos_adapter.extract_text
|
||||
end
|
||||
|
||||
# FIXME: I don't know quite what these are supposed to do, but they show up
|
||||
# quite often in the YARD handler code. Figure out whether they are
|
||||
# necessary.
|
||||
alias_method :show, :source
|
||||
def comments_hash_flag; nil end
|
||||
def comments_range; nil end
|
||||
|
||||
private
|
||||
# TODO: This stuff should probably be part of a separate class/adapter.
|
||||
COMMENT_PATTERN = /^\s*#.*\n/
|
||||
|
||||
def extract_comments
|
||||
comments = []
|
||||
program = pops_obj.eAllContainers.find {|c| c.is_a?(Puppet::Pops::Model::Program) }
|
||||
# FIXME: Horribly inefficient. Multiple copies. Generator pattern would
|
||||
# be much better.
|
||||
source_text = program.source_text.lines.to_a
|
||||
|
||||
source_text.slice(0, line-1).reverse.each do |line|
|
||||
if COMMENT_PATTERN.match(line)
|
||||
# FIXME: The gsub trims comments, but is extremely optimistic: It
|
||||
# assumes only one space separates the comment body from the
|
||||
# comment character.
|
||||
comments.unshift line.gsub(/^\s*#\s/, '')
|
||||
else
|
||||
# No comment found on this line. We must be done piecing together a
|
||||
# comment block.
|
||||
break
|
||||
end
|
||||
|
||||
@pops_obj = pops_obj
|
||||
@pos_adapter = Puppet::Pops::Adapters::SourcePosAdapter.adapt(@pops_obj)
|
||||
# FIXME: Perhaps this should be a seperate adapter?
|
||||
@comments = extract_comments
|
||||
end
|
||||
|
||||
def type
|
||||
pops_obj.class
|
||||
end
|
||||
|
||||
def line
|
||||
@line ||= @pos_adapter.line
|
||||
end
|
||||
|
||||
def source
|
||||
@source ||= @pos_adapter.extract_text
|
||||
end
|
||||
|
||||
# FIXME: I don't know quite what these are supposed to do, but they show up
|
||||
# quite often in the YARD handler code. Figure out whether they are
|
||||
# necessary.
|
||||
alias_method :show, :source
|
||||
def comments_hash_flag; nil end
|
||||
def comments_range; nil end
|
||||
|
||||
private
|
||||
# TODO: This stuff should probably be part of a separate class/adapter.
|
||||
COMMENT_PATTERN = /^\s*#.*\n/
|
||||
|
||||
def extract_comments
|
||||
comments = []
|
||||
program = pops_obj.eAllContainers.find {|c| c.is_a?(Puppet::Pops::Model::Program) }
|
||||
# FIXME: Horribly inefficient. Multiple copies. Generator pattern would
|
||||
# be much better.
|
||||
source_text = program.source_text.lines.to_a
|
||||
|
||||
source_text.slice(0, line-1).reverse.each do |line|
|
||||
if COMMENT_PATTERN.match(line)
|
||||
# FIXME: The gsub trims comments, but is extremely optimistic: It
|
||||
# assumes only one space separates the comment body from the
|
||||
# comment character.
|
||||
comments.unshift line.gsub(/^\s*#\s/, '')
|
||||
else
|
||||
# No comment found on this line. We must be done piecing together a
|
||||
# comment block.
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Stick everything back together.
|
||||
comments.join
|
||||
end
|
||||
|
||||
# Stick everything back together.
|
||||
comments.join
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,54 +1,47 @@
|
|||
require 'puppet/pops'
|
||||
# Loosely based on the TreeDumper classes in Pops::Model. The responsibility of
|
||||
# this class is to walk a Pops::Model and output objects that can be consumed
|
||||
# by YARD handlers.
|
||||
#
|
||||
# @note Currently, this class only extracts node, host class and type
|
||||
# definitions.
|
||||
class Puppetx::PuppetLabs::Strings::Pops::YARDTransformer
|
||||
def initialize
|
||||
@transform_visitor = Puppet::Pops::Visitor.new(self, 'transform')
|
||||
end
|
||||
|
||||
require_relative '../../strings'
|
||||
require_relative 'yard_statement'
|
||||
def transform(o)
|
||||
@transform_visitor.visit(o)
|
||||
end
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::Pops
|
||||
# Loosely based on the TreeDumper classes in Pops::Model. The responsibility of
|
||||
# this class is to walk a Pops::Model and output objects that can be consumed
|
||||
# by YARD handlers.
|
||||
#
|
||||
# @note Currently, this class only extracts node, host class and type
|
||||
# definitions.
|
||||
class YARDTransformer
|
||||
def initialize
|
||||
@transform_visitor = Puppet::Pops::Visitor.new(self, 'transform')
|
||||
private
|
||||
|
||||
def transform_Factory(o)
|
||||
transform(o.current)
|
||||
end
|
||||
|
||||
def transform_Program(o)
|
||||
o.definitions.map{|d| transform(d)}
|
||||
end
|
||||
|
||||
# Extract comments from type definitions and class definitions. Wrap them
|
||||
# into YARDStatement objects that provide an interface for YARD handlers.
|
||||
def transform_NamedDefinition(o)
|
||||
obj = Puppetx::PuppetLabs::Strings::Pops::YARDStatement.new(o)
|
||||
obj.parameters = o.parameters.map do |p|
|
||||
param_tuple = [transform(p)]
|
||||
param_tuple << ( p.value.nil? ? nil : transform(p.value) )
|
||||
end
|
||||
|
||||
def transform(o)
|
||||
@transform_visitor.visit(o)
|
||||
end
|
||||
obj
|
||||
end
|
||||
|
||||
private
|
||||
# Catch-all visitor.
|
||||
def transform_Positioned(o)
|
||||
Puppetx::PuppetLabs::Strings::Pops::YARDStatement.new(o)
|
||||
end
|
||||
|
||||
def transform_Factory(o)
|
||||
transform(o.current)
|
||||
end
|
||||
|
||||
def transform_Program(o)
|
||||
o.definitions.map{|d| transform(d)}
|
||||
end
|
||||
|
||||
# Extract comments from type definitions and class definitions. Wrap them
|
||||
# into YARDStatement objects that provide an interface for YARD handlers.
|
||||
def transform_NamedDefinition(o)
|
||||
obj = YARDStatement.new(o)
|
||||
obj.parameters = o.parameters.map do |p|
|
||||
param_tuple = [transform(p)]
|
||||
param_tuple << ( p.value.nil? ? nil : transform(p.value) )
|
||||
end
|
||||
|
||||
obj
|
||||
end
|
||||
|
||||
# Catch-all visitor.
|
||||
def transform_Positioned(o)
|
||||
YARDStatement.new(o)
|
||||
end
|
||||
|
||||
# nil in... nil out!
|
||||
def transform_NilClass(o)
|
||||
nil
|
||||
end
|
||||
# nil in... nil out!
|
||||
def transform_NilClass(o)
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
require_relative 'code_objects/puppet_namespace_object'
|
||||
require_relative 'code_objects/defined_type_object'
|
||||
require_relative 'code_objects/host_class_object'
|
|
@ -1,11 +1,5 @@
|
|||
require 'puppet/pops'
|
||||
|
||||
require_relative 'puppet_namespace_object'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
class DefinedTypeObject < PuppetNamespaceObject
|
||||
# A list of parameters attached to this class.
|
||||
# @return [Array<Array(String, String)>]
|
||||
attr_accessor :parameters
|
||||
end
|
||||
class Puppetx::PuppetLabs::Strings::YARD::CodeObjects::DefinedTypeObject < Puppetx::PuppetLabs::Strings::YARD::CodeObjects::PuppetNamespaceObject
|
||||
# A list of parameters attached to this class.
|
||||
# @return [Array<Array(String, String)>]
|
||||
attr_accessor :parameters
|
||||
end
|
||||
|
|
|
@ -1,26 +1,22 @@
|
|||
require_relative 'defined_type_object'
|
||||
class Puppetx::PuppetLabs::Strings::YARD::CodeObjects::HostClassObject < Puppetx::PuppetLabs::Strings::YARD::CodeObjects::DefinedTypeObject
|
||||
# The {HostClassObject} that this class inherits from, if any.
|
||||
# @return [HostClassObject, Proxy, nil]
|
||||
attr_accessor :parent_class
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
class HostClassObject < DefinedTypeObject
|
||||
# The {HostClassObject} that this class inherits from, if any.
|
||||
# @return [HostClassObject, Proxy, nil]
|
||||
attr_accessor :parent_class
|
||||
|
||||
# NOTE: `include_mods` is never used as it makes no sense for Puppet, but
|
||||
# this is called by `YARD::Registry` and it will pass a parameter.
|
||||
def inheritance_tree(include_mods = false)
|
||||
if parent_class.is_a?(HostClassObject)
|
||||
# Cool. We got a host class. Return self + parent inheritance tree.
|
||||
[self] + parent_class.inheritance_tree
|
||||
elsif parent_class.is_a?(YARD::CodeObjects::Proxy)
|
||||
# We have a reference to a parent that has not been created yet. Just
|
||||
# return it.
|
||||
[self, parent_class]
|
||||
else
|
||||
# Most likely no parent class. But also possibly an object that we
|
||||
# shouldn't inherit from. Just return self.
|
||||
[self]
|
||||
end
|
||||
# NOTE: `include_mods` is never used as it makes no sense for Puppet, but
|
||||
# this is called by `YARD::Registry` and it will pass a parameter.
|
||||
def inheritance_tree(include_mods = false)
|
||||
if parent_class.is_a?(Puppetx::PuppetLabs::Strings::YARD::CodeObjects::HostClassObject)
|
||||
# Cool. We got a host class. Return self + parent inheritance tree.
|
||||
[self] + parent_class.inheritance_tree
|
||||
elsif parent_class.is_a?(YARD::CodeObjects::Proxy)
|
||||
# We have a reference to a parent that has not been created yet. Just
|
||||
# return it.
|
||||
[self, parent_class]
|
||||
else
|
||||
# Most likely no parent class. But also possibly an object that we
|
||||
# shouldn't inherit from. Just return self.
|
||||
[self]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,36 +1,30 @@
|
|||
require 'yard'
|
||||
|
||||
require_relative '../../../strings'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
class PuppetNamespaceObject < YARD::CodeObjects::NamespaceObject
|
||||
# NOTE: `YARD::Registry#resolve` requires a method with this signature to
|
||||
# be present on all subclasses of `NamespaceObject`.
|
||||
def inheritance_tree(include_mods = false)
|
||||
[self]
|
||||
end
|
||||
|
||||
# FIXME: We used to override `self.new` to ensure no YARD proxies were
|
||||
# created for namespaces segments that did not map to a host class or
|
||||
# defined type. Fighting the system in this way turned out to be
|
||||
# counter-productive.
|
||||
#
|
||||
# However, if a proxy is left in, YARD will drop back to namspace-mangling
|
||||
# heuristics that are very specific to Ruby and which produce ugly paths in
|
||||
# the resulting output. Need to find a way to address this.
|
||||
#
|
||||
# Tried:
|
||||
#
|
||||
# - Overriding self.new in the code object. Failed because self.new
|
||||
# overrides are gross and difficult to pull off. Especially when
|
||||
# replacing an existing override.
|
||||
#
|
||||
# - Adding functionality to the base handler to ensure something other
|
||||
# than a proxy occupies each namespace segment. Failed because once a
|
||||
# code object is created with a namespace, it will never update.
|
||||
# Unless that namespace is set to a Proxy.
|
||||
#
|
||||
# def self.new(namespace, name, *args, &block)
|
||||
class Puppetx::PuppetLabs::Strings::YARD::CodeObjects::PuppetNamespaceObject < YARD::CodeObjects::NamespaceObject
|
||||
# NOTE: `YARD::Registry#resolve` requires a method with this signature to
|
||||
# be present on all subclasses of `NamespaceObject`.
|
||||
def inheritance_tree(include_mods = false)
|
||||
[self]
|
||||
end
|
||||
|
||||
# FIXME: We used to override `self.new` to ensure no YARD proxies were
|
||||
# created for namespaces segments that did not map to a host class or
|
||||
# defined type. Fighting the system in this way turned out to be
|
||||
# counter-productive.
|
||||
#
|
||||
# However, if a proxy is left in, YARD will drop back to namspace-mangling
|
||||
# heuristics that are very specific to Ruby and which produce ugly paths in
|
||||
# the resulting output. Need to find a way to address this.
|
||||
#
|
||||
# Tried:
|
||||
#
|
||||
# - Overriding self.new in the code object. Failed because self.new
|
||||
# overrides are gross and difficult to pull off. Especially when
|
||||
# replacing an existing override.
|
||||
#
|
||||
# - Adding functionality to the base handler to ensure something other
|
||||
# than a proxy occupies each namespace segment. Failed because once a
|
||||
# code object is created with a namespace, it will never update.
|
||||
# Unless that namespace is set to a Proxy.
|
||||
#
|
||||
# def self.new(namespace, name, *args, &block)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
require_relative 'handlers/base'
|
||||
require_relative 'handlers/defined_type_handler'
|
||||
require_relative 'handlers/host_class_handler'
|
||||
|
||||
require_relative 'handlers/puppet_3x_function_handler'
|
||||
require_relative 'handlers/puppet_4x_function_handler'
|
|
@ -1,19 +1,11 @@
|
|||
require 'yard'
|
||||
require 'puppet/pops'
|
||||
|
||||
require_relative '../../../strings'
|
||||
require_relative '../code_objects'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
class Base < YARD::Handlers::Base
|
||||
# Easy access to Pops model objects for handler matching.
|
||||
include Puppet::Pops::Model
|
||||
# Easy access to custom code objects from which documentation is generated.
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
def self.handles?(statement)
|
||||
handlers.any? {|h| h == statement.type}
|
||||
end
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::Base < YARD::Handlers::Base
|
||||
# Easy access to Pops model objects for handler matching.
|
||||
include Puppet::Pops::Model
|
||||
# Easy access to custom code objects from which documentation is generated.
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
def self.handles?(statement)
|
||||
handlers.any? {|h| h == statement.type}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
require_relative 'base'
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::DefinedTypeHandler < Puppetx::PuppetLabs::Strings::YARD::Handlers:: Base
|
||||
handles ResourceTypeDefinition
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
class DefinedTypeHandler < Base
|
||||
handles ResourceTypeDefinition
|
||||
|
||||
process do
|
||||
obj = DefinedTypeObject.new(:root, statement.pops_obj.name) do |o|
|
||||
o.parameters = statement.parameters.map do |a|
|
||||
param_tuple = [a[0].pops_obj.name]
|
||||
param_tuple << ( a[1].nil? ? nil : a[1].source )
|
||||
end
|
||||
process do
|
||||
obj = DefinedTypeObject.new(:root, statement.pops_obj.name) do |o|
|
||||
o.parameters = statement.parameters.map do |a|
|
||||
param_tuple = [a[0].pops_obj.name]
|
||||
param_tuple << ( a[1].nil? ? nil : a[1].source )
|
||||
end
|
||||
|
||||
register obj
|
||||
end
|
||||
|
||||
register obj
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
require_relative 'base'
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::HostClassHandler < Puppetx::PuppetLabs::Strings::YARD::Handlers::Base
|
||||
handles HostClassDefinition
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
class HostClassHandler < Base
|
||||
handles HostClassDefinition
|
||||
|
||||
process do
|
||||
obj = HostClassObject.new(:root, statement.pops_obj.name) do |o|
|
||||
o.parameters = statement.parameters.map do |a|
|
||||
param_tuple = [a[0].pops_obj.name]
|
||||
param_tuple << ( a[1].nil? ? nil : a[1].source )
|
||||
end
|
||||
process do
|
||||
obj = HostClassObject.new(:root, statement.pops_obj.name) do |o|
|
||||
o.parameters = statement.parameters.map do |a|
|
||||
param_tuple = [a[0].pops_obj.name]
|
||||
param_tuple << ( a[1].nil? ? nil : a[1].source )
|
||||
end
|
||||
|
||||
statement.pops_obj.tap do |o|
|
||||
if o.parent_class
|
||||
obj.parent_class = P(:root, o.parent_class)
|
||||
end
|
||||
end
|
||||
|
||||
register obj
|
||||
end
|
||||
|
||||
statement.pops_obj.tap do |o|
|
||||
if o.parent_class
|
||||
obj.parent_class = P(:root, o.parent_class)
|
||||
end
|
||||
end
|
||||
|
||||
register obj
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,89 +1,83 @@
|
|||
# This utility library contains some tools for working with Puppet docstrings.
|
||||
require 'puppet/util/docs'
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::Puppet3xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
require_relative '../code_objects'
|
||||
handles method_call(:newfunction)
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
class Puppet3xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
process do
|
||||
name, options = process_parameters
|
||||
|
||||
handles method_call(:newfunction)
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
|
||||
process do
|
||||
name, options = process_parameters
|
||||
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
|
||||
register obj
|
||||
if options['doc']
|
||||
register_docstring(obj, options['doc'], nil)
|
||||
end
|
||||
|
||||
# This has to be done _after_ register_docstring as all tags on the
|
||||
# object are overwritten by tags parsed out of the docstring.
|
||||
return_type = options['type']
|
||||
return_type ||= 'statement' # Default for newfunction
|
||||
obj.add_tag YARD::Tags::Tag.new(:return, '', return_type)
|
||||
|
||||
# FIXME: This is a hack that allows us to document the Puppet Core which
|
||||
# uses `--no-transitive-tag api` and then only shows things explicitly
|
||||
# tagged with `public` or `private` api. This is kind of insane and
|
||||
# should be fixed upstream.
|
||||
obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
register obj
|
||||
if options['doc']
|
||||
register_docstring(obj, options['doc'], nil)
|
||||
end
|
||||
|
||||
private
|
||||
# This has to be done _after_ register_docstring as all tags on the
|
||||
# object are overwritten by tags parsed out of the docstring.
|
||||
return_type = options['type']
|
||||
return_type ||= 'statement' # Default for newfunction
|
||||
obj.add_tag YARD::Tags::Tag.new(:return, '', return_type)
|
||||
|
||||
# Returns a {PuppetNamespaceObject} for holding functions. Creates this
|
||||
# object if necessary.
|
||||
#
|
||||
# @return [PuppetNamespaceObject]
|
||||
def function_namespace
|
||||
# NOTE: This tricky. If there is ever a Ruby class or module with the
|
||||
# name ::Puppet3xFunctions, then there will be a clash. Hopefully the name
|
||||
# is sufficiently uncommon.
|
||||
obj = P(:root, 'Puppet3xFunctions')
|
||||
if obj.is_a? Proxy
|
||||
namespace_obj = PuppetNamespaceObject.new(:root, 'Puppet3xFunctions')
|
||||
namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
# FIXME: This is a hack that allows us to document the Puppet Core which
|
||||
# uses `--no-transitive-tag api` and then only shows things explicitly
|
||||
# tagged with `public` or `private` api. This is kind of insane and
|
||||
# should be fixed upstream.
|
||||
obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
end
|
||||
|
||||
register namespace_obj
|
||||
end
|
||||
private
|
||||
|
||||
obj
|
||||
# Returns a {PuppetNamespaceObject} for holding functions. Creates this
|
||||
# object if necessary.
|
||||
#
|
||||
# @return [PuppetNamespaceObject]
|
||||
def function_namespace
|
||||
# NOTE: This tricky. If there is ever a Ruby class or module with the
|
||||
# name ::Puppet3xFunctions, then there will be a clash. Hopefully the name
|
||||
# is sufficiently uncommon.
|
||||
obj = P(:root, 'Puppet3xFunctions')
|
||||
if obj.is_a? Proxy
|
||||
namespace_obj = PuppetNamespaceObject.new(:root, 'Puppet3xFunctions')
|
||||
namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
|
||||
register namespace_obj
|
||||
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.
|
||||
obj
|
||||
end
|
||||
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
name = process_element(name)
|
||||
# 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
|
||||
|
||||
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
|
||||
name = process_element(name)
|
||||
|
||||
[name, Hash[opts]]
|
||||
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
|
||||
|
||||
# Sometimes the YARD parser returns Heredoc strings that start with `<-`
|
||||
# instead of `<<-`.
|
||||
HEREDOC_START = /^<?<-/
|
||||
[name, Hash[opts]]
|
||||
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.
|
||||
#
|
||||
|
@ -105,20 +99,19 @@ module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
|||
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
|
||||
# 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
|
||||
# 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
|
||||
# This utility method normalizes indentation and trims whitespace.
|
||||
Puppet::Util::Docs.scrub(source.join)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,98 +1,95 @@
|
|||
require_relative '../code_objects'
|
||||
# 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::Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
# 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 Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
handles method_call(:dispatch)
|
||||
|
||||
handles method_call(:dispatch)
|
||||
process do
|
||||
return unless owner.is_a?(MethodObject) && owner['puppet_4x_function']
|
||||
return unless statement.docstring
|
||||
|
||||
process do
|
||||
return unless owner.is_a?(MethodObject) && owner['puppet_4x_function']
|
||||
return unless statement.docstring
|
||||
docstring = ::YARD::Docstring.new(statement.docstring, nil)
|
||||
|
||||
docstring = ::YARD::Docstring.new(statement.docstring, nil)
|
||||
# FIXME: This does a wholesale copy of all possible tags. But, we're only
|
||||
# interested in the @overload tag.
|
||||
owner.add_tag *docstring.tags
|
||||
end
|
||||
end
|
||||
|
||||
# FIXME: This does a wholesale copy of all possible tags. But, we're only
|
||||
# interested in the @overload tag.
|
||||
owner.add_tag *docstring.tags
|
||||
end
|
||||
class Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
handles method_call(:create_function)
|
||||
|
||||
process do
|
||||
name = process_parameters
|
||||
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
obj['puppet_4x_function'] = true
|
||||
|
||||
register obj
|
||||
|
||||
obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
|
||||
blk = statement.block.children.first
|
||||
parse_block(blk, :owner => obj)
|
||||
end
|
||||
|
||||
class Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
private
|
||||
|
||||
handles method_call(:create_function)
|
||||
# Returns a {PuppetNamespaceObject} for holding functions. Creates this
|
||||
# object if necessary.
|
||||
#
|
||||
# @return [PuppetNamespaceObject]
|
||||
def function_namespace
|
||||
# NOTE: This tricky. If there is ever a Ruby class or module with the
|
||||
# name ::Puppet4xFunctions, then there will be a clash. Hopefully the name
|
||||
# is sufficiently uncommon.
|
||||
obj = P(:root, 'Puppet4xFunctions')
|
||||
if obj.is_a? Proxy
|
||||
namespace_obj = PuppetNamespaceObject.new(:root, 'Puppet4xFunctions')
|
||||
|
||||
process do
|
||||
name = process_parameters
|
||||
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
obj['puppet_4x_function'] = true
|
||||
|
||||
register obj
|
||||
|
||||
obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
|
||||
blk = statement.block.children.first
|
||||
parse_block(blk, :owner => obj)
|
||||
register namespace_obj
|
||||
# FIXME: The docstring has to be cleared. Otherwise, the namespace
|
||||
# object will be registered using the docstring of the
|
||||
# `create_function` call that is currently being processed.
|
||||
#
|
||||
# Figure out how to properly register the namespace without using the
|
||||
# function handler object.
|
||||
register_docstring(namespace_obj, '', nil)
|
||||
namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
end
|
||||
|
||||
private
|
||||
obj
|
||||
end
|
||||
|
||||
# Returns a {PuppetNamespaceObject} for holding functions. Creates this
|
||||
# object if necessary.
|
||||
#
|
||||
# @return [PuppetNamespaceObject]
|
||||
def function_namespace
|
||||
# NOTE: This tricky. If there is ever a Ruby class or module with the
|
||||
# name ::Puppet4xFunctions, then there will be a clash. Hopefully the name
|
||||
# is sufficiently uncommon.
|
||||
obj = P(:root, 'Puppet4xFunctions')
|
||||
if obj.is_a? Proxy
|
||||
namespace_obj = PuppetNamespaceObject.new(:root, 'Puppet4xFunctions')
|
||||
# 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.
|
||||
|
||||
register namespace_obj
|
||||
# FIXME: The docstring has to be cleared. Otherwise, the namespace
|
||||
# object will be registered using the docstring of the
|
||||
# `create_function` call that is currently being processed.
|
||||
#
|
||||
# Figure out how to properly register the namespace without using the
|
||||
# function handler object.
|
||||
register_docstring(namespace_obj, '', nil)
|
||||
namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
end
|
||||
# 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, _ = statement.parameters(false).compact
|
||||
|
||||
obj
|
||||
end
|
||||
name = process_element(name)
|
||||
|
||||
# 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.
|
||||
name
|
||||
end
|
||||
|
||||
# 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, _ = statement.parameters(false).compact
|
||||
|
||||
name = process_element(name)
|
||||
|
||||
name
|
||||
end
|
||||
|
||||
# Sometimes the YARD parser returns Heredoc strings that start with `<-`
|
||||
# instead of `<<-`.
|
||||
HEREDOC_START = /^<?<-/
|
||||
# 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.
|
||||
#
|
||||
|
@ -114,20 +111,19 @@ module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
|||
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
|
||||
# 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
|
||||
# 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
|
||||
# This utility method normalizes indentation and trims whitespace.
|
||||
Puppet::Util::Docs.scrub(source.join)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,32 +1,30 @@
|
|||
require 'yard'
|
||||
require 'puppet/pops'
|
||||
|
||||
require_relative '../../strings'
|
||||
require_relative '../pops/yard_transformer'
|
||||
require 'puppetx/puppetlabs/strings'
|
||||
require 'puppetx/puppetlabs/strings//pops/yard_transformer'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD
|
||||
class PuppetParser < YARD::Parser::Base
|
||||
attr_reader :file, :source
|
||||
class Puppetx::PuppetLabs::Strings::YARD::PuppetParser < YARD::Parser::Base
|
||||
attr_reader :file, :source
|
||||
|
||||
def initialize(source, filename)
|
||||
@source = source
|
||||
@file = filename
|
||||
|
||||
@parser = Puppet::Pops::Parser::Parser.new()
|
||||
@transformer = Puppetx::PuppetLabs::Strings::Pops::YARDTransformer.new()
|
||||
end
|
||||
|
||||
def parse
|
||||
@parse_result ||= @parser.parse_string(source)
|
||||
self
|
||||
end
|
||||
|
||||
def enumerator
|
||||
statements = @transformer.transform(@parse_result)
|
||||
|
||||
# Ensure an array is returned and prune any nil values.
|
||||
Array(statements).compact
|
||||
end
|
||||
def initialize(source, filename)
|
||||
@source = source
|
||||
@file = filename
|
||||
|
||||
@parser = Puppet::Pops::Parser::Parser.new()
|
||||
@transformer = Puppetx::PuppetLabs::Strings::Pops::YARDTransformer.new()
|
||||
end
|
||||
|
||||
def parse
|
||||
@parse_result ||= @parser.parse_string(source)
|
||||
self
|
||||
end
|
||||
|
||||
def enumerator
|
||||
statements = @transformer.transform(@parse_result)
|
||||
|
||||
# Ensure an array is returned and prune any nil values.
|
||||
Array(statements).compact
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
# TODO: Decide if supporting 1.8.7 is really worth it.
|
||||
if RUBY_VERSION < '1.9'
|
||||
require 'backports/1.9.1/kernel/require_relative'
|
||||
end
|
||||
|
||||
require 'puppet'
|
||||
|
||||
require_relative 'monkey_patches'
|
||||
require_relative 'parser'
|
||||
require_relative 'handlers'
|
||||
|
||||
YARD::Parser::SourceParser.register_parser_type(:puppet,
|
||||
Puppetx::PuppetLabs::Strings::YARD::PuppetParser,
|
||||
['pp'])
|
||||
YARD::Handlers::Processor.register_handler_namespace(:puppet,
|
||||
Puppetx::PuppetLabs::Strings::YARD::Handlers)
|
||||
|
||||
# FIXME: Might not be the best idea to have the template code on the Ruby
|
||||
# LOAD_PATH as the contents of this directory really aren't library code.
|
||||
YARD::Templates::Engine.register_template_path(File.join(
|
||||
File.dirname(__FILE__),
|
||||
'templates'))
|
|
@ -3,11 +3,17 @@ require 'spec_helper'
|
|||
module StringsSpec
|
||||
module Parsing
|
||||
|
||||
# Cleans up the Registry and gives YARD some source code
|
||||
# to generate documentation for
|
||||
def parse(string, parser = :ruby)
|
||||
Registry.clear
|
||||
YARD::Registry.clear
|
||||
YARD::Parser::SourceParser.parse_string(string, parser)
|
||||
end
|
||||
|
||||
# A custom matcher that allows us to compare aspects of a
|
||||
# Code Objects to the specified values. This gives us a
|
||||
# simplified way to ensure that the Code Object added to the
|
||||
# Registry is what we expect when testing handlers
|
||||
RSpec::Matchers.define :document_a do |arguments|
|
||||
match do |actual|
|
||||
compare_values(actual).empty?
|
||||
|
|
|
@ -5,9 +5,7 @@ require 'mocha'
|
|||
require 'puppet'
|
||||
require 'rspec'
|
||||
|
||||
# This is neeeded so we can access a Registry if YARD creates one
|
||||
require 'puppetx/puppetlabs/strings/yard/plugin'
|
||||
include YARD
|
||||
require 'puppetx/puppetlabs/strings'
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.mock_with :mocha
|
||||
|
|
|
@ -67,22 +67,6 @@ describe Puppet::Face do
|
|||
end
|
||||
end
|
||||
|
||||
describe "modules action" do
|
||||
it "should raise an error if yard is absent" do
|
||||
Puppet.features.stubs(:yard?).returns(false)
|
||||
expect{Puppet::Face[:strings, :current].modules}.to raise_error(RuntimeError, "The 'yard' gem must be installed in order to use this face.")
|
||||
end
|
||||
|
||||
it "should raise an error if rgen is absent" do
|
||||
Puppet.features.stubs(:rgen?).returns(false)
|
||||
expect{Puppet::Face[:strings, :current].modules}.to raise_error(RuntimeError, "The 'rgen' gem must be installed in order to use this face.")
|
||||
end
|
||||
|
||||
it "should raise an error if the Ruby version is less than 1.9", :if => RUBY_VERSION.match(/^1\.8/) do
|
||||
expect{Puppet::Face[:strings, :current].modules}.to raise_error(RuntimeError, "This face requires Ruby 1.9 or greater.")
|
||||
end
|
||||
end
|
||||
|
||||
describe "server action" do
|
||||
it "should raise an error if yard is absent" do
|
||||
Puppet.features.stubs(:yard?).returns(false)
|
||||
|
@ -118,3 +102,4 @@ describe Puppet::Face do
|
|||
File.read(File.join(dir, modulename, 'doc', file))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@ require 'puppetx/puppetlabs/strings/yard/handlers/defined_type_handler'
|
|||
require 'strings_spec/parsing'
|
||||
|
||||
|
||||
describe "DefinedTypeHanlder" do
|
||||
describe Puppetx::PuppetLabs::Strings::YARD::Handlers::DefinedTypeHandler do
|
||||
include StringsSpec::Parsing
|
||||
|
||||
def the_definedtype()
|
||||
Registry.at("foo::bar")
|
||||
YARD::Registry.at("foo::bar")
|
||||
end
|
||||
|
||||
it "should parse single-line documentation strings before a given defined type" do
|
||||
|
@ -56,6 +56,6 @@ describe "DefinedTypeHanlder" do
|
|||
|
||||
parse(puppet_code, :puppet)
|
||||
|
||||
expect(Registry.all).to be_empty
|
||||
expect(YARD::Registry.all).to be_empty
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,11 +2,11 @@ require 'spec_helper'
|
|||
require 'puppetx/puppetlabs/strings/yard/handlers/host_class_handler'
|
||||
require 'strings_spec/parsing'
|
||||
|
||||
describe "HostClassDefintion" do
|
||||
describe Puppetx::PuppetLabs::Strings::YARD::Handlers::HostClassHandler do
|
||||
include StringsSpec::Parsing
|
||||
|
||||
def the_hostclass()
|
||||
Registry.at("foo::bar")
|
||||
YARD::Registry.at("foo::bar")
|
||||
end
|
||||
|
||||
it "should parse single-line documentation strings before a given class" do
|
||||
|
|
|
@ -2,15 +2,15 @@ require 'spec_helper'
|
|||
require 'puppetx/puppetlabs/strings/yard/handlers/puppet_3x_function_handler'
|
||||
require 'strings_spec/parsing'
|
||||
|
||||
describe "Puppet3xFunctionHanlder" do
|
||||
describe Puppetx::PuppetLabs::Strings::YARD::Handlers::Puppet3xFunctionHandler do
|
||||
include StringsSpec::Parsing
|
||||
|
||||
def the_method()
|
||||
Registry.at("Puppet3xFunctions#the_function")
|
||||
YARD::Registry.at("Puppet3xFunctions#the_function")
|
||||
end
|
||||
|
||||
def the_namespace()
|
||||
Registry.at("Puppet3xFunctions")
|
||||
YARD::Registry.at("Puppet3xFunctions")
|
||||
end
|
||||
|
||||
it "should parse single-line documentation strings before a given function" do
|
|
@ -2,15 +2,15 @@ require 'spec_helper'
|
|||
require 'puppetx/puppetlabs/strings/yard/handlers/puppet_4x_function_handler'
|
||||
require 'strings_spec/parsing'
|
||||
|
||||
describe "Pupet4xFunctionHandler" do
|
||||
describe Puppetx::PuppetLabs::Strings::YARD::Handlers::Puppet4xFunctionHandler do
|
||||
include StringsSpec::Parsing
|
||||
|
||||
def the_method()
|
||||
Registry.at("Puppet4xFunctions#the_function")
|
||||
YARD::Registry.at("Puppet4xFunctions#the_function")
|
||||
end
|
||||
|
||||
def the_namespace()
|
||||
Registry.at("Puppet4xFunctions")
|
||||
YARD::Registry.at("Puppet4xFunctions")
|
||||
end
|
||||
|
||||
it "should parse single-line documentation strings before a given function" do
|
||||
|
@ -60,6 +60,6 @@ describe "Pupet4xFunctionHandler" do
|
|||
This is not ruby code
|
||||
RUBY
|
||||
|
||||
expect(Registry.all).to be_empty
|
||||
expect(YARD::Registry.all).to be_empty
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue