trollop 1.7.2 → 1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +11 -52
- data/lib/trollop.rb +19 -3
- data/test/test_trollop.rb +75 -0
- metadata +3 -3
data/README.txt
CHANGED
@@ -24,6 +24,7 @@ Trollop: getting you 90% of the way there with only 10% of the effort.
|
|
24
24
|
- Sensible defaults. No tweaking necessary, much tweaking possible.
|
25
25
|
- Support for long options, short options, short option bundling,
|
26
26
|
and automatic type validation and conversion.
|
27
|
+
- Support for subcommands.
|
27
28
|
- Automatic help message generation, wrapped to current screen width.
|
28
29
|
- Lots of unit tests.
|
29
30
|
|
@@ -61,63 +62,21 @@ Trollop: getting you 90% of the way there with only 10% of the effort.
|
|
61
62
|
Trollop::die :volume, "must be non-negative" if opts[:volume] < 0
|
62
63
|
Trollop::die :file, "must exist" unless File.exist?(opts[:file]) if opts[:file]
|
63
64
|
|
64
|
-
|
65
|
+
##### sub-command support ######
|
65
66
|
|
66
67
|
require 'trollop'
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
Synchronizes the Sup index with one or more message sources by adding
|
71
|
-
messages, deleting messages, or changing message state in the index as
|
72
|
-
appropriate.
|
73
|
-
|
74
|
-
[...]
|
75
|
-
|
76
|
-
Usage:
|
77
|
-
sup-sync [options] <source>*
|
78
|
-
|
79
|
-
where <source>* is zero or more source URIs. If no sources are given,
|
80
|
-
sync from all usual sources. Supported source URI schemes can be seen
|
81
|
-
by running "sup-add --help".
|
82
|
-
|
83
|
-
Options controlling WHICH messages sup-sync operates on:
|
84
|
-
EOS
|
85
|
-
opt :new, "Operate on new messages only. Don't scan over the entire source. (Default.)", :short => :none
|
86
|
-
opt :changed, "Scan over the entire source for messages that have been deleted, altered, or moved from another source. (In the case of mbox sources, this includes all messages AFTER an altered message.)"
|
87
|
-
opt :restored, "Operate only on those messages included in a dump file as specified by --restore which have changed state."
|
88
|
-
opt :all, "Operate on all messages in the source, regardless of newness or changedness."
|
89
|
-
opt :start_at, "For --changed and --all, start at a particular offset.", :type => :int
|
90
|
-
|
91
|
-
text <<EOS
|
92
|
-
|
93
|
-
Options controlling HOW message state is altered:
|
94
|
-
EOS
|
95
|
-
opt :asis, "If the message is already in the index, preserve its state. Otherwise, use default source state. (Default.)", :short => :none
|
96
|
-
opt :restore, "Restore message state from a dump file created with sup-dump. If a message is not in this dumpfile, act as --asis.", :type => String, :short => :none
|
97
|
-
opt :discard, "Discard any message state in the index and use the default source state. Dangerous!", :short => :none
|
98
|
-
opt :archive, "When using the default source state, mark messages as archived.", :short => "-x"
|
99
|
-
opt :read, "When using the default source state, mark messages as read."
|
100
|
-
opt :extra_labels, "When using the default source state, also apply these user-defined labels. Should be a comma-separated list.", :type => String, :short => :none
|
101
|
-
|
102
|
-
text <<EOS
|
103
|
-
|
104
|
-
Other options:
|
105
|
-
EOS
|
106
|
-
opt :verbose, "Print message ids as they're processed."
|
107
|
-
opt :optimize, "As the final operation, optimize the index."
|
108
|
-
opt :all_sources, "Scan over all sources.", :short => :none
|
109
|
-
opt :dry_run, "Don't actually modify the index. Probably only useful with --verbose.", :short => "-n"
|
110
|
-
opt :version, "Show version information", :short => :none
|
111
|
-
|
112
|
-
conflicts :changed, :all, :new, :restored
|
113
|
-
conflicts :asis, :restore, :discard
|
68
|
+
global_opts = Trollop::options do
|
69
|
+
opt :global_option, "This is a global option"
|
70
|
+
stop_on %w(sub-command-1 sub-command-2)
|
114
71
|
end
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
72
|
+
|
73
|
+
cmd = ARGV.shift
|
74
|
+
cmd_opts = Trollop::options do
|
75
|
+
opt :cmd_option, "This is an option only for the subcommand"
|
119
76
|
end
|
120
77
|
|
78
|
+
puts "global: #{global_opts.inspect}, cmd: #{cmd.inspect}, cmd options: #{cmd_opts.inspect}"
|
79
|
+
|
121
80
|
== REQUIREMENTS
|
122
81
|
|
123
82
|
* none!
|
data/lib/trollop.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
module Trollop
|
7
7
|
|
8
|
-
VERSION = "1.
|
8
|
+
VERSION = "1.8"
|
9
9
|
|
10
10
|
## Thrown by Parser in the event of a commandline error. Not needed if
|
11
11
|
## you're using the Trollop::options entry.
|
@@ -49,6 +49,7 @@ class Parser
|
|
49
49
|
@short = {}
|
50
50
|
@order = []
|
51
51
|
@constraints = []
|
52
|
+
@stop_words = []
|
52
53
|
|
53
54
|
#instance_eval(&b) if b # can't take arguments
|
54
55
|
cloaker(&b).bind(self).call(*a) if b
|
@@ -186,12 +187,27 @@ class Parser
|
|
186
187
|
@constraints << [:conflicts, syms]
|
187
188
|
end
|
188
189
|
|
190
|
+
## Defines a set of words which cause parsing to terminate when encountered,
|
191
|
+
## such that any options to the left of the word are parsed as usual, and
|
192
|
+
## options to the right of the word are left intact.
|
193
|
+
##
|
194
|
+
## A typical use case would be for subcommand support, where these would be
|
195
|
+
## set to the list of subcommands. A subsequent Trollop invocation would
|
196
|
+
## then be used to parse subcommand options.
|
197
|
+
def stop_on *words
|
198
|
+
@stop_words = [*words].flatten
|
199
|
+
end
|
200
|
+
|
189
201
|
## yield successive arg, parameter pairs
|
190
202
|
def each_arg args # :nodoc:
|
191
203
|
remains = []
|
192
204
|
i = 0
|
193
205
|
|
194
206
|
until i >= args.length
|
207
|
+
if @stop_words.member? args[i]
|
208
|
+
remains += args[i .. -1]
|
209
|
+
break
|
210
|
+
end
|
195
211
|
case args[i]
|
196
212
|
when /^--$/ # arg terminator
|
197
213
|
remains += args[(i + 1) .. -1]
|
@@ -200,7 +216,7 @@ class Parser
|
|
200
216
|
yield "--#{$1}", $2
|
201
217
|
i += 1
|
202
218
|
when /^--(\S+)$/ # long argument
|
203
|
-
if args[i + 1] && args[i + 1] !~ PARAM_RE
|
219
|
+
if args[i + 1] && args[i + 1] !~ PARAM_RE && !@stop_words.member?(args[i + 1])
|
204
220
|
remains << args[i + 1] unless yield args[i], args[i + 1]
|
205
221
|
i += 2
|
206
222
|
else # long argument no parameter
|
@@ -210,7 +226,7 @@ class Parser
|
|
210
226
|
when /^-(\S+)$/ # one or more short arguments
|
211
227
|
shortargs = $1.split(//)
|
212
228
|
shortargs.each_with_index do |a, j|
|
213
|
-
if j == (shortargs.length - 1) && args[i + 1] && args[i + 1] !~ PARAM_RE
|
229
|
+
if j == (shortargs.length - 1) && args[i + 1] && args[i + 1] !~ PARAM_RE && !@stop_words.member?(args[i + 1])
|
214
230
|
remains << args[i + 1] unless yield "-#{a}", args[i + 1]
|
215
231
|
i += 1 # once more below
|
216
232
|
else
|
data/test/test_trollop.rb
CHANGED
@@ -463,6 +463,81 @@ EOM
|
|
463
463
|
|
464
464
|
assert_nothing_raised { @p.parse(%w(--arg1 --arg2)) }
|
465
465
|
end
|
466
|
+
|
467
|
+
def test_stopwords_mixed
|
468
|
+
@p.opt "arg1", :default => false
|
469
|
+
@p.opt "arg2", :default => false
|
470
|
+
@p.stop_on %w(happy sad)
|
471
|
+
|
472
|
+
opts = @p.parse %w(--arg1 happy --arg2)
|
473
|
+
assert_equal true, opts["arg1"]
|
474
|
+
assert_equal false, opts["arg2"]
|
475
|
+
|
476
|
+
## restart parsing
|
477
|
+
@p.leftovers.shift
|
478
|
+
opts = @p.parse @p.leftovers
|
479
|
+
assert_equal false, opts["arg1"]
|
480
|
+
assert_equal true, opts["arg2"]
|
481
|
+
end
|
482
|
+
|
483
|
+
def test_stopwords_no_stopwords
|
484
|
+
@p.opt "arg1", :default => false
|
485
|
+
@p.opt "arg2", :default => false
|
486
|
+
@p.stop_on %w(happy sad)
|
487
|
+
|
488
|
+
opts = @p.parse %w(--arg1 --arg2)
|
489
|
+
assert_equal true, opts["arg1"]
|
490
|
+
assert_equal true, opts["arg2"]
|
491
|
+
|
492
|
+
## restart parsing
|
493
|
+
@p.leftovers.shift
|
494
|
+
opts = @p.parse @p.leftovers
|
495
|
+
assert_equal false, opts["arg1"]
|
496
|
+
assert_equal false, opts["arg2"]
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_stopwords_multiple_stopwords
|
500
|
+
@p.opt "arg1", :default => false
|
501
|
+
@p.opt "arg2", :default => false
|
502
|
+
@p.stop_on %w(happy sad)
|
503
|
+
|
504
|
+
opts = @p.parse %w(happy sad --arg1 --arg2)
|
505
|
+
assert_equal false, opts["arg1"]
|
506
|
+
assert_equal false, opts["arg2"]
|
507
|
+
|
508
|
+
## restart parsing
|
509
|
+
@p.leftovers.shift
|
510
|
+
opts = @p.parse @p.leftovers
|
511
|
+
assert_equal false, opts["arg1"]
|
512
|
+
assert_equal false, opts["arg2"]
|
513
|
+
|
514
|
+
## restart parsing again
|
515
|
+
@p.leftovers.shift
|
516
|
+
opts = @p.parse @p.leftovers
|
517
|
+
assert_equal true, opts["arg1"]
|
518
|
+
assert_equal true, opts["arg2"]
|
519
|
+
end
|
520
|
+
|
521
|
+
def test_stopwords_with_short_args
|
522
|
+
@p.opt :global_option, "This is a global option", :short => "-g"
|
523
|
+
@p.stop_on %w(sub-command-1 sub-command-2)
|
524
|
+
|
525
|
+
global_opts = @p.parse %w(-g sub-command-1 -c)
|
526
|
+
cmd = @p.leftovers.shift
|
527
|
+
|
528
|
+
@q = Parser.new
|
529
|
+
@q.opt :cmd_option, "This is an option only for the subcommand", :short => "-c"
|
530
|
+
cmd_opts = @q.parse @p.leftovers
|
531
|
+
|
532
|
+
assert_equal true, global_opts[:global_option]
|
533
|
+
assert_nil global_opts[:cmd_option]
|
534
|
+
|
535
|
+
assert_equal true, cmd_opts[:cmd_option]
|
536
|
+
assert_nil cmd_opts[:global_option]
|
537
|
+
|
538
|
+
assert_equal cmd, "sub-command-1"
|
539
|
+
assert_equal @q.leftovers, []
|
540
|
+
end
|
466
541
|
end
|
467
542
|
|
468
543
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trollop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: "1.8"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Morgan
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-06-16 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: "== DESCRIPTION Trollop is YAFCLAP --- yet another fine commandline argument processor for Ruby. Trollop is designed to provide the maximal amount of GNU-style argument processing in the minimum number of lines of code (for you, the programmer). - Simple usage. - Sensible defaults. No tweaking necessary, much tweaking possible. - Support for long options, short options, short option bundling, and automatic type validation and conversion. - Automatic help message generation, wrapped to current screen width. - Lots of unit tests. Synopsis ###### simple ###### require 'trollop' opts = Trollop::options do opt :monkey, \"Use monkey mode\" opt :goat, \"Use goat mode\", :default => true opt :num_limbs, \"Set number of limbs\", :default => 4 end p opts ###### medium ###### require 'trollop' opts = Trollop::options do version \"test 1.2.3 (c) 2007 William Morgan\" banner <<-EOS Test is an awesome program that does something very, very important. Usage: test [options] <filenames>+ where [options] are: EOS opt :ignore, \"Ignore incorrect values\" opt :file, \"Extra data filename to read in, with a very long option description like this one\", :type => String opt :volume, \"Volume level\", :default => 3.0 opt :iters, \"Number of iterations\", :default => 5 end Trollop::die :volume, \"must be non-negative\" if opts[:volume] < 0 Trollop::die :file, \"must exist\" unless File.exist?(opts[:file]) if opts[:file]
|
16
|
+
description: "== DESCRIPTION Trollop is YAFCLAP --- yet another fine commandline argument processor for Ruby. Trollop is designed to provide the maximal amount of GNU-style argument processing in the minimum number of lines of code (for you, the programmer). - Simple usage. - Sensible defaults. No tweaking necessary, much tweaking possible. - Support for long options, short options, short option bundling, and automatic type validation and conversion. - Support for subcommands. - Automatic help message generation, wrapped to current screen width. - Lots of unit tests. Synopsis ###### simple ###### require 'trollop' opts = Trollop::options do opt :monkey, \"Use monkey mode\" opt :goat, \"Use goat mode\", :default => true opt :num_limbs, \"Set number of limbs\", :default => 4 end p opts ###### medium ###### require 'trollop' opts = Trollop::options do version \"test 1.2.3 (c) 2007 William Morgan\" banner <<-EOS Test is an awesome program that does something very, very important. Usage: test [options] <filenames>+ where [options] are: EOS opt :ignore, \"Ignore incorrect values\" opt :file, \"Extra data filename to read in, with a very long option description like this one\", :type => String opt :volume, \"Volume level\", :default => 3.0 opt :iters, \"Number of iterations\", :default => 5 end Trollop::die :volume, \"must be non-negative\" if opts[:volume] < 0 Trollop::die :file, \"must exist\" unless File.exist?(opts[:file]) if opts[:file] ##### sub-command support ######"
|
17
17
|
email: wmorgan-trollop@masanjin.net
|
18
18
|
executables: []
|
19
19
|
|