github_cli 0.3.1 → 0.4.0

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.
Files changed (56) hide show
  1. data/CHANGELOG.md +21 -0
  2. data/Gemfile.lock +20 -22
  3. data/README.md +29 -4
  4. data/bin/ghc +1 -1
  5. data/features/download.feature +11 -0
  6. data/features/email.feature +9 -0
  7. data/features/errors.feature +10 -0
  8. data/features/event.feature +14 -0
  9. data/features/executable.feature +44 -17
  10. data/features/follower.feature +11 -0
  11. data/features/fork.feature +13 -0
  12. data/features/hook.feature +12 -0
  13. data/features/label.feature +16 -0
  14. data/features/member.feature +18 -0
  15. data/features/milestone.feature +11 -0
  16. data/features/organization.feature +9 -0
  17. data/features/reference.feature +11 -0
  18. data/features/repositories.feature +16 -7
  19. data/features/tag.feature +8 -0
  20. data/features/team.feature +18 -0
  21. data/features/tree.feature +8 -0
  22. data/features/user.feature +8 -0
  23. data/ghc_logo.png +0 -0
  24. data/github_cli.gemspec +2 -2
  25. data/lib/github_cli/api.rb +14 -11
  26. data/lib/github_cli/apis/follower.rb +40 -0
  27. data/lib/github_cli/apis/member.rb +52 -0
  28. data/lib/github_cli/apis/organization.rb +28 -0
  29. data/lib/github_cli/apis/team.rb +89 -0
  30. data/lib/github_cli/apis/user.rb +22 -0
  31. data/lib/github_cli/apis.rb +5 -0
  32. data/lib/github_cli/cli.rb +11 -4
  33. data/lib/github_cli/command.rb +40 -28
  34. data/lib/github_cli/commands/followers.rb +50 -0
  35. data/lib/github_cli/commands/members.rb +70 -0
  36. data/lib/github_cli/commands/organizations.rb +42 -0
  37. data/lib/github_cli/commands/teams.rb +148 -0
  38. data/lib/github_cli/commands/users.rb +26 -0
  39. data/lib/github_cli/commands.rb +5 -0
  40. data/lib/github_cli/editor.rb +27 -0
  41. data/lib/github_cli/errors.rb +6 -1
  42. data/lib/github_cli/formatter.rb +47 -0
  43. data/lib/github_cli/formatters/csv.rb +8 -8
  44. data/lib/github_cli/formatters/table.rb +237 -11
  45. data/lib/github_cli/pager.rb +66 -0
  46. data/lib/github_cli/subcommands.rb +15 -0
  47. data/lib/github_cli/system.rb +33 -0
  48. data/lib/github_cli/terminal.rb +60 -30
  49. data/lib/github_cli/thor_ext.rb +15 -0
  50. data/lib/github_cli/ui.rb +8 -0
  51. data/lib/github_cli/util.rb +55 -12
  52. data/lib/github_cli/version.rb +1 -1
  53. data/lib/github_cli.rb +3 -0
  54. data/spec/github_cli/pager_spec.rb +69 -0
  55. data/spec/github_cli/util_spec.rb +14 -4
  56. metadata +64 -14
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ # This class determines editor to use to open the output.
5
+ class Editor
6
+
7
+ def initialize(options={})
8
+ end
9
+
10
+ def editor
11
+ editors = [ ENV['GHC_EDITOR'], ENV['VISUAL'], ENV['EDITOR'], 'vi' ]
12
+ editor = GithubCLI.config['editor']
13
+ editor ||= editors.find { |e| !e.nil? && !e.empty? }
14
+ end
15
+
16
+ def open(name)
17
+ if editor
18
+ command = "#{editor} #{name}"
19
+ success = system(command)
20
+ GithubCLI.ui.info "Could not run '#{command}'" unless success
21
+ else
22
+ GithubCLI.info("To open output, set $EDITOR or $VISUL")
23
+ end
24
+ end
25
+
26
+ end # Editor
27
+ end # GithubCLI
@@ -8,6 +8,10 @@ module GithubCLI
8
8
  end
9
9
  end
10
10
 
11
+ class ApiError < GithubCLIError
12
+ status_code 5
13
+ end
14
+
11
15
  # Raised when a configuration file is corrupt or missing.
