pi 0.1.23 → 0.1.24

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.
@@ -1,37 +1,12 @@
1
- require "interact"
2
1
  module PI::Cli::Command
3
2
  class Services < Base
4
3
  include PI::Cli::ChooseHelper
5
- include Interactive
4
+ include PI::Cli::InteractHelper
6
5
 
7
- def usable_services(appname=nil)
8
- unless appname
9
- useproject = choose_project
10
- projectid = useproject[:id]
11
- useapp = choose_app(projectid)
12
- appname = useapp[:name]
13
- end
14
- services = client.usable_services(appname)
15
- return display JSON.pretty_generate(services) if @options[:json]
16
- return display "No Services" if services.nil? || services.empty?
17
- services.sort! {|a, b| a[:name] <=> b[:name] }
18
- services_table = table do |t|
19
- t.headings = 'Name', 'Version', 'Type'
20
- services.each do |s|
21
- t << [s[:name], s[:version] ,s[:service_type]]
22
- end
23
- end
24
- display services_table
25
- end
26
-
27
- def app_service(appname=nil)
28
- unless appname
29
- useproject = choose_project
30
- projectid = useproject[:id]
31
- useapp = choose_app(projectid)
32
- appname = useapp[:name]
33
- end
34
- services = client.app_service(appname)
6
+ def app_service(appid_or_appname=nil)
7
+ client.check_login_status
8
+ app = choose_app_help_target_not_all(appid_or_appname)
9
+ services = client.app_service(app[:id])
35
10
  return display JSON.pretty_generate(services) if @options[:json]
36
11
  return display "No Services" if services.nil? || services.empty?
37
12
  services.sort! {|a, b| a[:name] <=> b[:name] }
@@ -44,17 +19,10 @@ module PI::Cli::Command
44
19
  display services_table
45
20
  end
46
21
 
47
- def bind_service(appname=nil)
48
- unless appname
49
- useproject = choose_project
50
- projectid = useproject[:id]
51
- useapp = choose_app(projectid)
52
- appname = useapp[:name]
53
- end
54
- app = client.app_get_byname(appname)
55
- err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
56
-
57
- services = client.usable_services(appname)
22
+ def bind_service(appid_or_appname=nil)
23
+ client.check_login_status
24
+ app = choose_app_help_target_not_all(appid_or_appname)
25
+ services = client.usable_services(app[:id])
58
26
  err "No usable services!" if services.nil? || services.empty?
59
27
 
60
28
  choices = Array.new
@@ -62,10 +30,12 @@ module PI::Cli::Command
62
30
  choices << s[:name]
63
31
  end
64
32
 
65
- manifest = ask "Select services, indexed list?", :choices => choices, :indexed => true
66
- manifest = manifest.to_a
33
+ manifest = asks "Select services, indexed list?", :choices => choices, :indexed => true
67
34
  display "Selected services: ",false
68
- display "#{manifest}"
35
+ manifest.each do |m|
36
+ display "#{m} ",false
37
+ end
38
+ display "\n"
69
39
  display "Binding service: ",false
70
40
 
71
41
  t = Thread.new do
@@ -76,55 +46,60 @@ module PI::Cli::Command
76
46
  end
77
47
  end
78
48
 
79
- client.bind_service(appname,manifest)
80
- result = check_status(app[:name], "bindservice")
49
+ client.bind_service(app[:id],manifest)
50
+ result = check_status(app[:targetName], app[:name], "bindservice")
81
51
  Thread.kill(t)
82
- if result[:code] == 200
83
- display "OK".green
52
+ if result[:code] == 200
53
+ if not result[:text].empty?
54
+ display "OK".green
55
+ else
56
+ display "Please try again"
57
+ end
84
58
  else
85
59
  err result[:text]
86
60
  end
87
61
  end
88
62
 
