arvados-cli 0.1.20150108184905 → 0.1.20150112183934

Sign up to get free protection for your applications and to get access to all the features.
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