File: templates.rb

package info (click to toggle)
ruby-puppet-syntax 4.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 312 kB
  • sloc: ruby: 672; makefile: 6
file content (92 lines) | stat: -rw-r--r-- 2,901 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
require 'erb'
require 'stringio'

module PuppetSyntax
  class Templates
    def check(filelist)
      raise 'Expected an array of files' unless filelist.is_a?(Array)

      # We now have to redirect STDERR in order to capture warnings.
      $stderr = warnings = StringIO.new
      result = { warnings: [], errors: [] }

      filelist.each do |file|
        if File.extname(file) == '.epp' or PuppetSyntax.epp_only
          tmp = validate_epp(file)
        elsif File.extname(file) == '.erb'
          tmp = validate_erb(file)
        end
        result.merge!(tmp) { |_k, a, b| a.concat(b) } unless tmp.nil?
      end

      $stderr = STDERR
      result[:warnings] << warnings.string unless warnings.string.empty?

      result[:errors].map! { |e| e.to_s }
      result[:warnings].map! { |w| w.to_s }

      result
    end

    def validate_epp(filename)
      require 'puppet'
      result = { warnings: [], errors: [] }
      formatter = Puppet::Pops::Validation::DiagnosticFormatterPuppetStyle.new
      evaluating_parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new
      parser = evaluating_parser.parser
      begin
        parse_result = parser.parse_file(filename)
        validation_result = evaluating_parser.validate(parse_result.model)

        # print out any warnings
        validation_result.warnings.each do |warn|
          message = formatter.format_message(warn)
          file = warn.file
          line = warn.source_pos.line
          column = warn.source_pos.pos
          result[:warnings] << "#{file}:#{line}:#{column}: #{message}"
        end

        # collect errors and return them in order to indicate validation failure
        validation_result.errors.each do |err|
          message = formatter.format_message(err)
          file = err.file
          line = err.source_pos.line
          column = err.source_pos.pos
          result[:errors] << "#{file}:#{line}:#{column}: #{message}"
        end
      rescue Puppet::ParseError, SyntaxError => e
        result[:errors] << e
      rescue StandardError => e
        result[:errors] << e
      end

      result
    end

    def validate_erb(filename)
      result = { warnings: [], errors: [] }

      begin
        template = File.read(filename)
        erb = if RUBY_VERSION >= '2.6'
                ERB.new(template, trim_mode: '-')
              else
                ERB.new(template, trim_mode: '-')
              end
        erb.filename = filename
        erb.result
      rescue NameError => e
        # This is normal because we don't have the variables that would
        # ordinarily be bound by the parent Puppet manifest.
      rescue TypeError
        # This is normal because we don't have the variables that would
        # ordinarily be bound by the parent Puppet manifest.
      rescue SyntaxError => e
        result[:errors] << e
      end

      result
    end
  end
end