vmc 0.3.13.beta.5 → 0.3.13

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.
@@ -388,7 +388,6 @@ module VMC::Cli::Command
388
388
 
389
389
  # check if we have hit our app limit
390
390
  check_app_limit
391
-
392
391
  # check memsize here for capacity
393
392
  if memswitch && !no_start
394
393
  check_has_capacity_for(mem_choice_to_quota(memswitch) * instances)
@@ -572,6 +571,17 @@ module VMC::Cli::Command
572
571
  err "Can't deploy applications from staging directory: [#{Dir.tmpdir}]"
573
572
  end
574
573
 
574
+ def check_unreachable_links
575
+ path = Dir.pwd
576
+ files = Dir.glob("#{path}/**/*", File::FNM_DOTMATCH)
577
+ unreachable_paths = files.select { |f|
578
+ File.symlink? f and !File.expand_path(File.readlink(f)).include? path
579
+ } if files
580
+ if unreachable_paths.length > 0
581
+ err "Can't deploy application containing links '#{unreachable_paths}' that reach outside its root '#{path}'"
582
+ end
583
+ end
584
+
575
585
  def upload_app_bits(appname, path)
576
586
  display 'Uploading Application:'
577
587
 
@@ -586,6 +596,7 @@ module VMC::Cli::Command
586
596
  if war_file = Dir.glob('*.war').first
587
597
  VMC::Cli::ZipUtil.unpack(war_file, explode_dir)
588
598
  else
599
+ check_unreachable_links
589
600
  FileUtils.mkdir(explode_dir)
590
601
  files = Dir.glob('{*,.[^\.]*}')
591
602
  # Do not process .git files
@@ -1,5 +1,5 @@
1
-
2
1
  require 'rubygems'
2
+ require 'interact'
3
3
  require 'terminal-table/import'
4
4
 
5
5
  module VMC::Cli
@@ -7,6 +7,9 @@ module VMC::Cli
7
7
  module Command
8
8
 
9
9
  class Base
10
+ include Interactive
11
+ disable_rewind
12
+
10
13
  attr_reader :no_prompt, :prompt_ok
11
14
 
12
15
  def initialize(options={})
@@ -20,7 +23,9 @@ module VMC::Cli
20
23
  end
21
24
  end
22
25
 
23
- def client
26
+ # Inject a client to help in testing.
27
+ def client(cli=nil)
28
+ @client ||= cli
24
29
  return @client if @client
25
30
  @client = VMC::Client.new(target_url, auth_token)
26
31
  @client.trace = VMC::Cli::Config.trace if VMC::Cli::Config.trace
@@ -68,334 +68,6 @@ module VMCExtensions
68
68
  return sprintf("%.#{prec}fM", size/(1024.0*1024.0)) if size < (1024*1024*1024)
69
69
  return sprintf("%.#{prec}fG", size/(1024.0*1024.0*1024.0))
70
70
  end
