shellopts 2.0.1 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f5448df8e0fdd882072ab927e185511b09ebd8b594a9556937fdfd20d41070d
4
- data.tar.gz: 2743f77e88de6ff10562a2f7d3980b1bfc730d0e024e60e6472da48342a2f153
3
+ metadata.gz: 0170d9ce5144afcf716b90a3904250c0afa5d769b7a64f39db0b8084e77b4fb7
4
+ data.tar.gz: 81495a3802c472c65812594d847c43b0f59849ea0ebe093c74c2fb7d3e822658
5
5
  SHA512:
6
- metadata.gz: 9e08795c96b4f745a00cb6c38e5ea63beef08ceb640a0427d4bc46ee705189cab188a227a9d1775177d6530596155744d6e8624fa378c87c47f94c36e1adf98b
7
- data.tar.gz: cb12f16c665fe6fc0e0751ad2328aa7d8e1e48baad9d9d27addb4d88f6a083d780c61ee0b8b57e8218ee829a6e107afa8c076067dfa5d24a973bf353489d7433
6
+ metadata.gz: 195801ea89b22920fca88216ed4bd7ac426b3370e482b61547dac085d1c7d9f1bd0a2d0edc7c3368bf126cd5f4da815dd882ee3149cd291549ff631d6302e93a
7
+ data.tar.gz: 6dcd50871438db9f5b0520e4f670f6df6ad04756685838d309874a9601770ee79a7370ebc11b0469d19a9f2be89868c7cfd12cfe028c0c01719b4d8d0593fc59
@@ -14,8 +14,8 @@ module ShellOpts
14
14
  # safe for concurrent processing
15
15
  attr_reader :message
16
16
 
17
- # Return true if .value is an "instance" of self (not used atm. See
18
- # Command#[] and Grammar::Option#value?)
17
+ # Return true if .value is an "instance" of self. Ie. an Integer object
18
+ # if type is an IntegerArgument
19
19
  def value?(value) true end
20
20
 
21
21
  # Convert value to Ruby type
@@ -131,7 +131,7 @@ module ShellOpts
131
131
  class EnumArgument < ArgumentType
132
132
  attr_reader :values
133
133
  def initialize(values) @values = values.dup end
134
- def match?(name, literal) literal?(literal) or set_message "Illegal value in #{name}: '#{literal}'" end
134
+ def match?(name, literal) value?(literal) or set_message "Illegal value in #{name}: '#{literal}'" end
135
135
  def value?(value) @values.include?(value) end
136
136
  end
137
137
  end
@@ -4,30 +4,33 @@
4
4
  module ShellOpts
5
5
  # Command represents a program or a subcommand. It is derived from
6
6
  # BasicObject to have only a minimum of inherited member methods.
7
- # Additional methods defined in Command use the '__<identifier>__' naming
8
- # convention that doesn't collide with option or subcommand names but
9
- # they're rarely used in application code
10
7
  #
11
8
  # The names of the inherited methods can't be used as options or
12
9
  # command namess. They are: instance_eval, instance_exec method_missing,
13
10
  # singleton_method_added, singleton_method_removed, and
14
- # singleton_method_undefined
11
+ # singleton_method_undefined.
12
+ #
13
+ # Additional methods defined in Command use the '__<identifier>__' naming
14
+ # convention that doesn't collide with option or subcommand names but
15
+ # they're rarely used in application code
15
16
  #
16
17
  # Command also defines #subcommand and #subcommand! but they can be
17
18
  # overshadowed by an option or command declaration. Their values can
18
19
  # still be accessed using the dashed name, though
19
20
  #
20
- # Options and subcommands can be accessed using #[]
21
+ # Option and Command objects can be accessed using #[]. #key? is also defined
21
22
  #
22
23
  # The following methods are created dynamically for each declared option
23
24
  # with an attribute name
24
25
  #
25
- # def <identifier>(default = nil) self["<identifier>"] || default end
26
- # def <identifier>=(value) self["<identifier>"] = value end
27
- # def <identifier>?() self.key?("<identifier>") end
26
+ # <identifier>(default = nil)
27
+ # <identifier>=(value)
28
+ # <identifier>?()
29
+ #
30
+ # The default value is used if the option or its value is missing
28
31
  #
29
32
  # Options without an an attribute can still be accessed using #[] or trough
30
- # #__options__ or #__options_list__):
33
+ # #__option_values__, #__option_hash, or #__options_list__
31
34
  #
32
35
  # Each subcommand has a single method:
33
36
  #
@@ -42,9 +45,9 @@ module ShellOpts
42
45
 
43
46
  # These names can't be used as option or command names
