Class: Puppet::Plugins::SyntaxCheckers::SyntaxChecker Abstract Private

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/plugins/syntax_checkers.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

This class is abstract.

SyntaxChecker is a Puppet Extension Point for the purpose of extending Puppet with syntax checkers. The intended use is to create a class derived from this class and then register it with the Puppet context

Creating the Extension Class


As an example, a class for checking custom xml (aware of some custom schemes) may be authored in say a puppet module called 'exampleorg/xmldata'. The name of the class should start with `Puppetx::<user>::<module>`, e.g. 'Puppetx::Exampleorg::XmlData::XmlChecker“ and be located in `lib/puppetx/exampleorg/xml_data/xml_checker.rb`. The Puppet Binder will auto-load this file when it has a binding to the class `Puppetx::Exampleorg::XmlData::XmlChecker' The Ruby Module `Puppetx` is created by Puppet, the remaining modules should be created by the loaded logic - e.g.:

Implementing the check method


The implementation of the #check method should naturally perform syntax checking of the given text/string and produce found issues on the given `acceptor`. These can be warnings or errors. The method should return `false` if any warnings or errors were produced (it is up to the caller to check for error/warning conditions and report them to the user).

Issues are reported by calling the given `acceptor`, which takes a severity (e.g. `:error`, or `:warning), an Puppet::Pops::Issues::Issue instance, and a Puppet::Pops::Adapters::SourcePosAdapter (which describes details about linenumber, position, and length of the problem area). Note that the `location_info` given to the check method holds information about the location of the string in its container (e.g. the source position of a Heredoc); this information can be used if more detailed information is not available, or combined if there are more details (relative to the start of the checked string).

There is usually a cap on the number of errors/warnings that are presented to the user, this is handled by the reporting logic, but care should be taken to not generate too many as the issues are kept in memory until the checker returns. The acceptor may set a limit and simply ignore issues past a certain (high) number of reported issues (this number is typically higher than the cap on issues reported to the user).

The `syntax_identifier`


The extension makes use of a syntax identifier written in mime-style. This identifier can be something simple as 'xml', or 'json', but can also consist of several segments joined with '+' where the most specific syntax variant is placed first. When searching for a syntax checker; say for JSON having some special traits, say 'userdata', the author of the text may indicate this as the text having the syntax “userdata+json” - when a checker is looked up it is first checked if there is a checker for “userdata+json”, if none is found, a lookup is made for “json” (since the text must at least be valid json). The given identifier is passed to the checker (to allow the same checker to check for several dialects/specializations).

Use in Puppet DSL


The Puppet DSL Heredoc support makes use of the syntax checker extension. A user of a heredoc can specify the syntax in the heredoc tag, e.g.`@(END:userdata+json)`.

Examples:

Defining an XmlChecker

module Puppetx::Exampleorg
  module XmlData
    class XmlChecker < Puppetx::Puppetlabs::SyntaxCheckers::SyntaxChecker
      def check(text, syntax_identifier, acceptor, location_hash)
         # do the checking
      end
    end
  end
end

Reporting an issue

# create an issue with a symbolic name (that can serve as a reference to more details about the problem),
# make the name unique
issue = Puppet::Pops::Issues::issue(:EXAMPLEORG_XMLDATA_ILLEGAL_XML) { "syntax error found in xml text" }
source_pos = Puppet::Pops::Adapters::SourcePosAdapter.new()
source_pos.line = info[:line] # use this if there is no detail from the used parser
source_pos.pos = info[:pos]   # use this pos if there is no detail from used parser

# report it
acceptor.accept(Puppet::Pops::Validation::Diagnostic.new(:error, issue, info[:file], source_pos, {}))

Instance Method Summary collapse

Instance Method Details

#check(text, syntax_identifier, acceptor, location_info) ⇒ Boolean

Checks the text for syntax issues and reports them to the given acceptor. This implementation is abstract, it raises NotImplementedError since a subclass should have implemented the method.

Options Hash (location_info):

  • :file (String)

    The filename where the string originates

  • :line (Integer)

    The line number identifying the location where the string is being used/checked

  • :position (Integer)

    The position on the line identifying the location where the string is being used/checked

Raises:

  • (NotImplementedError)

93
94
95
# File 'lib/puppet/plugins/syntax_checkers.rb', line 93

def check(text, syntax_identifier, acceptor, location_info)
  raise NotImplementedError, "The class #{self.class.name} should have implemented the method check()"
end