kafo 0.9.8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -8
- data/lib/kafo/data_type.rb +100 -0
- data/lib/kafo/data_types/any.rb +8 -0
- data/lib/kafo/data_types/array.rb +62 -0
- data/lib/kafo/data_types/boolean.rb +24 -0
- data/lib/kafo/data_types/enum.rb +25 -0
- data/lib/kafo/data_types/float.rb +40 -0
- data/lib/kafo/data_types/hash.rb +70 -0
- data/lib/kafo/data_types/integer.rb +40 -0
- data/lib/kafo/data_types/not_undef.rb +34 -0
- data/lib/kafo/data_types/numeric.rb +16 -0
- data/lib/kafo/data_types/optional.rb +34 -0
- data/lib/kafo/data_types/pattern.rb +29 -0
- data/lib/kafo/data_types/regexp.rb +14 -0
- data/lib/kafo/data_types/scalar.rb +14 -0
- data/lib/kafo/data_types/string.rb +36 -0
- data/lib/kafo/data_types/struct.rb +100 -0
- data/lib/kafo/data_types/tuple.rb +76 -0
- data/lib/kafo/data_types/type_reference.rb +14 -0
- data/lib/kafo/data_types/undef.rb +12 -0
- data/lib/kafo/data_types/variant.rb +50 -0
- data/lib/kafo/hook_context.rb +2 -0
- data/lib/kafo/kafo_configure.rb +1 -5
- data/lib/kafo/param.rb +19 -33
- data/lib/kafo/param_builder.rb +8 -6
- data/lib/kafo/params/password.rb +0 -8
- data/lib/kafo/version.rb +1 -1
- data/lib/kafo/wizard.rb +1 -0
- metadata +22 -7
- data/lib/kafo/params/array.rb +0 -28
- data/lib/kafo/params/boolean.rb +0 -27
- data/lib/kafo/params/hash.rb +0 -38
- data/lib/kafo/params/integer.rb +0 -19
- data/lib/kafo/params/string.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37920206589ad542c671af010f5b8dd1bb02dff0
|
4
|
+
data.tar.gz: 3e001186cf0bd9f809a28d92e5223d6345e264e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c59eac78e4965f90f98b1bab03275aa2044e724f71e7ed3f90339e7dbc0201812d3cb04bf1ddd0b3b390a309a1c3455620bcd961cadba6fcca01c9b6e581a9f1
|
7
|
+
data.tar.gz: 797b544447e37f68faf90fe2a54afd033bda2254fa27d18b7c93d1c9ba453644db8b0c145ce9588e5c146507eebdaa60f59ac3321ad379d6f1b64fa3587f05a9
|
data/README.md
CHANGED
@@ -400,10 +400,10 @@ Example:
|
|
400
400
|
#
|
401
401
|
# $enc:: Should foreman act as an external node classifier (manage puppet class
|
402
402
|
# assignments)
|
403
|
-
#
|
403
|
+
#
|
404
404
|
class foreman (
|
405
|
-
$foreman_url
|
406
|
-
$enc
|
405
|
+
String $foreman_url = $foreman::params::foreman_url,
|
406
|
+
Boolean $enc = $foreman::params::enc
|
407
407
|
) {
|
408
408
|
class { 'foreman::install': }
|
409
409
|
}
|
@@ -445,20 +445,45 @@ the particular parameter belongs.
|
|
445
445
|
|
446
446
|
## Argument types
|
447
447
|
|
448
|
-
|
449
|
-
|
450
|
-
|
448
|
+
When using Puppet 4 or newer, the data type will be read from the parameter
|
449
|
+
list and defaults to Puppet's [Any](https://docs.puppet.com/puppet/latest/reference/lang_data_abstract.html#any)
|
450
|
+
data type, which Kafo handles as a basic string with no validation.
|
451
|
+
|
452
|
+
If more specific data types, such as `Optional[Array[2]]` or similar are
|
453
|
+
given in the [parameter list](https://docs.puppet.com/puppet/4.5/reference/lang_data_type.html#usage)
|
454
|
+
then Kafo will parse and validate parameters values according to the
|
455
|
+
specification.
|
456
|
+
|
457
|
+
```puppet
|
458
|
+
class example (
|
459
|
+
Boolean $param = false
|
460
|
+
) {
|
461
|
+
```
|
462
|
+
|
463
|
+
When using Puppet 3, data types can be specified in the manifest documentation
|
464
|
+
rather than the parameter list, like this:
|
451
465
|
|
452
466
|
```puppet
|
453
467
|
# $param:: Some documentation for param
|
454
|
-
type:
|
468
|
+
type:Array[String]
|
455
469
|
```
|
456
470
|
|
457
|
-
|
471
|
+
For compatibility with older Kafo releases, additional types are supported:
|
472
|
+
string, boolean, integer, array, password, hash. These are equivalent to their
|
473
|
+
Puppet 4 namesakes, plus wrapped in `Optional[..]` to permit `undef`.
|
474
|
+
|
475
|
+
If the data type is given in both the manifest documentation and the parameter
|
476
|
+
list, then the manifest documentation will be preferred.
|
458
477
|
|
459
478
|
Note that all arguments that are nil (have no value in answers.yaml or you
|
460
479
|
set them UNDEF (see below)) are translated to ```undef``` in puppet.
|
461
480
|
|
481
|
+
If your module declares its own types, you can add new corresponding subclasses
|
482
|
+
of DataType which implement validation and typecasting. This can be added to a
|
483
|
+
`boot` hook by calling:
|
484
|
+
|
485
|
+
Kafo::DataType.register_type('YourType', Kafo::DataType::YourType)
|
486
|
+
|
462
487
|
## Password arguments
|
463
488
|
|
464
489
|
Kafo supports password arguments. It's adding some level of protection for your
|
@@ -704,6 +729,10 @@ you must follow a few rules however:
|
|
704
729
|
These functions are re-implemented in Kafo from common stdlib functions, so please
|
705
730
|
contribute any missing ones.
|
706
731
|
|
732
|
+
If class parameters are declared with Puppet 4 data types then Kafo will
|
733
|
+
validate user inputs against Puppet's type validation rules, which should
|
734
|
+
replace the use of separate validation functions.
|
735
|
+
|
707
736
|
## Enabling or disabling module
|
708
737
|
|
709
738
|
You can enable or disable a module specified in the answers.yaml file. Every module
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Kafo
|
2
|
+
class DataType
|
3
|
+
def self.new_from_string(str)
|
4
|
+
keyword_re = /\A([\w:]+)(?:\[(.*)\])?\z/m.match(str)
|
5
|
+
if keyword_re
|
6
|
+
if (type = @keywords[keyword_re[1]])
|
7
|
+
args = if keyword_re[2]
|
8
|
+
hash_re = keyword_re[2].match(/\A\s*{(.*)}\s*\z/m)
|
9
|
+
if hash_re
|
10
|
+
[parse_hash(hash_re[1])]
|
11
|
+
else
|
12
|
+
split_arguments(keyword_re[2])
|
13
|
+
end
|
14
|
+
else
|
15
|
+
[]
|
16
|
+
end
|
17
|
+
type.new(*args)
|
18
|
+
elsif ['Data'].include?(keyword_re[1])
|
19
|
+
DataTypes::Any.new
|
20
|
+
elsif keyword_re[1] == 'Default'
|
21
|
+
DataTypes::Enum.new('default')
|
22
|
+
elsif @keywords[keyword_re[1].capitalize] # pre-Puppet 4 data types
|
23
|
+
DataTypes::Optional.new(keyword_re[1].capitalize)
|
24
|
+
else
|
25
|
+
raise ConfigurationException, "unknown data type #{keyword_re[1]}"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
raise ConfigurationException, "data type not recognized #{str}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.register_type(keyword, type)
|
33
|
+
@keywords ||= {}
|
34
|
+
raise ArgumentError, "Data type #{keyword} is already registered, cannot be re-registered" if @keywords.has_key?(keyword)
|
35
|
+
@keywords[keyword] = type
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.types
|
39
|
+
@keywords ? @keywords.keys : []
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.unregister_type(keyword)
|
43
|
+
@keywords.delete(keyword) if @keywords
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.split_arguments(input)
|
47
|
+
input.scan(%r{\s*["'/]?([\w:]+(?:\[.+\])?|.+?)["'/]?\s*(?:,|$)}m).flatten
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.parse_hash(input)
|
51
|
+
Hash[input.scan(%r{\s*["'/]?([\w:]+(?:\[[^\]]+\])?|.+?)["'/]?\s*=>\s*["'/]?([\w:]+(?:\[[^\]]+\])?|.+?)["'/]?\s*(?:,|$)}m)]
|
52
|
+
end
|
53
|
+
|
54
|
+
# public interface
|
55
|
+
|
56
|
+
def condition_value(value)
|
57
|
+
value.inspect
|
58
|
+
end
|
59
|
+
|
60
|
+
def dump_default(value)
|
61
|
+
%{"#{value}"}
|
62
|
+
end
|
63
|
+
|
64
|
+
def multivalued?
|
65
|
+
false
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
self.class.name.split('::').last.downcase
|
70
|
+
end
|
71
|
+
|
72
|
+
def typecast(value)
|
73
|
+
value == 'UNDEF' ? nil : value
|
74
|
+
end
|
75
|
+
|
76
|
+
def valid?(value, errors = [])
|
77
|
+
true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
require 'kafo/data_types/any'
|
83
|
+
require 'kafo/data_types/array'
|
84
|
+
require 'kafo/data_types/boolean'
|
85
|
+
require 'kafo/data_types/enum'
|
86
|
+
require 'kafo/data_types/float'
|
87
|
+
require 'kafo/data_types/hash'
|
88
|
+
require 'kafo/data_types/integer'
|
89
|
+
require 'kafo/data_types/not_undef'
|
90
|
+
require 'kafo/data_types/numeric'
|
91
|
+
require 'kafo/data_types/optional'
|
92
|
+
require 'kafo/data_types/pattern'
|
93
|
+
require 'kafo/data_types/regexp'
|
94
|
+
require 'kafo/data_types/scalar'
|
95
|
+
require 'kafo/data_types/string'
|
96
|
+
require 'kafo/data_types/struct'
|
97
|
+
require 'kafo/data_types/tuple'
|
98
|
+
require 'kafo/data_types/type_reference'
|
99
|
+
require 'kafo/data_types/undef'
|
100
|
+
require 'kafo/data_types/variant'
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Array < DataType
|
4
|
+
def initialize(inner_type = 'Data', min = :default, max = :default)
|
5
|
+
@inner_type = DataType.new_from_string(inner_type)
|
6
|
+
@min = (min.to_s == 'default') ? 0 : min.to_i
|
7
|
+
@max = (max.to_s == 'default') ? :infinite : max.to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
def condition_value(value)
|
11
|
+
"[ #{value.map { |v| @inner_type.condition_value(v) }.join(', ')} ]"
|
12
|
+
end
|
13
|
+
|
14
|
+
def multivalued?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
type = "array of #{@inner_type}"
|
20
|
+
if @min > 0 && @max == :infinite
|
21
|
+
"#{type} (at least #{@min} items)"
|
22
|
+
elsif @min == 0 && @max != :infinite
|
23
|
+
"#{type} (up to #{@max} items)"
|
24
|
+
elsif @min > 0 && @max != :infinite
|
25
|
+
"#{type} (between #{@min} and #{@max} items)"
|
26
|
+
else
|
27
|
+
type
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def typecast(value)
|
32
|
+
if value.nil?
|
33
|
+
nil
|
34
|
+
elsif value == ['EMPTY_ARRAY']
|
35
|
+
[]
|
36
|
+
else
|
37
|
+
[value].flatten.map { |v| @inner_type.typecast(v) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def valid?(input, errors = [])
|
42
|
+
unless input.is_a?(::Array)
|
43
|
+
errors << "#{input.inspect} is not a valid array"
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
|
47
|
+
inner_errors = []
|
48
|
+
input.each { |v| @inner_type.valid?(v, inner_errors) }
|
49
|
+
unless inner_errors.empty?
|
50
|
+
errors << "Elements of the array are invalid: #{inner_errors.join(', ')}"
|
51
|
+
end
|
52
|
+
|
53
|
+
errors << "The array must have at least #{@min} items" if input.size < @min
|
54
|
+
errors << "The array must have at maximum #{@max} items" if @max != :infinite && input.size > @max
|
55
|
+
|
56
|
+
return errors.empty?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
DataType.register_type('Array', Array)
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Boolean < DataType
|
4
|
+
def typecast(value)
|
5
|
+
case value
|
6
|
+
when '0', 'false', 'f', 'n', false
|
7
|
+
false
|
8
|
+
when '1', 'true', 't', 'y', true
|
9
|
+
true
|
10
|
+
else
|
11
|
+
value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid?(input, errors = [])
|
16
|
+
(input.is_a?(::TrueClass) || input.is_a?(::FalseClass)).tap do |valid|
|
17
|
+
errors << "#{input.inspect} is not a valid boolean" unless valid
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
DataType.register_type('Boolean', Boolean)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Enum < DataType
|
4
|
+
def initialize(*permitted)
|
5
|
+
@permitted = permitted
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
@permitted.map(&:inspect).join(' or ')
|
10
|
+
end
|
11
|
+
|
12
|
+
def valid?(input, errors = [])
|
13
|
+
unless input.is_a?(::String)
|
14
|
+
errors << "#{input.inspect} is not a valid string"
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
|
18
|
+
errors << "#{input} must be one of #{@permitted.join(', ')}" unless @permitted.include?(input)
|
19
|
+
return errors.empty?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
DataType.register_type('Enum', Enum)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Float < DataType
|
4
|
+
def initialize(min = :default, max = :default)
|
5
|
+
@min = (min.to_s == 'default') ? :infinite : min.to_i
|
6
|
+
@max = (max.to_s == 'default') ? :infinite : max.to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
if @min != :infinite && @max == :infinite
|
11
|
+
"float (at least #{@min})"
|
12
|
+
elsif @min == :infinite && @max != :infinite
|
13
|
+
"float (up to #{@max})"
|
14
|
+
elsif @min != :infinite && @max != :infinite
|
15
|
+
"float (between #{@min} and #{@max})"
|
16
|
+
else
|
17
|
+
"float"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def typecast(value)
|
22
|
+
value.to_s =~ /\d+/ ? value.to_f : value
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid?(input, errors = [])
|
26
|
+
unless input.is_a?(::Float)
|
27
|
+
errors << "#{input.inspect} is not a valid float"
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
|
31
|
+
errors << "#{input} must be at least #{@min}" if @min != :infinite && input < @min
|
32
|
+
errors << "#{input} must be up to #{@max}" if @max != :infinite && input > @max
|
33
|
+
|
34
|
+
return errors.empty?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
DataType.register_type('Float', Float)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Hash < DataType
|
4
|
+
def initialize(inner_key_type = 'Scalar', inner_value_type = 'Data', min = :default, max = :default)
|
5
|
+
@inner_key_type = DataType.new_from_string(inner_key_type)
|
6
|
+
@inner_value_type = DataType.new_from_string(inner_value_type)
|
7
|
+
@min = (min.to_s == 'default') ? 0 : min.to_i
|
8
|
+
@max = (max.to_s == 'default') ? :infinite : max.to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
def multivalued?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
type = "hash of #{@inner_key_type}/#{@inner_value_type}"
|
17
|
+
if @min > 0 && @max == :infinite
|
18
|
+
"#{type} (at least #{@min} items)"
|
19
|
+
elsif @min == 0 && @max != :infinite
|
20
|
+
"#{type} (up to #{@max} items)"
|
21
|
+
elsif @min > 0 && @max != :infinite
|
22
|
+
"#{type} (between #{@min} and #{@max} items)"
|
23
|
+
else
|
24
|
+
type
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def typecast(value)
|
29
|
+
if value.nil?
|
30
|
+
nil
|
31
|
+
elsif value.is_a?(::Hash)
|
32
|
+
value
|
33
|
+
elsif value == ['EMPTY_HASH']
|
34
|
+
{}
|
35
|
+
else
|
36
|
+
::Hash[[value].flatten.map do |kv|
|
37
|
+
k, v = kv.split(':', 2)
|
38
|
+
[@inner_key_type.typecast(k), @inner_value_type.typecast(v)]
|
39
|
+
end]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid?(input, errors = [])
|
44
|
+
unless input.is_a?(::Hash)
|
45
|
+
errors << "#{input.inspect} is not a valid hash"
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
inner_key_errors = []
|
50
|
+
input.keys.each { |v| @inner_key_type.valid?(v, inner_key_errors) }
|
51
|
+
unless inner_key_errors.empty?
|
52
|
+
errors << "Hash key elements are invalid: #{inner_key_errors.join(', ')}"
|
53
|
+
end
|
54
|
+
|
55
|
+
inner_value_errors = []
|
56
|
+
input.values.each { |v| @inner_value_type.valid?(v, inner_value_errors) }
|
57
|
+
unless inner_value_errors.empty?
|
58
|
+
errors << "Hash value elements are invalid: #{inner_value_errors.join(', ')}"
|
59
|
+
end
|
60
|
+
|
61
|
+
errors << "The hash must have at least #{@min} items" if input.size < @min
|
62
|
+
errors << "The hash must have at maximum #{@max} items" if @max != :infinite && input.size > @max
|
63
|
+
|
64
|
+
return errors.empty?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
DataType.register_type('Hash', Hash)
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Integer < DataType
|
4
|
+
def initialize(min = :default, max = :default)
|
5
|
+
@min = (min.to_s == 'default') ? :infinite : min.to_i
|
6
|
+
@max = (max.to_s == 'default') ? :infinite : max.to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
if @min != :infinite && @max == :infinite
|
11
|
+
"integer (at least #{@min})"
|
12
|
+
elsif @min == :infinite && @max != :infinite
|
13
|
+
"integer (up to #{@max})"
|
14
|
+
elsif @min != :infinite && @max != :infinite
|
15
|
+
"integer (between #{@min} and #{@max})"
|
16
|
+
else
|
17
|
+
"integer"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def typecast(value)
|
22
|
+
value =~ /\d+/ ? value.to_i : value
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid?(input, errors = [])
|
26
|
+
unless input.is_a?(::Integer)
|
27
|
+
errors << "#{input.inspect} is not a valid integer"
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
|
31
|
+
errors << "#{input} must be at least #{@min}" if @min != :infinite && input < @min
|
32
|
+
errors << "#{input} must be up to #{@max}" if @max != :infinite && input > @max
|
33
|
+
|
34
|
+
return errors.empty?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
DataType.register_type('Integer', Integer)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class NotUndef < DataType
|
4
|
+
extend Forwardable
|
5
|
+
def_delegators :@inner_type, :condition_value, :dump_default, :multivalued?, :typecast
|
6
|
+
attr_reader :inner_type, :inner_value
|
7
|
+
|
8
|
+
def initialize(inner_type_or_value)
|
9
|
+
begin
|
10
|
+
@inner_type = DataType.new_from_string(inner_type_or_value)
|
11
|
+
rescue ConfigurationException
|
12
|
+
@inner_value = inner_type_or_value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
if @inner_type
|
18
|
+
"#{@inner_type} but not undef"
|
19
|
+
else
|
20
|
+
"#{@inner_value.inspect} but not undef"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid?(input, errors = [])
|
25
|
+
return false if input.nil?
|
26
|
+
return true if @inner_type && @inner_type.valid?(input, errors)
|
27
|
+
return true if @inner_value && @inner_value == input
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
DataType.register_type('NotUndef', NotUndef)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Numeric < DataType
|
4
|
+
def typecast(value)
|
5
|
+
value =~ /\d+/ ? value.to_f : value
|
6
|
+
end
|
7
|
+
|
8
|
+
def valid?(input, errors = [])
|
9
|
+
errors << "#{input.inspect} is not a valid number" unless input.is_a?(::Integer) || input.is_a?(::Float)
|
10
|
+
return errors.empty?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
DataType.register_type('Numeric', Numeric)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Optional < DataType
|
4
|
+
extend Forwardable
|
5
|
+
def_delegators :@inner_type, :condition_value, :dump_default, :multivalued?, :typecast
|
6
|
+
attr_reader :inner_type, :inner_value
|
7
|
+
|
8
|
+
def initialize(inner_type_or_value)
|
9
|
+
begin
|
10
|
+
@inner_type = DataType.new_from_string(inner_type_or_value)
|
11
|
+
rescue ConfigurationException
|
12
|
+
@inner_value = inner_type_or_value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
if @inner_type
|
18
|
+
"#{@inner_type} or undef"
|
19
|
+
else
|
20
|
+
"#{@inner_value.inspect} or undef"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid?(input, errors = [])
|
25
|
+
return true if input.nil?
|
26
|
+
return true if @inner_type && @inner_type.valid?(input, errors)
|
27
|
+
return true if @inner_value && @inner_value == input
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
DataType.register_type('Optional', Optional)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Pattern < DataType
|
4
|
+
def initialize(*regexes)
|
5
|
+
@regex_strings = regexes
|
6
|
+
@regexes = regexes.map { |r| ::Regexp.new(r) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
"regexes matching #{@regex_strings.map { |r| "/#{r}/" }.join(' or ')}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid?(input, errors = [])
|
14
|
+
unless input.is_a?(::String)
|
15
|
+
errors << "#{input.inspect} is not a valid string"
|
16
|
+
return false
|
17
|
+
end
|
18
|
+
|
19
|
+
unless @regexes.any? { |r| r.match(input) }
|
20
|
+
errors << "#{input} must match one of #{@regexes.join(', ')}"
|
21
|
+
end
|
22
|
+
|
23
|
+
return errors.empty?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
DataType.register_type('Pattern', Pattern)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Regexp < DataType
|
4
|
+
extend Forwardable
|
5
|
+
def_delegators :@inner_type, :condition_value, :dump_default, :multivalued?, :typecast, :valid?
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@inner_type = DataTypes::String.new
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
DataType.register_type('Regexp', Regexp)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Scalar < DataType
|
4
|
+
extend Forwardable
|
5
|
+
def_delegators :@inner_type, :condition_value, :dump_default, :multivalued?, :typecast, :valid?
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@inner_type = DataTypes::Variant.new('Integer', 'Float', 'String', 'Boolean', 'Regexp')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
DataType.register_type('Scalar', Scalar)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class String < DataType
|
4
|
+
def initialize(min = :default, max = :default)
|
5
|
+
@min = (min.to_s == 'default') ? 0 : min.to_i
|
6
|
+
@max = (max.to_s == 'default') ? :infinite : max.to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
if @min > 0 && @max == :infinite
|
11
|
+
"string (at least #{@min} characters)"
|
12
|
+
elsif @min == 0 && @max != :infinite
|
13
|
+
"string (up to #{@max} characters)"
|
14
|
+
elsif @min > 0 && @max != :infinite
|
15
|
+
"string (between #{@min} and #{@max} characters)"
|
16
|
+
else
|
17
|
+
"string"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid?(input, errors = [])
|
22
|
+
unless input.is_a?(::String)
|
23
|
+
errors << "#{input.inspect} is not a valid string"
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
|
27
|
+
errors << "#{input} must be at least #{@min}" if input.size < @min
|
28
|
+
errors << "#{input} must be up to #{@max}" if @max != :infinite && input.size > @max
|
29
|
+
|
30
|
+
return errors.empty?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
DataType.register_type('String', String)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Struct < DataType
|
4
|
+
def initialize(spec)
|
5
|
+
@spec = ::Hash[spec.map do |k,v|
|
6
|
+
begin
|
7
|
+
k = DataType.new_from_string(k)
|
8
|
+
rescue ConfigurationException; end
|
9
|
+
begin
|
10
|
+
v = DataType.new_from_string(v)
|
11
|
+
rescue ConfigurationException; end
|
12
|
+
[k, v]
|
13
|
+
end]
|
14
|
+
end
|
15
|
+
|
16
|
+
def multivalued?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"struct containing " + @spec.keys.map do |k|
|
22
|
+
if k.is_a?(Optional)
|
23
|
+
[k.inner_value, %{"#{k.inner_value}" (optional #{@spec[k]})}]
|
24
|
+
elsif k.is_a?(NotUndef)
|
25
|
+
[k.inner_value, %{"#{k.inner_value}" (required #{@spec[k]})}]
|
26
|
+
else
|
27
|
+
[k, %{"#{k}" (#{@spec[k]})}]
|
28
|
+
end
|
29
|
+
end.sort_by(&:first).map(&:last).join(', ')
|
30
|
+
end
|
31
|
+
|
32
|
+
def typecast(value)
|
33
|
+
if value.nil?
|
34
|
+
nil
|
35
|
+
elsif value.is_a?(::Hash)
|
36
|
+
value
|
37
|
+
elsif value == ['EMPTY_HASH']
|
38
|
+
{}
|
39
|
+
else
|
40
|
+
::Hash[[value].flatten.map do |kv|
|
41
|
+
k, v = kv.split(':', 2)
|
42
|
+
if (value_type = spec_value(k))
|
43
|
+
[k, value_type.typecast(v)]
|
44
|
+
else
|
45
|
+
[k, v]
|
46
|
+
end
|
47
|
+
end]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def valid?(input, errors = [])
|
52
|
+
unless input.is_a?(::Hash)
|
53
|
+
errors << "#{input.inspect} is not a valid struct"
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
|
57
|
+
required_keys = @spec.keys.select { |k| k.is_a?(NotUndef) }.map { |k| k.inner_value }
|
58
|
+
missing_keys = required_keys - input.keys
|
59
|
+
errors << "Struct elements are missing: #{missing_keys.join(', ')}" unless missing_keys.empty?
|
60
|
+
|
61
|
+
known_keys = @spec.keys.map { |k| spec_key_name(k) }
|
62
|
+
extra_keys = input.keys - known_keys
|
63
|
+
errors << "Struct elements are not permitted: #{extra_keys.join(', ')}" unless extra_keys.empty?
|
64
|
+
|
65
|
+
value_errors = []
|
66
|
+
|
67
|
+
# Only check values for optional keys if present
|
68
|
+
optional_keys = @spec.keys.select { |k| k.is_a?(Optional) }.map { |k| k.inner_value }
|
69
|
+
(optional_keys & input.keys).each { |k| spec_value(k).valid?(input[k], value_errors) }
|
70
|
+
|
71
|
+
# For non-optional and non-required keys, assume nil/undef values if absent
|
72
|
+
regular_keys = @spec.keys.select { |k| !k.is_a?(Optional) }.map { |k| spec_key_name(k) }
|
73
|
+
regular_keys.each { |k| spec_value(k).valid?(input[k], value_errors) }
|
74
|
+
|
75
|
+
errors << "Struct values are invalid: #{value_errors.join(', ')}" unless value_errors.empty?
|
76
|
+
|
77
|
+
return errors.empty?
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def spec_value(key)
|
83
|
+
spec_entry = @spec.find do |k,v|
|
84
|
+
spec_key_name(k) == key
|
85
|
+
end
|
86
|
+
spec_entry ? spec_entry.last : nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def spec_key_name(key)
|
90
|
+
if key.is_a?(Optional) || key.is_a?(NotUndef)
|
91
|
+
key.inner_value
|
92
|
+
else
|
93
|
+
key
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
DataType.register_type('Struct', Struct)
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Tuple < DataType
|
4
|
+
def initialize(*args)
|
5
|
+
if args.last.to_s =~ /\d+/ || args.last.to_s == 'default'
|
6
|
+
max = args.pop
|
7
|
+
min = args.pop
|
8
|
+
else
|
9
|
+
max = :default
|
10
|
+
min = :default
|
11
|
+
end
|
12
|
+
@max = (max.to_s == 'default') ? :infinite : max.to_i
|
13
|
+
@min = (min.to_s == 'default') ? 0 : min.to_i
|
14
|
+
@inner_types = args.map { |type| DataType.new_from_string(type) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def condition_value(value)
|
18
|
+
"[ #{value.each_with_index.map { |v,i| inner_types(value)[i].condition_value(v) }.join(', ')} ]"
|
19
|
+
end
|
20
|
+
|
21
|
+
def multivalued?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
type = "tuple of #{@inner_types.join(', ')}"
|
27
|
+
if @min > 0 && @max == :infinite
|
28
|
+
"#{type} (at least #{@min} items)"
|
29
|
+
elsif @min == 0 && @max != :infinite
|
30
|
+
"#{type} (up to #{@max} items)"
|
31
|
+
elsif @min > 0 && @max != :infinite
|
32
|
+
"#{type} (between #{@min} and #{@max} items)"
|
33
|
+
else
|
34
|
+
type
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def typecast(value)
|
39
|
+
if value.nil?
|
40
|
+
nil
|
41
|
+
elsif value == ['EMPTY_ARRAY']
|
42
|
+
[]
|
43
|
+
else
|
44
|
+
values = [value].flatten
|
45
|
+
values.each_with_index.map { |v,i| inner_types(values)[i].typecast(v) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid?(input, errors = [])
|
50
|
+
unless input.is_a?(::Array)
|
51
|
+
errors << "#{input.inspect} is not a valid tuple"
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
|
55
|
+
inner_errors = []
|
56
|
+
input.each_with_index { |v,i| inner_types(input)[i].valid?(v, inner_errors) }
|
57
|
+
unless inner_errors.empty?
|
58
|
+
errors << "Elements of the tuple are invalid: #{inner_errors.join(', ')}"
|
59
|
+
end
|
60
|
+
|
61
|
+
errors << "The tuple must have at least #{@min} items" if input.size < @min
|
62
|
+
errors << "The tuple must have at maximum #{@max} items" if @max != :infinite && input.size > @max
|
63
|
+
|
64
|
+
return errors.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def inner_types(value)
|
70
|
+
@inner_types + ([@inner_types.last] * (value.size - @inner_types.size))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
DataType.register_type('Tuple', Tuple)
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class TypeReference < DataType
|
4
|
+
extend Forwardable
|
5
|
+
def_delegators :@inner_type, :condition_value, :dump_default, :multivalued?, :to_s, :typecast, :valid?
|
6
|
+
|
7
|
+
def initialize(inner_type)
|
8
|
+
@inner_type = DataType.new_from_string(inner_type)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
DataType.register_type('TypeReference', TypeReference)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Kafo
|
2
|
+
module DataTypes
|
3
|
+
class Variant < DataType
|
4
|
+
def initialize(*inner_types)
|
5
|
+
@inner_types = inner_types.map { |t| DataType.new_from_string(t) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def condition_value(value)
|
9
|
+
type = find_type(value)
|
10
|
+
type ? type.condition_value(value) : super(value)
|
11
|
+
end
|
12
|
+
|
13
|
+
def dump_default(value)
|
14
|
+
type = find_type(value)
|
15
|
+
type ? type.dump_default(value) : super(value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def multivalued?
|
19
|
+
@inner_types.any? { |t| t.multivalued? }
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
@inner_types.join(' or ')
|
24
|
+
end
|
25
|
+
|
26
|
+
def typecast(value)
|
27
|
+
type = find_type(value)
|
28
|
+
type ? type.typecast(value) : value
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid?(value, errors = [])
|
32
|
+
type = find_type(value)
|
33
|
+
if type
|
34
|
+
type.valid?(value, errors)
|
35
|
+
else
|
36
|
+
errors << "#{value} is not one of #{to_s}"
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def find_type(value)
|
44
|
+
@inner_types.find { |t| t.valid?(t.typecast(value)) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
DataType.register_type('Variant', Variant)
|
49
|
+
end
|
50
|
+
end
|
data/lib/kafo/hook_context.rb
CHANGED
data/lib/kafo/kafo_configure.rb
CHANGED
@@ -197,10 +197,6 @@ module Kafo
|
|
197
197
|
self.class.exit(:unknown_module)
|
198
198
|
end
|
199
199
|
|
200
|
-
def enabled_params
|
201
|
-
params.select { |p| p.module.enabled? }
|
202
|
-
end
|
203
|
-
|
204
200
|
def reset_params_cache
|
205
201
|
@params = nil
|
206
202
|
params
|
@@ -395,7 +391,7 @@ module Kafo
|
|
395
391
|
|
396
392
|
def validate_all(logging = true)
|
397
393
|
logger.info 'Running validation checks'
|
398
|
-
results =
|
394
|
+
results = params.map do |param|
|
399
395
|
result = param.valid?
|
400
396
|
errors = param.validation_errors.join(', ')
|
401
397
|
progress_log(:error, "Parameter #{with_prefix(param)} invalid: #{errors}") if logging && !result
|
data/lib/kafo/param.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'kafo/condition'
|
3
|
+
require 'kafo/validator'
|
3
4
|
|
4
5
|
module Kafo
|
5
6
|
class Param
|
6
|
-
attr_reader :name, :module
|
7
|
+
attr_reader :name, :module, :type
|
7
8
|
attr_accessor :default, :doc, :value_set, :condition
|
8
9
|
attr_writer :groups
|
9
10
|
|
10
|
-
def initialize(builder, name)
|
11
|
+
def initialize(builder, name, type)
|
11
12
|
@name = name
|
12
13
|
@module = builder
|
14
|
+
@type = DataType.new_from_string(type)
|
13
15
|
end
|
14
16
|
|
15
17
|
def groups
|
@@ -18,12 +20,13 @@ module Kafo
|
|
18
20
|
|
19
21
|
# we use @value_set flag because even nil can be valid value
|
20
22
|
def value
|
21
|
-
@value_set ? @value : default
|
23
|
+
@value_set ? @type.typecast(@value) : default
|
22
24
|
end
|
23
25
|
|
24
26
|
def value=(value)
|
25
27
|
@value_set = true
|
26
|
-
|
28
|
+
value = value.to_s if value.is_a?(::HighLine::String) # don't persist highline extensions
|
29
|
+
@value = value
|
27
30
|
end
|
28
31
|
|
29
32
|
def unset_value
|
@@ -32,7 +35,7 @@ module Kafo
|
|
32
35
|
end
|
33
36
|
|
34
37
|
def dump_default
|
35
|
-
default
|
38
|
+
@type.dump_default(default)
|
36
39
|
end
|
37
40
|
|
38
41
|
def module_name
|
@@ -40,7 +43,7 @@ module Kafo
|
|
40
43
|
end
|
41
44
|
|
42
45
|
def to_s
|
43
|
-
"#<#{self.class}:#{self.object_id} @name=#{name.inspect} @default=#{default.inspect} @value=#{value.inspect}>"
|
46
|
+
"#<#{self.class}:#{self.object_id} @name=#{name.inspect} @default=#{default.inspect} @value=#{value.inspect} @type=#{@type}>"
|
44
47
|
end
|
45
48
|
|
46
49
|
def set_default(defaults)
|
@@ -86,22 +89,23 @@ module Kafo
|
|
86
89
|
{:name => v.name, :arguments => interpret_validation_args(args)}
|
87
90
|
end
|
88
91
|
|
92
|
+
# run old style validation functions
|
89
93
|
@validator = Validator.new
|
90
94
|
validations.each { |v| @validator.send(v[:name], v[:arguments]) }
|
91
|
-
@validator.errors.
|
95
|
+
@validation_errors = @validator.errors.dup
|
96
|
+
|
97
|
+
# run data type based validations, append errors
|
98
|
+
@type.valid?(value, @validation_errors)
|
99
|
+
|
100
|
+
@validation_errors.empty?
|
92
101
|
end
|
93
102
|
|
94
103
|
def validation_errors
|
95
|
-
|
96
|
-
@validator.errors
|
97
|
-
else
|
98
|
-
[]
|
99
|
-
end
|
104
|
+
@validation_errors || []
|
100
105
|
end
|
101
106
|
|
102
|
-
# To be overwritten in children
|
103
107
|
def multivalued?
|
104
|
-
|
108
|
+
@type.multivalued?
|
105
109
|
end
|
106
110
|
|
107
111
|
def <=> o
|
@@ -117,7 +121,7 @@ module Kafo
|
|
117
121
|
end
|
118
122
|
|
119
123
|
def condition_value
|
120
|
-
value
|
124
|
+
@type.condition_value(value)
|
121
125
|
end
|
122
126
|
|
123
127
|
private
|
@@ -139,25 +143,7 @@ module Kafo
|
|
139
143
|
arg == :undef ? nil : arg
|
140
144
|
end
|
141
145
|
end
|
142
|
-
|
143
|
-
def normalize_value(value)
|
144
|
-
case value
|
145
|
-
when ::HighLine::String # don't persist highline extensions
|
146
|
-
value.to_s
|
147
|
-
when Array
|
148
|
-
value.map { |v| normalize_value(v) }
|
149
|
-
when Hash
|
150
|
-
Hash[value.map { |k,v| [normalize_value(k), normalize_value(v)] }]
|
151
|
-
else
|
152
|
-
value
|
153
|
-
end
|
154
|
-
end
|
155
146
|
end
|
156
147
|
end
|
157
148
|
|
158
|
-
require 'kafo/params/boolean'
|
159
|
-
require 'kafo/params/string'
|
160
149
|
require 'kafo/params/password'
|
161
|
-
require 'kafo/params/array'
|
162
|
-
require 'kafo/params/hash'
|
163
|
-
require 'kafo/params/integer'
|
data/lib/kafo/param_builder.rb
CHANGED
@@ -52,7 +52,14 @@ module Kafo
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def build(name, data)
|
55
|
-
|
55
|
+
data_type = data[:types][name] || 'Data'
|
56
|
+
if data_type == 'password'
|
57
|
+
type = Params::Password
|
58
|
+
data_type = 'String'
|
59
|
+
else
|
60
|
+
type = Param
|
61
|
+
end
|
62
|
+
param = type.new(@module, name, data_type)
|
56
63
|
param.default = data[:values][name]
|
57
64
|
param.doc = data[:docs][name]
|
58
65
|
param.groups = data[:groups][name]
|
@@ -77,10 +84,5 @@ module Kafo
|
|
77
84
|
end
|
78
85
|
param_group
|
79
86
|
end
|
80
|
-
|
81
|
-
def get_type(type)
|
82
|
-
type = (type || 'string').capitalize
|
83
|
-
Params.const_defined?(type) ? Params.const_get(type) : raise(TypeError, "undefined parameter type '#{type}'")
|
84
|
-
end
|
85
87
|
end
|
86
88
|
end
|
data/lib/kafo/params/password.rb
CHANGED
data/lib/kafo/version.rb
CHANGED
data/lib/kafo/wizard.rb
CHANGED
@@ -124,6 +124,7 @@ END
|
|
124
124
|
def configure(param)
|
125
125
|
say "\n" + HighLine.color("Parameter #{param.name} (of module #{param.module.name})", :headline)
|
126
126
|
say HighLine.color(param.doc.join("\n").gsub('"', '\"'), :important)
|
127
|
+
say HighLine.color("Data type: #{param.type}", :important)
|
127
128
|
value = param.multivalued? ? configure_multi(param) : configure_single(param)
|
128
129
|
value_was = param.value
|
129
130
|
param.value = value unless value.empty?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kafo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marek Hulan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -220,6 +220,26 @@ files:
|
|
220
220
|
- lib/kafo/color_scheme.rb
|
221
221
|
- lib/kafo/condition.rb
|
222
222
|
- lib/kafo/configuration.rb
|
223
|
+
- lib/kafo/data_type.rb
|
224
|
+
- lib/kafo/data_types/any.rb
|
225
|
+
- lib/kafo/data_types/array.rb
|
226
|
+
- lib/kafo/data_types/boolean.rb
|
227
|
+
- lib/kafo/data_types/enum.rb
|
228
|
+
- lib/kafo/data_types/float.rb
|
229
|
+
- lib/kafo/data_types/hash.rb
|
230
|
+
- lib/kafo/data_types/integer.rb
|
231
|
+
- lib/kafo/data_types/not_undef.rb
|
232
|
+
- lib/kafo/data_types/numeric.rb
|
233
|
+
- lib/kafo/data_types/optional.rb
|
234
|
+
- lib/kafo/data_types/pattern.rb
|
235
|
+
- lib/kafo/data_types/regexp.rb
|
236
|
+
- lib/kafo/data_types/scalar.rb
|
237
|
+
- lib/kafo/data_types/string.rb
|
238
|
+
- lib/kafo/data_types/struct.rb
|
239
|
+
- lib/kafo/data_types/tuple.rb
|
240
|
+
- lib/kafo/data_types/type_reference.rb
|
241
|
+
- lib/kafo/data_types/undef.rb
|
242
|
+
- lib/kafo/data_types/variant.rb
|
223
243
|
- lib/kafo/exceptions.rb
|
224
244
|
- lib/kafo/exit_handler.rb
|
225
245
|
- lib/kafo/help_builder.rb
|
@@ -236,12 +256,7 @@ files:
|
|
236
256
|
- lib/kafo/param.rb
|
237
257
|
- lib/kafo/param_builder.rb
|
238
258
|
- lib/kafo/param_group.rb
|
239
|
-
- lib/kafo/params/array.rb
|
240
|
-
- lib/kafo/params/boolean.rb
|
241
|
-
- lib/kafo/params/hash.rb
|
242
|
-
- lib/kafo/params/integer.rb
|
243
259
|
- lib/kafo/params/password.rb
|
244
|
-
- lib/kafo/params/string.rb
|
245
260
|
- lib/kafo/parser_cache_reader.rb
|
246
261
|
- lib/kafo/parser_cache_writer.rb
|
247
262
|
- lib/kafo/password_manager.rb
|
data/lib/kafo/params/array.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
module Kafo
|
2
|
-
module Params
|
3
|
-
class Array < Param
|
4
|
-
def value=(value)
|
5
|
-
super
|
6
|
-
if @value == ['EMPTY_ARRAY']
|
7
|
-
@value = []
|
8
|
-
else
|
9
|
-
@value = typecast(@value)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def multivalued?
|
14
|
-
true
|
15
|
-
end
|
16
|
-
|
17
|
-
def condition_value
|
18
|
-
"[ #{value.map(&:inspect).join(', ')} ]"
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def typecast(value)
|
24
|
-
value.nil? ? nil : [value].flatten
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/kafo/params/boolean.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module Kafo
|
2
|
-
module Params
|
3
|
-
class Boolean < Param
|
4
|
-
def value=(value)
|
5
|
-
super
|
6
|
-
@value = typecast(@value)
|
7
|
-
end
|
8
|
-
|
9
|
-
def dump_default
|
10
|
-
%{"#{super}"}
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
def typecast(value)
|
16
|
-
case value
|
17
|
-
when '0', 'false', 'f', 'n', false
|
18
|
-
false
|
19
|
-
when '1', 'true', 't', 'y', true
|
20
|
-
true
|
21
|
-
else
|
22
|
-
value
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
data/lib/kafo/params/hash.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
module Kafo
|
2
|
-
module Params
|
3
|
-
class Hash < Param
|
4
|
-
def value=(value)
|
5
|
-
super
|
6
|
-
if @value == ['EMPTY_HASH']
|
7
|
-
@value = {}
|
8
|
-
else
|
9
|
-
@value = typecast(@value)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def multivalued?
|
14
|
-
true
|
15
|
-
end
|
16
|
-
|
17
|
-
def condition_value
|
18
|
-
value.inspect
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def typecast(value)
|
24
|
-
if value.nil?
|
25
|
-
nil
|
26
|
-
elsif value.is_a?(::Hash)
|
27
|
-
value
|
28
|
-
else
|
29
|
-
value = [value].flatten
|
30
|
-
::Hash[value.map { |v| v.split(':', 2) }]
|
31
|
-
end
|
32
|
-
rescue NoMethodError => e
|
33
|
-
KafoConfigure.logger.warn "Could not typecast #{value} for parameter #{name}, defaulting to {}"
|
34
|
-
return {}
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
data/lib/kafo/params/integer.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
module Kafo
|
2
|
-
module Params
|
3
|
-
class Integer < Param
|
4
|
-
def value=(value)
|
5
|
-
super
|
6
|
-
@value = typecast(@value)
|
7
|
-
end
|
8
|
-
|
9
|
-
private
|
10
|
-
|
11
|
-
def typecast(value)
|
12
|
-
value.nil? ? nil : value.to_i
|
13
|
-
rescue NoMethodError => e
|
14
|
-
KafoConfigure.logger.warn "Could not typecast #{value} for parameter #{name}, defaulting to 0"
|
15
|
-
return 0
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|