X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/b653edb9423532b89f9f534033fc5587798b0743..12d990a6590e5f23a5998d29a2d8efdb0f733688:/sdk/cli/bin/arv diff --git a/sdk/cli/bin/arv b/sdk/cli/bin/arv index cf3fffa131..ec3d8061b5 100755 --- a/sdk/cli/bin/arv +++ b/sdk/cli/bin/arv @@ -2,7 +2,7 @@ # Arvados cli client # -# Ward Vandewege +# Ward Vandewege require 'fileutils' @@ -53,17 +53,25 @@ end class Google::APIClient def discovery_document(api, version) api = api.to_s - return @discovery_documents["#{api}:#{version}"] ||= + discovery_uri = self.discovery_uri(api, version) + discovery_uri_hash = Digest::MD5.hexdigest(discovery_uri) + return @discovery_documents[discovery_uri_hash] ||= begin # fetch new API discovery doc if stale - cached_doc = File.expand_path '~/.cache/arvados/discovery_uri.json' - if not File.exist?(cached_doc) or (Time.now - File.mtime(cached_doc)) > 86400 + cached_doc = File.expand_path "~/.cache/arvados/discovery-#{discovery_uri_hash}.json" rescue nil + + if cached_doc.nil? or not File.exist?(cached_doc) or (Time.now - File.mtime(cached_doc)) > 86400 response = self.execute!(:http_method => :get, - :uri => self.discovery_uri(api, version), + :uri => discovery_uri, :authenticated => false) - FileUtils.makedirs(File.dirname cached_doc) - File.open(cached_doc, 'w') do |f| - f.puts response.body + + begin + FileUtils.makedirs(File.dirname cached_doc) + File.open(cached_doc, 'w') do |f| + f.puts response.body + end + rescue + return JSON.load response.body end end @@ -85,8 +93,8 @@ end def init_config # read authentication data from arvados configuration file if present lineno = 0 - config_file = File.expand_path('~/.config/arvados/settings.conf') - if File.exist? config_file then + config_file = File.expand_path('~/.config/arvados/settings.conf') rescue nil + if not config_file.nil? and File.exist? config_file then File.open(config_file, 'r').each do |line| lineno = lineno + 1 # skip comments @@ -110,7 +118,7 @@ def check_subcommands client, arvados, subcommand, global_opts, remaining_opts case subcommand when 'keep' @sub = remaining_opts.shift - if ['get', 'put', 'ls', 'normalize'].index @sub then + if ['get', 'put', 'ls', 'normalize', 'copy'].index @sub then # Native Arvados exec `which arv-#{@sub}`.strip, *remaining_opts elsif ['less', 'check'].index @sub then @@ -143,9 +151,14 @@ def check_subcommands client, arvados, subcommand, global_opts, remaining_opts end end +def arv_edit_save_tmp tmp + FileUtils::cp tmp.path, tmp.path + ".saved" + puts "Saved contents to " + tmp.path + ".saved" +end + def arv_edit client, arvados, global_opts, remaining_opts - n = remaining_opts.shift - if n.nil? or n == "-h" or n == "--help" + uuid = remaining_opts.shift + if uuid.nil? or uuid == "-h" or uuid == "--help" puts head_banner puts "Usage: arv edit [uuid] [fields...]\n\n" puts "Fetch the specified Arvados object, select the specified fields, \n" @@ -162,9 +175,9 @@ def arv_edit client, arvados, global_opts, remaining_opts # determine controller - m = /([a-z0-9]{5})-([a-z0-9]{5})-([a-z0-9]{15})/.match n + m = /([a-z0-9]{5})-([a-z0-9]{5})-([a-z0-9]{15})/.match uuid if !m - if /^[a-f0-9]{32}/.match n + if /^[a-f0-9]{32}/.match uuid abort "Arvados collections are not editable." else abort "#{n} does not appear to be an Arvados uuid" @@ -187,7 +200,7 @@ def arv_edit client, arvados, global_opts, remaining_opts api_method = 'arvados.' + rsc + '.get' result = client.execute(:api_method => eval(api_method), - :parameters => {"uuid" => n}, + :parameters => {"uuid" => uuid}, :authenticated => false, :headers => { authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN'] @@ -213,7 +226,7 @@ def arv_edit client, arvados, global_opts, remaining_opts require 'tempfile' - tmp = Tempfile.new([n, "." + global_opts[:format]]) + tmp = Tempfile.new([uuid, "." + global_opts[:format]]) tmp.write(content) tmp.close @@ -251,9 +264,13 @@ def arv_edit client, arvados, global_opts, remaining_opts n += 1 end puts "\nTry again (y/n)? " - yn = $stdin.read 1 + yn = "X" + while not ["y", "Y", "n", "N"].include?(yn) + yn = $stdin.read 1 + end if yn == 'n' or yn == 'N' - exit 1 + arv_edit_save_tmp tmp + abort end end else @@ -262,31 +279,45 @@ def arv_edit client, arvados, global_opts, remaining_opts end end - tmp.close(true) - - if newobj != results - api_method = 'arvados.' + rsc + '.update' - dumped = Oj.dump(newobj) - result = client.execute(:api_method => eval(api_method), - :parameters => {"uuid" => n, rsc.singularize => dumped}, - :authenticated => false, - :headers => { - authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN'] - }) - - begin - results = JSON.parse result.body - rescue JSON::ParserError => e - abort "Failed to parse server response:\n" + e.to_s - end + begin + if newobj != results + api_method = 'arvados.' + rsc + '.update' + dumped = Oj.dump(newobj) - if result.response.status != 200 - puts "Update failed. Server responded #{result.response.status}: #{results['errors']} " - puts "Update body was:" - puts dumped + begin + result = client.execute(:api_method => eval(api_method), + :parameters => {"uuid" => uuid}, + :body => { rsc.singularize => dumped }, + :authenticated => false, + :headers => { + authorization: 'OAuth2 '+ENV['ARVADOS_API_TOKEN'] + }) + rescue Exception => e + puts "Error communicating with server, error was #{e}" + puts "Update body was:" + puts dumped + arv_edit_save_tmp tmp + abort + end + + begin + results = JSON.parse result.body + rescue JSON::ParserError => e + abort "Failed to parse server response:\n" + e.to_s + end + + if result.response.status != 200 + puts "Update failed. Server responded #{result.response.status}: #{results['errors']} " + puts "Update body was:" + puts dumped + arv_edit_save_tmp tmp + abort + end + else + puts "Object is unchanged, did not update." end - else - puts "Object is unchanged, did not update." + ensure + tmp.close(true) end exit 0 @@ -327,10 +358,6 @@ end def help_resources(option_parser, discovery_document, resource) option_parser.educate - - if not resource.nil? and resource != '--help' then - Trollop::die "Unknown resource type #{resource.inspect}" - end exit 255 end @@ -390,7 +417,7 @@ def parse_arguments(discovery_document, subcommands) if not subcommands.include? resource if not resource_types.include?(resource) - puts "Resource or subcommand '#{resource}' is not recognized.\n\n" + puts "Resource or subcommand '#{resource}' is not recognized.\n\n" if !resource.nil? help_resources(option_parser, discovery_document, resource) end