71
-
72
- # general-purpose interaction
73
- #
74
- # `question' is the prompt (without ": " at the end)
75
- # `options' is a hash containing:
76
- # :input - the input source (defaults to STDIN)
77
- # :default - the default value, also used to attempt type conversion
78
- # of the answer (e.g. numeric/boolean)
79
- # :choices - a list of strings to choose from
80
- # :indexed - whether to allow choosing from `:choices' by their index,
81
- # best for when there are many choices
82
- # :echo - a string to echo when showing the input;
83
- # used for things like censoring password inpt
84
- # :callback - a block used to override certain actions
85
- #
86
- # takes 4 arguments:
87
- # action: the event, e.g. :up or [:key, X] where X is a
88
- # string containing a single character
89
- # answer: the current answer to the question; you'll
90
- # probably mutate this
91
- # position: the current offset from the start of the
92
- # answer string, e.g. when typing in the middle
93
- # of the input, this will be where you insert
94
- # characters
95
- # echo: the :echo option above, may be nil
96
- #
97
- # the block should return the updated `position', or nil if
98
- # it didn't handle the event
99
- def ask(question, options = {})
100
- default = options[:default]
101
- choices = options[:choices]
102
- indexed = options[:indexed]
103
- callback = options[:callback]
104
- input = options[:input] || STDIN
105
- echo = options[:echo]
106
-
107
- if choices
108
- VMCExtensions.ask_choices(input, question, default, choices, indexed, echo, &callback)
109
- else
110
- VMCExtensions.ask_default(input, question, default, echo, &callback)
111
- end
112
- end
113
-
114
- ESCAPES = {
115
- "[A" => :up, "H" => :up,
116
- "[B" => :down, "P" => :down,
117
- "[C" => :right, "M" => :right,
118
- "[D" => :left, "K" => :left,
119
- "[3~" => :delete, "S" => :delete,
120
- "[H" => :home, "G" => :home,
121
- "[F" => :end, "O" => :end
122
- }
123
-
124
- def handle_action(which, ans, pos, echo = nil)
125
- if block_given?
126
- res = yield which, ans, pos, echo
127
- return res unless res.nil?
128
- end
129
-
130
- case which
131
- when :up
132
- # nothing
133
-
134
- when :down
135
- # nothing
136
-
137
- when :tab
138
- # nothing
139
-
140
- when :right
141
- unless pos == ans.size
142
- display censor(ans[pos .. pos], echo), false
143
- return pos + 1
144
- end
145
-
146
- when :left
147
- unless pos == 0
148
- display "\b", false
149
- return pos - 1
150
- end
151
-
152
- when :delete
153
- unless pos == ans.size
154
- ans.slice!(pos, 1)
155
- if WINDOWS
156
- rest = ans[pos .. -1]
157
- display(censor(rest, echo) + " \b" + ("\b" * rest.size), false)
158
- else
159
- display("\e[P", false)
160
- end
161
- end
162
-
163
- when :home
164
- display("\b" * pos, false)
165
- return 0
166
-
167
- when :end
168
- display(censor(ans[pos .. -1], echo), false)
169
- return ans.size
170
-
171
- when :backspace
172
- if pos > 0
173
- ans.slice!(pos - 1, 1)
174
-
175
- if WINDOWS
176
- rest = ans[pos - 1 .. -1]
177
- display("\b" + censor(rest, echo) + " \b" + ("\b" * rest.size), false)
178
- else
179
- display("\b\e[P", false)
180
- end
181
-
182
- return pos - 1
183
- end
184
-
185
- when :interrupt
186
- raise Interrupt.new
187
-
188
- when :eof
189
- return false if ans.empty?
190
-
191
- when :kill_word
192
- if pos > 0
193
- start = /[^\s]*\s*$/ =~ ans[0 .. pos]
194
- length = pos - start
195
- ans.slice!(start, length)
196
- display("\b" * length + " " * length + "\b" * length, false)
197
- return start
198
- end
199
-
200
- when Array
201
- case which[0]
202
- when :key
203
- c = which[1]
204
- rest = ans[pos .. -1]
205
-
206
- ans.insert(pos, c)
207
-
208
- display(censor(c + rest, echo) + ("\b" * rest.size), false)
209
-
210
- return pos + 1
211
- end
212
- end
213
-
214
- pos
215
- end
216
-
217
- def censor(str, with)
218
- return str unless with
219
- with * str.size
220
- end
221
-
222
- # ask a simple question, maybe with a default answer
223
- #
224
- # reads character-by-character, handling backspaces, and sending each
225
- # character to a block if provided
226
- def self.ask_default(input, question, default = nil, echo = nil, &callback)
227
- while true
228
- prompt(question, default)
229
-
230
- ans = ""
231
- pos = 0
232
- escaped = false
233
- escape_seq = ""
234
-
235
- with_char_io(input) do
236
- until pos == false or (c = get_character(input)) =~ /[\r\n]/
237
- if c == "\e" || c == "\xE0"
238
- escaped = true
239
- elsif escaped
240
- escape_seq << c
241
-
242
- if cmd = ESCAPES[escape_seq]
243
- pos = handle_action(cmd, ans, pos, echo, &callback)
244
- escaped, escape_seq = false, ""
245
- elsif ESCAPES.select { |k, v| k.start_with? escape_seq }.empty?
246
- escaped, escape_seq = false, ""
247
- end
248
- elsif c == "\177" or c == "\b" # backspace
249
- pos = handle_action(:backspace, ans, pos, echo, &callback)
250
- elsif c == "\x01"
251
- pos = handle_action(:home, ans, pos, echo, &callback)
252
- elsif c == "\x03"
253
- pos = handle_action(:interrupt, ans, pos, echo, &callback)
254
- elsif c == "\x04"
255
- pos = handle_action(:eof, ans, pos, echo, &callback)
256
- elsif c == "\x05"
257
- pos = handle_action(:end, ans, pos, echo, &callback)
258
- elsif c == "\x17"
259
- pos = handle_action(:kill_word, ans, pos, echo, &callback)
260
- elsif c == "\t"
261
- pos = handle_action(:tab, ans, pos, echo, &callback)
262
- elsif c < " "
263
- # ignore
264
- else
265
- pos = handle_action([:key, c], ans, pos, echo, &callback)
266
- end
267
- end
268
- end
269
-
270
- display "\n", false
271
-
272
- if ans.empty?
273
- return default unless default.nil?
274
- else
275
- return match_type(ans, default)
276
- end
277
- end
278
- end
279
-
280
- def self.ask_choices(input, question, default, choices, indexed = false, echo = nil, &callback)
281
- msg = question.dup
282
-
283
- if indexed
284
- choices.each.with_index do |o, i|
285
- say "#{i + 1}: #{o}"
286
- end
287
- else
288
- msg << " (#{choices.collect(&:inspect).join ", "})"
289
- end
290
-
291
- while true
292
- ans = ask_default(input, msg, default, echo, &callback)
293
-
294
- matches = choices.select { |x| x.start_with? ans }
295
-
296
- if matches.size == 1
297
- return matches.first
298
- elsif indexed and ans =~ /^\d+$/ and res = choices.to_a[ans.to_i - 1]
299
- return res
300
- elsif matches.size > 1
301
- warn "Please disambiguate: #{matches.join " or "}?"
302
- else
303
- warn "Unknown answer, please try again!"
304
- end
305
- end
306
- end
307
-
308
- # display a question and show the default value
309
- def self.prompt(question, default = nil)
310
- msg = question.dup
311
-
312
- case default
313
- when true
314
- msg << " [Yn]"
315
- when false
316
- msg << " [yN]"
317
- else
318
- msg << " [#{default.inspect}]" if default
319
- end
320
-
321
- display "#{msg}: ", false
322
- end
323
-
324
- # try to make `str' be the same class as `x'
325
- def self.match_type(str, x)
326
- case x
327
- when Integer
328
- str.to_i
329
- when true, false
330
- str.upcase.start_with? "Y"
331
- else
332
- str
333
- end
334
- end
335
-
336
- # definitions for reading character-by-character
337
- begin
338
- require "Win32API"
339
-
340
- def self.with_char_io(input)
341
- yield
342
- end
343
-
344
- def self.get_character(input)
345
- if input == STDIN
346
- begin
347
- Win32API.new("msvcrt", "_getch", [], "L").call.chr
348
- rescue
349
- Win32API.new("crtdll", "_getch", [], "L").call.chr
350
- end
351
- else
352
- input.getc.chr
353
- end
354
- end
355
- rescue LoadError
356
- begin
357
- require "termios"
358
-
359
- def self.with_char_io(input)
360
- return yield unless input.tty?
361
-
362
- before = Termios.getattr(input)
363
-
364
- new = before.dup
365
- new.c_lflag &= ~(Termios::ECHO | Termios::ICANON)
366
- new.c_cc[Termios::VMIN] = 1
367
-
368
- begin
369
- Termios.setattr(input, Termios::TCSANOW, new)
370
- yield
371
- ensure
372
- Termios.setattr(input, Termios::TCSANOW, before)
373
- end
374
- end
375
-
376
- def self.get_character(input)
377
- input.getc.chr
378
- end
379
- rescue LoadError
380
- # set tty modes for the duration of a block, restoring them afterward
381
- def self.with_char_io(input)
382
- return yield unless input.tty?
383
-
384
- begin
385
- before = `stty -g`
386
- system("stty raw -echo -icanon isig")
387
- yield
388
- ensure
389
- system("stty #{before}")
390
- end
391
- end
392
-
393
- # this assumes we're wrapped in #with_stty
394
- def self.get_character(input)
395
- input.getc.chr
396
- end
397
- end
398
- end
399
71
  end
