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
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'gli/command_line_token.rb'
|
2
|
+
|
3
|
+
module GLI
|
4
|
+
# An option, not a command or argument, on the command line
|
5
|
+
class CommandLineOption < CommandLineToken #:nodoc:
|
6
|
+
|
7
|
+
attr_accessor :default_value
|
8
|
+
# Command to which this option "belongs", nil if it's a global option
|
9
|
+
attr_accessor :associated_command
|
10
|
+
|
11
|
+
# Creates a new option
|
12
|
+
#
|
13
|
+
# names - Array of symbols or strings representing the names of this switch
|
14
|
+
# options - hash of options:
|
15
|
+
# :desc - the short description
|
16
|
+
# :long_desc - the long description
|
17
|
+
# :default_value - the default value of this option
|
18
|
+
def initialize(names,options = {})
|
19
|
+
super(names,options[:desc],options[:long_desc])
|
20
|
+
@default_value = options[:default_value]
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.name_as_string(name,negatable=true)
|
24
|
+
string = name.to_s
|
25
|
+
if string.length == 1
|
26
|
+
"-#{string}"
|
27
|
+
elsif negatable
|
28
|
+
"--[no-]#{string}"
|
29
|
+
else
|
30
|
+
"--#{string}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -2,12 +2,12 @@ module GLI
|
|
2
2
|
# Abstract base class for a logical element of a command line, mostly so that subclasses can have similar
|
3
3
|
# initialization and interface
|
4
4
|
class CommandLineToken
|
5
|
-
attr_reader :name #:
|
6
|
-
attr_reader :aliases #:
|
7
|
-
attr_reader :description #:
|
8
|
-
attr_reader :long_description #:
|
5
|
+
attr_reader :name #:nodoc:
|
6
|
+
attr_reader :aliases #:nodoc:
|
7
|
+
attr_reader :description #:nodoc:
|
8
|
+
attr_reader :long_description #:nodoc:
|
9
9
|
|
10
|
-
def initialize(names,description,long_description=nil) #:
|
10
|
+
def initialize(names,description,long_description=nil) #:nodoc:
|
11
11
|
@description = description
|
12
12
|
@long_description = long_description
|
13
13
|
@name,@aliases,@names = parse_names(names)
|
@@ -17,7 +17,7 @@ module GLI
|
|
17
17
|
all_forms
|
18
18
|
end
|
19
19
|
|
20
|
-
# Sort based on name
|
20
|
+
# Sort based on primary name
|
21
21
|
def <=>(other)
|
22
22
|
self.name.to_s <=> other.name.to_s
|
23
23
|
end
|
@@ -37,7 +37,7 @@ module GLI
|
|
37
37
|
def parse_names(names)
|
38
38
|
# Allow strings; convert to symbols
|
39
39
|
names = [names].flatten.map { |name| name.to_sym }
|
40
|
-
names_hash =
|
40
|
+
names_hash = {}
|
41
41
|
names.each do |name|
|
42
42
|
raise ArgumentError.new("#{name} has spaces; they are not allowed") if name.to_s =~ /\s/
|
43
43
|
names_hash[self.class.name_as_string(name)] = true
|
@@ -47,10 +47,14 @@ module GLI
|
|
47
47
|
[name,aliases,names_hash]
|
48
48
|
end
|
49
49
|
|
50
|
+
def negatable?
|
51
|
+
false;
|
52
|
+
end
|
53
|
+
|
50
54
|
def all_forms_a
|
51
|
-
forms = [self.class.name_as_string(name)]
|
55
|
+
forms = [self.class.name_as_string(name,negatable?)]
|
52
56
|
if aliases
|
53
|
-
forms |= aliases.
|
57
|
+
forms |= aliases.map { |one_alias| self.class.name_as_string(one_alias,negatable?) }.sort { |one,two| one.length <=> two.length }
|
54
58
|
end
|
55
59
|
forms
|
56
60
|
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
module GLI
|
2
|
+
# Things unrelated to the true public interface of Command that are needed for bookkeeping
|
3
|
+
# and help support. Generally, you shouldn't be calling these methods; they are technically public
|
4
|
+
# but are essentially part of GLI's internal implementation and subject to change
|
5
|
+
module CommandSupport
|
6
|
+
# The parent of this command, either the GLI app, or another command
|
7
|
+
attr_accessor :parent
|
8
|
+
|
9
|
+
def context_description
|
10
|
+
"in the command #{name}"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return true to avoid including this command in your help strings
|
14
|
+
def nodoc
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return the arguments description
|
19
|
+
def arguments_description
|
20
|
+
@arguments_description
|
21
|
+
end
|
22
|
+
|
23
|
+
# If true, this command doesn't want the pre block run before it executes
|
24
|
+
def skips_pre
|
25
|
+
@skips_pre
|
26
|
+
end
|
27
|
+
|
28
|
+
# If true, this command doesn't want the post block run before it executes
|
29
|
+
def skips_post
|
30
|
+
@skips_post
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return the Array of the command's names
|
34
|
+
def names
|
35
|
+
all_forms
|
36
|
+
end
|
37
|
+
|
38
|
+
def flag(*names)
|
39
|
+
new_flag = if parent.kind_of? Command
|
40
|
+
parent.flag(*names)
|
41
|
+
else
|
42
|
+
super(*names)
|
43
|
+
end
|
44
|
+
new_flag.associated_command = self
|
45
|
+
new_flag
|
46
|
+
end
|
47
|
+
|
48
|
+
def switch(*names)
|
49
|
+
new_switch = if parent.kind_of? Command
|
50
|
+
parent.switch(*names)
|
51
|
+
else
|
52
|
+
super(*names)
|
53
|
+
end
|
54
|
+
new_switch.associated_command = self
|
55
|
+
new_switch
|
56
|
+
end
|
57
|
+
|
58
|
+
def desc(d)
|
59
|
+
if parent.kind_of? Command
|
60
|
+
parent.desc(d)
|
61
|
+
else
|
62
|
+
super(d)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def long_desc(d)
|
67
|
+
if parent.kind_of? Command
|
68
|
+
parent.long_desc(d)
|
69
|
+
else
|
70
|
+
super(d)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def arg_name(d)
|
75
|
+
if parent.kind_of? Command
|
76
|
+
parent.arg_name(d)
|
77
|
+
else
|
78
|
+
super(d)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def default_value(d)
|
83
|
+
if parent.kind_of? Command
|
84
|
+
parent.default_value(d)
|
85
|
+
else
|
86
|
+
super(d)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Get the usage string
|
91
|
+
# CR: This should probably not be here
|
92
|
+
def usage
|
93
|
+
usage = name.to_s
|
94
|
+
usage += ' [command options]' if !flags.empty? || !switches.empty?
|
95
|
+
usage += ' ' + @arguments_description if @arguments_description
|
96
|
+
usage
|
97
|
+
end
|
98
|
+
|
99
|
+
# Return the flags as a Hash
|
100
|
+
def flags
|
101
|
+
@flags ||= {}
|
102
|
+
end
|
103
|
+
# Return the switches as a Hash
|
104
|
+
def switches
|
105
|
+
@switches ||= {}
|
106
|
+
end
|
107
|
+
|
108
|
+
def commands # :nodoc:
|
109
|
+
@commands ||= {}
|
110
|
+
end
|
111
|
+
|
112
|
+
def default_description
|
113
|
+
@default_desc
|
114
|
+
end
|
115
|
+
|
116
|
+
# Executes the command
|
117
|
+
def execute(global_options,options,arguments)
|
118
|
+
subcommand,arguments = find_subcommand(arguments)
|
119
|
+
if subcommand
|
120
|
+
subcommand.execute(global_options,options,arguments)
|
121
|
+
else
|
122
|
+
get_action(arguments).call(global_options,options,arguments)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def topmost_ancestor
|
127
|
+
some_command = self
|
128
|
+
top = some_command
|
129
|
+
while some_command.kind_of? self.class
|
130
|
+
top = some_command
|
131
|
+
some_command = some_command.parent
|
132
|
+
end
|
133
|
+
top
|
134
|
+
end
|
135
|
+
|
136
|
+
def has_action?
|
137
|
+
!!@action
|
138
|
+
end
|
139
|
+
|
140
|
+
def get_default_command
|
141
|
+
@default_command
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def get_action(arguments)
|
147
|
+
if @action
|
148
|
+
@action
|
149
|
+
else
|
150
|
+
generate_error_action(arguments)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def generate_error_action(arguments)
|
155
|
+
lambda { |global_options,options,arguments|
|
156
|
+
if am_subcommand?
|
157
|
+
if arguments.size > 0
|
158
|
+
raise UnknownCommand,"Unknown command '#{arguments[0]}'"
|
159
|
+
else
|
160
|
+
raise BadCommandLine,"Command '#{name}' requires a subcommand"
|
161
|
+
end
|
162
|
+
elsif have_subcommands?
|
163
|
+
raise BadCommandLine,"Command '#{name}' requires a subcommand"
|
164
|
+
else
|
165
|
+
raise "Command '#{name}' has no action block"
|
166
|
+
end
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
def am_subcommand?
|
171
|
+
parent.kind_of?(Command)
|
172
|
+
end
|
173
|
+
|
174
|
+
def have_subcommands?
|
175
|
+
!self.commands.empty?
|
176
|
+
end
|
177
|
+
|
178
|
+
def find_subcommand(arguments)
|
179
|
+
subcommand = find_explicit_subcommand(arguments)
|
180
|
+
if subcommand
|
181
|
+
[subcommand,arguments[1..-1]]
|
182
|
+
else
|
183
|
+
if !@default_command.nil?
|
184
|
+
[find_explicit_subcommand([@default_command.to_s]),arguments]
|
185
|
+
else
|
186
|
+
[false,arguments]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def find_explicit_subcommand(arguments)
|
192
|
+
arguments = Array(arguments)
|
193
|
+
return false if arguments.empty?
|
194
|
+
subcommand_name = arguments.first
|
195
|
+
self.commands.values.find { |command|
|
196
|
+
[command.name,Array(command.aliases)].flatten.map(&:to_s).any? { |name| name == subcommand_name }
|
197
|
+
}
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module GLI
|
2
|
+
module Commands
|
3
|
+
# A command that calls other commands in order
|
4
|
+
class CompoundCommand < Command
|
5
|
+
# base:: object that respondes to +commands+
|
6
|
+
# configuration:: Array of arrays: index 0 is the array of names of this command and index 1
|
7
|
+
# is the names of the compound commands.
|
8
|
+
def initialize(base,configuration,options={})
|
9
|
+
name = configuration.keys.first
|
10
|
+
super(options.merge(:names => [name]))
|
11
|
+
|
12
|
+
command_names = configuration[name]
|
13
|
+
|
14
|
+
check_for_unknown_commands!(base,command_names)
|
15
|
+
|
16
|
+
@commands = command_names.map { |name| self.class.find_command(base,name) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute(global_options,options,arguments) #:nodoc:
|
20
|
+
@commands.each do |command|
|
21
|
+
command.execute(global_options,options,arguments)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def check_for_unknown_commands!(base,command_names)
|
28
|
+
known_commands = base.commands.keys.map(&:to_s)
|
29
|
+
unknown_commands = command_names.map(&:to_s) - known_commands
|
30
|
+
|
31
|
+
unless unknown_commands.empty?
|
32
|
+
raise "Unknown commands #{unknown_commands.join(',')}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.find_command(base,name)
|
37
|
+
base.commands.values.find { |command| command.name == name }
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'gli/command'
|
3
|
+
require 'gli/terminal'
|
4
|
+
require 'gli/commands/help_modules/list_formatter'
|
5
|
+
require 'gli/commands/help_modules/text_wrapper'
|
6
|
+
require 'gli/commands/help_modules/options_formatter'
|
7
|
+
require 'gli/commands/help_modules/global_help_format'
|
8
|
+
require 'gli/commands/help_modules/command_help_format'
|
9
|
+
|
10
|
+
module GLI
|
11
|
+
module Commands
|
12
|
+
# The help command used for the two-level interactive help system
|
13
|
+
class Help < Command
|
14
|
+
def initialize(app,output=$stdout,error=$stderr)
|
15
|
+
super(:names => :help,
|
16
|
+
:description => 'Shows a list of commands or help for one command',
|
17
|
+
:arguments_name => 'command',
|
18
|
+
:long_desc => 'Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function',
|
19
|
+
:skips_pre => true,
|
20
|
+
:skips_post => true)
|
21
|
+
@app = app
|
22
|
+
action do |global_options,options,arguments|
|
23
|
+
show_help(global_options,options,arguments,output,error)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def show_help(global_options,options,arguments,out,error)
|
30
|
+
if arguments.empty?
|
31
|
+
out.puts HelpModules::GlobalHelpFormat.new(@app).format
|
32
|
+
else
|
33
|
+
name = arguments.shift
|
34
|
+
command = find_command(name,@app)
|
35
|
+
return if unknown_command(command,name,error)
|
36
|
+
while !arguments.empty?
|
37
|
+
name = arguments.shift
|
38
|
+
command = find_command(name,command)
|
39
|
+
return if unknown_command(command,name,error)
|
40
|
+
end
|
41
|
+
out.puts HelpModules::CommandHelpFormat.new(command,@app,File.basename($0).to_s).format
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def unknown_command(command,name,error)
|
46
|
+
if command.nil?
|
47
|
+
error.puts "error: Unknown command '#{name}'. Use 'gli help' for a list of commands."
|
48
|
+
true
|
49
|
+
else
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def find_command(command_name,base)
|
55
|
+
base.commands.values.select { |command|
|
56
|
+
if [command.name,Array(command.aliases)].flatten.map(&:to_s).any? { |_| _ == command_name }
|
57
|
+
command
|
58
|
+
end
|
59
|
+
}.first
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module GLI
|
4
|
+
module Commands
|
5
|
+
module HelpModules
|
6
|
+
class CommandHelpFormat
|
7
|
+
def initialize(command,app,basic_invocation)
|
8
|
+
@basic_invocation = basic_invocation
|
9
|
+
@app = app
|
10
|
+
@command = command
|
11
|
+
end
|
12
|
+
|
13
|
+
def format
|
14
|
+
command_wrapper = TextWrapper.new(Terminal.instance.size[0],4 + @command.name.to_s.size + 3)
|
15
|
+
wrapper = TextWrapper.new(Terminal.instance.size[0],4)
|
16
|
+
flags_and_switches = Hash[@command.topmost_ancestor.flags.merge(@command.topmost_ancestor.switches).select { |_,option| option.associated_command == @command }]
|
17
|
+
options_description = OptionsFormatter.new(flags_and_switches).format
|
18
|
+
commands_description = format_subcommands(@command)
|
19
|
+
|
20
|
+
synopses = []
|
21
|
+
one_line_usage = basic_usage(flags_and_switches)
|
22
|
+
one_line_usage << @command.arguments_description
|
23
|
+
if @command.commands.empty?
|
24
|
+
synopses << one_line_usage
|
25
|
+
else
|
26
|
+
synopses = sorted_synopses(flags_and_switches)
|
27
|
+
if @command.has_action?
|
28
|
+
synopses.unshift(one_line_usage)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
COMMAND_HELP.result(binding)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
COMMAND_HELP = ERB.new(%q(NAME
|
38
|
+
<%= @command.name %> - <%= command_wrapper.wrap(@command.description) %>
|
39
|
+
|
40
|
+
SYNOPSIS
|
41
|
+
<% synopses.each do |s| %>
|
42
|
+
<%= s %>
|
43
|
+
<% end %>
|
44
|
+
<% unless @command.long_description.nil? %>
|
45
|
+
|
46
|
+
DESCRIPTION
|
47
|
+
<%= wrapper.wrap(@command.long_description) %>
|
48
|
+
<% end %>
|
49
|
+
<% if options_description.strip.length != 0 %>
|
50
|
+
|
51
|
+
COMMAND OPTIONS
|
52
|
+
<%= options_description %>
|
53
|
+
<% end %>
|
54
|
+
<% unless @command.commands.empty? %>
|
55
|
+
|
56
|
+
COMMANDS
|
57
|
+
<%= commands_description %>
|
58
|
+
<% end %>),nil,'<>')
|
59
|
+
|
60
|
+
def command_with_subcommand_usage(sub,flags_and_switches,is_default_command)
|
61
|
+
usage = basic_usage(flags_and_switches)
|
62
|
+
sub_options = @command.flags.merge(@command.switches).select { |_,o| o.associated_command == sub }
|
63
|
+
usage << sub_options.map { |option_name,option|
|
64
|
+
all_names = [option.name,Array(option.aliases)].flatten
|
65
|
+
all_names.map { |_|
|
66
|
+
CommandLineOption.name_as_string(_,false) + (option.kind_of?(Flag) ? " #{option.argument_name }" : '')
|
67
|
+
}.join('|')
|
68
|
+
}.map { |_| "[#{_}]" }.sort.join(' ')
|
69
|
+
usage << ' '
|
70
|
+
if is_default_command
|
71
|
+
usage << "[#{sub.name}]"
|
72
|
+
else
|
73
|
+
usage << sub.name.to_s
|
74
|
+
end
|
75
|
+
usage
|
76
|
+
end
|
77
|
+
|
78
|
+
def basic_usage(flags_and_switches)
|
79
|
+
usage = @basic_invocation.dup
|
80
|
+
usage << " [global options] #{path_to_command} "
|
81
|
+
usage << "[command options] " unless global_flags_and_switches.empty?
|
82
|
+
usage
|
83
|
+
end
|
84
|
+
|
85
|
+
def path_to_command
|
86
|
+
path = []
|
87
|
+
c = @command
|
88
|
+
while c.kind_of? Command
|
89
|
+
path.unshift(c.name)
|
90
|
+
c = c.parent
|
91
|
+
end
|
92
|
+
path.join(' ')
|
93
|
+
end
|
94
|
+
|
95
|
+
def global_flags_and_switches
|
96
|
+
@app.flags.merge(@app.switches)
|
97
|
+
end
|
98
|
+
|
99
|
+
def format_subcommands(command)
|
100
|
+
commands_array = command.commands.values.sort.map { |cmd|
|
101
|
+
if command.get_default_command == cmd.name
|
102
|
+
[cmd.names,cmd.description + " (default)"]
|
103
|
+
else
|
104
|
+
[cmd.names,cmd.description]
|
105
|
+
end
|
106
|
+
}
|
107
|
+
if command.has_action?
|
108
|
+
commands_array.unshift(["<default>",command.default_description])
|
109
|
+
end
|
110
|
+
formatter = ListFormatter.new(commands_array)
|
111
|
+
StringIO.new.tap { |io| formatter.output(io) }.string
|
112
|
+
end
|
113
|
+
|
114
|
+
def sorted_synopses(flags_and_switches)
|
115
|
+
synopses_command = {}
|
116
|
+
@command.commands.each do |name,sub|
|
117
|
+
default = @command.get_default_command == name
|
118
|
+
synopsis = command_with_subcommand_usage(sub,flags_and_switches,default)
|
119
|
+
synopses_command[synopsis] = sub
|
120
|
+
end
|
121
|
+
synopses = synopses_command.keys.sort { |one,two|
|
122
|
+
if synopses_command[one].name == @command.get_default_command
|
123
|
+
-1
|
124
|
+
elsif synopses_command[two].name == @command.get_default_command
|
125
|
+
1
|
126
|
+
else
|
127
|
+
synopses_command[one] <=> synopses_command[two]
|
128
|
+
end
|
129
|
+
}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|