s0nspark-choice 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2009 Tim Ferrell
2
+ Original Copyright (c) 2006 Chris Wanstrath
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ this software and associated documentation files (the "Software"), to deal in
6
+ the Software without restriction, including without limitation the rights to
7
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ the Software, and to permit persons to whom the Software is furnished to do so,
9
+ subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,441 @@
1
+ = Welcome to Choice
2
+
3
+ Choice is a small library for defining and parsing command line options. It
4
+ works awesomely with Highline[http://highline.rubyforge.org/] or other command
5
+ line interface libraries.
6
+
7
+ Choice was written by Chris Wanstrath as an exercise in test driving development
8
+ of a DSL. This project is still an infant: bugs are expected and tattling on them
9
+ is appreciated.
10
+
11
+ Installing is easy, with RubyGems. Give it a shot:
12
+ $ gem install choice
13
+
14
+ If you are lost, you can find Choice at http://choice.rubyforge.org or
15
+ http://rubyforge.org/projects/choice/. E-mail inquiries can be directed to
16
+ mailto:chris[at]ozmm[dot]org.
17
+
18
+ Of course, Choice is licensed under the MIT License, which you can find included
19
+ in the LICENSE file or by surfing your World Wide Web browser of choice towards
20
+ http://www.opensource.org/licenses/mit-license.php.
21
+
22
+ == Using Choice
23
+
24
+ An +examples+ directory is included with Choice, in which some contrived Ruby
25
+ programs utilizing the library have been placed. Here's a snippet:
26
+
27
+ === ftpd.rb
28
+
29
+ require 'choice'
30
+
31
+ PROGRAM_VERSION = 4
32
+
33
+ Choice.options do
34
+ header ''
35
+ header 'Specific options:'
36
+
37
+ option :host do
38
+ short '-h'
39
+ long '--host=HOST'
40
+ desc 'The hostname or ip of the host to bind to (default 127.0.0.1)'
41
+ default '127.0.0.1'
42
+ end
43
+
44
+ option :port do
45
+ short '-p'
46
+ long '--port=PORT'
47
+ desc 'The port to listen on (default 21)'
48
+ cast Integer
49
+ default 21
50
+ end
51
+
52
+ separator ''
53
+ separator 'Common options: '
54
+
55
+ option :help do
56
+ long '--help'
57
+ desc 'Show this message'
58
+ end
59
+
60
+ option :version do
61
+ short '-v'
62
+ long '--version'
63
+ desc 'Show version'
64
+ action do
65
+ puts "ftpd.rb FTP server v#{PROGRAM_VERSION}"
66
+ exit
67
+ end
68
+ end
69
+ end
70
+
71
+ puts 'port: ' + Choice.choices[:port]
72
+
73
+ Notice the last line. For free, you will be given a <tt>Choice.choices</tt>
74
+ hash which contain, at runtime, the options found and their values.
75
+
76
+ Because we gave option <tt>:port</tt> a default of 21,
77
+ <tt>Choice.choices[:port]</tt> should be 21 if we run ftpd.rb with no options.
78
+ Let's see.
79
+
80
+ $ ruby ftpd.rb
81
+ port: 21
82
+
83
+ Cool. On our system, port 21 is reserved. Let's use another port.
84
+
85
+ $ ruby ftpd.rb -p 2100
86
+ port: 2100
87
+
88
+ Alright. And, of course, there is the hard way of doing things.
89
+
90
+ $ ruby ftpd.rb --port=2100
91
+ port: 2100
92
+
93
+ That <tt>:version</tt> option looks pretty interesting, huh? I wonder what it
94
+ does...
95
+
96
+ $ ruby ftpd.rb -v
97
+ ftpd.rb FTP server v4
98
+
99
+ That's not all, though. We also get a <tt>--help</tt> option for free.
100
+
101
+ $ ruby ftpd.rb --help
102
+ Usage: ftpd.rb [-hpv]
103
+
104
+ Specific options:
105
+ -h, --host=HOST The hostname or ip of the host to bind to (default 127.0.0.1)
106
+ -p, --port=PORT The port to listen on (default 21)
107
+
108
+ Common options:
109
+ --help Show this message
110
+ -v, --version Show version
111
+
112
+
113
+ == The Choice.choices hash
114
+
115
+ For better or worse, the <tt>Choice.choices</tt> hash is a bit lazy. It does
116
+ not care how you access it. Using the above example, assume we have a
117
+ <tt>:port</tt> option and we replace the last line of our program with the
118
+ following three lines:
119
+
120
+ puts 'port: ' + Choice.choices[:port]
121
+ puts 'port: ' + Choice.choices['port']
122
+ puts 'port: ' + Choice.choices.port
123
+
124
+ Now, run it.
125
+
126
+ $ ftpd.rb -p 2100
127
+ port: 2100
128
+ port: 2100
129
+ port: 2100
130
+
131
+ Lazy, huh?
132
+
133
+ Keep in mind that your option's key in the <tt>Choice.choices</tt> hash is
134
+ defined by the first parameter passed to option statement. This is perfectly
135
+ legit, albeit somewhat confusing:
136
+
137
+ option :name do
138
+ short '-h'
139
+ long '--handle=NAME'
140
+ desc "Your handle."
141
+ end
142
+
143
+ You can access this option by using <tt>Choice.choices[:name]</tt>, not
144
+ <tt>:handle</tt>.
145
+
146
+ == Option options
147
+
148
+ Obviously, Choice revolves around the <tt>option</tt> statement, which receives
149
+ a block. Here are all the, er, options +option+ accepts. None of them are
150
+ required but +short+ or +long+ must be present for Choice to know what to do.
151
+
152
+ Options must be defined in the context of a <tt>Choice.options</tt> block, as
153
+ seen above. This context is assumed for the following explanations.
154
+
155
+ For the quick learners, here's the list:
156
+ * short
157
+ * long
158
+ * default
159
+ * desc
160
+ * cast
161
+ * valid (takes array)
162
+ * validate (takes regex)
163
+ * filter (takes a block)
164
+ * action (ditto)
165
+
166
+ You can define these within your option in any order which pleases you.
167
+
168
+ === short
169
+
170
+ Defines the short switch for an option. Expected to be a dash and a single
171
+ character.
172
+
173
+ short '-s'
174
+
175
+ === long
176
+
177
+ Defines the long switch for an option. Expected to be a double dash followed by
178
+ a string, an equal sign (or a space), and another string.
179
+
180
+ There are two variants: longs where a parameter is required and longs where a
181
+ parameter is optional, in which case the value will be +true+ if the option is
182
+ present.
183
+
184
+ *Optional*:
185
+ long '--debug=[LEVEL]'
186
+
187
+ Assuming our program defines Choices and ends with this line:
188
+ puts 'debug: ' + Choice.choices[:debug]
189
+
190
+ we can do this:
191
+
192
+ $ ruby ftpd.rb --debug
193
+ debug: true
194
+
195
+ $ ruby ftpd.rb --debug=1
196
+ debug: 1
197
+
198
+ $ ruby ftpd.rb --debug 1
199
+ debug: 1
200
+
201
+ *Required*:
202
+ long '--debug=LEVEL'
203
+
204
+ Assuming the same as above:
205
+
206
+ $ ruby ftpd.rb --debug 1
207
+ debug: 1
208
+
209
+ $ ruby ftpd.rb --debug
210
+ <help screen printed>
211
+
212
+ === long as array
213
+
214
+ Often you may wish to allow users the ability to pass in multiple arguments and have
215
+ them all combined into an array. You can accomplish this by defining a +long+ and
216
+ setting the caps-argument to *ARG. Like this:
217
+
218
+ long '--suit *SUITS'
219
+
220
+ <tt>Choice.choices.suits</tt> will now return an array. Here's an example of usage:
221
+
222
+ $ ruby --suit hearts clubs
223
+ suit: ['hearts', 'clubs']
224
+
225
+ Check out <tt>examples/gamble.rb</tt> for more information on this cool feature.
226
+
227
+ === default
228
+
229
+ You can define a default value for your option, if you'd like. If the option
230
+ is not present in the argument list, the default will be returned when trying
231
+ to access that element of the <tt>Choice.choices</tt> hash.
232
+
233
+ As with the above, assume our program prints <tt>Choice.choices[:debug]</tt>:
234
+
235
+ default 'info'
236
+
237
+ If we don't pass in <tt>--debug</tt>, the <tt>:debug</tt> element of our hash
238
+ will be 'info.'
239
+
240
+ $ ftpd.rb
241
+ debug: info
242
+
243
+ $ ftpd.rb --debug warn
244
+ debug: warn
245
+
246
+ === desc
247
+
248
+ The description of this option. Fairly straightforward, with one little trick:
249
+ multiple +desc+ statements in a single option will be considered new desc lines.
250
+ The desc lines will be printed in the order they are defined. Like this:
251
+
252
+ desc "Your hostname."
253
+ desc "(default 'localhost')"
254
+
255
+ A snippet from your <tt>--help</tt> might then look like this:
256
+
257
+ -h, --host=HOST Your hostname.
258
+ (default 127.0.0.1)
259
+
260
+
261
+ === cast
262
+
263
+ By default, all members of the <tt>Choice.choices</tt> hash are strings. If
264
+ you want something different, like an Integer for a port number, you can use
265
+ the +cast+ statement.
266
+
267
+ cast Integer
268
+
269
+ Currently support +cast+ options:
270
+
271
+ * Integer
272
+ * String
273
+ * Float
274
+ * Symbol
275
+
276
+ We'll probably add Date, Time, and DateTime in the future, if people want them.
277
+
278
+ === valid
279
+
280
+ Giving +valid+ an array creates a whitelist of acceptable arguments.
281
+
282
+ valid %w[clubs hearts spades diamonds]
283
+
284
+ If our option is passed anything other than one of the four card suits, the help
285
+ screen will be printed. It might be a good idea to include acceptable arguments in
286
+ your option's "desc" value.
287
+
288
+ $ ruby gamble.rb -s clubs
289
+ suit: clubs
290
+
291
+ $ ruby gamble.rb -s joker
292
+ <help screen printed>
293
+
294
+ === validate
295
+
296
+ The +validate+ statement accepts a regular expression which it will test
297
+ against the value passed. If the test fails, the <tt>--help</tt> screen will
298
+ be printed. I love ports, so let's stick with that example:
299
+
300
+ validate /^\d+$/
301
+
302
+ Of course, 2100 matches this:
303
+
304
+ $ ruby ftpd.rb -p 2100
305
+ port: 2100
306
+
307
+ I like dogs. I wish dogs could be ports. Alas, Choice knows better (once
308
+ I've told it so):
309
+
310
+ $ ruby ftpd.rb -p labradoodle
311
+ <help screen printed>
312
+
313
+ === filter
314
+
315
+ The +filter+ statement lets you play with a value before it goes into the
316
+ <tt>Choice.choices</tt> hash. If you use +cast+, this will occur post-casting.
317
+
318
+ In this program we're defining a :name option and saying we don't want any
319
+ crazy characters in it, then printing that element of the
320
+ <tt>Choice.choices</tt>+ hash:
321
+
322
+ filter do |value|
323
+ value = value.gsub(/[^\w]/, '')
324
+ end
325
+
326
+ Now:
327
+
328
+ $ ruby ftpd.rb --name=c.hr.is
329
+ name: chris
330
+
331
+ You can probably think of better uses.
332
+
333
+ === action
334
+
335
+ A block passed to the +action+ statement will be run if that particular option
336
+ is passed. See the <tt>--version</tt> example earlier.
337
+
338
+ === required options
339
+
340
+ You can specify an option as being required by passing :required => true to the
341
+ option definition. Choice will then print the help screen if this option is
342
+ not present. Please let your dear users know which options are required.
343
+
344
+ For example:
345
+
346
+ option :card, :required => true do
347
+ short '-c'
348
+ long '--card CARD'
349
+ desc "The card you wish to gamble on. Required. Only one, please."
350
+ end
351
+
352
+ Then:
353
+
354
+ $ ruby gamble.rb
355
+ <help screen, -c or --card wasn't passed>
356
+
357
+ == Other options
358
+
359
+ These statements are purely aesthetic, used to help make your <tt>--help</tt>
360
+ screen a little more digestible.
361
+
362
+ Passing an empty string to any of these options will print a newline.
363
+
364
+ === banner
365
+
366
+ The banner is the first line printed when your program is called with
367
+ <tt>--help</tt>. By default, it will be something like this, based on the
368
+ options defined:
369
+
370
+ Usage: ftpd.rb [-hpv]
371
+
372
+ You can pass any string to the +banner+ statement to override what prints. This
373
+ might be useful if you're into ascii art.
374
+
375
+ banner "Usage: ftpd.rb"
376
+
377
+ === header
378
+
379
+ The header is what shows up after the banner but before your option definitions
380
+ are printed. Each header call is a newline. Check out the example above.
381
+
382
+ header "ftp is a harsh and unforgiving protocol."
383
+
384
+ === separator
385
+
386
+ As in the example above, you can put separators between options to help display
387
+ the logical groupings of your options. Or whatever.
388
+
389
+ separator "----"
390
+
391
+ To get a blank line, rock an empty string:
392
+
393
+ separator ''
394
+
395
+ === footer
396
+
397
+ The footer is displayed after all your options are displayed. Nothing new
398
+ here, works like the other options above.
399
+
400
+ footer "That's all there is to it!"
401
+
402
+ == Shorthand
403
+
404
+ Now that you've gone through all the hard stuff, here's the easy stuff: Choice
405
+ options can be defined with a simple hash if you'd like. Here's an example,
406
+ from the tests:
407
+
408
+ Choice.options do
409
+ header "Tell me about yourself?"
410
+ header ""
411
+ options :band => { :short => "-b", :long => "--band=BAND", :cast => String, :desc => "Your favorite band.",
412
+ :validate => /\w+/ },
413
+ :animal => { :short => "-a", :long => "--animal=ANIMAL", :cast => String, :desc => "Your favorite animal." }
414
+
415
+ footer ""
416
+ footer "--help This message"
417
+ end
418
+
419
+ How's that tickle you? Real nice.
420
+
421
+ == It looks like poetry
422
+
423
+ That's it. Not much, I know. Maybe this will make handling your command
424
+ line options a bit easier. You can always use the option parser in the standard
425
+ Ruby library, but DSLs are just so cool. As one of my non-programmer friends
426
+ said of a Ruby DSL: "It looks like poetry."
427
+
428
+ == It's totally broken
429
+
430
+ Okay, I knew this would happen. Do me a favor, if you have time: run +rake+
431
+ from the Choice directory and send me the output (mailto:chris[at]ozmm[dot]org).
432
+ This'll run the unit tests. Also, if you would, send me a bit of information
433
+ on your platform. Choice was tested on OS X and RHEL with a 2.4 kernel but who
434
+ knows. Thanks a lot.
435
+
436
+ == Thanks to
437
+
438
+ For bug reports, patches, and ideas I'd be honored to thank the following:
439
+
440
+ - Justin Bailey
441
+ - Alexis Li