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.
- data/bin/rhc +9 -9
- data/bin/rhc-port-forward +3 -0
- data/bin/rhc-sshkey +3 -0
- data/features/README.md +163 -35
- data/features/application.feature +24 -0
- data/features/cartridge.feature +24 -0
- data/features/client.feature +11 -0
- data/features/domain.feature +29 -0
- data/features/lib/rhc_helper.rb +14 -0
- data/features/lib/rhc_helper/app.rb +2 -8
- data/features/lib/rhc_helper/cartridge.rb +1 -7
- data/features/lib/rhc_helper/commandify.rb +37 -6
- data/features/lib/rhc_helper/domain.rb +5 -1
- data/features/lib/rhc_helper/httpify.rb +124 -60
- data/features/lib/rhc_helper/loggable.rb +0 -2
- data/features/lib/rhc_helper/persistable.rb +12 -2
- data/features/lib/rhc_helper/sshkey.rb +29 -0
- data/features/multiple_cartridge.feature +17 -0
- data/features/sshkey.feature +58 -0
- data/features/step_definitions/application_steps.rb +60 -52
- data/features/step_definitions/cartridge_steps.rb +22 -24
- data/features/step_definitions/client_steps.rb +9 -2
- data/features/step_definitions/domain_steps.rb +4 -0
- data/features/step_definitions/sshkey_steps.rb +56 -0
- data/features/support/assumptions.rb +37 -0
- data/features/support/before_hooks.rb +25 -0
- data/features/support/env.rb +84 -39
- data/features/support/key1 +27 -0
- data/features/support/key1.pub +1 -0
- data/features/support/key2 +27 -0
- data/features/support/key2.pub +1 -0
- data/features/support/key3.pub +1 -0
- data/features/support/ssh.sh +2 -0
- data/features/verify.feature +18 -159
- data/lib/rhc-common.rb +8 -21
- data/lib/rhc.rb +9 -5
- data/lib/rhc/autocomplete.rb +68 -0
- data/lib/rhc/autocomplete_templates/rhc.erb +33 -0
- data/lib/rhc/cli.rb +9 -6
- data/lib/rhc/command_runner.rb +108 -0
- data/lib/rhc/commands.rb +66 -132
- data/lib/rhc/commands/base.rb +95 -24
- data/lib/rhc/commands/domain.rb +33 -50
- data/lib/rhc/commands/port-forward.rb +81 -0
- data/lib/rhc/commands/setup.rb +1 -1
- data/lib/rhc/commands/sshkey.rb +95 -0
- data/lib/rhc/config.rb +108 -103
- data/lib/rhc/context_helper.rb +19 -0
- data/lib/rhc/coverage_helper.rb +1 -1
- data/lib/rhc/exceptions.rb +55 -4
- data/lib/rhc/help_formatter.rb +2 -3
- data/lib/rhc/helpers.rb +31 -23
- data/lib/{rhc-rest.rb → rhc/rest.rb} +95 -23
- data/lib/{rhc-rest → rhc/rest}/application.rb +1 -1
- data/lib/{rhc-rest → rhc/rest}/cartridge.rb +1 -1
- data/lib/{rhc-rest → rhc/rest}/client.rb +40 -9
- data/lib/{rhc-rest → rhc/rest}/domain.rb +1 -1
- data/lib/{rhc-rest → rhc/rest}/key.rb +11 -1
- data/lib/{rhc-rest → rhc/rest}/user.rb +1 -1
- data/lib/rhc/ssh_key_helpers.rb +10 -1
- data/lib/rhc/targz.rb +7 -8
- data/lib/rhc/usage_templates/command_help.erb +7 -6
- data/lib/rhc/usage_templates/help.erb +6 -9
- data/lib/rhc/usage_templates/missing_help.erb +1 -0
- data/lib/rhc/version.rb +2 -2
- data/lib/rhc/wizard.rb +4 -9
- data/spec/coverage_helper.rb +2 -2
- data/spec/rest_spec_helper.rb +66 -16
- data/spec/rhc/cli_spec.rb +16 -5
- data/spec/rhc/command_spec.rb +61 -6
- data/spec/rhc/commands/domain_spec.rb +50 -27
- data/spec/rhc/commands/port-forward_spec.rb +133 -0
- data/spec/rhc/commands/setup_spec.rb +2 -2
- data/spec/rhc/commands/sshkey_spec.rb +141 -0
- data/spec/rhc/common_spec.rb +1 -1
- data/spec/rhc/config_spec.rb +6 -4
- data/spec/rhc/helpers_spec.rb +0 -21
- data/spec/rhc/rest_application_spec.rb +7 -7
- data/spec/rhc/rest_client_spec.rb +87 -24
- data/spec/rhc/rest_spec.rb +36 -36
- data/spec/rhc/wizard_spec.rb +3 -3
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +3 -3
- metadata +61 -31
- data/lib/rhc-rest/exceptions/exceptions.rb +0 -75
- data/test/functional/application_test.rb +0 -71
- data/test/functional/domain_test.rb +0 -123
- data/test/functional/test_credentials.rb +0 -5
- data/test/sample-usage.rb +0 -122
- data/test/support/server.rb +0 -14
- data/test/support/testcase.rb +0 -3
- data/test/test_helper.rb +0 -4
- data/test/unit/command_test.rb +0 -19
data/features/verify.feature
CHANGED
@@ -1,159 +1,18 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
Scenario:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
Scenario:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
Scenario:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
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 =
|
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
|
529
|
+
rescue RHC::Rest::ConnectionException, RHC::Rest::ResourceAccessException => e
|
530
530
|
print_response_err(Struct::FakeResponse.new(e.message,e.code))
|
531
|
-
rescue
|
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
|
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
|
-
|
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
|
-
|
14
|
-
|
15
|
-
autoload :
|
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::
|
31
|
+
runner = RHC::CommandRunner.new(args)
|
29
32
|
Commander::Runner.instance_variable_set :@singleton, runner
|
30
33
|
|
31
|
-
program :name,
|
32
|
-
program :
|
33
|
-
program :
|
34
|
-
program :help_formatter, RHC::
|
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
|