rhc 0.97.17 → 0.98.16

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 (93) hide show
  1. data/bin/rhc +9 -9
  2. data/bin/rhc-port-forward +3 -0
  3. data/bin/rhc-sshkey +3 -0
  4. data/features/README.md +163 -35
  5. data/features/application.feature +24 -0
  6. data/features/cartridge.feature +24 -0
  7. data/features/client.feature +11 -0
  8. data/features/domain.feature +29 -0
  9. data/features/lib/rhc_helper.rb +14 -0
  10. data/features/lib/rhc_helper/app.rb +2 -8
  11. data/features/lib/rhc_helper/cartridge.rb +1 -7
  12. data/features/lib/rhc_helper/commandify.rb +37 -6
  13. data/features/lib/rhc_helper/domain.rb +5 -1
  14. data/features/lib/rhc_helper/httpify.rb +124 -60
  15. data/features/lib/rhc_helper/loggable.rb +0 -2
  16. data/features/lib/rhc_helper/persistable.rb +12 -2
  17. data/features/lib/rhc_helper/sshkey.rb +29 -0
  18. data/features/multiple_cartridge.feature +17 -0
  19. data/features/sshkey.feature +58 -0
  20. data/features/step_definitions/application_steps.rb +60 -52
  21. data/features/step_definitions/cartridge_steps.rb +22 -24
  22. data/features/step_definitions/client_steps.rb +9 -2
  23. data/features/step_definitions/domain_steps.rb +4 -0
  24. data/features/step_definitions/sshkey_steps.rb +56 -0
  25. data/features/support/assumptions.rb +37 -0
  26. data/features/support/before_hooks.rb +25 -0
  27. data/features/support/env.rb +84 -39
  28. data/features/support/key1 +27 -0
  29. data/features/support/key1.pub +1 -0
  30. data/features/support/key2 +27 -0
  31. data/features/support/key2.pub +1 -0
  32. data/features/support/key3.pub +1 -0
  33. data/features/support/ssh.sh +2 -0
  34. data/features/verify.feature +18 -159
  35. data/lib/rhc-common.rb +8 -21
  36. data/lib/rhc.rb +9 -5
  37. data/lib/rhc/autocomplete.rb +68 -0
  38. data/lib/rhc/autocomplete_templates/rhc.erb +33 -0
  39. data/lib/rhc/cli.rb +9 -6
  40. data/lib/rhc/command_runner.rb +108 -0
  41. data/lib/rhc/commands.rb +66 -132
  42. data/lib/rhc/commands/base.rb +95 -24
  43. data/lib/rhc/commands/domain.rb +33 -50
  44. data/lib/rhc/commands/port-forward.rb +81 -0
  45. data/lib/rhc/commands/setup.rb +1 -1
  46. data/lib/rhc/commands/sshkey.rb +95 -0
  47. data/lib/rhc/config.rb +108 -103
  48. data/lib/rhc/context_helper.rb +19 -0
  49. data/lib/rhc/coverage_helper.rb +1 -1
  50. data/lib/rhc/exceptions.rb +55 -4
  51. data/lib/rhc/help_formatter.rb +2 -3
  52. data/lib/rhc/helpers.rb +31 -23
  53. data/lib/{rhc-rest.rb → rhc/rest.rb} +95 -23
  54. data/lib/{rhc-rest → rhc/rest}/application.rb +1 -1
  55. data/lib/{rhc-rest → rhc/rest}/cartridge.rb +1 -1
  56. data/lib/{rhc-rest → rhc/rest}/client.rb +40 -9
  57. data/lib/{rhc-rest → rhc/rest}/domain.rb +1 -1
  58. data/lib/{rhc-rest → rhc/rest}/key.rb +11 -1
  59. data/lib/{rhc-rest → rhc/rest}/user.rb +1 -1
  60. data/lib/rhc/ssh_key_helpers.rb +10 -1
  61. data/lib/rhc/targz.rb +7 -8
  62. data/lib/rhc/usage_templates/command_help.erb +7 -6
  63. data/lib/rhc/usage_templates/help.erb +6 -9
  64. data/lib/rhc/usage_templates/missing_help.erb +1 -0
  65. data/lib/rhc/version.rb +2 -2
  66. data/lib/rhc/wizard.rb +4 -9
  67. data/spec/coverage_helper.rb +2 -2
  68. data/spec/rest_spec_helper.rb +66 -16
  69. data/spec/rhc/cli_spec.rb +16 -5
  70. data/spec/rhc/command_spec.rb +61 -6
  71. data/spec/rhc/commands/domain_spec.rb +50 -27
  72. data/spec/rhc/commands/port-forward_spec.rb +133 -0
  73. data/spec/rhc/commands/setup_spec.rb +2 -2
  74. data/spec/rhc/commands/sshkey_spec.rb +141 -0
  75. data/spec/rhc/common_spec.rb +1 -1
  76. data/spec/rhc/config_spec.rb +6 -4
  77. data/spec/rhc/helpers_spec.rb +0 -21
  78. data/spec/rhc/rest_application_spec.rb +7 -7
  79. data/spec/rhc/rest_client_spec.rb +87 -24
  80. data/spec/rhc/rest_spec.rb +36 -36
  81. data/spec/rhc/wizard_spec.rb +3 -3
  82. data/spec/spec.opts +1 -0
  83. data/spec/spec_helper.rb +3 -3
  84. metadata +61 -31
  85. data/lib/rhc-rest/exceptions/exceptions.rb +0 -75
  86. data/test/functional/application_test.rb +0 -71
  87. data/test/functional/domain_test.rb +0 -123
  88. data/test/functional/test_credentials.rb +0 -5
  89. data/test/sample-usage.rb +0 -122
  90. data/test/support/server.rb +0 -14
  91. data/test/support/testcase.rb +0 -3
  92. data/test/test_helper.rb +0 -4
  93. data/test/unit/command_test.rb +0 -19
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bash
2
+ ssh -o StrictHostKeyChecking=no -- "$@"
@@ -1,159 +1,18 @@
1
- Feature: Client Integration Tests
2
- @init
3
- Scenario: Setup Wizard
4
- Given the libra client tools
5
- When the setup wizard is run
6
- Then the client tools should be setup
7
-
8
- @init
9
- Scenario: Domain Creation
10
- Given the libra client tools
11
- When a new domain is needed and created
12
- Then the domain should be reserved
13
-
14
- Scenario: Domain Update
15
- Given the libra client tools
16
- And an existing domain
17
- When domain is updated
18
- Then the domain should be reserved
19
-
20
- Scenario: Domain Show
21
- Given the libra client tools
22
- And an existing domain
23
- When rhc domain is run
24
- When rhc domain show is run
25
- Then the default domain action output should equal the show action output
26
-
27
- Scenario: Domain Create Fails
28
- Given the libra client tools
29
- And an existing domain
30
- When rhc domain create is called
31
- Then the domain command should fail with an exitcode of 128
32
-
33
- Scenario: Domain Delete
34
- Given the libra client tools
35
- And an existing domain
36
- When domain is deleted
37
- Then domains should be empty
38
-
39
- Scenario: Domain Update Fails
40
- Given the libra client tools
41
- And given domains is empty
42
- When domain is updated
43
- Then the domain command should fail with an exitcode of 127
44
-
45
- @init
46
- Scenario: Domain Creation for Apps
47
- Given the libra client tools
48
- When a new domain is needed and created
49
- Then the domain should be reserved
50
-
51
- Scenario: Application Creation
52
- Given the libra client tools
53
- When 1 php-5.3 applications are created
54
- Then the applications should be accessible
55
-
56
- Scenario: Application Stopping
57
- Given the libra client tools
58
- And an existing php-5.3 application
59
- When the application is stopped
60
- Then the application should not be accessible
61
-
62
- Scenario: Application Starting
63
- Given the libra client tools
64
- And an existing php-5.3 application
65
- When the application is started
66
- Then the application should be accessible
67
-
68
- Scenario: Application Restarting
69
- Given the libra client tools
70
- And an existing php-5.3 application
71
- When the application is restarted
72
- Then the application should be accessible
73
-
74
- Scenario: Application Snapshot
75
- Given the libra client tools
76
- And an existing php-5.3 application
77
- When the application is snapshot
78
- Then the snapshot should be found
79
-
80
- Scenario: Application Tidy
81
- Given the libra client tools
82
- And an existing php-5.3 application
83
- When the application is tidied
84
- Then it should succeed
85
-
86
- Scenario: Application Show
87
- Given the libra client tools
88
- And an existing php-5.3 application
89
- When the application is shown
90
- Then it should succeed
91
-
92
- Scenario: Cartridge Add
93
- Given the libra client tools
94
- And an existing php-5.3 application
95
- When the mysql-5.1 cartridge is added
96
- Then the mysql-5.1 cartridge should be running
97
-
98
- Scenario: Cartridge Stop
99
- Given the libra client tools
100
- And an existing php-5.3 application with an embedded mysql-5.1 cartridge
101
- When the mysql-5.1 cartridge is stopped
102
- Then the mysql-5.1 cartridge should be stopped
103
-
104
- Scenario: Cartridge Start
105
- Given the libra client tools
106
- And an existing php-5.3 application with an embedded mysql-5.1 cartridge
107
- When the mysql-5.1 cartridge is started
108
- Then the mysql-5.1 cartridge should be running
109
-
110
- Scenario: Cartridge Restart
111
- Given the libra client tools
112
- And an existing php-5.3 application with an embedded mysql-5.1 cartridge
113
- When the mysql-5.1 cartridge is restarted
114
- Then the mysql-5.1 cartridge should be running
115
-
116
- Scenario: Supporting Cartridge Added
117
- Given the libra client tools
118
- And an existing php-5.3 application with an embedded mysql-5.1 cartridge
119
- When the phpmyadmin-3.4 cartridge is added
120
- Then the phpmyadmin-3.4 cartridge should be running
121
-
122
- Scenario: Conflicting Cartridge Fails
123
- Given the libra client tools
124
- And an existing php-5.3 application with embedded mysql-5.1 and phpmyadmin-3.4 cartridges
125
- Then adding the postgresql-8.5 cartridge should fail
126
-
127
- Scenario: Cartridge Removed
128
- Given the libra client tools
129
- And an existing php-5.3 application with embedded mysql-5.1 and phpmyadmin-3.4 cartridges
130
- When the phpmyadmin-3.4 cartridge is removed
131
- When the mysql-5.1 cartridge is removed
132
- Then the phpmyadmin-3.4 cartridge should be removed
133
- Then the mysql-5.1 cartridge should be removed
134
-
135
- Scenario: Add Alias
136
- Scenario: Remove Alias
137
-
138
- Scenario: Application Destroy
139
- Given the libra client tools
140
- And an existing php-5.3 application
141
- When the application is destroyed
142
- Then the application should not be accessible
143
-
144
- @init
145
- Scenario: Template Creation
146
- Scenario: Domain Changed
147
- Scenario: Template Deleted
148
- Scenario: Domain Changed Again
149
- Scenario: Domain Deleted
150
-
151
- @init
152
- Scenario: Key Added
153
- Scenario: Additional Key Added
154
- Scenario: Default Key Deleted
155
- Scenario: Key Overwritten
156
- Scenario: Key Deleted
157
-
158
- @init
159
- Scenario: Get Server Status
1
+ # these were defined before refactoring and have not been implemented yet
2
+ #Feature: Client Integration Tests
3
+ # Scenario: Add Alias
4
+ # Scenario: Remove Alias
5
+ #
6
+ # @init
7
+ # Scenario: Template Creation
8
+ # Scenario: Domain Changed
9
+ # Scenario: Template Deleted
10
+ # Scenario: Domain Changed Again
11
+ # Scenario: Domain Deleted
12
+ #
13
+ # @init
14
+ # Scenario: Key Added
15
+ # Scenario: Additional Key Added
16
+ # Scenario: Default Key Deleted
17
+ # Scenario: Key Overwritten
18
+ # Scenario: Key Deleted
data/lib/rhc-common.rb CHANGED
@@ -9,7 +9,7 @@ require 'resolv'
9
9
  require 'uri'
