puppet 5.0.1-universal-darwin → 5.1.0-universal-darwin

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/lib/puppet/agent.rb +1 -0
  3. data/lib/puppet/defaults.rb +1 -1
  4. data/lib/puppet/functions.rb +6 -7
  5. data/lib/puppet/functions/all.rb +100 -0
  6. data/lib/puppet/functions/any.rb +105 -0
  7. data/lib/puppet/functions/defined.rb +3 -3
  8. data/lib/puppet/functions/new.rb +2 -1
  9. data/lib/puppet/functions/reduce.rb +31 -0
  10. data/lib/puppet/functions/tree_each.rb +200 -0
  11. data/lib/puppet/module.rb +30 -0
  12. data/lib/puppet/parser/functions/new.rb +67 -0
  13. data/lib/puppet/parser/functions/reduce.rb +31 -0
  14. data/lib/puppet/parser/relationship.rb +2 -2
  15. data/lib/puppet/parser/resource.rb +39 -10
  16. data/lib/puppet/parser/scope.rb +1 -1
  17. data/lib/puppet/pops/evaluator/access_operator.rb +11 -4
  18. data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -1
  19. data/lib/puppet/pops/evaluator/evaluator_impl.rb +4 -4
  20. data/lib/puppet/pops/evaluator/relationship_operator.rb +1 -1
  21. data/lib/puppet/pops/evaluator/runtime3_converter.rb +3 -3
  22. data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +1 -1
  23. data/lib/puppet/pops/loader/module_loaders.rb +1 -1
  24. data/lib/puppet/pops/loader/static_loader.rb +1 -2
  25. data/lib/puppet/pops/loaders.rb +1 -2
  26. data/lib/puppet/pops/lookup/context.rb +1 -1
  27. data/lib/puppet/pops/lookup/lookup_adapter.rb +2 -1
  28. data/lib/puppet/pops/model/ast.rb +440 -436
  29. data/lib/puppet/pops/model/factory.rb +140 -140
  30. data/lib/puppet/pops/pcore.rb +1 -2
  31. data/lib/puppet/pops/resource/param.rb +1 -1
  32. data/lib/puppet/pops/resource/resource_type_impl.rb +1 -1
  33. data/lib/puppet/pops/serialization/from_data_converter.rb +0 -12
  34. data/lib/puppet/pops/time/timestamp.rb +29 -17
  35. data/lib/puppet/pops/types/annotatable.rb +2 -2
  36. data/lib/puppet/pops/types/annotation.rb +8 -8
  37. data/lib/puppet/pops/types/class_loader.rb +3 -3
  38. data/lib/puppet/pops/types/implementation_registry.rb +1 -1
  39. data/lib/puppet/pops/types/iterable.rb +2 -2
  40. data/lib/puppet/pops/types/p_binary_type.rb +2 -2
  41. data/lib/puppet/pops/types/p_init_type.rb +238 -0
  42. data/lib/puppet/pops/types/p_meta_type.rb +14 -11
  43. data/lib/puppet/pops/types/p_object_type.rb +15 -15
  44. data/lib/puppet/pops/types/p_sem_ver_range_type.rb +2 -2
  45. data/lib/puppet/pops/types/p_sem_ver_type.rb +2 -2
  46. data/lib/puppet/pops/types/p_sensitive_type.rb +2 -2
  47. data/lib/puppet/pops/types/p_timespan_type.rb +6 -6
  48. data/lib/puppet/pops/types/p_timestamp_type.rb +6 -2
  49. data/lib/puppet/pops/types/p_type_set_type.rb +10 -9
  50. data/lib/puppet/pops/types/ruby_generator.rb +6 -5
  51. data/lib/puppet/pops/types/ruby_method.rb +2 -2
  52. data/lib/puppet/pops/types/string_converter.rb +1 -1
  53. data/lib/puppet/pops/types/tree_iterators.rb +250 -0
  54. data/lib/puppet/pops/types/type_calculator.rb +13 -13
  55. data/lib/puppet/pops/types/type_factory.rb +26 -7
  56. data/lib/puppet/pops/types/type_formatter.rb +9 -4
  57. data/lib/puppet/pops/types/type_parser.rb +8 -3
  58. data/lib/puppet/pops/types/type_set_reference.rb +2 -2
  59. data/lib/puppet/pops/types/types.rb +168 -109
  60. data/lib/puppet/provider/package/gem.rb +10 -9
  61. data/lib/puppet/provider/package/pip.rb +12 -3
  62. data/lib/puppet/provider/package/yum.rb +9 -1
  63. data/lib/puppet/resource/capability_finder.rb +30 -11
  64. data/lib/puppet/type/file.rb +21 -13
  65. data/lib/puppet/util/execution.rb +67 -14
  66. data/lib/puppet/util/suidmanager.rb +1 -0
  67. data/lib/puppet/version.rb +1 -1
  68. data/locales/puppet.pot +130 -66
  69. data/man/man5/puppet.conf.5 +1 -1
  70. data/spec/fixtures/unit/provider/package/yum/yum-check-update-simple.txt +1 -0
  71. data/spec/integration/parser/collection_spec.rb +40 -1
  72. data/spec/shared_contexts/types_setup.rb +41 -2
  73. data/spec/unit/agent_spec.rb +11 -0
  74. data/spec/unit/file_bucket/dipper_spec.rb +13 -4
  75. data/spec/unit/functions/all_spec.rb +97 -0
  76. data/spec/unit/functions/any_spec.rb +109 -0
  77. data/spec/unit/functions/hiera_spec.rb +5 -0
  78. data/spec/unit/functions/new_spec.rb +66 -0
  79. data/spec/unit/functions/tree_each_spec.rb +444 -0
  80. data/spec/unit/module_spec.rb +29 -0
  81. data/spec/unit/pops/serialization/serialization_spec.rb +2 -2
  82. data/spec/unit/pops/serialization/to_from_hr_spec.rb +2 -2
  83. data/spec/unit/pops/types/iterable_spec.rb +9 -9
  84. data/spec/unit/pops/types/p_init_type_spec.rb +285 -0
  85. data/spec/unit/pops/types/p_object_type_spec.rb +8 -8
  86. data/spec/unit/pops/types/p_sensitive_type_spec.rb +4 -0
  87. data/spec/unit/pops/types/p_timespan_type_spec.rb +14 -0
  88. data/spec/unit/pops/types/p_timestamp_type_spec.rb +19 -1
  89. data/spec/unit/pops/types/p_type_set_type_spec.rb +2 -2
  90. data/spec/unit/pops/types/ruby_generator_spec.rb +9 -22
  91. data/spec/unit/pops/types/string_converter_spec.rb +2 -2
  92. data/spec/unit/pops/types/type_acceptor_spec.rb +2 -2
  93. data/spec/unit/pops/types/type_calculator_spec.rb +43 -38
  94. data/spec/unit/pops/types/type_factory_spec.rb +6 -6
  95. data/spec/unit/pops/types/type_formatter_spec.rb +6 -6
  96. data/spec/unit/pops/types/types_spec.rb +16 -4
  97. data/spec/unit/provider/package/gem_spec.rb +6 -6
  98. data/spec/unit/provider/package/pip_spec.rb +44 -23
  99. data/spec/unit/provider/package/puppet_gem_spec.rb +1 -1
  100. data/spec/unit/provider/package/yum_spec.rb +8 -0
  101. data/spec/unit/resource/capability_finder_spec.rb +4 -5
  102. data/spec/unit/type/file_spec.rb +19 -14
  103. data/spec/unit/util/execution_spec.rb +216 -82
  104. data/tasks/generate_ast_model.rake +10 -2
  105. metadata +15 -2
