Add rudimentary comment extractor

With this patch, the `yardoc` face will parse a manifest file and then extract
any comments associated with each node, class and type definition.
This commit is contained in:
Charlie Sharpsteen 2014-05-21 22:14:53 -07:00
parent 3ad750d103
commit f53cbed1bb
2 changed files with 68 additions and 3 deletions

View File

@ -1,11 +1,12 @@
require 'puppet/face' require 'puppet/face'
require 'puppetx/yardoc/util'
Puppet::Face.define(:yardoc, '0.0.1') do Puppet::Face.define(:yardoc, '0.0.1') do
action(:yardoc) do action(:yardoc) do
default default
when_invoked do |*args| when_invoked do |manifest, options|
unless Puppet.features.yard? unless Puppet.features.yard?
raise RuntimeError, "The 'yard' gem must be installed in order to use this face." raise RuntimeError, "The 'yard' gem must be installed in order to use this face."
@ -18,9 +19,11 @@ Puppet::Face.define(:yardoc, '0.0.1') do
end end
parser = Puppet::Pops::Parser::Parser.new() parser = Puppet::Pops::Parser::Parser.new()
parse_result = parser.parse_file(args[0]) parse_result = parser.parse_file(manifest)
return 0 commentor = Puppetx::Yardoc::Commentor.new()
return commentor.get_comments(parse_result)
end end
end end
end end

View File

@ -0,0 +1,62 @@
require 'puppetx'
require 'puppet/pops'
# TODO: A catch-all module for now. Everything in here should eventually move
# to a designated home.
module Puppetx::Yardoc
# Loosly based on the TreeDumper classes in Pops::Model.
class Puppetx::Yardoc::Commentor
def initialize
@docstring_visitor = Puppet::Pops::Visitor.new(self,'docstring')
end
def get_comments(parse_result)
@docstring_visitor.visit(parse_result)
end
private
COMMENT_PATTERN = /^\s*#.*\n/
def comments(o)
@docstring_visitor.visit(o)
end
def docstring_Factory(o)
comments(o.current)
end
def docstring_Program(o)
@source_text = o.source_text.lines.to_a
@locator = o.locator
o.definitions.map{|d| comments(d)}
end
# Extract comments from "Definition" objects. That is: nodes definitions,
# type definitions and class definitions.
def docstring_Definition(o)
line = @locator.line_for_offset(o.offset)
comments_before(line)
end
def comments_before(line)
comments = []
# FIXME: Horribly inefficient. Multiple copies. Generator pattern would
# be much better.
@source_text.slice(0, line-1).reverse.each do |line|
if COMMENT_PATTERN.match(line)
comments.unshift line
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
end
end