opt_parse_validator 0.0.2
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/.gitignore +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +4 -0
- data/.simplecov +4 -0
- data/.travis.yml +15 -0
- data/Gemfile +6 -0
- data/README.md +40 -0
- data/Rakefile +9 -0
- data/lib/opt_parse_validator/hacks.rb +15 -0
- data/lib/opt_parse_validator/options_file.rb +62 -0
- data/lib/opt_parse_validator/opts/base.rb +74 -0
- data/lib/opt_parse_validator/opts/boolean.rb +20 -0
- data/lib/opt_parse_validator/opts/choice.rb +33 -0
- data/lib/opt_parse_validator/opts/credentials.rb +14 -0
- data/lib/opt_parse_validator/opts/directory_path.rb +10 -0
- data/lib/opt_parse_validator/opts/file_path.rb +24 -0
- data/lib/opt_parse_validator/opts/integer.rb +12 -0
- data/lib/opt_parse_validator/opts/path.rb +61 -0
- data/lib/opt_parse_validator/opts/positive_integer.rb +13 -0
- data/lib/opt_parse_validator/opts/proxy.rb +5 -0
- data/lib/opt_parse_validator/opts/string.rb +6 -0
- data/lib/opt_parse_validator/opts/uri.rb +24 -0
- data/lib/opt_parse_validator/opts/url.rb +9 -0
- data/lib/opt_parse_validator/opts.rb +3 -0
- data/lib/opt_parse_validator/version.rb +4 -0
- data/lib/opt_parse_validator.rb +77 -0
- data/opt_parse_validator.gemspec +32 -0
- data/spec/fixtures/options_file/default.json +4 -0
- data/spec/fixtures/options_file/malformed.json +4 -0
- data/spec/fixtures/options_file/override.yml +1 -0
- data/spec/fixtures/options_file/unsupported.ext +1 -0
- data/spec/fixtures/r.txt +1 -0
- data/spec/fixtures/rwx.txt +1 -0
- data/spec/lib/opt_parse_validator/options_file_spec.rb +50 -0
- data/spec/lib/opt_parse_validator/opts/base_spec.rb +169 -0
- data/spec/lib/opt_parse_validator/opts/boolean_spec.rb +36 -0
- data/spec/lib/opt_parse_validator/opts/choice_spec.rb +78 -0
- data/spec/lib/opt_parse_validator/opts/credentials_spec.rb +23 -0
- data/spec/lib/opt_parse_validator/opts/direcyory_path_spec.rb +25 -0
- data/spec/lib/opt_parse_validator/opts/file_path_spec.rb +93 -0
- data/spec/lib/opt_parse_validator/opts/integer_spec.rb +19 -0
- data/spec/lib/opt_parse_validator/opts/path_spec.rb +7 -0
- data/spec/lib/opt_parse_validator/opts/positive_integer_spec.rb +19 -0
- data/spec/lib/opt_parse_validator/opts/proxy_spec.rb +12 -0
- data/spec/lib/opt_parse_validator/opts/uri_spec.rb +58 -0
- data/spec/lib/opt_parse_validator/opts/url_spec.rb +28 -0
- data/spec/lib/opt_parse_validator/version_spec.rb +7 -0
- data/spec/lib/opt_parse_validator_spec.rb +152 -0
- data/spec/spec_helper.rb +25 -0
- metadata +213 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 1b0a34c11c84d6fa32580ed925dac42346cee747
|
|
4
|
+
data.tar.gz: 7c50ea36943042d5cf7f8b77c15fd93b0969339c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 051c726116d357bd876f87d9a113ba3c00f53a2b146e92e69d2447bef77de471fe2150f2c834356d52a1ec0b5b14f0b8e94e3177e3e6c84190ceac2068be1579
|
|
7
|
+
data.tar.gz: 910103742d3c7cfab15980043a02a169a9708f4ed3f11086ee280eec9d8cdd57621d82a8cf04f7739083f7384fd50c98e45ac2e5a129175c5a5461f52d2c8ff6
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.simplecov
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
OptParseValidator
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
[](https://travis-ci.org/wpscanteam/OptParseValidator)
|
|
5
|
+
[](https://coveralls.io/r/wpscanteam/OptParseValidator?branch=master)
|
|
6
|
+
[](https://codeclimate.com/github/wpscanteam/OptParseValidator)
|
|
7
|
+
[](https://gemnasium.com/wpscanteam/OptParseValidator)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Available Validators & associated attributes:
|
|
11
|
+
- Boolean
|
|
12
|
+
- Choice
|
|
13
|
+
- :choices (mandatory)
|
|
14
|
+
- :case_sensitive
|
|
15
|
+
- Credentials
|
|
16
|
+
- Directory Path
|
|
17
|
+
- :exists
|
|
18
|
+
- :executable
|
|
19
|
+
- :readable
|
|
20
|
+
- :writable
|
|
21
|
+
- File Path
|
|
22
|
+
- :exists
|
|
23
|
+
- :executable
|
|
24
|
+
- :readable
|
|
25
|
+
- :writable
|
|
26
|
+
- Integer
|
|
27
|
+
- Positive Integer
|
|
28
|
+
- Path
|
|
29
|
+
- :file
|
|
30
|
+
- :directory
|
|
31
|
+
- :exists
|
|
32
|
+
- :executable
|
|
33
|
+
- :readable
|
|
34
|
+
- :writable
|
|
35
|
+
- Proxy
|
|
36
|
+
- :protocols
|
|
37
|
+
- String
|
|
38
|
+
- URI
|
|
39
|
+
- :protocols
|
|
40
|
+
- URL
|
data/Rakefile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class OptionParser
|
|
2
|
+
# Hack to suppress the completion (expect for the -h/--help) which was leading to
|
|
3
|
+
# unwanted behaviours
|
|
4
|
+
# See https://github.com/wpscanteam/CMSScanner/issues/2
|
|
5
|
+
module Completion
|
|
6
|
+
class << self
|
|
7
|
+
alias_method :original_candidate, :candidate
|
|
8
|
+
|
|
9
|
+
def candidate(key, icase = false, pat = nil, &block)
|
|
10
|
+
# Maybe also do this for -v/--version ?
|
|
11
|
+
key == 'h' ? original_candidate('help', icase, pat, &block) : []
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
module OptParseValidator
|
|
5
|
+
# TODO
|
|
6
|
+
class OptParser < OptionParser
|
|
7
|
+
def options_files
|
|
8
|
+
@options_files ||= []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def load_options_files
|
|
12
|
+
files_data = {}
|
|
13
|
+
|
|
14
|
+
options_files.each do |file|
|
|
15
|
+
data = parse_file(file)
|
|
16
|
+
files_data.merge!(data) if data
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
@opts.each do |opt|
|
|
20
|
+
# Annoying thing: the hash returned from parse_file is a string-full {"key"=>"value"}
|
|
21
|
+
# and not a ruby hash {key: value} :/ As a result, symbol.to_s has to be used
|
|
22
|
+
next unless files_data.key?(opt.to_sym.to_s)
|
|
23
|
+
|
|
24
|
+
@results[opt.to_sym] = opt.normalize(opt.validate(files_data[opt.to_sym.to_s]))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
protected
|
|
29
|
+
|
|
30
|
+
# @param [ String ] file_path
|
|
31
|
+
#
|
|
32
|
+
# @return [ Hash ]
|
|
33
|
+
def parse_file(file_path)
|
|
34
|
+
return unless File.exist?(file_path)
|
|
35
|
+
|
|
36
|
+
file_ext = File.extname(file_path).delete('.')
|
|
37
|
+
method_to_call = "parse_#{file_ext}"
|
|
38
|
+
|
|
39
|
+
fail "The format #{file_ext} is not supported" unless respond_to?(method_to_call, true) # The true allows to check protected & private methods
|
|
40
|
+
|
|
41
|
+
begin
|
|
42
|
+
method(method_to_call).call(file_path)
|
|
43
|
+
rescue
|
|
44
|
+
raise "Parse Error, #{file_path} seems to be malformed"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @param [ String ] file_path
|
|
49
|
+
#
|
|
50
|
+
# @return [ Hash ]
|
|
51
|
+
def parse_json(file_path)
|
|
52
|
+
JSON.parse(File.read(file_path))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @param [ String ] file_path
|
|
56
|
+
#
|
|
57
|
+
# @return [ Hash ]
|
|
58
|
+
def parse_yml(file_path)
|
|
59
|
+
YAML.load_file(file_path)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Base Option
|
|
3
|
+
# This Option should not be called, children should be used.
|
|
4
|
+
class OptBase
|
|
5
|
+
attr_writer :required
|
|
6
|
+
attr_reader :option, :attrs
|
|
7
|
+
|
|
8
|
+
# @param [ Array ] option See OptionParser#on
|
|
9
|
+
# @param [ Hash ] attrs
|
|
10
|
+
# @option attrs [ Boolean ] :required
|
|
11
|
+
# @option attrs [ Mixed ] :default The default value to use if the option is not supplied
|
|
12
|
+
# @option attrs [ Boolean ] :to_sym If true, returns the symbol of the validated value
|
|
13
|
+
# @option attrs [ Array<Symbol> ] :normalize See #normalize
|
|
14
|
+
#
|
|
15
|
+
# @note The :default and :normalize 'logics' are done in OptParseValidator::OptParser#add_option
|
|
16
|
+
def initialize(option, attrs = {})
|
|
17
|
+
@option = option
|
|
18
|
+
@attrs = attrs
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [ Boolean ]
|
|
22
|
+
def required?
|
|
23
|
+
@required || attrs[:required]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @param [ String ] value
|
|
27
|
+
def validate(value)
|
|
28
|
+
fail 'Empty option value supplied' if value.nil? || value.to_s.empty?
|
|
29
|
+
value
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Apply each methods from attrs[:normalize] to the value if possible
|
|
33
|
+
# User input should not be used in this attrs[:normalize]
|
|
34
|
+
#
|
|
35
|
+
# e.g: normalize: :to_sym will return the symbol of the value
|
|
36
|
+
# normalize: [:to_sym, :upcase] Will return the upercased symbol
|
|
37
|
+
#
|
|
38
|
+
# @param [ Mixed ] value
|
|
39
|
+
#
|
|
40
|
+
# @return [ Mixed ]
|
|
41
|
+
def normalize(value)
|
|
42
|
+
[*attrs[:normalize]].each do |method|
|
|
43
|
+
next unless method.is_a?(Symbol)
|
|
44
|
+
|
|
45
|
+
value = value.send(method) if value.respond_to?(method)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
value
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @return [ Symbol ]
|
|
52
|
+
def to_sym
|
|
53
|
+
unless @symbol
|
|
54
|
+
long_option = to_long
|
|
55
|
+
|
|
56
|
+
fail "Could not find option symbol for #{option}" unless long_option
|
|
57
|
+
|
|
58
|
+
@symbol = long_option.gsub(/^--/, '').gsub(/-/, '_').to_sym
|
|
59
|
+
end
|
|
60
|
+
@symbol
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [ String ] The raw long option (e.g: --proxy)
|
|
64
|
+
def to_long
|
|
65
|
+
option.each do |option_attr|
|
|
66
|
+
if option_attr =~ /^--/
|
|
67
|
+
return option_attr.gsub(/ .*$/, '')
|
|
68
|
+
.gsub(/\[[^\]]+\]/, '')
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
nil
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Implementation of the Boolean Option
|
|
3
|
+
class OptBoolean < OptBase
|
|
4
|
+
TRUE_PATTERN = /\A(true|t|yes|y|1)\z/i
|
|
5
|
+
FALSE_PATTERN = /\A(false|f|no|n|0)\z/i
|
|
6
|
+
|
|
7
|
+
# @return [ Boolean ]
|
|
8
|
+
def validate(value)
|
|
9
|
+
value = value.to_s
|
|
10
|
+
|
|
11
|
+
if value.match(TRUE_PATTERN)
|
|
12
|
+
return true
|
|
13
|
+
elsif value.match(FALSE_PATTERN)
|
|
14
|
+
return false
|
|
15
|
+
else
|
|
16
|
+
fail 'Invalid boolean value, expected true|t|yes|y|1|false|f|no|n|0'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Implementation of the Choice Option
|
|
3
|
+
class OptChoice < OptBase
|
|
4
|
+
# @param [ Array ] option See OptBase#new
|
|
5
|
+
# @param [ Hash ] attrs
|
|
6
|
+
# :choices [ Array ] The available choices (mandatory)
|
|
7
|
+
# :case_sensitive [ Boolean ] Default: false
|
|
8
|
+
def initialize(option, attrs = {})
|
|
9
|
+
fail 'The :choices attribute is mandatory' unless attrs.key?(:choices)
|
|
10
|
+
fail 'The :choices attribute must be an array' unless attrs[:choices].is_a?(Array)
|
|
11
|
+
|
|
12
|
+
super(option, attrs)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [ String ]
|
|
16
|
+
# If :case_sensitive if false (or nil), the downcased value of the choice
|
|
17
|
+
# will be returned
|
|
18
|
+
def validate(value)
|
|
19
|
+
value = value.to_s
|
|
20
|
+
choices = attrs[:choices]
|
|
21
|
+
|
|
22
|
+
unless attrs[:case_sensitive]
|
|
23
|
+
value.downcase!
|
|
24
|
+
choices.map!(&:downcase)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
fail "'#{value}' is not a valid choice, expected one " \
|
|
28
|
+
"of the followings: #{choices.join(',')}" unless choices.include?(value)
|
|
29
|
+
|
|
30
|
+
value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Implementation of the Credentials Option
|
|
3
|
+
class OptCredentials < OptBase
|
|
4
|
+
# @return [ Hash ] A hash containing the :username and :password
|
|
5
|
+
def validate(value)
|
|
6
|
+
unless value.index(':')
|
|
7
|
+
fail 'Incorrect credentials format, username:password expected'
|
|
8
|
+
end
|
|
9
|
+
creds = value.split(':', 2)
|
|
10
|
+
|
|
11
|
+
{ username: creds[0], password: creds[1] }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Implementation of the FilePath Option
|
|
3
|
+
class OptFilePath < OptPath
|
|
4
|
+
# @param [ Array ] option See OptBase#new
|
|
5
|
+
# @param [ Hash ] attrs See OptPath#new
|
|
6
|
+
# :extensions [ Array | String ] The allowed extension(s)
|
|
7
|
+
def initialize(option, attrs = {})
|
|
8
|
+
super(option, attrs)
|
|
9
|
+
|
|
10
|
+
@attrs.merge!(file: true)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def allowed_attrs
|
|
14
|
+
# :extensions is put at the first place
|
|
15
|
+
[:extensions] + super
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def check_extensions(path)
|
|
19
|
+
return if [*attrs[:extensions]].include?(path.extname.delete('.'))
|
|
20
|
+
|
|
21
|
+
fail "The extension of '#{path}' is not allowed"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Implementation of the Integer Option
|
|
3
|
+
class OptInteger < OptBase
|
|
4
|
+
# @param [ String ] value
|
|
5
|
+
#
|
|
6
|
+
# @return [ Integer ]
|
|
7
|
+
def validate(value)
|
|
8
|
+
fail "#{value} is not an integer" if value.to_i.to_s != value
|
|
9
|
+
value.to_i
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Implementation of the Path Option
|
|
3
|
+
class OptPath < OptBase
|
|
4
|
+
# Initialize attrs:
|
|
5
|
+
#
|
|
6
|
+
# :exists if set to false, will ignore the file? and directory? checks
|
|
7
|
+
#
|
|
8
|
+
# :file Check if the path is a file
|
|
9
|
+
# :directory Check if the path is a directory
|
|
10
|
+
#
|
|
11
|
+
# :executable
|
|
12
|
+
# :readable
|
|
13
|
+
# :writable
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
# @param [ String ] value
|
|
17
|
+
#
|
|
18
|
+
# @return [ String ]
|
|
19
|
+
def validate(value)
|
|
20
|
+
path = Pathname.new(value)
|
|
21
|
+
allowed_attrs.each do |key|
|
|
22
|
+
method = "check_#{key}"
|
|
23
|
+
send(method, path) if self.respond_to?(method) && attrs[key]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
path.to_s
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def allowed_attrs
|
|
30
|
+
[:file, :directory, :executable, :readable, :writable]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @param [ Pathname ] path
|
|
34
|
+
def check_file(path)
|
|
35
|
+
fail "'#{path}' is not a file" unless path.file? || attrs[:exists] == false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @param [ Pathname ] path
|
|
39
|
+
def check_directory(path)
|
|
40
|
+
fail "'#{path}' is not a directory" unless path.directory? || attrs[:exists] == false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @param [ Pathname ] path
|
|
44
|
+
def check_executable(path)
|
|
45
|
+
fail "'#{path}' is not executable" unless path.executable?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @param [ Pathname ] path
|
|
49
|
+
def check_readable(path)
|
|
50
|
+
fail "'#{path}' is not readable" unless path.readable?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# If the path does not exist, it will check for the parent
|
|
54
|
+
# directory write permission
|
|
55
|
+
#
|
|
56
|
+
# @param [ Pathname ] path
|
|
57
|
+
def check_writable(path)
|
|
58
|
+
fail "'#{path}' is not writable" if path.exist? && !path.writable? || !path.parent.writable?
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Implementation of the Positive Integer Option
|
|
3
|
+
class OptPositiveInteger < OptInteger
|
|
4
|
+
# @param [ String ] value
|
|
5
|
+
#
|
|
6
|
+
# @return [ Integer ]
|
|
7
|
+
def validate(value)
|
|
8
|
+
i = super(value)
|
|
9
|
+
fail "#{i} is not > 0" unless i > 0
|
|
10
|
+
i
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module OptParseValidator
|
|
2
|
+
# Implementation of the URI Option
|
|
3
|
+
class OptURI < OptBase
|
|
4
|
+
def allowed_protocols
|
|
5
|
+
@allowed_protocols ||= [*attrs[:protocols]]
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# @param [ String ] value
|
|
9
|
+
#
|
|
10
|
+
# @return [ String ]
|
|
11
|
+
def validate(value)
|
|
12
|
+
uri = Addressable::URI.parse(value)
|
|
13
|
+
protocols = allowed_protocols
|
|
14
|
+
|
|
15
|
+
unless protocols.empty? || protocols.include?(uri.scheme)
|
|
16
|
+
# For future refs: will have to check if the uri.scheme exists,
|
|
17
|
+
# otherwise it means that the value was empty
|
|
18
|
+
fail Addressable::URI::InvalidURIError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
uri.to_s
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Gems
|
|
2
|
+
require 'addressable/uri'
|
|
3
|
+
# Standard Libs
|
|
4
|
+
require 'optparse'
|
|
5
|
+
require 'pathname'
|
|
6
|
+
# Custom Libs
|
|
7
|
+
require 'opt_parse_validator/hacks'
|
|
8
|
+
require 'opt_parse_validator/opts'
|
|
9
|
+
require 'opt_parse_validator/version'
|
|
10
|
+
require 'opt_parse_validator/options_file'
|
|
11
|
+
|
|
12
|
+
# Gem namespace
|
|
13
|
+
module OptParseValidator
|
|
14
|
+
# Validator
|
|
15
|
+
class OptParser < OptionParser
|
|
16
|
+
attr_reader :symbols_used, :opts
|
|
17
|
+
|
|
18
|
+
def initialize(banner = nil, width = 32, indent = ' ' * 4)
|
|
19
|
+
@results = {}
|
|
20
|
+
@symbols_used = []
|
|
21
|
+
@opts = []
|
|
22
|
+
|
|
23
|
+
super(banner, width, indent)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @param [ OptBase ] options
|
|
27
|
+
#
|
|
28
|
+
# @return [ void ]
|
|
29
|
+
def add(*options)
|
|
30
|
+
options.each { |option| add_option(option) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @param [ OptBase ] opt
|
|
34
|
+
#
|
|
35
|
+
# @return [ void ]
|
|
36
|
+
def add_option(opt)
|
|
37
|
+
fail "The option is not an OptBase, #{opt.class} supplied" unless opt.is_a?(OptBase)
|
|
38
|
+
fail "The option #{opt.to_sym} is already used !" if @symbols_used.include?(opt.to_sym)
|
|
39
|
+
|
|
40
|
+
@opts << opt
|
|
41
|
+
@symbols_used << opt.to_sym
|
|
42
|
+
# Set the default option value if it exists
|
|
43
|
+
@results[opt.to_sym] = opt.attrs[:default] if opt.attrs.key?(:default)
|
|
44
|
+
|
|
45
|
+
on(*opt.option) do |arg|
|
|
46
|
+
begin
|
|
47
|
+
@results[opt.to_sym] = opt.normalize(opt.validate(arg))
|
|
48
|
+
rescue => e
|
|
49
|
+
# Adds the long option name to the message
|
|
50
|
+
# e.g --proxy Invalid Scheme format.
|
|
51
|
+
raise e.class, "#{opt.to_long} #{e}"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @return [ Hash ]
|
|
57
|
+
def results(argv = default_argv)
|
|
58
|
+
load_options_files
|
|
59
|
+
self.parse!(argv)
|
|
60
|
+
post_processing
|
|
61
|
+
|
|
62
|
+
@results
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Ensure that all required options are supplied
|
|
66
|
+
# Should be overriden to modify the behavior
|
|
67
|
+
#
|
|
68
|
+
# @return [ Void ]
|
|
69
|
+
def post_processing
|
|
70
|
+
@opts.each do |opt|
|
|
71
|
+
next unless opt.required? && !@results.key?(opt.to_sym)
|
|
72
|
+
|
|
73
|
+
fail "The option #{opt.to_sym} is required"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
|
|
5
|
+
require 'opt_parse_validator/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |s|
|
|
8
|
+
s.name = 'opt_parse_validator'
|
|
9
|
+
s.version = OptParseValidator::VERSION
|
|
10
|
+
s.platform = Gem::Platform::RUBY
|
|
11
|
+
s.required_ruby_version = '>= 2.0.0'
|
|
12
|
+
s.authors = ['WPScanTeam - Erwan le Rousseau']
|
|
13
|
+
s.email = ['erwan.lr@gmail.com']
|
|
14
|
+
s.summary = 'Testing Gem'
|
|
15
|
+
s.description = 'Testing Gem ...'
|
|
16
|
+
s.homepage = 'https://github.com/wpscanteam/OptParseValidator'
|
|
17
|
+
s.license = 'MIT'
|
|
18
|
+
|
|
19
|
+
s.files = `git ls-files -z`.split("\x0")
|
|
20
|
+
s.executables = s.files.grep(/^bin\//) { |f| File.basename(f) }
|
|
21
|
+
s.test_files = s.files.grep(/^(test|spec|features)\//)
|
|
22
|
+
s.require_paths = ['lib']
|
|
23
|
+
|
|
24
|
+
s.add_dependency 'addressable', '~> 2.3'
|
|
25
|
+
|
|
26
|
+
s.add_development_dependency 'rake'
|
|
27
|
+
s.add_development_dependency 'rspec', '~> 3.1'
|
|
28
|
+
s.add_development_dependency 'rspec-its'
|
|
29
|
+
s.add_development_dependency 'bundler', '~> 1.6'
|
|
30
|
+
s.add_development_dependency 'rubocop', '~> 0.26'
|
|
31
|
+
s.add_development_dependency 'simplecov', '~> 0.9'
|
|
32
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
override_me: "Yeaa"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Unsupported file format
|
data/spec/fixtures/r.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This file is a chmod 400
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This file is a chmod 777
|