@@ -10,6 +10,8 @@ KEY_VALUE = 'value'.freeze
10
10
  class PMetaType < PAnyType
11
11
  include Annotatable
12
12
 
13
+ attr_reader :loader
14
+
13
15
  def self.register_ptype(loader, ir)
14
16
  # Abstract type. It doesn't register anything
15
17
  end
@@ -31,16 +33,17 @@ class PMetaType < PAnyType
31
33
  # @param loader [Loader::Loader] loader to use when loading type aliases
32
34
  # @return [PTypeAliasType] the receiver of the call, i.e. `self`
33
35
  # @api private
34
- def resolve(type_parser, loader)
36
+ def resolve(loader)
35
37
  unless @init_hash_expression.nil?
38
+ @loader = loader
36
39
  @self_recursion = true # assumed while it being found out below
37
40
 
38
41
  init_hash_expression = @init_hash_expression
39
42
  @init_hash_expression = nil
40
43
  if init_hash_expression.is_a?(Model::LiteralHash)
41
- init_hash = resolve_literal_hash(type_parser, loader, init_hash_expression)
44
+ init_hash = resolve_literal_hash(loader, init_hash_expression)
42
45
  else
43
- init_hash = resolve_hash(type_parser, loader, init_hash_expression)
46
+ init_hash = resolve_hash(loader, init_hash_expression)
44
47
  end
45
48
  _pcore_init_from_hash(init_hash)
46
49
 
@@ -54,22 +57,22 @@ class PMetaType < PAnyType
54
57
  self
55
58
  end
56
59
 
