From ba63bcbe0fd067c9d124860af9cb20384db5da84 Mon Sep 17 00:00:00 2001 From: "brettw@chromium.org" Date: Mon, 28 Oct 2013 19:55:48 +0000 Subject: [PATCH] Add a platform filtering and executable setting abilities to download_from_google_storage. Adds a command line flag --platform to control which platforms the given download occurs on. Automatically marks downloads executable on non-Windows if the header x-goog-meta-executable is set. Automatically set this flag on upload when the executable bit is set. BUG=233100 Review URL: https://codereview.chromium.org/42273002 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@231387 0039d316-1c4b-4281-b951-d872f2087c98 --- download_from_google_storage.py | 29 ++++++++++++++++++++++++++++- upload_to_google_storage.py | 13 +++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/download_from_google_storage.py b/download_from_google_storage.py index b398790498..bbb9e64f3b 100755 --- a/download_from_google_storage.py +++ b/download_from_google_storage.py @@ -11,6 +11,7 @@ import optparse import os import Queue import re +import stat import sys import threading import time @@ -185,6 +186,20 @@ def _downloader_worker_thread(thread_num, q, force, base_url, out_q.put('%d> %s' % (thread_num, err)) ret_codes.put((code, err)) + # Mark executable if necessary. We key off of the custom header + # "x-goog-meta-executable". + # + # TODO(hinoka): It is supposedly faster to use "gsutil stat" but that + # doesn't appear to be supported by the gsutil currently in our tree. When + # we update, this code should use that instead of "gsutil ls -L". + if not sys.platform.startswith('win'): + code, out, _ = gsutil.check_call('ls', '-L', file_url) + if code != 0: + out_q.put('%d> %s' % (thread_num, err)) + ret_codes.put((code, err)) + elif re.search('x-goog-meta-executable:', out): + st = os.stat(output_filename) + os.chmod(output_filename, st.st_mode | stat.S_IEXEC) def printer_worker(output_queue): while True: @@ -282,9 +297,21 @@ def main(args): help='Alias for "gsutil config". Run this if you want ' 'to initialize your saved Google Storage ' 'credentials.') + parser.add_option('-p', '--platform', + help='A regular expression that is compared against ' + 'Python\'s sys.platform. If this option is specified, ' + 'the download will happen only if there is a match.') (options, args) = parser.parse_args() - # First, make sure we can find a working instance of gsutil. + + # Make sure we should run at all based on platform matching. + if options.platform: + if not re.match(options.platform, sys.platform): + print('The current platform doesn\'t match "%s", skipping.' % + options.platform) + return 0 + + # Make sure we can find a working instance of gsutil. if os.path.exists(GSUTIL_DEFAULT_PATH): gsutil = Gsutil(GSUTIL_DEFAULT_PATH, boto_path=options.boto) else: diff --git a/upload_to_google_storage.py b/upload_to_google_storage.py index f10a8d83f6..e6cd2eeb5e 100755 --- a/upload_to_google_storage.py +++ b/upload_to_google_storage.py @@ -10,6 +10,7 @@ import optparse import os import Queue import re +import stat import sys import threading import time @@ -103,6 +104,18 @@ def _upload_worker( (filename, file_url, err))) continue + # Mark executable files with the header "x-goog-meta-executable: 1" which + # the download script will check for to preserve the executable bit. + if not sys.platform.startswith('win'): + if os.stat(filename).st_mode & stat.S_IEXEC: + code, _, err = gsutil.check_call('setmeta', '-h', + 'x-goog-meta-executable:1', file_url) + if code: + ret_codes.put( + (code, + 'Encountered error on setting metadata on %s\n%s' % + (file_url, err))) + def get_targets(args, parser, use_null_terminator): if not args: