File: //usr/lib/ruby/site_ruby/1.8/puppet/face/parser.rb
require 'puppet/face'
require 'puppet/parser'
Puppet::Face.define(:parser, '0.0.1') do
copyright "Puppet Labs", 2011
license "Apache 2 license; see COPYING"
summary "Interact directly with the parser."
action :validate do
summary "Validate the syntax of one or more Puppet manifests."
arguments "[<manifest>] [<manifest> ...]"
returns "Nothing, or the first syntax error encountered."
description <<-'EOT'
This action validates Puppet DSL syntax without compiling a catalog or
syncing any resources. If no manifest files are provided, it will
validate the default site manifest.
When validating with --parser current, the validation stops after the first
encountered issue.
When validating with --parser future, multiple issues per file are reported up
to the settings of max_error, and max_warnings. The processing stops
after having reported issues for the first encountered file with errors.
EOT
examples <<-'EOT'
Validate the default site manifest at /etc/puppet/manifests/site.pp:
$ puppet parser validate
Validate two arbitrary manifest files:
$ puppet parser validate init.pp vhost.pp
Validate from STDIN:
$ cat init.pp | puppet parser validate
EOT
when_invoked do |*args|
args.pop
files = args
if files.empty?
if not STDIN.tty?
Puppet[:code] = STDIN.read
validate_manifest
else
manifest = Puppet.lookup(:current_environment).manifest
files << manifest
Puppet.notice "No manifest specified. Validating the default manifest #{manifest}"
end
end
missing_files = []
files.each do |file|
if Puppet::FileSystem.exist?(file)
validate_manifest(file)
else
missing_files << file
end
end
unless missing_files.empty?
raise Puppet::Error, "One or more file(s) specified did not exist:\n#{missing_files.collect {|f| " " * 3 + f + "\n"}}"
end
nil
end
end
action (:dump) do
summary "Outputs a dump of the internal parse tree for debugging"
arguments "-e <source>| [<manifest> ...] "
returns "A dump of the resulting AST model unless there are syntax or validation errors."
description <<-'EOT'
This action parses and validates the Puppet DSL syntax without compiling a catalog
or syncing any resources. It automatically turns on the future parser for the parsing.
The command accepts one or more manifests (.pp) files, or an -e followed by the puppet
source text.
If no arguments are given, the stdin is read (unless it is attached to a terminal)
The output format of the dumped tree is not API, it may change from time to time.
EOT
option "--e <source>" do
default_to { nil }
summary "dump one source expression given on the command line."
end
option("--[no-]validate") do
summary "Whether or not to validate the parsed result, if no-validate only syntax errors are reported"
end
when_invoked do |*args|
require 'puppet/pops'
options = args.pop
if options[:e]
dump_parse(options[:e], 'command-line-string', options, false)
elsif args.empty?
if ! STDIN.tty?
dump_parse(STDIN.read, 'stdin', options, false)
else
raise Puppet::Error, "No input to parse given on command line or stdin"
end
else
missing_files = []
files = args
available_files = files.select do |file|
Puppet::FileSystem.exist?(file)
end
missing_files = files - available_files
dumps = available_files.collect do |file|
dump_parse(File.read(file), file, options)
end.join("")
if missing_files.empty?
dumps
else
dumps + "One or more file(s) specified did not exist:\n" + missing_files.collect { |f| " #{f}" }.join("\n")
end
end
end
end
def dump_parse(source, filename, options, show_filename = true)
output = ""
dumper = Puppet::Pops::Model::ModelTreeDumper.new
evaluating_parser = Puppet::Pops::Parser::EvaluatingParser.new
begin
if options[:validate]
parse_result = evaluating_parser.parse_string(source, filename)
else
# side step the assert_and_report step
parse_result = evaluating_parser.parser.parse_string(source)
end
if show_filename
output << "--- #{filename}"
end
output << dumper.dump(parse_result) << "\n"
rescue Puppet::ParseError => detail
if show_filename
Puppet.err("--- #{filename}")
end
Puppet.err(detail.message)
""
end
end
# @api private
def validate_manifest(manifest = nil)
env = Puppet.lookup(:current_environment)
validation_environment = manifest ? env.override_with(:manifest => manifest) : env
validation_environment.check_for_reparse
validation_environment.known_resource_types.clear
rescue => detail
Puppet.log_exception(detail)
exit(1)
end
end