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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.github/workflows/ruby.yml +41 -0
- data/.gitignore +12 -0
- data/.rspec +1 -0
- data/.rubocop.yml +160 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +11 -0
- data/Gemfile +30 -0
- data/README.md +299 -0
- data/Rakefile +34 -0
- data/examples/ruby_shell.rb +11 -0
- data/gemspec.yml +28 -0
- data/lib/ronin/core/class_registry.rb +246 -0
- data/lib/ronin/core/cli/command.rb +87 -0
- data/lib/ronin/core/cli/command_shell/command.rb +110 -0
- data/lib/ronin/core/cli/command_shell.rb +345 -0
- data/lib/ronin/core/cli/generator/options/author.rb +106 -0
- data/lib/ronin/core/cli/generator/options/description.rb +54 -0
- data/lib/ronin/core/cli/generator/options/reference.rb +60 -0
- data/lib/ronin/core/cli/generator/options/summary.rb +54 -0
- data/lib/ronin/core/cli/generator.rb +238 -0
- data/lib/ronin/core/cli/logging.rb +59 -0
- data/lib/ronin/core/cli/options/param.rb +68 -0
- data/lib/ronin/core/cli/options/values/arches.rb +45 -0
- data/lib/ronin/core/cli/options/values/oses.rb +32 -0
- data/lib/ronin/core/cli/printing/arch.rb +71 -0
- data/lib/ronin/core/cli/printing/metadata.rb +113 -0
- data/lib/ronin/core/cli/printing/os.rb +54 -0
- data/lib/ronin/core/cli/printing/params.rb +69 -0
- data/lib/ronin/core/cli/ruby_shell.rb +131 -0
- data/lib/ronin/core/cli/shell.rb +186 -0
- data/lib/ronin/core/git.rb +73 -0
- data/lib/ronin/core/home.rb +86 -0
- data/lib/ronin/core/metadata/authors/author.rb +241 -0
- data/lib/ronin/core/metadata/authors.rb +120 -0
- data/lib/ronin/core/metadata/description.rb +100 -0
- data/lib/ronin/core/metadata/id.rb +88 -0
- data/lib/ronin/core/metadata/references.rb +87 -0
- data/lib/ronin/core/metadata/summary.rb +78 -0
- data/lib/ronin/core/metadata/version.rb +74 -0
- data/lib/ronin/core/params/exceptions.rb +38 -0
- data/lib/ronin/core/params/mixin.rb +317 -0
- data/lib/ronin/core/params/param.rb +137 -0
- data/lib/ronin/core/params/types/boolean.rb +64 -0
- data/lib/ronin/core/params/types/enum.rb +107 -0
- data/lib/ronin/core/params/types/float.rb +68 -0
- data/lib/ronin/core/params/types/integer.rb +100 -0
- data/lib/ronin/core/params/types/numeric.rb +106 -0
- data/lib/ronin/core/params/types/regexp.rb +67 -0
- data/lib/ronin/core/params/types/string.rb +118 -0
- data/lib/ronin/core/params/types/type.rb +54 -0
- data/lib/ronin/core/params/types/uri.rb +72 -0
- data/lib/ronin/core/params/types.rb +62 -0
- data/lib/ronin/core/params.rb +19 -0
- data/lib/ronin/core/version.rb +24 -0
- data/ronin-core.gemspec +59 -0
- data/spec/class_registry_spec.rb +224 -0
- data/spec/cli/command_shell/command_spec.rb +113 -0
- data/spec/cli/command_shell_spec.rb +1114 -0
- data/spec/cli/command_spec.rb +16 -0
- data/spec/cli/fixtures/irb_command +8 -0
- data/spec/cli/fixtures/template/dir/file1.txt +1 -0
- data/spec/cli/fixtures/template/dir/file2.txt +1 -0
- data/spec/cli/fixtures/template/file.erb +1 -0
- data/spec/cli/fixtures/template/file.txt +1 -0
- data/spec/cli/generator/options/author_spec.rb +121 -0
- data/spec/cli/generator/options/description_spec.rb +45 -0
- data/spec/cli/generator/options/reference_spec.rb +53 -0
- data/spec/cli/generator/options/summary_spec.rb +45 -0
- data/spec/cli/generator_spec.rb +244 -0
- data/spec/cli/logging_spec.rb +95 -0
- data/spec/cli/options/param_spec.rb +67 -0
- data/spec/cli/options/values/arches_spec.rb +62 -0
- data/spec/cli/printing/arch_spec.rb +130 -0
- data/spec/cli/printing/metadata_spec.rb +211 -0
- data/spec/cli/printing/os_spec.rb +64 -0
- data/spec/cli/printing/params_spec.rb +63 -0
- data/spec/cli/ruby_shell.rb +99 -0
- data/spec/cli/shell_spec.rb +211 -0
- data/spec/fixtures/example_class_registry/base_class.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/loaded_class.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/name_mismatch.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/no_module.rb +4 -0
- data/spec/fixtures/example_class_registry.rb +8 -0
- data/spec/git_spec.rb +58 -0
- data/spec/home_spec.rb +64 -0
- data/spec/metadata/authors/author_spec.rb +335 -0
- data/spec/metadata/authors_spec.rb +126 -0
- data/spec/metadata/description_spec.rb +74 -0
- data/spec/metadata/id_spec.rb +92 -0
- data/spec/metadata/references_spec.rb +100 -0
- data/spec/metadata/summary_spec.rb +74 -0
- data/spec/metadata/version_spec.rb +72 -0
- data/spec/params/mixin_spec.rb +484 -0
- data/spec/params/param_spec.rb +164 -0
- data/spec/params/types/boolean_spec.rb +56 -0
- data/spec/params/types/enum_spec.rb +94 -0
- data/spec/params/types/float_spec.rb +107 -0
- data/spec/params/types/integer_spec.rb +155 -0
- data/spec/params/types/numeric_spec.rb +138 -0
- data/spec/params/types/regexp_spec.rb +64 -0
- data/spec/params/types/string_spec.rb +174 -0
- data/spec/params/types/type_spec.rb +14 -0
- data/spec/params/types/uri_spec.rb +62 -0
- data/spec/spec_helper.rb +11 -0
- metadata +252 -0
|
@@ -0,0 +1,107 @@
|
|
|
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 mapping of Ruby values to their String equivalents.
|
|
27
|
+
#
|
|
28
|
+
class Enum < Type
|
|
29
|
+
|
|
30
|
+
# The values of the enum.
|
|
31
|
+
#
|
|
32
|
+
# @return [Array<Object>]
|
|
33
|
+
#
|
|
34
|
+
# @api semipublic
|
|
35
|
+
attr_reader :values
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# Initializes the enum type.
|
|
39
|
+
#
|
|
40
|
+
# @param [Array<Object>] values
|
|
41
|
+
# The values of the enum type.
|
|
42
|
+
#
|
|
43
|
+
# @raise [ArgumentError]
|
|
44
|
+
# Cannot initialize an enum type with an empty Array of values.
|
|
45
|
+
#
|
|
46
|
+
# @api semipublic
|
|
47
|
+
#
|
|
48
|
+
def initialize(values)
|
|
49
|
+
if values.empty?
|
|
50
|
+
raise(ArgumentError,"cannot initialize an empty Enum")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@values = values
|
|
54
|
+
@map = Hash[values.map { |value| [value.to_s, value] }]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Creates a new enum.
|
|
59
|
+
#
|
|
60
|
+
# @param [Array<Object>] values
|
|
61
|
+
# List of enum values.
|
|
62
|
+
#
|
|
63
|
+
# @return [Enum]
|
|
64
|
+
# The newly created enum object.
|
|
65
|
+
#
|
|
66
|
+
# @api public
|
|
67
|
+
#
|
|
68
|
+
def self.[](*values)
|
|
69
|
+
new(values)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
#
|
|
73
|
+
# Coerces the value into one of the enum values.
|
|
74
|
+
#
|
|
75
|
+
# @param [::String, ::Symbol, Object] value
|
|
76
|
+
#
|
|
77
|
+
# @return [Symbol]
|
|
78
|
+
# The coerced value.
|
|
79
|
+
#
|
|
80
|
+
# @raise [ValidationError]
|
|
81
|
+
# The value was not a valid enum value or a String that maps to an
|
|
82
|
+
# enum value.
|
|
83
|
+
#
|
|
84
|
+
# @api private
|
|
85
|
+
#
|
|
86
|
+
def coerce(value)
|
|
87
|
+
case value
|
|
88
|
+
when ::Symbol
|
|
89
|
+
unless @values.include?(value)
|
|
90
|
+
raise(ValidationError,"unknown value (#{value.inspect})")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
value
|
|
94
|
+
when ::String
|
|
95
|
+
@map.fetch(value) do
|
|
96
|
+
raise(ValidationError,"unknown value (#{value.inspect})")
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
raise(ValidationError,"value must be either a Symbol or a String (#{value.inspect})")
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
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/numeric'
|
|
20
|
+
|
|
21
|
+
module Ronin
|
|
22
|
+
module Core
|
|
23
|
+
module Params
|
|
24
|
+
module Types
|
|
25
|
+
#
|
|
26
|
+
# Represents a true/false param.
|
|
27
|
+
#
|
|
28
|
+
class Float < Numeric
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Coerces a value into a Float value.
|
|
32
|
+
#
|
|
33
|
+
# @param [::Float, ::String, #to_f, Object] value
|
|
34
|
+
# The value to coerce.
|
|
35
|
+
#
|
|
36
|
+
# @return [::Float]
|
|
37
|
+
# The coerced Float value.
|
|
38
|
+
#
|
|
39
|
+
# @raise [ValidationError]
|
|
40
|
+
# The value was not a Float, a String, or was not within {#range},
|
|
41
|
+
# or below {#min}, or above {#max}.
|
|
42
|
+
#
|
|
43
|
+
# @api private
|
|
44
|
+
#
|
|
45
|
+
def coerce(value)
|
|
46
|
+
case value
|
|
47
|
+
when ::Float
|
|
48
|
+
super(value)
|
|
49
|
+
when ::String
|
|
50
|
+
if value =~ /\A[+-]?\d+(?:\.\d+)?\z/
|
|
51
|
+
super(value.to_f)
|
|
52
|
+
else
|
|
53
|
+
raise(ValidationError,"value contains non-numeric characters (#{value.inspect})")
|
|
54
|
+
end
|
|
55
|
+
else
|
|
56
|
+
if value.respond_to?(:to_f)
|
|
57
|
+
super(value.to_f)
|
|
58
|
+
else
|
|
59
|
+
raise(ValidationError,"value does not define a #to_f method (#{value.inspect})")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
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/numeric'
|
|
20
|
+
|
|
21
|
+
module Ronin
|
|
22
|
+
module Core
|
|
23
|
+
module Params
|
|
24
|
+
module Types
|
|
25
|
+
#
|
|
26
|
+
# Represents a numeric value.
|
|
27
|
+
#
|
|
28
|
+
class Integer < Numeric
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Coerces a String into an Integer value.
|
|
32
|
+
#
|
|
33
|
+
# @param [::Integer, ::String, #to_i, Object] value
|
|
34
|
+
# The given value to coerce.
|
|
35
|
+
#
|
|
36
|
+
# @return [::Integer]
|
|
37
|
+
# The coerced Integer value.
|
|
38
|
+
#
|
|
39
|
+
# @raise [ValidationError]
|
|
40
|
+
# The value was not an Integer, a String, or was not within
|
|
41
|
+
# {#range}, or below {#min}, or above {#max}.
|
|
42
|
+
#
|
|
43
|
+
# @api private
|
|
44
|
+
#
|
|
45
|
+
def coerce(value)
|
|
46
|
+
case value
|
|
47
|
+
when ::Integer then super(value)
|
|
48
|
+
when ::String
|
|
49
|
+
case value
|
|
50
|
+
when /\A[+-]?\d+\z/
|
|
51
|
+
super(value.to_i)
|
|
52
|
+
when /\A[+-]?0b[01]+\z/
|
|
53
|
+
super(parse_binary(value))
|
|
54
|
+
when /\A[+-]?(?:0x)?[0-9A-Fa-f]+\z/
|
|
55
|
+
super(parse_hexadecimal(value))
|
|
56
|
+
else
|
|
57
|
+
raise(ValidationError,"value contains non-numeric characters (#{value.inspect})")
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
if value.respond_to?(:to_i)
|
|
61
|
+
super(value.to_i)
|
|
62
|
+
else
|
|
63
|
+
raise(ValidationError,"value does not define a #to_i method (#{value.inspect})")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Parses a binary string.
|
|
72
|
+
#
|
|
73
|
+
# @param [::String] string
|
|
74
|
+
#
|
|
75
|
+
# @return [::Integer]
|
|
76
|
+
#
|
|
77
|
+
def parse_binary(string)
|
|
78
|
+
integer = string.sub(/\A[+-]?0b/,'').to_i(2)
|
|
79
|
+
integer = -integer if string.start_with?('-')
|
|
80
|
+
integer
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Parses a hexadecimal string.
|
|
85
|
+
#
|
|
86
|
+
# @param [::String] string
|
|
87
|
+
#
|
|
88
|
+
# @return [::Integer]
|
|
89
|
+
#
|
|
90
|
+
def parse_hexadecimal(string)
|
|
91
|
+
integer = string.sub(/\A[+-]?(?:0x)?/,'').to_i(16)
|
|
92
|
+
integer = -integer if string.start_with?('-')
|
|
93
|
+
integer
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
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 Numeric < Type
|
|
29
|
+
|
|
30
|
+
# The optional minimum value.
|
|
31
|
+
#
|
|
32
|
+
# @return [::Integer, nil]
|
|
33
|
+
#
|
|
34
|
+
# @api private
|
|
35
|
+
attr_reader :min
|
|
36
|
+
|
|
37
|
+
# The optional maximum value.
|
|
38
|
+
#
|
|
39
|
+
# @return [::Integer, nil]
|
|
40
|
+
#
|
|
41
|
+
# @api private
|
|
42
|
+
attr_reader :max
|
|
43
|
+
|
|
44
|
+
# The optional range of acceptable numbers.
|
|
45
|
+
#
|
|
46
|
+
# @return [Range, nil]
|
|
47
|
+
#
|
|
48
|
+
# @api private
|
|
49
|
+
attr_reader :range
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# Initializes the numeric value.
|
|
53
|
+
#
|
|
54
|
+
# @param [::Integer, nil] min
|
|
55
|
+
# Optional minimum value for the integer param.
|
|
56
|
+
#
|
|
57
|
+
# @param [::Integer, nil] max
|
|
58
|
+
# Optional maximum value for the integer param.
|
|
59
|
+
#
|
|
60
|
+
# @param [Range] range
|
|
61
|
+
# Optional range of acceptable integers.
|
|
62
|
+
#
|
|
63
|
+
def initialize(min: nil, max: nil, range: nil)
|
|
64
|
+
@min = min
|
|
65
|
+
@max = max
|
|
66
|
+
@range = range
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# Validates a numeric value.
|
|
71
|
+
#
|
|
72
|
+
# @param [::Integer, ::Float] value
|
|
73
|
+
# The value to validate.
|
|
74
|
+
#
|
|
75
|
+
# @return [::Integer, ::Float]
|
|
76
|
+
# The validated value.
|
|
77
|
+
#
|
|
78
|
+
# @raise [ValidationError]
|
|
79
|
+
# The value was not within {#range}, or below {#min}, or above
|
|
80
|
+
# {#max}.
|
|
81
|
+
#
|
|
82
|
+
# @abstract
|
|
83
|
+
#
|
|
84
|
+
def coerce(value)
|
|
85
|
+
if @range
|
|
86
|
+
unless @range.include?(value)
|
|
87
|
+
raise(ValidationError,"value is not within the range of acceptable values #{@range.begin}-#{@range.end} (#{value.inspect})")
|
|
88
|
+
end
|
|
89
|
+
else
|
|
90
|
+
if @min && (value < @min)
|
|
91
|
+
raise(ValidationError,"value is below minimum value of #{@min} (#{value.inspect})")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if @max && (value > @max)
|
|
95
|
+
raise(ValidationError,"value is above maximum value of #{@max} (#{value.inspect})")
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
return value
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
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 Regexp type.
|
|
27
|
+
#
|
|
28
|
+
class Regexp < Type
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Parses the String value.
|
|
32
|
+
#
|
|
33
|
+
# @param [::String, ::Regexp, Object] value
|
|
34
|
+
# The String value to coerce.
|
|
35
|
+
#
|
|
36
|
+
# @return [Regexp]
|
|
37
|
+
# The coerced Regexp value.
|
|
38
|
+
#
|
|
39
|
+
# @raise [ValidationError]
|
|
40
|
+
# The value was not a Regexp, a String, or a String that could not
|
|
41
|
+
# be parsed by `Regexp.new`.
|
|
42
|
+
#
|
|
43
|
+
# @api private
|
|
44
|
+
#
|
|
45
|
+
def coerce(value)
|
|
46
|
+
case value
|
|
47
|
+
when ::Regexp then value
|
|
48
|
+
when ::String
|
|
49
|
+
unless (value.start_with?('/') && value.end_with?('/'))
|
|
50
|
+
raise(ValidationError,"value must be of the format '/.../' (#{value.inspect})")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
begin
|
|
54
|
+
::Regexp.new(value[1..-2])
|
|
55
|
+
rescue RegexpError
|
|
56
|
+
raise(ValidationError,"value is not a valid Regexp (#{value.inspect})")
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
raise(ValidationError,"value must be either a String or a Regexp (#{value.inspect})")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
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 string type.
|
|
27
|
+
#
|
|
28
|
+
class String < Type
|
|
29
|
+
|
|
30
|
+
# Optional regexp to validate values with.
|
|
31
|
+
#
|
|
32
|
+
# @return [::Regexp, nil]
|
|
33
|
+
attr_reader :format
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Initializes the value.
|
|
37
|
+
#
|
|
38
|
+
# @param [::Boolean] allow_empty
|
|
39
|
+
# Specifies whether the argument may accept empty values.
|
|
40
|
+
#
|
|
41
|
+
# @param [::Boolean] allow_blank
|
|
42
|
+
# Specifies whether the argument may accept blank values.
|
|
43
|
+
#
|
|
44
|
+
# @param [(::Regexp, ::String), nil] format
|
|
45
|
+
# Optional regular expression to validate the given param value.
|
|
46
|
+
#
|
|
47
|
+
def initialize(allow_empty: false, allow_blank: false, format: nil)
|
|
48
|
+
@allow_empty = allow_empty
|
|
49
|
+
@allow_blank = allow_blank
|
|
50
|
+
|
|
51
|
+
@format = format
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Specifies whether the param may accept empty values.
|
|
56
|
+
#
|
|
57
|
+
# @return [::Boolean]
|
|
58
|
+
#
|
|
59
|
+
# @api private
|
|
60
|
+
#
|
|
61
|
+
def allow_empty?
|
|
62
|
+
@allow_empty
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
#
|
|
66
|
+
# Specifies whether the param may accept blank values.
|
|
67
|
+
#
|
|
68
|
+
# @return [::Boolean]
|
|
69
|
+
#
|
|
70
|
+
# @api private
|
|
71
|
+
#
|
|
72
|
+
def allow_blank?
|
|
73
|
+
@allow_blank
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# Validates the given value.
|
|
78
|
+
#
|
|
79
|
+
# @param [Object] value
|
|
80
|
+
# The given value to validate.
|
|
81
|
+
#
|
|
82
|
+
# @return [::String]
|
|
83
|
+
# The coerced String.
|
|
84
|
+
#
|
|
85
|
+
# @raise [ValidationError]
|
|
86
|
+
# The given value was not a String and did not define a `#to_s`
|
|
87
|
+
# method, or was a String that did not match {#format}.
|
|
88
|
+
#
|
|
89
|
+
# @api private
|
|
90
|
+
#
|
|
91
|
+
def coerce(value)
|
|
92
|
+
case value
|
|
93
|
+
when Enumerable
|
|
94
|
+
raise(ValidationError,"cannot convert an Enumerable into a String (#{value.inspect})")
|
|
95
|
+
else
|
|
96
|
+
unless value.respond_to?(:to_s)
|
|
97
|
+
raise(ValidationError,"value does not define a #to_s method (#{value.inspect})")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
string = value.to_s
|
|
101
|
+
|
|
102
|
+
if @format && string !~ @format
|
|
103
|
+
raise(ValidationError,"does not match the format (#{string.inspect})")
|
|
104
|
+
elsif (string.empty? && !allow_empty?)
|
|
105
|
+
raise(ValidationError,"value cannot be empty")
|
|
106
|
+
elsif (string =~ /\A\s+\z/ && !allow_blank?)
|
|
107
|
+
raise(ValidationError,"value cannot contain all whitespace (#{string.inspect})")
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
return string
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
|
|
21
|
+
module Ronin
|
|
22
|
+
module Core
|
|
23
|
+
module Params
|
|
24
|
+
module Types
|
|
25
|
+
#
|
|
26
|
+
# The base type for all command-line argument types.
|
|
27
|
+
#
|
|
28
|
+
# @api private
|
|
29
|
+
#
|
|
30
|
+
class Type
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# The default coerce method.
|
|
34
|
+
#
|
|
35
|
+
# @param [Object] value
|
|
36
|
+
# The value to coerce.
|
|
37
|
+
#
|
|
38
|
+
# @return [Object]
|
|
39
|
+
# The coerced value.
|
|
40
|
+
#
|
|
41
|
+
# @raise [ValidationError]
|
|
42
|
+
# The given value was invalid.
|
|
43
|
+
#
|
|
44
|
+
# @abstract
|
|
45
|
+
#
|
|
46
|
+
def coerce(value)
|
|
47
|
+
raise(NotImplementedError,"#{self.class}##{__method__} method was not implemented")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
require 'uri'
|
|
22
|
+
|
|
23
|
+
module Ronin
|
|
24
|
+
module Core
|
|
25
|
+
module Params
|
|
26
|
+
module Types
|
|
27
|
+
#
|
|
28
|
+
# Represents a URL type.
|
|
29
|
+
#
|
|
30
|
+
class URI < Type
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Parses the String value.
|
|
34
|
+
#
|
|
35
|
+
# @param [::String, ::URI, Object] value
|
|
36
|
+
# The String value to coerce.
|
|
37
|
+
#
|
|
38
|
+
# @return [::URI]
|
|
39
|
+
# The coerced URI value.
|
|
40
|
+
#
|
|
41
|
+
# @raise [ValidationError]
|
|
42
|
+
# The given value was invalid.
|
|
43
|
+
#
|
|
44
|
+
# @api private
|
|
45
|
+
#
|
|
46
|
+
def coerce(value)
|
|
47
|
+
case value
|
|
48
|
+
when ::URI then value
|
|
49
|
+
when ::String
|
|
50
|
+
if value.empty?
|
|
51
|
+
raise(ValidationError,"value must not be empty")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
unless value =~ /\A[a-z]+:/
|
|
55
|
+
raise(ValidationError,"value must start with a 'scheme:' (#{value.inspect})")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
begin
|
|
59
|
+
::URI.parse(value)
|
|
60
|
+
rescue ::URI::InvalidURIError
|
|
61
|
+
raise(ValidationError,"value is not a valid URI (#{value.inspect})")
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
raise(ValidationError,"value must be either a String or a URI (#{value.inspect})")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|