10
10
  require 'highline/import'
11
11
  require 'rhc'
12
- require 'rhc-rest'
12
+ require 'rhc/rest'
13
13
  require 'rhc/helpers'
14
14
  require 'rhc/config'
15
15
  require 'rhc/wizard'
@@ -337,7 +337,7 @@ end
337
337
  tempfile = `mktemp /tmp/openshift.XXXXXXXX`
338
338
  `echo "#{type} #{key}" > #{tempfile}`
339
339
  ssh_keys['keys'][name]['fingerprint'] = `ssh-keygen -lf #{tempfile}`.split(' ')[1]
340
- rescue NotImplementedError, Net::SSH::Exception
340
+ rescue NotImplementedError, Net::SSH::Exception, OpenSSL::PKey::PKeyError
341
341
  # Could be a new unsupported key type or invalid data on the server
342
342
  ssh_keys['keys'][name]['fingerprint'] = 'Key type is not recognized. Please check this key is valid.'
343
343
  end
@@ -509,7 +509,7 @@ end
509
509
  # API in order to access the rest of the logic in this function
510
510
  if scale
511
511
  end_point = "https://#{libra_server}/broker/rest/api"
512
- client = Rhc::Rest::Client.new(end_point, rhlogin, password)
512
+ client = RHC::Rest::Client.new(end_point, rhlogin, password)
513
513
 