57
- def resolve_literal_hash(type_parser, loader, init_hash_expression)
58
- type_parser.interpret_LiteralHash(init_hash_expression, loader)
60
+ def resolve_literal_hash(loader, init_hash_expression)
61
+ TypeParser.singleton.interpret_LiteralHash(init_hash_expression, loader)
59
62
  end
60
63
 
61
- def resolve_hash(type_parser, loader, init_hash)
62
- resolve_type_refs(type_parser, loader, init_hash)
64
+ def resolve_hash(loader, init_hash)
65
+ resolve_type_refs(loader, init_hash)
63
66
  end
64
67
 
65
- def resolve_type_refs(type_parser, loader, o)
68
+ def resolve_type_refs(loader, o)
66
69
  case o
67
70
  when Hash
68
- Hash[o.map { |k, v| [resolve_type_refs(type_parser, loader, k), resolve_type_refs(type_parser, loader, v)] }]
71
+ Hash[o.map { |k, v| [resolve_type_refs(loader, k), resolve_type_refs(loader, v)] }]
69
72
  when Array
70
- o.map { |e| resolve_type_refs(type_parser, loader, e) }
73
+ o.map { |e| resolve_type_refs(loader, e) }
71
74
  when PAnyType
72
- o.resolve(type_parser, loader)
75
+ o.resolve(loader)
73
76
  else
74
77
  o
75
78
  end
@@ -25,7 +25,7 @@ class PObjectType < PMetaType
25
25
  TYPE_OBJECT_NAME = Pcore::TYPE_QUALIFIED_REFERENCE
26
26
 
