command_mapper 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.document +3 -0
- data/.github/workflows/ruby.yml +2 -1
- data/ChangeLog.md +30 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +57 -19
- data/lib/command_mapper/arg.rb +3 -0
- data/lib/command_mapper/argument.rb +1 -0
- data/lib/command_mapper/command.rb +153 -30
- data/lib/command_mapper/option.rb +45 -13
- data/lib/command_mapper/option_value.rb +2 -0
- data/lib/command_mapper/types/enum.rb +2 -0
- data/lib/command_mapper/types/hex.rb +15 -2
- data/lib/command_mapper/types/input_dir.rb +3 -0
- data/lib/command_mapper/types/input_file.rb +3 -0
- data/lib/command_mapper/types/input_path.rb +3 -0
- data/lib/command_mapper/types/key_value.rb +4 -1
- data/lib/command_mapper/types/key_value_list.rb +1 -1
- data/lib/command_mapper/types/list.rb +5 -0
- data/lib/command_mapper/types/map.rb +20 -2
- data/lib/command_mapper/types/num.rb +27 -1
- data/lib/command_mapper/types/type.rb +9 -1
- data/lib/command_mapper/types.rb +6 -0
- data/lib/command_mapper/version.rb +1 -1
- data/spec/commnad_spec.rb +329 -74
- data/spec/option_spec.rb +252 -1
- data/spec/types/hex_spec.rb +59 -1
- data/spec/types/map_spec.rb +20 -3
- data/spec/types/num_spec.rb +93 -3
- data/spec/types_spec.rb +48 -0
- metadata +4 -2
@@ -7,12 +7,18 @@ module CommandMapper
|
|
7
7
|
#
|
8
8
|
class Option
|
9
9
|
|
10
|
+
# The option's flag (ex: `-o` or `--output`).
|
11
|
+
#
|
10
12
|
# @return [String]
|
11
13
|
attr_reader :flag
|
12
14
|
|
15
|
+
# The option's name.
|
16
|
+
#
|
13
17
|
# @return [Symbol]
|
14
18
|
attr_reader :name
|
15
19
|
|
20
|
+
# Describes the option's value.
|
21
|
+
#
|
16
22
|
# @return [OptionValue, nil]
|
17
23
|
attr_reader :value
|
18
24
|
|
@@ -25,10 +31,6 @@ module CommandMapper
|
|
25
31
|
# @param [Symbol, nil] name
|
26
32
|
# The option's name.
|
27
33
|
#
|
28
|
-
# @param [Boolean] equals
|
29
|
-
# Specifies whether the option's flag and value should be separated with a
|
30
|
-
# `=` character.
|
31
|
-
#
|
32
34
|
# @param [Hash, nil] value
|
33
35
|
# The option's value.
|
34
36
|
#
|
@@ -41,15 +43,29 @@ module CommandMapper
|
|
41
43
|
# @param [Boolean] repeats
|
42
44
|
# Specifies whether the option can be given multiple times.
|
43
45
|
#
|
44
|
-
|
46
|
+
# @param [Boolean] equals
|
47
|
+
# Specifies whether the option's flag and value should be separated with a
|
48
|
+
# `=` character.
|
49
|
+
#
|
50
|
+
# @param [Boolean] value_in_flag
|
51
|
+
# Specifies that the value should be appended to the option's flag
|
52
|
+
# (ex: `-Fvalue`).
|
53
|
+
#
|
54
|
+
def initialize(flag, name: nil, value: nil, repeats: false,
|
55
|
+
# formatting options
|
56
|
+
equals: nil,
|
57
|
+
value_in_flag: nil)
|
45
58
|
@flag = flag
|
46
59
|
@name = name || self.class.infer_name_from_flag(flag)
|
47
|
-
@equals = equals
|
48
60
|
@value = case value
|
49
61
|
when Hash then OptionValue.new(**value)
|
50
62
|
when true then OptionValue.new
|
51
63
|
end
|
52
64
|
@repeats = repeats
|
65
|
+
|
66
|
+
# formatting options
|
67
|
+
@equals = equals
|
68
|
+
@value_in_flag = value_in_flag
|
53
69
|
end
|
54
70
|
|
55
71
|
#
|
@@ -90,6 +106,15 @@ module CommandMapper
|
|
90
106
|
!@value.nil?
|
91
107
|
end
|
92
108
|
|
109
|
+
#
|
110
|
+
# Determines whether the option can be given multiple times.
|
111
|
+
#
|
112
|
+
# @return [Boolean]
|
113
|
+
#
|
114
|
+
def repeats?
|
115
|
+
@repeats
|
116
|
+
end
|
117
|
+
|
93
118
|
#
|
94
119
|
# Indicates whether the option flag and value should be separated with a
|
95
120
|
# `=` character.
|
@@ -101,18 +126,21 @@ module CommandMapper
|
|
101
126
|
end
|
102
127
|
|
103
128
|
#
|
104
|
-
#
|
129
|
+
# Indicates whether the value will be appended to the option's flag.
|
105
130
|
#
|
106
131
|
# @return [Boolean]
|
107
132
|
#
|
108
|
-
|
109
|
-
|
133
|
+
# @since 0.2.0
|
134
|
+
#
|
135
|
+
def value_in_flag?
|
136
|
+
@value_in_flag
|
110
137
|
end
|
111
138
|
|
112
139
|
#
|
113
140
|
# Validates whether the given value is compatible with the option.
|
114
141
|
#
|
115
142
|
# @param [Array<Object>, Object] value
|
143
|
+
# The given value to validate.
|
116
144
|
#
|
117
145
|
# @return [true, (false, String)]
|
118
146
|
# Returns true if the value is valid, or `false` and a validation error
|
@@ -175,6 +203,7 @@ module CommandMapper
|
|
175
203
|
# Validates a value when the option can be repeated.
|
176
204
|
#
|
177
205
|
# @param [Array<Object>, Object] value
|
206
|
+
# The given value to validate.
|
178
207
|
#
|
179
208
|
# @return [true, (false, String)]
|
180
209
|
# Returns true if the value is valid, or `false` and a validation error
|
@@ -208,6 +237,7 @@ module CommandMapper
|
|
208
237
|
# Validates a value when the option does not accept a value.
|
209
238
|
#
|
210
239
|
# @param [Array<Object>, Object] value
|
240
|
+
# The given value to validate.
|
211
241
|
#
|
212
242
|
# @return [true, (false, String)]
|
213
243
|
# Returns true if the value is valid, or `false` and a validation error
|
@@ -266,13 +296,15 @@ module CommandMapper
|
|
266
296
|
else
|
267
297
|
string = @value.format(value)
|
268
298
|
|
269
|
-
if string.start_with?('-')
|
270
|
-
raise(ValidationError,"option #{@name} formatted value (#{string.inspect}) cannot start with a '-'")
|
271
|
-
end
|
272
|
-
|
273
299
|
if equals?
|
274
300
|
argv << "#{@flag}=#{string}"
|
301
|
+
elsif value_in_flag?
|
302
|
+
argv << "#{@flag}#{string}"
|
275
303
|
else
|
304
|
+
if string.start_with?('-')
|
305
|
+
raise(ValidationError,"option #{@name} formatted value (#{string.inspect}) cannot start with a '-'")
|
306
|
+
end
|
307
|
+
|
276
308
|
argv << @flag << string
|
277
309
|
end
|
278
310
|
end
|
@@ -14,9 +14,11 @@ module CommandMapper
|
|
14
14
|
# Specifies whether the hex value will start with `0x` or not.
|
15
15
|
#
|
16
16
|
# @param [Hash{Symbol => Object}] kwargs
|
17
|
-
# Additional keyword arguments for {
|
17
|
+
# Additional keyword arguments for {Num#initialize}.
|
18
18
|
#
|
19
|
-
def initialize(leading_zero: false)
|
19
|
+
def initialize(leading_zero: false, **kwargs)
|
20
|
+
super(**kwargs)
|
21
|
+
|
20
22
|
@leading_zero = leading_zero
|
21
23
|
end
|
22
24
|
|
@@ -33,8 +35,11 @@ module CommandMapper
|
|
33
35
|
# Validates a value.
|
34
36
|
#
|
35
37
|
# @param [String, Integer, Object] value
|
38
|
+
# The given value to validate.
|
36
39
|
#
|
37
40
|
# @return [true, (false, String)]
|
41
|
+
# Returns true if the value is valid, or `false` and a validation error
|
42
|
+
# message if the value is not compatible.
|
38
43
|
#
|
39
44
|
def validate(value)
|
40
45
|
case value
|
@@ -43,6 +48,12 @@ module CommandMapper
|
|
43
48
|
return [false, "not in hex format (#{value.inspect})"]
|
44
49
|
end
|
45
50
|
|
51
|
+
if @range
|
52
|
+
unless @range.include?(value.to_i(16))
|
53
|
+
return [false, "unacceptable value (#{value.inspect})"]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
46
57
|
return true
|
47
58
|
else
|
48
59
|
super(value)
|
@@ -53,8 +64,10 @@ module CommandMapper
|
|
53
64
|
# Formats the value.
|
54
65
|
#
|
55
66
|
# @param [#to_i] value
|
67
|
+
# The given numeric value.
|
56
68
|
#
|
57
69
|
# @return [String]
|
70
|
+
# The formatted numeric value.
|
58
71
|
#
|
59
72
|
def format(value)
|
60
73
|
case value
|
@@ -11,8 +11,11 @@ module CommandMapper
|
|
11
11
|
# Validates whether the directory exists.
|
12
12
|
#
|
13
13
|
# @param [Object] value
|
14
|
+
# The given value to validate.
|
14
15
|
#
|
15
16
|
# @return [true, (false, String)]
|
17
|
+
# Returns true if the value is valid, or `false` and a validation error
|
18
|
+
# message if the value is not compatible.
|
16
19
|
#
|
17
20
|
def validate(value)
|
18
21
|
valid, message = super(value)
|
@@ -11,8 +11,11 @@ module CommandMapper
|
|
11
11
|
# Validates the file exists.
|
12
12
|
#
|
13
13
|
# @param [Object] value
|
14
|
+
# The given value to validate.
|
14
15
|
#
|
15
16
|
# @return [true, (false, String)]
|
17
|
+
# Returns true if the value is valid, or `false` and a validation error
|
18
|
+
# message if the value is not compatible.
|
16
19
|
#
|
17
20
|
def validate(value)
|
18
21
|
valid, message = super(value)
|
@@ -11,8 +11,11 @@ module CommandMapper
|
|
11
11
|
# Validates whether the path exists or not.
|
12
12
|
#
|
13
13
|
# @param [Object] value
|
14
|
+
# The given value to validate.
|
14
15
|
#
|
15
16
|
# @return [true, (false, String)]
|
17
|
+
# Returns true if the value is valid, or `false` and a validation error
|
18
|
+
# message if the value is not compatible.
|
16
19
|
#
|
17
20
|
def validate(value)
|
18
21
|
unless value.empty?
|
@@ -57,8 +57,11 @@ module CommandMapper
|
|
57
57
|
# Valides the given value.
|
58
58
|
#
|
59
59
|
# @param [Object] value
|
60
|
+
# The given value to validate.
|
60
61
|
#
|
61
62
|
# @return [true, (false, String)]
|
63
|
+
# Returns true if the value is valid, or `false` and a validation error
|
64
|
+
# message if the value is not compatible.
|
62
65
|
#
|
63
66
|
def validate(value)
|
64
67
|
case value
|
@@ -105,7 +108,7 @@ module CommandMapper
|
|
105
108
|
# Formats a value into a key-value pair.
|
106
109
|
#
|
107
110
|
# @param [Hash, Array, #to_s] value
|
108
|
-
# The given value.
|
111
|
+
# The given value to format.
|
109
112
|
#
|
110
113
|
# @return [String]
|
111
114
|
# The formatted key-value pair.
|
@@ -51,8 +51,11 @@ module CommandMapper
|
|
51
51
|
# Validates the value.
|
52
52
|
#
|
53
53
|
# @param [Object] value
|
54
|
+
# The given value to validate.
|
54
55
|
#
|
55
56
|
# @return [true, (false, String)]
|
57
|
+
# Returns true if the value is valid, or `false` and a validation error
|
58
|
+
# message if the value is not compatible.
|
56
59
|
#
|
57
60
|
def validate(value)
|
58
61
|
values = Array(value)
|
@@ -78,8 +81,10 @@ module CommandMapper
|
|
78
81
|
# Formats the value into a list.
|
79
82
|
#
|
80
83
|
# @param [Object] value
|
84
|
+
# The given value to format.
|
81
85
|
#
|
82
86
|
# @return [String]
|
87
|
+
# The formatted list.
|
83
88
|
#
|
84
89
|
def format(value)
|
85
90
|
Array(value).map(&@type.method(:format)).join(@separator)
|
@@ -4,6 +4,8 @@ module CommandMapper
|
|
4
4
|
module Types
|
5
5
|
class Map < Type
|
6
6
|
|
7
|
+
# The map of values to Strings.
|
8
|
+
#
|
7
9
|
# @return [Hash{Object => String}]
|
8
10
|
attr_reader :map
|
9
11
|
|
@@ -39,24 +41,40 @@ module CommandMapper
|
|
39
41
|
# Validates a value.
|
40
42
|
#
|
41
43
|
# @param [Object] value
|
44
|
+
# The given value to validate.
|
42
45
|
#
|
43
46
|
# @return [true, (false, String)]
|
47
|
+
# Returns true if the value is valid, or `false` and a validation error
|
48
|
+
# message if the value is not compatible.
|
44
49
|
#
|
45
50
|
def validate(value)
|
46
|
-
unless @map.has_key?(value)
|
51
|
+
unless (@map.has_key?(value) || @map.has_value?(value))
|
47
52
|
return [false, "unknown value (#{value.inspect})"]
|
48
53
|
end
|
49
54
|
|
50
55
|
return true
|
51
56
|
end
|
52
57
|
|
58
|
+
#
|
59
|
+
# Maps a value.
|
53
60
|
#
|
54
61
|
# @param [Object] value
|
62
|
+
# The given value.
|
55
63
|
#
|
56
64
|
# @return [String]
|
65
|
+
# The mapped value.
|
66
|
+
#
|
67
|
+
# @raise [KeyError]
|
68
|
+
# The given value is not a key or value in the map.
|
57
69
|
#
|
58
70
|
def format(value)
|
59
|
-
|
71
|
+
if @map.has_key?(value)
|
72
|
+
super(@map[value])
|
73
|
+
elsif @map.has_value?(value)
|
74
|
+
super(value)
|
75
|
+
else
|
76
|
+
raise(KeyError,"value (#{value.inspect}) is not a key or value in the map: #{@map.inspect}")
|
77
|
+
end
|
60
78
|
end
|
61
79
|
|
62
80
|
end
|
@@ -7,17 +7,35 @@ module CommandMapper
|
|
7
7
|
#
|
8
8
|
class Num < Type
|
9
9
|
|
10
|
+
# The optional range of acceptable numbers.
|
11
|
+
#
|
12
|
+
# @return [Range, nil]
|
13
|
+
attr_reader :range
|
14
|
+
|
15
|
+
#
|
16
|
+
# Initializes the numeric value.
|
17
|
+
#
|
18
|
+
# @param [Range] range
|
19
|
+
# Specifies the range of acceptable numbers.
|
20
|
+
#
|
21
|
+
def initialize(range: nil)
|
22
|
+
@range = range
|
23
|
+
end
|
24
|
+
|
10
25
|
#
|
11
26
|
# Validates a value.
|
12
27
|
#
|
13
28
|
# @param [String, Integer] value
|
29
|
+
# The given value to validate.
|
14
30
|
#
|
15
31
|
# @return [true, (false, String)]
|
32
|
+
# Returns true if the value is valid, or `false` and a validation error
|
33
|
+
# message if the value is not compatible.
|
16
34
|
#
|
17
35
|
def validate(value)
|
18
36
|
case value
|
19
37
|
when Integer
|
20
|
-
|
38
|
+
# no-op
|
21
39
|
when String
|
22
40
|
unless value =~ /\A\d+\z/
|
23
41
|
return [false, "contains non-numeric characters (#{value.inspect})"]
|
@@ -28,6 +46,12 @@ module CommandMapper
|
|
28
46
|
end
|
29
47
|
end
|
30
48
|
|
49
|
+
if @range
|
50
|
+
unless @range.include?(value.to_i)
|
51
|
+
return [false, "unacceptable value (#{value.inspect})"]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
31
55
|
return true
|
32
56
|
end
|
33
57
|
|
@@ -35,8 +59,10 @@ module CommandMapper
|
|
35
59
|
# Formats a numeric value.
|
36
60
|
#
|
37
61
|
# @param [String, Integer, #to_i] value
|
62
|
+
# The given value to format.
|
38
63
|
#
|
39
64
|
# @return [String]
|
65
|
+
# The formatted numeric value.
|
40
66
|
#
|
41
67
|
def format(value)
|
42
68
|
case value
|
@@ -56,8 +56,11 @@ module CommandMapper
|
|
56
56
|
# The default `validate` method for all types.
|
57
57
|
#
|
58
58
|
# @param [Object]
|
59
|
+
# The given value to format.
|
59
60
|
#
|
60
61
|
# @return [true, (false, String)]
|
62
|
+
# Returns true if the value is valid, or `false` and a validation error
|
63
|
+
# message if the value is not compatible.
|
61
64
|
#
|
62
65
|
def validate(value)
|
63
66
|
true
|
@@ -67,6 +70,7 @@ module CommandMapper
|
|
67
70
|
# The default `format` method for all types.
|
68
71
|
#
|
69
72
|
# @param [#to_s] value
|
73
|
+
# The given value to format.
|
70
74
|
#
|
71
75
|
# @return [String]
|
72
76
|
# The String version of the value.
|
@@ -83,10 +87,14 @@ module CommandMapper
|
|
83
87
|
# Converts a value into a {Type} object.
|
84
88
|
#
|
85
89
|
# @param [Type, Hash, nil] value
|
90
|
+
# The type value or `Hash` of keyword arguments.
|
86
91
|
#
|
87
|
-
# @return [Type]
|
92
|
+
# @return [Type, Str]
|
93
|
+
# The type object or a new {Str} type object if a `Hash` of keyword
|
94
|
+
# arguments is given.
|
88
95
|
#
|
89
96
|
# @raise [ArgumentError]
|
97
|
+
# The given type value was not a {Type}, `Hash`, or `nil`,
|
90
98
|
#
|
91
99
|
def self.Type(value)
|
92
100
|
case value
|
data/lib/command_mapper/types.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'command_mapper/types/type'
|
2
2
|
require 'command_mapper/types/str'
|
3
|
+
require 'command_mapper/types/num'
|
4
|
+
require 'command_mapper/types/hex'
|
3
5
|
require 'command_mapper/types/map'
|
6
|
+
require 'command_mapper/types/enum'
|
4
7
|
require 'command_mapper/types/list'
|
5
8
|
require 'command_mapper/types/key_value'
|
6
9
|
require 'command_mapper/types/key_value_list'
|
10
|
+
require 'command_mapper/types/input_path'
|
11
|
+
require 'command_mapper/types/input_file'
|
12
|
+
require 'command_mapper/types/input_dir'
|