shellopts 2.0.14 → 2.0.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2101f633ad0e166982b108842a83f91b3d216869f9fe3d6ac7ecea5256f2b437
4
- data.tar.gz: da77f695902e5e921e598dd8d1327af4ce07ffe7b9cfadb88fe1b0889b95b4e0
3
+ metadata.gz: ebd7911e579af4ddddd064399e7b456b45cef80dc3c6589e404ba5e32811bd6c
4
+ data.tar.gz: ea555ad68d0d6c43bad39a4e195e6661f72e1e43b6d3dbe647f4c8ff13d7eea3
5
5
  SHA512:
6
- metadata.gz: 36dbd8d33d74a5b985463df5fb514501c2881881bdd68f1fa479c7ecac3de2bc4a2bc3a713acfe735d3e53ccdde10f5abf5ecc066d370fa8e795a77e290f9988
7
- data.tar.gz: b364c8d00de2f7ece58d3c721ef3d4f40a892a232aa39a0c94df2b7ef37cf86e78c99df25c07e8802b0e48640ec928c4157bd89a2cb0851955484ed5957733ca
6
+ metadata.gz: 453d3bd1e4354a56947623232f1fabcdc8d212a91d317ce16026c356c71c77ab53031e4e42d05242d0c04ce309ccd69fd75386d3d40705feac461f58d6a2c86b
7
+ data.tar.gz: 282655ab16154e1b50c25b6ddf8a07196a296f8a2bad4086cd78b8962a9003c22e1fb8dfbe2e339fc97973fef95b1cf9965a829bab23b2ad98f63df1aef8c009
data/PROBLEMS ADDED
@@ -0,0 +1,41 @@
1
+
2
+ # Subcommand options are not recognized unless there exists an option on the
3
+ # program level (try to remove -a below)
4
+
5
+ SPEC = %(
6
+ Foreign data wrapper maintenance tool
7
+
8
+ -a,an-option
9
+ Gryf
10
+
11
+ list.servers! -- DATABASE
12
+ List foreign servers
13
+
14
+ create.server! -- DATABASE FDW-SERVER MSSQL-DATABASE [MSSQL-HOST [MSSQL-PORT]]
15
+ Create a new FDW server
16
+
17
+ -c,credentials=EFILE
18
+ Credentials file. The credentials file is a YAML formatted file that can
19
+ define the fields 'user', 'password', 'host', and 'port'
20
+
21
+ drop.server! -- DATABASE FDW-SERVER
22
+ Drop a FDW server. This cascades to FDW users too
23
+
24
+ list.users! -- DATABASE
25
+ List FDW users. 'users' in this context is postgres users that have an
26
+ associated FDW user mapping
27
+
28
+ --servers @ Also list the user's FDW servers
29
+
30
+ create.user! -- DATABASE FDW-SERVER [FDW-USER [FDW-PASSWORD]]
31
+ Create a FDW user. The user has to exist beforehand, this command only adds
32
+ a user mapping to the user and grants the usage privilege
33
+
34
+ -c,credentials=EFILE
35
+ Credentials file
36
+
37
+ drop.user! -- DATABASE FDW-USER
38
+ Drops a FDW user. The postgres user is not dropped but the user's user
39
+ mapping and grants are
40
+ )
41
+
data/TODO CHANGED
@@ -1,4 +1,5 @@
1
-
1
+ o --option can't be escaped if on the start of a block line?
2
+ o Use require_relative
2
3
  o In the following list is a command with a mandatory sub-command
3
4
 
4
5
  list.tables!
@@ -14,7 +15,6 @@ o In the following list is a command with a mandatory sub-command
14
15
  and not as
15
16
  list [tables|uuids]
16
17
 
17
-
18
18
  o Replace -h with -? when -h is specified by the user (eg. as a shorthand for --host)
19
19
  o Limit text width to -10 chars of what it is today (same as stackexchange width in characters)
20
20
  o Fix formatting error in long arguments (see ms2pg)