27
27
  TYPE_ATTRIBUTE = TypeFactory.struct({
28
- KEY_TYPE => PType::DEFAULT,
28
+ KEY_TYPE => PTypeType::DEFAULT,
29
29
  TypeFactory.optional(KEY_FINAL) => PBooleanType::DEFAULT,
30
30
  TypeFactory.optional(KEY_OVERRIDE) => PBooleanType::DEFAULT,
31
31
  TypeFactory.optional(KEY_KIND) => TYPE_ATTRIBUTE_KIND,
@@ -35,7 +35,7 @@ class PObjectType < PMetaType
35
35
  TYPE_ATTRIBUTES = TypeFactory.hash_kv(Pcore::TYPE_MEMBER_NAME, TypeFactory.not_undef)
36
36
  TYPE_ATTRIBUTE_CALLABLE = TypeFactory.callable(0,0)
37
37
 
38
- TYPE_FUNCTION_TYPE = PType.new(PCallableType::DEFAULT)
38
+ TYPE_FUNCTION_TYPE = PTypeType.new(PCallableType::DEFAULT)
39
39
 
40
40
  TYPE_FUNCTION = TypeFactory.struct({
41
41
  KEY_TYPE => TYPE_FUNCTION_TYPE,
@@ -51,7 +51,7 @@ class PObjectType < PMetaType
51
51
 
52
52
  TYPE_OBJECT_I12N = TypeFactory.struct({
53
53
  TypeFactory.optional(KEY_NAME) => TYPE_OBJECT_NAME,
54
- TypeFactory.optional(KEY_PARENT) => PType::DEFAULT,
54
+ TypeFactory.optional(KEY_PARENT) => PTypeType::DEFAULT,
55
55
  TypeFactory.optional(KEY_ATTRIBUTES) => TYPE_ATTRIBUTES,
56
56
  TypeFactory.optional(KEY_FUNCTIONS) => TYPE_FUNCTIONS,
57
57
  TypeFactory.optional(KEY_EQUALITY) => TYPE_EQUALITY,
@@ -64,7 +64,7 @@ class PObjectType < PMetaType
64
64
  type = create_ptype(loader, ir, 'AnyType', '_pcore_init_hash' => TYPE_OBJECT_I12N)
65
65
 
66
66
  # Now, when the Object type exists, add annotations with keys derived from Annotation and freeze the types.
67
- annotations = TypeFactory.optional(PHashType.new(PType.new(Annotation._pcore_type), TypeFactory.hash_kv(Pcore::TYPE_MEMBER_NAME, PAnyType::DEFAULT)))
67
+ annotations = TypeFactory.optional(PHashType.new(PTypeType.new(Annotation._pcore_type), TypeFactory.hash_kv(Pcore::TYPE_MEMBER_NAME, PAnyType::DEFAULT)))
68
68
  TYPE_ATTRIBUTE.hashed_elements[KEY_ANNOTATIONS].replace_value_type(annotations)
69
69
  TYPE_FUNCTION.hashed_elements[KEY_ANNOTATIONS].replace_value_type(annotations)
70
70
  TYPE_OBJECT_I12N.hashed_elements[KEY_ANNOTATIONS].replace_value_type(annotations)
@@ -96,7 +96,7 @@ class PObjectType < PMetaType
96
96
  # @option init_hash [PAnyType] 'type' The member type (required)
97
97
  # @option init_hash [Boolean] 'override' `true` if this feature must override an inherited feature. Default is `false`.
98
98
  # @option init_hash [Boolean] 'final' `true` if this feature cannot be overridden. Default is `false`.
99
- # @option init_hash [Hash{PType => Hash}] 'annotations' Annotations hash. Default is `nil`.
99
+ # @option init_hash [Hash{PTypeType => Hash}] 'annotations' Annotations hash. Default is `nil`.
100
100
  # @api public
101
101
  def initialize(name, container, init_hash)
102
102
  @name = name
@@ -392,8 +392,8 @@ class PObjectType < PMetaType
392
392
  end
393
393
 
394
394
  # @api private
395
- def new_function(loader)
396
- @new_function ||= create_new_function(loader)
395
+ def new_function
396
+ @new_function ||= create_new_function
397
397
  end
398
398
 
399
399
  # Assign a new instance reader to this type
@@ -428,7 +428,7 @@ class PObjectType < PMetaType
428
428
  end
429
429
 
430
430
  # @api private
431
- def create_new_function(loader)
431
+ def create_new_function
432
432
  impl_class = implementation_class
433
433
  class_name = impl_class.name || "Anonymous Ruby class for #{name}"
434
434
 
@@ -439,7 +439,7 @@ class PObjectType < PMetaType
439
439
  param_types << param_names.size
440
440
 
441
441
  create_type = TypeFactory.callable(*param_types)
442
- from_hash_type = TypeFactory.callable(i12n_type, 1, 1)
442
+ from_hash_type = TypeFactory.callable(init_hash_type, 1, 1)
443
443
 
444
444
  # Create and return a #new_XXX function where the dispatchers are added programmatically.
445
445
  Puppet::Functions.create_loaded_function(:"new_#{name}", loader) do
@@ -514,7 +514,7 @@ class PObjectType < PMetaType
514
514
  opt_names = []
515
515
  non_opt_types = []
516
516
  non_opt_names = []
517
- i12n_type.elements.each do |se|
517
+ init_hash_type.elements.each do |se|
518
518
  if se.key_type.is_a?(POptionalType)
519
519
  opt_names << se.name
520
520
  opt_types << se.value_type
@@ -598,7 +598,7 @@ class PObjectType < PMetaType
598
598
  unless attr_specs.nil? || attr_specs.empty?
599
599
  @attributes = Hash[attr_specs.map do |key, attr_spec|
600
600
  unless attr_spec.is_a?(Hash)
601
- attr_type = TypeAsserter.assert_instance_of(nil, PType::DEFAULT, attr_spec) { "attribute #{label}[#{key}]" }
601
+ attr_type = TypeAsserter.assert_instance_of(nil, PTypeType::DEFAULT, attr_spec) { "attribute #{label}[#{key}]" }
602
602
  attr_spec = { KEY_TYPE => attr_type }
603
603
  attr_spec[KEY_VALUE] = nil if attr_type.is_a?(POptionalType)
604
604
  end
@@ -684,8 +684,8 @@ class PObjectType < PMetaType
684
684
  #
685
685
  # @return [PStructType] the initialization hash type
686
686
  # @api public
687
- def i12n_type
688
- @i12n_type ||= create_i12n_type
687
+ def init_hash_type
688
+ @init_hash_type ||= create_init_hash_type
689
689
  end
690
690
 
691
691
  def allocate
@@ -704,7 +704,7 @@ class PObjectType < PMetaType
704
704
  #
705
705
  # @return [PStructType] the initialization hash type
706
706
  # @api private
707
- def create_i12n_type
707
+ def create_init_hash_type
708
708
  struct_elems = {}
709
709
  attributes(true).values.each do |attr|
710
710
  unless attr.kind == ATTRIBUTE_KIND_CONSTANT || attr.kind == ATTRIBUTE_KIND_DERIVED
@@ -818,7 +818,7 @@ class PObjectType < PMetaType
818
818
 
819
819
  # @api private
820
820
  def label
821
- @name || '<anonymous object type>'
821
+ @name || 'Object'
822
822
  end
823
823
 
824
824
  # @api private
@@ -106,9 +106,9 @@ class PSemVerRangeType < PAnyType
106
106
  super ^ @version_range.hash
107
107
  end
108
108
 
109
- def self.new_function(_, loader)
109
+ def self.new_function(type)
110
110
  range_expr = "\\A#{range_pattern}\\Z"
111
- @@new_function ||= Puppet::Functions.create_loaded_function(:new_VersionRange, loader) do
111
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_VersionRange, type.loader) do
112
112
  local_types do
113
113
  type 'SemVerRangeString = String[1]'
114
114
  type 'SemVerRangeHash = Struct[{min=>Variant[default,SemVer],Optional[max]=>Variant[default,SemVer],Optional[exclude_max]=>Boolean}]'
@@ -55,8 +55,8 @@ class PSemVerType < PScalarType
55
55
  end
56
56
 
57
57
  # @api private
58
- def self.new_function(_, loader)
59
- @@new_function ||= Puppet::Functions.create_loaded_function(:new_Version, loader) do
58
+ def self.new_function(type)
59
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_Version, type.loader) do
60
60
  local_types do
61
61
  type 'PositiveInteger = Integer[0,default]'
62
62
  type 'SemVerQualifier = Pattern[/\A(?<part>[0-9A-Za-z-]+)(?:\.\g<part>)*\Z/]'
@@ -38,8 +38,8 @@ class PSensitiveType < PTypeWithContainedType
38
38
  o.is_a?(Sensitive) && @type.instance?(o.unwrap, guard)
39
39
  end
40
40
 
41
- def self.new_function(_, loader)
42
- @new_function ||= Puppet::Functions.create_loaded_function(:new_Sensitive, loader) do
41
+ def self.new_function(type)
42
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_Sensitive, type.loader) do
43
43
 
44
44
  dispatch :from_sensitive do
45
45
  param 'Sensitive', :value
@@ -50,10 +50,6 @@ module Types
50
50
  self.class == o.class && @from == o.numeric_from && @to == o.numeric_to
51
51
  end
52
52
 
53
- def instance?(o, guard = nil)
54
- o.is_a?(Numeric) && o >= @from && o <= @to
55
- end
56
-
57
53
  def unbounded?
58
54
  @from == -Float::INFINITY && @to == Float::INFINITY
59
55
  end
@@ -107,8 +103,8 @@ module Types
107
103
  )
108
104
  end
109
105
 
110
- def self.new_function(_, loader)
111
- @new_function ||= Puppet::Functions.create_loaded_function(:new_timespan, loader) do
106
+ def self.new_function(type)
107
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_timespan, type.loader) do
112
108
  local_types do
113
109
  type 'Formats = Variant[String[2],Array[String[2]], 1]'
114
110
  end
@@ -186,6 +182,10 @@ module Types
186
182
  Time::Timespan
187
183
  end
188
184
 
185
+ def instance?(o, guard = nil)
186
+ o.is_a?(Time::Timespan) && o >= @from && o <= @to
187
+ end
188
+
189
189
  DEFAULT = PTimespanType.new(nil, nil)
190
190
  end
191
191
  end
@@ -8,8 +8,8 @@ module Types
8
8
  )
9
9
  end
10
10
 
11
- def self.new_function(_, loader)
12
- @new_function ||= Puppet::Functions.create_loaded_function(:new_timestamp, loader) do
11
+ def self.new_function(type)
12
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_timestamp, type.loader) do
13
13
  local_types do
