File: pcore.rb

package info (click to toggle)
puppet-agent 7.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,092 kB
  • sloc: ruby: 245,074; sh: 456; makefile: 38; xml: 33
file content (135 lines) | stat: -rw-r--r-- 5,769 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
require 'uri'

module Puppet::Pops
module Pcore
  include Types::PuppetObject

  TYPE_URI_RX = Types::TypeFactory.regexp(URI.regexp)
  TYPE_URI = Types::TypeFactory.pattern(TYPE_URI_RX)
  TYPE_URI_ALIAS = Types::PTypeAliasType.new('Pcore::URI', nil, TYPE_URI)
  TYPE_SIMPLE_TYPE_NAME = Types::TypeFactory.pattern(/\A[A-Z]\w*\z/)
  TYPE_QUALIFIED_REFERENCE = Types::TypeFactory.pattern(/\A[A-Z][\w]*(?:::[A-Z][\w]*)*\z/)
  TYPE_MEMBER_NAME = Types::PPatternType.new([Types::PRegexpType.new(Patterns::PARAM_NAME)])

  KEY_PCORE_URI = 'pcore_uri'.freeze
  KEY_PCORE_VERSION = 'pcore_version'.freeze

  PCORE_URI = 'http://puppet.com/2016.1/pcore'
  PCORE_VERSION = SemanticPuppet::Version.new(1,0,0)
  PARSABLE_PCORE_VERSIONS = SemanticPuppet::VersionRange.parse('1.x')

  RUNTIME_NAME_AUTHORITY = 'http://puppet.com/2016.1/runtime'

  def self._pcore_type
    @type
  end

  def self.annotate(instance, annotations_hash)
    annotations_hash.each_pair do |type, init_hash|
      type.implementation_class.annotate(instance) { init_hash }
    end
    instance
  end

  def self.init_env(loader)
    if Puppet[:tasks]
      add_object_type('Task', <<-PUPPET, loader)
        {
          attributes => {
            # Fully qualified name of the task
            name => { type => Pattern[/\\A[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)*\\z/] },

            # List of file references referenced by metadata and their paths on disk.
            # If there are no implementations listed in metadata, the first file is always
            # the task executable.
            files => { type => Array[Struct[name => String, path => String]] },

            # Task metadata
            metadata => { type => Hash[String, Any] },

            # Map parameter names to their parsed data type
            parameters => { type => Optional[Hash[Pattern[/\\A[a-z][a-z0-9_]*\\z/], Type]], value => undef },
          }
        }
      PUPPET
    end
  end

  def self.init(loader, ir)
    add_alias('Pcore::URI_RX', TYPE_URI_RX, loader)
    add_type(TYPE_URI_ALIAS, loader)
    add_alias('Pcore::SimpleTypeName', TYPE_SIMPLE_TYPE_NAME, loader)
    add_alias('Pcore::MemberName', TYPE_MEMBER_NAME, loader)
    add_alias('Pcore::TypeName', TYPE_QUALIFIED_REFERENCE, loader)
    add_alias('Pcore::QRef', TYPE_QUALIFIED_REFERENCE, loader)
    Types::TypedModelObject.register_ptypes(loader, ir)

    @type = create_object_type(loader, ir, Pcore, 'Pcore', nil)

    ir.register_implementation_namespace('Pcore', 'Puppet::Pops::Pcore')
    ir.register_implementation_namespace('Puppet::AST', 'Puppet::Pops::Model')
    ir.register_implementation('Puppet::AST::Locator', 'Puppet::Pops::Parser::Locator::Locator19')
    Resource.register_ptypes(loader, ir)
    Lookup::Context.register_ptype(loader, ir);
    Lookup::DataProvider.register_types(loader)

    add_object_type('Deferred', <<-PUPPET, loader)
      {
        attributes => {
          # Fully qualified name of the function
          name  => { type => Pattern[/\\A[$]?[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)*\\z/] },
          arguments => { type => Optional[Array[Any]], value => undef},
        }
      }
    PUPPET

  end

  # Create and register a new `Object` type in the Puppet Type System and map it to an implementation class
  #
  # @param loader [Loader::Loader] The loader where the new type will be registered
  # @param ir [ImplementationRegistry] The implementation registry that maps this class to the new type
  # @param impl_class [Class] The class that is the implementation of the type
  # @param type_name [String] The fully qualified name of the new type
  # @param parent_name [String,nil] The fully qualified name of the parent type
  # @param attributes_hash [Hash{String => Object}] A hash of attribute definitions for the new type
  # @param functions_hash [Hash{String => Object}] A hash of function definitions for the new type
  # @param equality [Array<String>] An array with names of attributes that participate in equality comparison
  # @return [PObjectType] the created type. Not yet resolved
  #
  # @api private
  def self.create_object_type(loader, ir, impl_class, type_name, parent_name, attributes_hash = EMPTY_HASH, functions_hash = EMPTY_HASH, equality = nil)
    init_hash = {}
    init_hash[Types::KEY_PARENT] = Types::PTypeReferenceType.new(parent_name) unless parent_name.nil?
    init_hash[Types::KEY_ATTRIBUTES] = attributes_hash unless attributes_hash.empty?
    init_hash[Types::KEY_FUNCTIONS] = functions_hash unless functions_hash.empty?
    init_hash[Types::KEY_EQUALITY] = equality unless equality.nil?
    ir.register_implementation(type_name, impl_class)
    add_type(Types::PObjectType.new(type_name, init_hash), loader)
  end

  def self.add_object_type(name, body, loader)
    add_type(Types::PObjectType.new(name, Parser::EvaluatingParser.new.parse_string(body).body), loader)
  end

  def self.add_alias(name, type, loader, name_authority = RUNTIME_NAME_AUTHORITY)
    add_type(Types::PTypeAliasType.new(name, nil, type), loader, name_authority)
  end

  def self.add_type(type, loader, name_authority = RUNTIME_NAME_AUTHORITY)
    loader.set_entry(Loader::TypedName.new(:type, type.name, name_authority), type)
    type
  end

  def self.register_implementations(impls, name_authority = RUNTIME_NAME_AUTHORITY)
    Loaders.loaders.register_implementations(impls, name_authority)
  end

  def self.register_aliases(aliases, name_authority = RUNTIME_NAME_AUTHORITY, loader = Loaders.loaders.private_environment_loader)
    aliases.each do |name, type_string|
      add_type(Types::PTypeAliasType.new(name, Types::TypeFactory.type_reference(type_string), nil), loader, name_authority)
    end
    aliases.each_key.map { |name| loader.load(:type, name).resolve(loader) }
  end
end
end