89
- def unbind_service(appname=nil)
90
- unless appname
91
- useproject = choose_project
92
- projectid = useproject[:id]
93
- useapp = choose_app(projectid)
94
- appname = useapp[:name]
95
- end
96
- app = client.app_get_byname(appname)
97
- err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
98
- services = client.app_service(appname)
99
- err "No binded services!" if services.nil? || services.empty?
100
-
101
- useservice = nil
102
- choose do |menu|
103
- display "=============Services============"
104
- menu.prompt = "Select Service: "
105
- menu.select_by = :index_or_name
106
- services.each do |service|
107
- menu.choice("#{service[:name]}") { useservice = service }
108
- end
109
- end
110
- display "Selected Service: ",false
111
- display "#{useservice[:name]}"
112
- manifest = [useservice[:name]]
113
- display "Unbinding service: ",false
114
-
63
+ def unbind_service(appid_or_appname=nil)
64
+ client.check_login_status
65
+ app = choose_app_help_target_not_all(appid_or_appname)
66
+ services = client.app_service(app[:id])
67
+ err "No binded services!" if services.nil? || services.empty?
68
+ service_choices = Array.new
69
+ services.each do |s|
70
+ service_choices << s[:name]
71
+ end
72
+ services = asks "Select Service", :choices => service_choices, :indexed => true
73
+ display "Selected DNS: ",false
74
+ services.each do |m|
75
+ display "#{m} ",false
76
+ end
77
+ display "\n"
78
+ services.each do |service|
79
+ do_unbind_service(app, service)
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def do_unbind_service(app, service)
86
+ display "Unbinding service '#{service}': ",false
115
87
  t = Thread.new do
116
88
  loop do
117
89
  display '.', false
118
90
  sleep (1)
119
91
  break unless t.alive?
120
92
  end
121
- end
122
-
123
- client.unbind_service(appname,manifest)
124
- result = check_status(app[:name], "unbindservice")
93
+ end
94
+ client.unbind_service(app[:id], service)
95
+ result = check_status(app[:targetName], app[:name], "unbindservice")
125
96
  Thread.kill(t)
126
- if result[:code] == 200
127
- display "OK".green
97
+ if result[:code] == 200
98
+ if not result[:text].empty?
99
+ display "OK".green
100
+ else
101
+ display "Please try again"
102
+ end
128
103
  else
129
104
  err result[:text]
130
105
  end
@@ -3,8 +3,12 @@ require 'set'
3
3
  module PI::Cli::Command
4
4
 
5
5
  class User < Base
6
-
6
+ YES_SET = Set.new(["y", "Y", "yes", "YES"])
7
+ NO_SET = Set.new(["n", "N", "no", "NO"])
8
+
7
9
  def login(url=nil)
10
+ user = @options[:user]
11
+ password = @options[:password]
8
12
  unless url
9
13
  url = ask "Attempting login to '#{target_url}'?", :default => true
10
14
  if url == true
@@ -14,12 +18,16 @@ module PI::Cli::Command
14
18
  end
15
19
  end
16
20
  url = "#{target_url}" if url.nil? || url.empty?
17
- eval("PI::Cli::Command::Misc").new().send("set_target", url)
21
+ eval("PI::Cli::Command::Misc").new().send("set_target", url)
22
+ unless client.target_valid?
23
+ display "Host is not available or is not valid: '#{target_url}'".red
24
+ display "\n<<<\n#{client.raw_info}\n>>>\n"
25
+ exit(false)
26
+ end
27
+
18
28
  tries ||= 0
19
- user = ask "User"
20
- password = ask "Password", :echo => '*'
21
- err "Need a valid user" unless user
22
- err "Need a password" unless password
29
+ user = ask "User" unless user
30
+ password = ask "Password", :echo => '*' unless password
23
31
  login_and_save_token(user, password)
24
32
  say "Successfully logged into [#{target_url}]".green
25
33
  rescue PI::Client::TargetError
@@ -27,7 +35,7 @@ module PI::Cli::Command
27
35
  retry if (tries += 1) < 3 && !@options[:passwd]
28
36
  exit 1
29
37
  rescue => e
30
- display "Problem with login, #{e}, try again or register for an account.".red
38
+ display "Problem with login, #{e}, try again.".red
31
39
  exit 1
32
40
  end
33
41
 
@@ -46,6 +54,7 @@ module PI::Cli::Command
46
54
  end
47
55
 
48
56
  def user
57
+ client.check_login_status
49
58
  user = client.user_info