data/lib/ext/follow.rb ADDED
@@ -0,0 +1,26 @@
1
+
2
+ module Algorithm
3
+ class FollowEnumerator < Enumerator
4
+ def initialize(object, method = nil, &block)
5
+ closure = method ? lambda { |object| object.__send__(method) } : block
6
+ super() { |yielder|
7
+ while object
8
+ yielder << object
9
+ object = closure.call(object)
10
+ end
11
+ }
12
+ end
13
+ end
14
+
15
+ def follow(object, method = nil, &block)
16
+ !method.nil? || block_given? or raise ArgumentError, "Needs either a method or a block"
17
+ method.nil? == block_given? or raise ArgumentError, "Can't use both method and block"
18
+ FollowEnumerator.new(object, method, &block)
19
+ end
20
+
21
+ module_function :follow
22
+ end
23
+
24
+
25
+
26
+
@@ -52,7 +52,7 @@ module ShellOpts
52
52
  # These methods can be overridden by an option or a command (this constant
53
53
  # is not used - it is just for informational purposes)
54
54
  OVERRIDEABLE_METHOD_NAMES = %w(
55
- subcommand subcommand! supercommand!
55
+ subcommand subcommand! subcommands subcommands! supercommand!
56
56
  )
57
57
 
58
58
  # Redefine ::new to call #__initialize__
@@ -101,10 +101,10 @@ module ShellOpts
101
101
  def to_h(*keys)
102
102
  keys = ::Kernel::Array(keys).flatten
103
103
  if keys.empty?
104
- @__option_values__
104
+ self.to_h(@__grammar__.options.map(&:ident))
105
105
  else
106
106
  keys.map { |key|
107
- @__option_values__.key?(key) ? [key, @__option_values__[key]] : nil
107
+ self.__send__("#{key}?".to_sym) ? [key, self.__send__(key)] : nil
108
108
  }.compact.to_h
109
109
  end
110
110
  end
@@ -133,6 +133,13 @@ module ShellOpts
133
133
  #
134
134
  def subcommand!() __subcommand__! end
135
135
 
136
+ # Returns the concatenated identifier of subcommands (eg. :cmd.subcmd!)
137
+ def subcommands() __subcommands__ end
138
+
139
+ # Returns the subcommands in an array. This doesn't include the top-level
140
+ # program object
141
+ def subcommands!() __subcommands__! end
142
+
136
143
  # The parent command or nil. Initialized by #add_command
137
144
  #
138
145
  # Note: Can be overridden by a subcommand declaration (but not an
@@ -153,10 +160,10 @@ module ShellOpts
153
160
  # Grammar object
154
161
  attr_reader :__grammar__
155
162
 
156
- # Hash from identifier to value. Can be Integer, Float, or String
157
- # depending on the option's type. Repeated options options without
158
- # arguments have the number of occurences as the value, with arguments
159
- # the value is an array of the given values
163
+ # Hash from identifier to value. Can be Integer, Float, or String depending
164
+ # on the option's type. Repeated options options without arguments have the
165
+ # number of occurences as value, repeated option with arguments have the
166
+ # array of values as value
160
167
  attr_reader :__option_values__
161
168
 
162
169
  # List of Option objects for the subcommand in the same order as
@@ -180,6 +187,16 @@ module ShellOpts
180
187
  # The actual subcommand object or nil if not present
181
188
  def __subcommand__!() @__subcommand__ end
182
189
 
190
+ # Implementation of the #subcommands method
191
+ def __subcommands__()
192
+ __subcommands__!.last&.__uid__&.to_sym
193
+ end
194
+
195
+ # Implementation of the #subcommands! method
196
+ def __subcommands__!()
197
+ ::Algorithm.follow(self.__subcommand__!, :__subcommand__!).to_a
198
+ end
199
+
183
200
  private
184
201
  def __initialize__(grammar)
185
202
  @__grammar__ = grammar
@@ -194,7 +211,48 @@ module ShellOpts
194
211
 
195
212
  def __define_option_methods__
