arvados-cli 0.1.20150108184905 → 0.1.20150112183934

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/arv +147 -171
  3. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 153a67d36836b7514ef712e6d223ffca811f1c04
4
- data.tar.gz: fa5b78b27d52f0670d05dc3a0ec17eaadb5d16e1
3
+ metadata.gz: 6a1c216f86130d1ccfc6b58e9971fb2d66e5127b
4
+ data.tar.gz: a02667962b435b1bbac3b22324da0ff6e0e5f724
5
5
  SHA512:
6
- metadata.gz: 5ffe37170dc000b4651f04624a3dd0c6c2e29338bcf724d265a5bf5a0bbb098a820687c1e678a82a20ee2c36618c1d9845d0dfb2c103a1a08ac5cf0d0ac4fc0b
7
- data.tar.gz: badfb94148c8a34c2d46cbed018a294ed23ad486ebc9900adbc03300288e6e1980192b71c6309bb656e35cb7430eb935198e1e3e5a0390a0e7c7f91c831802f8
6
+ metadata.gz: 8b96c89224d0c3830dff1dc67948351f7f936a7a1578550b8353ef8c853a4876d2ac8e4e17742518af33633efaeeb6e729beaeb2f466852f41eaec23269e84d7
7
+ data.tar.gz: d128b712ad4662be5622a5aaf4f026cdac53f50c62a93dcc526251d7d4be981467ff963603530c0c51e5be25e30627ac217eca106fd609b2280fb1fb4321a59f
data/bin/arv CHANGED
@@ -24,6 +24,7 @@ begin
24
24
  require 'active_support/inflector'
25
25
  require 'yaml'
26
26
  require 'tempfile'
27
+ require 'net/http'
27
28
  rescue LoadError
28
29
  abort <<-EOS
29
30
 
@@ -153,70 +154,126 @@ def check_subcommands client, arvados, subcommand, global_opts, remaining_opts
153
154
  end
154
155
  end
155
156
 
156
- def arv_edit_save_tmp tmp
157
- FileUtils::cp tmp.path, tmp.path + ".saved"
158
- puts "Saved contents to " + tmp.path + ".saved"
159
- end
160
-
161
157
  def command_exists?(command)
162
- ENV['PATH'].split(':').each {|folder| File.executable?(File.join(folder, command))}
158
+ File.executable?(command) || ENV['PATH'].split(':').any? {|folder| File.executable?(File.join(folder, command))}
163
159
  end
164
160
 
165
- def run_editor tmp_file, global_opts
166
- need_edit = true
167
- while need_edit
168
- pid = Process::fork
169
- if pid.nil?
170
- editor = nil
171
- [ENV["VISUAL"], ENV["EDITOR"], "nano", "vi"].each do |e|
172
- editor ||= e if e and command_exists? e
173
- end
174
- if editor.nil?
175
- puts "Could not find any editor to use, please set $VISUAL or $EDITOR to your desired editor."
176
- exit 1
177
- end
178
- exec editor, tmp_file.path
179
- else
180
- Process.wait pid
161
+ def run_editor path
162
+ pid = Process::fork
163
+ if pid.nil?
164
+ editor = nil
165
+ [ENV["VISUAL"], ENV["EDITOR"], "nano", "vi"].each do |e|
166
+ editor ||= e if e and command_exists? e
167
+ end
168
+ if editor.nil?
169
+ abort "Could not find any editor to use, please set $VISUAL or $EDITOR to your desired editor."
181
170
  end
171
+ exec editor, path
172
+ else
173
+ Process.wait pid
174
+ end
175
+
176
+ if $?.exitstatus != 0
177
+ raise "Editor exited with status #{$?.exitstatus}"
178
+ end
179
+ end
182
180
 
183
- if $?.exitstatus == 0
184
- tmp_file.open
185
- newcontent = tmp_file.read()
181
+ def edit_and_commit_object initial_obj, tmp_stem, global_opts, &block
186
182
 
187
- newobj = {}
183
+ content = case global_opts[:format]
184
+ when 'json'
185
+ Oj.dump(initial_obj, :indent => 1)
186
+ when 'yaml'
187
+ initial_obj.to_yaml
188
+ else
189
+ abort "Unrecognized format #{global_opts[:format]}"
190
+ end
191
+
192
+ tmp_file = Tempfile.new([tmp_stem, ".#{global_opts[:format]}"])
193
+ tmp_file.write(content)
194
+ tmp_file.close
195
+
196
+ begin
197
+ error_text = ''
198
+ while true
188
199
  begin
189
- case global_opts[:format]
190
- when 'json'
191
- newobj = Oj.load(newcontent)
192
- when 'yaml'
193
- newobj = YAML.load(newcontent)
194
- end
195
- need_edit = false
196
- rescue Exception => e
197
- n = 1
198
- newcontent.each_line do |line|
199
- puts "#{n.to_s.rjust 4} #{line}"
200
- n += 1
200
+ run_editor tmp_file.path
201
+
202
+ tmp_file.open
203
+ newcontent = tmp_file.read()
204
+ tmp_file.close
205
+
206
+ # Strip lines starting with '#'
207
+ newcontent = newcontent.lines.select {|l| !l.start_with? '#'}.join
208
+
209
+ # Load the new object
210
+ newobj = case global_opts[:format]
211
+ when 'json'
212
+ Oj.load(newcontent)
213
+ when 'yaml'
214
+ YAML.load(newcontent)
215
+ end
216
+
217
+ yield newobj
218
+
219
+ break
220
+ rescue => e
221
+ can_retry = true
222
+ if e.is_a? Psych::SyntaxError
223
+ this_error = "YAML error parsing your input: #{e}"
224
+ elsif e.is_a? JSON::ParserError or e.is_a? Oj::ParseError
225
+ this_error = "JSON error parsing your input: #{e}"
226
+ elsif e.is_a? ArvadosAPIError
227
+ this_error = "API responded with error #{e}"
228
+ else
229
+ this_error = "#{e.class}: #{e}"
230
+ can_retry = false
201
231
  end
202
- puts "Parse error! " + e.to_s
203
- puts "\nTry again (y/n)? "
204
- yn = "X"
205
- while not ["y", "Y", "n", "N"].include?(yn)
206
- yn = $stdin.read 1
207
- end
208
- if yn == 'n' or yn == 'N'
209
- arv_edit_save_tmp tmp_file
210
- abort
232
+ puts this_error
233
+
234
+ tmp_file.open
235
+ newcontent = tmp_file.read()
236
+ tmp_file.close
237
+
238
+ if newcontent == error_text or not can_retry
239
+ FileUtils::cp tmp_file.path, tmp_file.path + ".saved"
240
+ puts "File is unchanged, edit aborted." if can_retry
241
+ abort "Saved contents to " + tmp_file.path + ".saved"
242
+ else
243
+ tmp_file.open
244
+ tmp_file.truncate 0
245
+ error_text = this_error.to_s.lines.map {|l| '# ' + l}.join + "\n"
246
+ error_text += "# Please fix the error and try again.\n"
247
+ error_text += newcontent.lines.select {|l| !l.start_with? '#'}.join
248
+ tmp_file.write error_text
249
+ tmp_file.close
211
250
  end
212
251
  end
213
- else
214
- puts "Editor exited with status #{$?.exitstatus}"
215
- exit $?.exitstatus
216
252
  end
253
+ ensure
254
+ tmp_file.close(true)
217
255
  end
218
256
 
219
- newobj
257
+ nil
258
+ end
259
+
260
+ class ArvadosAPIError < RuntimeError
261
+ end
262
+
263
+ def check_response result
264
+ begin
265
+ results = JSON.parse result.body
266
+ rescue JSON::ParserError, Oj::ParseError => e
267
+ raise "Failed to parse server response:\n" + e.to_s
268
+ end
269
+
270
+ if result.response.status != 200
271
+ raise ArvadosAPIError.new("#{result.response.status}: #{
272
+ ((results['errors'] && results['errors'].join('\n')) ||
273
+ Net::HTTPResponse::CODE_TO_OBJ[status.to_s].to_s.sub(/^Net::HTTP/, '').titleize)}")
274
+ end
275
+
276
+ results
220
277
  end
221
278
 
222
279
  def arv_edit client, arvados, global_opts, remaining_opts
@@ -243,7 +300,7 @@ def arv_edit client, arvados, global_opts, remaining_opts
243
300
  if /^[a-f0-9]{32}/.match uuid
244
301
  abort "Arvados collections are not editable."
245
302
  else
246
- abort "#{n} does not appear to be an Arvados uuid"
303
+ abort "'#{uuid}' does not appear to be an Arvados uuid"
247
304
  end
248
305
  end
249
306
 
@@ -260,79 +317,37 @@ def arv_edit client, arvados, global_opts, remaining_opts
260
317
  abort "Could not determine resource type #{m[2]}"
261
318
  end
262
319
 
263
- api_method = 'arvados.' + rsc + '.get'
264
-
265
- result = client.execute(:api_method => eval(api_method),
266
- :parameters => {"uuid" => uuid},
267
- :authenticated => false,
268
- :headers => {
269
- authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN']
270
- })
271
320
  begin
272
- results = JSON.parse result.body
273
- rescue JSON::ParserError => e
274
- abort "Failed to parse server response:\n" + e.to_s
321
+ result = client.execute(:api_method => eval('arvados.' + rsc + '.get'),
322
+ :parameters => {"uuid" => uuid},
323
+ :authenticated => false,
324
+ :headers => {
325
+ authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN']
326
+ })
327
+ oldobj = check_response result
328
+ rescue => e
329
+ abort "Server error: #{e}"
275
330
  end
276
331
 
277
332
  if remaining_opts.length > 0
278
- results.select! { |k, v| remaining_opts.include? k }
279
- end
280
-
281
- content = ""
282
-
283
- case global_opts[:format]
284
- when 'json'
285
- content = Oj.dump(results, :indent => 1)
286
- when 'yaml'
287
- content = results.to_yaml
288
- end
289
-
290
- tmp_file = Tempfile.new([uuid, "." + global_opts[:format]])
291
- tmp_file.write(content)
292
- tmp_file.close
293
-
294
- newobj = run_editor tmp_file, global_opts
295
-
296
- begin
297
- if newobj != results
298
- api_method = 'arvados.' + rsc + '.update'
299
- dumped = Oj.dump(newobj)
300
-
301
- begin
302
- result = client.execute(:api_method => eval(api_method),
303
- :parameters => {"uuid" => uuid},
304
- :body_object => { rsc.singularize => dumped },
305
- :authenticated => false,
306
- :headers => {
307
- authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN']
308
- })
309
- rescue Exception => e
310
- puts "Error communicating with server, error was #{e}"
311
- puts "Update body was:"
312
- puts dumped
313
- arv_edit_save_tmp tmp_file
314
- abort
315
- end
316
-
317
- begin
318
- results = JSON.parse result.body
319
- rescue JSON::ParserError => e
320
- arv_edit_save_tmp tmp_file
321
- abort "Failed to parse server response:\n" + e.to_s
322
- end
323
-
324
- if result.response.status != 200
325
- puts "Update failed. Server responded #{result.response.status}: #{results['errors']} "
326
- puts "Update body was:"
327
- puts dumped
328
- arv_edit_save_tmp tmp_file
329
- abort
330
- end
333
+ oldobj.select! { |k, v| remaining_opts.include? k }
334
+ end
335
+
336
+ edit_and_commit_object oldobj, uuid, global_opts do |newobj|
337
+ newobj.select! {|k| newobj[k] != oldobj[k]}
338
+ if !newobj.empty?
339
+ result = client.execute(:api_method => eval('arvados.' + rsc + '.update'),
340
+ :parameters => {"uuid" => uuid},
341
+ :body_object => { rsc.singularize => newobj },
342
+ :authenticated => false,
343
+ :headers => {
344
+ authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN']
345
+ })
346
+ results = check_response result
347
+ puts "Updated object #{results['uuid']}"
331
348
  else
332
349
  puts "Object is unchanged, did not update."
333
350
  end
334
- ensure
335
- tmp_file.close(true)
336
351
  end
337
352
 
338
353
  exit 0
@@ -379,60 +394,21 @@ def arv_create client, arvados, global_opts, remaining_opts
379
394
  end
380
395
  end
381
396
 
382
-
383
- newobj = {}
397
+ initial_obj = {}
384
398
  if create_opts[:project_uuid]
385
- newobj["owner_uuid"] = create_opts[:project_uuid]
386
- end
387
-
388
- case global_opts[:format]
389
- when 'json'
390
- content = Oj.dump(newobj, :indent => 1)
391
- when 'yaml'
392
- content = newobj.to_yaml
393
- end
394
-
395
- tmp_file = Tempfile.new(["", ".#{global_opts[:format]}"])
396
- tmp_file.write(content)
397
- tmp_file.close
398
-
399
- newobj = run_editor tmp_file, global_opts
400
-
401
- begin
402
- api_method = 'arvados.' + rsc + '.create'
403
- dumped = Oj.dump(newobj)
404
-
405
- result = client.execute(:api_method => eval(api_method),
406
- :parameters => method_opts,
407
- :body_object => {object_type => newobj},
408
- :authenticated => false,
409
- :headers => {
410
- authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN']
411
- })
412
-
413
- begin
414
- results = JSON.parse result.body
415
- rescue JSON::ParserError => e
416
- arv_edit_save_tmp tmp_file
417
- abort "Failed to parse server response:\n" + e.to_s
418
- end
419
-
420
- if result.response.status != 200
421
- puts "Create failed. Server responded #{result.response.status}: #{results['errors']} "
422
- puts "Create body was:"
423
- puts dumped
424
- arv_edit_save_tmp tmp_file
425
- abort
426
- end
427
-
428
- begin
429
- puts "Created object #{results['uuid']}"
430
- rescue
431
- arv_edit_save_tmp tmp_file
432
- abort "Unexpected response:\n#{results}"
433
- end
434
- ensure
435
- tmp_file.close(true)
399
+ initial_obj["owner_uuid"] = create_opts[:project_uuid]
400
+ end
401
+
402
+ edit_and_commit_object initial_obj, "", global_opts do |newobj|
403
+ result = client.execute(:api_method => eval('arvados.' + rsc + '.create'),
404
+ :parameters => method_opts,
405
+ :body_object => {object_type => newobj},
406
+ :authenticated => false,
407
+ :headers => {
408
+ authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN']
409
+ })
410
+ results = check_response result
411
+ puts "Created object #{results['uuid']}"
436
412
  end
437
413
 
438
414
  exit 0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arvados-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.20150108184905
4
+ version: 0.1.20150112183934
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arvados Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-08 00:00:00.000000000 Z
11
+ date: 2015-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: arvados
@@ -178,7 +178,7 @@ dependencies:
178
178
  - - "<"
179
179
  - !ruby/object:Gem::Version
180
180
  version: 1.0.0
181
- description: Arvados command line tools, git commit 5523be76b00bc58cf9568cf7a1353326c6795cac
181
+ description: Arvados command line tools, git commit 138a4b0a5de177faede5255841a5c6fca06b31f4
182
182
  email: gem-dev@curoverse.com
183
183
  executables:
184
184
  - arv