pyer-options 2.0.2 → 2.0.3

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pyer/options.rb +161 -227
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4d0bd1e1b3c7c4e854b8f1060c4ae6ce23a2a831
4
- data.tar.gz: 27a2dde14744f669bb0cc8e26dc7abbe9805fd4d
3
+ metadata.gz: e93a13c4796ad6001e9df121e775e0a699173c0c
4
+ data.tar.gz: 1f6a3a8d2993c450e690689028623941d5957bb2
5
5
  SHA512:
6
- metadata.gz: 94bc9a131d424a43577bc08aa08fb140df8101ec93c54604d0e7fddcf2af5130d4de0bbf8c530a11ed2561a24161f2793b8c83897fdfb9dce9e9bc765add383d
7
- data.tar.gz: 081cfb6ba5bf3f5279f0e08787b7acc83d73ebd80e2a66062573754c0c92870086da7c4bbb1ee4495d745b3b9a87daa987452c52175d7dce02db46286b01b7aa
6
+ metadata.gz: 1a0eea84d1d081e24dabf025d409a0c1942e7f836085b4e942555ce3d5c491af85d041ab6f537336d357080fada4b09172bf5aed6d591413b160d80cc2fc58ac
7
+ data.tar.gz: 94abaf3ae34cd81f45ee94996f4c0e884ce81325b7fb3a90b0f465ffceae6b47ca1930be582e61d541e9c7ae7fcd0b6ae819f503039cf98632804ccdb5414b7d
@@ -1,30 +1,28 @@
1
+ # encoding: UTF-8
1
2
  module Pyer
2
- class Options
3
- include Enumerable
4
-
5
- # Raised when the command starts whith '-', or is not given
6
- class InvalidCommandError < StandardError
7
- end
3
+ # Raised when the command starts whith '-', or is not given
4
+ class InvalidCommandError < StandardError
5
+ end
8
6
 
9
- # Raised when the command is not defined
10
- class UnknownCommandError < StandardError
11
- end
7
+ # Raised when the command is not defined
8
+ class UnknownCommandError < StandardError
9
+ end
12
10
 
13
- # Raised when an invalid option is found.
14
- class InvalidOptionError < StandardError
15
- end
11
+ # Raised when an invalid option is found.
12
+ class InvalidOptionError < StandardError
13
+ end
16
14
 
17
- # Raised when an unknown option is found.
18
- class UnknownOptionError < StandardError
19
- end
15
+ # Raised when an unknown option is found.
16
+ class UnknownOptionError < StandardError
17
+ end
20
18
 
21
- # Raised when an option argument is expected but none are given.
22
- class MissingArgumentError < StandardError
23
- end
19
+ # Raised when an option argument is expected but none are given.
20
+ class MissingArgumentError < StandardError
21
+ end
24
22
 
25
- # Raised when an option argument starts whith '-'
26
- class InvalidArgumentError < StandardError
27
- end
23
+ # Options class
24
+ class Options
25
+ include Enumerable
28
26
 
29
27
  # items - The Array of items to extract options from (default: ARGV).
30
28
  # block - An optional block used to add options.
@@ -39,32 +37,23 @@ module Pyer
39
37
  # short option is the first letter of long option
40
38
  # Returns a new instance of Options.
41
39
  def self.parse(items = ARGV, &block)
42
- new( &block ).parse items
40
+ new(&block).parse items
43
41
  end
44
42
 
45
- # The Array of Options::Command objects tied to this Options instance.
46
43
  attr_reader :commands
47
-
48
- # The Array of Options::Option objects tied to this Options instance.
49
44
  attr_reader :options
50
45
 
51
46
  # Create a new instance of Options and optionally build options via a block.
52
47
  #
53
48
  # block - An optional block used to specify options.
54
49
  def initialize(&block)
55
- @banner = ""
56
- @runner = nil
50
+ @banner = ''
57
51
  @commands = []
58
- @command_name = nil
59
- @command_callback = nil
60
- @options = []
52
+ @triggered_command = nil
53
+ @options = []
61
54
  @triggered_options = []
62
55
  @longest_cmd = 0
63
- @longest_flag = 0
64
-
65
- # if block_given?
66
- # block.arity == 1 ? yield(self) : instance_eval(&block)
67
- # end
56
+ @longest_opt = 0
68
57
  instance_eval(&block) if block_given?
69
58
  end
70
59
 
@@ -74,91 +63,94 @@ module Pyer
74
63
  # block - An optional block which when used will yield non options.
75
64
  #
76
65
  # Returns an Array of original items with options removed.
77
- def parse(items = ARGV, &block)
78
- item=items.shift
66
+ def parse(items = ARGV)
67
+ item = items.shift
79
68
  # need some help ?
80
- if item == '?' || item == '-h' || item == '--help' || item == 'help' || item.nil?
81
- puts self.help
82
- exit
83
- end
69
+ show_help if item == '?' || item == '-h' || item == '--help' || item == 'help' || item.nil?
84
70
  # parsing command
85
- if !@commands.empty?
86
- cmd = commands.find { |cmd| cmd.name == item }
87
- raise UnknownCommandError if cmd.nil?
88
- @command_name = cmd.name
89
- @command_call = cmd.callback
90
- item=items.shift
71
+ unless commands.empty?
72
+ parse_command(item)
73
+ item = items.shift
91
74
  end
92
75
  # parsing options
93
76
  until item.nil?
94
- #break if item == '--'
95
- if item.match(/^--[^-]+$/).nil? && item.match(/^-[^-]$/).nil?
96
- raise InvalidOptionError, "invalid #{item} option"
97
- end
98
- key = item.sub(/\A--?/, '')
99
- option = options.find { |opt| opt.name == key || opt.short == key }
100
- if option
101
- @triggered_options << option
102
- if option.expects_argument?
103
- option.value = items.shift
104
- raise MissingArgumentError, "missing #{item} argument" if option.value.nil?
105
- raise InvalidArgumentError, "(#{item}=#{option.value}) argument can't start with '-'" if option.value.start_with?('-')
106
- else
107
- option.value = true
108
- end
77
+ option = parse_option(item)
78
+ if option.expects_argument
79
+ option.value = items.shift
80
+ fail MissingArgumentError, "missing #{item} argument" if option.value.nil? || option.value.start_with?('-')
109
81
  else
110
- raise UnknownOptionError, "unknown #{item} option"
82
+ option.value = true
111
83
  end
112
- item=items.shift
113
- end
114
- if @runner.respond_to?(:call)
115
- @runner.call(self, items)
84
+ item = items.shift
116
85
  end
117
86
  # return the Options instance
118
87
  self
119
88
  end
120
89
 
121
- # Print a handy Options help string.
122
- #
123
- # Returns the banner followed by available option help strings.
124
- def help
125
- if @commands.empty?
126
- helpstr = "Usage: #{File.basename($0)} [options]\n"
127
- else
128
- helpstr = "Usage: #{File.basename($0)} command [options]\n"
90
+ def parse_command(command)
91
+ cmd = commands.find { |c| c.name == command }
92
+ fail UnknownCommandError if cmd.nil?
93
+ @triggered_command = cmd
94
+ end
95
+
96
+ def parse_option(option)
97
+ if option.match(/^--[^-]+$/).nil? && option.match(/^-[^-]$/).nil?
98
+ fail InvalidOptionError, "invalid #{option} option"
129
99
  end
