Module: PuppetfileResolver::Puppetfile::Parser::R10KEval

Defined in:
lib/puppetfile-resolver/puppetfile/parser/r10k_eval.rb,
lib/puppetfile-resolver/puppetfile/parser/r10k_eval/dsl.rb,
lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/git.rb,
lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/svn.rb,
lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/forge.rb,
lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/local.rb,
lib/puppetfile-resolver/puppetfile/parser/r10k_eval/puppet_module.rb,
lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/invalid.rb

Overview

Parses a Puppetfile using the instance_eval method from R10K

Defined Under Namespace

Modules: Module, PuppetModule Classes: DSL

Class Method Summary collapse

Class Method Details

.parse(puppetfile_contents) ⇒ Object



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
# File 'lib/puppetfile-resolver/puppetfile/parser/r10k_eval.rb', line 15

def self.parse(puppetfile_contents)
  document = ::PuppetfileResolver::Puppetfile::Document.new(puppetfile_contents)

  puppetfile_dsl = DSL.new(document)
  begin
    puppetfile_dsl.instance_eval(puppetfile_contents, PUPPETFILE_MONIKER)
  rescue StandardError, LoadError => e
    # Find the originating error from within the puppetfile
    loc = e.backtrace_locations
           .select { |item| item.absolute_path == PUPPETFILE_MONIKER }
           .first
    start_line_number = loc.nil? ? 0 : loc.lineno - 1 # Line numbers from ruby are base 1
    end_line_number = loc.nil? ? puppetfile_contents.lines.count - 1 : loc.lineno - 1 # Line numbers from ruby are base 1
    # Note - Ruby doesn't give a character position so just highlight the entire line

    err = PuppetfileResolver::Puppetfile::Parser::ParserError.new(e.to_s)
    err.location = PuppetfileResolver::Puppetfile::DocumentLocation.new.tap do |doc_loc|
      doc_loc.start_line = start_line_number
      doc_loc.end_line = end_line_number
    end
    raise err, e.backtrace
  rescue SyntaxError => e
    # Syntax Errrors are special as they don't appear in the backtrace :-(
    # Sytnax Errors are _really_ horrible as they don't give you the line or character position
    # as methods on the error. Instead we have to use janky regexes to get the information
    matches = /^#{PUPPETFILE_MONIKER}:(\d+):/.match(e.message)
    line_num = matches.nil? ? 0 : matches[1].to_i - 1 # Line numbers from ruby are base 1
    # If we get a string that can't be cast to integer properly to_i returns 0, which we then take 1 from
    # which results in a negative number. As a simple precaution, anything that's negative, just assume line zero
    line_num = 0 if line_num < 0

    err = PuppetfileResolver::Puppetfile::Parser::ParserError.new(e.to_s)
    err.location = PuppetfileResolver::Puppetfile::DocumentLocation.new.tap do |doc_loc|
      doc_loc.start_line = line_num
      doc_loc.end_line = line_num
      # We can't get character position reliably
    end
    raise err, e.backtrace
  end

  # Post process magic comments
  post_process_flags!(document)

  # Freeze the flags so they can't be modified
  document.modules.each { |mod| mod.resolver_flags.freeze }

  document
end