14
14
  type 'Formats = Variant[String[2],Array[String[2]], 1]'
15
15
  end
@@ -63,6 +63,10 @@ module Types
63
63
  Time::Timestamp
64
64
  end
65
65
 
66
+ def instance?(o, guard = nil)
67
+ o.is_a?(Time::Timestamp) && o >= @from && o <= @to
68
+ end
69
+
66
70
  DEFAULT = PTimestampType.new(nil, nil)
67
71
  end
68
72
  end
@@ -48,13 +48,13 @@ class PTypeSetType < PMetaType
48
48
  TypeFactory.optional(KEY_NAME_AUTHORITY) => Pcore::TYPE_URI,
49
49
  TypeFactory.optional(KEY_NAME) => Pcore::TYPE_QUALIFIED_REFERENCE,
50
50
  TypeFactory.optional(KEY_VERSION) => TYPE_STRING_OR_VERSION,
51
- TypeFactory.optional(KEY_TYPES) => TypeFactory.hash_kv(Pcore::TYPE_SIMPLE_TYPE_NAME, PType::DEFAULT, PCollectionType::NOT_EMPTY_SIZE),
51
+ TypeFactory.optional(KEY_TYPES) => TypeFactory.hash_kv(Pcore::TYPE_SIMPLE_TYPE_NAME, PTypeType::DEFAULT, PCollectionType::NOT_EMPTY_SIZE),
52
52
  TypeFactory.optional(KEY_REFERENCES) => TypeFactory.hash_kv(Pcore::TYPE_SIMPLE_TYPE_NAME, TYPE_TYPE_REFERENCE_I12N, PCollectionType::NOT_EMPTY_SIZE),
53
53
  TypeFactory.optional(KEY_ANNOTATIONS) => TYPE_ANNOTATIONS,
