pyer-options 2.0.2 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
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