514
514
  domain = client.find_domain(user_info['user_info']['domains'][0]['namespace'])
515
515
 
@@ -526,12 +526,12 @@ end
526
526
  health_check_path = application.health_check_path
527
527
 
528
528
  puts "DEBUG: '#{app_name}' creation returned success." if @mydebug
529
- rescue Rhc::Rest::ConnectionException, Rhc::Rest::ResourceAccessException => e
529
+ rescue RHC::Rest::ConnectionException, RHC::Rest::ResourceAccessException => e
530
530
  print_response_err(Struct::FakeResponse.new(e.message,e.code))
531
- rescue Rhc::Rest::ValidationException => e
531
+ rescue RHC::Rest::ValidationException => e
532
532
  validation_error_code = (e.code.nil?) ? 406 : e.code
533
533
  print_response_err(Struct::FakeResponse.new(e.message, validation_error_code))
534
- rescue Rhc::Rest::ServerErrorException => e
534
+ rescue RHC::Rest::ServerErrorException => e
535
535
  error_code = (e.code.nil?) ? 500 : e.code
536
536
  print_response_err(Struct::FakeResponse.new(e.message, error_code))
537
537
  end
@@ -642,9 +642,9 @@ WARNING
642
642
  unless no_git
643
643
  puts "Pulling new repo down" if @mydebug