54
54
  })
55
55
 
56
56
  def self.register_ptype(loader, ir)
57
- create_ptype(loader, ir, 'AnyType', '_pcore_init_hash' => TYPE_TYPESET_I12N.resolve(TypeParser.singleton, loader))
57
+ create_ptype(loader, ir, 'AnyType', '_pcore_init_hash' => TYPE_TYPESET_I12N.resolve(loader))
58
58
  end
59
59
 
60
60
  attr_reader :pcore_uri
@@ -254,17 +254,18 @@ class PTypeSetType < PMetaType
254
254
  end
255
255
 
256
256
  # @api private
257
- def resolve(type_parser, loader)
257
+ def resolve(loader)
258
258
  super
259
- @references.each_value { |ref| ref.resolve(type_parser, loader) }
259
+ @references.each_value { |ref| ref.resolve(loader) }
260
260
  tsa_loader = TypeSetLoader.new(self, loader)
261
- @types.values.each { |type| type.resolve(type_parser, tsa_loader) }
261
+ @types.values.each { |type| type.resolve(tsa_loader) }
262
262
  self
263
263
  end
264
264
 
265
265
  # @api private
266
- def resolve_literal_hash(type_parser, loader, init_hash_expression)
266
+ def resolve_literal_hash(loader, init_hash_expression)
267
267
  result = {}
268
+ type_parser = TypeParser.singleton
268
269
  init_hash_expression.entries.each do |entry|
269
270
  key = type_parser.interpret_any(entry.key, loader)
270
271
  if (key == KEY_TYPES || key == KEY_REFERENCES) && entry.value.is_a?(Model::LiteralHash)
@@ -297,10 +298,10 @@ class PTypeSetType < PMetaType
297
298
  end
298
299
 
299
300
  # @api private
300
- def resolve_hash(type_parser, loader, init_hash)
301
+ def resolve_hash(loader, init_hash)
301
302
  result = Hash[init_hash.map do |key, value|
302
- key = resolve_type_refs(type_parser, loader, key)
303
- value = resolve_type_refs(type_parser, loader, value) unless key == KEY_TYPES && value.is_a?(Hash)
303
+ key = resolve_type_refs(loader, key)
304
+ value = resolve_type_refs(loader, value) unless key == KEY_TYPES && value.is_a?(Hash)
304
305
  [key, value]
305
306
  end]
306
307
  name_auth = resolve_name_authority(result, loader)
@@ -60,6 +60,7 @@ class RubyGenerator < TypeFormatter
60
60
  index += 1
61
61
  len > segments.size ? segments.size : len
62
62
  end
63
+ min_prefix_length = 0 if min_prefix_length == Float::INFINITY
63
64
 
64
65
  common_prefix = []
65
66
  segments_array = names_by_prefix.keys
@@ -190,17 +191,17 @@ class RubyGenerator < TypeFormatter
190
191
 
191
192
  unless obj.parent.is_a?(PObjectType) && obj_attrs.empty?
192
193
  # Output type safe hash constructor
193
- bld << "\n def self.from_hash(i12n)\n"
194
+ bld << "\n def self.from_hash(init_hash)\n"
194
195
  bld << ' from_asserted_hash(' << namespace_relative(segments, TypeAsserter.name) << '.assert_instance_of('
195
- bld << "'" << obj.label << " initializer', _pcore_type.i12n_type, i12n))\n end\n\n def self.from_asserted_hash(i12n)\n new"
196
+ bld << "'" << obj.label << " initializer', _pcore_type.init_hash_type, init_hash))\n end\n\n def self.from_asserted_hash(init_hash)\n new"
196
197
  unless non_opt.empty? && opt.empty?
197
198
  bld << "(\n"
198
- non_opt.each { |ip| bld << " i12n['" << ip.name << "'],\n" }
199
+ non_opt.each { |ip| bld << " init_hash['" << ip.name << "'],\n" }
199
200
  opt.each do |ip|
200
201
  if ip.value.nil?
201
- bld << " i12n['" << ip.name << "'],\n"
202
+ bld << " init_hash['" << ip.name << "'],\n"
202
203
  else
203
- bld << " i12n.fetch('" << ip.name << "') { "
204
+ bld << " init_hash.fetch('" << ip.name << "') { "
204
205
  default_string(bld, ip)
205
206
  bld << " },\n"
206
207
  end
@@ -12,8 +12,8 @@ module Types
12
12
  )
13
13
  end
14
14
 
15
- def self.from_hash(i12n)
16
- from_asserted_hash(Types::TypeAsserter.assert_instance_of('RubyMethod initializer', _pcore_type.i12n_type, i12n))
15
+ def self.from_hash(init_hash)
16
+ from_asserted_hash(Types::TypeAsserter.assert_instance_of('RubyMethod initializer', _pcore_type.init_hash_type, init_hash))
17
17
  end
