vmc 0.3.23 → 0.4.0.beta.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.
- data/bin/vmc +11 -2
- data/vmc-ng/LICENSE +746 -0
- data/vmc-ng/Rakefile +11 -0
- data/vmc-ng/bin/vmc +14 -0
- data/vmc-ng/lib/vmc.rb +2 -0
- data/vmc-ng/lib/vmc/cli.rb +327 -0
- data/vmc-ng/lib/vmc/cli/app.rb +622 -0
- data/vmc-ng/lib/vmc/cli/better_help.rb +193 -0
- data/vmc-ng/lib/vmc/cli/command.rb +523 -0
- data/vmc-ng/lib/vmc/cli/dots.rb +133 -0
- data/vmc-ng/lib/vmc/cli/service.rb +122 -0
- data/vmc-ng/lib/vmc/cli/user.rb +72 -0
- data/vmc-ng/lib/vmc/constants.rb +10 -0
- data/vmc-ng/lib/vmc/detect.rb +64 -0
- data/vmc-ng/lib/vmc/errors.rb +17 -0
- data/vmc-ng/lib/vmc/plugin.rb +40 -0
- data/vmc-ng/lib/vmc/version.rb +3 -0
- data/{LICENSE → vmc/LICENSE} +0 -0
- data/{README.md → vmc/README.md} +1 -5
- data/{Rakefile → vmc/Rakefile} +0 -0
- data/vmc/bin/vmc +6 -0
- data/{caldecott_helper → vmc/caldecott_helper}/Gemfile +0 -0
- data/{caldecott_helper → vmc/caldecott_helper}/Gemfile.lock +0 -0
- data/{caldecott_helper → vmc/caldecott_helper}/server.rb +0 -0
- data/{config → vmc/config}/clients.yml +0 -0
- data/{config → vmc/config}/micro/offline.conf +0 -0
- data/{config → vmc/config}/micro/paths.yml +0 -0
- data/{config → vmc/config}/micro/refresh_ip.rb +0 -0
- data/{lib → vmc/lib}/cli.rb +0 -0
- data/{lib → vmc/lib}/cli/commands/admin.rb +0 -0
- data/{lib → vmc/lib}/cli/commands/apps.rb +0 -0
- data/{lib → vmc/lib}/cli/commands/base.rb +0 -0
- data/{lib → vmc/lib}/cli/commands/manifest.rb +0 -0
- data/{lib → vmc/lib}/cli/commands/micro.rb +0 -0
- data/{lib → vmc/lib}/cli/commands/misc.rb +0 -0
- data/{lib → vmc/lib}/cli/commands/services.rb +0 -0
- data/{lib → vmc/lib}/cli/commands/user.rb +2 -6
- data/{lib → vmc/lib}/cli/config.rb +0 -0
- data/{lib → vmc/lib}/cli/console_helper.rb +4 -14
- data/{lib → vmc/lib}/cli/core_ext.rb +0 -0
- data/{lib → vmc/lib}/cli/errors.rb +0 -0
- data/{lib → vmc/lib}/cli/frameworks.rb +1 -1
- data/{lib → vmc/lib}/cli/manifest_helper.rb +0 -0
- data/{lib → vmc/lib}/cli/runner.rb +0 -0
- data/{lib → vmc/lib}/cli/services_helper.rb +0 -0
- data/{lib → vmc/lib}/cli/tunnel_helper.rb +0 -0
- data/{lib → vmc/lib}/cli/usage.rb +0 -0
- data/{lib → vmc/lib}/cli/version.rb +1 -1
- data/{lib → vmc/lib}/cli/zip_util.rb +0 -0
- data/{lib → vmc/lib}/vmc.rb +0 -0
- data/{lib → vmc/lib}/vmc/client.rb +0 -0
- data/{lib → vmc/lib}/vmc/const.rb +0 -0
- data/{lib → vmc/lib}/vmc/micro.rb +0 -0
- data/{lib → vmc/lib}/vmc/micro/switcher/base.rb +0 -0
- data/{lib → vmc/lib}/vmc/micro/switcher/darwin.rb +0 -0
- data/{lib → vmc/lib}/vmc/micro/switcher/dummy.rb +0 -0
- data/{lib → vmc/lib}/vmc/micro/switcher/linux.rb +0 -0
- data/{lib → vmc/lib}/vmc/micro/switcher/windows.rb +0 -0
- data/{lib → vmc/lib}/vmc/micro/vmrun.rb +1 -11
- metadata +177 -93
@@ -0,0 +1,193 @@
|
|
1
|
+
module VMC
|
2
|
+
module BetterHelp
|
3
|
+
@@groups = []
|
4
|
+
@@tree = {}
|
5
|
+
|
6
|
+
def nothing_printable?(group, all = false)
|
7
|
+
group[:members].reject { |_, _, opts| !all && opts[:hidden] }.empty? &&
|
8
|
+
group[:children].all? { |g| nothing_printable?(g) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def print_help_group(group, all = false, indent = 0)
|
12
|
+
return if nothing_printable?(group, all)
|
13
|
+
|
14
|
+
members = group[:members]
|
15
|
+
|
16
|
+
unless all
|
17
|
+
members = members.reject do |_, _, opts|
|
18
|
+
opts[:hidden]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
members = members.collect do |cls, name, opts|
|
23
|
+
[cls, cls.tasks[name]]
|
24
|
+
end
|
25
|
+
|
26
|
+
i = " " * indent
|
27
|
+
|
28
|
+
print i
|
29
|
+
puts group[:description]
|
30
|
+
|
31
|
+
width = 0
|
32
|
+
members.each do |cls, t|
|
33
|
+
sub = find_subcommand_name(cls)
|
34
|
+
len = (sub ? sub.size + 1 : 0) + t.usage.size
|
35
|
+
if len > width
|
36
|
+
width = len
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
members.each do |cls, t|
|
41
|
+
sub = find_subcommand_name(cls)
|
42
|
+
|
43
|
+
print "#{i} "
|
44
|
+
|
45
|
+
label = sub ? "#{sub} " : ""
|
46
|
+
label << t.usage
|
47
|
+
|
48
|
+
print "#{label.ljust(width)}\t#{t.description}"
|
49
|
+
|
50
|
+
puts ""
|
51
|
+
end
|
52
|
+
|
53
|
+
puts "" unless members.empty?
|
54
|
+
|
55
|
+
group[:children].each do |group|
|
56
|
+
print_help_group(group, all, indent + 1)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def groups(*tree)
|
61
|
+
tree.each do |*args|
|
62
|
+
add_group(@@groups, @@tree, *args.first)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_group(groups, tree, name, desc, *subs)
|
67
|
+
members = []
|
68
|
+
|
69
|
+
meta = {:members => members, :children => []}
|
70
|
+
groups << meta
|
71
|
+
|
72
|
+
tree[name] = {:members => members, :children => {}}
|
73
|
+
|
74
|
+
meta[:description] = desc
|
75
|
+
|
76
|
+
subs.each do |*args|
|
77
|
+
add_group(meta[:children], tree[name][:children], *args.first)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def group(*names)
|
82
|
+
options =
|
83
|
+
if names.last.is_a? Hash
|
84
|
+
names.pop
|
85
|
+
else
|
86
|
+
{}
|
87
|
+
end
|
88
|
+
|
89
|
+
where = @@tree
|
90
|
+
top = true
|
91
|
+
names.each do |n|
|
92
|
+
where = where[:children] unless top
|
93
|
+
|
94
|
+
unless where
|
95
|
+
raise "unknown group: #{names.join("/")}"
|
96
|
+
end
|
97
|
+
|
98
|
+
where = where[n]
|
99
|
+
|
100
|
+
top = false
|
101
|
+
end
|
102
|
+
|
103
|
+
where[:members] << [self, @usage.split.first, options]
|
104
|
+
end
|
105
|
+
|
106
|
+
def subcommand_classes
|
107
|
+
@subcommand_classes ||= {}
|
108
|
+
end
|
109
|
+
|
110
|
+
def subcommand_names
|
111
|
+
@subcommand_names ||= {}
|
112
|
+
end
|
113
|
+
|
114
|
+
def subcommand(name, cls)
|
115
|
+
subcommand_classes[name] = cls
|
116
|
+
subcommand_names[cls] = name
|
117
|
+
super
|
118
|
+
end
|
119
|
+
|
120
|
+
def find_subcommand_name(cls)
|
121
|
+
found = subcommand_names[cls]
|
122
|
+
return found if found
|
123
|
+
|
124
|
+
if superclass.respond_to?(:find_subcommand_name) &&
|
125
|
+
found = superclass.find_subcommand_name(cls)
|
126
|
+
return found
|
127
|
+
end
|
128
|
+
|
129
|
+
subcommand_classes.each do |name, sub|
|
130
|
+
if found = sub.find_subcommand_name(cls)
|
131
|
+
return name + " " + found
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
nil
|
136
|
+
end
|
137
|
+
|
138
|
+
def find_subcommand(name)
|
139
|
+
found = subcommand_classes[name]
|
140
|
+
return found if found
|
141
|
+
|
142
|
+
if superclass.respond_to? :find_subcommand
|
143
|
+
superclass.find_subcommand(name)
|
144
|
+
else
|
145
|
+
nil
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def task_help(shell, task_name)
|
150
|
+
if sub = find_subcommand(task_name)
|
151
|
+
sub.help(shell, true)
|
152
|
+
elsif t = all_tasks[task_name]
|
153
|
+
puts t.description
|
154
|
+
puts ""
|
155
|
+
puts "Usage: #{t.usage}"
|
156
|
+
puts ""
|
157
|
+
class_options_help(shell, nil => t.options.map { |_, o| o })
|
158
|
+
else
|
159
|
+
super
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def help(shell, subcommand = false)
|
164
|
+
puts "Tasks:"
|
165
|
+
|
166
|
+
width = 0
|
167
|
+
@tasks.each do |_, t|
|
168
|
+
len = t.usage.size
|
169
|
+
if len > width
|
170
|
+
width = len
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
@tasks.each do |_, t|
|
175
|
+
print " "
|
176
|
+
|
177
|
+
print "#{t.usage.ljust(width)}\t#{t.description}"
|
178
|
+
|
179
|
+
puts ""
|
180
|
+
end
|
181
|
+
|
182
|
+
puts ""
|
183
|
+
|
184
|
+
class_options_help(shell)
|
185
|
+
end
|
186
|
+
|
187
|
+
def print_help_groups(all = false)
|
188
|
+
@@groups.each do |commands|
|
189
|
+
print_help_group(commands, all)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,523 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "interact"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
require "cfoundry"
|
6
|
+
|
7
|
+
require "vmc/constants"
|
8
|
+
require "vmc/errors"
|
9
|
+
require "vmc/cli/dots"
|
10
|
+
require "vmc/cli/better_help"
|
11
|
+
|
12
|
+
|
13
|
+
module VMC
|
14
|
+
module Interactive
|
15
|
+
include ::Interactive::Rewindable
|
16
|
+
include Dots
|
17
|
+
|
18
|
+
class InteractiveDefault
|
19
|
+
attr_reader :method
|
20
|
+
|
21
|
+
def initialize(query, cls, cmd, flag)
|
22
|
+
# here be dragons
|
23
|
+
#
|
24
|
+
# MRI has no Proc -> Lambda, so this is kind of the only way to work
|
25
|
+
# around Proc's "convenient" argument handling while keeping the
|
26
|
+
# blocks evaluated on the Command instance
|
27
|
+
|
28
|
+
@method = :"__interact_#{cmd}_#{flag}__"
|
29
|
+
cls.queries.send(:define_method, @method, &query)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
"(interaction)"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def force?
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def ask(question, options = {})
|
42
|
+
if force? and options.key?(:default)
|
43
|
+
options[:default]
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def list_choices(choices, options)
|
50
|
+
choices.each_with_index do |o, i|
|
51
|
+
puts "#{c(i + 1, :green)}: #{o}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def input_state(options)
|
56
|
+
CFState.new(options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def prompt(question, options)
|
60
|
+
value =
|
61
|
+
case options[:default]
|
62
|
+
when true
|
63
|
+
"y"
|
64
|
+
when false
|
65
|
+
"n"
|
66
|
+
when nil
|
67
|
+
""
|
68
|
+
else
|
69
|
+
options[:default].to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
print "#{question}"
|
73
|
+
print c("> ", :blue)
|
74
|
+
|
75
|
+
unless value.empty?
|
76
|
+
print "#{c(value, :black) + "\b" * value.size}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def handler(which, state)
|
81
|
+
ans = state.answer
|
82
|
+
pos = state.position
|
83
|
+
|
84
|
+
if state.default?
|
85
|
+
if which.is_a?(Array) and which[0] == :key
|
86
|
+
# initial non-movement keypress clears default answer
|
87
|
+
clear_input(state)
|
88
|
+
else
|
89
|
+
# wipe away any coloring
|
90
|
+
redraw_input(state)
|
91
|
+
end
|
92
|
+
|
93
|
+
state.clear_default!
|
94
|
+
end
|
95
|
+
|
96
|
+
super
|
97
|
+
|
98
|
+
print "\n" if which == :enter
|
99
|
+
end
|
100
|
+
|
101
|
+
class CFState < Interactive::InputState
|
102
|
+
def initialize(options = {}, answer = nil, position = 0)
|
103
|
+
@options = options
|
104
|
+
|
105
|
+
if answer
|
106
|
+
@answer = answer
|
107
|
+
elsif options[:default]
|
108
|
+
case options[:default]
|
109
|
+
when true
|
110
|
+
@answer = "y"
|
111
|
+
when false
|
112
|
+
@answer = "n"
|
113
|
+
else
|
114
|
+
@answer = options[:default].to_s
|
115
|
+
end
|
116
|
+
|
117
|
+
@default = true
|
118
|
+
else
|
119
|
+
@answer = ""
|
120
|
+
end
|
121
|
+
|
122
|
+
@position = position
|
123
|
+
@done = false
|
124
|
+
end
|
125
|
+
|
126
|
+
def clear_default!
|
127
|
+
@default = false
|
128
|
+
end
|
129
|
+
|
130
|
+
def default?
|
131
|
+
@default
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class Command < Thor
|
137
|
+
include Interactive
|
138
|
+
extend BetterHelp
|
139
|
+
|
140
|
+
class_option :proxy, :aliases => "-u", :desc => "Proxy user"
|
141
|
+
|
142
|
+
class_option :verbose,
|
143
|
+
:type => :boolean, :aliases => "-v", :desc => "Verbose"
|
144
|
+
|
145
|
+
class_option :force,
|
146
|
+
:type => :boolean, :aliases => "-f", :desc => "Force (no interaction)"
|
147
|
+
|
148
|
+
class_option :simple_output,
|
149
|
+
:type => :boolean, :desc => "Simplified output format."
|
150
|
+
|
151
|
+
class_option :script, :type => :boolean, :aliases => "-s",
|
152
|
+
:desc => "--simple-output and --force"
|
153
|
+
|
154
|
+
class_option :trace, :type => :boolean, :aliases => "-t",
|
155
|
+
:desc => "Show API requests and responses"
|
156
|
+
|
157
|
+
class_option :color, :type => :boolean, :desc => "Colored output"
|
158
|
+
|
159
|
+
def self.queries
|
160
|
+
return @queries if @queries
|
161
|
+
|
162
|
+
@queries = Module.new
|
163
|
+
include @queries
|
164
|
+
|
165
|
+
@queries
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.flag(name, options = {}, &query)
|
169
|
+
if query
|
170
|
+
options[:default] ||=
|
171
|
+
InteractiveDefault.new(query, self, @usage.split.first, name)
|
172
|
+
end
|
173
|
+
|
174
|
+
method_option(name, options)
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.callbacks_for(name)
|
178
|
+
cs = callbacks[name]
|
179
|
+
if superclass.respond_to? :callbacks
|
180
|
+
cs.merge superclass.callbacks_for(name)
|
181
|
+
else
|
182
|
+
cs
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.callbacks
|
187
|
+
@callbacks ||= Hash.new do |h, name|
|
188
|
+
h[name] = Hash.new do |h, task|
|
189
|
+
h[task] = []
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def self.add_callback(name, task, callback)
|
195
|
+
callbacks[name][task] << callback
|
196
|
+
end
|
197
|
+
|
198
|
+
def self.before(task, &callback)
|
199
|
+
add_callback(:before, task, callback)
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.after(task, &callback)
|
203
|
+
add_callback(:after, task, callback)
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.ensuring(task, &callback)
|
207
|
+
add_callback(:ensuring, task, callback)
|
208
|
+
end
|
209
|
+
|
210
|
+
def self.around(task, &callback)
|
211
|
+
add_callback(:around, task, callback)
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
def callbacks_for(what)
|
217
|
+
self.class.callbacks_for(what)
|
218
|
+
end
|
219
|
+
|
220
|
+
def passed_value(flag)
|
221
|
+
if (val = options[flag]) && \
|
222
|
+
!val.is_a?(VMC::Interactive::InteractiveDefault)
|
223
|
+
val
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def inputs
|
228
|
+
@inputs ||= {}
|
229
|
+
end
|
230
|
+
|
231
|
+
def input(name, *args)
|
232
|
+
return inputs[name] if inputs.key?(name)
|
233
|
+
|
234
|
+
val = options[name]
|
235
|
+
inputs[name] =
|
236
|
+
if val.is_a?(VMC::Interactive::InteractiveDefault)
|
237
|
+
send(val.method, *args)
|
238
|
+
elsif val.respond_to? :to_proc
|
239
|
+
instance_exec(*args, &options[name])
|
240
|
+
else
|
241
|
+
options[name]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def forget(name)
|
246
|
+
@inputs.delete name
|
247
|
+
end
|
248
|
+
|
249
|
+
def script?
|
250
|
+
if options.key?("script")
|
251
|
+
options["script"]
|
252
|
+
else
|
253
|
+
!$stdout.tty?
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def force?
|
258
|
+
if options.key?("force")
|
259
|
+
options["force"]
|
260
|
+
else
|
261
|
+
script?
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def verbose?
|
266
|
+
options["verbose"]
|
267
|
+
end
|
268
|
+
|
269
|
+
def simple_output?
|
270
|
+
if options.key?("simple_output")
|
271
|
+
options["simple_output"]
|
272
|
+
else
|
273
|
+
script?
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def color?
|
278
|
+
if options.key?("color")
|
279
|
+
options["color"]
|
280
|
+
else
|
281
|
+
!simple_output?
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def err(msg, exit_status = 1)
|
286
|
+
if script?
|
287
|
+
$stderr.puts(msg)
|
288
|
+
else
|
289
|
+
puts c(msg, :red)
|
290
|
+
end
|
291
|
+
|
292
|
+
$exit_status = 1
|
293
|
+
end
|
294
|
+
|
295
|
+
def with_inputs(new)
|
296
|
+
return yield if !new || new.empty?
|
297
|
+
|
298
|
+
begin
|
299
|
+
orig = {}
|
300
|
+
new.each do |k, v|
|
301
|
+
orig[k] = inputs[k]
|
302
|
+
inputs[k] = v
|
303
|
+
end
|
304
|
+
|
305
|
+
yield
|
306
|
+
ensure
|
307
|
+
orig.each do |k, v|
|
308
|
+
if v.nil?
|
309
|
+
inputs.delete(k)
|
310
|
+
else
|
311
|
+
inputs[k] = v
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def fail(msg)
|
318
|
+
raise UserError, msg
|
319
|
+
end
|
320
|
+
|
321
|
+
def invoke_task(task, args)
|
322
|
+
callbacks_for(:before)[task.name.to_sym].each do |c|
|
323
|
+
c.call
|
324
|
+
end
|
325
|
+
|
326
|
+
action = proc do |*given_args|
|
327
|
+
if inputs = given_args.first
|
328
|
+
with_inputs(inputs) do
|
329
|
+
task.run(self, args)
|
330
|
+
end
|
331
|
+
else
|
332
|
+
task.run(self, args)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
callbacks_for(:around)[task.name.to_sym].each do |a|
|
337
|
+
before = action
|
338
|
+
action = proc do |*given_args|
|
339
|
+
if inputs = given_args.first
|
340
|
+
with_inputs(inputs) do
|
341
|
+
instance_exec(before, args, &a)
|
342
|
+
end
|
343
|
+
else
|
344
|
+
instance_exec(before, args, &a)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
res = instance_exec(args, &action)
|
350
|
+
|
351
|
+
callbacks_for(:after)[task.name.to_sym].each do |c|
|
352
|
+
c.call
|
353
|
+
end
|
354
|
+
|
355
|
+
res
|
356
|
+
rescue Interrupt
|
357
|
+
$exit_status = 130
|
358
|
+
rescue Thor::Error
|
359
|
+
raise
|
360
|
+
rescue UserError => e
|
361
|
+
err e.message
|
362
|
+
rescue Exception => e
|
363
|
+
msg = e.class.name
|
364
|
+
msg << ": #{e}" unless e.to_s.empty?
|
365
|
+
err msg
|
366
|
+
|
367
|
+
ensure_config_dir
|
368
|
+
|
369
|
+
File.open(File.expand_path(VMC::CRASH_FILE), "w") do |f|
|
370
|
+
f.print "Time of crash:\n "
|
371
|
+
f.puts Time.now
|
372
|
+
f.puts ""
|
373
|
+
f.puts msg
|
374
|
+
f.puts ""
|
375
|
+
|
376
|
+
e.backtrace.each do |loc|
|
377
|
+
if loc =~ /\/gems\//
|
378
|
+
f.puts loc.sub(/.*\/gems\//, "")
|
379
|
+
else
|
380
|
+
f.puts loc.sub(File.expand_path("../../../..", __FILE__) + "/", "")
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
ensure
|
385
|
+
callbacks_for(:ensuring)[task.name.to_sym].each do |c|
|
386
|
+
c.call
|
387
|
+
end
|
388
|
+
end
|
389
|
+
public :invoke_task
|
390
|
+
|
391
|
+
def sane_target_url(url)
|
392
|
+
unless url =~ /^https?:\/\//
|
393
|
+
url = "http://#{url}"
|
394
|
+
end
|
395
|
+
|
396
|
+
url.gsub(/\/$/, "")
|
397
|
+
end
|
398
|
+
|
399
|
+
def target_file
|
400
|
+
one_of(VMC::TARGET_FILE, VMC::OLD_TARGET_FILE)
|
401
|
+
end
|
402
|
+
|
403
|
+
def tokens_file
|
404
|
+
one_of(VMC::TOKENS_FILE, VMC::OLD_TOKENS_FILE)
|
405
|
+
end
|
406
|
+
|
407
|
+
def one_of(*paths)
|
408
|
+
paths.each do |p|
|
409
|
+
exp = File.expand_path(p)
|
410
|
+
return exp if File.exist? exp
|
411
|
+
end
|
412
|
+
|
413
|
+
paths.first
|
414
|
+
end
|
415
|
+
|
416
|
+
def client_target
|
417
|
+
File.read(target_file).chomp
|
418
|
+
end
|
419
|
+
|
420
|
+
def ensure_config_dir
|
421
|
+
config = File.expand_path(VMC::CONFIG_DIR)
|
422
|
+
Dir.mkdir(config) unless File.exist? config
|
423
|
+
end
|
424
|
+
|
425
|
+
def set_target(url)
|
426
|
+
ensure_config_dir
|
427
|
+
|
428
|
+
File.open(File.expand_path(VMC::TARGET_FILE), "w") do |f|
|
429
|
+
f.write(sane_target_url(url))
|
430
|
+
end
|
431
|
+
|
432
|
+
@client = nil
|
433
|
+
end
|
434
|
+
|
435
|
+
def tokens
|
436
|
+
new_toks = File.expand_path(VMC::TOKENS_FILE)
|
437
|
+
old_toks = File.expand_path(VMC::OLD_TOKENS_FILE)
|
438
|
+
|
439
|
+
if File.exist? new_toks
|
440
|
+
YAML.load_file(new_toks)
|
441
|
+
elsif File.exist? old_toks
|
442
|
+
JSON.load(File.read(old_toks))
|
443
|
+
else
|
444
|
+
{}
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
def client_token
|
449
|
+
tokens[client_target]
|
450
|
+
end
|
451
|
+
|
452
|
+
def save_tokens(ts)
|
453
|
+
ensure_config_dir
|
454
|
+
|
455
|
+
File.open(File.expand_path(VMC::TOKENS_FILE), "w") do |io|
|
456
|
+
YAML.dump(ts, io)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
def save_token(token)
|
461
|
+
ts = tokens
|
462
|
+
ts[client_target] = token
|
463
|
+
save_tokens(ts)
|
464
|
+
end
|
465
|
+
|
466
|
+
def remove_token
|
467
|
+
ts = tokens
|
468
|
+
ts.delete client_target
|
469
|
+
save_tokens(ts)
|
470
|
+
end
|
471
|
+
|
472
|
+
def client
|
473
|
+
return @client if @client
|
474
|
+
|
475
|
+
@client = CFoundry::Client.new(client_target, client_token)
|
476
|
+
@client.proxy = options[:proxy]
|
477
|
+
@client.trace = options[:trace]
|
478
|
+
@client
|
479
|
+
end
|
480
|
+
|
481
|
+
def usage(used, limit)
|
482
|
+
"#{b(human_size(used))} of #{b(human_size(limit, 0))}"
|
483
|
+
end
|
484
|
+
|
485
|
+
def percentage(num, low = 50, mid = 70)
|
486
|
+
color =
|
487
|
+
if num <= low
|
488
|
+
:green
|
489
|
+
elsif num <= mid
|
490
|
+
:yellow
|
491
|
+
else
|
492
|
+
:red
|
493
|
+
end
|
494
|
+
|
495
|
+
c(format("%.1f\%", num), color)
|
496
|
+
end
|
497
|
+
|
498
|
+
def megabytes(str)
|
499
|
+
if str =~ /T$/i
|
500
|
+
str.to_i * 1024 * 1024
|
501
|
+
elsif str =~ /G$/i
|
502
|
+
str.to_i * 1024
|
503
|
+
elsif str =~ /M$/i
|
504
|
+
str.to_i
|
505
|
+
elsif str =~ /K$/i
|
506
|
+
str.to_i / 1024
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
def human_size(num, precision = 1)
|
511
|
+
sizes = ["G", "M", "K"]
|
512
|
+
sizes.each.with_index do |suf, i|
|
513
|
+
pow = sizes.size - i
|
514
|
+
unit = 1024 ** pow
|
515
|
+
if num >= unit
|
516
|
+
return format("%.#{precision}f%s", num / unit, suf)
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
format("%.#{precision}fB", num)
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|