trollop 1.10 → 1.10.1
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.
- data/History.txt +7 -0
- data/README.txt +1 -1
- data/Rakefile +8 -4
- data/lib/trollop.rb +82 -14
- data/test/test_trollop.rb +61 -2
- metadata +4 -13
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 1.10.1 / 2008-10-22
|
2
|
+
* Options hash now responds to method calls as well as standard hash lookup.
|
3
|
+
* Default values for multi-occurrence parameters now autoboxed.
|
4
|
+
* The relationship between multi-value, multi-occurrence, and default values
|
5
|
+
improved and explained.
|
6
|
+
* Documentation improvements.
|
7
|
+
|
1
8
|
== 1.10 / 2008-10-21
|
2
9
|
* Added :io type for parameters that point to IO streams (filenames, URIs, etc).
|
3
10
|
* For screen size detection, first try `stty size` before loading Curses.
|
data/README.txt
CHANGED
data/Rakefile
CHANGED
@@ -7,8 +7,8 @@ $:.unshift "lib"
|
|
7
7
|
require 'trollop'
|
8
8
|
|
9
9
|
class Hoe
|
10
|
-
def
|
11
|
-
end
|
10
|
+
def extra_dev_deps; @extra_dev_deps.reject { |x| x[0] == "hoe" } end
|
11
|
+
end
|
12
12
|
|
13
13
|
Hoe.new('trollop', Trollop::VERSION) do |p|
|
14
14
|
p.rubyforge_name = 'trollop'
|
@@ -25,8 +25,12 @@ task :upload_webpage => WWW_FILES do |t|
|
|
25
25
|
sh "rsync -Paz -essh #{t.prerequisites * ' '} wmorgan@rubyforge.org:/var/www/gforge-projects/trollop/"
|
26
26
|
end
|
27
27
|
|
28
|
-
task :
|
29
|
-
sh "
|
28
|
+
task :rdoc do |t|
|
29
|
+
sh "rdoc lib README.txt History.txt"
|
30
|
+
end
|
31
|
+
|
32
|
+
task :upload_docs => [:rdoc] do |t|
|
33
|
+
sh "rsync -az -essh doc/* wmorgan@rubyforge.org:/var/www/gforge-projects/trollop/trollop/"
|
30
34
|
end
|
31
35
|
|
32
36
|
# vim: syntax=ruby
|
data/lib/trollop.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
module Trollop
|
7
7
|
|
8
|
-
VERSION = "1.10"
|
8
|
+
VERSION = "1.10.1"
|
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.
|
@@ -26,7 +26,7 @@ FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))$/
|
|
26
26
|
PARAM_RE = /^-(-|\.$|[^\d\.])/
|
27
27
|
|
28
28
|
## The commandline parser. In typical usage, the methods in this class
|
29
|
-
## will be handled internally by Trollop
|
29
|
+
## will be handled internally by Trollop::options. In this case, only the
|
30
30
|
## #opt, #banner and #version, #depends, and #conflicts methods will
|
31
31
|
## typically be called.
|
32
32
|
##
|
@@ -79,18 +79,43 @@ class Parser
|
|
79
79
|
end
|
80
80
|
|
81
81
|
## Define an option. +name+ is the option name, a unique identifier
|
82
|
-
## for the option that you will use internally
|
83
|
-
##
|
84
|
-
## in help messages.
|
82
|
+
## for the option that you will use internally, which should be a
|
83
|
+
## symbol or a string. +desc+ is a string description which will be
|
84
|
+
## displayed in help messages.
|
85
85
|
##
|
86
86
|
## Takes the following optional arguments:
|
87
87
|
##
|
88
88
|
## [+:long+] Specify the long form of the argument, i.e. the form with two dashes. If unspecified, will be automatically derived based on the argument name by turning the +name+ option into a string, and replacing any _'s by -'s.
|
89
89
|
## [+:short+] Specify the short form of the argument, i.e. the form with one dash. If unspecified, will be automatically derived from +name+.
|
90
|
-
## [+:type+] Require that the argument take a parameter or parameters of type +type+. For a single parameter, the value can be a member of +SINGLE_ARG_TYPES+, or a corresponding Ruby class (e.g. +Integer+ for +:int+). For multiple parameters, the value can be any member of +MULTI_ARG_TYPES+ constant. If unset, the default argument type is +:flag+, meaning that the argument does not take a parameter. The specification of +:type+ is not necessary if +:default+ is given.
|
91
|
-
## [+:default+] Set the default value for an argument. Without a default value, the hash returned by #parse (and thus Trollop
|
90
|
+
## [+:type+] Require that the argument take a parameter or parameters of type +type+. For a single parameter, the value can be a member of +SINGLE_ARG_TYPES+, or a corresponding Ruby class (e.g. +Integer+ for +:int+). For multiple-argument parameters, the value can be any member of +MULTI_ARG_TYPES+ constant. If unset, the default argument type is +:flag+, meaning that the argument does not take a parameter. The specification of +:type+ is not necessary if a +:default+ is given.
|
91
|
+
## [+:default+] Set the default value for an argument. Without a default value, the hash returned by #parse (and thus Trollop::options) will have a +nil+ value for this key unless the argument is given on the commandline. The argument type is derived automatically from the class of the default value given, so specifying a +:type+ is not necessary if a +:default+ is given. (But see below for an important caveat when +:multi+: is specified too.) If the argument is a flag, and the default is set to +true+, then if it is specified on the the commandline the value will be +false+.
|
92
92
|
## [+:required+] If set to +true+, the argument must be provided on the commandline.
|
93
|
-
## [+:multi+] If set to +true+, allows multiple
|
93
|
+
## [+:multi+] If set to +true+, allows multiple occurrences of the option on the commandline. Otherwise, only a single instance of the option is allowed. (Note that this is different from taking multiple parameters. See below.)
|
94
|
+
##
|
95
|
+
## Note that there are two types of argument multiplicity: an argument
|
96
|
+
## can take multiple values, e.g. "--arg 1 2 3". An argument can also
|
97
|
+
## be allowed to occur multiple times, e.g. "--arg 1 --arg 2".
|
98
|
+
##
|
99
|
+
## Arguments that take multiple values should have a +:type+ parameter
|
100
|
+
## drawn from +MULTI_ARG_TYPES+ (e.g. +:strings+), or a +:default:+
|
101
|
+
## value of an array of the correct type (e.g. [String]). The
|
102
|
+
## value of this argument will be an array of the parameters on the
|
103
|
+
## commandline.
|
104
|
+
##
|
105
|
+
## Arguments that can occur multiple times should be marked with
|
106
|
+
## +:multi+ => +true+. The value of this argument will also be an array.
|
107
|
+
##
|
108
|
+
## These two attributes can be combined (e.g. +:type+ => +:strings+,
|
109
|
+
## +:multi+ => +true+), in which case the value of the argument will be
|
110
|
+
## an array of arrays.
|
111
|
+
##
|
112
|
+
## There's one ambiguous case to be aware of: when +:multi+: is true and a
|
113
|
+
## +:default+ is set to an array (of something), it's ambiguous whether this
|
114
|
+
## is a multi-value argument as well as a multi-occurrence argument.
|
115
|
+
## In thise case, Trollop assumes that it's not a multi-value argument.
|
116
|
+
## If you want a multi-value, multi-occurrence argument with a default
|
117
|
+
## value, you must specify +:type+ as well.
|
118
|
+
|
94
119
|
def opt name, desc="", opts={}
|
95
120
|
raise ArgumentError, "you already have an argument named '#{name}'" if @specs.member? name
|
96
121
|
|
@@ -118,8 +143,19 @@ class Parser
|
|
118
143
|
opts[:type]
|
119
144
|
end
|
120
145
|
|
146
|
+
## for options with :multi => true, an array default doesn't imply
|
147
|
+
## a multi-valued argument. for that you have to specify a :type
|
148
|
+
## as well. (this is how we disambiguate an ambiguous situation;
|
149
|
+
## see the docs for Parser#opt for details.)
|
150
|
+
disambiguated_default =
|
151
|
+
if opts[:multi] && opts[:default].is_a?(Array) && !opts[:type]
|
152
|
+
opts[:default].first
|
153
|
+
else
|
154
|
+
opts[:default]
|
155
|
+
end
|
156
|
+
|
121
157
|
type_from_default =
|
122
|
-
case
|
158
|
+
case disambiguated_default
|
123
159
|
when Integer; :int
|
124
160
|
when Numeric; :float
|
125
161
|
when TrueClass, FalseClass; :flag
|
@@ -144,7 +180,7 @@ class Parser
|
|
144
180
|
|
145
181
|
raise ArgumentError, ":type specification and default type don't match" if opts[:type] && type_from_default && opts[:type] != type_from_default
|
146
182
|
|
147
|
-
opts[:type] =
|
183
|
+
opts[:type] = opts[:type] || type_from_default || :flag
|
148
184
|
|
149
185
|
## fill in :long
|
150
186
|
opts[:long] = opts[:long] ? opts[:long].to_s : name.to_s.gsub("_", "-")
|
@@ -184,6 +220,9 @@ class Parser
|
|
184
220
|
## fill in :default for flags
|
185
221
|
opts[:default] = false if opts[:type] == :flag && opts[:default].nil?
|
186
222
|
|
223
|
+
## autobox :default for :multi (multi-occurrence) arguments
|
224
|
+
opts[:default] = [opts[:default]] if opts[:default] && opts[:multi] && !opts[:default].is_a?(Array)
|
225
|
+
|
187
226
|
## fill in :multi
|
188
227
|
opts[:multi] ||= false
|
189
228
|
|
@@ -417,6 +456,12 @@ class Parser
|
|
417
456
|
# else: multiple options, with multiple parameters
|
418
457
|
end
|
419
458
|
|
459
|
+
## allow openstruct-style accessors
|
460
|
+
class << vals
|
461
|
+
def method_missing(m, *args)
|
462
|
+
self[m] || self[m.to_s]
|
463
|
+
end
|
464
|
+
end
|
420
465
|
vals
|
421
466
|
end
|
422
467
|
|
@@ -509,16 +554,27 @@ class Parser
|
|
509
554
|
|
510
555
|
spec = @specs[opt]
|
511
556
|
stream.printf " %#{leftcol_width}s: ", left[opt]
|
512
|
-
desc = spec[:desc] +
|
557
|
+
desc = spec[:desc] + begin
|
558
|
+
default_s = case spec[:default]
|
559
|
+
when $stdout; "<stdout>"
|
560
|
+
when $stdin; "<stdin>"
|
561
|
+
when $stderr; "<stderr>"
|
562
|
+
when Array
|
563
|
+
spec[:default].join(", ")
|
564
|
+
else
|
565
|
+
spec[:default].to_s
|
566
|
+
end
|
567
|
+
|
513
568
|
if spec[:default]
|
514
569
|
if spec[:desc] =~ /\.$/
|
515
|
-
" (Default: #{
|
570
|
+
" (Default: #{default_s})"
|
516
571
|
else
|
517
|
-
" (default: #{
|
572
|
+
" (default: #{default_s})"
|
518
573
|
end
|
519
574
|
else
|
520
575
|
""
|
521
576
|
end
|
577
|
+
end
|
522
578
|
stream.puts wrap(desc, :width => width - rightcol_start - 1, :prefix => rightcol_start)
|
523
579
|
end
|
524
580
|
end
|
@@ -573,7 +629,19 @@ end
|
|
573
629
|
## (Parser#opt), zero or more calls to +text+ (Parser#text), and
|
574
630
|
## probably a call to +version+ (Parser#version).
|
575
631
|
##
|
576
|
-
##
|
632
|
+
## Example:
|
633
|
+
##
|
634
|
+
## require 'trollop'
|
635
|
+
## opts = Trollop::options do
|
636
|
+
## opt :monkey, "Use monkey mode" # a flag --monkey, defaulting to false
|
637
|
+
## opt :goat, "Use goat mode", :default => true # a flag --goat, defaulting to true
|
638
|
+
## opt :num_limbs, "Number of limbs", :default => 4 # an integer --num-limbs <i>, defaulting to 4
|
639
|
+
## opt :num_thumbs, "Number of thumbs", :type => :int # an integer --num-thumbs <i>, defaulting to nil
|
640
|
+
## end
|
641
|
+
##
|
642
|
+
## p opts # returns a hash: { :monkey => false, :goat => true, :num_limbs => 4, :num_thumbs => nil }
|
643
|
+
##
|
644
|
+
## See more examples at http://trollop.rubyforge.org.
|
577
645
|
def options args = ARGV, *a, &b
|
578
646
|
@p = Parser.new(*a, &b)
|
579
647
|
begin
|
data/test/test_trollop.rb
CHANGED
@@ -884,14 +884,73 @@ EOM
|
|
884
884
|
assert_kind_of File, opts[:arg]
|
885
885
|
assert_equal "/dev/null", opts[:arg].path
|
886
886
|
|
887
|
-
|
888
|
-
|
887
|
+
#TODO: move to mocks
|
888
|
+
#assert_nothing_raised { opts = @p.parse %w(--arg2 http://google.com/) }
|
889
|
+
#assert_kind_of StringIO, opts[:arg2]
|
889
890
|
|
890
891
|
assert_nothing_raised { opts = @p.parse %w(--arg3 stdin) }
|
891
892
|
assert_equal $stdin, opts[:arg3]
|
892
893
|
|
893
894
|
assert_raises(CommandlineError) { opts = @p.parse %w(--arg /fdasfasef/fessafef/asdfasdfa/fesasf) }
|
894
895
|
end
|
896
|
+
|
897
|
+
def test_openstruct_style_access
|
898
|
+
@p.opt "arg1", "desc", :type => :int
|
899
|
+
@p.opt :arg2, "desc", :type => :int
|
900
|
+
|
901
|
+
opts = @p.parse(%w(--arg1 3 --arg2 4))
|
902
|
+
|
903
|
+
assert_nothing_raised { opts.arg1 }
|
904
|
+
assert_nothing_raised { opts.arg2 }
|
905
|
+
assert_equal 3, opts.arg1
|
906
|
+
assert_equal 4, opts.arg2
|
907
|
+
end
|
908
|
+
|
909
|
+
def test_multi_args_autobox_defaults
|
910
|
+
@p.opt :arg1, "desc", :default => "hello", :multi => true
|
911
|
+
@p.opt :arg2, "desc", :default => ["hello"], :multi => true
|
912
|
+
|
913
|
+
opts = @p.parse
|
914
|
+
assert_equal ["hello"], opts[:arg1]
|
915
|
+
assert_equal ["hello"], opts[:arg2]
|
916
|
+
|
917
|
+
opts = @p.parse %w(--arg1 hello)
|
918
|
+
assert_equal ["hello"], opts[:arg1]
|
919
|
+
assert_equal ["hello"], opts[:arg2]
|
920
|
+
|
921
|
+
opts = @p.parse %w(--arg1 hello --arg1 there)
|
922
|
+
assert_equal ["hello", "there"], opts[:arg1]
|
923
|
+
end
|
924
|
+
|
925
|
+
def test_ambigious_multi_plus_array_default_resolved_as_specified_by_documentation
|
926
|
+
@p.opt :arg1, "desc", :default => ["potato"], :multi => true
|
927
|
+
@p.opt :arg2, "desc", :default => ["potato"], :multi => true, :type => :strings
|
928
|
+
@p.opt :arg3, "desc", :default => ["potato"]
|
929
|
+
@p.opt :arg4, "desc", :default => ["potato", "rhubarb"], :short => :none, :multi => true
|
930
|
+
|
931
|
+
## arg1 should be multi-occurring but not multi-valued
|
932
|
+
opts = @p.parse %w(--arg1 one two)
|
933
|
+
assert_equal ["one"], opts[:arg1]
|
934
|
+
assert_equal ["two"], @p.leftovers
|
935
|
+
|
936
|
+
opts = @p.parse %w(--arg1 one --arg1 two)
|
937
|
+
assert_equal ["one", "two"], opts[:arg1]
|
938
|
+
assert_equal [], @p.leftovers
|
939
|
+
|
940
|
+
## arg2 should be multi-valued and multi-occurring
|
941
|
+
opts = @p.parse %w(--arg2 one two)
|
942
|
+
assert_equal [["one", "two"]], opts[:arg2]
|
943
|
+
assert_equal [], @p.leftovers
|
944
|
+
|
945
|
+
## arg3 should be multi-valued but not multi-occurring
|
946
|
+
opts = @p.parse %w(--arg3 one two)
|
947
|
+
assert_equal ["one", "two"], opts[:arg3]
|
948
|
+
assert_equal [], @p.leftovers
|
949
|
+
|
950
|
+
## arg4 should be multi-valued but not multi-occurring
|
951
|
+
opts = @p.parse %w()
|
952
|
+
assert_equal ["potato", "rhubarb"], opts[:arg4]
|
953
|
+
end
|
895
954
|
end
|
896
955
|
|
897
956
|
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:
|
4
|
+
version: 1.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Morgan
|
@@ -9,19 +9,10 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-10-
|
12
|
+
date: 2008-10-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
name: hoe
|
17
|
-
type: :development
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 1.8.0
|
24
|
-
version:
|
14
|
+
dependencies: []
|
15
|
+
|
25
16
|
description: == DESCRIPTION Trollop is a commandline option parser for Ruby that just gets out of your way. One line of code per option is all you need to write. For that, you get a nice automatically-generated help page, robust option parsing, command subcompletion, and sensible defaults for everything you don't specify. * A burning desire to write less code. == INSTALL * gem install trollop == LICENSE Copyright (c) 2008 William Morgan. Trollop is distributed under the same terms as Ruby.
|
26
17
|
email: wmorgan-trollop@masanjin.net
|
27
18
|
executables: []
|