44
47
  RESERVED_OPTION_NAMES = %w(
45
- is_a
46
- instance_eval instance_exec method_missing singleton_method_added
47
- singleton_method_removed singleton_method_undefined)
48
+ is_a instance_eval instance_exec method_missing singleton_method_added
49
+ singleton_method_removed singleton_method_undefined
50
+ )
48
51
 
49
52
  # These methods can be overridden by an option (the value is not used -
50
53
  # this is just for informational purposes)
@@ -59,43 +62,25 @@ module ShellOpts
59
62
  object
60
63
  end
61
64
 
62
- # Return command object or option argument value if present, otherwise nil
65
+ # Return command or option object if present, otherwise nil. Returns a
66
+ # possibly empty array of option objects if the option is repeatable
63
67
  #
64
68
  # The key is the name or identifier of the object or any any option
65
69
  # alias. Eg. :f, '-f', :file, or '--file' are all usable as option keys
66
70
  # and :cmd! or 'cmd' as command keys
67
71
  #
68
- # For options, the returned value is the argument given by the user
69
- # optionally converted to Integer or Float or nil if the option doesn't
70
- # take arguments. If the option takes an argument and it is repeatable
71
- # the value is an array of the arguments. Repeatable options without
72
- # arguments have the number of occurences as the value
73
- #
74
72
  def [](key)
75
73
  case object = __grammar__[key]
76
74
  when ::ShellOpts::Grammar::Command
77
75
  object.ident == __subcommand__!.__ident__ ? __subcommand__! : nil
78
76
  when ::ShellOpts::Grammar::Option
79
- __options__[object.ident]
80
- else
81
- nil
82
- end
83
- end
84
-
85
- # Assign a value to an existing option. This can be used to implement
86
- # default values. #[]= doesn't currently check the type of the given
87
- # value so take care. Note that the corresponding option(s) in
88
- # #__option_list__ is not updated
89
- def []=(key, value)
90
- case object = __grammar__[key]
91
- when ::ShellOpts::Grammar::Command
92
- ::Kernel.raise ArgumentError, "#{key.inspect} is not an option"
93
- when ::ShellOpts::Grammar::Option
94
- object.argument? || object.repeatable? or
95
- ::Kernel.raise ArgumentError, "#{key.inspect} is not assignable"
96
- __options__[object.ident] = value
77
+ if object.repeatable?
78
+ __option_hash__[object.ident] || []
79
+ else
80
+ __option_hash__[object.ident]
81
+ end
97
82
  else
98
- ::Kernel.raise ArgumentError, "Unknown option or command: #{key.inspect}"
83
+ ::Kernel.raise ::ArgumentError, "Unknown command or option: '#{key}'"
99
84
  end
100
85
  end
101
86
 
@@ -103,11 +88,11 @@ module ShellOpts
103
88
  def key?(key)
104
89
  case object = __grammar__[key]
105
90
  when ::ShellOpts::Grammar::Command
106
- object.ident == __subcommand__!.ident ? __subcommand__! : nil
91
+ object.ident == __subcommand__
107
92
  when ::ShellOpts::Grammar::Option
108
- __options__.key?(object.ident)
93
+ __option_hash__.key?(object.ident)
109
94
  else
110
- nil
95
+ ::Kernel.raise ::ArgumentError, "Unknown command or option: '#{key}'"
111
96
  end
112
97
  end
113
98
 
@@ -153,13 +138,17 @@ module ShellOpts
153
138
  # depending on the option's type. Repeated options options without
154
139
  # arguments have the number of occurences as the value, with arguments
155
140
  # the value is an array of the given values
156
- attr_reader :__options__
141
+ attr_reader :__option_values__
157
142
 
158
143
  # List of Option objects for the subcommand in the same order as
159
144
  # given by the user but note that options are reordered to come after
160
145
  # their associated subcommand if float is true. Repeated options are not
161
146
  # collapsed
162
147
  attr_reader :__option_list__
148
+
149
+ # Map from identifier to option object or to a list of option objects if
150
+ # the option is repeatable
151
+ attr_reader :__option_hash__
163
152
 
164
153
  # The subcommand identifier (a Symbol incl. the exclamation mark) or nil
165
154
  # if not present. Use #subcommand!, or the dynamically generated
@@ -172,9 +161,10 @@ module ShellOpts
172
161
  private
173
162
  def __initialize__(grammar)
174
163
  @__grammar__ = grammar
175
- @__options__ = {}
164
+ @__option_values__ = {}
176
165
  @__option_list__ = []
177
- @__options__ = {}
166
+ @__option_hash__ = {}
167
+ @__option_values__ = {}
178
168
  @__subcommand__ = nil
179
169
 
180
170
  __define_option_methods__
@@ -182,36 +172,34 @@ module ShellOpts
182
172
 
183
173
  def __define_option_methods__
184
174
  @__grammar__.options.each { |opt|
185
- next if opt.attr.nil?
186
175
  if opt.argument? || opt.repeatable?
187
176
  if opt.optional?
188
177
  self.instance_eval %(
189
178
  def #{opt.attr}(default = nil)
190
- if @__options__.key?(:#{opt.attr})
191
- @__options__[:#{opt.attr}] || default
179
+ if @__option_values__.key?(:#{opt.attr})
180
+ @__option_values__[:#{opt.attr}]
192
181
  else
193
- nil
182
+ default
194
183
  end
195
184
  end
196
185
  )
197
- elsif !opt.argument?
186
+ elsif !opt.argument? # Repeatable w/o argument
198
187
  self.instance_eval %(
199
- def #{opt.attr}(default = nil)
200
- if @__options__.key?(:#{opt.attr})
201
- value = @__options__[:#{opt.attr}]
202
- value == 0 ? default : value
188
+ def #{opt.attr}(default = [])
189
+ if @__option_values__.key?(:#{opt.attr})
190
+ @__option_values__[:#{opt.attr}]
203
191
  else
204
- nil
192
+ default
205
193
  end
206
194
  end
207
195
  )
208
196
  else
209
- self.instance_eval("def #{opt.attr}() @__options__[:#{opt.attr}] end")
197
+ self.instance_eval("def #{opt.attr}() @__option_values__[:#{opt.attr}] end")
210
198
  end
211
- self.instance_eval("def #{opt.attr}=(value) @__options__[:#{opt.attr}] = value end")
212
- @__options__[opt.attr] = 0 if !opt.argument?
199
+ self.instance_eval("def #{opt.attr}=(value) @__option_values__[:#{opt.attr}] = value end")
200
+ @__option_values__[opt.attr] = 0 if !opt.argument?
213
201
  end
214
- self.instance_eval("def #{opt.attr}?() @__options__.key?(:#{opt.attr}) end")
202
+ self.instance_eval("def #{opt.attr}?() @__option_values__.key?(:#{opt.attr}) end")
215
203
  }
216
204
 
217
205
  @__grammar__.commands.each { |cmd|
@@ -228,14 +216,15 @@ module ShellOpts
228
216
  ident = option.grammar.ident
229
217
  @__option_list__ << option
230
218
  if option.repeatable?
219
+ (@__option_hash__[ident] ||= []) << option
231
220
  if option.argument?
232
- (@__options__[ident] ||= []) << option.argument
221
+ (@__option_values__[ident] ||= []) << option.argument
233
222
  else
234
- @__options__[ident] ||= 0
235
- @__options__[ident] += 1
223
+ @__option_values__[ident] = (@__option_values__[ident] || 0) + 1
236
224
  end
237
225
  else
238
- @__options__[ident] = option.argument
226
+ @__option_hash__[ident] = option
227
+ @__option_values__[ident] = option.argument
239
228
  end
240
229
  end
241
230
 
@@ -254,7 +243,7 @@ module ShellOpts
254
243
 
255
244
  # Option models an option as given by the user on the subcommand line.
256
245
  # Compiled options (and possibly aggregated) options are stored in the
257
- # Command#__options__ array
246
+ # Command#__option_values__ array
258
247
  class Option
259
248
  # Associated Grammar::Option object
260
249
  attr_reader :grammar
@@ -1,3 +1,3 @@
1
1
  module ShellOpts
2
- VERSION = "2.0.1"
2
+ VERSION = "2.0.4"
3
3
  end
data/lib/shellopts.rb CHANGED
@@ -201,9 +201,9 @@ module ShellOpts
201
201
  def brief() Formatter.brief(@grammar) end
202
202
 
203
203
  # Print help for the given subject or the full documentation if +subject+
204
- # is nil
204
+ # is nil. Clears the screen beforehand if :clear is true
205
205
  #
206
- def help(subject = nil)
206
+ def help(subject = nil, clear: false)
207
207
  node = (subject ? @grammar[subject] : @grammar) or
208
208
  raise ArgumentError, "No such command: '#{subject&.sub(".", " ")}'"
209
209
  Formatter.help(node)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shellopts
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-28 00:00:00.000000000 Z
11
+ date: 2022-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forward_to
@@ -187,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  - !ruby/object:Gem::Version
188
188
  version: '0'
189
189
  requirements: []
190
- rubygems_version: 3.2.26
190
+ rubygems_version: 3.1.4
191
191
  signing_key:
192
192
  specification_version: 4
193
193
  summary: Parse command line options and arguments