130
- helpstr << @banner if !@banner.empty?
131
- if !@commands.empty?
132
- helpstr << "Commands:\n"
133
- commands.each { |cmd|
134
- tab = ' ' * ( @longest_cmd + 1 - cmd.name.size )
135
- helpstr << ' ' + cmd.name + tab + ': ' + cmd.description + "\n"
136
- }
100
+ key = option.sub(/\A--?/, '')
101
+ triggered_option = options.find { |opt| opt.name == key || opt.short == key }
102
+ fail UnknownOptionError, "unknown #{option} option" if triggered_option.nil?
103
+ @triggered_options << triggered_option
104
+ triggered_option
105
+ end
106
+
107
+ private :parse_command, :parse_option
108
+
109
+ # Print a handy Options help string and exit.
110
+ def help
111
+ helpstr = "Usage: #{File.basename($PROGRAM_NAME)} "
112
+ helpstr << 'command ' unless commands.empty?
113
+ helpstr << "[options]\n"
114
+ helpstr << ' ' + banner unless banner.empty?
115
+ helpstr << help_commands unless commands.empty?
116
+ helpstr << help_options
117
+ helpstr
118
+ end
119
+
120
+ def help_commands
121
+ helpstr = "Commands:\n"
122
+ @commands.each do |cmd|
123
+ tab = ' ' * (@longest_cmd + 1 - cmd.name.size)
124
+ helpstr << ' ' + cmd.name + tab + ': ' + cmd.description + "\n"
137
125
  end
138
- helpstr << "Options:\n"
139
- options.each { |opt|
140
- tab = ' ' * ( @longest_flag + 1 - opt.name.size )
141
- if opt.expects_argument?
142
- arg = ' <arg>'
143
- else
144
- arg = ' '
145
- end
126
+ helpstr
127
+ end
128
+
129
+ def help_options
130
+ helpstr = "Options:\n"
131
+ @options.each do |opt|
132
+ tab = ' ' * (@longest_opt + 1 - opt.name.size)
133
+ arg = opt.expects_argument ? ' <arg>' : ' '
146
134
  helpstr << ' -' + opt.short + '|--' + opt.name + arg + tab + ': ' + opt.description + "\n"
147
- }
135
+ end
148
136
  helpstr
149
137
  end
150
138
 
139
+ def show_help
140
+ puts help
141
+ exit
142
+ end
143
+
144
+ private :help_commands, :help_options, :show_help
145
+
151
146
  # Banner
152
147
  #
153
148
  # Example:
154
149
  # banner 'This is the banner'
155
150
  #
156
- def banner( desc = nil )
157
- if desc.nil?
158
- @banner
159
- else
160
- @banner += desc +"\n"
161
- end
151
+ def banner(desc = nil)
152
+ @banner += desc + "\n" unless desc.nil?
153
+ @banner
162
154
  end
163
155
 
164
156
  # Command
@@ -167,30 +159,20 @@ module Pyer
167
159
  # command 'run', 'Running'
168
160
  # command :test, 'Testing'
169
161
  #
170
- # Returns the created instance of Options::Command.
162
+ # Returns the created instance of Command.
171
163
  # or returns the command given in argument
172
164
  #
173
165
  def command(name = nil, desc = nil, &block)
174
- if !name.nil?
166
+ if name.nil?
167
+ @triggered_command.callback.call if !@triggered_command.nil? && @triggered_command.callback.respond_to?(:call)
168
+ @triggered_command.nil? ? nil : @triggered_command.name
169
+ else
175
170
  @longest_cmd = name.size if name.size > @longest_cmd
176
171
  cmd = Command.new(name, desc, &block)
177
172
  @commands << cmd
178
173
  end
179
- @command_name
180
- end
181
- alias cmd command
182
-
183
- # Call the command callback of the command given in ARGV
184
- #
185
- # Example:
186
- # # show messahe when command is executed (not during parsing)
187
- # command 'run', 'Running' do
188
- # puts "run in progress"
189
- # end
190
- #
191
- def callback
192
- @command_call.call if @command_call.respond_to?(:call)
193
174
  end
175
+ alias_method :cmd, :command
194
176
 
195
177
  # Add a value to options
196
178
  #
@@ -198,10 +180,10 @@ module Pyer
198
180
  # value 'user', 'Your username'
199
181
  # value :pass, 'Your password'
200
182
  #
201
- # Returns the created instance of Options::Value.
183
+ # Returns the created instance of Value.
202
184
  #
203
185
  def value(name, desc, &block)
