kafo 0.9.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|