ronin-core 0.1.0.beta1

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.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.github/workflows/ruby.yml +41 -0
  4. data/.gitignore +12 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +160 -0
  7. data/.ruby-version +1 -0
  8. data/.yardopts +1 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +11 -0
  11. data/Gemfile +30 -0
  12. data/README.md +299 -0
  13. data/Rakefile +34 -0
  14. data/examples/ruby_shell.rb +11 -0
  15. data/gemspec.yml +28 -0
  16. data/lib/ronin/core/class_registry.rb +246 -0
  17. data/lib/ronin/core/cli/command.rb +87 -0
  18. data/lib/ronin/core/cli/command_shell/command.rb +110 -0
  19. data/lib/ronin/core/cli/command_shell.rb +345 -0
  20. data/lib/ronin/core/cli/generator/options/author.rb +106 -0
  21. data/lib/ronin/core/cli/generator/options/description.rb +54 -0
  22. data/lib/ronin/core/cli/generator/options/reference.rb +60 -0
  23. data/lib/ronin/core/cli/generator/options/summary.rb +54 -0
  24. data/lib/ronin/core/cli/generator.rb +238 -0
  25. data/lib/ronin/core/cli/logging.rb +59 -0
  26. data/lib/ronin/core/cli/options/param.rb +68 -0
  27. data/lib/ronin/core/cli/options/values/arches.rb +45 -0
  28. data/lib/ronin/core/cli/options/values/oses.rb +32 -0
  29. data/lib/ronin/core/cli/printing/arch.rb +71 -0
  30. data/lib/ronin/core/cli/printing/metadata.rb +113 -0
  31. data/lib/ronin/core/cli/printing/os.rb +54 -0
  32. data/lib/ronin/core/cli/printing/params.rb +69 -0
  33. data/lib/ronin/core/cli/ruby_shell.rb +131 -0
  34. data/lib/ronin/core/cli/shell.rb +186 -0
  35. data/lib/ronin/core/git.rb +73 -0
  36. data/lib/ronin/core/home.rb +86 -0
  37. data/lib/ronin/core/metadata/authors/author.rb +241 -0
  38. data/lib/ronin/core/metadata/authors.rb +120 -0
  39. data/lib/ronin/core/metadata/description.rb +100 -0
  40. data/lib/ronin/core/metadata/id.rb +88 -0
  41. data/lib/ronin/core/metadata/references.rb +87 -0
  42. data/lib/ronin/core/metadata/summary.rb +78 -0
  43. data/lib/ronin/core/metadata/version.rb +74 -0
  44. data/lib/ronin/core/params/exceptions.rb +38 -0
  45. data/lib/ronin/core/params/mixin.rb +317 -0
  46. data/lib/ronin/core/params/param.rb +137 -0
  47. data/lib/ronin/core/params/types/boolean.rb +64 -0
  48. data/lib/ronin/core/params/types/enum.rb +107 -0
  49. data/lib/ronin/core/params/types/float.rb +68 -0
  50. data/lib/ronin/core/params/types/integer.rb +100 -0
  51. data/lib/ronin/core/params/types/numeric.rb +106 -0
  52. data/lib/ronin/core/params/types/regexp.rb +67 -0
  53. data/lib/ronin/core/params/types/string.rb +118 -0
  54. data/lib/ronin/core/params/types/type.rb +54 -0
  55. data/lib/ronin/core/params/types/uri.rb +72 -0
  56. data/lib/ronin/core/params/types.rb +62 -0
  57. data/lib/ronin/core/params.rb +19 -0
  58. data/lib/ronin/core/version.rb +24 -0
  59. data/ronin-core.gemspec +59 -0
  60. data/spec/class_registry_spec.rb +224 -0
  61. data/spec/cli/command_shell/command_spec.rb +113 -0
  62. data/spec/cli/command_shell_spec.rb +1114 -0
  63. data/spec/cli/command_spec.rb +16 -0
  64. data/spec/cli/fixtures/irb_command +8 -0
  65. data/spec/cli/fixtures/template/dir/file1.txt +1 -0
  66. data/spec/cli/fixtures/template/dir/file2.txt +1 -0
  67. data/spec/cli/fixtures/template/file.erb +1 -0
  68. data/spec/cli/fixtures/template/file.txt +1 -0
  69. data/spec/cli/generator/options/author_spec.rb +121 -0
  70. data/spec/cli/generator/options/description_spec.rb +45 -0
  71. data/spec/cli/generator/options/reference_spec.rb +53 -0
  72. data/spec/cli/generator/options/summary_spec.rb +45 -0
  73. data/spec/cli/generator_spec.rb +244 -0
  74. data/spec/cli/logging_spec.rb +95 -0
  75. data/spec/cli/options/param_spec.rb +67 -0
  76. data/spec/cli/options/values/arches_spec.rb +62 -0
  77. data/spec/cli/printing/arch_spec.rb +130 -0
  78. data/spec/cli/printing/metadata_spec.rb +211 -0
  79. data/spec/cli/printing/os_spec.rb +64 -0
  80. data/spec/cli/printing/params_spec.rb +63 -0
  81. data/spec/cli/ruby_shell.rb +99 -0
  82. data/spec/cli/shell_spec.rb +211 -0
  83. data/spec/fixtures/example_class_registry/base_class.rb +9 -0
  84. data/spec/fixtures/example_class_registry/classes/loaded_class.rb +9 -0
  85. data/spec/fixtures/example_class_registry/classes/name_mismatch.rb +9 -0
  86. data/spec/fixtures/example_class_registry/classes/no_module.rb +4 -0
  87. data/spec/fixtures/example_class_registry.rb +8 -0
  88. data/spec/git_spec.rb +58 -0
  89. data/spec/home_spec.rb +64 -0
  90. data/spec/metadata/authors/author_spec.rb +335 -0
  91. data/spec/metadata/authors_spec.rb +126 -0
  92. data/spec/metadata/description_spec.rb +74 -0
  93. data/spec/metadata/id_spec.rb +92 -0
  94. data/spec/metadata/references_spec.rb +100 -0
  95. data/spec/metadata/summary_spec.rb +74 -0
  96. data/spec/metadata/version_spec.rb +72 -0
  97. data/spec/params/mixin_spec.rb +484 -0
  98. data/spec/params/param_spec.rb +164 -0
  99. data/spec/params/types/boolean_spec.rb +56 -0
  100. data/spec/params/types/enum_spec.rb +94 -0
  101. data/spec/params/types/float_spec.rb +107 -0
  102. data/spec/params/types/integer_spec.rb +155 -0
  103. data/spec/params/types/numeric_spec.rb +138 -0
  104. data/spec/params/types/regexp_spec.rb +64 -0
  105. data/spec/params/types/string_spec.rb +174 -0
  106. data/spec/params/types/type_spec.rb +14 -0
  107. data/spec/params/types/uri_spec.rb +62 -0
  108. data/spec/spec_helper.rb +11 -0
  109. metadata +252 -0
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module Ronin
20
+ module Core
21
+ module Metadata
22
+ #
23
+ # Adds a {Version::ClassMethods#version version} metadata
24
+ # attribute to a class.
25
+ #
26
+ # ### Example
27
+ #
28
+ # class MyModule
29
+ #
30
+ # include Ronin::Core::Metadata::Version
31
+ #
32
+ # version '0.2'
33
+ #
34
+ # end
35
+ #
36
+ module Version
37
+ #
38
+ # Adds {ClassMethods} to the class.
39
+ #
40
+ # @param [Class] base
41
+ # The base class which is including {Version}.
42
+ #
43
+ # @api private
44
+ #
45
+ def self.included(base)
46
+ base.extend ClassMethods
47
+ end
48
+
49
+ module ClassMethods
50
+ #
51
+ # Gets or sets the version number.
52
+ #
53
+ # @param [String, nil] new_version
54
+ # The optional new version number to set.
55
+ #
56
+ # @return [String, nil]
57
+ # The previously set version number.
58
+ #
59
+ # @example Setting the version:
60
+ # version '0.2'
61
+ #
62
+ # @example Getting the version:
63
+ # MyModule.version
64
+ #
65
+ def version(new_version=nil)
66
+ if new_version then @version = new_version
67
+ else @version
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module Ronin
20
+ module Core
21
+ module Params
22
+ class UnknownType < ArgumentError
23
+ end
24
+
25
+ class ParamError < RuntimeError
26
+ end
27
+
28
+ class UnknownParam < ParamError
29
+ end
30
+
31
+ class ValidationError < ParamError
32
+ end
33
+
34
+ class RequiredParam < ValidationError
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,317 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'ronin/core/params/exceptions'
20
+ require 'ronin/core/params/param'
21
+ require 'ronin/core/params/types'
22
+
23
+ module Ronin
24
+ module Core
25
+ module Params
26
+ #
27
+ # Allows classes to define configurable parameters.
28
+ #
29
+ # ## Examples
30
+ #
31
+ # class BaseClass
32
+ #
33
+ # include Ronin::Core::Params::Mixin
34
+ #
35
+ # end
36
+ #
37
+ # class MyModule < BaseClass
38
+ #
39
+ # param :str, desc: 'A basic string param'
40
+ #
41
+ # param :feature_flag, Boolean, desc: 'A boolean param'
42
+ #
43
+ # param :enum, Enum[:one, :two, :three],
44
+ # desc: 'An enum param'
45
+ #
46
+ # param :num1, Integer, desc: 'An integer param'
47
+ #
48
+ # param :num2, Integer, default: 42,
49
+ # desc: 'A param with a default value'
50
+ #
51
+ # param :num3, Integer, default: ->{ rand(42) },
52
+ # desc: 'A param with a dynamic default value'
53
+ #
54
+ # param :float, Float, 'Floating point param'
55
+ #
56
+ # param :url, URI, desc: 'URL param'
57
+ #
58
+ # param :pattern, Regexp, desc: 'Regular Expression param'
59
+ #
60
+ # end
61
+ #
62
+ # mod = MyModule.new(params: {num1: 1, enum: :two})
63
+ # mod.params
64
+ # # => {:num2=>42, :num3=>25, :num1=>1, :enum=>:two}
65
+ #
66
+ # @api semipublic
67
+ #
68
+ module Mixin
69
+ # The boolean param type.
70
+ Boolean = Params::Types::Boolean
71
+
72
+ # The enum param type.
73
+ Enum = Params::Types::Enum
74
+
75
+ #
76
+ # Adds {ClassMethods} to the given class.
77
+ #
78
+ # @param [Class] base_class
79
+ # The class which is including {Mixin}.
80
+ #
81
+ # @raise [TypeError]
82
+ # {Mixin} was inclued into a module instead of a class.
83
+ #
84
+ # @api private
85
+ #
86
+ def self.included(base_class)
87
+ unless base_class.kind_of?(Class)
88
+ raise(TypeError,"#{Mixin} can only be included into classes")
89
+ end
90
+
91
+ base_class.extend ClassMethods
92
+ end
93
+
94
+ #
95
+ # Class methods.
96
+ #
97
+ module ClassMethods
98
+ #
99
+ # All defined params.
100
+ #
101
+ # @return [Hash{Symbol => Param}]
102
+ #
103
+ # @api private
104
+ #
105
+ def params
106
+ @params ||= if superclass < Mixin
107
+ superclass.params.dup
108
+ else
109
+ {}
110
+ end
111
+ end
112
+
113
+ #
114
+ # Defines a new param.
115
+ #
116
+ # @param [Symbol] name
117
+ # The name for the new param.
118
+ #
119
+ # @param [Class, Types::Type] type
120
+ # The type for the new param. Available types are:
121
+ # * {Types::Boolean Boolean}
122
+ # * {Types::Enum Enum}
123
+ # * {Types::String String}
124
+ # * {Types::Integer Integer}
125
+ # * {Types::Float Float}
126
+ # * {Types::Regexp Regexp}
127
+ # * {Types::URI URI}
128
+ #
129
+ # @param [Boolean] required
130
+ # Specifies whether the param requires a value or is optional.
131
+ #
132
+ # @param [Object, nil] default
133
+ # The optional default value for the param.
134
+ #
135
+ # @param [String] desc
136
+ # The description for the param. All defined params must have a
137
+ # description.
138
+ #
139
+ # @param [Hash{Symbol => Object}] kwargs
140
+ # Additional keyword arguments for the {Types type class}.
141
+ #
142
+ # @example Define a basic String param:
143
+ # param :foo, desc: 'Foo param'
144
+ #
145
+ # @example Define a param with an explicit type:
146
+ # param :foo, String, desc: 'Foo param'
147
+ #
148
+ # @example Define a required param:
149
+ # param :foo, required: true, desc: 'A required param'
150
+ #
151
+ # @example Define a String param with a validation regex:
152
+ # param :foo, String, format: /\A...\z/, desc: 'Foo param'
153
+ #
154
+ # @example Define a boolean param:
155
+ # param :mode, Boolean
156
+ #
157
+ # @example Define an enum param:
158
+ # param :mode, Enum[:one, :two, :three]
159
+ #
160
+ # @example Define a Regexp param:
161
+ # param :pattern, Regexp
162
+ #
163
+ # @example Define a URI param:
164
+ # param :pattern, URI
165
+ #
166
+ # @example Define a param with a specific type:
167
+ # param :foo, Integer, desc: 'Foo param'
168
+ #
169
+ # @example Define a param with type validations:
170
+ # param :foo, Integer, min: 1,
171
+ # max: 100,
172
+ # desc: 'Foo param'
173
+ #
174
+ # @example Define a param with a default value:
175
+ # param :foo, Integer, default: 42,
176
+ # desc: 'Foo param'
177
+ #
178
+ # @example Define a param with a proc default value:
179
+ # param :foo, Integer, default: ->{ rand(42) },
180
+ # desc: 'Foo param'
181
+ #
182
+ # @api public
183
+ #
184
+ def param(name,type=Types::String.new, required: false,
185
+ default: nil,
186
+ desc: ,
187
+ **kwargs)
188
+ type = case type
189
+ when Types::Type then type
190
+ else Types.lookup(type).new(**kwargs)
191
+ end
192
+
193
+ params[name] = Param.new(name,type, required: required,
194
+ default: default,
195
+ desc: desc)
196
+ end
197
+ end
198
+
199
+ # The param values.
200
+ #
201
+ # @return [Hash{Symbol => Object}]
202
+ #
203
+ # @api public
204
+ attr_reader :params
205
+
206
+ #
207
+ # Initializes the params.
208
+ #
209
+ # @param [Array] arguments
210
+ # Additional arguments for the class'es `initialize` method.
211
+ #
212
+ # @param [Hash{Symbol => Object}] params
213
+ # The param values.
214
+ #
215
+ # @param [Hash{Symbol => Object}] kwargs
216
+ # Additional keyword arguments for the superclass'es `initialize`
217
+ # method.
218
+ #
219
+ # @api public
220
+ #
221
+ def initialize(*arguments, params: nil, **kwargs, &block)
222
+ if params then self.params = params
223
+ else initialize_params()
224
+ end
225
+
226
+ super(*arguments,**kwargs,&block)
227
+ end
228
+
229
+ #
230
+ # Initializes {#params}.
231
+ #
232
+ # @api semipublic
233
+ #
234
+ def initialize_params
235
+ @params = {}
236
+
237
+ self.class.params.each do |name,param|
238
+ @params[name] = param.default_value if param.has_default?
239
+ end
240
+ end
241
+
242
+ #
243
+ # Sets a param's value.
244
+ #
245
+ # @param [Symbol] name
246
+ # The param name.
247
+ #
248
+ # @param [Object] value
249
+ # The new param value.
250
+ #
251
+ # @return [Object]
252
+ # The param's new value.
253
+ #
254
+ # @raise [ValidationError]
255
+ # The given param value was invalid.
256
+ #
257
+ # @api semipublic
258
+ #
259
+ def set_param(name,value)
260
+ unless (param = self.class.params[name])
261
+ raise(UnknownParam,"unknown param: #{name.inspect}")
262
+ end
263
+
264
+ @params[name] = begin
265
+ param.coerce(value)
266
+ rescue ValidationError => error
267
+ raise(ValidationError,"invalid param value for param '#{name}': #{error.message}")
268
+ end
269
+ end
270
+
271
+ #
272
+ # Sets the params.
273
+ #
274
+ # @param [Hash{Symbol => Object}] new_params
275
+ # The new param values.
276
+ #
277
+ # @raise [RequiredParam]
278
+ # One of the required params is not set.
279
+ #
280
+ # @api semipublic
281
+ #
282
+ def params=(new_params)
283
+ # re-initialize the params each time they are set en-mass
284
+ initialize_params()
285
+
286
+ new_params.each do |name,value|
287
+ set_param(name,value)
288
+ end
289
+
290
+ validate_params
291
+ return new_params
292
+ end
293
+
294
+ #
295
+ # Validates that all required params are set.
296
+ #
297
+ # @return [true]
298
+ # Indicates all required params have non-nil values.
299
+ #
300
+ # @raise [RequiredParam]
301
+ # One of the required params is not set.
302
+ #
303
+ # @api semipublic
304
+ #
305
+ def validate_params
306
+ self.class.params.each do |name,param|
307
+ if param.required? && @params[name].nil?
308
+ raise(RequiredParam,"param '#{name}' requires a value")
309
+ end
310
+ end
311
+
312
+ return true
313
+ end
314
+ end
315
+ end
316
+ end
317
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module Ronin
20
+ module Core
21
+ module Params
22
+ #
23
+ # Represents an individual param.
24
+ #
25
+ # @api semipublic
26
+ #
27
+ class Param
28
+
29
+ # The name of the param.
30
+ #
31
+ # @return [Symbol]
32
+ attr_reader :name
33
+
34
+ # The param type.
35
+ #
36
+ # @return [Types::Type]
37
+ attr_reader :type
38
+
39
+ # Specifies whether the param is required or not.
40
+ #
41
+ # @return [Boolean]
42
+ attr_reader :required
43
+
44
+ # The cefault value or proc for the param.
45
+ #
46
+ # @return [Object, Proc, nil]
47
+ attr_reader :default
48
+
49
+ # The description of the param.
50
+ #
51
+ # @return [String]
52
+ attr_reader :desc
53
+
54
+ #
55
+ # Initializes the param.
56
+ #
57
+ # @param [Symbol] name
58
+ # The name of the param.
59
+ #
60
+ # @param [Type] type
61
+ # The type of the param.
62
+ #
63
+ # @param [Boolean] required
64
+ # Whether the param is required or not.
65
+ #
66
+ # @param [Object, Proc, nil] default
67
+ # The optional default value or default value proc for the param.
68
+ #
69
+ # @param [String] desc
70
+ # A short one-line description of the param.
71
+ #
72
+ # @api private
73
+ #
74
+ def initialize(name,type, required: false, default: nil, desc: )
75
+ @name = name
76
+ @type = type
77
+ @required = required
78
+ @default = default
79
+ @desc = desc
80
+ end
81
+
82
+ #
83
+ # Determines if the param is required.
84
+ #
85
+ # @return [Boolean]
86
+ #
87
+ def required?
88
+ @required
89
+ end
90
+
91
+ #
92
+ # Determines if the param has a default value.
93
+ #
94
+ # @return [Boolean]
95
+ #
96
+ def has_default?
97
+ !@default.nil?
98
+ end
99
+
100
+ #
101
+ # Returns the default value for the param.
102
+ #
103
+ # @return [Object]
104
+ #
105
+ def default_value
106
+ if @default.respond_to?(:call) then @default.call
107
+ else @default.dup
108
+ end
109
+ end
110
+
111
+ #
112
+ # Coerces the value for the param.
113
+ #
114
+ # @param [Object] value
115
+ # The value to coerce.
116
+ #
117
+ # @return [Object]
118
+ # The coerced value.
119
+ #
120
+ # @raise [ValidationError]
121
+ # The param requires a non-nil value.
122
+ #
123
+ def coerce(value)
124
+ case value
125
+ when nil
126
+ if required?
127
+ raise(ValidationError,"param requires a non-nil value")
128
+ end
129
+ else
130
+ @type.coerce(value)
131
+ end
132
+ end
133
+
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'ronin/core/params/types/type'
20
+
21
+ module Ronin
22
+ module Core
23
+ module Params
24
+ module Types
25
+ #
26
+ # Represents a true/false param.
27
+ #
28
+ class Boolean < Type
29
+
30
+ #
31
+ # Coerces a value into a boolean value.
32
+ #
33
+ # @param [::String, true, false, nil] value
34
+ # The value to coerce.
35
+ #
36
+ # @return [true, false, nil]
37
+ # The coerced boolean value.
38
+ #
39
+ # @raise [ValidationError]
40
+ # The given value was not `nil`, `true`, `false`, `"true"`, `"false"`, `"yes"`, `"no"`, `"y"`, `"n"`, `"on"`, or `"off"`.
41
+ #
42
+ # @api private
43
+ #
44
+ def coerce(value)
45
+ case value
46
+ when nil then false
47
+ when true, false then value
48
+ when ::String
49
+ case value
50
+ when /\A(?:true|yes|y|on)\z/i then true
51
+ when /\A(?:false|no|n|off)\z/i then false
52
+ else
53
+ raise(ValidationError,"value must be either 'true', 'false', 'yes', 'no', 'y', 'n', 'on', or 'off' (#{value.inspect})")
54
+ end
55
+ else
56
+ raise(ValidationError,"value must be either true, false, or a String (#{value.inspect})")
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end