196
213
  @__grammar__.options.each { |opt|
197
- if opt.argument?
214
+ if !opt.repeatable?
215
+ self.instance_eval %(
216
+ def #{opt.attr}?()
217
+ @__option_values__.key?(:#{opt.attr})
218
+ end
219
+ )
220
+ end
221
+
222
+ if opt.repeatable?
223
+ if opt.argument?
224
+ self.instance_eval %(
225
+ def #{opt.attr}?()
226
+ (@__option_values__[:#{opt.attr}]&.size || 0) > 0
227
+ end
228
+ )
229
+ self.instance_eval %(
230
+ def #{opt.attr}(default = [])
231
+ if @__option_values__.key?(:#{opt.attr})
232
+ @__option_values__[:#{opt.attr}]
233
+ else
234
+ default
235
+ end
236
+ end
237
+ )
238
+ else
239
+ self.instance_eval %(
240
+ def #{opt.attr}?()
241
+ (@__option_values__[:#{opt.attr}] || 0) > 0
242
+ end
243
+ )
244
+ self.instance_eval %(
245
+ def #{opt.attr}(default = 0)
246
+ if default > 0 && (@__option_values__[:#{opt.attr}] || 0) == 0
247
+ default
248
+ else
249
+ @__option_values__[:#{opt.attr}] || 0
250
+ end
251
+ end
252
+ )
253
+ end
254
+
255
+ elsif opt.argument?
198
256
  self.instance_eval %(
199
257
  def #{opt.attr}(default = nil)
200
258
  if @__option_values__.key?(:#{opt.attr})
@@ -205,26 +263,13 @@ module ShellOpts
205
263
  end
206
264
  )
207
265
 
208
- elsif opt.repeatable?
266
+ else
209
267
  self.instance_eval %(
210
- def #{opt.attr}(default = 0)
211
- if default > 0 && @__option_values__[:#{opt.attr}] == 0
212
- default
213
- else
214
- @__option_values__[:#{opt.attr}]
215
- end
268
+ def #{opt.attr}()
269
+ @__option_values__.key?(:#{opt.attr})
216
270
  end
217
271
  )
218
- else
219
- self.instance_eval("def #{opt.attr}() @__option_values__[:#{opt.attr}] end")
220
272
  end
221
-
222
- if opt.argument? || opt.repeatable?
223
- self.instance_eval("def #{opt.attr}=(value) @__option_values__[:#{opt.attr}] = value end")
224
- @__option_values__[opt.attr] = 0 if !opt.argument?
225
- end
226
-
227
- self.instance_eval("def #{opt.attr}?() @__option_values__.key?(:#{opt.attr}) end")
228
273
  }
229
274
 
230
275
  @__grammar__.commands.each { |cmd|
@@ -1,3 +1,3 @@
1
1
  module ShellOpts
2
- VERSION = "2.0.14"
2
+ VERSION = "2.0.17"
3
3
  end
data/lib/shellopts.rb CHANGED
@@ -5,6 +5,7 @@ require 'constrain'
5
5
  include Constrain
6
6
 
7
7
  require 'ext/array.rb'
8
+ require 'ext/follow.rb'
8
9
  require 'ext/forward_to.rb'
9
10
  require 'ext/lcs.rb'
10
11
  include ForwardTo
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.14
4
+ version: 2.0.17
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-04-05 00:00:00.000000000 Z
11
+ date: 2022-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forward_to
@@ -135,6 +135,7 @@ files:
135
135
  - ".rspec"
136
136
  - ".ruby-version"
137
137
  - Gemfile
138
+ - PROBLEMS
138
139
  - README.md
139
140
  - Rakefile
140
141
  - TODO
@@ -147,6 +148,7 @@ files:
147
148
  - doc/syntax.rb
148
149
  - doc/syntax.txt
149
150
  - lib/ext/array.rb
151
+ - lib/ext/follow.rb
150
152
  - lib/ext/forward_to.rb
151
153
  - lib/ext/lcs.rb
152
154
  - lib/shellopts.rb