50
59
  github_info = client.github_info
51
60
  github_info[:name] = "null" if github_info[:name].empty? || github_info[:name].nil?
@@ -62,6 +71,7 @@ module PI::Cli::Command
62
71
  end
63
72
 
64
73
  def targets
74
+ client.check_login_status
65
75
  targets = client.targets
66
76
  return display JSON.pretty_generate(targets) if @options[:json]
67
77
  return display 'No Targets' if targets.empty?
@@ -75,7 +85,8 @@ module PI::Cli::Command
75
85
  display targets_table
76
86
  end
77
87
 
78
- def password(newpassword=nil)
88
+ def password(newpassword=nil)
89
+ client.check_login_status
79
90
  unless newpassword
80
91
  loop{
81
92
  newpassword = ask "New Password", :echo => '*'
@@ -94,9 +105,12 @@ module PI::Cli::Command
94
105
  end
95
106
 
96
107
  def github(name=nil)
108
+ client.check_login_status
109
+ email = @options[:email]
110
+ password = @options[:password]
97
111
  name = ask "Please input your name" unless name
98
- email = ask "Please input your email"
99
- password = ask "Please input your password", :echo => '*'
112
+ email = ask "Please input your email" unless email
113
+ password = ask "Please input your password", :echo => '*' unless password
100
114
  manifest = {
101
115
  :name => "#{name}",
102
116
  :password => "#{password}",
@@ -108,6 +122,7 @@ module PI::Cli::Command
108
122
  end
109
123
 
110
124
  def runtimes
125
+ client.check_login_status
111
126
  runtimes_info = client.runtimes
112
127
  return display JSON.pretty_generate(runtimes_info) if @options[:json]
113
128
  return display "No Runtimes" if runtimes_info.empty?
@@ -120,6 +135,7 @@ module PI::Cli::Command
120
135
  end
121
136
 
122
137
  def frameworks
138
+ client.check_login_status
123
139
  runtimes = client.runtimes
124
140
  java_runtime = runtimes[0].downcase
125
141
  ruby_runtime = runtimes[1].downcase
@@ -0,0 +1,538 @@
1
+ module PI::Cli
2
+ module InteractHelper
3
+ EVENTS = {
4
+ "\b" => :backspace,
5
+ "\t" => :tab,
6
+ "\x01" => :home,
7
+ "\x03" => :interrupt,
8
+ "\x04" => :eof,
9
+ "\x05" => :end,
10
+ "\x17" => :kill_word,
11
+ "\x7f" => :backspace,
12
+ "\r" => :enter,
13
+ "\n" => :enter
14
+ }
15
+
16
+ ESCAPES = {
17
+ "[A" => :up, "H" => :up,
18
+ "[B" => :down, "P" => :down,
19
+ "[C" => :right, "M" => :right,
20
+ "[D" => :left, "K" => :left,
21
+ "[3~" => :delete, "S" => :delete,
22
+ "[H" => :home, "G" => :home,
23
+ "[F" => :end, "O" => :end,
24
+ "[Z" => :shift_tab
25
+ }
26
+
27
+ class InputState
28
+ attr_accessor :options, :answer, :position
29
+
30
+ def initialize(options = {}, answer = "", position = 0)
31
+ @options = options
32
+ @answer = answer
33
+ @position = position
34
+ @done = false
35
+ end
36
+
37
+ # Call to signal to the input reader that it can stop.
38
+ def done!
39
+ @done = true
40
+ end
41
+
42
+ # Is the input finished/complete?
43
+ def done?
44
+ @done
45
+ end
46
+
47
+ def censor(what)
48
+ if with = @options[:echo]
49
+ with * what.size
50
+ else
51
+ what
52
+ end
53
+ end
54
+
55
+ def display(what)
56
+ print(censor(what))
57
+ @position += what.size
58
+ end
59
+
60
+ def back(x)
61
+ return if x == 0
62
+
63
+ print("\b" * (x * char_size))
64
+
65
+ @position -= x
66
+ end
67
+
68
+ def clear(x)
69
+ return if x == 0
70
+
71
+ print(" " * (x * char_size))
72
+
73
+ @position += x
74
+
75
+ back(x)
76
+ end
77
+
78
+ def goto(pos)
79
+ return if pos == position
80
+
81
+ if pos > position
82
+ display(answer[position .. pos])
83
+ else
84
+ print("\b" * (position - pos) * char_size)
85
+ end
86
+
87
+ @position = pos
88
+ end
89
+
90
+ private
91
+
92
+ def char_size
93
+ @options[:echo] ? @options[:echo].size : 1
94
+ end
95
+ end
96
+
97
+ def read_char(options = {})
98
+ input = options[:input] || $stdin
99
+
100
+ with_char_io(input) do
101
+ get_character(input)
102
+ end
103
+ end
104
+
105
+ def read_event(options = {})
106
+ input = options[:input] || $stdin
107
+
108
+ with_char_io(input) do
109
+ get_event(input)
110
+ end
111
+ end
112
+
113
+ def read_line(options = {})
114
+ input = options[:input] || $stdin
115
+
116
+ state = input_state(options)
117
+ with_char_io(input) do
118
+ until state.done?
119
+ handler(get_event(input), state)
120
+ end
121
+ end
122
+
123
+ state.answer
124
+ end
125
+
126
+ def asks(question, options = {})
127
+ choices = options[:choices] && options[:choices].to_a
128
+
129
+ list_choices(choices, options) if choices
130
+
131
+ while true
132
+ prompt(question, options)
133
+ ok, res = new_answered(read_line(options), options)
134
+ return res if ok
135
+ end
136
+ end
137
+
138
+ private
139
+
140
+ def clear_input(state)
141
+ state.goto(0)
142
+ state.clear(state.answer.size)
143
+ state.answer = ""
144
+ end
145
+
146
+ def set_input(state, input)
147
+ clear_input(state)
148
+ state.display(input)
149
+ state.answer = input
150
+ end
151
+
152
+ def redraw_input(state)
153
+ pos = state.position
154
+ state.goto(0)
155
+ state.display(state.answer)
156
+ state.goto(pos)
157
+ end
158
+
159
+ def input_state(options)
160
+ InputState.new(options)
161
+ end
162
+
163
+ def get_event(input)
164
+ escaped = false
165
+ escape_seq = ""
166
+
167
+ while true
168
+ c = get_character(input)
169
+
170
+ if not c
171
+ return :eof
172
+ elsif c == "\e" || c == "\xE0"
173
+ escaped = true
174
+ elsif escaped
175
+ escape_seq << c
176
+
177
+ if cmd = ESCAPES[escape_seq]
178
+ return cmd
179
+ elsif ESCAPES.select { |k, v|
180
+ k.start_with? escape_seq
181
+ }.empty?
182
+ escaped, escape_seq = false, ""
183
+ end
184
+ elsif EVENTS.key? c
185
+ return EVENTS[c]
186
+ elsif c < " "
187
+ # ignore
188
+ else
189
+ return [:key, c]
190
+ end
191
+ end
192
+ end
193
+
194
+ def new_answered(ans, options)
195
+ print "\n"
196
+
197
+ if ans.empty?
198
+ if options.key?(:default)
199
+ [true, options[:default]]
200
+ end
201
+ elsif choices = options[:choices]
202
+ matches = choices.select { |x|
203
+ choice_completion(x, options).start_with? ans
204
+ }
205
+
206
+ if choices and ans =~ /^\s*\d+\s*$/ and \
207
+ ans.to_i - 1 >= 0 and res = choices.to_a[ans.to_i - 1]
208
+ res = Array.new
209
+ res = res.push(choices.to_a[ans.to_i - 1])
210
+ [true, res]
211
+ #add
212
+ elsif choices and ans =~ /^\s*(\d+,)*\d+\s*$/ and \
213
+ ans.to_i - 1 >= 0
214
+ ans = ans.split(",")
215
+ res = Array.new
216
+ ans.each do |a|
217
+ res.push(choices[a.to_i - 1])
218
+ end
219
+ # res = ["rails.samsungpaas.comrailstest.samsungpaas.com"]
220
+ [true, res]
221
+ #add
222
+ elsif matches.size == 1
223
+ [true, matches.first]
224
+ elsif matches.size > 1
225
+ matches_list = matches.collect { |m|
226
+ show_choice(m, options)
227
+ }.join " or "
228
+
229
+ puts "Please disambiguate: #{matches_list}?"
230
+
231
+ [false, nil]
232
+ else
233
+ puts "Unknown answer, please try again!"
234
+ [false, nil]
235
+ end
236
+ else
237
+ [true, match_type(ans, options[:default])]
238
+ end
239
+ end
240
+
241
+ def list_choices(choices, options = {})
242
+ return unless options[:indexed]
243
+
244
+ choices.each_with_index do |o, i|
245
+ puts "#{i + 1}: #{show_choice(o, options)}"
246
+ end
247
+ end
248
+
249
+ def show_choice(choice, options = {})
250
+ display = options[:display] || proc(&:to_s)
251
+ display.call(choice)
252
+ end
253
+
254
+ def choice_completion(choice, options = {})
255
+ complete = options[:complete] || options[:display] || proc(&:to_s)
256
+ complete.call(choice)
257
+ end
258
+
259
+ def common_prefix(*strs)
260
+ return strs.first.dup if strs.size == 1
261
+
262
+ longest = strs.sort_by(&:size).last
263
+ longest.size.times do |i|
264
+ sub = longest[0..(-1 - i)]
265
+ if strs.all? { |s| s.start_with?(sub) }
266
+ return sub
267
+ end
268
+ end
269
+
270
+ ""
271
+ end
272
+
273
+ def handler(which, state)
274
+ ans = state.answer
275
+ pos = state.position
276
+
277
+ case which
278
+ when :up
279
+ # nothing
280
+
281
+ when :down
282
+ # nothing
283
+
284
+ when :tab
285
+ matches =
286
+ if choices = state.options[:choices]
287
+ choices.collect { |c|
288
+ choice_completion(c, state.options)
289
+ }.select { |c|
290
+ c.start_with? ans
291
+ }
292
+ else
293
+ matching_paths(ans)
294
+ end
295
+
296
+ if matches.empty?
297
+ print("\a") # bell
298
+ else
299
+ old = ans
300
+ ans = state.answer = common_prefix(*matches)
301
+ state.display(ans[pos .. -1])
302
+ print("\a") if ans == old
303
+ end
304
+
305
+ when :right
306
+ unless pos == ans.size
307
+ state.display(ans[pos .. pos])
308
+ end
309
+
310
+ when :left
311
+ unless pos == 0
312
+ state.back(1)
313
+ end
314
+
315
+ when :delete
316
+ unless pos == ans.size
317
+ ans.slice!(pos, 1)
318
+ rest = ans[pos .. -1]
319
+ state.display(rest)
320
+ state.clear(1)
321
+ state.back(rest.size)
322
+ end
323
+
324
+ when :home
325
+ state.goto(0)
326
+
327
+ when :end
328
+ state.goto(ans.size)
329
+
330
+ when :backspace
331
+ if pos > 0
332
+ rest = ans[pos .. -1]
333
+
334
+ ans.slice!(pos - 1, 1)
335
+
336
+ state.back(1)
337
+ state.display(rest)
338
+ state.clear(1)
339
+ state.back(rest.size)
340
+ end
341
+
342
+ when :interrupt
343
+ raise Interrupt.new
344
+
345
+ when :eof
346
+ state.done! if ans.empty?
347
+
348
+ when :kill_word
349
+ if pos > 0
350
+ start = /[[:alnum:]]*\s*[^[:alnum:]]?$/ =~ ans[0 .. (pos - 1)]
351
+
352
+ if pos < ans.size
353
+ to_end = ans.size - pos
354
+ rest = ans[pos .. -1]
355
+ state.clear(to_end)
356
+ end
357
+
358
+ length = pos - start
359
+
360
+ ans.slice!(start, length)
361
+ state.back(length)
362
+ state.clear(length)
363
+
364
+ if to_end
365
+ state.display(rest)
366
+ state.back(to_end)
367
+ end
368
+ end
369
+
370
+ when :enter
371
+ state.done!
372
+
373
+ when Array
374
+ case which[0]
375
+ when :key
376
+ c = which[1]
377
+ rest = ans[pos .. -1]
378
+
379
+ ans.insert(pos, c)
380
+
381
+ state.display(c + rest)
382
+ state.back(rest.size)
383
+ end
384
+
385
+ else
386
+ return false
387
+ end
388
+
389
+ true
390
+ end
391
+
392
+ def matching_paths(input)
393
+ home = File.expand_path("~")
394
+
395
+ Dir.glob(input.sub("~", home) + "*").collect do |p|
396
+ p.sub(home, "~")
397
+ end
398
+ end
399
+
400
+ def prompt(question, options = {})
401
+ print question
402
+
403
+ if (choices = options[:choices]) && !options[:indexed]
404
+ print " (#{choices.collect(&:to_s).join ", "})"
405
+ end
406
+
407
+ case options[:default]
408
+ when true
409
+ print " [Yn]"
410
+ when false
411
+ print " [yN]"
412
+ when nil
413
+ else
414
+ print " [#{options[:default]}]"
415
+ end
416
+
417
+ print ": "
418
+ end
419
+
420
+ def match_type(str, x)
421
+ case x
422
+ when Integer
423
+ str.to_i
424
+ when true, false
425
+ str.upcase.start_with? "Y"
426
+ else
427
+ str
428
+ end
429
+ end
430
+
431
+ def with_char_io(input)
432
+ before = set_input_state(input)
433
+ yield
434
+ ensure
435
+ restore_input_state(input, before)
436
+ end
437
+
438
+ def chr(x)
439
+ x && x.chr
440
+ end
441
+
442
+ private :chr
443
+
444
+ # Definitions for reading character-by-character with no echoing.
445
+ begin
446
+ require "Win32API"
447
+
448
+ def set_input_state(input)
449
+ nil
450
+ end
451
+
452
+ def restore_input_state(input, state)
453
+ nil
454
+ end
455
+
456
+ def get_character(input)
457
+ if input == STDIN
458
+ begin
459
+ chr(Win32API.new("msvcrt", "_getch", [], "L").call)
460
+ rescue
461
+ chr(Win32API.new("crtdll", "_getch", [], "L").call)
462
+ end
463
+ else
464
+ chr(input.getc)
465
+ end
466
+ end
467
+ rescue LoadError
468
+ begin
469
+ require "termios"
470
+
471
+ def set_input_state(input)
472
+ return nil unless input.tty?
473
+ before = Termios.getattr(input)
474
+
475
+ new = before.dup
476
+ new.c_lflag &= ~(Termios::ECHO | Termios::ICANON)
477
+ new.c_cc[Termios::VMIN] = 1
478
+
479
+ Termios.setattr(input, Termios::TCSANOW, new)
480
+
481
+ before
482
+ end
483
+
484
+ def restore_input_state(input, before)
485
+ if before
486
+ Termios.setattr(input, Termios::TCSANOW, before)
487
+ end
488
+ end
489
+
490
+ def get_character(input)
491
+ chr(input.getc)
492
+ end
493
+ rescue LoadError
494
+ begin
495
+ require "ffi-ncurses"
496
+
497
+ def set_input_state(input)
498
+ return nil unless input.tty?
499
+
500
+ FFI::NCurses.initscr
501
+ FFI::NCurses.cbreak
502
+
503
+ true
504
+ end
505
+
506
+ def restore_input_state(input, before)
507
+ if before
508
+ FFI::NCurses.endwin
509
+ end
510
+ end
511
+
512
+ def get_character(input)
513
+ chr(input.getc)
514
+ end
515
+ rescue LoadError
516
+ def set_input_state(input)
517
+ return nil unless input.tty?
518
+
519
+ before = `stty -g`
520
+
521
+ Kernel.system("stty -echo -icanon isig")
522
+
523
+ before
524
+ end
525
+
526
+ def restore_input_state(input, before)
527
+ Kernel.system("stty #{before}") if before
528
+ end
529
+
530
+ def get_character(input)
531
+ chr(input.getc)
532
+ end
533
+ end
534
+ end
535
+ end
536
+
537
+ end
538
+ end