18
18
 
19
19
  def self.from_asserted_hash(init_hash)
@@ -1073,7 +1073,7 @@ class StringConverter
1073
1073
  end
1074
1074
 
1075
1075
  # @api private
1076
- def string_PType(val_type, val, format_map, _)
1076
+ def string_PTypeType(val_type, val, format_map, _)
1077
1077
  f = get_format(val_type, format_map)
1078
1078
  case f.format
1079
1079
  when :s
@@ -0,0 +1,250 @@
1
+ module Puppet::Pops::Types
2
+ module Iterable
3
+
4
+ class TreeIterator
5
+ include Iterable
6
+
7
+ DEFAULT_CONTAINERS = TypeFactory.variant(
8
+ PArrayType::DEFAULT,
9
+ PHashType::DEFAULT,
10
+ PObjectType::DEFAULT
11
+ )
12
+
13
+ # Creates a TreeIterator that by default treats all Array, Hash and Object instances as
14
+ # containers - the 'containers' option can be set to a type that denotes which types of values
15
+ # should be treated as containers - a `Variant[Array, Hash]` would for instance not treat
16
+ # Object values as containers, whereas just `Object` would only treat objects as containers.
17
+ #
18
+ # Unrecognized options are silently ignored
19
+ #
20
+ # @param [Hash] options the options
21
+ # @option options [PTypeType] :container_type ('Variant[Hash, Array, Object]') The type(s) that should be treated as containers. The
22
+ # given type(s) must be assignable to the default container_type.
23
+ # @option options [Boolean] :include_root ('true') If the root container itself should be included in the iteration (requires
24
+ # `include_containers` to also be `true` to take effect).
25
+ # @option options [Boolean] :include_containers ('true') If containers should be included in the iteration
26
+ # @option options [Boolean] :include_values ('true') If non containers (values) should be included in the iteration
27
+ # @option options [Boolean] :include_refs ('false') If (non containment) referenced values in Objects should be included
28
+ #
29
+ def initialize(enum, options=EMPTY_HASH)
30
+ @root = enum
31
+ @element_t = nil
32
+ @value_stack = [enum]
33
+ @indexer_stack = []
34
+ @current_path = []
35
+ @recursed = false
36
+ @containers_t = options['container_type'] || DEFAULT_CONTAINERS
37
+ unless DEFAULT_CONTAINERS.assignable?(@containers_t)
38
+ raise ArgumentError, _("Only Array, Hash, and Object types can be used as container types. Got %{type}") % {type: @containers_t}
39
+ end
40
+ @with_root = extract_option(options, 'include_root', true)
41
+ @with_containers = extract_option(options, 'include_containers', true)
42
+ @with_values = extract_option(options, 'include_values', true)
43
+ @with_root = @with_containers && extract_option(options, 'include_root', true)
44
+ unless @with_containers || @with_values
45
+ raise ArgumentError, _("Options 'include_containers' and 'include_values' cannot both be false")
46
+ end
47
+ @include_refs = !!options['include_refs']
48
+ end
49
+
50
+ # Yields each `path, value` if the block arity is 2, and only `value` if arity is 1
51
+ #
52
+ def each(&block)
53
+ loop do
54
+ if block.arity == 1
55
+ yield(self.next)
56
+ else
57
+ yield(*self.next)
58
+ end
59
+ end
60
+ end
61
+
62
+ def size
63
+ raise "Not yet implemented - computes size lazily"
64
+ end
65
+
66
+ def unbounded?
67
+ false
68
+ end
69
+
70
+ def to_array
71
+ result = []
72
+ loop do
73
+ result << self.next
74
+ end
75
+ result
76
+ end
77
+
78
+ def reverse_each(&block)
79
+ r = Iterator.new(PAnyType::DEFAULT, to_array.reverse_each)
80
+ block_given? ? r.each(&block) : r
81
+ end
82
+
83
+ def step(step, &block)
84
+ r = StepIterator.new(PAnyType::DEFAULT, self, step)
85
+ block_given? ? r.each(&block) : r
86
+ end
87
+
88
+ def indexer_on(val)
89
+ return nil unless @containers_t.instance?(val)
90
+ if val.is_a?(Array)
91
+ val.size.times
92
+ elsif val.is_a?(Hash)
93
+ val.each_key
94
+ else
95
+ if @include_refs
96
+ val._pcore_type.attributes.each_key
97
+ else
98
+ val._pcore_type.attributes.reject {|k,v| v.kind == PObjectType::ATTRIBUTE_KIND_REFERENCE }.each_key
99
+ end
100
+ end
101
+ end
102
+ private :indexer_on
103
+
104
+ def has_next?(iterator)
105
+ begin
106
+ iterator.peek
107
+ true
108
+ rescue StopIteration
109
+ false
110
+ end
111
+ end
112
+ private :has_next?
113
+
114
+ def extract_option(options, key, default)
115
+ v = options[key]
116
+ v.nil? ? default : !!v
117
+ end
118
+ private :extract_option
119
+ end
120
+
121
+ class DepthFirstTreeIterator < TreeIterator
122
+
123
+ # Creates a DepthFirstTreeIterator that by default treats all Array, Hash and Object instances as
124
+ # containers - the 'containers' option can be set to a type that denotes which types of values
125
+ # should be treated as containers - a `Variant[Array, Hash]` would for instance not treat
126
+ # Object values as containers, whereas just `Object` would only treat objects as containers.
127
+ #
128
+ # @param [Hash] options the options
129
+ # @option options [PTypeType] :containers ('Variant[Hash, Array, Object]') The type(s) that should be treated as containers
130
+ # @option options [Boolean] :with_root ('true') If the root container itself should be included in the iteration
131
+ #
132
+ def initialize(enum, options = EMPTY_HASH)
133
+ super
134
+ end
135
+
136
+ def next
137
+ loop do
138
+ break if @value_stack.empty?
139
+
140
+ # first call
141
+ if @indexer_stack.empty?
142
+ @indexer_stack << indexer_on(@root)
143
+ @recursed = true
144
+ return [[], @root] if @with_root
145
+ end
146
+
147
+ begin
148
+ if @recursed
149
+ @current_path << nil
150
+ @recursed = false
151
+ end
152
+ idx = @indexer_stack[-1].next
153
+ @current_path[-1] = idx
154
+ v = @value_stack[-1]
155
+ value = v.is_a?(PuppetObject) ? v.send(idx) : v[idx]
156
+ indexer = indexer_on(value)
157
+ if indexer
158
+ # recurse
159
+ @recursed = true
160
+ @value_stack << value
161
+ @indexer_stack << indexer
162
+ redo unless @with_containers
163
+ else
164
+ redo unless @with_values
165
+ end
166
+ return [@current_path.dup, value]
167
+
168
+ rescue StopIteration
169
+ # end of current value's range of content
170
+ # pop all until out of next values
171
+ at_the_very_end = false
172
+ loop do
173
+ pop_level
174
+ at_the_very_end = @indexer_stack.empty?
175
+ break if at_the_very_end || has_next?(@indexer_stack[-1])
176
+ end
177
+ end
178
+ end
179
+ raise StopIteration
180
+ end
181
+
182
+ def pop_level
183
+ @value_stack.pop
184
+ @indexer_stack.pop
185
+ @current_path.pop
186
+ end
187
+ private :pop_level
188
+ end
189
+
190
+ class BreadthFirstTreeIterator < TreeIterator
191
+ def initialize(enum, options = EMPTY_HASH)
192
+ @path_stack = []
193
+ super
194
+ end
195
+
196
+ def next
197
+ loop do
198
+ break if @value_stack.empty?
199
+
200
+ # first call
201
+ if @indexer_stack.empty?
202
+ @indexer_stack << indexer_on(@root)
203
+ @recursed = true
204
+ return [[], @root] if @with_root
205
+ end
206
+
207
+ begin
208
+ if @recursed
209
+ @current_path << nil
210
+ @recursed = false
211
+ end
212
+
213
+ idx = @indexer_stack[0].next
214
+ @current_path[-1] = idx
215
+ v = @value_stack[0]
216
+ value = v.is_a?(PuppetObject) ? v.send(idx) : v[idx]
217
+ indexer = indexer_on(value)
218
+ if indexer
219
+ @value_stack << value
220
+ @indexer_stack << indexer
221
+ @path_stack << @current_path.dup
222
+ next unless @with_containers
223
+ end
224
+ return [@current_path.dup, value]
225
+
226
+ rescue StopIteration
227
+ # end of current value's range of content
228
+ # shift all until out of next values
229
+ at_the_very_end = false
230
+ loop do
231
+ shift_level
232
+ at_the_very_end = @indexer_stack.empty?
233
+ break if at_the_very_end || has_next?(@indexer_stack[0])
234
+ end
235
+ end
236
+ end
237
+ raise StopIteration
238
+ end
239
+
240
+ def shift_level
241
+ @value_stack.shift
242
+ @indexer_stack.shift
243
+ @current_path = @path_stack.shift
244
+ @recursed = true
245
+ end
246
+ private :shift_level
247
+
248
+ end
249
+ end
250
+ end