morpheus-cli 2.10.0 → 2.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/morpheus +27 -32
- data/lib/morpheus/api/accounts_interface.rb +36 -47
- data/lib/morpheus/api/api_client.rb +141 -110
- data/lib/morpheus/api/app_templates_interface.rb +56 -72
- data/lib/morpheus/api/apps_interface.rb +111 -132
- data/lib/morpheus/api/auth_interface.rb +30 -0
- data/lib/morpheus/api/clouds_interface.rb +71 -76
- data/lib/morpheus/api/custom_instance_types_interface.rb +21 -46
- data/lib/morpheus/api/dashboard_interface.rb +10 -17
- data/lib/morpheus/api/deploy_interface.rb +60 -72
- data/lib/morpheus/api/deployments_interface.rb +53 -71
- data/lib/morpheus/api/groups_interface.rb +55 -45
- data/lib/morpheus/api/instance_types_interface.rb +19 -23
- data/lib/morpheus/api/instances_interface.rb +179 -177
- data/lib/morpheus/api/key_pairs_interface.rb +11 -17
- data/lib/morpheus/api/license_interface.rb +18 -23
- data/lib/morpheus/api/load_balancers_interface.rb +54 -69
- data/lib/morpheus/api/logs_interface.rb +25 -29
- data/lib/morpheus/api/options_interface.rb +13 -17
- data/lib/morpheus/api/provision_types_interface.rb +19 -22
- data/lib/morpheus/api/roles_interface.rb +75 -94
- data/lib/morpheus/api/security_group_rules_interface.rb +28 -37
- data/lib/morpheus/api/security_groups_interface.rb +39 -51
- data/lib/morpheus/api/servers_interface.rb +113 -115
- data/lib/morpheus/api/setup_interface.rb +31 -0
- data/lib/morpheus/api/task_sets_interface.rb +36 -38
- data/lib/morpheus/api/tasks_interface.rb +56 -69
- data/lib/morpheus/api/users_interface.rb +67 -76
- data/lib/morpheus/api/virtual_images_interface.rb +61 -61
- data/lib/morpheus/api/whoami_interface.rb +12 -15
- data/lib/morpheus/cli.rb +71 -60
- data/lib/morpheus/cli/accounts.rb +254 -315
- data/lib/morpheus/cli/alias_command.rb +219 -0
- data/lib/morpheus/cli/app_templates.rb +264 -272
- data/lib/morpheus/cli/apps.rb +608 -671
- data/lib/morpheus/cli/cli_command.rb +259 -21
- data/lib/morpheus/cli/cli_registry.rb +99 -14
- data/lib/morpheus/cli/clouds.rb +599 -372
- data/lib/morpheus/cli/config_file.rb +126 -0
- data/lib/morpheus/cli/credentials.rb +141 -117
- data/lib/morpheus/cli/dashboard_command.rb +48 -56
- data/lib/morpheus/cli/deployments.rb +254 -268
- data/lib/morpheus/cli/deploys.rb +150 -142
- data/lib/morpheus/cli/error_handler.rb +38 -0
- data/lib/morpheus/cli/groups.rb +551 -179
- data/lib/morpheus/cli/hosts.rb +862 -617
- data/lib/morpheus/cli/instance_types.rb +103 -95
- data/lib/morpheus/cli/instances.rb +1335 -1009
- data/lib/morpheus/cli/key_pairs.rb +82 -90
- data/lib/morpheus/cli/library.rb +498 -499
- data/lib/morpheus/cli/license.rb +83 -101
- data/lib/morpheus/cli/load_balancers.rb +314 -300
- data/lib/morpheus/cli/login.rb +66 -44
- data/lib/morpheus/cli/logout.rb +47 -46
- data/lib/morpheus/cli/mixins/accounts_helper.rb +69 -31
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +106 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +181 -17
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +535 -458
- data/lib/morpheus/cli/mixins/whoami_helper.rb +2 -2
- data/lib/morpheus/cli/option_parser.rb +35 -0
- data/lib/morpheus/cli/option_types.rb +232 -192
- data/lib/morpheus/cli/recent_activity_command.rb +61 -65
- data/lib/morpheus/cli/remote.rb +446 -199
- data/lib/morpheus/cli/roles.rb +884 -906
- data/lib/morpheus/cli/security_group_rules.rb +213 -203
- data/lib/morpheus/cli/security_groups.rb +237 -192
- data/lib/morpheus/cli/shell.rb +338 -231
- data/lib/morpheus/cli/tasks.rb +326 -308
- data/lib/morpheus/cli/users.rb +457 -462
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/version_command.rb +16 -18
- data/lib/morpheus/cli/virtual_images.rb +526 -345
- data/lib/morpheus/cli/whoami.rb +125 -111
- data/lib/morpheus/cli/workflows.rb +338 -185
- data/lib/morpheus/formatters.rb +8 -1
- data/lib/morpheus/logging.rb +1 -1
- data/lib/morpheus/rest_client.rb +17 -8
- metadata +9 -3
- data/lib/morpheus/api/custom_instance_types.rb +0 -55
@@ -1,5 +1,9 @@
|
|
1
|
+
require 'morpheus/cli/option_parser'
|
1
2
|
require 'morpheus/cli/cli_registry'
|
2
3
|
require 'morpheus/cli/mixins/print_helper'
|
4
|
+
require 'morpheus/cli/credentials'
|
5
|
+
require 'morpheus/api/api_client'
|
6
|
+
require 'morpheus/cli/remote'
|
3
7
|
|
4
8
|
module Morpheus
|
5
9
|
module Cli
|
@@ -7,9 +11,9 @@ module Morpheus
|
|
7
11
|
module CliCommand
|
8
12
|
|
9
13
|
def self.included(klass)
|
10
|
-
Morpheus::Cli::CliRegistry.add(klass)
|
11
14
|
klass.send :include, Morpheus::Cli::PrintHelper
|
12
15
|
klass.extend ClassMethods
|
16
|
+
Morpheus::Cli::CliRegistry.add(klass, klass.command_name)
|
13
17
|
end
|
14
18
|
|
15
19
|
def build_common_options(opts, options, includes=[])
|
@@ -26,9 +30,10 @@ module Morpheus
|
|
26
30
|
end
|
27
31
|
|
28
32
|
when :options
|
29
|
-
|
33
|
+
options[:options] ||= {}
|
34
|
+
opts.on( '-O', '--option OPTION', "Option in the format var=\"value\"" ) do |option|
|
30
35
|
custom_option_args = option.split('=')
|
31
|
-
custom_options = options[:options]
|
36
|
+
custom_options = options[:options]
|
32
37
|
option_name_args = custom_option_args[0].split('.')
|
33
38
|
if option_name_args.count > 1
|
34
39
|
nested_options = custom_options
|
@@ -43,7 +48,6 @@ module Morpheus
|
|
43
48
|
else
|
44
49
|
custom_options[custom_option_args[0]] = custom_option_args[1]
|
45
50
|
end
|
46
|
-
|
47
51
|
options[:options] = custom_options
|
48
52
|
end
|
49
53
|
opts.on('-N','--no-prompt', "Skip prompts. Use default values for all optional fields.") do |val|
|
@@ -52,8 +56,8 @@ module Morpheus
|
|
52
56
|
options[:options] ||= {}
|
53
57
|
options[:options][:no_prompt] = true
|
54
58
|
end
|
59
|
+
|
55
60
|
when :list
|
56
|
-
|
57
61
|
opts.on( '-m', '--max MAX', "Max Results" ) do |max|
|
58
62
|
options[:max] = max.to_i
|
59
63
|
end
|
@@ -75,10 +79,26 @@ module Morpheus
|
|
75
79
|
end
|
76
80
|
|
77
81
|
when :remote
|
78
|
-
|
79
|
-
|
82
|
+
|
83
|
+
# this is the only option now...
|
84
|
+
# first, you must do `remote use [appliance]`
|
85
|
+
opts.on( '-r', '--remote REMOTE', "Remote Appliance Name to use for this command. The active appliance is used by default." ) do |val|
|
86
|
+
options[:remote] = val
|
87
|
+
end
|
88
|
+
|
89
|
+
# todo: also require this for talking to plain old HTTP
|
90
|
+
opts.on('-I','--insecure', "Allow for insecure HTTPS communication i.e. bad SSL certificate") do |val|
|
91
|
+
Morpheus::RestClient.enable_ssl_verification = false
|
80
92
|
end
|
81
93
|
|
94
|
+
# skipping the rest of this for now..
|
95
|
+
|
96
|
+
next
|
97
|
+
|
98
|
+
# opts.on( '-r', '--remote REMOTE', "Remote Appliance" ) do |remote|
|
99
|
+
# options[:remote] = remote
|
100
|
+
# end
|
101
|
+
|
82
102
|
opts.on( '-U', '--url REMOTE', "API Url" ) do |remote|
|
83
103
|
options[:remote_url] = remote
|
84
104
|
end
|
@@ -94,36 +114,39 @@ module Morpheus
|
|
94
114
|
opts.on( '-T', '--token ACCESS_TOKEN', "Access Token" ) do |remote|
|
95
115
|
options[:remote_token] = remote
|
96
116
|
end
|
97
|
-
|
98
|
-
when :auto_confirm
|
117
|
+
when :auto_confirm
|
99
118
|
opts.on( '-y', '--yes', "Auto Confirm" ) do
|
100
119
|
options[:yes] = true
|
101
120
|
end
|
102
|
-
|
103
|
-
when :json
|
121
|
+
when :json
|
104
122
|
opts.on('-j','--json', "JSON Output") do |json|
|
105
123
|
options[:json] = true
|
106
124
|
end
|
107
125
|
|
108
126
|
when :dry_run
|
109
|
-
opts.on('-d','--dry-run', "Dry Run, print
|
127
|
+
opts.on('-d','--dry-run', "Dry Run, print the API request instead of executing it") do |json|
|
110
128
|
options[:dry_run] = true
|
111
129
|
end
|
112
|
-
|
130
|
+
when :quiet
|
131
|
+
opts.on('-q','--quiet', "No Output, when successful") do |json|
|
132
|
+
options[:quiet] = true
|
133
|
+
end
|
134
|
+
|
113
135
|
else
|
114
136
|
raise "Unknown common_option key: #{option_key}"
|
115
137
|
end
|
116
138
|
end
|
117
139
|
|
118
140
|
# options that are always included
|
119
|
-
|
141
|
+
|
142
|
+
# disable ANSI coloring
|
143
|
+
opts.on('-C','--nocolor', "Disable ANSI coloring") do
|
120
144
|
Term::ANSIColor::coloring = false
|
121
145
|
end
|
122
146
|
|
123
147
|
opts.on('-V','--debug', "Print extra output for debugging. ") do |json|
|
124
148
|
options[:debug] = true
|
125
|
-
|
126
|
-
# Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
149
|
+
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
127
150
|
# perhaps...
|
128
151
|
# create a new logger instance just for this command instance
|
129
152
|
# this way we don't elevate the global level for subsequent commands in a shell
|
@@ -132,21 +155,166 @@ module Morpheus
|
|
132
155
|
# @logger.log_level = Morpheus::Logging::Logger::DEBUG
|
133
156
|
# end
|
134
157
|
end
|
135
|
-
|
158
|
+
|
136
159
|
opts.on('-h', '--help', "Prints this help" ) do
|
137
160
|
puts opts
|
138
161
|
exit
|
139
162
|
end
|
140
163
|
|
141
164
|
end
|
142
|
-
|
165
|
+
|
166
|
+
def command_name
|
167
|
+
self.class.command_name
|
168
|
+
end
|
169
|
+
|
170
|
+
def subcommands
|
171
|
+
self.class.subcommands
|
172
|
+
end
|
173
|
+
|
174
|
+
def subcommand_aliases
|
175
|
+
self.class.subcommand_aliases
|
176
|
+
end
|
177
|
+
|
178
|
+
def default_subcommand
|
179
|
+
self.class.default_subcommand
|
180
|
+
end
|
181
|
+
|
182
|
+
def usage
|
183
|
+
if !subcommands.empty?
|
184
|
+
"Usage: morpheus #{command_name} [command] [options]"
|
185
|
+
else
|
186
|
+
"Usage: morpheus #{command_name} [options]"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def subcommand_usage(*extra)
|
191
|
+
calling_method = caller[0][/`([^']*)'/, 1].to_s.sub('block in ', '')
|
192
|
+
subcommand_name = subcommands.key(calling_method)
|
193
|
+
extra = extra.flatten
|
194
|
+
if !subcommand_name.empty? && extra.first == subcommand_name
|
195
|
+
extra.shift
|
196
|
+
end
|
197
|
+
#extra = ["[options]"] if extra.empty?
|
198
|
+
"Usage: morpheus #{command_name} #{subcommand_name} #{extra.join(' ')}".squeeze(' ').strip
|
199
|
+
end
|
200
|
+
|
201
|
+
def print_usage()
|
202
|
+
puts usage
|
203
|
+
if !subcommands.empty?
|
204
|
+
puts "Commands:"
|
205
|
+
subcommands.sort.each {|cmd, method|
|
206
|
+
puts "\t#{cmd.to_s}"
|
207
|
+
}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# a default handler
|
212
|
+
def handle_subcommand(args)
|
213
|
+
commands = subcommands
|
214
|
+
if subcommands.empty?
|
215
|
+
raise "#{self.class} has no available subcommands"
|
216
|
+
end
|
217
|
+
# meh, could deprecate and make subcommand define handle() itself
|
218
|
+
if args.count == 0 && default_subcommand
|
219
|
+
# p "using default subcommand #{default_subcommand}"
|
220
|
+
return self.send(default_subcommand, args || [])
|
221
|
+
end
|
222
|
+
cmd_name = args[0]
|
223
|
+
if subcommand_aliases[cmd_name]
|
224
|
+
cmd_name = subcommand_aliases[cmd_name]
|
225
|
+
end
|
226
|
+
cmd_method = subcommands[cmd_name]
|
227
|
+
if cmd_name && !cmd_method
|
228
|
+
#puts "unknown command '#{cmd_name}'"
|
229
|
+
end
|
230
|
+
if !cmd_method
|
231
|
+
print_usage
|
232
|
+
exit 127
|
233
|
+
end
|
234
|
+
self.send(cmd_method, args[1..-1])
|
235
|
+
end
|
236
|
+
|
237
|
+
def handle(args)
|
238
|
+
raise "#{self} has not defined handle()!"
|
239
|
+
end
|
240
|
+
|
241
|
+
# This supports the simple remote option eg. `instances add --remote "qa"`
|
242
|
+
# It will establish a connection to the pre-configured appliance named "qa"
|
243
|
+
# The calling command needs to populate @appliances and/or @appliance_name
|
244
|
+
# This returns a new instance of Morpheus::APIClient (and sets @access_token, and @appliance)
|
245
|
+
# Your command should be ready to make api requests after this.
|
246
|
+
# todo: probably don't exit here, just return nil or raise
|
247
|
+
def establish_remote_appliance_connection(options)
|
248
|
+
@appliances ||= ::Morpheus::Cli::Remote.appliances
|
249
|
+
if !@appliance_name
|
250
|
+
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
251
|
+
end
|
252
|
+
|
253
|
+
# todo: support old way of accepting --username and --password on the command line
|
254
|
+
# it's probably better not to do that tho, just so it stays out of history files
|
255
|
+
|
256
|
+
# use a specific remote appliance by name
|
257
|
+
if options[:remote]
|
258
|
+
@appliance_name = options[:remote].to_sym rescue nil
|
259
|
+
if !@appliances
|
260
|
+
print_red_alert "You have no appliances configured. See the `remote add` command."
|
261
|
+
exit 1
|
262
|
+
end
|
263
|
+
found_appliance = @appliances[@appliance_name.to_sym]
|
264
|
+
if !found_appliance
|
265
|
+
print_red_alert "You have no appliance named '#{@appliance_name}' configured. See the `remote add` command."
|
266
|
+
exit 1
|
267
|
+
end
|
268
|
+
@appliance = found_appliance
|
269
|
+
@appliance_name = @appliance_name
|
270
|
+
@appliance_url = @appliance[:host]
|
271
|
+
if options[:debug]
|
272
|
+
print dark,"# => Using remote appliance [#{@appliance_name}] #{@appliance_url}",reset,"\n" if !options[:quiet]
|
273
|
+
end
|
274
|
+
else
|
275
|
+
#@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
276
|
+
end
|
277
|
+
|
278
|
+
if !@appliance_name
|
279
|
+
print_red_alert "You must specify a remote appliance with --remote, or see the `remote use` command."
|
280
|
+
exit 1
|
281
|
+
end
|
282
|
+
|
283
|
+
puts "#{dark} #=> establishing connection to [#{@appliance_name}] #{@appliance_url}#{reset}\n" if options[:debug]
|
284
|
+
|
285
|
+
# ok, get some credentials.
|
286
|
+
# this prompts for username, password without options[:no_prompt]
|
287
|
+
@access_token = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).request_credentials(options)
|
288
|
+
|
289
|
+
# bail if we got nothing
|
290
|
+
if @access_token.empty?
|
291
|
+
print_red_alert "Invalid Credentials. Unable to acquire access token. Please verify your credentials and try again."
|
292
|
+
exit 1
|
293
|
+
end
|
294
|
+
|
295
|
+
# ok, connect to the appliance.. actually this just instantiates an ApiClient
|
296
|
+
# setup our api client for all including commands to use.
|
297
|
+
@api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
|
298
|
+
return @api_client
|
299
|
+
end
|
143
300
|
|
144
301
|
module ClassMethods
|
145
|
-
|
146
|
-
|
302
|
+
|
303
|
+
def set_command_name(cmd_name)
|
304
|
+
@command_name = cmd_name
|
305
|
+
Morpheus::Cli::CliRegistry.add(self, self.command_name)
|
306
|
+
end
|
307
|
+
|
308
|
+
def default_command_name
|
309
|
+
Morpheus::Cli::CliRegistry.cli_ize(self.name.split('::')[-1])
|
310
|
+
end
|
311
|
+
|
312
|
+
def command_name
|
313
|
+
@command_name ||= default_command_name
|
314
|
+
@command_name
|
147
315
|
end
|
148
316
|
|
149
|
-
def
|
317
|
+
def set_command_hidden(val=true)
|
150
318
|
@hidden_command = val
|
151
319
|
end
|
152
320
|
|
@@ -154,6 +322,76 @@ module Morpheus
|
|
154
322
|
!!@hidden_command
|
155
323
|
end
|
156
324
|
|
325
|
+
# construct map of command name => instance method
|
326
|
+
def register_subcommands(*cmds)
|
327
|
+
@subcommands ||= {}
|
328
|
+
cmds.flatten.each {|cmd|
|
329
|
+
if cmd.is_a?(Hash)
|
330
|
+
cmd.each {|k,v|
|
331
|
+
# @subcommands[k] = v
|
332
|
+
add_subcommand(k.to_s, v.to_s)
|
333
|
+
}
|
334
|
+
elsif cmd.is_a?(Array)
|
335
|
+
cmd.each {|it| register_subcommands(it) }
|
336
|
+
elsif cmd.is_a?(String) || cmd.is_a?(Symbol)
|
337
|
+
#k = Morpheus::Cli::CliRegistry.cli_ize(cmd)
|
338
|
+
k = cmd.to_s.gsub('_', '-')
|
339
|
+
v = cmd.to_s.gsub('-', '_')
|
340
|
+
register_subcommands({(k) => v})
|
341
|
+
else
|
342
|
+
raise "Unable to register command of type: #{cmd.class} #{cmd}"
|
343
|
+
end
|
344
|
+
}
|
345
|
+
return
|
346
|
+
end
|
347
|
+
|
348
|
+
def set_default_subcommand(cmd)
|
349
|
+
@default_subcommand = cmd
|
350
|
+
end
|
351
|
+
|
352
|
+
def default_subcommand
|
353
|
+
@default_subcommand
|
354
|
+
end
|
355
|
+
|
356
|
+
def subcommands
|
357
|
+
@subcommands ||= {}
|
358
|
+
end
|
359
|
+
|
360
|
+
def has_subcommand?(cmd_name)
|
361
|
+
return false if cmd_name.empty?
|
362
|
+
@subcommands && @subcommands[cmd_name.to_s]
|
363
|
+
end
|
364
|
+
|
365
|
+
def add_subcommand(cmd_name, method)
|
366
|
+
@subcommands ||= {}
|
367
|
+
@subcommands[cmd_name.to_s] = method
|
368
|
+
end
|
369
|
+
|
370
|
+
def remove_subcommand(cmd_name)
|
371
|
+
@subcommands ||= {}
|
372
|
+
@subcommands.delete(cmd_name.to_s)
|
373
|
+
end
|
374
|
+
|
375
|
+
# register an alias for a command
|
376
|
+
def alias_subcommand(alias_cmd_name, cmd_name)
|
377
|
+
add_subcommand_alias(alias_cmd_name.to_s, cmd_name.to_s.gsub('_', '-'))
|
378
|
+
return
|
379
|
+
end
|
380
|
+
|
381
|
+
def subcommand_aliases
|
382
|
+
@subcommand_aliases ||= {}
|
383
|
+
end
|
384
|
+
|
385
|
+
def add_subcommand_alias(alias_cmd_name, cmd_name)
|
386
|
+
@subcommand_aliases ||= {}
|
387
|
+
@subcommand_aliases[alias_cmd_name.to_s] = cmd_name
|
388
|
+
end
|
389
|
+
|
390
|
+
def remove_subcommand_alias(alias_cmd_name)
|
391
|
+
@subcommand_aliases ||= {}
|
392
|
+
@subcommand_aliases.delete(alias_cmd_name.to_s)
|
393
|
+
end
|
394
|
+
|
157
395
|
end
|
158
396
|
end
|
159
397
|
end
|
@@ -1,36 +1,76 @@
|
|
1
|
-
|
1
|
+
require 'term/ansicolor'
|
2
2
|
module Morpheus
|
3
3
|
module Cli
|
4
4
|
class CliRegistry
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
@commands = {}
|
7
|
+
@commands = {} # this is command => Class that includes ::CliCommand
|
8
|
+
@aliases = {} # this is alias => String full input string
|
8
9
|
end
|
9
|
-
|
10
|
+
|
10
11
|
class << self
|
12
|
+
include Term::ANSIColor
|
11
13
|
|
14
|
+
ALIAS_SPLIT_REGEX=/(\;)(?=(?:[^"']|"[^'"]*")*$)/
|
15
|
+
|
12
16
|
def instance
|
13
17
|
@instance ||= CliRegistry.new
|
14
18
|
end
|
15
19
|
|
20
|
+
#todo: move execution out of the CliRegistry
|
16
21
|
def exec(command_name, args)
|
17
|
-
|
18
|
-
|
22
|
+
exec_command(command_name, args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def exec_command(command_name, args)
|
26
|
+
#puts "exec_command(#{command_name}, #{args})"
|
27
|
+
found_alias_command = instance.get_alias(command_name)
|
28
|
+
if found_alias_command
|
29
|
+
exec_alias(command_name, args)
|
30
|
+
else
|
31
|
+
#puts "running regular command #{command_name} with arguments #{args.join(' ')}"
|
19
32
|
instance.get(command_name).new.handle(args)
|
20
|
-
|
21
|
-
|
22
|
-
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def exec_alias(alias_name, args)
|
37
|
+
#puts "exec_alias(#{alias_name}, #{args})"
|
38
|
+
found_alias_command = instance.get_alias(alias_name)
|
39
|
+
# support aliases of multiple commands, semicolon delimiter
|
40
|
+
# todo:
|
41
|
+
all_commands = found_alias_command.gsub(ALIAS_SPLIT_REGEX, '__ALIAS_SPLIT_REGEX__').split('__ALIAS_SPLIT_REGEX__').collect {|it| it.to_s.strip }.select {|it| !it.empty? }.compact
|
42
|
+
print "#{dark} #=> executing alias #{alias_name} as #{all_commands.join('; ')}#{reset}\n" if Morpheus::Logging.debug?
|
43
|
+
all_commands.each do |a_command_string|
|
44
|
+
alias_args = a_command_string.to_s.split(/\s+/) # or just ' '
|
45
|
+
command_name = alias_args.shift
|
46
|
+
command_args = alias_args + args
|
47
|
+
if command_name == alias_name
|
48
|
+
# needs to be better than this
|
49
|
+
print Term::ANSIColor.red,"alias '#{alias_name}' is calling itself? '#{found_alias_command}'", Term::ANSIColor.reset, "\n"
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
# this allows aliases to use other aliases
|
53
|
+
# todo: prevent recursion infinite loop
|
54
|
+
if has_alias?(command_name)
|
55
|
+
exec_alias(command_name, command_args)
|
56
|
+
elsif has_command?(command_name)
|
57
|
+
#puts "executing alias #{found_alias_command} as #{command_name} with args #{args.join(' ')}"
|
58
|
+
instance.get(command_name).new.handle(alias_args + args)
|
59
|
+
else
|
60
|
+
# raise UnrecognizedCommandError.new(command_name)
|
61
|
+
print Term::ANSIColor.red,"alias '#{alias_name}' uses and unknown command: '#{command_name}'", Term::ANSIColor.reset, "\n"
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
end
|
23
65
|
end
|
24
66
|
|
25
67
|
def add(klass, command_name=nil)
|
26
68
|
klass_command_name = cli_ize(klass.name.split('::')[-1])
|
27
|
-
|
28
|
-
if has_command?(klass_command_name) && !command_name.nil?
|
69
|
+
if has_command?(klass_command_name)
|
29
70
|
instance.remove(klass_command_name)
|
30
|
-
instance.add(command_name, klass)
|
31
|
-
else
|
32
|
-
instance.add(klass_command_name, klass)
|
33
71
|
end
|
72
|
+
command_name ||= klass_command_name
|
73
|
+
instance.add(command_name, klass)
|
34
74
|
end
|
35
75
|
|
36
76
|
def has_command?(command_name)
|
@@ -41,11 +81,21 @@ module Morpheus
|
|
41
81
|
end
|
42
82
|
end
|
43
83
|
|
84
|
+
def has_alias?(alias_name)
|
85
|
+
if alias_name.nil? || alias_name == ''
|
86
|
+
false
|
87
|
+
else
|
88
|
+
!instance.get_alias(alias_name).nil?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
44
92
|
def all
|
45
93
|
instance.all
|
46
94
|
end
|
47
95
|
|
48
|
-
|
96
|
+
def all_aliases
|
97
|
+
instance.all_aliases
|
98
|
+
end
|
49
99
|
|
50
100
|
def cli_ize(klass_name)
|
51
101
|
# borrowed from ActiveSupport
|
@@ -58,6 +108,18 @@ module Morpheus
|
|
58
108
|
word.downcase!
|
59
109
|
word.chop.tr('_', '-')
|
60
110
|
end
|
111
|
+
|
112
|
+
def parse_alias_definition(input)
|
113
|
+
# todo: one multi group regex would work
|
114
|
+
alias_name, command_string = nil, nil
|
115
|
+
chunks = input.to_s.sub(/^alias\s+/, "").split('=')
|
116
|
+
alias_name = chunks.shift
|
117
|
+
command_string = chunks.compact.reject {|it| it.empty? }.join('=')
|
118
|
+
command_string = command_string.strip.sub(/^'/, "").sub(/'\Z/, "").strip
|
119
|
+
return alias_name, command_string
|
120
|
+
end
|
121
|
+
|
122
|
+
|
61
123
|
end
|
62
124
|
|
63
125
|
def all
|
@@ -75,6 +137,29 @@ module Morpheus
|
|
75
137
|
def remove(cmd_name)
|
76
138
|
@commands.delete(cmd_name.to_sym)
|
77
139
|
end
|
140
|
+
|
141
|
+
def all_aliases
|
142
|
+
@aliases
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_alias(alias_name)
|
146
|
+
@aliases[alias_name.to_sym]
|
147
|
+
end
|
148
|
+
|
149
|
+
def add_alias(alias_name, command_string)
|
150
|
+
#return @commands[alias_name.to_sym]
|
151
|
+
if self.class.has_command?(alias_name)
|
152
|
+
raise "alias name '#{alias_name}' is invalid. That is the name of a morpheus command."
|
153
|
+
elsif alias_name.to_s.downcase.strip == command_string.to_s.downcase.strip
|
154
|
+
raise "alias #{alias_name}=#{command_string} is invalid..."
|
155
|
+
end
|
156
|
+
@aliases[alias_name.to_sym] = command_string
|
157
|
+
end
|
158
|
+
|
159
|
+
def remove_alias(alias_name)
|
160
|
+
@aliases.delete(alias_name.to_sym)
|
161
|
+
end
|
162
|
+
|
78
163
|
end
|
79
164
|
end
|
80
165
|
end
|