644
644
 
645
- puts "git clone --quiet #{git_url} #{repo_dir}" if @mydebug
646
645
  quiet = (@mydebug ? ' ' : '--quiet ')
647
- git_clone = %x<git clone #{quiet} #{git_url} #{repo_dir}>
646
+ puts "git clone #{quiet}#{git_url} #{repo_dir}" if @mydebug
647
+ git_clone = %x[git clone #{quiet} #{git_url} #{repo_dir} 2>&1]
648
648
  if $?.exitstatus != 0
649
649
 
650
650
  if RHC::Helpers.windows?
@@ -1221,16 +1221,3 @@ end
1221
1221
  def get_var(key)
1222
1222
  RHC::Config[key]
1223
1223
  end
1224
-
1225
- # Public: convinience function for running the wizard
1226
- #
1227
- # Returns: false if wizard did not need to run
1228
- # true if wizard ran successfuly
1229
- # nil of there was an error
1230
- #
1231
- def default_setup_wizard
1232
- w = RHC::Wizard.new(RHC::Config)
1233
- return w.run if w.needs_configuration?
1234
-
1235
- false
1236
- end
data/lib/rhc.rb CHANGED
@@ -7,15 +7,19 @@ require 'logger'
7
7
 
8
8
  # Extend core methods
9
9
  require 'rhc/core_ext'
10
- require 'rhc/version'
11
10
 
12
11
  module RHC
13
- module Commands; end
14
-
15
- autoload :Helpers, 'rhc/helpers'
12
+ autoload :Helpers, 'rhc/helpers'
13
+ autoload :Rest, 'rhc/rest'
14
+ autoload :HelpFormatter, 'rhc/help_formatter'
15
+ autoload :CommandRunner, 'rhc/command_runner'
16
+ autoload :VERSION, 'rhc/version'
17
+ autoload :Commands, 'rhc/commands'
18
+ autoload :Config, 'rhc/config'
16
19
  end
17
20
 
21
+ require 'rhc/exceptions'
22
+
18
23
  # Replace me with proper autoloads on the module RHC
19
24
  require 'rhc-common'
20
- require 'rhc-rest'
21
25
 
@@ -0,0 +1,68 @@
1
+ require 'rhc'
2
+ require 'commander'
3
+ require 'commander/runner'
4
+ require 'commander/delegates'
5
+ require 'rhc/commands'
6
+
7
+ module RHC
8
+ class AutoCompleteBindings
9
+ attr_reader :top_level_opts, :commands
10
+ def initialize(top_level_opts, commands)
11
+ @top_level_opts = top_level_opts
12
+ @commands = commands
13
+ end
14
+ end
15
+
16
+ class AutoComplete
17
+ def initialize(script="rhc")
18
+ @script_erb = ERB.new(File.read(File.join(File.dirname(__FILE__), 'autocomplete_templates', "#{script}.erb")), nil, '-')
19
+ cli_init
20
+ # :name => {:actions => [], :switches => []}
21
+ @command_data = {}
22
+ @top_level_commands = []
23
+ @global_switches = []
24
+ Commander::Runner.instance.options.each { |o| @global_switches << o[:switches][-1] }
25
+ end
26
+
27
+ def gen()
28
+ process_data
29
+ gen_script
30
+ end
31
+
32
+ private
33
+ def cli_init
34
+ runner = RHC::CommandRunner.new([])
35
+ Commander::Runner.instance_variable_set :@singleton, runner
36
+ RHC::Commands.load.to_commander
37
+ end
38
+
39
+ def process_data
40
+ Commander::Runner.instance.commands.each_pair do |name, cmd|
41
+ next if cmd.summary.nil?
42
+
43
+ if name.rindex(' ').nil?
44
+ @top_level_commands << name
45
+ else
46
+ commands = name.split ' '
47
+ action = commands.pop
48
+ id = commands.join(' ')
49
+ data = @command_data[:"#{id}"] || {:actions => [],
50
+ :switches => []}
51
+ data[:actions] << action
52
+ @command_data[:"#{id}"] = data
53
+ end
54
+
55
+ switches = []
56
+ cmd.options { |o| switches << o[:switches][-1] if o[:switches] }
57
+ data = @command_data[:"#{name}"] || {:actions => [],
58
+ :switches => []}
59
+ data[:switches] = switches.concat(@global_switches)
60
+ @command_data[:"#{name}"] = data
61
+ end
62
+ end
63
+
64
+ def gen_script
65
+ @script_erb.result AutoCompleteBindings.new(@top_level_commands.join(' '), @command_data).get_binding
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,33 @@
1
+ #
2
+ # This is the bash auto completion script for the rhc command
3
+ #
4
+ _rhc()
5
+ {
6
+ local cur opts prev
7
+ COMPREPLY=()
8
+ cur="${COMP_WORDS[COMP_CWORD]}"
9
+ if [ $COMP_CWORD -eq 1 ]; then
10
+ opts=<%= "\"%s\"" % @top_level_opts %>
11
+ else
12
+ prev="${COMP_WORDS[@]:0:COMP_CWORD}"
13
+ SAVE_IFS=$IFS
14
+ IFS=" "
15
+ case "${prev[*]}" in
16
+ <%- for name, data in @commands %>
17
+ <%= "\"rhc %s\")" % name %>
18
+ if [[ "$cur" == -* ]]; then
19
+ opts=<%= "\"%s\"" % data[:switches].join(" ") %>
20
+ else
21
+ opts=<%= "\"%s\"" % data[:actions].join(" ") %>
22
+ fi
23
+ ;;
24
+ <%- end %>
25
+ esac
26
+ IFS=$SAVE_IFS
27
+ fi
28
+
29
+ COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
30
+ return 0
31
+ }
32
+
33
+ complete -o default -F _rhc rhc
data/lib/rhc/cli.rb CHANGED
@@ -3,7 +3,6 @@ require 'commander'
3
3
  require 'commander/runner'
4
4
  require 'commander/delegates'
5
5
  require 'rhc/commands'
6
- require 'rhc/help_formatter'
7
6
 
8
7
  include Commander::UI
9
8
  include Commander::UI::AskForClass
@@ -22,16 +21,20 @@ module RHC
22
21
 
23
22
  def self.set_terminal
24
23
  $terminal.wrap_at = HighLine::SystemExtensions.terminal_size.first - 5 rescue 80 if $stdin.tty?
24
+ # FIXME: ANSI terminals are not default on windows but we may just be
25
+ # hitting a bug in highline if windows does support another method.
26
+ # This is a safe fix for now but needs more research.
27
+ HighLine::use_color = false if RHC::Helpers.windows?
25
28
  end
26
29
 
27
30
  def self.start(args)
28
- runner = RHC::Commands::Runner.new(args)
31
+ runner = RHC::CommandRunner.new(args)
29
32
  Commander::Runner.instance_variable_set :@singleton, runner
30
33
 
31
- program :name, 'rhc'
32
- program :version, RHC::VERSION::STRING
33
- program :description, 'Command line interface for OpenShift.'
34
- program :help_formatter, RHC::UsageHelpFormatter
34
+ program :name, 'rhc'
35
+ program :description, 'Command line interface for OpenShift.'
36
+ program :version, RHC::VERSION::STRING
37
+ program :help_formatter, RHC::HelpFormatter
35
38
 
36
39
  RHC::Commands.load.to_commander
37
40
  exit(run! || 0)
@@ -0,0 +1,108 @@
1
+ module RHC
2
+ class CommandRunner < Commander::Runner
3
+ # regex fix from git - match on word boundries
4
+ def valid_command_names_from *args
5
+ arg_string = args.delete_if { |value| value =~ /^-/ }.join ' '
6
+ commands.keys.find_all { |name| name if /^#{name}\b/.match arg_string }
7
+ end
8
+
9
+ # override so we can do our own error handling
10
+ def run!
11
+ trace = false
12
+ require_program :version, :description
13
+
14
+ trap('INT') { abort program(:int_message) } if program(:int_message)
15
+ trap('INT') { program(:int_block).call } if program(:int_block)
16
+
17
+ global_option('-h', '--help', 'Display help documentation') do
18
+ args = @args - %w[-h --help]
19
+ command(:help).run(*args)
20
+ return
21
+ end
22
+ global_option('-v', '--version', 'Display version information') { say version; return }
23
+ global_option('-t', '--trace', 'Display backtrace when an error occurs') { trace = true }
24
+
25
+ parse_global_options
26
+ remove_global_options options, @args
27
+
28
+ unless trace
29
+ begin
30
+ run_active_command
31
+ rescue InvalidCommandError => e
32
+ if provided_arguments.empty?
33
+ say RHC::HelpFormatter.new(self).render
34
+ else
35
+ RHC::Helpers.error "The command '#{program :name} #{provided_arguments.join(' ')}' is not recognized.\n"
36
+ say "See '#{program :name} help' for a list of valid commands."
37
+ end
38
+ 1
39
+ rescue \
40
+ ArgumentError,
41
+ OptionParser::InvalidOption,
42
+ OptionParser::InvalidArgument,
43
+ OptionParser::MissingArgument => e
44
+
45
+ help_bindings = CommandHelpBindings.new(active_command, commands, Commander::Runner.instance.options)
46
+ usage = RHC::HelpFormatter.new(self).render_command(help_bindings)
47
+ RHC::Helpers.error e.message
48
+ say "\n#{usage}"
49
+ 1
50
+ rescue RHC::Exception, RHC::Rest::Exception => e
51
+ RHC::Helpers.error e.message
52
+ e.code.nil? ? 128 : e.code
53
+ end
54
+ else
55
+ run_active_command
56
+ end
57
+ end
58
+
59
+ def provided_arguments
60
+ @args[0, @args.find_index { |arg| arg.start_with?('-') } || @args.length]
61
+ end
62
+
63
+ def global_option(*args, &block)
64
+ opts = args.pop if Hash === args.last
65
+ super(*args, &block).tap do |options|
66
+ options.last.merge!(opts) if opts
67
+ end
68
+ end
69
+
70
+ def create_default_commands
71
+ command :help do |c|
72
+ c.syntax = 'rhc help <command>'
73
+ c.description = 'Display global or <command> help documentation.'
74
+ c.when_called do |args, options|
75
+ if args.empty?
76
+ say help_formatter.render
77
+ else
78
+ command = command args.join(' ')
79
+ begin
80
+ require_valid_command command
81
+ rescue InvalidCommandError => e
82
+ RHC::Helpers.error "The command '#{program :name} #{provided_arguments.join(' ')}' is not recognized.\n"
83
+ say "See '#{program :name} help' for a list of valid commands."
84
+ next
85
+ end
86
+
87
+ help_bindings = CommandHelpBindings.new command, commands, Commander::Runner.instance.options
88
+ say help_formatter.render_command help_bindings
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ class CommandHelpBindings
96
+ def initialize(command, instance_commands, global_options)
97
+ @command = command
98
+ @actions = instance_commands.collect do |command_name, command_class|
99
+ next if command_class.summary.nil?
100
+ m = /^#{command.name} ([^ ]+)/.match(command_name)
101
+ # if we have a match and it is not an alias then we can use it
102
+ m and command_name == command_class.name ? {:name => m[1], :summary => command_class.summary || ""} : nil
103
+ end
104
+ @actions.compact!
105
+ @global_options = global_options
106
+ end
107
+ end
108
+ end