bolt 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/bolt/cli.rb +65 -28
- data/lib/bolt/config.rb +18 -8
- data/lib/bolt/executor.rb +21 -6
- data/lib/bolt/node.rb +3 -0
- data/lib/bolt/node/result.rb +5 -0
- data/lib/bolt/node/ssh.rb +81 -25
- data/lib/bolt/node/winrm.rb +70 -31
- data/lib/bolt/notifier.rb +20 -0
- data/lib/bolt/outputter.rb +21 -0
- data/lib/bolt/outputter/human.rb +30 -0
- data/lib/bolt/outputter/json.rb +51 -0
- data/lib/bolt/result.rb +32 -5
- data/lib/bolt/version.rb +1 -1
- data/vendored/puppet/lib/puppet.rb +4 -5
- data/vendored/puppet/lib/puppet/agent.rb +22 -2
- data/vendored/puppet/lib/puppet/application/agent.rb +1 -1
- data/vendored/puppet/lib/puppet/application/apply.rb +1 -1
- data/vendored/puppet/lib/puppet/configurer/downloader_factory.rb +10 -0
- data/vendored/puppet/lib/puppet/configurer/plugin_handler.rb +4 -4
- data/vendored/puppet/lib/puppet/defaults.rb +21 -2
- data/vendored/puppet/lib/puppet/external/nagios/parser.rb +1 -1
- data/vendored/puppet/lib/puppet/file_serving/configuration.rb +3 -0
- data/vendored/puppet/lib/puppet/file_serving/configuration/parser.rb +2 -0
- data/vendored/puppet/lib/puppet/file_serving/mount/locales.rb +35 -0
- data/vendored/puppet/lib/puppet/forge.rb +9 -3
- data/vendored/puppet/lib/puppet/forge/repository.rb +1 -1
- data/vendored/puppet/lib/puppet/functions/file_upload.rb +20 -15
- data/vendored/puppet/lib/puppet/functions/new.rb +1 -4
- data/vendored/puppet/lib/puppet/functions/run_command.rb +15 -13
- data/vendored/puppet/lib/puppet/functions/run_script.rb +27 -14
- data/vendored/puppet/lib/puppet/functions/run_task.rb +21 -19
- data/vendored/puppet/lib/puppet/gettext/config.rb +86 -28
- data/vendored/puppet/lib/puppet/indirector/catalog/compiler.rb +25 -5
- data/vendored/puppet/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
- data/vendored/puppet/lib/puppet/module.rb +13 -17
- data/vendored/puppet/lib/puppet/pops/evaluator/access_operator.rb +20 -21
- data/vendored/puppet/lib/puppet/pops/evaluator/compare_operator.rb +3 -3
- data/vendored/puppet/lib/puppet/pops/evaluator/evaluator_impl.rb +9 -0
- data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +20 -1
- data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +2 -1
- data/vendored/puppet/lib/puppet/pops/loaders.rb +6 -41
- data/vendored/puppet/lib/puppet/pops/pcore.rb +9 -0
- data/vendored/puppet/lib/puppet/pops/serialization/from_data_converter.rb +64 -10
- data/vendored/puppet/lib/puppet/pops/serialization/json_path.rb +2 -1
- data/vendored/puppet/lib/puppet/pops/types/execution_result.rb +7 -4
- data/vendored/puppet/lib/puppet/pops/types/p_binary_type.rb +9 -2
- data/vendored/puppet/lib/puppet/pops/types/p_init_type.rb +1 -1
- data/vendored/puppet/lib/puppet/pops/types/p_meta_type.rb +4 -0
- data/vendored/puppet/lib/puppet/pops/types/p_object_type.rb +81 -4
- data/vendored/puppet/lib/puppet/pops/types/p_object_type_extension.rb +213 -0
- data/vendored/puppet/lib/puppet/pops/types/p_sem_ver_type.rb +10 -2
- data/vendored/puppet/lib/puppet/pops/types/puppet_object.rb +11 -1
- data/vendored/puppet/lib/puppet/pops/types/type_calculator.rb +2 -2
- data/vendored/puppet/lib/puppet/pops/types/type_factory.rb +16 -6
- data/vendored/puppet/lib/puppet/pops/types/type_formatter.rb +22 -14
- data/vendored/puppet/lib/puppet/pops/types/type_parser.rb +17 -15
- data/vendored/puppet/lib/puppet/pops/types/types.rb +181 -72
- data/vendored/puppet/lib/puppet/provider.rb +18 -8
- data/vendored/puppet/lib/puppet/provider/package/yum.rb +22 -7
- data/vendored/puppet/lib/puppet/provider/service/base.rb +21 -8
- data/vendored/puppet/lib/puppet/provider/service/launchd.rb +2 -3
- data/vendored/puppet/lib/puppet/provider/user/aix.rb +1 -0
- data/vendored/puppet/lib/puppet/provider/user/user_role_add.rb +7 -1
- data/vendored/puppet/lib/puppet/provider/user/useradd.rb +3 -2
- data/vendored/puppet/lib/puppet/provider/zfs/zfs.rb +5 -1
- data/vendored/puppet/lib/puppet/type/exec.rb +5 -4
- data/vendored/puppet/lib/puppet/type/macauthorization.rb +1 -1
- data/vendored/puppet/lib/puppet/type/user.rb +19 -0
- data/vendored/puppet/lib/puppet/util/log/destinations.rb +10 -0
- data/vendored/puppet/lib/puppet/util/windows/file.rb +35 -4
- data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +1 -1
- data/vendored/puppet/lib/puppet/version.rb +1 -1
- data/vendored/puppet/lib/puppet_pal.rb +15 -5
- metadata +8 -3
- data/vendored/puppet/lib/puppet/pops/types/p_error_type.rb +0 -158
@@ -60,14 +60,14 @@ class PSemVerType < PScalarType
|
|
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/]'
|
63
|
-
type
|
63
|
+
type "SemVerPattern = Pattern[/\\A#{SemanticPuppet::Version::REGEX_FULL}\\Z/]"
|
64
64
|
type 'SemVerHash = Struct[{major=>PositiveInteger,minor=>PositiveInteger,patch=>PositiveInteger,Optional[prerelease]=>SemVerQualifier,Optional[build]=>SemVerQualifier}]'
|
65
65
|
end
|
66
66
|
|
67
67
|
# Creates a SemVer from a string as specified by http://semver.org/
|
68
68
|
#
|
69
69
|
dispatch :from_string do
|
70
|
-
param '
|
70
|
+
param 'SemVerPattern', :str
|
71
71
|
end
|
72
72
|
|
73
73
|
# Creates a SemVer from integers, prerelease, and build arguments
|
@@ -86,6 +86,10 @@ class PSemVerType < PScalarType
|
|
86
86
|
param 'SemVerHash', :hash_args
|
87
87
|
end
|
88
88
|
|
89
|
+
argument_mismatch :on_error do
|
90
|
+
param 'String', :str
|
91
|
+
end
|
92
|
+
|
89
93
|
def from_string(str)
|
90
94
|
SemanticPuppet::Version.parse(str)
|
91
95
|
end
|
@@ -97,6 +101,10 @@ class PSemVerType < PScalarType
|
|
97
101
|
def from_hash(hash)
|
98
102
|
SemanticPuppet::Version.new(hash['major'], hash['minor'], hash['patch'], hash['prerelease'], hash['build'])
|
99
103
|
end
|
104
|
+
|
105
|
+
def on_error(str)
|
106
|
+
_("The string '%{str}' cannot be converted to a SemVer") % { str: str }
|
107
|
+
end
|
100
108
|
end
|
101
109
|
end
|
102
110
|
|
@@ -9,7 +9,17 @@ module PuppetObject
|
|
9
9
|
#
|
10
10
|
# @return [PObjectType] the type
|
11
11
|
def _pcore_type
|
12
|
-
self.class._pcore_type
|
12
|
+
t = self.class._pcore_type
|
13
|
+
if t.parameterized?
|
14
|
+
unless instance_variable_defined?(:@_cached_ptype)
|
15
|
+
# Create a parameterized type based on the values of this instance that
|
16
|
+
# contains a parameter value for each type parameter that matches an
|
17
|
+
# attribute by name and type of value
|
18
|
+
@_cached_ptype = PObjectTypeExtension.create(t, self)
|
19
|
+
end
|
20
|
+
t = @_cached_ptype
|
21
|
+
end
|
22
|
+
t
|
13
23
|
end
|
14
24
|
|
15
25
|
def _pcore_all_contents(path, &block)
|
@@ -614,12 +614,12 @@ class TypeCalculator
|
|
614
614
|
|
615
615
|
# @api private
|
616
616
|
def infer_TrueClass(o)
|
617
|
-
PBooleanType::
|
617
|
+
PBooleanType::TRUE
|
618
618
|
end
|
619
619
|
|
620
620
|
# @api private
|
621
621
|
def infer_FalseClass(o)
|
622
|
-
PBooleanType::
|
622
|
+
PBooleanType::FALSE
|
623
623
|
end
|
624
624
|
|
625
625
|
# @api private
|
@@ -127,7 +127,13 @@ module TypeFactory
|
|
127
127
|
# @api public
|
128
128
|
#
|
129
129
|
def self.enum(*values)
|
130
|
-
|
130
|
+
last = values.last
|
131
|
+
case_insensitive = false
|
132
|
+
if last == true || last == false
|
133
|
+
case_insensitive = last
|
134
|
+
values = values[0...-1]
|
135
|
+
end
|
136
|
+
PEnumType.new(values, case_insensitive)
|
131
137
|
end
|
132
138
|
|
133
139
|
# Produces the Variant type, optionally with the "one of" types
|
@@ -227,8 +233,8 @@ module TypeFactory
|
|
227
233
|
# Produces the Boolean type
|
228
234
|
# @api public
|
229
235
|
#
|
230
|
-
def self.boolean
|
231
|
-
PBooleanType::DEFAULT
|
236
|
+
def self.boolean(value = nil)
|
237
|
+
value.nil? ? PBooleanType::DEFAULT : (value ? PBooleanType::TRUE : PBooleanType::FALSE)
|
232
238
|
end
|
233
239
|
|
234
240
|
# Produces the Any type
|
@@ -511,11 +517,15 @@ module TypeFactory
|
|
511
517
|
inst_type.nil? ? PTypeType::DEFAULT : PTypeType.new(inst_type)
|
512
518
|
end
|
513
519
|
|
514
|
-
# Produces a type for Error
|
520
|
+
# Produces a type for Error
|
515
521
|
# @api public
|
516
522
|
#
|
517
|
-
def self.error
|
518
|
-
|
523
|
+
def self.error
|
524
|
+
@error_t ||= TypeParser.singleton.parse('Error', Loaders.static_loader)
|
525
|
+
end
|
526
|
+
|
527
|
+
def self.target
|
528
|
+
@target_t ||= TypeParser.singleton.parse('Target')
|
519
529
|
end
|
520
530
|
|
521
531
|
# Produce a type corresponding to the class of given unless given is a
|
@@ -149,7 +149,9 @@ class TypeFormatter
|
|
149
149
|
def string_PDefaultType(_) ; @bld << 'Default' ; end
|
150
150
|
|
151
151
|
# @api private
|
152
|
-
def string_PBooleanType(
|
152
|
+
def string_PBooleanType(t)
|
153
|
+
append_array('Boolean', t.value.nil?) { append_string(t.value) }
|
154
|
+
end
|
153
155
|
|
154
156
|
# @api private
|
155
157
|
def string_PScalarType(_) ; @bld << 'Scalar' ; end
|
@@ -213,7 +215,13 @@ class TypeFormatter
|
|
213
215
|
|
214
216
|
# @api private
|
215
217
|
def string_PEnumType(t)
|
216
|
-
append_array('Enum', t.values.empty?)
|
218
|
+
append_array('Enum', t.values.empty?) do
|
219
|
+
append_strings(t.values)
|
220
|
+
if t.case_insensitive?
|
221
|
+
@bld << COMMA_SEP
|
222
|
+
append_string(true)
|
223
|
+
end
|
224
|
+
end
|
217
225
|
end
|
218
226
|
|
219
227
|
# @api private
|
@@ -322,17 +330,6 @@ class TypeFormatter
|
|
322
330
|
append_array('Pattern', t.patterns.empty?) { append_strings(t.patterns.map(&:regexp)) }
|
323
331
|
end
|
324
332
|
|
325
|
-
# @api private
|
326
|
-
def string_PErrorType(t)
|
327
|
-
append_array('Error', t.kind.nil? && t.issue_code.nil?) do
|
328
|
-
t.kind.nil? ? append_default : append_error_param(t.kind)
|
329
|
-
unless t.issue_code.nil?
|
330
|
-
@bld << COMMA_SEP
|
331
|
-
append_error_param(t.issue_code)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
333
|
def append_error_param(ep)
|
337
334
|
case ep
|
338
335
|
when PStringType
|
@@ -490,6 +487,17 @@ class TypeFormatter
|
|
490
487
|
end
|
491
488
|
end
|
492
489
|
|
490
|
+
def string_PObjectTypeExtension(t)
|
491
|
+
append_array(@type_set ? @type_set.name_for(t, t.name) : t.name, false) do
|
492
|
+
ips = t.init_parameters
|
493
|
+
if ips.is_a?(Array)
|
494
|
+
append_strings(ips)
|
495
|
+
else
|
496
|
+
append_string(ips)
|
497
|
+
end
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
493
501
|
# @api private
|
494
502
|
def string_PSensitiveType(t)
|
495
503
|
append_array('Sensitive', PAnyType::DEFAULT == t.type) { append_string(t.type) }
|
@@ -569,7 +577,7 @@ class TypeFormatter
|
|
569
577
|
end
|
570
578
|
|
571
579
|
# @api private
|
572
|
-
def string_NilClass(t) ; @bld << (@ruby ? 'nil' : '
|
580
|
+
def string_NilClass(t) ; @bld << (@ruby ? 'nil' : 'undef') ; end
|
573
581
|
|
574
582
|
# @api private
|
575
583
|
def string_Numeric(t) ; @bld << t.to_s ; end
|
@@ -201,7 +201,6 @@ class TypeParser
|
|
201
201
|
'semverrange' => TypeFactory.sem_ver_range,
|
202
202
|
'timestamp' => TypeFactory.timestamp,
|
203
203
|
'timespan' => TypeFactory.timespan,
|
204
|
-
'error' => TypeFactory.error
|
205
204
|
}.freeze
|
206
205
|
end
|
207
206
|
|
@@ -341,27 +340,22 @@ class TypeParser
|
|
341
340
|
TypeFactory.regexp(parameters[0])
|
342
341
|
|
343
342
|
when 'enum'
|
344
|
-
# 1..m parameters being
|
343
|
+
# 1..m parameters being string
|
344
|
+
last = parameters.last
|
345
|
+
case_insensitive = false
|
346
|
+
if last == true || last == false
|
347
|
+
parameters = parameters[0...-1]
|
348
|
+
case_insensitive = last
|
349
|
+
end
|
345
350
|
raise_invalid_parameters_error('Enum', '1 or more', parameters.size) unless parameters.size >= 1
|
346
351
|
parameters.each { |p| raise Puppet::ParseError, 'Enum parameters must be identifiers or strings' unless p.is_a?(String) }
|
347
|
-
|
352
|
+
PEnumType.new(parameters, case_insensitive)
|
348
353
|
|
349
354
|
when 'pattern'
|
350
355
|
# 1..m parameters being strings or regular expressions
|
351
356
|
raise_invalid_parameters_error('Pattern', '1 or more', parameters.size) unless parameters.size >= 1
|
352
357
|
TypeFactory.pattern(*parameters)
|
353
358
|
|
354
|
-
when 'error'
|
355
|
-
# 1 - 2 parameters where both are string, regexp, or type
|
356
|
-
case parameters.size
|
357
|
-
when 1, 2
|
358
|
-
pt = PErrorType::TYPE_ERROR_PARAM
|
359
|
-
parameters.each { |p| raise Puppet::ParseError, "Error parameters must be ${pt}" unless pt.instance?(p) }
|
360
|
-
TypeFactory.error(*parameters)
|
361
|
-
else
|
362
|
-
raise_invalid_parameters_error('Error', '1 - 2', parameters.size)
|
363
|
-
end
|
364
|
-
|
365
359
|
when 'variant'
|
366
360
|
# 1..m parameters being strings or regular expressions
|
367
361
|
raise_invalid_parameters_error('Variant', '1 or more', parameters.size) unless parameters.size >= 1
|
@@ -405,6 +399,12 @@ class TypeParser
|
|
405
399
|
raise_invalid_type_specification_error(ast) unless h.is_a?(Hash)
|
406
400
|
TypeFactory.struct(h)
|
407
401
|
|
402
|
+
when 'boolean'
|
403
|
+
raise_invalid_parameters_error('Boolean', '1', parameters.size) unless parameters.size == 1
|
404
|
+
p = parameters[0]
|
405
|
+
raise Puppet::ParseError, 'Boolean parameter must be true or false' unless p == true || p == false
|
406
|
+
TypeFactory.boolean(p)
|
407
|
+
|
408
408
|
when 'integer'
|
409
409
|
if parameters.size == 1
|
410
410
|
case parameters[0]
|
@@ -497,7 +497,7 @@ class TypeParser
|
|
497
497
|
assert_type(ast, param) unless param.is_a?(String)
|
498
498
|
TypeFactory.optional(param)
|
499
499
|
|
500
|
-
when 'any', 'data', 'catalogentry', '
|
500
|
+
when 'any', 'data', 'catalogentry', 'scalar', 'undef', 'numeric', 'default', 'semverrange'
|
501
501
|
raise_unparameterized_type_error(qref)
|
502
502
|
|
503
503
|
when 'notundef'
|
@@ -548,6 +548,8 @@ class TypeParser
|
|
548
548
|
elsif type.is_a?(PResourceType)
|
549
549
|
raise_invalid_parameters_error(qref.cased_value, 1, parameters.size) unless parameters.size == 1
|
550
550
|
TypeFactory.resource(type.type_name, parameters[0])
|
551
|
+
elsif type.is_a?(PObjectType)
|
552
|
+
PObjectTypeExtension.create(type, parameters)
|
551
553
|
else
|
552
554
|
# Must be a type alias. They can't use parameters (yet)
|
553
555
|
raise_unparameterized_type_error(qref)
|
@@ -482,7 +482,7 @@ class PTypeType < PTypeWithContainedType
|
|
482
482
|
def self.new_function(type)
|
483
483
|
@new_function ||= Puppet::Functions.create_loaded_function(:new_type, type.loader) do
|
484
484
|
dispatch :from_string do
|
485
|
-
param 'String', :type_string
|
485
|
+
param 'String[1]', :type_string
|
486
486
|
end
|
487
487
|
|
488
488
|
def from_string(type_string)
|
@@ -756,13 +756,20 @@ end
|
|
756
756
|
#
|
757
757
|
class PEnumType < PScalarDataType
|
758
758
|
def self.register_ptype(loader, ir)
|
759
|
-
create_ptype(loader, ir, 'ScalarDataType',
|
759
|
+
create_ptype(loader, ir, 'ScalarDataType',
|
760
|
+
'values' => PArrayType.new(PStringType::NON_EMPTY),
|
761
|
+
'case_insensitive' => { 'type' => PBooleanType::DEFAULT, 'value' => false })
|
760
762
|
end
|
761
763
|
|
762
|
-
attr_reader :values
|
764
|
+
attr_reader :values, :case_insensitive
|
763
765
|
|
764
|
-
def initialize(values)
|
766
|
+
def initialize(values, case_insensitive = false)
|
765
767
|
@values = values.uniq.sort.freeze
|
768
|
+
@case_insensitive = case_insensitive
|
769
|
+
end
|
770
|
+
|
771
|
+
def case_insensitive?
|
772
|
+
@case_insensitive
|
766
773
|
end
|
767
774
|
|
768
775
|
# Returns Enumerator if no block is given, otherwise, calls the given
|
@@ -792,15 +799,19 @@ class PEnumType < PScalarDataType
|
|
792
799
|
end
|
793
800
|
|
794
801
|
def hash
|
795
|
-
@values.hash
|
802
|
+
@values.hash ^ @case_insensitive.hash
|
796
803
|
end
|
797
804
|
|
798
805
|
def eql?(o)
|
799
|
-
self.class == o.class && @values == o.values
|
806
|
+
self.class == o.class && @values == o.values && @case_insensitive == o.case_insensitive?
|
800
807
|
end
|
801
808
|
|
802
809
|
def instance?(o, guard = nil)
|
803
|
-
o.is_a?(String)
|
810
|
+
if o.is_a?(String)
|
811
|
+
@case_insensitive ? @values.any? { |p| p.casecmp(o) == 0 } : @values.any? { |p| p == o }
|
812
|
+
else
|
813
|
+
false
|
814
|
+
end
|
804
815
|
end
|
805
816
|
|
806
817
|
DEFAULT = PEnumType.new(EMPTY_ARRAY)
|
@@ -819,13 +830,26 @@ class PEnumType < PScalarDataType
|
|
819
830
|
# if the contained string is found in the set of enums
|
820
831
|
instance?(o.value, guard)
|
821
832
|
when PEnumType
|
822
|
-
!o.values.empty? && o.values.all? { |s| instance?(s, guard) }
|
833
|
+
!o.values.empty? && (case_insensitive? || !o.case_insensitive?) && o.values.all? { |s| instance?(s, guard) }
|
823
834
|
else
|
824
835
|
false
|
825
836
|
end
|
826
837
|
end
|
827
838
|
end
|
828
839
|
|
840
|
+
INTEGER_HEX = '(?:0[xX][0-9A-Fa-f]+)'
|
841
|
+
INTEGER_OCT = '(?:0[0-7]+)'
|
842
|
+
INTEGER_BIN = '(?:0[bB][01]+)'
|
843
|
+
INTEGER_DEC = '(?:0|[1-9]\d*)'
|
844
|
+
SIGN_PREFIX = '[+-]?\s*'
|
845
|
+
|
846
|
+
OPTIONAL_FRACTION = '(?:\.\d+)?'
|
847
|
+
OPTIONAL_EXPONENT = '(?:[eE]-?\d+)?'
|
848
|
+
FLOAT_DEC = '(?:' + INTEGER_DEC + OPTIONAL_FRACTION + OPTIONAL_EXPONENT + ')'
|
849
|
+
|
850
|
+
INTEGER_PATTERN = '\A' + SIGN_PREFIX + '(?:' + INTEGER_DEC + '|' + INTEGER_HEX + '|' + INTEGER_OCT + '|' + INTEGER_BIN + ')\z'
|
851
|
+
FLOAT_PATTERN = '\A' + SIGN_PREFIX + '(?:' + FLOAT_DEC + '|' + INTEGER_HEX + '|' + INTEGER_OCT + '|' + INTEGER_BIN + ')\z'
|
852
|
+
|
829
853
|
# @api public
|
830
854
|
#
|
831
855
|
class PNumericType < PScalarDataType
|
@@ -839,7 +863,7 @@ class PNumericType < PScalarDataType
|
|
839
863
|
def self.new_function(type)
|
840
864
|
@new_function ||= Puppet::Functions.create_loaded_function(:new_numeric, type.loader) do
|
841
865
|
local_types do
|
842
|
-
type
|
866
|
+
type "Convertible = Variant[Integer, Float, Boolean, Pattern[/#{FLOAT_PATTERN}/], Timespan, Timestamp]"
|
843
867
|
type 'NamedArgs = Struct[{from => Convertible, Optional[abs] => Boolean}]'
|
844
868
|
end
|
845
869
|
|
@@ -852,6 +876,11 @@ class PNumericType < PScalarDataType
|
|
852
876
|
param 'NamedArgs', :hash_args
|
853
877
|
end
|
854
878
|
|
879
|
+
argument_mismatch :on_error do
|
880
|
+
param 'Any', :from
|
881
|
+
optional_param 'Boolean', :abs
|
882
|
+
end
|
883
|
+
|
855
884
|
def from_args(from, abs = false)
|
856
885
|
result = from_convertible(from)
|
857
886
|
abs ? result.abs : result
|
@@ -863,8 +892,6 @@ class PNumericType < PScalarDataType
|
|
863
892
|
|
864
893
|
def from_convertible(from)
|
865
894
|
case from
|
866
|
-
when NilClass
|
867
|
-
throw :undefined_value
|
868
895
|
when Float
|
869
896
|
from
|
870
897
|
when Integer
|
@@ -875,7 +902,7 @@ class PNumericType < PScalarDataType
|
|
875
902
|
1
|
876
903
|
when FalseClass
|
877
904
|
0
|
878
|
-
|
905
|
+
else
|
879
906
|
begin
|
880
907
|
if from[0] == '0' && (from[1].downcase == 'b' || from[1].downcase == 'x')
|
881
908
|
Integer(from)
|
@@ -887,9 +914,15 @@ class PNumericType < PScalarDataType
|
|
887
914
|
rescue ArgumentError => e
|
888
915
|
raise TypeConversionError.new(e.message)
|
889
916
|
end
|
917
|
+
end
|
918
|
+
end
|
919
|
+
|
920
|
+
def on_error(from, abs = false)
|
921
|
+
if from.is_a?(String)
|
922
|
+
_("The string '%{str}' cannot be converted to Numeric") % { str: from }
|
890
923
|
else
|
891
|
-
t =
|
892
|
-
|
924
|
+
t = TypeCalculator.singleton.infer(from).generalize
|
925
|
+
_("Value of type %{type} cannot be converted to Numeric") % { type: t }
|
893
926
|
end
|
894
927
|
end
|
895
928
|
end
|
@@ -945,7 +978,7 @@ class PNumericType < PScalarDataType
|
|
945
978
|
end
|
946
979
|
|
947
980
|
def instance?(o, guard = nil)
|
948
|
-
o.is_a?(
|
981
|
+
(o.is_a?(Float) || o.is_a?(Integer)) && o >= @from && o <= @to
|
949
982
|
end
|
950
983
|
|
951
984
|
def unbounded?
|
@@ -1050,7 +1083,7 @@ class PIntegerType < PNumericType
|
|
1050
1083
|
@@new_function ||= Puppet::Functions.create_loaded_function(:new, loader) do
|
1051
1084
|
local_types do
|
1052
1085
|
type 'Radix = Variant[Default, Integer[2,2], Integer[8,8], Integer[10,10], Integer[16,16]]'
|
1053
|
-
type
|
1086
|
+
type "Convertible = Variant[Numeric, Boolean, Pattern[/#{INTEGER_PATTERN}/], Timespan, Timestamp]"
|
1054
1087
|
type 'NamedArgs = Struct[{from => Convertible, Optional[radix] => Radix, Optional[abs] => Boolean}]'
|
1055
1088
|
end
|
1056
1089
|
|
@@ -1064,6 +1097,16 @@ class PIntegerType < PNumericType
|
|
1064
1097
|
param 'NamedArgs', :hash_args
|
1065
1098
|
end
|
1066
1099
|
|
1100
|
+
argument_mismatch :on_error_hash do
|
1101
|
+
param 'Hash', :hash_args
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
argument_mismatch :on_error do
|
1105
|
+
param 'Any', :from
|
1106
|
+
optional_param 'Integer', :radix
|
1107
|
+
optional_param 'Boolean', :abs
|
1108
|
+
end
|
1109
|
+
|
1067
1110
|
def from_args(from, radix = :default, abs = false)
|
1068
1111
|
result = from_convertible(from, radix)
|
1069
1112
|
abs ? result.abs : result
|
@@ -1075,8 +1118,6 @@ class PIntegerType < PNumericType
|
|
1075
1118
|
|
1076
1119
|
def from_convertible(from, radix)
|
1077
1120
|
case from
|
1078
|
-
when NilClass
|
1079
|
-
throw :undefined_value
|
1080
1121
|
when Float, Time::TimeData
|
1081
1122
|
from.to_i
|
1082
1123
|
when Integer
|
@@ -1085,9 +1126,9 @@ class PIntegerType < PNumericType
|
|
1085
1126
|
1
|
1086
1127
|
when FalseClass
|
1087
1128
|
0
|
1088
|
-
|
1129
|
+
else
|
1089
1130
|
begin
|
1090
|
-
radix == :default ? Integer(from) : Integer(from,
|
1131
|
+
radix == :default ? Integer(from) : Integer(from, radix)
|
1091
1132
|
rescue TypeError => e
|
1092
1133
|
raise TypeConversionError.new(e.message)
|
1093
1134
|
rescue ArgumentError => e
|
@@ -1103,17 +1144,34 @@ class PIntegerType < PNumericType
|
|
1103
1144
|
end
|
1104
1145
|
raise TypeConversionError.new(e.message)
|
1105
1146
|
end
|
1147
|
+
end
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
def on_error_hash(args_hash)
|
1151
|
+
if args_hash.include?('from')
|
1152
|
+
from = args_hash['from']
|
1153
|
+
return on_error(from) unless loader.load(:type, 'convertible').instance?(from)
|
1154
|
+
end
|
1155
|
+
radix = args_hash['radix']
|
1156
|
+
assert_radix(radix) unless radix.nil? || radix == :default
|
1157
|
+
TypeAsserter.assert_instance_of('Integer.new', loader.load(:type, 'namedargs'), args_hash)
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
def on_error(from, radix = :default, abs = nil)
|
1161
|
+
assert_radix(radix) unless radix == :default
|
1162
|
+
if from.is_a?(String)
|
1163
|
+
_("The string '%{str}' cannot be converted to Integer") % { str: from }
|
1106
1164
|
else
|
1107
|
-
t =
|
1108
|
-
|
1165
|
+
t = TypeCalculator.singleton.infer(from).generalize
|
1166
|
+
_("Value of type %{type} cannot be converted to Integer") % { type: t }
|
1109
1167
|
end
|
1110
1168
|
end
|
1111
1169
|
|
1112
1170
|
def assert_radix(radix)
|
1113
1171
|
case radix
|
1114
|
-
when 2, 8, 10, 16
|
1172
|
+
when 2, 8, 10, 16
|
1115
1173
|
else
|
1116
|
-
raise ArgumentError.new("Illegal radix:
|
1174
|
+
raise ArgumentError.new(_("Illegal radix: %{radix}, expected 2, 8, 10, 16, or default") % { radix: radix })
|
1117
1175
|
end
|
1118
1176
|
radix
|
1119
1177
|
end
|
@@ -1160,7 +1218,7 @@ class PFloatType < PNumericType
|
|
1160
1218
|
def self.new_function(type)
|
1161
1219
|
@new_function ||= Puppet::Functions.create_loaded_function(:new_float, type.loader) do
|
1162
1220
|
local_types do
|
1163
|
-
type
|
1221
|
+
type "Convertible = Variant[Numeric, Boolean, Pattern[/#{FLOAT_PATTERN}/], Timespan, Timestamp]"
|
1164
1222
|
type 'NamedArgs = Struct[{from => Convertible, Optional[abs] => Boolean}]'
|
1165
1223
|
end
|
1166
1224
|
|
@@ -1173,6 +1231,11 @@ class PFloatType < PNumericType
|
|
1173
1231
|
param 'NamedArgs', :hash_args
|
1174
1232
|
end
|
1175
1233
|
|
1234
|
+
argument_mismatch :on_error do
|
1235
|
+
param 'Any', :from
|
1236
|
+
optional_param 'Boolean', :abs
|
1237
|
+
end
|
1238
|
+
|
1176
1239
|
def from_args(from, abs = false)
|
1177
1240
|
result = from_convertible(from)
|
1178
1241
|
abs ? result.abs : result
|
@@ -1184,8 +1247,6 @@ class PFloatType < PNumericType
|
|
1184
1247
|
|
1185
1248
|
def from_convertible(from)
|
1186
1249
|
case from
|
1187
|
-
when NilClass
|
1188
|
-
throw :undefined_value
|
1189
1250
|
when Float
|
1190
1251
|
from
|
1191
1252
|
when Integer
|
@@ -1196,7 +1257,7 @@ class PFloatType < PNumericType
|
|
1196
1257
|
1.0
|
1197
1258
|
when FalseClass
|
1198
1259
|
0.0
|
1199
|
-
|
1260
|
+
else
|
1200
1261
|
begin
|
1201
1262
|
# support a binary as float
|
1202
1263
|
if from[0] == '0' && from[1].downcase == 'b'
|
@@ -1218,9 +1279,15 @@ class PFloatType < PNumericType
|
|
1218
1279
|
end
|
1219
1280
|
raise TypeConversionError.new(e.message)
|
1220
1281
|
end
|
1282
|
+
end
|
1283
|
+
end
|
1284
|
+
|
1285
|
+
def on_error(from, _ = false)
|
1286
|
+
if from.is_a?(String)
|
1287
|
+
_("The string '%{str}' cannot be converted to Float") % { str: from }
|
1221
1288
|
else
|
1222
|
-
t =
|
1223
|
-
|
1289
|
+
t = TypeCalculator.singleton.infer(from).generalize
|
1290
|
+
_("Value of type %{type} cannot be converted to Float") % { type: t }
|
1224
1291
|
end
|
1225
1292
|
end
|
1226
1293
|
end
|
@@ -1577,7 +1644,7 @@ class PStringType < PScalarDataType
|
|
1577
1644
|
# Must match exactly when value is a string
|
1578
1645
|
@size_type_or_value.nil? || @size_type_or_value == o.size_type_or_value
|
1579
1646
|
when PEnumType
|
1580
|
-
@size_type_or_value.nil? ? true : o.values.size == 1 &&
|
1647
|
+
@size_type_or_value.nil? ? true : o.values.size == 1 && !o.case_insensitive? && o.values[0]
|
1581
1648
|
when PPatternType
|
1582
1649
|
@size_type_or_value.nil?
|
1583
1650
|
else
|
@@ -1786,46 +1853,73 @@ class PBooleanType < PScalarDataType
|
|
1786
1853
|
create_ptype(loader, ir, 'ScalarDataType')
|
1787
1854
|
end
|
1788
1855
|
|
1856
|
+
attr_reader :value
|
1857
|
+
|
1858
|
+
def initialize(value = nil)
|
1859
|
+
@value = value
|
1860
|
+
end
|
1861
|
+
|
1862
|
+
def eql?(o)
|
1863
|
+
o.is_a?(PBooleanType) && @value == o.value
|
1864
|
+
end
|
1865
|
+
|
1866
|
+
def generalize
|
1867
|
+
PBooleanType::DEFAULT
|
1868
|
+
end
|
1869
|
+
|
1870
|
+
def hash
|
1871
|
+
31 ^ @value.hash
|
1872
|
+
end
|
1873
|
+
|
1789
1874
|
def instance?(o, guard = nil)
|
1790
|
-
o == true || o == false
|
1875
|
+
(o == true || o == false) && (@value.nil? || value == o)
|
1791
1876
|
end
|
1792
1877
|
|
1793
1878
|
def self.new_function(type)
|
1794
1879
|
@new_function ||= Puppet::Functions.create_loaded_function(:new_boolean, type.loader) do
|
1795
1880
|
dispatch :from_args do
|
1796
|
-
param
|
1881
|
+
param "Variant[Integer, Float, Boolean, Enum['false','true','yes','no','y','n',true]]", :from
|
1882
|
+
end
|
1883
|
+
|
1884
|
+
argument_mismatch :on_error do
|
1885
|
+
param 'Any', :from
|
1797
1886
|
end
|
1798
1887
|
|
1799
1888
|
def from_args(from)
|
1800
1889
|
from = from.downcase if from.is_a?(String)
|
1801
1890
|
case from
|
1802
|
-
when NilClass
|
1803
|
-
throw :undefined_value
|
1804
1891
|
when Float
|
1805
1892
|
from != 0.0
|
1806
1893
|
when Integer
|
1807
1894
|
from != 0
|
1808
|
-
when
|
1809
|
-
from
|
1810
|
-
when 'false', 'no', 'n'
|
1895
|
+
when false, 'false', 'no', 'n'
|
1811
1896
|
false
|
1812
|
-
|
1897
|
+
else
|
1813
1898
|
true
|
1899
|
+
end
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
def on_error(from)
|
1903
|
+
if from.is_a?(String)
|
1904
|
+
_("The string '%{str}' cannot be converted to Boolean") % { str: from }
|
1814
1905
|
else
|
1815
|
-
|
1906
|
+
t = TypeCalculator.singleton.infer(from).generalize
|
1907
|
+
_("Value of type %{type} cannot be converted to Boolean") % { type: t }
|
1816
1908
|
end
|
1817
1909
|
end
|
1818
1910
|
end
|
1819
1911
|
end
|
1820
1912
|
|
1821
1913
|
DEFAULT = PBooleanType.new
|
1914
|
+
TRUE = PBooleanType.new(true)
|
1915
|
+
FALSE = PBooleanType.new(false)
|
1822
1916
|
|
1823
1917
|
protected
|
1824
1918
|
|
1825
1919
|
# @api private
|
1826
1920
|
#
|
1827
1921
|
def _assignable?(o, guard)
|
1828
|
-
o.is_a?(PBooleanType)
|
1922
|
+
o.is_a?(PBooleanType) && (@value.nil? || @value == o.value)
|
1829
1923
|
end
|
1830
1924
|
end
|
1831
1925
|
|
@@ -2504,41 +2598,43 @@ class PArrayType < PCollectionType
|
|
2504
2598
|
def self.new_function(type)
|
2505
2599
|
@new_function ||= Puppet::Functions.create_loaded_function(:new_array, type.loader) do
|
2506
2600
|
|
2507
|
-
dispatch :
|
2508
|
-
param '
|
2509
|
-
optional_param 'Boolean',
|
2601
|
+
dispatch :to_array do
|
2602
|
+
param 'Variant[Array,Hash,Binary,Iterable]', :from
|
2603
|
+
optional_param 'Boolean[false]', :wrap
|
2604
|
+
end
|
2605
|
+
|
2606
|
+
dispatch :wrapped do
|
2607
|
+
param 'Any', :from
|
2608
|
+
param 'Boolean[true]', :wrap
|
2609
|
+
end
|
2610
|
+
|
2611
|
+
argument_mismatch :on_error do
|
2612
|
+
param 'Any', :from
|
2613
|
+
optional_param 'Boolean', :wrap
|
2510
2614
|
end
|
2511
2615
|
|
2512
|
-
def
|
2616
|
+
def wrapped(from, _)
|
2617
|
+
from.is_a?(Array) ? from : [from]
|
2618
|
+
end
|
2619
|
+
|
2620
|
+
def to_array(from, _ = false)
|
2513
2621
|
case from
|
2514
|
-
when NilClass
|
2515
|
-
if wrap
|
2516
|
-
[nil]
|
2517
|
-
else
|
2518
|
-
throw :undefined_value
|
2519
|
-
end
|
2520
2622
|
when Array
|
2521
2623
|
from
|
2522
2624
|
when Hash
|
2523
|
-
|
2524
|
-
|
2625
|
+
from.to_a
|
2525
2626
|
when PBinaryType::Binary
|
2526
2627
|
# For older rubies, the #bytes method returns an Enumerator that must be rolled out
|
2527
|
-
|
2528
|
-
|
2628
|
+
from.binary_buffer.bytes.to_a
|
2529
2629
|
else
|
2530
|
-
|
2531
|
-
[from]
|
2532
|
-
else
|
2533
|
-
if PIterableType::DEFAULT.instance?(from)
|
2534
|
-
Iterable.on(from).to_a
|
2535
|
-
else
|
2536
|
-
t = Puppet::Pops::Types::TypeCalculator.singleton.infer(from).generalize
|
2537
|
-
raise TypeConversionError.new("Value of type '#{t}' cannot be converted to Array")
|
2538
|
-
end
|
2539
|
-
end
|
2630
|
+
Iterable.on(from).to_a
|
2540
2631
|
end
|
2541
2632
|
end
|
2633
|
+
|
2634
|
+
def on_error(from, _ = false)
|
2635
|
+
t = TypeCalculator.singleton.infer(from).generalize
|
2636
|
+
_("Value of type %{type} cannot be converted to Array") % { type: t }
|
2637
|
+
end
|
2542
2638
|
end
|
2543
2639
|
end
|
2544
2640
|
|
@@ -2738,14 +2834,12 @@ class PHashType < PCollectionType
|
|
2738
2834
|
|
2739
2835
|
def from_array(from)
|
2740
2836
|
case from
|
2741
|
-
when NilClass
|
2742
|
-
throw :undefined_value
|
2743
2837
|
when Array
|
2744
2838
|
if from.size == 0
|
2745
2839
|
{}
|
2746
2840
|
else
|
2747
2841
|
unless from.size % 2 == 0
|
2748
|
-
raise TypeConversionError.new(
|
2842
|
+
raise TypeConversionError.new(_('odd number of arguments for Hash'))
|
2749
2843
|
end
|
2750
2844
|
Hash[*from]
|
2751
2845
|
end
|
@@ -2755,8 +2849,8 @@ class PHashType < PCollectionType
|
|
2755
2849
|
if PIterableType::DEFAULT.instance?(from)
|
2756
2850
|
Hash[*Iterable.on(from).to_a]
|
2757
2851
|
else
|
2758
|
-
t =
|
2759
|
-
raise TypeConversionError.new("Value of type
|
2852
|
+
t = TypeCalculator.singleton.infer(from).generalize
|
2853
|
+
raise TypeConversionError.new(_("Value of type %{type} cannot be converted to Hash") % { type: t })
|
2760
2854
|
end
|
2761
2855
|
end
|
2762
2856
|
end
|
@@ -2948,8 +3042,9 @@ class PVariantType < PAnyType
|
|
2948
3042
|
|
2949
3043
|
# @api private
|
2950
3044
|
def merge_enums(array)
|
3045
|
+
# Merge case sensitive enums and strings
|
2951
3046
|
if array.size > 1
|
2952
|
-
parts = array.partition {|t| t.is_a?(PEnumType) && !t.values.empty? || t.is_a?(PStringType) && !t.value.nil? }
|
3047
|
+
parts = array.partition {|t| t.is_a?(PEnumType) && !t.values.empty? && !t.case_insensitive? || t.is_a?(PStringType) && !t.value.nil? }
|
2953
3048
|
enums = parts[0]
|
2954
3049
|
if enums.size > 1
|
2955
3050
|
others = parts[1]
|
@@ -2957,6 +3052,20 @@ class PVariantType < PAnyType
|
|
2957
3052
|
array = others
|
2958
3053
|
end
|
2959
3054
|
end
|
3055
|
+
|
3056
|
+
# Merge case insensitive enums
|
3057
|
+
if array.size > 1
|
3058
|
+
parts = array.partition {|t| t.is_a?(PEnumType) && !t.values.empty? && t.case_insensitive? }
|
3059
|
+
enums = parts[0]
|
3060
|
+
if enums.size > 1
|
3061
|
+
others = parts[1]
|
3062
|
+
values = []
|
3063
|
+
enums.each { |enum| enum.values.each { |value| values << value.downcase }}
|
3064
|
+
values.uniq!
|
3065
|
+
others << PEnumType.new(values, true)
|
3066
|
+
array = others
|
3067
|
+
end
|
3068
|
+
end
|
2960
3069
|
array
|
2961
3070
|
end
|
2962
3071
|
|
@@ -3513,7 +3622,7 @@ require_relative 'p_timespan_type'
|
|
3513
3622
|
require_relative 'p_timestamp_type'
|
3514
3623
|
require_relative 'p_binary_type'
|
3515
3624
|
require_relative 'p_init_type'
|
3516
|
-
require_relative '
|
3625
|
+
require_relative 'p_object_type_extension'
|
3517
3626
|
require_relative 'type_set_reference'
|
3518
3627
|
require_relative 'implementation_registry'
|
3519
3628
|
require_relative 'tree_iterators'
|