204
- @longest_flag = name.size if name.size > @longest_flag
186
+ @longest_opt = name.size if name.size > @longest_opt
205
187
  option = Value.new(name, desc, &block)
206
188
  @options << option
207
189
  option
@@ -213,31 +195,15 @@ module Pyer
213
195
  # flag :verbose, 'Enable verbose mode'
214
196
  # flag 'debug', 'Enable debug mode'
215
197
  #
216
- # Returns the created instance of Options::Flag.
198
+ # Returns the created instance of Flag.
217
199
  #
218
200
  def flag(name, desc, &block)
219
- @longest_flag = name.size if name.size > @longest_flag
201
+ @longest_opt = name.size if name.size > @longest_opt
220
202
  option = Flag.new(name, desc, &block)
221
203
  @options << option
222
204
  option
223
205
  end
224
206
 
225
- # Specify code to be executed when these options are parsed.
226
- #
227
- # Example:
228
- #
229
- # opts = Options.parse do
230
- # flag :v, :verbose
231
- #
232
- # run do |opts, args|
233
- # puts "Arguments: #{args.inspect}" if opts.verbose?
234
- # end
235
- # end
236
- #def run(callable = nil, &block)
237
- def run(&block)
238
- @runner = block if block_given?
239
- end
240
-
241
207
  # Fetch an options argument value.
242
208
  #
243
209
  # key - The Symbol or String option short or long flag.
@@ -249,7 +215,7 @@ module Pyer
249
215
  option.value if option
250
216
  end
251
217
 
252
- # Enumerable interface. Yields each Options::Option.
218
+ # Enumerable interface. Yields each Option.
253
219
  def each(&block)
254
220
  options.each(&block)
255
221
  end
@@ -260,124 +226,92 @@ module Pyer
260
226
  def to_hash
261
227
  Hash[options.map { |opt| [opt.name.to_sym, opt.value] }]
262
228
  end
263
- alias to_h to_hash
264
229
 
265
- # Fetch a list of options which were missing from the parsed list.
266
- #
267
- # Examples:
268
- #
269
- # opts = Options.new do
270
- # value :n, :name
271
- # value :p, :password
272
- # end
273
- #
274
- # opts.parse %w[ --name Lee ]
275
- # opts.missing #=> ['password']
276
- #
230
+ alias_method :to_h, :to_hash
231
+
232
+ private
233
+
277
234
  # Returns an Array of Strings representing missing options.
278
- def missing
279
- (options - @triggered_options).map(&:name)
235
+ def find_option(name)
236
+ @triggered_options.find { |opt| opt.name == name }
280
237
  end
281
238
 
282
- private
283
239
  # Returns true if this option is present.
284
240
  # If this method does not end with a ? character it will instead
285
241
  # return the value of the option or nil
286
242
  #
287
243
  # Examples:
288
- # opts.parse %( --verbose )
244
+ # opts.parse %(--verbose)
289
245
  # opts.verbose? #=> true
290
246
  # opts.other? #=> false
291
247
  #
292
248
  def method_missing(method)
293
249
  meth = method.to_s
294
250
  if meth.end_with?('?')
295
- meth.chop!
296
- !(@triggered_options.find { |opt| opt.name == meth }).nil?
251
+ !find_option(meth.chop!).nil?
297
252
  else
298
- o = @triggered_options.find { |opt| opt.name == meth }
299
- # o.nil? ? super : o.value
300
- if o.nil?
301
- nil
302
- else
303
- o.callback.call if o.callback.respond_to?(:call)
304
- o.nil? ? nil : o.value
305
- end
253
+ o = find_option(meth)
254
+ o.callback.call if !o.nil? && o.callback.respond_to?(:call)
255
+ o.nil? ? nil : o.value
306
256
  end
307
257
  end
258
+ end
308
259
 