12
16
  class ConfigFileNotFound < GithubCLIError
13
17
  status_code 10
@@ -30,8 +34,9 @@ module GithubCLI
30
34
  status_code 13
31
35
 
32
36
  def initialize(format)
33
- super %{Unrecognized formatting options: #{format} }
37
+ super %{Unrecognized formatting options: #{format}}
34
38
  end
35
39
  end
36
40
 
41
+
37
42
  end # GithubCLI
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ # This is the main entry point for formatting output.
5
+ # It delegates to other objects like Formatter::Table
6
+ # to perform actual rendering.
7
+ class Formatter
8
+ attr_reader :response, :format
9
+
10
+ def initialize(response, options={})
11
+ @response = response
12
+ @format = options[:format]
13
+ end
14
+
15
+ def render_output
16
+ render_status
17
+ Terminal.paged_output
18
+ determine_output_formatter
19
+ end
20
+
21
+ def determine_output_formatter
22
+ case format.to_s
23
+ when 'table', /table:v.*/, /table:h.*/
24
+ formatter = Formatters::Table.new(response,
25
+ :transform => format.to_s.split(':').last
26
+ )
27
+ formatter.format
28
+ when 'csv'
29
+ formatter = Formatters::CSV.new(response)
30
+ formatter.format
31
+ when 'json'
32
+ 'json output'
33
+ else
34
+ raise UnknownFormatError, format
35
+ end
36
+ end
37
+
38
+ # Render status code
39
+ def render_status
40
+ if response.respond_to? :status
41
+ Terminal.line "Response Status: #{response.status}\n"
42
+ Terminal.newline
43
+ end
44
+ end
45
+
46
+ end # Formatter
47
+ end # GithubCLi
@@ -14,24 +14,24 @@ module GithubCLI
14
14
  render_headers @response.first
15
15
  @response.each_with_index do |item, indx|
16
16
  render_line indx, item
17
- $stdout.puts
17
+ Terminal.newline
18
18
  end
19
- else
19
+ when Hash
20
20
  render_headers @response
21
21
  render_line 1, @response
22
+ else
23
+ Terminal.line "#{@response}\n"
22
24
  end
23
25
  end
24
26
 
25
27
  def render_headers(response)
26
- output = {}
27
- GithubCLI::Util.flatten_hash(response.to_hash, output)
28
- puts "Index," + output.keys.join(',')
28
+ output = GithubCLI::Util.flatten_hash(response.to_hash)
29
+ Terminal.line "Index,#{output.keys.join(',')}\n"
29
30
  end
30
31
 
31
32
  def render_line(index, item)
32
- output = {}
33
- GithubCLI::Util.flatten_hash(item.to_hash, output)
34
- printf "%d,%s", index, output.values.join(',')
33
+ output = GithubCLI::Util.flatten_hash(item.to_hash)
34
+ $stdout.printf "%d,%s", index, output.values.join(',')
35
35
  end
36
36
 
37
37
  end # CSV
@@ -1,34 +1,260 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'ostruct'
4
+ require 'forwardable'
5
+
3
6
  module GithubCLI
4
7
  module Formatters
5
8
  class Table
9
+ include GithubCLI::Util
10
+ include Enumerable
11
+ extend Forwardable
12
+
13
+ OPTIONS = {
14
+ :border => {
15
+ 'top' => '━',
16
+ 'top_mid' => '┳',
17
+ 'top_left' => '┏',
18
+ 'top_right' => '┓',
19
+ 'bottom' => '━',
20
+ 'bottom_mid' => '┻',
21
+ 'bottom_left' => '┗',
22
+ 'bottom_right' => '┛',
23
+ 'left' => '┃',
24
+ 'left_mid' => '┣',
25
+ 'mid' => '━',
26
+ 'mid_mid' => '╋',
27
+ 'right' => '┃',
28
+ 'right_mid' => '┫'
29
+ },
30
+ :truncate => '…',
31
+ :style => {
32
+ :padding_left => 1,
33
+ :padding_right => 1,
34
+ :align => :left,
35
+ :head => ['cyan'],
36
+ :compact => false
37
+ }
38
+ }
39
+
40
+ attr_reader :response, :transform, :output_array, :total_records
41
+
42
+ # Subset of safe methods that both Array and Hash implement
43
+ def_delegators(:@output_array, :[], :assoc, :each, :empty?, :flatten,
44
+ :include?, :index, :inspect, :length, :select, :size, :to_a, :values_at,
45
+ :pretty_print, :rassoc)
46
+
47
+ def initialize(response, options={})
48
+ @total_records = 1
49
+ @transform = determine_layout(options[:transform])
50
+ @response = response
51
+ @output_array = build_output
52
+ end
53
+
54
+ def determine_layout(layout)
55
+ ( !layout.nil? && layout.index('h') ) ? :horizontal : :vertical
56
+ end
6
57
 
7
- def initialize(response)
8
- @response = response
58
+ def options
59
+ OPTIONS
60
+ end
61
+
62
+ def border
63
+ OpenStruct.new OPTIONS[:border]
64
+ end
65
+
66
+ def style
67
+ OpenStruct.new OPTIONS[:style]
68
+ end
69
+
70
+ # Builds output array from response hash
71
+ #
72
+ def build_output
73
+ case response
74
+ when Array
75
+ case transform
76
+ when :horizontal
77
+ array = [flatten_hash(response[0].to_hash).keys]
78
+ response.each do |item|
79
+ array << convert_values(flatten_hash(item.to_hash).values)
80
+ end
81
+ array
82
+ when :vertical
83
+ response.inject([]) do |array, item|
84
+ output = flatten_hash(item.to_hash)
85
+ rows = output.keys.zip(convert_values(output.values))
86
+ rows.each {|row| array << row }
87
+ @total_records = rows.size
88
+ array
89
+ end
90
+ end
91
+ when Hash
92
+ output = flatten_hash(response)
93
+ case transform
94
+ when :horizontal
95
+ array = [output.keys]
96
+ array << convert_values(output.values)
97
+ when :vertical
98
+ output.keys.zip(convert_values(output.values))
99
+ end
100
+ else
101
+ [response]
102
+ end
103
+ end
104
+
105
+ def column_widths
106
+ @column_widths ||= begin
107
+ array = case transform
108
+ when :horizontal
109
+ field_len = (
110
+ (Terminal.width - (output_array[0].size)).to_f / output_array[0].size.to_f
111
+ ).round
112
+ Array.new(output_array[0].size, field_len)
113
+ when :vertical
114
+ start = 0
115
+ maximas = []
116
+ colcount = output_array.max{ |a,b| a.size <=> b.size }.size
117
+
118
+ start.upto(colcount - 1) do |index|
119
+ maxima = output_array.map do |row|
120
+ row[index] ? (style.padding_left+ row[index].to_s.size + style.padding_right) : 0
121
+ end.max
122
+ maximas << maxima
123
+ end
124
+ maximas
125
+ end
126
+ array
127
+ end
128
+ end
129
+
130
+ def column_width(index)
131
+ width = column_widths[index] || 0
132
+ end
133
+
134
+ def columns
135
+ column_widths.size
136
+ end
137
+
138
+ def total_width
139
+ column_widths.reduce(0, :+).round + column_widths.size + border.right.length
9
140
  end
10
141
 
11
142
  def format
12
- case @response
143
+ case response
13
144
  when Array
14
- @response.each do |item|
15
- render_vertical item
16
- $stdout.puts
145
+ render_top_line
146
+ output_array.each_with_index do |row, indx|
147
+ render_row row
148
+ if (output_array.size - 1 != indx) && ((indx + 1) % total_records == 0)
149
+ render_middle_line
150
+ end
151
+ end
152
+ render_bottom_line
153
+ when Hash
154
+ render_top_line
155
+ output_array.each_with_index do |row, indx|
156
+ render_row row
157
+ if transform == :horizontal && output_array.size - 1 != indx
158
+ render_middle_line
159
+ end
17
160
  end
161
+ render_bottom_line
18
162
  else
19
- render_vertical @response
163
+ Terminal.line "#{response}\n"
20
164
  end
21
165
  end
22
166
 
23
167
  def render_vertical(item)
24
- output = {}
25
- GithubCLI::Util.flatten_hash(item.to_hash, output)
168
+ output = GithubCLI::Util.flatten_hash(item.to_hash)
26
169
  GithubCLI.ui.print_table(
27
- output.keys.zip(GithubCLI::Util.convert_values(output.values))
170
+ output.keys.zip(GithubCLI::Util.convert_values(output.values)),
171
+ :truncate => true
172
+ )
173
+ end
174
+
175
+ def render_horizontal(item)
176
+ output = GithubCLI::Util.flatten_hash(item.to_hash)
177
+ GithubCLI.ui.print_table(
178
+ [GithubCLI::Util.convert_values(output.values)],
179
+ :truncate => true
180
+ )
181
+ end
182
+
183
+ def render_line(line, left, right, intersection)
184
+ line = left + (line * (total_width - 2)) + right
185
+ width = 0
186
+
187
+ column_widths.each_with_index do |col_width, indx|
188
+ # Skip last column
189
+ if indx != (column_widths.size - 1)
190
+ width += col_width + 1
191
+ line = line[0...width] + intersection + line[width+1..-1]
192
+ else
193
+ width += col_width - 1
194
+ line = line[0...width] + right
195
+ end
196
+ end
197
+ Terminal.line line + "\n"
198
+ end
199
+
200
+ def render_top_line
201
+ render_line(
202
+ border.top,
203
+ border.top_left || border.top,
204
+ border.top_right || border.top,
205
+ border.top_mid
28
206
  )
29
207
  end
30
208
 
31
- def render_horizontal
209
+ def render_middle_line
210
+ render_line(
211
+ border.mid,
212
+ border.left_mid || border.mid,
213
+ border.right_mid || border.mid,
214
+ border.mid_mid
215
+ )
216
+ end
217
+
218
+ def render_bottom_line
219
+ render_line(
220
+ border.bottom,
221
+ border.bottom_left || border.bottom,
222
+ border.bottom_right || border.top,
223
+ border.bottom_mid
224
+ )
225
+ end
226
+
227
+ def render_cell(field, indx)
228
+ width = column_widths[indx] -
229
+ (style.padding_left || 0) -
230
+ (style.padding_right || 0)
231
+
232
+ if (indx == (column_widths.size - 1))
233
+ # Don't output 2 trailing spaces when printing last column
234
+ width = width - 2 if width > 3 # Ensure sensible width
235
+ end
236
+ field = if field.length == width
237
+ field
238
+ elsif field.length < width
239
+ pad(field.to_s, width, :align => style.align)
240
+ else
241
+ truncate(field.to_s, width)
242
+ end
243
+
244
+ string = ''
245
+ string << ' ' * (style.padding_left || 0)
246
+ string << "#{field}"
247
+ string << ' ' * (style.padding_right || 0)
248
+ string << "#{border.right}"
249
+ string
250
+ end
251
+
252
+ def render_row(fields, options={})
253
+ columns = []
254
+ fields.each_with_index do |field, indx|
255
+ columns << render_cell(field, indx)
256
+ end
257
+ Terminal.line border.left + columns.join + "\n"
32
258
  end
33
259
 
34
260
  end # Table
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ # This class provides pagining of terminal output.
5
+ class Pager
6
+ class << self
7
+
8
+ def pager_command(*cmds)
9
+ @pager_command = (!@pager_command.nil? && cmds.empty?) || begin
10
+ commands = [
11
+ ENV['GIT_PAGER'], `git config --get-all core.pager`.split.first,
12
+ ENV['PAGER'], 'less -isr', 'more', 'cat', 'pager'
13
+ ]
14
+ commands = cmds + commands
15
+ commands.compact.uniq.find { |cmd| System.command? cmd }
16
+ end
17
+ end
18
+
19
+ # Indicates if pager is enabled
20
+ def enabled?
21
+ @enabled && true
22
+ end
23
+
24
+ def enable
25
+ @enabled = true
26
+ end
27
+
28
+ def disable
29
+ @enabled = false
30
+ end
31
+ end
32
+
33
+ def initialize(options={})
34
+ @pager_command = options[:pager_command] if options[:pager_command]
35
+ end
36
+
37
+ # Pages output using configured pager.
38
+ def page
39
+ return if not $stdout.tty? or System.windows?
40
+
41
+ read_io, write_io = IO.pipe
42
+
43
+ if Kernel.fork
44
+ $stdin.reopen(read_io)
45
+ read_io.close
46
+ write_io.close
47
+
48
+ # Don't page if the input is short enough
49
+ ENV['LESS'] = 'FSRX'
50
+
51
+ # Wait until we have input before we start the pager
52
+ Kernel.select [$stdin]
53
+
54
+ pager = Pager.pager_command
55
+
56
+ Kernel.exec pager rescue Kernel.exec "/bin/sh", "-c", pager
57
+ else
58
+ # Child process
59
+ $stdout.reopen(write_io)
60
+ $stderr.reopen(write_io) if $stderr.tty?
61
+ write_io.close
62
+ read_io.close
63
+ end
64
+ end
65
+ end # System
66
+ end # GithubCLI
@@ -24,6 +24,9 @@ module GithubCLI
24
24
  desc "event <command>", "Leverage Events API"
25
25
  subcommand "event", GithubCLI::Commands::Events
26
26
 
27
+ desc "follower <command>", "Leverage Followers API"
28
+ subcommand "follower", GithubCLI::Commands::Followers
29
+
27
30
  desc "fork <command>", "Leverage Forks API"
28
31
  subcommand "fork", GithubCLI::Commands::Forks
29
32
 
@@ -42,9 +45,15 @@ module GithubCLI
42
45
  desc "label <command>", "Leverage Labels API"
43
46
  subcommand "label", GithubCLI::Commands::Labels
44
47
 
48
+ desc "member <command>", "Leverage Members API"
49
+ subcommand "member", GithubCLI::Commands::Members
50
+
45
51
  desc "milestone <command>", "Leverage Milestones API"
46
52
  subcommand "milestone", GithubCLI::Commands::Milestones
47
53
 
54
+ desc "org <command>", "Leverage Organizations API"
55
+ subcommand "org", GithubCLI::Commands::Organizations
56
+
48
57
  desc "pull <command>", "Leverage Pull Requests API"
49
58
  subcommand "pull", GithubCLI::Commands::PullRequests
50
59
 
@@ -57,9 +66,15 @@ module GithubCLI
57
66
  desc "tag <command>", "Leverage Tags API"
58
67
  subcommand "tag", GithubCLI::Commands::Tags
59
68
 
69
+ desc "team <command>", "Leverage Teams API"
70
+ subcommand "team", GithubCLI::Commands::Teams
71
+
60
72
  desc "tree <command>", "Leverage Trees API"
61
73
  subcommand "tree", GithubCLI::Commands::Trees
62
74
 
75
+ desc "user <command>", "Leverage Users API"
76
+ subcommand "user", GithubCLI::Commands::Users
77
+
63
78
  desc "watch <command>", "Leverage Watching API"
64
79
  subcommand "watch", GithubCLI::Commands::Watching
65
80
 
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ # This class provides methods for reading system settings.
5
+ class System
6
+ class << self
7
+
8
+ # Checks if windows platform.
9
+ def windows?
10
+ require 'rbconfig'
11
+ RbConfig::CONFIG['host_os'] =~ /msdos|mswin|djgpp|mingw|windows/
12
+ end
13
+
14
+ # Finds executable in $PATH.
15
+ def which(command)
16
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
17
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
18
+ exts.each do |ext|
19
+ exe = "#{path}/#{command}#{ext}"
20
+ return exe if File.executable? exe
21
+ end
22
+ end
23
+ return nil
24
+ end
25
+
26
+ # Checks if command exists.
27
+ def command?(name)
28
+ !which(name).nil?
29
+ end
30
+
31
+ end
32
+ end # System
33
+ end # GithubCLI
@@ -3,38 +3,44 @@
3
3
  module GithubCLI
4
4
  # Responsible for display and size detection.
5
5
  class Terminal
6
- DEFAULT_WIDTH = 120
6
+ DEFAULT_WIDTH = 80
7
7
  DEFAULT_HEIGHT = 40
8
8
 
9
9
  class << self
10
- attr_accessor :size
11
-
12
- def render_output(response, options={})
13
- render_status response
14
- case options[:format].to_s
15
- when 'table'
16
- formatter = Formatters::Table.new(response)
17
- formatter.format
18
- when 'csv'
19
- formatter = Formatters::CSV.new(response)
20
- formatter.format
21
- when 'json'
22
- 'json output'
23
- else
24
- raise UnknownFormatError, options[:format]
25
- end
10
+
11
+ def default_width
12
+ DEFAULT_WIDTH
13
+ end
14
+
15
+ def width
16
+ GithubCLI.ui.terminal_width
26
17
  end
27
18
 
28
- # Render status code
29
- def render_status(response)
30
- puts "Response Status: #{response.status}"
31
- puts
19
+ def line(text)
20
+ $stdout.print text
32
21
  end
33
22
 
34
- def render_header
23
+ def newline
24
+ $stdout.print "\n"
25
+ nil
26
+ end
27
+
28
+ def paged_output
29
+ if Pager.enabled?
30
+ pager.page
31
+ true
32
+ else
33
+ false
34
+ end
35
+ end
36
+
37
+ def pager
38
+ @pager ||= Pager.new
35
39
  end
36
40
 
37
41
  def print_commands(pattern=nil)
42
+ Terminal.line "\n" + GithubCLI.program_name + "\n"
43
+ Terminal.newline
38
44
  GithubCLI.ui.info "Commands:"
39
45
 
40
46
  commands = Command.all.select do |cmd|
@@ -63,23 +69,47 @@ module GithubCLI
63
69
  GithubCLI.ui.info "ghc: '#{cmd}' is not a ghc command. See 'ghc --help'."
64
70
  end
65
71
 
66
- def print_program_name(print=true)
72
+ def print_usage(flags, command='<command>')
67
73
  GithubCLI.ui.info <<-TEXT
68
74
 
69
- #{GithubCLI.program_name}
75
+ #{GithubCLI.program_name}
76
+
77
+ Usage: ghc #{format_usage(flags, command, :indent => 11)}
70
78
 
71
79
  TEXT
72
80
  end
73
81
 
74
- def print_usage(print=true)
75
- if print
76
- GithubCLI.ui.info <<-TEXT
77
-
78
- Usage: ghc <command> <subcommand> [<args>]
82
+ # Options
83
+ # indent - Indent the line with by indent value. Assumes that the first
84
+ # the first line is already filled in with other padding.
85
+ # length - Line length, otherwise the default terminal width is assumed.
86
+ def format_usage(flags, command, options={})
87
+ synopsis = "#{flags} #{command} <subcommand> [<args>]"
88
+ indent = options[:indent] || 0
89
+ padding = sprintf("%#{indent}s",'')
90
+ length = options[:length] || default_width
91
+ wrap synopsis, length, indent, padding
92
+ end
79
93
 
80
- TEXT
94
+ # Wraps text at the given line length using given indent value.
95
+ def wrap(text, length, indent=0, padding=0)
96
+ if text.length > length - indent
97
+ paragraphs = []
98
+ line = ''
99
+ text.split(/\s+/).map(&:chomp).reject(&:empty?).each do |fragment|
100
+ if line.length < length - indent
101
+ line << fragment + ' '
102
+ else
103
+ paragraphs << line
104
+ line = padding + fragment + ' '
105
+ end
106
+ end
107
+ paragraphs << line
108
+ text = paragraphs.join("\n")
81
109
  end
110
+ text
82
111
  end
112
+
83
113
  end
84
114
 
85
115
  end # Terminal
@@ -12,12 +12,27 @@ class Thor
12
12
  end
13
13
  list.sort!{ |a,b| a[0] <=> b[0] }
14
14
 
15
+ GithubCLI::Terminal.print_usage global_flags, GithubCLI::Command.command_to_show(list[0][0])
16
+
15
17
  shell.say "Commands:"
16
18
  shell.print_table(list, :indent => 2, :truncate => true)
17
19
  shell.say
18
20
  class_options_help(shell)
19
21
  end
20
22
 
23
+ # String representation of all available global flags
24
+ def global_flags
25
+ return if class_options.empty?
26
+
27
+ all_options = ''
28
+ class_options.each do |key, val|
29
+ all_options << '[' + val.switch_name
30
+ all_options << (!val.aliases.empty? ? ('|' + val.aliases.join('|')) : '')
31
+ all_options << '] '
32
+ end
33
+ all_options
34
+ end
35
+
21
36
  def subcommand_help(cmd)
22
37
  desc "help <command>", "Describe subcommands or one specific subcommand"
23
38
  class_eval <<-RUBY