rhc 1.6.8 → 1.7.8
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/autocomplete/rhc_bash +1167 -0
- data/features/README.md +1 -1
- data/features/domain.feature +1 -1
- data/features/lib/rhc_helper/persistable.rb +4 -1
- data/features/multiple_cartridge.feature +4 -3
- data/features/sshkey.feature +3 -3
- data/features/support/assumptions.rb +3 -3
- data/features/support/env.rb +10 -0
- data/features/support/platform_support.rb +2 -2
- data/lib/rhc.rb +6 -0
- data/lib/rhc/auth/token.rb +4 -0
- data/lib/rhc/autocomplete.rb +50 -52
- data/lib/rhc/autocomplete_templates/{rhc.erb → bash.erb} +8 -2
- data/lib/rhc/cartridge_helpers.rb +1 -1
- data/lib/rhc/cli.rb +1 -7
- data/lib/rhc/command_runner.rb +45 -16
- data/lib/rhc/commands.rb +75 -55
- data/lib/rhc/commands/account.rb +7 -51
- data/lib/rhc/commands/alias.rb +26 -17
- data/lib/rhc/commands/app.rb +75 -39
- data/lib/rhc/commands/authorization.rb +4 -2
- data/lib/rhc/commands/base.rb +31 -29
- data/lib/rhc/commands/cartridge.rb +66 -44
- data/lib/rhc/commands/domain.rb +20 -8
- data/lib/rhc/commands/git_clone.rb +3 -3
- data/lib/rhc/commands/logout.rb +51 -0
- data/lib/rhc/commands/port_forward.rb +15 -11
- data/lib/rhc/commands/setup.rb +25 -0
- data/lib/rhc/commands/snapshot.rb +20 -10
- data/lib/rhc/commands/sshkey.rb +21 -7
- data/lib/rhc/commands/tail.rb +2 -2
- data/lib/rhc/commands/threaddump.rb +2 -2
- data/lib/rhc/context_helper.rb +0 -4
- data/lib/rhc/core_ext.rb +96 -76
- data/lib/rhc/exceptions.rb +6 -0
- data/lib/rhc/help_formatter.rb +19 -2
- data/lib/rhc/helpers.rb +32 -194
- data/lib/rhc/highline_extensions.rb +412 -0
- data/lib/rhc/output_helpers.rb +31 -67
- data/lib/rhc/rest.rb +4 -2
- data/lib/rhc/rest/alias.rb +0 -2
- data/lib/rhc/rest/application.rb +9 -4
- data/lib/rhc/rest/authorization.rb +0 -2
- data/lib/rhc/rest/base.rb +1 -1
- data/lib/rhc/rest/client.rb +11 -9
- data/lib/rhc/rest/domain.rb +5 -1
- data/lib/rhc/rest/gear_group.rb +0 -2
- data/lib/rhc/rest/key.rb +0 -2
- data/lib/rhc/rest/mock.rb +32 -10
- data/lib/rhc/ssh_helpers.rb +2 -2
- data/lib/rhc/usage_templates/command_help.erb +20 -13
- data/lib/rhc/usage_templates/command_syntax_help.erb +1 -3
- data/lib/rhc/usage_templates/help.erb +15 -16
- data/lib/rhc/usage_templates/options_help.erb +7 -9
- data/lib/rhc/wizard.rb +193 -159
- data/spec/rest_spec_helper.rb +2 -2
- data/spec/rhc/cli_spec.rb +36 -5
- data/spec/rhc/command_spec.rb +94 -42
- data/spec/rhc/commands/account_spec.rb +1 -75
- data/spec/rhc/commands/alias_spec.rb +28 -28
- data/spec/rhc/commands/app_spec.rb +141 -33
- data/spec/rhc/commands/apps_spec.rb +4 -4
- data/spec/rhc/commands/authorization_spec.rb +8 -8
- data/spec/rhc/commands/cartridge_spec.rb +18 -9
- data/spec/rhc/commands/domain_spec.rb +16 -16
- data/spec/rhc/commands/git_clone_spec.rb +3 -3
- data/spec/rhc/commands/logout_spec.rb +86 -0
- data/spec/rhc/commands/port_forward_spec.rb +9 -9
- data/spec/rhc/commands/server_spec.rb +5 -5
- data/spec/rhc/commands/setup_spec.rb +19 -5
- data/spec/rhc/commands/snapshot_spec.rb +12 -12
- data/spec/rhc/commands/sshkey_spec.rb +11 -11
- data/spec/rhc/commands/tail_spec.rb +5 -5
- data/spec/rhc/commands/threaddump_spec.rb +3 -3
- data/spec/rhc/config_spec.rb +6 -6
- data/spec/rhc/helpers_spec.rb +72 -219
- data/spec/rhc/highline_extensions_spec.rb +269 -0
- data/spec/rhc/rest_application_spec.rb +28 -1
- data/spec/rhc/rest_client_spec.rb +20 -21
- data/spec/rhc/rest_spec.rb +10 -0
- data/spec/rhc/wizard_spec.rb +72 -32
- data/spec/spec_helper.rb +86 -56
- data/spec/wizard_spec_helper.rb +7 -4
- metadata +165 -160
- data/spec/spec.opts +0 -1
data/features/README.md
CHANGED
@@ -179,7 +179,7 @@ doesn't exist.
|
|
179
179
|
Given "a demo directory exists or is created" do
|
180
180
|
begin
|
181
181
|
Given "the demo directory exists"
|
182
|
-
rescue
|
182
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
183
183
|
Then "create the demo directory"
|
184
184
|
end
|
185
185
|
end
|
data/features/domain.feature
CHANGED
@@ -17,7 +17,7 @@ Feature: Existing Domain Operations
|
|
17
17
|
|
18
18
|
Scenario: Domain Create Fails
|
19
19
|
When rhc domain create is called
|
20
|
-
Then the domain command should fail with an exitcode of
|
20
|
+
Then the domain command should fail with an exitcode of 1
|
21
21
|
|
22
22
|
Scenario: Domain Delete
|
23
23
|
When domain is deleted
|
@@ -31,7 +31,10 @@ module RHCHelper
|
|
31
31
|
app.mysql_password = json['mysql_password']
|
32
32
|
app.mysql_hostname = json['mysql_hostname']
|
33
33
|
app.uid = json['uid']
|
34
|
-
|
34
|
+
# Strip off any version info for the type
|
35
|
+
app.type = app.type.split('-').first
|
36
|
+
|
37
|
+
app
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
@@ -8,11 +8,12 @@ Feature: Multiple Cartridge Tests
|
|
8
8
|
Then the phpmyadmin cartridge should be running
|
9
9
|
|
10
10
|
@not-origin
|
11
|
-
Scenario:
|
12
|
-
|
11
|
+
Scenario: Multiple DBs Allowed
|
12
|
+
When the postgresql cartridge is added
|
13
|
+
Then the postgresql cartridge should be running
|
13
14
|
|
14
15
|
Scenario: Cartridge Removed
|
15
16
|
When the phpmyadmin cartridge is removed
|
16
17
|
When the mysql cartridge is removed
|
17
18
|
Then the phpmyadmin cartridge should be removed
|
18
|
-
Then the mysql cartridge should be removed
|
19
|
+
Then the mysql cartridge should be removed
|
data/features/sshkey.feature
CHANGED
@@ -28,7 +28,7 @@ As an OpenShift user, I want to manage SSH keys with 'rhc sshkey' commands.
|
|
28
28
|
@sshkey_add
|
29
29
|
Scenario: invalid key name is given
|
30
30
|
When a new SSH key "key1.pub" is added as "blah\\ss"
|
31
|
-
Then the command exits with status code
|
31
|
+
Then the command exits with status code 1
|
32
32
|
|
33
33
|
@sshkey_add
|
34
34
|
Scenario: invalid SSH key is added
|
@@ -43,13 +43,13 @@ As an OpenShift user, I want to manage SSH keys with 'rhc sshkey' commands.
|
|
43
43
|
@sshkey_add @key1
|
44
44
|
Scenario: SSH key with the same name already exists
|
45
45
|
When a new SSH key "key2.pub" is added as "key1"
|
46
|
-
Then the command exits with status code
|
46
|
+
Then the command exits with status code 1
|
47
47
|
|
48
48
|
@sshkey_add
|
49
49
|
Scenario: SSH key with the identical content already exists
|
50
50
|
Given a new SSH key "key1.pub" is added as "key1"
|
51
51
|
And a new SSH key "key1.pub" is added as "key2"
|
52
|
-
Then the command exits with status code
|
52
|
+
Then the command exits with status code 1
|
53
53
|
|
54
54
|
@sshkey_remove @key1
|
55
55
|
Scenario: SSH key is deleted successfully
|
@@ -9,7 +9,7 @@ Given 'we have an existing domain' do
|
|
9
9
|
begin
|
10
10
|
step 'the key "key1" is shown'
|
11
11
|
step 'the output includes the key information for "key1"'
|
12
|
-
rescue
|
12
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
13
13
|
step 'a new SSH key "key1.pub" is added as "key1"'
|
14
14
|
end
|
15
15
|
end
|
@@ -27,7 +27,7 @@ Given /^we have a (.*) (.*) cartridge$/ do |status,type|
|
|
27
27
|
retried = false
|
28
28
|
begin
|
29
29
|
step "the #{type} cartridge should be #{status}"
|
30
|
-
rescue
|
30
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
31
31
|
step "the #{type} cartridge is #{cmd}"
|
32
32
|
(retried = true && retry) unless retried
|
33
33
|
end
|
@@ -43,7 +43,7 @@ Given /^we have a (stopped|running) application$/ do |state|
|
|
43
43
|
|
44
44
|
begin
|
45
45
|
step "the application should #{before}"
|
46
|
-
rescue
|
46
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
47
47
|
step "the application is #{after}"
|
48
48
|
end
|
49
49
|
end
|
data/features/support/env.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
$: << File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
|
2
2
|
|
3
|
+
begin
|
4
|
+
require 'rspec/expectations'
|
5
|
+
World(RSpec::Matchers)
|
6
|
+
rescue
|
7
|
+
puts "Require RSpec >= 2"
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
|
11
|
+
$target_os = ENV['RHC_TARGET'] || (File.exist?("/etc/fedora-release") ? "Fedora" : "RHEL")
|
12
|
+
|
3
13
|
require 'rhc/coverage_helper'
|
4
14
|
SimpleCov.at_exit{ SimpleCov.result.format! } if defined? SimpleCov
|
5
15
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
if
|
1
|
+
if $target_os == 'Fedora'
|
2
2
|
CARTRIDGE_MAP = {
|
3
3
|
"php" => { type: "php-5.4", name: "PHP 5.4" },
|
4
4
|
"mysql" => { type: "mysql-5.1", name: "MySQL Database 5.1" },
|
@@ -26,4 +26,4 @@ end
|
|
26
26
|
|
27
27
|
def map_cartridge_name(type)
|
28
28
|
CARTRIDGE_MAP[type][:name]
|
29
|
-
end
|
29
|
+
end
|
data/lib/rhc.rb
CHANGED
@@ -11,6 +11,7 @@ require 'pry' if ENV['PRY']
|
|
11
11
|
require 'rhc/core_ext'
|
12
12
|
|
13
13
|
module RHC
|
14
|
+
autoload :AutoComplete, 'rhc/autocomplete'
|
14
15
|
autoload :Auth, 'rhc/auth'
|
15
16
|
autoload :CartridgeHelpers, 'rhc/cartridge_helpers'
|
16
17
|
autoload :CommandRunner, 'rhc/command_runner'
|
@@ -27,3 +28,8 @@ end
|
|
27
28
|
|
28
29
|
require 'rhc/exceptions'
|
29
30
|
|
31
|
+
require 'commander'
|
32
|
+
require 'commander/delegates'
|
33
|
+
require 'highline/system_extensions'
|
34
|
+
|
35
|
+
require 'rhc/highline_extensions'
|
data/lib/rhc/auth/token.rb
CHANGED
@@ -16,8 +16,10 @@ module RHC::Auth
|
|
16
16
|
|
17
17
|
def to_request(request)
|
18
18
|
if token
|
19
|
+
debug "Using token authentication"
|
19
20
|
(request[:headers] ||= {})['authorization'] = "Bearer #{token}"
|
20
21
|
elsif auth and (!@allows_tokens or @can_get_token == false)
|
22
|
+
debug "Bypassing token auth"
|
21
23
|
auth.to_request(request)
|
22
24
|
end
|
23
25
|
request
|
@@ -56,6 +58,7 @@ module RHC::Auth
|
|
56
58
|
if has_token
|
57
59
|
raise RHC::Rest::TokenExpiredOrInvalid, "Your authorization token is expired or invalid."
|
58
60
|
end
|
61
|
+
debug "Cannot authenticate via token or password, exiting"
|
59
62
|
return false
|
60
63
|
end
|
61
64
|
|
@@ -78,6 +81,7 @@ module RHC::Auth
|
|
78
81
|
|
79
82
|
return auth.retry_auth?(response, client) unless @can_get_token
|
80
83
|
|
84
|
+
debug "Creating a new authorization token"
|
81
85
|
if auth_token = client.new_session(:auth => auth)
|
82
86
|
@fetch_once = true
|
83
87
|
save(auth_token.token)
|
data/lib/rhc/autocomplete.rb
CHANGED
@@ -1,68 +1,66 @@
|
|
1
|
-
require 'rhc'
|
2
|
-
require 'commander'
|
3
|
-
require 'commander/runner'
|
4
|
-
require 'commander/delegates'
|
5
|
-
require 'rhc/commands'
|
6
|
-
|
7
1
|
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
2
|
class AutoComplete
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@command_data = {}
|
22
|
-
@top_level_commands = []
|
23
|
-
@global_switches = []
|
24
|
-
Commander::Runner.instance.options.each { |o| @global_switches << o[:switches][-1] }
|
3
|
+
attr_reader :runner
|
4
|
+
|
5
|
+
def initialize(runner=::Commander::Runner.instance, shell='bash')
|
6
|
+
@runner, @shell = runner, shell
|
25
7
|
end
|
26
8
|
|
27
|
-
def
|
28
|
-
|
29
|
-
gen_script
|
9
|
+
def to_s
|
10
|
+
@s ||= template.result AutoCompleteBindings.new(self).get_binding
|
30
11
|
end
|
31
12
|
|
32
13
|
private
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
RHC::Commands.load.to_commander
|
14
|
+
|
15
|
+
def template
|
16
|
+
@template ||= ERB.new(File.read(File.join(File.dirname(__FILE__), 'autocomplete_templates', "#{@shell}.erb")), nil, '-')
|
37
17
|
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class AutoCompleteBindings
|
21
|
+
attr_reader :commands, :top_level_commands, :global_options
|
22
|
+
|
23
|
+
def initialize(data)
|
24
|
+
@commands = {}
|
25
|
+
@top_level_commands = []
|
38
26
|
|
39
|
-
|
40
|
-
|
41
|
-
|
27
|
+
data.runner.commands.each_pair do |name, cmd|
|
28
|
+
next if cmd.summary.nil?
|
29
|
+
next if cmd.deprecated(name)
|
42
30
|
|
43
|
-
|
31
|
+
if cmd.root?
|
32
|
+
if cmd.name == name
|
44
33
|
@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
34
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
35
|
+
else
|
36
|
+
@top_level_commands << name if name == cmd.name
|
37
|
+
commands = name.split ' '
|
38
|
+
action = commands.pop
|
39
|
+
id = commands.join(' ')
|
40
|
+
v = @commands[id] || {:actions => [], :switches => []}
|
41
|
+
v[:actions] << action unless id == '' && name != cmd.name
|
42
|
+
@commands[id] = v
|
61
43
|
end
|
62
|
-
end
|
63
44
|
|
64
|
-
|
65
|
-
|
45
|
+
v = @commands[name.to_s] || {:actions => [], :switches => []}
|
46
|
+
v[:switches].concat(cmd.options.map do |o|
|
47
|
+
if o[:switches]
|
48
|
+
s = o[:switches][-1].split(' ')[0]
|
49
|
+
if m = /--\[no-\](.+)/.match(s)
|
50
|
+
s = ["--#{m[1]}", "--no-#{m[1]}"]
|
51
|
+
else
|
52
|
+
s
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end.flatten.compact.sort)
|
56
|
+
@commands[name.to_s] = v
|
66
57
|
end
|
67
|
-
|
58
|
+
@commands.delete('')
|
59
|
+
@commands = @commands.to_a.sort{ |a,b| a[0] <=> b[0] }
|
60
|
+
|
61
|
+
@top_level_commands.sort!
|
62
|
+
|
63
|
+
@global_options = data.runner.options.map{ |o| o[:switches][-1].split(' ')[0] }.sort
|
64
|
+
end
|
65
|
+
end
|
68
66
|
end
|
@@ -7,13 +7,19 @@ _rhc()
|
|
7
7
|
COMPREPLY=()
|
8
8
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
9
9
|
if [ $COMP_CWORD -eq 1 ]; then
|
10
|
-
|
10
|
+
if [[ "$cur" == -* ]]; then
|
11
|
+
opts=<%= "\"%s\"" % global_options.join(' ') %>
|
12
|
+
elif [ -z $cur ]; then
|
13
|
+
opts=<%= "\"%s\"" % top_level_commands.join(' ') %>
|
14
|
+
else
|
15
|
+
opts=<%= "\"%s\"" % commands.map{ |c| c.first }.delete_if{ |s| s.include? ' ' }.sort.join(' ') %>
|
16
|
+
fi
|
11
17
|
else
|
12
18
|
prev="${COMP_WORDS[@]:0:COMP_CWORD}"
|
13
19
|
SAVE_IFS=$IFS
|
14
20
|
IFS=" "
|
15
21
|
case "${prev[*]}" in
|
16
|
-
<%- for name, data in
|
22
|
+
<%- for name, data in commands %>
|
17
23
|
<%= "\"rhc %s\")" % name %>
|
18
24
|
if [[ "$cur" == -* ]]; then
|
19
25
|
opts=<%= "\"%s\"" % data[:switches].join(" ") %>
|
@@ -92,7 +92,7 @@ module RHC
|
|
92
92
|
carts = cartridges.map{ |c| [c.name, c.display_name || ''] }.sort{ |a,b| a[1].downcase <=> b[1].downcase }
|
93
93
|
carts.unshift ['==========', '=========']
|
94
94
|
carts.unshift ['Short Name', 'Full name']
|
95
|
-
say table(carts)
|
95
|
+
say table(carts)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
data/lib/rhc/cli.rb
CHANGED
@@ -1,12 +1,6 @@
|
|
1
1
|
require 'rhc'
|
2
|
-
require 'commander'
|
3
|
-
require 'commander/runner'
|
4
|
-
require 'commander/delegates'
|
5
2
|
require 'rhc/commands'
|
6
3
|
|
7
|
-
include Commander::UI
|
8
|
-
include Commander::UI::AskForClass
|
9
|
-
|
10
4
|
module RHC
|
11
5
|
#
|
12
6
|
# Run and execute a command line session with the RHC tools.
|
@@ -21,7 +15,7 @@ module RHC
|
|
21
15
|
|
22
16
|
def self.set_terminal
|
23
17
|
$terminal.wrap_at = HighLine::SystemExtensions.terminal_size.first rescue 80 if $stdin.tty?
|
24
|
-
|
18
|
+
#$terminal.page_at = :auto if $stdin.tty? and $stdout.tty?
|
25
19
|
# FIXME: ANSI terminals are not default on windows but we may just be
|
26
20
|
# hitting a bug in highline if windows does support another method.
|
27
21
|
# This is a safe fix for now but needs more research.
|
data/lib/rhc/command_runner.rb
CHANGED
@@ -35,7 +35,7 @@ module RHC
|
|
35
35
|
if (@args & HELP_OPTIONS).present?
|
36
36
|
args = (@args -= HELP_OPTIONS)
|
37
37
|
args.shift if args.first == 'help' && !command_exists?(args.join(' '))
|
38
|
-
exit run_help(args
|
38
|
+
exit run_help(args)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -69,14 +69,8 @@ module RHC
|
|
69
69
|
begin
|
70
70
|
run_active_command
|
71
71
|
rescue InvalidCommandError => e
|
72
|
-
|
73
|
-
|
74
|
-
say RHC::HelpFormatter.new(self).render
|
75
|
-
else
|
76
|
-
RHC::Helpers.error "The command '#{program :name} #{provided_arguments.join(' ')}' is not recognized.\n"
|
77
|
-
say "See '#{program :name} help' for a list of valid commands."
|
78
|
-
end
|
79
|
-
1
|
72
|
+
return RHC::Wizard.new.run unless RHC::Wizard.has_configuration? || provided_arguments.present?
|
73
|
+
run_help(provided_arguments)
|
80
74
|
rescue \
|
81
75
|
OptionParser::InvalidOption => e
|
82
76
|
RHC::Helpers.error e.message
|
@@ -107,7 +101,7 @@ module RHC
|
|
107
101
|
end
|
108
102
|
|
109
103
|
def provided_arguments
|
110
|
-
@args[0, @args.find_index { |arg| arg.start_with?('-') } || @args.length]
|
104
|
+
@args[0, @args.find_index { |arg| arg != '--' and arg.start_with?('-') } || @args.length]
|
111
105
|
end
|
112
106
|
|
113
107
|
def global_option(*args, &block)
|
@@ -122,6 +116,7 @@ module RHC
|
|
122
116
|
c.description = "Display all global options and information about configuration"
|
123
117
|
c.when_called do |args, options|
|
124
118
|
say help_formatter.render_options self
|
119
|
+
0
|
125
120
|
end
|
126
121
|
end
|
127
122
|
command :help do |c|
|
@@ -131,17 +126,51 @@ module RHC
|
|
131
126
|
end
|
132
127
|
end
|
133
128
|
|
134
|
-
def run_help(args, options)
|
135
|
-
|
129
|
+
def run_help(args=[], options=nil)
|
130
|
+
args.delete_if{ |a| a.start_with? '-' }
|
131
|
+
unless args[0] == 'commands'
|
132
|
+
variations = (1..args.length).reverse_each.map{ |n| args[0,n].join('-') }
|
133
|
+
cmd = variations.first(1).find{ |cmd| command_exists?(cmd) }
|
134
|
+
end
|
136
135
|
|
137
136
|
if args.empty?
|
138
137
|
say help_formatter.render
|
139
138
|
0
|
140
|
-
elsif cmd.nil?
|
141
|
-
RHC::Helpers.error "The command '#{program :name} #{provided_arguments.join(' ')}' is not recognized.\n"
|
142
|
-
say "See '#{program :name} help' for a list of valid commands."
|
143
|
-
1
|
144
139
|
else
|
140
|
+
if cmd.nil?
|
141
|
+
matches = (variations || ['']).inject(nil) do |candidates, term|
|
142
|
+
prefix = commands.keys.select{ |n| n.downcase.start_with? term.downcase }
|
143
|
+
inline = commands.keys.select{ |n| n.downcase.include? term.downcase }
|
144
|
+
break [term, prefix, inline - prefix] unless prefix.empty? && inline.empty?
|
145
|
+
end
|
146
|
+
|
147
|
+
unless matches
|
148
|
+
RHC::Helpers.error "The command '#{program :name} #{provided_arguments.join(' ')}' is not recognized.\n"
|
149
|
+
say "See '#{program :name} help' for a list of valid commands."
|
150
|
+
return 1
|
151
|
+
end
|
152
|
+
|
153
|
+
candidates = (matches[1] + matches[2]).map{ |n| commands[n] }.uniq.sort_by{ |c| c.name }.reverse
|
154
|
+
if candidates.length == 1
|
155
|
+
cmd = candidates.first.name
|
156
|
+
else
|
157
|
+
RHC::Helpers.pager
|
158
|
+
RHC::Helpers.say matches[0] != '' ? "Showing commands matching '#{matches[0]}'" : "Showing all commands"
|
159
|
+
candidates.reverse.each do |command|
|
160
|
+
RHC::Helpers.paragraph do
|
161
|
+
aliases = (commands.map{ |(k,v)| k if command == v }.compact - [command.name]).map{ |s| "'#{s}'"}
|
162
|
+
aliases[0] = "(also #{aliases[0]}" if aliases[0]
|
163
|
+
aliases[-1] << ')' if aliases[0]
|
164
|
+
|
165
|
+
RHC::Helpers.header [RHC::Helpers.color(command.name, :cyan), *aliases.join(', ')]
|
166
|
+
say command.description || command.summary
|
167
|
+
end
|
168
|
+
end
|
169
|
+
return 1
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
RHC::Helpers.pager
|
145
174
|
command = command(cmd)
|
146
175
|
help_bindings = CommandHelpBindings.new command, commands, self
|
147
176
|
say help_formatter.render_command help_bindings
|
data/lib/rhc/commands.rb
CHANGED
@@ -5,10 +5,19 @@ require 'commander/command'
|
|
5
5
|
# to avoid conflicts and side effects of similar short switches
|
6
6
|
module Commander
|
7
7
|
class Command
|
8
|
-
attr_accessor :default_action
|
8
|
+
attr_accessor :default_action, :root, :info
|
9
9
|
def default_action?
|
10
10
|
default_action.present?
|
11
11
|
end
|
12
|
+
def root?
|
13
|
+
root.present?
|
14
|
+
end
|
15
|
+
|
16
|
+
def deprecated(as_alias=nil)
|
17
|
+
return false unless info
|
18
|
+
return info[:deprecated] if info[:deprecated]
|
19
|
+
info[:aliases].select{ |a| ['-',' '].map{ |s| Array(a[:action]).join(s) }.include?(as_alias) }.map{ |a| a[:deprecated] }.first if as_alias
|
20
|
+
end
|
12
21
|
|
13
22
|
def parse_options_and_call_procs *args
|
14
23
|
runner = Commander::Runner.instance
|
@@ -25,7 +34,11 @@ module Commander
|
|
25
34
|
opts
|
26
35
|
end
|
27
36
|
|
28
|
-
|
37
|
+
# Separate option lists with '--'
|
38
|
+
remaining = args.split('--').map{ |a| opts.parse!(a) }.inject([]) do |arr, sub|
|
39
|
+
arr << '--' unless arr.empty?
|
40
|
+
arr.concat(sub)
|
41
|
+
end
|
29
42
|
|
30
43
|
_, config_path = proxy_options.find{ |arg| arg[0] == :config }
|
31
44
|
clean, _ = proxy_options.find{ |arg| arg[0] == :clean }
|
@@ -134,12 +147,12 @@ module RHC
|
|
134
147
|
global_options << [args.freeze, block]
|
135
148
|
end
|
136
149
|
|
137
|
-
def self.deprecated
|
138
|
-
|
139
|
-
|
150
|
+
def self.deprecated!
|
151
|
+
instance = Commander::Runner.instance
|
152
|
+
command_name = instance.command_name_from_args
|
153
|
+
command = instance.active_command
|
140
154
|
|
141
|
-
new_cmd = deprecated
|
142
|
-
if new_cmd
|
155
|
+
if new_cmd = command.deprecated(command_name)
|
143
156
|
new_cmd = "rhc #{command.name}" if new_cmd == true
|
144
157
|
RHC::Helpers.deprecated_command new_cmd
|
145
158
|
end
|
@@ -152,9 +165,7 @@ module RHC
|
|
152
165
|
config.has_local_config? or
|
153
166
|
config.has_opts_config?)
|
154
167
|
|
155
|
-
RHC::Helpers.
|
156
|
-
"You have not yet configured the OpenShift client tools. Please run 'rhc setup'.",
|
157
|
-
:stderr => true)
|
168
|
+
$stderr.puts RHC::Helpers.color("You have not yet configured the OpenShift client tools. Please run 'rhc setup'.", :yellow)
|
158
169
|
end
|
159
170
|
end
|
160
171
|
|
@@ -166,47 +177,48 @@ module RHC
|
|
166
177
|
option.merge!(opts)
|
167
178
|
end
|
168
179
|
commands.each_pair do |name, opts|
|
180
|
+
name = Array(name)
|
181
|
+
names = [name.reverse.join('-'), name.join(' ')] if name.length > 1
|
182
|
+
name = name.join('-')
|
183
|
+
|
169
184
|
instance.command name do |c|
|
170
185
|
c.description = opts[:description]
|
171
186
|
c.summary = opts[:summary]
|
172
187
|
c.syntax = opts[:syntax]
|
173
188
|
c.default_action = opts[:default]
|
174
189
|
|
175
|
-
|
190
|
+
c.info = opts
|
191
|
+
|
192
|
+
(options_metadata = Array(opts[:options])).each do |o|
|
176
193
|
option_data = [o[:switches], o[:description]].flatten(1)
|
177
194
|
c.option *option_data
|
178
195
|
o[:arg] = Commander::Runner.switch_to_sym(Array(o[:switches]).last)
|
179
196
|
end
|
180
197
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
unless arg_switches.nil? or arg_switches.empty?
|
187
|
-
arg_switches << arg_meta[:description]
|
188
|
-
c.option *arg_switches
|
198
|
+
(args_metadata = Array(opts[:args])).each do |meta|
|
199
|
+
switches = meta[:switches]
|
200
|
+
unless switches.nil? or switches.empty?
|
201
|
+
switches << meta[:description]
|
202
|
+
c.option *switches
|
189
203
|
end
|
190
204
|
end
|
191
205
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
# prepend the current resource
|
198
|
-
alias_components = name.split(" ")
|
199
|
-
alias_components[-1] = a[:action]
|
200
|
-
alias_cmd = alias_components.join(' ').to_sym
|
201
|
-
end
|
202
|
-
|
203
|
-
deprecated[alias_cmd] = true if a[:deprecated]
|
204
|
-
instance.alias_command "#{alias_cmd}", :"#{name}"
|
206
|
+
Array(opts[:aliases]).each do |a|
|
207
|
+
action = Array(a[:action])
|
208
|
+
[' ', '-'].each do |s|
|
209
|
+
cmd = action.join(s)
|
210
|
+
instance.alias_command cmd, name
|
205
211
|
end
|
206
212
|
end
|
207
213
|
|
214
|
+
if names
|
215
|
+
names.each{ |alt| instance.alias_command alt, name }
|
216
|
+
else
|
217
|
+
c.root = true
|
218
|
+
end
|
219
|
+
|
208
220
|
c.when_called do |args, options|
|
209
|
-
deprecated
|
221
|
+
deprecated!
|
210
222
|
|
211
223
|
config = c.instance_variable_get(:@config)
|
212
224
|
|
@@ -232,7 +244,7 @@ module RHC
|
|
232
244
|
Commander::Runner.instance.options.each do |opt|
|
233
245
|
if opt[:context]
|
234
246
|
arg = Commander::Runner.switch_to_sym(opt[:switches].last)
|
235
|
-
options[arg] ||= lambda{ cmd.send(opt[:context]) }
|
247
|
+
options.__hash__[arg] ||= lambda{ cmd.send(opt[:context]) }
|
236
248
|
end
|
237
249
|
end
|
238
250
|
|
@@ -258,32 +270,43 @@ module RHC
|
|
258
270
|
end
|
259
271
|
raise ArgumentError.new("Missing required option '#{arg}'.") if option_meta[:required] && options[arg].nil?
|
260
272
|
end
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
args_metadata.each_with_index do |
|
265
|
-
|
266
|
-
|
267
|
-
context_helper = arg_meta[:context_helper]
|
273
|
+
|
274
|
+
available = args.dup
|
275
|
+
slots = Array.new(args_metadata.length)
|
276
|
+
args_metadata.each_with_index do |arg, i|
|
277
|
+
option = arg[:option_symbol]
|
278
|
+
context_helper = arg[:context_helper]
|
268
279
|
|
269
280
|
value = options.__hash__[option] if option
|
270
|
-
|
281
|
+
|
282
|
+
if value.nil?
|
283
|
+
value =
|
284
|
+
if arg[:arg_type] == :list
|
285
|
+
all = []
|
286
|
+
while available.first && available.first != '--'
|
287
|
+
all << available.shift
|
288
|
+
end
|
289
|
+
available.shift if available.first == '--'
|
290
|
+
all
|
291
|
+
else
|
292
|
+
available.shift
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
271
296
|
value = cmd.send(context_helper) if value.nil? and context_helper
|
272
297
|
|
273
|
-
if
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
298
|
+
if value.nil?
|
299
|
+
raise ArgumentError, "Missing required argument '#{arg[:name]}'." unless arg[:optional]
|
300
|
+
break if available.empty?
|
301
|
+
else
|
302
|
+
slots[i] = value
|
303
|
+
options.__hash__[option] = value if option
|
279
304
|
end
|
280
|
-
arg_slots[i] = value
|
281
|
-
options.__hash__[option] = value if option
|
282
305
|
end
|
283
306
|
|
284
|
-
raise ArgumentError
|
307
|
+
raise ArgumentError, "Too many arguments passed in: #{available.reverse.join(" ")}" unless available.empty?
|
285
308
|
|
286
|
-
|
309
|
+
slots
|
287
310
|
end
|
288
311
|
|
289
312
|
def self.commands
|
@@ -292,8 +315,5 @@ module RHC
|
|
292
315
|
def self.global_options
|
293
316
|
@options ||= []
|
294
317
|
end
|
295
|
-
def self.deprecated
|
296
|
-
@deprecated ||= {}
|
297
|
-
end
|
298
318
|
end
|
299
319
|
end
|