309
- class Command
310
- attr_reader :name, :description, :callback
311
-
312
- # Incapsulate internal command.
313
- #
314
- # name - The String or Symbol command name.
315
- # description - The String description text.
316
- # block - An optional block.
317
- def initialize(name, description, &block)
318
- @name = name.to_s
319
- raise InvalidCommandError, "Command #{@name} is invalid" if @name.start_with?('-')
320
- @description = description
321
- @callback = (block_given? ? block : nil)
322
- end
323
- end
260
+ # Command class
261
+ class Command
262
+ attr_reader :name, :description, :callback
324
263
 
325
- class Flag
326
- attr_reader :short, :name, :description, :callback
327
- attr_accessor :value
328
-
329
- # Incapsulate internal option information, mainly used to store
330
- # option specific configuration data, most of the meat of this
331
- # class is found in the #value method.
332
- #
333
- # name - The String or Symbol option name.
334
- # description - The String description text.
335
- # block - An optional block.
336
- def initialize(name, description, &block)
337
- # Remove leading '-' from name if any
338
- @name = name.to_s.gsub(/^--?/, '')
339
- raise InvalidOptionError, "Option #{@name} is invalid" if @name.size < 2
340
- @expects_argument = false
341
- @value = false
342
- @short = @name[0]
343
- @description = description
344
- @callback = (block_given? ? block : nil)
345
- end
346
-
347
- # Returns true if this option expects an argument.
348
- def expects_argument?
349
- @expects_argument
350
- end
264
+ # Incapsulate internal command.
265
+ #
266
+ # name - The String or Symbol command name.
267
+ # description - The String description text.
268
+ # block - An optional block.
269
+ def initialize(name, description, &block)
270
+ @name = name.to_s
271
+ fail InvalidCommandError, "Command #{@name} is invalid" if @name.start_with?('-')
272
+ @description = description
273
+ @callback = (block_given? ? block : nil)
351
274
  end
275
+ end
352
276
 
353
- class Value
354
- attr_reader :short, :name, :description, :callback
355
- attr_accessor :value
356
-
357
- # Incapsulate internal option information, mainly used to store
358
- # option specific configuration data, most of the meat of this
359
- # class is found in the #value method.
360
- #
361
- # name - The String or Symbol option name.
362
- # description - The String description text.
363
- # block - An optional block.
364
- def initialize(name, description, &block)
365
- # Remove leading '-' from name if any
366
- @name = name.to_s.gsub(/^--?/, '')
367
- raise InvalidOptionError, "Option #{@name} is invalid" if @name.size < 2
368
- @expects_argument = true
369
- @value = nil
370
- @short = @name[0]
371
- @description = description
372
- @callback = (block_given? ? block : nil)
373
- end
277
+ # Option class
278
+ class Option
279
+ attr_reader :short, :name, :description, :callback
280
+ attr_reader :expects_argument
281
+ attr_accessor :value
282
+
283
+ # Incapsulate internal option information, mainly used to store
284
+ # option specific configuration data.
285
+ #
286
+ # name - The String or Symbol option name.
287
+ # description - The String description text.
288
+ # block - An optional block.
289
+ def initialize(name, description, &block)
290
+ # Remove leading '-' from name if any
291
+ @name = name.to_s.gsub(/^--?/, '')
292
+ fail InvalidOptionError, "Option #{@name} is invalid" if @name.size < 2
293
+ @expects_argument = false
294
+ @value = nil
295
+ @short = @name[0]
296
+ @description = description
297
+ @callback = (block_given? ? block : nil)
298
+ end
299
+ end
374
300
 
375
- # Returns true if this option expects an argument.
376
- def expects_argument?
377
- @expects_argument
378
- end
301
+ # Flag class
302
+ class Flag < Option
303
+ def initialize(name, description, &block)
304
+ super
305
+ @value = false
379
306
  end
307
+ end
380
308
 
309
+ # Value class
310
+ class Value < Option
311
+ def initialize(name, description, &block)
312
+ super
313
+ @expects_argument = true
314
+ end
381
315
  end
382
316
  end
383
317
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pyer-options
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pierre BAZONNARD
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-15 00:00:00.000000000 Z
11
+ date: 2015-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake