zillabyte-cli 0.0.23 → 0.0.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NDg1OTM3OGJmYzhiM2VkN2Y4MTFlYzMzNWJiZDM5NDc1MTljYWVkNw==
4
+ NzQ3YzkyMjYxM2QzZTIzMWVlZmNlNzQ2NTc2MWE2ODkxZTA2NGM1Ng==
5
5
  data.tar.gz: !binary |-
6
- ZjgxNTcxYjZjYTUwODc4NzQ1MGRkZjA4OGMzZjNhNGI1ZjM4MDI1Ng==
6
+ NjlkZmQ0ODY0Y2EyYTM1ZDRiZWQ4YmQ5Zjk0NzFlOWRkNTMxY2QzMg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YjhlNjQ0NDZlYTk3NjczMWViNTg0ODQ3ZDg3MDM0ZDU3MDM3YTRlMGQ1ZjE1
10
- MjRmNTNlNTQyMWFmYzY3ODBmOGZkNWUwNTgwNzA4MmNhMzNlYzM0MGQxMTI4
11
- NjM3NDM5YzQ5OGJiMGMzNmE3MDRiMzBhNzAwNWUzYTdkYzM2OGQ=
9
+ N2UxNmUyZjlkZGZhZWZkNjM3MzM2MmE5YWM5MzBmMjMyZDc3N2UzNDI3ZDYz
10
+ NWNmYjhhODM0NmExYzI1ZTVkODgxMjZlOTcyN2NmNWRjZjI2MGQ3NjAwNzI1
11
+ MzQxZGZlYzA5YzI0OThlNWJjZTI5YzU3MmI3MzI1MmVmY2Q2YjM=
12
12
  data.tar.gz: !binary |-
13
- YjExOGE1ODBmMDliMzI2OTExMTdhNGY4NTI3ZGI4MDc3ZGQ1NWUxYTNhOWFk
14
- YTg2ZDUwNmE0NjllMWJjZWI0NTE4ZjI3MWFkNzA0MTMzMzJhNzRkNTNjM2Jj
15
- MDQyODIwYjFiMmVkYWU5ZTM0Y2EyMzkzYzUwZTg0ZGZjYWE4ZTg=
13
+ N2YxNzllMGY3MzYyZGQ5MzgyZDJiZmZkZTcyNmY5Mzk1NmQxODM1NDI1YjUz
14
+ NjEyMzNmM2ZlMzQ2NTAwMmMxOGY3MWRkNmQxNjM0OGI3YTFhZTZlMTlmMTA4
15
+ OTgzZWFjNDNkNTBjMDE3MGEyMzY5ZjU4OThhNjA5ZDhhMmI4MWQ=
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  TODO: Write a gem description
4
4
 
5
+
5
6
  ## Installation
6
7
 
7
8
  Add this line to your application's Gemfile:
@@ -27,3 +28,9 @@ TODO: Write usage instructions here
27
28
  3. Commit your changes (`git commit -am 'Add some feature'`)
28
29
  4. Push to the branch (`git push origin my-new-feature`)
29
30
  5. Create new Pull Request
31
+
32
+
33
+ # F.A.Q.
34
+
35
+ ### How does the CLI communicate with the API?
36
+
@@ -116,7 +116,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
116
116
  def pull_to_directory(id, dir, session = nil, options = {})
117
117
 
118
118
  # Get the resource. note query params
119
- type = options[:type]
119
+ type = options[:output_type]
120
120
  session.display "downloading ##{id}" if session && type.nil?