400
72
 
401
73
  module VMCStringExtensions
@@ -438,6 +438,10 @@ class VMC::Cli::Runner
438
438
  end
439
439
 
440
440
  rescue OptionParser::InvalidOption => e
441
+ puts(e.message.red)
442
+ puts("\n")
443
+ puts(basic_usage)
444
+ @exit_status = false
441
445
  rescue OptionParser::AmbiguousOption => e
442
446
  puts(e.message.red)
443
447
  puts("\n")
@@ -473,7 +477,7 @@ class VMC::Cli::Runner
473
477
  rescue Interrupt => e
474
478
  say("\nInterrupted".red)
475
479
  @exit_status = false
476
- rescue => e
480
+ rescue Exception => e
477
481
  puts e.message.red
478
482
  puts e.backtrace
479
483
  @exit_status = false
@@ -2,6 +2,6 @@ module VMC
2
2
  module Cli
3
3
  # This version number is used as the RubyGem release version.
4
4
  # The internal VMC version number is VMC::VERSION.
5
- VERSION = '0.3.13.beta.5'
5
+ VERSION = '0.3.13'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vmc
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: 7
5
- version: 0.3.13.beta.5
4
+ prerelease:
5
+ version: 0.3.13
6
6
  platform: ruby
7
7
  authors:
