getopt 1.6.0 → 1.7.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
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +6 -2
- data/Gemfile +2 -3
- data/MANIFEST.md +2 -2
- data/README.md +5 -2
- data/Rakefile +12 -2
- data/getopt.gemspec +12 -7
- data/lib/getopt/long.rb +246 -224
- data/lib/getopt/std.rb +91 -91
- data/lib/getopt/version.rb +3 -1
- data/spec/getopt_long_spec.rb +200 -121
- data/spec/getopt_std_spec.rb +74 -71
- data.tar.gz.sig +0 -0
- metadata +36 -8
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e45a7211aea22472efcebd09ba6aa5b344eac0441213144d6c8c408d0adfabf5
|
|
4
|
+
data.tar.gz: 2a95d618c4ededa6de05a091429c85dc38cdd5f43d75618587e5a74d589bcd50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ecda8ad35cfaac66dd59c0432796a7901f22f351ee2fd347aff8e4f0a730a5ca963fe428608de5988a7f00bd367c1d3e6b4f3865bc44cb4762a06962b831ca3c
|
|
7
|
+
data.tar.gz: 9b5308a4a046cb6df55353114bd396749c75443d75e4c8c1f2c886702420e16a2bb57cec3fc253ee17f2cea9d9dfbad9a2d5e84e60cb984aae09cfa389380962
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGES.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
# 1.7.0 - 13-Feb-2026
|
|
2
|
+
* Added the NEGATABLE option so you can do --no-whatever.
|
|
3
|
+
* A few warnings were cleaned up, along with rubocop updates.
|
|
4
|
+
* Some administrative stuff, updated Rakefile, Gemfile, etc.
|
|
5
|
+
|
|
1
6
|
## 1.6.0 - 2-Mar-2021
|
|
2
|
-
*
|
|
3
|
-
* Added a Gemfile.
|
|
7
|
+
* Switched tests to use rspec.
|
|
4
8
|
|
|
5
9
|
## 1.5.1 - 23-Mar-2020
|
|
6
10
|
* Properly add a LICENSE file since the Apache-2.0 license requires it.
|
data/Gemfile
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
source 'https://rubygems.org'
|
|
2
|
-
|
|
3
|
-
end
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
gemspec
|
data/MANIFEST.md
CHANGED
data/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
[](https://github.com/djberg96/getopt/actions/workflows/ruby.yml)
|
|
2
|
+
|
|
1
3
|
## Description
|
|
2
4
|
The getopt Ruby library is a simple command line parsing library. It implements
|
|
3
5
|
a `Getopt::Std` class for basic command line parsing, as well as a `Getopt::Long`
|
|
@@ -5,6 +7,9 @@ class for more advanced command line parsing.
|
|
|
5
7
|
|
|
6
8
|
## Installation
|
|
7
9
|
`gem install getopt`
|
|
10
|
+
|
|
11
|
+
## Adding the trusted cert
|
|
12
|
+
`gem cert --add <(curl -Ls https://raw.githubusercontent.com/djberg96/getopt/main/certs/djberg96_pub.pem)`
|
|
8
13
|
|
|
9
14
|
## Synopsis
|
|
10
15
|
### Getopt::Std
|
|
@@ -123,8 +128,6 @@ only once.
|
|
|
123
128
|
|
|
124
129
|
## Future Plans
|
|
125
130
|
|
|
126
|
-
* Add support for negatable options so that you can do "--no-foo", for example.
|
|
127
|
-
|
|
128
131
|
* Add support for numeric types, so that you don't have to manually convert
|
|
129
132
|
strings to numbers.
|
|
130
133
|
|
data/Rakefile
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
require 'rake'
|
|
2
2
|
require 'rake/clean'
|
|
3
3
|
require 'rspec/core/rake_task'
|
|
4
|
+
require 'rubocop/rake_task'
|
|
4
5
|
|
|
5
|
-
CLEAN.include("**/*.gem", "**/*.rbc")
|
|
6
|
+
CLEAN.include("**/*.gem", "**/*.rbc", "**/*.lock")
|
|
6
7
|
|
|
7
8
|
namespace :gem do
|
|
8
9
|
desc "Create the getopt gem"
|
|
9
10
|
task :create => [:clean] do
|
|
10
11
|
require 'rubygems/package'
|
|
11
|
-
spec =
|
|
12
|
+
spec = Gem::Specification.load('getopt.gemspec')
|
|
12
13
|
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
|
13
14
|
Gem::Package.build(spec)
|
|
14
15
|
end
|
|
@@ -22,6 +23,8 @@ end
|
|
|
22
23
|
|
|
23
24
|
namespace :spec do
|
|
24
25
|
RSpec::Core::RakeTask.new(:all) do |t|
|
|
26
|
+
t.verbose = false
|
|
27
|
+
t.rspec_opts = '-f documentation -w'
|
|
25
28
|
t.pattern = FileList['spec/*_spec.rb']
|
|
26
29
|
end
|
|
27
30
|
|
|
@@ -34,4 +37,11 @@ namespace :spec do
|
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
|
|
40
|
+
RuboCop::RakeTask.new
|
|
41
|
+
|
|
42
|
+
# Clean up afterwards
|
|
43
|
+
Rake::Task[:spec].enhance do
|
|
44
|
+
Rake::Task[:clean].invoke
|
|
45
|
+
end
|
|
46
|
+
|
|
37
47
|
task :default => 'spec:all'
|
data/getopt.gemspec
CHANGED
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = 'getopt'
|
|
5
|
-
spec.version = '1.
|
|
5
|
+
spec.version = '1.7.0'
|
|
6
6
|
spec.author = 'Daniel J. Berger'
|
|
7
7
|
spec.license = 'Apache-2.0'
|
|
8
8
|
spec.email = 'djberg96@gmail.com'
|
|
@@ -14,14 +14,19 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
|
|
15
15
|
spec.add_development_dependency('rake')
|
|
16
16
|
spec.add_development_dependency('rspec', '~> 3.9')
|
|
17
|
+
spec.add_development_dependency('rubocop')
|
|
18
|
+
spec.add_development_dependency('rubocop-rspec')
|
|
17
19
|
|
|
18
20
|
spec.metadata = {
|
|
19
|
-
'homepage_uri'
|
|
20
|
-
'bug_tracker_uri'
|
|
21
|
-
'changelog_uri'
|
|
22
|
-
'documentation_uri'
|
|
23
|
-
'source_code_uri'
|
|
24
|
-
'wiki_uri'
|
|
21
|
+
'homepage_uri' => 'https://github.com/djberg96/getopt',
|
|
22
|
+
'bug_tracker_uri' => 'https://github.com/djberg96/getopt/issues',
|
|
23
|
+
'changelog_uri' => 'https://github.com/djberg96/getopt/blob/main/CHANGES.md',
|
|
24
|
+
'documentation_uri' => 'https://github.com/djberg96/getopt/wiki',
|
|
25
|
+
'source_code_uri' => 'https://github.com/djberg96/getopt',
|
|
26
|
+
'wiki_uri' => 'https://github.com/djberg96/getopt/wiki',
|
|
27
|
+
'rubygems_mfa_required' => 'true',
|
|
28
|
+
'github_repo' => 'https://github.com/djberg96/getopt',
|
|
29
|
+
'funding_uri' => 'https://github.com/sponsors/djberg96'
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
spec.description = <<-EOF
|
data/lib/getopt/long.rb
CHANGED
|
@@ -1,244 +1,266 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'version'
|
|
2
4
|
|
|
3
5
|
# The Getopt module serves as a namespace only
|
|
4
6
|
module Getopt
|
|
7
|
+
REQUIRED = 0 # Argument is required if switch is provided.
|
|
8
|
+
BOOLEAN = 1 # Value of argument is true if provided, false otherwise.
|
|
9
|
+
OPTIONAL = 2 # Argument is optional if switch is provided.
|
|
10
|
+
INCREMENT = 3 # Argument is incremented by 1 each time the switch appears.
|
|
11
|
+
NEGATABLE = 4 # Automatically provide --no-<switch> to set value to false.
|
|
12
|
+
|
|
13
|
+
# INTEGER = 5 # Argument automatically converted to integer if provided.
|
|
14
|
+
# FLOAT = 6 # Argument automatically converted to float if provided.
|
|
15
|
+
|
|
16
|
+
# The Getopt::Long class encapsulates longhanded parameter parsing options
|
|
17
|
+
class Long
|
|
18
|
+
include Getopt::Version
|
|
19
|
+
|
|
20
|
+
# Error raised if an illegal option or argument is passed
|
|
21
|
+
class Error < StandardError; end
|
|
22
|
+
|
|
23
|
+
# Takes an array of switches. Each array consists of up to three
|
|
24
|
+
# elements that indicate the name and type of switch. Returns a hash
|
|
25
|
+
# containing each switch name, minus the '-', as a key. The value
|
|
26
|
+
# for each key depends on the type of switch and/or the value provided
|
|
27
|
+
# by the user.
|
|
28
|
+
#
|
|
29
|
+
# The long switch _must_ be provided. The short switch defaults to the
|
|
30
|
+
# first letter of the short switch. The default type is BOOLEAN.
|
|
31
|
+
#
|
|
32
|
+
# Example:
|
|
33
|
+
#
|
|
34
|
+
# opts = Getopt::Long.getopts(
|
|
35
|
+
# ['--debug' ],
|
|
36
|
+
# ['--verbose', '-v' ],
|
|
37
|
+
# ['--level', '-l', INCREMENT]
|
|
38
|
+
# )
|
|
39
|
+
#
|
|
40
|
+
# See the README file for more information.
|
|
41
|
+
#
|
|
42
|
+
def self.getopts(*switches)
|
|
43
|
+
if switches.empty?
|
|
44
|
+
raise ArgumentError, 'no switches provided'
|
|
45
|
+
end
|
|
5
46
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# NEGATABLE = 4 # Automatically provide negative switch equivalent.
|
|
12
|
-
# INTEGER = 5 # Argument automatically converted to integer if provided.
|
|
13
|
-
# FLOAT = 6 # Argument automatically converted to float if provided.
|
|
14
|
-
|
|
15
|
-
# The Getopt::Long class encapsulates longhanded parameter parsing options
|
|
16
|
-
class Long
|
|
17
|
-
include Getopt::Version
|
|
47
|
+
hash = {} # Hash returned to user
|
|
48
|
+
valid = [] # Tracks valid switches
|
|
49
|
+
types = {} # Tracks argument types
|
|
50
|
+
syns = {} # Tracks long and short arguments, or multiple shorts
|
|
51
|
+
negs = {} # Tracks negated switches (maps --no-foo to --foo)
|
|
18
52
|
|
|
19
|
-
#
|
|
20
|
-
|
|
53
|
+
# If a string is passed, split it and convert it to an array of arrays
|
|
54
|
+
if switches.first.is_a?(String)
|
|
55
|
+
switches = switches.join.split
|
|
56
|
+
switches.map!{ |switch| [switch] }
|
|
57
|
+
end
|
|
21
58
|
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
switches.each{ |switch|
|
|
59
|
-
valid.push(switch[0]) # Set valid long switches
|
|
60
|
-
|
|
61
|
-
# Set type for long switch, default to BOOLEAN.
|
|
62
|
-
if switch[1].kind_of?(Integer)
|
|
63
|
-
switch[2] = switch[1]
|
|
64
|
-
types[switch[0]] = switch[2]
|
|
65
|
-
switch[1] = switch[0][1..2]
|
|
66
|
-
else
|
|
67
|
-
switch[2] ||= BOOLEAN
|
|
68
|
-
types[switch[0]] = switch[2]
|
|
69
|
-
switch[1] ||= switch[0][1..2]
|
|
70
|
-
end
|
|
59
|
+
# Set our list of valid switches, and proper types for each switch
|
|
60
|
+
switches.each do |switch|
|
|
61
|
+
valid.push(switch[0]) # Set valid long switches
|
|
62
|
+
|
|
63
|
+
# Set type for long switch, default to BOOLEAN.
|
|
64
|
+
if switch[1].is_a?(Integer)
|
|
65
|
+
switch[2] = switch[1]
|
|
66
|
+
types[switch[0]] = switch[2]
|
|
67
|
+
switch[1] = switch[0][1..2]
|
|
68
|
+
else
|
|
69
|
+
switch[2] ||= BOOLEAN
|
|
70
|
+
types[switch[0]] = switch[2]
|
|
71
|
+
switch[1] ||= switch[0][1..2]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Create synonym hash. Default to first char of long switch for
|
|
75
|
+
# short switch, e.g. "--verbose" creates a "-v" synonym. The same
|
|
76
|
+
# synonym can only be used once - first one wins.
|
|
77
|
+
syns[switch[0]] = switch[1] unless syns[switch[1]]
|
|
78
|
+
syns[switch[1]] = switch[0] unless syns[switch[1]]
|
|
79
|
+
|
|
80
|
+
switch[1] = [switch[1]]
|
|
81
|
+
|
|
82
|
+
switch[1].each do |char|
|
|
83
|
+
types[char] = switch[2] # Set type for short switch
|
|
84
|
+
valid.push(char) # Set valid short switches
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# For NEGATABLE switches, register the --no- variant
|
|
88
|
+
if switch[2] == NEGATABLE
|
|
89
|
+
negated = switch[0].sub(/^--/, '--no-')
|
|
90
|
+
valid.push(negated)
|
|
91
|
+
types[negated] = NEGATABLE
|
|
92
|
+
negs[negated] = switch[0] # Map --no-foo back to --foo
|
|
93
|
+
end
|
|
94
|
+
end
|
|
71
95
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
syns[switch[1]] = switch[0] unless syns[switch[1]]
|
|
77
|
-
|
|
78
|
-
switch[1] = [switch[1]]
|
|
79
|
-
|
|
80
|
-
switch[1].each{ |char|
|
|
81
|
-
types[char] = switch[2] # Set type for short switch
|
|
82
|
-
valid.push(char) # Set valid short switches
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
re_long = /^(--\w+[-\w+]*)?$/
|
|
87
|
-
re_short = /^(-\w)$/
|
|
88
|
-
re_long_eq = /^(--\w+[-\w+]*)?=(.*?)$|(-\w?)=(.*?)$/
|
|
89
|
-
re_short_sq = /^(-\w)(\S+?)$/
|
|
90
|
-
|
|
91
|
-
ARGV.each_with_index{ |opt, index|
|
|
92
|
-
|
|
93
|
-
# Allow either -x -v or -xv style for single char args
|
|
94
|
-
if re_short_sq.match(opt)
|
|
95
|
-
chars = opt.split("")[1..-1].map{ |s| s = "-#{s}" }
|
|
96
|
-
|
|
97
|
-
chars.each_with_index{ |char, i|
|
|
98
|
-
unless valid.include?(char)
|
|
99
|
-
raise Error, "invalid switch '#{char}'"
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# Grab the next arg if the switch takes a required arg
|
|
103
|
-
if types[char] == REQUIRED
|
|
104
|
-
# Deal with a argument squished up against switch
|
|
105
|
-
if chars[i+1]
|
|
106
|
-
arg = chars[i+1..-1].join.tr('-', '')
|
|
107
|
-
ARGV.push(char, arg)
|
|
108
|
-
break
|
|
109
|
-
else
|
|
110
|
-
arg = ARGV.delete_at(index+1)
|
|
111
|
-
if arg.nil? || valid.include?(arg) # Minor cheat here
|
|
112
|
-
err = "no value provided for required argument '#{char}'"
|
|
113
|
-
raise Error, err
|
|
114
|
-
end
|
|
115
|
-
ARGV.push(char, arg)
|
|
116
|
-
end
|
|
117
|
-
elsif types[char] == OPTIONAL
|
|
118
|
-
if chars[i+1] && !valid.include?(chars[i+1])
|
|
119
|
-
arg = chars[i+1..-1].join.tr("-","")
|
|
120
|
-
ARGV.push(char, arg)
|
|
121
|
-
break
|
|
122
|
-
elsif
|
|
123
|
-
if ARGV[index+1] && !valid.include?(ARGV[index+1])
|
|
124
|
-
arg = ARGV.delete_at(index+1)
|
|
125
|
-
ARGV.push(char, arg)
|
|
126
|
-
end
|
|
127
|
-
else
|
|
128
|
-
ARGV.push(char)
|
|
129
|
-
end
|
|
130
|
-
else
|
|
131
|
-
ARGV.push(char)
|
|
132
|
-
end
|
|
133
|
-
}
|
|
134
|
-
next
|
|
135
|
-
end
|
|
96
|
+
re_long = /^(--\w+[-\w+]*)?$/
|
|
97
|
+
re_short = /^(-\w)$/
|
|
98
|
+
re_long_eq = /^(--\w+[-\w+]*)?=(.*?)$|(-\w?)=(.*?)$/
|
|
99
|
+
re_short_sq = /^(-\w)(\S+?)$/
|
|
136
100
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
101
|
+
ARGV.each_with_index do |opt, index|
|
|
102
|
+
# Allow either -x -v or -xv style for single char args
|
|
103
|
+
if re_short_sq.match(opt)
|
|
104
|
+
chars = opt.chars[1..].map{ |s| "-#{s}" }
|
|
140
105
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
next
|
|
106
|
+
chars.each_with_index do |char, i|
|
|
107
|
+
unless valid.include?(char)
|
|
108
|
+
raise Error, "invalid switch '#{char}'"
|
|
145
109
|
end
|
|
146
110
|
|
|
147
|
-
#
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
# Make sure there's a value for mandatory arguments
|
|
160
|
-
if nextval.nil?
|
|
161
|
-
err = "no value provided for required argument '#{switch}'"
|
|
162
|
-
raise Error, err
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# If there is a value, make sure it's not another switch
|
|
166
|
-
if valid.include?(nextval)
|
|
167
|
-
err = "cannot pass switch '#{nextval}' as an argument"
|
|
111
|
+
# Grab the next arg if the switch takes a required arg
|
|
112
|
+
if types[char] == REQUIRED
|
|
113
|
+
# Deal with a argument squished up against switch
|
|
114
|
+
if chars[i + 1]
|
|
115
|
+
arg = chars[i + 1..].join.tr('-', '')
|
|
116
|
+
ARGV.push(char, arg)
|
|
117
|
+
break
|
|
118
|
+
else
|
|
119
|
+
arg = ARGV.delete_at(index + 1)
|
|
120
|
+
if arg.nil? || valid.include?(arg) # Minor cheat here
|
|
121
|
+
err = "no value provided for required argument '#{char}'"
|
|
168
122
|
raise Error, err
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
123
|
+
end
|
|
124
|
+
ARGV.push(char, arg)
|
|
125
|
+
end
|
|
126
|
+
elsif types[char] == OPTIONAL
|
|
127
|
+
if chars[i + 1] && !valid.include?(chars[i + 1])
|
|
128
|
+
arg = chars[i + 1..].join.tr('-', '')
|
|
129
|
+
ARGV.push(char, arg)
|
|
130
|
+
break
|
|
131
|
+
elsif ARGV[index + 1] && !valid.include?(ARGV[index + 1])
|
|
132
|
+
arg = ARGV.delete_at(index + 1)
|
|
133
|
+
ARGV.push(char, arg)
|
|
134
|
+
else
|
|
135
|
+
ARGV.push(char)
|
|
136
|
+
end
|
|
137
|
+
else
|
|
138
|
+
ARGV.push(char)
|
|
179
139
|
end
|
|
140
|
+
end
|
|
141
|
+
next
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
match = re_long.match(opt) || re_short.match(opt)
|
|
145
|
+
switch = match.captures.first if match
|
|
146
|
+
|
|
147
|
+
if match = re_long_eq.match(opt)
|
|
148
|
+
switch, value = match.captures.compact
|
|
149
|
+
ARGV.push(switch, value)
|
|
150
|
+
next
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Make sure that all the switches are valid. If 'switch' isn't
|
|
154
|
+
# defined at this point, it means an option was passed without
|
|
155
|
+
# a preceding switch, e.g. --option foo bar.
|
|
156
|
+
unless valid.include?(switch)
|
|
157
|
+
switch ||= opt
|
|
158
|
+
raise Error, "invalid switch '#{switch}'"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Required arguments
|
|
162
|
+
if types[switch] == REQUIRED
|
|
163
|
+
nextval = ARGV[index + 1]
|
|
164
|
+
|
|
165
|
+
# Make sure there's a value for mandatory arguments
|
|
166
|
+
if nextval.nil?
|
|
167
|
+
err = "no value provided for required argument '#{switch}'"
|
|
168
|
+
raise Error, err
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# If there is a value, make sure it's not another switch
|
|
172
|
+
if valid.include?(nextval)
|
|
173
|
+
err = "cannot pass switch '#{nextval}' as an argument"
|
|
174
|
+
raise Error, err
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# If the same option appears more than once, put the values in array.
|
|
178
|
+
if hash[switch]
|
|
179
|
+
hash[switch] = [hash[switch], nextval].flatten
|
|
180
|
+
else
|
|
181
|
+
hash[switch] = nextval
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
ARGV.delete_at(index + 1)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# For boolean arguments set the switch's value to true.
|
|
188
|
+
if types[switch] == BOOLEAN
|
|
189
|
+
if hash.key?(switch)
|
|
190
|
+
raise Error, 'boolean switch already set'
|
|
191
|
+
end
|
|
192
|
+
hash[switch] = true
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# For increment arguments, set the switch's value to 0, or
|
|
196
|
+
# increment it by one if it already exists.
|
|
197
|
+
if types[switch] == INCREMENT
|
|
198
|
+
if hash.key?(switch)
|
|
199
|
+
hash[switch] += 1
|
|
200
|
+
else
|
|
201
|
+
hash[switch] = 1
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# For negatable arguments, --foo sets true, --no-foo sets false.
|
|
206
|
+
# The value is stored under the base switch name (without --no-).
|
|
207
|
+
if types[switch] == NEGATABLE
|
|
208
|
+
base_switch = negs[switch] || switch
|
|
209
|
+
if hash.key?(base_switch)
|
|
210
|
+
raise Error, 'negatable switch already set'
|
|
211
|
+
end
|
|
212
|
+
hash[base_switch] = !negs.key?(switch) # true unless it's a --no- variant
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# For optional argument, there may be an argument. If so, it
|
|
216
|
+
# cannot be another switch. If not, it is set to true.
|
|
217
|
+
if types[switch] == OPTIONAL
|
|
218
|
+
nextval = ARGV[index + 1]
|
|
219
|
+
if valid.include?(nextval)
|
|
220
|
+
hash[switch] = true
|
|
221
|
+
else
|
|
222
|
+
hash[switch] = nextval
|
|
223
|
+
ARGV.delete_at(index + 1)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
180
227
|
|
|
181
|
-
|
|
182
|
-
if types[switch] == BOOLEAN
|
|
183
|
-
if hash.has_key?(switch)
|
|
184
|
-
raise Error, 'boolean switch already set'
|
|
185
|
-
end
|
|
186
|
-
hash[switch] = true
|
|
187
|
-
end
|
|
228
|
+
# rubocop:disable Style/CombinableLoops
|
|
188
229
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
hash[switch] = nextval
|
|
207
|
-
ARGV.delete_at(index+1)
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
# Set synonymous switches to the same value, e.g. if -t is a synonym
|
|
213
|
-
# for --test, and the user passes "--test", then set "-t" to the same
|
|
214
|
-
# value that "--test" was set to.
|
|
215
|
-
#
|
|
216
|
-
# This allows users to refer to the long or short switch and get
|
|
217
|
-
# the same value
|
|
218
|
-
hash.dup.each{ |switch, val|
|
|
219
|
-
if syns.keys.include?(switch)
|
|
220
|
-
syns[switch] = [syns[switch]]
|
|
221
|
-
syns[switch].each{ |key|
|
|
222
|
-
hash[key] = val
|
|
223
|
-
}
|
|
224
|
-
end
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
# Get rid of leading "--" and "-" to make it easier to reference
|
|
228
|
-
hash.dup.each{ |key, value|
|
|
229
|
-
if key =~ /^-/
|
|
230
|
-
if key[0,2] == '--'
|
|
231
|
-
nkey = key.sub('--', '')
|
|
232
|
-
else
|
|
233
|
-
nkey = key.sub('-', '')
|
|
234
|
-
end
|
|
235
|
-
hash.delete(key)
|
|
236
|
-
hash[nkey] = value
|
|
237
|
-
end
|
|
238
|
-
}
|
|
230
|
+
# Set synonymous switches to the same value, e.g. if -t is a synonym
|
|
231
|
+
# for --test, and the user passes "--test", then set "-t" to the same
|
|
232
|
+
# value that "--test" was set to.
|
|
233
|
+
#
|
|
234
|
+
# This allows users to refer to the long or short switch and get
|
|
235
|
+
# the same value
|
|
236
|
+
hash.dup.each do |switch, val|
|
|
237
|
+
# Skip negated switches - they've already been mapped to base switch
|
|
238
|
+
next if negs.key?(switch)
|
|
239
|
+
|
|
240
|
+
if syns.keys.include?(switch)
|
|
241
|
+
syns[switch] = [syns[switch]]
|
|
242
|
+
syns[switch].each do |key|
|
|
243
|
+
hash[key] = val
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
239
247
|
|
|
240
|
-
|
|
248
|
+
# Get rid of leading "--" and "-" to make it easier to reference
|
|
249
|
+
hash.dup.each do |key, value|
|
|
250
|
+
if key =~ /^-/
|
|
251
|
+
if key[0, 2] == '--'
|
|
252
|
+
nkey = key.sub('--', '')
|
|
253
|
+
else
|
|
254
|
+
nkey = key.sub('-', '')
|
|
255
|
+
end
|
|
256
|
+
hash.delete(key)
|
|
257
|
+
hash[nkey] = value
|
|
258
|
+
end
|
|
241
259
|
end
|
|
242
260
|
|
|
243
|
-
|
|
261
|
+
# rubocop:enable Style/CombinableLoops
|
|
262
|
+
|
|
263
|
+
hash
|
|
264
|
+
end
|
|
265
|
+
end
|
|
244
266
|
end
|