121
121
  res = @api.request(
122
122
  :expects => 200,
@@ -164,7 +164,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
164
164
  #
165
165
  def push_directory(dir, session = nil, options = {})
166
166
 
167
- type = options[:type]
167
+ type = options[:output_type]
168
168
  # Get the meta info
169
169
  options[:local_flag] = 1
170
170
  hash = Zillabyte::API::Apps.get_rich_meta_info_from_script(dir, session, options)
@@ -242,7 +242,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
242
242
  return {"status" => "error", "error" => "invalid_directory", "error_message" => "The specified directory (#{dir}) does not appear to contain a valid Zillabyte configuration file."}
243
243
  end
244
244
 
245
- type = options[:type]
245
+ type = options[:output_type]
246
246
 
247
247
  full_script = File.join(dir, hash['script'])
248
248
  command = nil
@@ -3,7 +3,6 @@ require 'open-uri'
3
3
 
4
4
  class Zillabyte::API::Logs < Zillabyte::API::Base
5
5
 
6
-
7
6
  # GET /flows/ID/logs
8
7
  def get(app_id, operation_id, options = {}, &block)
9
8
 
@@ -13,7 +12,7 @@ class Zillabyte::API::Logs < Zillabyte::API::Base
13
12
  res = @api.request({
14
13
  :expects => 200,
15
14
  :method => :get,
16
- :path => "/flows/#{app_id}/logs/#{operation_id}/stream",
15
+ :path => "/flows/#{app_id}/logs",
17
16
  :body => options.to_json
18
17
  }, &block)
19
18
 
@@ -7,18 +7,19 @@ require 'open3'
7
7
  require 'securerandom'
8
8
  require 'colorize'
9
9
  require 'time_difference'
10
+ require 'net/http'
10
11
 
11
12
  # manage custom apps
12
13
  #
13
14
  class Zillabyte::Command::Apps < Zillabyte::Command::Base
14
15
 
15
- MAX_POLL_SECONDS = 60 * 5
16
+ MAX_POLL_SECONDS = 60 * 15
16
17
  POLL_SLEEP = 0.5
17
18
 
18
19
  # apps
19
20
  #
20
21
  # list custom apps
21
- # --type TYPE # specify an output type i.e. json
22
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
22
23
  #
23
24
  def index
24
25
  self.list
@@ -29,9 +30,9 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
29
30
  # apps
30
31
  #
31
32
  # list custom apps
32
- # --type TYPE # specify an output type i.e. json
33
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
33
34
  def list
34
- type = options[:type]
35
+ type = options[:output_type]
35
36
 
36
37
  headings = ["id", "name", "state", "cycles"]
37
38
  rows = api.app.list.map do |row|
@@ -56,7 +57,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
56
57
  def details
57
58
 
58
59
  app_id = options[:id] || shift_argument
59
- type = options[:type]
60
+ type = options[:output_type]
60
61
 
61
62
  if app_id.nil?
62
63
  app_id = read_name_from_conf(options)
@@ -182,7 +183,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
182
183
  # uploads an app
183
184
  #
184
185
  # --config CONFIG_FILE # use the given config file
185
- # --type TYPE # specify an output type i.e. json
186
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
186
187
  # --directory DIR # app directory
187
188
  #
188
189
  #Examples:
@@ -199,7 +200,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
199
200
  dir = File.expand_path(dir)
200
201
  end
201
202
  options[:directory] = dir
202
- type = options[:type]
203
+ type = options[:output_type]
203
204
 
204
205
  res = api.apps.push_directory dir, session, options
205
206
 
@@ -212,21 +213,11 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
212
213
  display "Starting up your app...please wait..." if type.nil?
213
214
  sleep(2) # wait for kill command
214
215
 
215
- lf = LogFormatter::Startup.new
216
- api.logs.get_startup(res['id'], "_ALL_", {:push => true}) do |hash|
217
-
218
- # Error?
219
- error(hash['error_message'], type) if hash['error']
220
-
221
- # Print it
222
- lf.print_log_line(hash) if type.nil?
223
-
224
- # Exit when we get the 'done' message
225
- # exit(0) if (hash['line'] || '').downcase.include?("app deployed")
226
-
227
- end
216
+ hash = self.api.logs.get(res['id'], nil, options)
217
+ fetch_logs(hash, "_ALL_", "App deployed")
218
+
228
219
  display "{}" if type == "json"
229
-
220
+
230
221
  end
231
222
  alias_command "push", "apps:push"
232
223
 
@@ -237,7 +228,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
237
228
  # pulls an app source to a directory.
238
229
  #
239
230
  # --force # pulls even if the directory exists
240
- # --type TYPE # specify an output type i.e. json
231
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
241
232
  # --directory DIR # Directory of the app
242
233
  #
243
234
  # Examples:
@@ -256,7 +247,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
256
247
  error("no directory given", type) if dir.nil?
257
248
  dir = File.expand_path(dir)
258
249
 
259
- type = options[:type]
250
+ type = options[:output_type]
260
251
 
261
252
  error("no id given", type) if app_id.nil?
262
253
 
@@ -290,7 +281,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
290
281
  # deletes an app. if the app is running, this command will kill it.
291
282
  #
292
283
  # -f, --force # don't ask for confirmation
293
- # --type TYPE # specify an output type i.e. json
284
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
294
285
  #
295
286
  def delete
296
287
  app_id = options[:id] || shift_argument
@@ -302,7 +293,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
302
293
  options[:is_name] = true
303
294
  end
304
295
  forced = options[:force]
305
- type = options[:type]
296
+ type = options[:output_type]
306
297
 
307
298
  if not forced
308
299
 
@@ -338,11 +329,11 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
338
329
  # performs any necessary initialization for the app
339
330
  #
340
331
  # --directory DIR # app directory
341
- # --type TYPE # specify an output type i.e. json
332
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
342
333
  #
343
334
  def prep
344
335
 
345
- type = options[:type]
336
+ type = options[:output_type]
346
337
  dir = options[:directory] || shift_argument
347
338
  if dir.nil?
348
339
  dir = Dir.pwd
@@ -392,7 +383,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
392
383
  # initializes a new executable in DIR
393
384
  # [LANG] defaults to ruby, and [DIR] to the current directory
394
385
  #
395
- # --type TYPE # specify an output type i.e. json
386
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
396
387
  # --directory DIR # Directory of the app
397
388
  #
398
389
  #Examples:
@@ -408,7 +399,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
408
399
  else
409
400
  dir = File.expand_path(dir)
410
401
  end
411
- type = options[:type]
402
+ type = options[:output_type]
412
403
 
413
404
  languages = ["ruby","python", "js"]
414
405
 
@@ -426,7 +417,8 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
426
417
  #
427
418
  # streams logs from the distributed workers
428
419
  #
429
- # --type TYPE # specify an output type i.e. json
420
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
421
+ # --operation OPERATION_NAME # specify the operation to show logs for
430
422
  # -v, --verbose LEVEL # sets the verbosity (error, info, debug) (default: info)
431
423
  #
432
424
  def logs
@@ -441,20 +433,16 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
441
433
 
442
434
  operation_id = options[:operation] || shift_argument || '_ALL_'
443
435
  category = options[:verbose] || '_ALL_'
444
- type = options[:type]
436
+ type = options[:output_type]
445
437
 
446
438
  carry_settings = {
447
439
  :category => category
448
440
  }
449
441
 
450
442
  display "Retrieving logs for app ##{app_id}...please wait..." if type.nil?
451
- lf = LogFormatter::Operation.new
452
- self.api.logs.get(app_id, operation_id, options) do |line|
453
-
454
- error(line['error_message'], type) if line['error']
455
- lf.print_log_line(line) if type.nil?
456
-
457
- end
443
+ hash = self.api.logs.get(app_id, operation_id, options)
444
+
445
+ fetch_logs(hash, operation_id)
458
446
 
459
447
  end
460
448
  alias_command "logs", "apps:logs"
@@ -464,7 +452,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
464
452
  # apps:errors ID
465
453
  #
466
454
  # show recent errors generated by the app
467
- # --type TYPE # specify an output type i.e. json
455
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
468
456
  #
469
457
  def errors
470
458
 
@@ -479,7 +467,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
479
467
  options[:is_name] = true
480
468
  end
481
469
 
482
- type = options[:type]
470
+ type = options[:output_type]
483
471
 
484
472
  # Make the request
485
473
  res = api.request(
@@ -521,6 +509,14 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
521
509
  end
522
510
 
523
511
  end
512
+
513
+
514
+
515
+
516
+
517
+
518
+
519
+
524
520
 
525
521
  # apps:cycles ID [OPTIONS]
526
522
  #
@@ -528,11 +524,11 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
528
524
  # with no options, the command lists the apps cycles
529
525
  # -n, --next # request the app to move to the next cycle
530
526
  # -f, --forever # don't wait on cycles any more
531
- # --type TYPE # specify an output type i.e. json
527
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
532
528
  #
533
529
  def cycles
534
530
  app_id = options[:id] || shift_argument
535
- type = options[:type]
531
+ type = options[:output_type]
536
532
 
537
533
  trigger_next = options[:next] || false
538
534
  trigger_forever = options[:forever] || false
@@ -622,7 +618,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
622
618
  def test
623
619
 
624
620
  output = options[:output]
625
- otype = options[:type] #type is used below for something else
621
+ otype = options[:output_type] #type is used below for something else
626
622
 
627
623
  max_seconds = (options[:wait] || "30").to_i
628
624
  batches = (options[:batches] || "1").to_i
@@ -912,7 +908,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
912
908
  op_display.call "receiving: #{display_hash}"
913
909
  elsif write_json['command'] == 'next'
914
910
  last_call_next_tuple = true
915
- op_display.call "getting next set of tuples in the batch"
911
+ op_display.call "asking for next tuple(s)"
916
912
  else
917
913
  # puts write_json
918
914
  end
@@ -951,7 +947,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
951
947
 
952
948
  # Get next message
953
949
  read_msg = read_message(stdout, color);
954
-
950
+
955
951
  if read_msg == "done" || read_msg.nil?
956
952
 
957
953
  # For sources, if we receive a "done", check to see if any of the streams emitted by the source has
@@ -1085,12 +1081,12 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
1085
1081
  # kills the given app
1086
1082
  #
1087
1083
  # --config CONFIG_FILE # use the given config file
1088
- # --type TYPE # specify an output type i.e. json
1084
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
1089
1085
  #
1090
1086
  def kill
1091
1087
 
1092
1088
  id = options[:id] || shift_argument
1093
- type = options[:type]
1089
+ type = options[:output_type]
1094
1090
 
1095
1091
  if id.nil?
1096
1092
  id = read_name_from_conf(options)
@@ -1116,14 +1112,14 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
1116
1112
  # runs a local app with live data
1117
1113
  #
1118
1114
  # --config CONFIG_FILE # use the given config file
1119
- # --type TYPE # specify an output type i.e. json
1115
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
1120
1116
  # --directory DIR # Directory of the app
1121
1117
  #
1122
1118
  # HIDDEN:
1123
1119
  def live_run
1124
1120
 
1125
1121
  name = options[:name] || shift_argument
1126
- type = options[:type]
1122
+ type = options[:output_type]
1127
1123
 
1128
1124
  thread_id = options[:thread] || shift_argument || ""
1129
1125
  dir = options[:directory] || shift_argument
@@ -1154,13 +1150,13 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
1154
1150
  #
1155
1151
  # fetches detailed status of the app
1156
1152
  #
1157
- # --type TYPE # specify an output type i.e. json
1153
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
1158
1154
  # --directory DIR # Directory of the app
1159
1155
  #
1160
1156
  def status
1161
1157
 
1162
1158
  id = options[:id] || shift_argument
1163
- type = options[:type]
1159
+ type = options[:output_type]
1164
1160
 
1165
1161
  if id.nil?
1166
1162
  id = read_name_from_conf(options)
@@ -1193,7 +1189,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
1193
1189
  # outputs the info for the app in the dir.
1194
1190
  #
1195
1191
  # --pretty # Pretty prints the info output
1196
- # --type TYPE # specify an output type i.e. json
1192
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
1197
1193
  # --directory DIR # Directory of the app
1198
1194
  #
1199
1195
  def info
@@ -1207,7 +1203,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
1207
1203
  options[:directory] = dir
1208
1204
 
1209
1205
  info_file = "#{dir}/#{SecureRandom.uuid}"
1210
- type = options[:type]
1206
+ type = options[:output_type]
1211
1207
 
1212
1208
  cmd = command("--info --file #{info_file}", type, dir)
1213
1209
  app_info = Zillabyte::Command::Apps.get_info(cmd, info_file, dir, options)
@@ -1228,17 +1224,17 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
1228
1224
 
1229
1225
 
1230
1226
  #
1231
- # --type TYPE # specify an output type i.e. json
1227
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
1232
1228
  #
1233
1229
  def self.get_info(cmd, info_file, dir, options = {})
1234
- type = options[:type]
1230
+ type = options[:output_type]
1235
1231
 
1236
1232
  response = `#{cmd}`
1237
1233
  if($?.exitstatus == 1)
1238
1234
 
1239
1235
  File.delete("#{info_file}") if File.exists?(info_file)
1240
1236
 
1241
- if options[:type].nil?
1237
+ if options[:output_type].nil?
1242
1238
  exit(1)
1243
1239
  else
1244
1240
  Zillabyte::Helpers.error("error: #{response}", type)
@@ -1272,7 +1268,7 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
1272
1268
  private
1273
1269
 
1274
1270
  #
1275
- # --type TYPE # specify an output type i.e. json
1271
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
1276
1272
  #
1277
1273
  def command(arg="--execute_live", type = nil, dir = Dir.pwd, ignore_stderr = false)
1278
1274
  meta = Zillabyte::CLI::Config.get_config_info(dir, self, options)
@@ -1331,10 +1327,43 @@ class Zillabyte::Command::Apps < Zillabyte::Command::Base
1331
1327
  #
1332
1328
  #
1333
1329
  def read_name_from_conf(options = {})
1334
- type = options[:type]
1330
+ type = options[:output_type]
1335
1331
  hash = Zillabyte::API::Apps.get_rich_meta_info_from_script Dir.pwd, options
1336
1332
  error("No id given and current directory does not contain a valid Zillabyte configuration file. Please specify an app id or run command from the directory containing the app.",type) if hash["error"]
1337
1333
  hash["name"]
1338
1334
  end
1339
1335
 
1336
+ def fetch_logs(hash, operation=nil, exit_on=nil)
1337
+ def color_for(operation_name)
1338
+ @color_map[operation_name] ||= @all_colors[ @color_map.size % @all_colors.size ]
1339
+ @color_map[operation_name]
1340
+ end
1341
+
1342
+ @color_map = {}
1343
+ @all_colors = [:green, :yellow, :magenta, :cyan, :light_black, :light_green, :light_yellow, :light_blue, :light_magenta, :light_cyan]
1344
+ if(hash["server"] == "localhost")
1345
+ cmd = "tail -n 500 -f /tmp/flows/f#{hash["app"]}/flow_logs/app_#{hash["app"]}.log"
1346
+ else
1347
+ cmd = "curl -G http://#{hash["app"]}:#{hash["token"]}@#{hash["server"]}:#{hash["port"]}/getLogs?app=#{hash["app"]}"
1348
+ end
1349
+
1350
+ begin
1351
+ PTY.spawn( cmd ) do |r, w, pid|
1352
+ r.each do |line|
1353
+ begin
1354
+ op = line.match(/\[(.*?)\]/)[0].to_s[1...-1]
1355
+ op_name = op.split(".")[0]
1356
+ next if op_name != operation and operation != "_ALL_"
1357
+ line_split = line.split("[")
1358
+ print line_split[0] + "[" + op.colorize(color_for(op)) + line_split[1..-1].join("[")[op.length..-1]
1359
+ break if exit_on and line.include? exit_on
1360
+ rescue Exception => e
1361
+ next
1362
+ end
1363
+ end
1364
+ end
1365
+ rescue PTY::ChildExited => e
1366
+ end
1367
+ end
1368
+
1340
1369
  end
@@ -18,7 +18,7 @@ module Zillabyte
18
18
  else
19
19
  conf_file = File.join(dir, options[:config_file] || DEFAULT_CONFIG_FILE)
20
20
  end
21
- type = options[:type]
21
+ type = options[:output_type]
22
22
 
23
23
  return nil unless File.exists?(conf_file)
24
24
  hash = YAML.load_file(conf_file)
@@ -0,0 +1,180 @@
1
+ require "zillabyte/cli/base"
2
+ require "zillabyte/cli/config"
3
+ require "zillabyte/common"
4
+ require "pty"
5
+ require 'indentation'
6
+ require 'open3'
7
+ require 'securerandom'
8
+ require 'colorize'
9
+ require 'time_difference'
10
+
11
+
12
+ # executes arbitrary input against apps
13
+ #
14
+ # HIDDEN
15
+ class Zillabyte::Command::Executes < Zillabyte::Command::Base
16
+
17
+ POLL_DELAY = 3
18
+
19
+
20
+ # executes:exec ID INPUT_PARAMS [INPUT_PARAMS]
21
+ #
22
+ # executes an app against with the given parameters. INPUT_PARAMS
23
+ # is expected to be in JSON format.
24
+ #
25
+ # --json # return the results as JSON
26
+ # --async # returns immediately. Use executes:results to fetch results
27
+ # --select FIELDS # returns only the fields in this list. useful for scripting
28
+ #
29
+ # Examples:
30
+ #
31
+ # $ zillabyte exec "web_screenshot", "{url: 'google.com'}"
32
+ # $ zillabyte exec "web_screenshot", "{url: 'google.com'}", "{url: 'facebook.com'}"
33
+ def exec
34
+
35
+ # INIT
36
+ app_id = options[:id] || shift_argument
37
+ async = options[:async] || false
38
+ select_field = options[:select]
39
+
40
+ # Get the inputs
41
+ input_params = []
42
+ while ((ip = shift_argument()) != nil)
43
+ input_params << JSON.parse(ip)
44
+ end
45
+
46
+ # Sanity
47
+ error("At least one input parameter is required") if input_params.size == 0
48
+ error("Unable to execute multiple requests synchronously. Add the --async flag or call with only one input_param") if input_params.size > 1 and !async
49
+ error("The --select option and --async cannot be used at the same time") if async and select_field
50
+
51
+ # Work with concrete ids or names
52
+ if !(app_id =~ /^\d*$/)
53
+ options[:is_name] = true
54
+ end
55
+
56
+ # Build the hash
57
+ options[:input] = input_params
58
+
59
+ # Make the request
60
+ res = api.request(
61
+ :expects => 200,
62
+ :method => :post,
63
+ :body => options.to_json,
64
+ :path => "/flows/#{CGI.escape(app_id)}/executes"
65
+ ).body
66
+
67
+
68
+ if async
69
+
70
+ # Async. Return right away...
71
+ if res['status'] == 'success'
72
+ if options[:display_type] == :json
73
+ display res.to_s
74
+ else
75
+ # TODO:
76
+ display res.to_s
77
+ end
78
+ else
79
+ error res['error_message']
80
+ end
81
+
82
+ else
83
+
84
+ # Synchronous... poll until done..
85
+ execute_ids = res['execute_ids']
86
+ while (true)
87
+
88
+ res = get_results(app_id, execute_ids)
89
+ if res['status'] == 'success'
90
+
91
+ execute_ids.each do |execute_id|
92
+ h = res['results'][execute_id]
93
+ if h['status'] == 'complete'
94
+ if select_field
95
+ display(h['data'][select_field])
96
+ else
97
+ display(h.to_json)
98
+ end
99
+ execute_ids.delete(execute_id)
100
+ end
101
+ end
102
+
103
+ else
104
+ error(res.to_json)
105
+ end
106
+
107
+ if execute_ids.size == 0
108
+ # success. done
109
+ return
110
+ else
111
+ # still more. keep polling
112
+ sleep(POLL_DELAY)
113
+ end
114
+
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+ alias_command "exec", "executes:exec"
121
+ alias_command "execute", "executes:exec"
122
+
123
+
124
+
125
+
126
+
127
+ # executes:results ID EXECUTE_ID [EXECUTE_ID]
128
+ #
129
+ # fetches the results associated with the given execute_id.
130
+ #
131
+ # --json # return the results as JSON
132
+ #
133
+ def results
134
+
135
+ # INIT
136
+ app_id = options[:id] || shift_argument
137
+ execute_ids = []
138
+ while ((eid = shift_argument()) != nil)
139
+ execute_ids << eid
140
+ end
141
+
142
+ # Sanity
143
+ error("at least one execute id parameter is required") if execute_ids.size == 0
144
+
145
+ # Work with concrete ids or names
146
+ if !(app_id =~ /^\d*$/)
147
+ options[:is_name] = true
148
+ end
149
+
150
+ # Fetch the results...
151
+ display( get_results(app_id, execute_ids).to_json )
152
+
153
+
154
+
155
+ end
156
+ alias_command "results", "executes:results"
157
+
158
+
159
+
160
+ private
161
+
162
+ def get_results(app_id, execute_ids)
163
+
164
+ hash = {
165
+ :execute_ids => execute_ids
166
+ }
167
+
168
+ res = api.request(
169
+ :expects => 200,
170
+ :method => :get,
171
+ :body => hash.to_json,
172
+ :path => "/flows/#{CGI.escape(app_id)}/executes"
173
+ ).body
174
+
175
+ return res
176
+
177
+ end
178
+
179
+
180
+ end
@@ -31,7 +31,7 @@ class Zillabyte::Command::Nuke < Zillabyte::Command::Base
31
31
  )
32
32
  res.body
33
33
 
34
- if options[:type] == "json"
34
+ if options[:output_type] == "json"
35
35
  display res.body.to_json
36
36
  else
37
37
  display "Nuked #{res.body['deleted_apps']} app(s) and #{res.body['deleted_apps']} relations(s)"
@@ -13,7 +13,7 @@ class Zillabyte::Command::Query < Zillabyte::Command::Base
13
13
  #
14
14
  # -o, --offset OFFSET # skips to the offset (default: 0)
15
15
  # -l, --limit LIMIT # sets the result limit (default: 20)
16
- # --type TYPE # the output format type i.e json
16
+ # --output_type OUTPUT_TYPE # the output format type i.e json
17
17
  # -t, --tail TAIL # continuously watches for new results
18
18
  #
19
19
  #Examples:
@@ -25,7 +25,7 @@ class Zillabyte::Command::Query < Zillabyte::Command::Base
25
25
  opts = {}
26
26
  opts[:offset] = options[:offset] || 0
27
27
  opts[:limit] = options[:limit] || 10
28
- type = options[:type]
28
+ type = options[:output_type]
29
29
  tail = options[:tail] || false
30
30
  expression = options[:expression] || shift_argument
31
31
  opts[:since] = options[:since]
@@ -117,7 +117,7 @@ class Zillabyte::Command::Query < Zillabyte::Command::Base
117
117
  # -t, --tail TAIL # continuously watches for new results
118
118
  # -s, --since SINCE # newer records since
119
119
  # --no_truncation # doesn't truncate long strings
120
- # --type TYPE # The result display type
120
+ # --output_type OUTPUT_TYPE # The result display type
121
121
  #
122
122
  #Examples:
123
123
  #
@@ -132,7 +132,7 @@ class Zillabyte::Command::Query < Zillabyte::Command::Base
132
132
  tail = options[:tail] || false
133
133
  expression = options[:expression] || shift_argument
134
134
  opts[:since] = options[:since]
135
- type = options[:type]
135
+ type = options[:output_type]
136
136
  seen = {}
137
137
 
138
138
  if expression.nil?
@@ -249,7 +249,7 @@ class Zillabyte::Command::Query < Zillabyte::Command::Base
249
249
 
250
250
  query = options[:query] || shift_argument
251
251
  file = options[:file] || shift_argument
252
- type = options[:type]
252
+ type = options[:output_type]
253
253
  error("no query given", type) if query.nil?
254
254
  error("no file given", type) if file.nil?
255
255
  file = "#{file}.gz" unless File.extname(file) == ".gz"
@@ -312,13 +312,13 @@ class Zillabyte::Command::Query < Zillabyte::Command::Base
312
312
  # query:pull:s3 QUERY S3_KEY S3_SECRET S3_BUCKET s3_FILE_KEY
313
313
  #
314
314
  # pulls query data to S3_BUCKET/FILE_KEY/part***.gz
315
- # --type TYPE # specify an output format type i.e. json
315
+ # --output_type OUTPUT_TYPE # specify an output format type i.e. json
316
316
  def pull_to_s3
317
317
 
318
318
  query = options[:query] || shift_argument
319
319
  error("query cannot be empty", type) if query.nil?
320
320
 
321
- type = options [:type]
321
+ type = options [:output_type]
322
322
 
323
323
  user_s3_access_key = options[:s3_access_key] || shift_argument
324
324
  user_s3_secret = options[:s3_secret] || shift_argument
@@ -18,7 +18,7 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
18
18
  # relations
19
19
  #
20
20
  # lists your custom relations
21
- # --type TYPE # specify an output type i.e. json
21
+ # --output_type OUTPUT_TYPE # specify an output type i.e. json
22
22
  #
23
23
  def index
24
24
  self.list
@@ -26,12 +26,12 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
26
26
 
27
27
 
28
28
  # relations
29
- # v
29
+ #
30
30
  # lists your custom relations
31
31
  #
32
- # --type TYPE # The output format type
32
+ # --output_type OUTPUT_TYPE # The output format type
33
33
  def list
34
- type = options[:type] || nil
34
+ type = options[:output_type] || nil
35
35
 
36
36
  response = api.request(
37
37
  :expects => 200,
@@ -61,11 +61,11 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
61
61
  # deletes a relation
62
62
  #
63
63
  # -f, --force # Delete without asking for confirmation
64
- # --type TYPE # The output format type
64
+ # --output_type OUTPUT_TYPE # The output format type
65
65
  def delete
66
66
  id = options[:id] || shift_argument
67
67
  forced = options[:force]
68
- type = options[:type] || nil
68
+ type = options[:output_type] || nil
69
69
 
70
70
  if !forced
71
71
 
@@ -103,20 +103,20 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
103
103
  #
104
104
  # creates a new relation
105
105
  #
106
- # --schema SCHEMA # Column names and types in the format "field_1:type_1,field_2:type_2,..."
106
+ # --schema SCHEMA # Column names and types in the format "field_1:output_type_1,field_2:output_type_2,..."
107
107
  # --public SCOPE # Make the relation public
108
108
  # --file FILE # A data file
109
109
  # --filetype FILETYPE # File format type, defaults to csv
110
110
  # --description DESCRIPTION # Description of relation contents
111
111
  # --aliases ALIASES # Relation name aliases in the format "alias_1,alias_2,..."
112
- # --type TYPE # The output format type
112
+ # --output_type OUTPUT_TYPE # The output format type
113
113
  #
114
114
  def create
115
115
 
116
116
  name = options[:name] || shift_argument
117
117
  file = options[:file] || nil
118
118
  filetype = options[:filetype] || nil
119
- type = options[:type]
119
+ type = options[:output_type]
120
120
 
121
121
  error("no name given", type) if name.nil?
122
122
 
@@ -156,13 +156,13 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
156
156
  #
157
157
  # adds data to an existing relation
158
158
  # --filetype FILETYPE # Input File format type, defaults to csv
159
- # --type TYPE # Output formatting type i.e. json
159
+ # --output_type OUTPUT_TYPE # Output formatting type i.e. json
160
160
  #
161
161
  def append
162
162
 
163
163
  id = options[:id] || shift_argument
164
164
  file = options[:file] || shift_argument
165
- type = options[:type]
165
+ type = options[:output_type]
166
166
 
167
167
  filetype = options[:filetype]
168
168
  filetype ||= File.extname(file || "").gsub(".", "")
@@ -200,13 +200,13 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
200
200
  # pulls relation data into OUTPUT.gz
201
201
  #
202
202
  # --cycle_id [cycle_id] # retrieve data generated for that cycle, only if this relation is associated with an app. (defaults to the last cycle
203
- # --type TYPE # specify a communication format (i.e json) for programmatic interaction
203
+ # --output_type OUTPUT_TYPE # specify a communication format (i.e json) for programmatic interaction
204
204
  #
205
205
  def pull
206
206
 
207
207
  id = options[:id] || shift_argument
208
208
  file = options[:file] || shift_argument
209
- type = options[:type]
209
+ type = options[:output_type]
210
210
  error("no id given", type) if id.nil?
211
211
  error("no file given", type) if file.nil?
212
212
 
@@ -259,13 +259,13 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
259
259
  # pulls relation data to S3_BUCKET/FILE_KEY/part***.gz
260
260
  #
261
261
  # --cycle_id [cycle_id] # retrieve data generated for that cycle, only if this relation is associated with an app. (defaults to the last cycle)
262
- # -t, --type TYPE # the output format types
262
+ # -t, --output_type OUTPUT_TYPE # the output format types
263
263
  #
264
264
 
265
265
  def pull_to_s3
266
266
 
267
267
  id = options[:id] || shift_argument
268
- type = options[:type]
268
+ type = options[:output_type]
269
269
  error("no id given", type) if id.nil?
270
270
 
271
271
  user_s3_access_key = options[:s3_access_key] || shift_argument
@@ -300,10 +300,10 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
300
300
  #
301
301
  # --cycle_id [cycle_id] # retrieve data generated for that cycle, only if this relation is associated with an app. (defaults to the last cycle)
302
302
  # --no_truncation # don't truncate long strings
303
- # --type TYPE # the type of the output
303
+ # --output_type OUTPUT_TYPE # the type of the output
304
304
  def show
305
305
  name = options[:name] || shift_argument
306
- type = options[:type]
306
+ type = options[:output_type]
307
307
  error "no id given" if name.nil?
308
308
 
309
309
  # Initial request..
@@ -438,7 +438,7 @@ class Zillabyte::Command::Relations < Zillabyte::Command::Base
438
438
  error("specify public or private using --public")
439
439
  end
440
440
 
441
- {:schema => schema, :public => is_public, :description => description, :aliases => aliases, :type => type}
441
+ {:schema => schema, :public => is_public, :description => description, :aliases => aliases, :output_type => type}
442
442
  end
443
443
 
444
444
 
@@ -1,5 +1,6 @@
1
1
  require "zillabyte/cli/base"
2
2
  require 'readline'
3
+ require("shellwords")
3
4
  # REPL console for zillabyte commands
4
5
  #
5
6
  class Zillabyte::Command::Repl < Zillabyte::Command::Base
@@ -11,8 +12,8 @@ class Zillabyte::Command::Repl < Zillabyte::Command::Base
11
12
  # --history HISTORY# HIDDEN hack to allow history for readline
12
13
  def index
13
14
  if !options[:quiet]
14
- v = `zillabyte version`
15
- display "\n#{v}Type q,exit or Ctrl+D to quit\n\n"
15
+ Zillabyte::Command.run("version")
16
+ display "Type q,exit or Ctrl+D to quit\n\n"
16
17
  end
17
18
  server = `echo $ZILLABYTE_API_HOST` || ""
18
19
  prompt = ""
@@ -29,13 +30,28 @@ class Zillabyte::Command::Repl < Zillabyte::Command::Base
29
30
  end
30
31
  end
31
32
  # TODO: Add tab completion for basic commands, app/relation names etc.
33
+ buf = ""
32
34
  while cmd = Readline.readline(prompt, true)
33
35
  if cmd && cmd.length > 0
34
36
  if cmd.downcase == "exit" || cmd.downcase == "q"
35
37
  display "" # TODO Make Ctrl+D print a newline too
36
38
  return
37
39
  else
38
- exec "zillabyte #{cmd}; zillabyte repl --quiet --history '#{Readline::HISTORY.to_a.to_json}'"
40
+ buf << cmd
41
+ begin
42
+ args = Shellwords.split(buf)
43
+ raise if args.empty?()
44
+ command = args.shift
45
+ buf = ""
46
+ begin
47
+ pid = fork() do
48
+ Zillabyte::Command.run(command, args)
49
+ end
50
+ ensure
51
+ Process.waitpid(pid)
52
+ end
53
+ rescue => e
54
+ end
39
55
  end
40
56
  end
41
57
  end
@@ -8,7 +8,7 @@ class Zillabyte::Command::Version < Zillabyte::Command::Base
8
8
  #
9
9
  # display version number of the CLI
10
10
  def index(*direct_args)
11
- if options[:type] == "json"
11
+ if options[:output_type] == "json"
12
12
  display( {:version => Zillabyte::CLI::VERSION}.to_json )
13
13
  else
14
14
  display "Zillabyte CLI Version #{Zillabyte::CLI::VERSION}"
@@ -168,7 +168,7 @@ module Zillabyte
168
168
  # Make the --json command universal..
169
169
  if invalid_options.include?("--json")
170
170
  invalid_options.delete("--json")
171
- opts[:type] = "json"
171
+ opts[:output_type] = "json"
172
172
  end
173
173
 
174
174
  @current_args = args
@@ -1,5 +1,5 @@
1
1
  module Zillabyte
2
2
  module CLI
3
- VERSION = "0.0.23"
3
+ VERSION = "0.0.24"
4
4
  end
5
5
  end
@@ -31,7 +31,6 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency "activesupport", "~> 3.2.11"
32
32
  spec.add_dependency "actionpack", "~> 3.2.13"
33
33
  spec.add_dependency "multi_json", "~> 1.0"
34
- spec.add_dependency "mini_portile", "~> 0.5.0"
35
34
 
36
35
  spec.add_dependency "bundler", "~> 1.3"
37
36
  spec.add_dependency "colorize", "~> 0.6"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zillabyte-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.23
4
+ version: 0.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - zillabyte
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-14 00:00:00.000000000 Z
11
+ date: 2014-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -122,20 +122,6 @@ dependencies:
122
122
  - - ~>
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.0'
125
- - !ruby/object:Gem::Dependency
126
- name: mini_portile
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ~>
130
- - !ruby/object:Gem::Version
131
- version: 0.5.0
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ~>
137
- - !ruby/object:Gem::Version
138
- version: 0.5.0
139
125
  - !ruby/object:Gem::Dependency
140
126
  name: bundler
141
127
  requirement: !ruby/object:Gem::Requirement
@@ -261,6 +247,7 @@ files:
261
247
  - lib/zillabyte/cli/base.rb
262
248
  - lib/zillabyte/cli/config.rb
263
249
  - lib/zillabyte/cli/counters.rb
250
+ - lib/zillabyte/cli/executes.rb
264
251
  - lib/zillabyte/cli/help.rb
265
252
  - lib/zillabyte/cli/helpers/data_schema_builder.rb
266
253
  - lib/zillabyte/cli/helpers/table_output_builder.rb