morpheus-cli 2.10.0 → 2.10.1
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.
- 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
|