gli 1.6.0 → 2.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +11 -0
- data/.rvmrc +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +201 -0
- data/ObjectModel.graffle +1191 -0
- data/README.rdoc +60 -10
- data/Rakefile +145 -0
- data/bin/gli +12 -30
- data/bin/report_on_rake_results +10 -0
- data/bin/test_all_rubies.sh +6 -0
- data/features/gli_executable.feature +84 -0
- data/features/gli_init.feature +219 -0
- data/features/step_definitions/gli_executable_steps.rb +12 -0
- data/features/step_definitions/gli_init_steps.rb +11 -0
- data/features/step_definitions/todo_steps.rb +69 -0
- data/features/support/env.rb +49 -0
- data/features/todo.feature +182 -0
- data/gli.cheat +95 -0
- data/gli.gemspec +34 -0
- data/lib/gli.rb +11 -571
- data/lib/gli/app.rb +184 -0
- data/lib/gli/app_support.rb +226 -0
- data/lib/gli/command.rb +107 -95
- data/lib/gli/command_line_option.rb +34 -0
- data/lib/gli/command_line_token.rb +13 -9
- data/lib/gli/command_support.rb +200 -0
- data/lib/gli/commands/compound_command.rb +42 -0
- data/lib/gli/commands/help.rb +63 -0
- data/lib/gli/commands/help_modules/command_help_format.rb +134 -0
- data/lib/gli/commands/help_modules/global_help_format.rb +61 -0
- data/lib/gli/commands/help_modules/list_formatter.rb +22 -0
- data/lib/gli/commands/help_modules/options_formatter.rb +50 -0
- data/lib/gli/commands/help_modules/text_wrapper.rb +53 -0
- data/lib/gli/commands/initconfig.rb +67 -0
- data/lib/{support → gli/commands}/scaffold.rb +150 -34
- data/lib/gli/dsl.rb +194 -0
- data/lib/gli/exceptions.rb +13 -4
- data/lib/gli/flag.rb +30 -41
- data/lib/gli/gli_option_parser.rb +98 -0
- data/lib/gli/option_parser_factory.rb +44 -0
- data/lib/gli/options.rb +2 -1
- data/lib/gli/switch.rb +19 -51
- data/lib/gli/terminal.rb +30 -20
- data/lib/gli/version.rb +5 -0
- data/test/apps/README.md +2 -0
- data/test/apps/todo/Gemfile +2 -0
- data/test/apps/todo/README.rdoc +6 -0
- data/test/apps/todo/Rakefile +23 -0
- data/test/apps/todo/bin/todo +52 -0
- data/test/apps/todo/lib/todo/commands/create.rb +22 -0
- data/test/apps/todo/lib/todo/commands/list.rb +53 -0
- data/test/apps/todo/lib/todo/commands/ls.rb +47 -0
- data/test/apps/todo/lib/todo/version.rb +3 -0
- data/test/apps/todo/test/tc_nothing.rb +14 -0
- data/test/apps/todo/todo.gemspec +23 -0
- data/test/apps/todo/todo.rdoc +5 -0
- data/test/config.yaml +10 -0
- data/test/fake_std_out.rb +30 -0
- data/test/gli.reek +122 -0
- data/test/init_simplecov.rb +8 -0
- data/test/option_test_helper.rb +13 -0
- data/test/roodi.yaml +18 -0
- data/test/tc_command.rb +260 -0
- data/test/tc_compount_command.rb +22 -0
- data/test/tc_flag.rb +56 -0
- data/test/tc_gli.rb +611 -0
- data/test/tc_help.rb +223 -0
- data/test/tc_options.rb +31 -0
- data/test/tc_subcommands.rb +162 -0
- data/test/tc_switch.rb +57 -0
- data/test/tc_terminal.rb +97 -0
- data/test/test_helper.rb +13 -0
- metadata +318 -49
- data/lib/gli_version.rb +0 -3
- data/lib/support/help.rb +0 -179
- data/lib/support/initconfig.rb +0 -34
- data/lib/support/rdoc.rb +0 -119
data/lib/gli/dsl.rb
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
module GLI
|
2
|
+
# The primary DSL for GLI. This represents the methods shared between your top-level app and
|
3
|
+
# the commands. See GLI::Command for additional methods that apply only to command objects.
|
4
|
+
module DSL
|
5
|
+
# Describe the next switch, flag, or command. This should be a
|
6
|
+
# short, one-line description
|
7
|
+
#
|
8
|
+
# +description+:: A String of the short descripiton of the switch, flag, or command following
|
9
|
+
def desc(description); @next_desc = description; end
|
10
|
+
alias :d :desc
|
11
|
+
|
12
|
+
# Provide a longer, more detailed description. This
|
13
|
+
# will be reformatted and wrapped to fit in the terminal's columns
|
14
|
+
#
|
15
|
+
# +long_desc+:: A String that is s longer description of the switch, flag, or command following.
|
16
|
+
def long_desc(long_desc); @next_long_desc = long_desc; end
|
17
|
+
|
18
|
+
# Describe the argument name of the next flag. It's important to keep
|
19
|
+
# this VERY short and, ideally, without any spaces (see Example).
|
20
|
+
#
|
21
|
+
# +name+:: A String that *briefly* describes the argument given to the following command or flag.
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
# desc 'Set the filename'
|
25
|
+
# arg_name 'file_name'
|
26
|
+
# flag [:f,:filename]
|
27
|
+
#
|
28
|
+
# Produces:
|
29
|
+
# -f, --filename=file_name Set the filename
|
30
|
+
def arg_name(name); @next_arg_name = name; end
|
31
|
+
|
32
|
+
# set the default value of the next flag
|
33
|
+
#
|
34
|
+
# +val+:: A String reprensenting the default value to be used for the following flag if the user doesn't specify one
|
35
|
+
# and, when using a config file, the config also doesn't specify one
|
36
|
+
def default_value(val); @next_default_value = val; end
|
37
|
+
|
38
|
+
# Create a flag, which is a switch that takes an argument
|
39
|
+
#
|
40
|
+
# +names+:: a String or Symbol, or an Array of String or Symbol that represent all the different names
|
41
|
+
# and aliases for this flag. The last element can be a hash of options:
|
42
|
+
# +:desc+:: the description, instead of using #desc
|
43
|
+
# +:long_desc+:: the long_description, instead of using #long_desc
|
44
|
+
# +:default_value+:: the default value, instead of using #default_value
|
45
|
+
# +:arg_name+:: the arg name, instead of using #arg_name
|
46
|
+
# +:must_match+:: A regexp that the flag's value must match
|
47
|
+
# +:type+:: A Class (or object you passed to GLI::App#accept) to trigger type coversion
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
#
|
51
|
+
# desc 'Set the filename'
|
52
|
+
# flag [:f,:filename,'file-name']
|
53
|
+
#
|
54
|
+
# flag :ipaddress, :desc => "IP Address", :must_match => /\d+\.\d+\.\d+\.\d+/
|
55
|
+
#
|
56
|
+
# flag :names, :desc => "list of names", :type => Array
|
57
|
+
#
|
58
|
+
# Produces:
|
59
|
+
#
|
60
|
+
# -f, --filename, --file-name=arg Set the filename
|
61
|
+
def flag(*names)
|
62
|
+
options = extract_options(names)
|
63
|
+
names = [names].flatten
|
64
|
+
|
65
|
+
verify_unused(names)
|
66
|
+
flag = Flag.new(names,options)
|
67
|
+
flags[flag.name] = flag
|
68
|
+
|
69
|
+
clear_nexts
|
70
|
+
flag
|
71
|
+
end
|
72
|
+
alias :f :flag
|
73
|
+
|
74
|
+
# Create a switch, which is a command line flag that takes no arguments (thus, it _switches_ something on)
|
75
|
+
#
|
76
|
+
# +names+:: a String or Symbol, or an Array of String or Symbol that represent all the different names
|
77
|
+
# and aliases for this switch. The last element can be a hash of options:
|
78
|
+
# +:desc+:: the description, instead of using #desc
|
79
|
+
# +:long_desc+:: the long_description, instead of using #long_desc
|
80
|
+
# +:negatable+:: if true, this switch will get a negatable form (e.g. <tt>--[no-]switch</tt>, false it will not. Default is true
|
81
|
+
def switch(*names)
|
82
|
+
options = extract_options(names)
|
83
|
+
names = [names].flatten
|
84
|
+
|
85
|
+
verify_unused(names)
|
86
|
+
switch = Switch.new(names,options)
|
87
|
+
switches[switch.name] = switch
|
88
|
+
|
89
|
+
clear_nexts
|
90
|
+
switch
|
91
|
+
end
|
92
|
+
alias :s :switch
|
93
|
+
|
94
|
+
def clear_nexts # :nodoc:
|
95
|
+
@next_desc = nil
|
96
|
+
@next_arg_name = nil
|
97
|
+
@next_default_value = nil
|
98
|
+
@next_long_desc = nil
|
99
|
+
end
|
100
|
+
|
101
|
+
# Define a new command. This can be done in a few ways, but the most common method is
|
102
|
+
# to pass a symbol (or Array of symbols) representing the command name (or names) and a block.
|
103
|
+
# The block will be given an instance of the Command that was created.
|
104
|
+
# You then may call methods on this object to define aspects of that Command.
|
105
|
+
#
|
106
|
+
# Alternatively, you can call this with a one element Hash, where the key is the symbol representing the name
|
107
|
+
# of the command, and the value being an Array of symbols representing the commands to call in order, as a
|
108
|
+
# chained or compound command. Note that these commands must exist already, and that only those command-specific
|
109
|
+
# options defined in *this* command will be parsed and passed to the chained commands. This might not be what you expect
|
110
|
+
#
|
111
|
+
# +names+:: a String or Symbol, or an Array of String or Symbol that represent all the different names and aliases
|
112
|
+
# for this command *or* a Hash, as described above.
|
113
|
+
#
|
114
|
+
# ==Examples
|
115
|
+
#
|
116
|
+
# # Make a command named list
|
117
|
+
# command :list do |c|
|
118
|
+
# c.action do |global_options,options,args|
|
119
|
+
# # your command code
|
120
|
+
# end
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# # Make a command named list, callable by ls as well
|
124
|
+
# command [:list,:ls] do |c|
|
125
|
+
# c.action do |global_options,options,args|
|
126
|
+
# # your command code
|
127
|
+
# end
|
128
|
+
# end
|
129
|
+
#
|
130
|
+
# # Make a command named all, that calls list and list_contexts
|
131
|
+
# command :all => [ :list, :list_contexts ]
|
132
|
+
#
|
133
|
+
# # Make a command named all, aliased as :a:, that calls list and list_contexts
|
134
|
+
# command [:all,:a] => [ :list, :list_contexts ]
|
135
|
+
#
|
136
|
+
def command(*names)
|
137
|
+
command_options = {
|
138
|
+
:description => @next_desc,
|
139
|
+
:arguments_name => @next_arg_name,
|
140
|
+
:long_desc => @next_long_desc,
|
141
|
+
:skips_pre => @skips_pre,
|
142
|
+
:skips_post => @skips_post,
|
143
|
+
}
|
144
|
+
if names.first.kind_of? Hash
|
145
|
+
command = GLI::Commands::CompoundCommand.new(self,
|
146
|
+
names.first,
|
147
|
+
command_options)
|
148
|
+
command.parent = self
|
149
|
+
commands[command.name] = command
|
150
|
+
else
|
151
|
+
command = Command.new(command_options.merge(:names => [names].flatten))
|
152
|
+
command.parent = self
|
153
|
+
commands[command.name] = command
|
154
|
+
yield command
|
155
|
+
end
|
156
|
+
clear_nexts
|
157
|
+
end
|
158
|
+
alias :c :command
|
159
|
+
|
160
|
+
private
|
161
|
+
# Checks that the names passed in have not been used in another flag or option
|
162
|
+
def verify_unused(names) # :nodoc:
|
163
|
+
names.each do |name|
|
164
|
+
verify_unused_in_option(name,flags,"flag")
|
165
|
+
verify_unused_in_option(name,switches,"switch")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def verify_unused_in_option(name,option_like,type) # :nodoc:
|
170
|
+
return if name.to_s == 'help'
|
171
|
+
raise ArgumentError.new("#{name} has already been specified as a #{type} #{context_description}") if option_like[name]
|
172
|
+
option_like.each do |one_option_name,one_option|
|
173
|
+
if one_option.aliases
|
174
|
+
if one_option.aliases.include? name
|
175
|
+
raise ArgumentError.new("#{name} has already been specified as an alias of #{type} #{one_option_name} #{context_description}")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Extract the options hash out of the argument to flag/switch and
|
182
|
+
# set the values if using classic style
|
183
|
+
def extract_options(names)
|
184
|
+
options = {}
|
185
|
+
options = names.pop if names.last.kind_of? Hash
|
186
|
+
options = { :desc => @next_desc,
|
187
|
+
:long_desc => @next_long_desc,
|
188
|
+
:default_value => @next_default_value,
|
189
|
+
:arg_name => @next_arg_name}.merge(options)
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
end
|
194
|
+
end
|
data/lib/gli/exceptions.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
module GLI
|
2
|
+
# Mixed into all exceptions that GLI handles; you can use this to catch
|
3
|
+
# anything that came from GLI intentionally. You can also mix this into non-GLI
|
4
|
+
# exceptions to get GLI's exit behavior.
|
5
|
+
module StandardException
|
6
|
+
def exit_code; 1; end
|
7
|
+
end
|
2
8
|
# Indicates that the command line invocation was bad
|
3
|
-
class BadCommandLine <
|
4
|
-
|
9
|
+
class BadCommandLine < StandardError
|
10
|
+
include StandardException
|
11
|
+
def exit_code; 64; end
|
5
12
|
end
|
6
13
|
|
7
14
|
# Indicates the bad command line was an unknown command
|
@@ -14,6 +21,7 @@ module GLI
|
|
14
21
|
|
15
22
|
# Indicates the bad command line was an unknown command argument
|
16
23
|
class UnknownCommandArgument < BadCommandLine
|
24
|
+
# The command for which the argument was unknown
|
17
25
|
attr_reader :command
|
18
26
|
# +message+:: the error message to show the user
|
19
27
|
# +command+:: the command we were using to parse command-specific options
|
@@ -24,14 +32,15 @@ module GLI
|
|
24
32
|
end
|
25
33
|
|
26
34
|
# Raise this if you want to use an exit status that isn't the default
|
27
|
-
# provided by GLI. Note that GLI#exit_now! might be a bit more to your liking.
|
35
|
+
# provided by GLI. Note that GLI::App#exit_now! might be a bit more to your liking.
|
28
36
|
#
|
29
37
|
# Example:
|
30
38
|
#
|
31
39
|
# raise CustomExit.new("Not connected to DB",-5) unless connected?
|
32
40
|
# raise CustomExit.new("Bad SQL",-6) unless valid_sql?(args[0])
|
33
41
|
#
|
34
|
-
class CustomExit <
|
42
|
+
class CustomExit < StandardError
|
43
|
+
include StandardException
|
35
44
|
attr_reader :exit_code #:nodoc:
|
36
45
|
# Create a custom exit exception
|
37
46
|
#
|
data/lib/gli/flag.rb
CHANGED
@@ -1,52 +1,41 @@
|
|
1
|
-
require 'gli/
|
2
|
-
require 'gli/switch.rb'
|
1
|
+
require 'gli/command_line_option.rb'
|
3
2
|
|
4
3
|
module GLI
|
5
4
|
# Defines a flag, which is to say a switch that takes an argument
|
6
|
-
class Flag <
|
5
|
+
class Flag < CommandLineOption # :nodoc:
|
7
6
|
|
8
|
-
|
7
|
+
# Regexp that is used to see if the flag's argument matches
|
8
|
+
attr_reader :must_match
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
@argument_name = argument_name || "arg"
|
13
|
-
@default_value = default
|
14
|
-
end
|
10
|
+
# Type to which we want to cast the values
|
11
|
+
attr_reader :type
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
return @default_value
|
13
|
+
# Name of the argument that user configured
|
14
|
+
attr_reader :argument_name
|
15
|
+
|
16
|
+
# Creates a new option
|
17
|
+
#
|
18
|
+
# names - Array of symbols or strings representing the names of this switch
|
19
|
+
# options - hash of options:
|
20
|
+
# :desc - the short description
|
21
|
+
# :long_desc - the long description
|
22
|
+
# :default_value - the default value of this option
|
23
|
+
# :arg_name - the name of the flag's argument, default is "arg"
|
24
|
+
# :must_match - a regexp that the flag's value must match
|
25
|
+
# :type - a class to convert the value to
|
26
|
+
def initialize(names,options)
|
27
|
+
super(names,options)
|
28
|
+
@argument_name = options[:arg_name] || "arg"
|
29
|
+
@default_value = options[:default_value]
|
30
|
+
@must_match = options[:must_match]
|
31
|
+
@type = options[:type]
|
36
32
|
end
|
37
33
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
@names.keys.each() do |name|
|
45
|
-
match_string = "^#{name}=(.*)$"
|
46
|
-
match_data = arg.match(match_string)
|
47
|
-
return [true,name,$1] if match_data;
|
48
|
-
end
|
49
|
-
[false,nil,nil]
|
34
|
+
def arguments_for_option_parser
|
35
|
+
args = all_forms_a.map { |name| "#{name} VAL" }
|
36
|
+
args << @must_match if @must_match
|
37
|
+
args << @type if @type
|
38
|
+
args
|
50
39
|
end
|
51
40
|
|
52
41
|
# Returns a string of all possible forms
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module GLI
|
2
|
+
# Parses the command-line options using an actual +OptionParser+
|
3
|
+
class GLIOptionParser
|
4
|
+
def initialize(commands,flags,switches,accepts)
|
5
|
+
@commands = commands
|
6
|
+
@flags = flags
|
7
|
+
@switches = switches
|
8
|
+
@accepts = accepts
|
9
|
+
end
|
10
|
+
|
11
|
+
# Given the command-line argument array, returns and array of size 4:
|
12
|
+
#
|
13
|
+
# 0:: global options
|
14
|
+
# 1:: command, as a Command
|
15
|
+
# 2:: command-specific options
|
16
|
+
# 3:: unparsed arguments
|
17
|
+
def parse_options(args) # :nodoc:
|
18
|
+
args_clone = args.clone
|
19
|
+
global_options = {}
|
20
|
+
command = nil
|
21
|
+
command_options = {}
|
22
|
+
remaining_args = nil
|
23
|
+
|
24
|
+
global_options,command_name,args = parse_global_options(OptionParserFactory.new(@flags,@switches,@accepts), args)
|
25
|
+
@flags.each do |name,flag|
|
26
|
+
global_options[name] = flag.default_value unless global_options[name]
|
27
|
+
end
|
28
|
+
|
29
|
+
command_name ||= @default_command || :help
|
30
|
+
command = find_command(command_name)
|
31
|
+
if Array(command).empty?
|
32
|
+
raise UnknownCommand.new("Unknown command '#{command_name}'")
|
33
|
+
elsif command.kind_of? Array
|
34
|
+
raise UnknownCommand.new("Ambiguous command '#{command_name}'. It matches #{command.sort.join(',')}")
|
35
|
+
end
|
36
|
+
|
37
|
+
command_options,args = parse_command_options(OptionParserFactory.new(command.flags,command.switches,@accepts),
|
38
|
+
command,
|
39
|
+
args)
|
40
|
+
|
41
|
+
command.flags.each do |name,flag|
|
42
|
+
command_options[name] = flag.default_value unless command_options[name]
|
43
|
+
end
|
44
|
+
command.switches.each do |name,switch|
|
45
|
+
command_options[name] = switch.default_value unless command_options[name]
|
46
|
+
end
|
47
|
+
|
48
|
+
[global_options,command,command_options,args]
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def parse_command_options(option_parser_factory,command,args)
|
54
|
+
option_parser,command_options = option_parser_factory.option_parser
|
55
|
+
option_parser.parse!(args)
|
56
|
+
[command_options,args]
|
57
|
+
rescue OptionParser::InvalidOption => ex
|
58
|
+
raise UnknownCommandArgument.new("Unknown option #{ex.args.join(' ')}",command)
|
59
|
+
rescue OptionParser::InvalidArgument => ex
|
60
|
+
raise UnknownCommandArgument.new("#{ex.reason}: #{ex.args.join(' ')}",command)
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_global_options(option_parser_factory,args,&error_handler)
|
64
|
+
if error_handler.nil?
|
65
|
+
error_handler = lambda { |message|
|
66
|
+
raise UnknownGlobalArgument.new(message)
|
67
|
+
}
|
68
|
+
end
|
69
|
+
option_parser,global_options = option_parser_factory.option_parser
|
70
|
+
command = nil
|
71
|
+
option_parser.order!(args) do |non_option|
|
72
|
+
command = non_option
|
73
|
+
break
|
74
|
+
end
|
75
|
+
[global_options,command,args]
|
76
|
+
rescue OptionParser::InvalidOption => ex
|
77
|
+
error_handler.call("Unknown option #{ex.args.join(' ')}")
|
78
|
+
rescue OptionParser::InvalidArgument => ex
|
79
|
+
error_handler.call("#{ex.reason}: #{ex.args.join(' ')}")
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_command(name) # :nodoc:
|
83
|
+
names_to_commands = {}
|
84
|
+
@commands.each do |command_name,command|
|
85
|
+
names_to_commands[command_name.to_s] = command
|
86
|
+
Array(command.aliases).each do |command_alias|
|
87
|
+
names_to_commands[command_alias.to_s] = command
|
88
|
+
end
|
89
|
+
end
|
90
|
+
name = name.to_s
|
91
|
+
return names_to_commands[name] if names_to_commands[name]
|
92
|
+
# Now try to match on partial names
|
93
|
+
partial_matches = names_to_commands.keys.select { |command_name| command_name =~ /^#{name}/ }
|
94
|
+
return names_to_commands[partial_matches[0]] if partial_matches.size == 1
|
95
|
+
partial_matches
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module GLI
|
2
|
+
# Factory for creating an OptionParser based on app configuration and DSL calls
|
3
|
+
class OptionParserFactory
|
4
|
+
# Create an OptionParserFactory for the given
|
5
|
+
# flags, switches, and accepts
|
6
|
+
def initialize(flags,switches,accepts)
|
7
|
+
@flags = flags
|
8
|
+
@switches = switches
|
9
|
+
@accepts = accepts
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return an option parser to parse the given flags, switches and accepts
|
13
|
+
def option_parser
|
14
|
+
options = {}
|
15
|
+
option_parser = OptionParser.new do |opts|
|
16
|
+
self.class.setup_accepts(opts,@accepts)
|
17
|
+
self.class.setup_options(opts,@switches,options)
|
18
|
+
self.class.setup_options(opts,@flags,options)
|
19
|
+
end
|
20
|
+
[option_parser,options]
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def self.setup_accepts(opts,accepts)
|
26
|
+
accepts.each do |object,block|
|
27
|
+
opts.accept(object) do |arg_as_string|
|
28
|
+
block.call(arg_as_string)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.setup_options(opts,tokens,options)
|
34
|
+
tokens.each do |ignore,token|
|
35
|
+
opts.on(*token.arguments_for_option_parser) do |arg|
|
36
|
+
[token.name,token.aliases].flatten.compact.each do |name|
|
37
|
+
options[name] = arg
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|