8
8
  - VMware
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-10-24 00:00:00 -07:00
13
+ date: 2011-11-02 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -61,38 +61,49 @@ dependencies:
61
61
  type: :runtime
62
62
  version_requirements: *id004
63
63
  - !ruby/object:Gem::Dependency
64
- name: rake
64
+ name: interact
65
65
  prerelease: false
66
66
  requirement: &id005 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ~>
70
+ - !ruby/object:Gem::Version
71
+ version: 0.2.0
72
+ type: :runtime
73
+ version_requirements: *id005
74
+ - !ruby/object:Gem::Dependency
75
+ name: rake
76
+ prerelease: false
77
+ requirement: &id006 !ruby/object:Gem::Requirement
67
78
  none: false
68
79
  requirements:
69
80
  - - ">="
70
81
  - !ruby/object:Gem::Version
71
82
  version: "0"
72
83
  type: :development
73
- version_requirements: *id005
84
+ version_requirements: *id006
74
85
  - !ruby/object:Gem::Dependency
75
86
  name: rspec
76
87
  prerelease: false
77
- requirement: &id006 !ruby/object:Gem::Requirement
88
+ requirement: &id007 !ruby/object:Gem::Requirement
78
89
  none: false
79
90
  requirements:
80
91
  - - ~>
81
92
  - !ruby/object:Gem::Version
82
93
  version: 1.3.0
83
94
  type: :development
84
- version_requirements: *id006
95
+ version_requirements: *id007
85
96
  - !ruby/object:Gem::Dependency
86
97
  name: webmock
87
98
  prerelease: false
88
- requirement: &id007 !ruby/object:Gem::Requirement
99
+ requirement: &id008 !ruby/object:Gem::Requirement
89
100
  none: false
90
101
  requirements:
91
102
  - - "="
92
103
  - !ruby/object:Gem::Version
93
104
  version: 1.5.0
94
105
  type: :development
95
- version_requirements: *id007
106
+ version_requirements: *id008
96
107
  description: Client library and CLI that provides access to the VMware Cloud Application Platform.
97
108
  email: support@vmware.com
98
109
  executables:
@@ -144,9 +155,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
155
  required_rubygems_version: !ruby/object:Gem::Requirement
145
156
  none: false
146
157
  requirements:
147
- - - ">"
158
+ - - ">="
148
159
  - !ruby/object:Gem::Version
149
- version: 1.3.1
160
+ version: "0"
150
161
  requirements: []
151
162
 
152
163
  rubyforge_project: