Add does_storage_object_exist to gs_utils
Needed for recreate_skps script
BUG=skia:3008
Review URL: https://codereview.chromium.org/661563002
diff --git a/.gitignore b/.gitignore
index 2f78cf5..f4bf1d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
*.pyc
-
+third_party/externals
diff --git a/py/utils/gs_utils.py b/py/utils/gs_utils.py
index d5c5b95..fd9999c 100644
--- a/py/utils/gs_utils.py
+++ b/py/utils/gs_utils.py
@@ -52,7 +52,7 @@
# each core sits idle waiting for network I/O to complete.
DEFAULT_UPLOAD_THREADS = 10
-_GS_PREFIX = 'gs://'
+GS_PREFIX = 'gs://'
class AnonymousGSConnection(GSConnection):
@@ -132,19 +132,34 @@
Params:
boto_file_path: full path (local-OS-style) on local disk where .boto
- credentials file can be found. If None, then the GSUtils object
- created will be able to access only public files in Google Storage.
+ credentials file can be found. If None, fall back on the
+ AWS_CREDENTIAL_FILE environment variable, then look in a set of
+ common paths for the .boto file. If no .boto file is found, then the
+ GSUtils object created will be able to access only public files in
+ Google Storage.
Raises an exception if no file is found at boto_file_path, or if the file
found there is malformed.
"""
self._gs_access_key_id = None
self._gs_secret_access_key = None
+ if not boto_file_path:
+ if os.environ.get('AWS_CREDENTIAL_FILE'):
+ boto_file_path = os.path.expanduser(os.environ['AWS_CREDENTIAL_FILE'])
+ if not boto_file_path:
+ for path in (os.path.join(os.path.expanduser('~'), '.boto'),):
+ if os.path.isfile(path):
+ boto_file_path = path
+ break
+
if boto_file_path:
print ('Reading boto file from %s' % boto_file_path)
boto_dict = _config_file_as_dict(filepath=boto_file_path)
self._gs_access_key_id = boto_dict['gs_access_key_id']
self._gs_secret_access_key = boto_dict['gs_secret_access_key']
+ else:
+ print >> sys.stderr, 'Warning: no .boto file found.'
+
# Which field we get/set in ACL entries, depending on IdType.
self._field_by_id_type = {
self.IdType.GROUP_BY_DOMAIN: 'domain',
@@ -582,13 +597,24 @@
dirs.append(item.name[prefix_length:-1])
return (dirs, files)
+ def does_storage_object_exist(self, bucket, object_name):
+ """Determines whether an object exists in Google Storage.
+
+ Returns True if it exists else returns False.
+ """
+ b = self._connect_to_bucket(bucket=bucket)
+ if object_name in b:
+ return True
+ dirs, files = self.list_bucket_contents(bucket, object_name)
+ return bool(dirs or files)
+
@staticmethod
def is_gs_url(url):
"""Returns True if url is a legal Google Storage URL ("gs://bucket/file").
"""
try:
- if url.lower().startswith(_GS_PREFIX) and len(url) > len(_GS_PREFIX):
- return url[len(_GS_PREFIX)].isalnum()
+ if url.lower().startswith(GS_PREFIX) and len(url) > len(GS_PREFIX):
+ return url[len(GS_PREFIX)].isalnum()
else:
return False
except AttributeError:
@@ -602,7 +628,7 @@
"""
if not GSUtils.is_gs_url(url):
raise AttributeError('"%s" is not a legal Google Storage URL' % url)
- prefix_removed = url[len(_GS_PREFIX):]
+ prefix_removed = url[len(GS_PREFIX):]
pathsep_index = prefix_removed.find('/')
if pathsep_index < 0:
return (prefix_removed, '')
diff --git a/py/utils/gs_utils_manualtest.py b/py/utils/gs_utils_manualtest.py
index 3365055..2ba63e4 100755
--- a/py/utils/gs_utils_manualtest.py
+++ b/py/utils/gs_utils_manualtest.py
@@ -388,6 +388,17 @@
path=posixpath.join(remote_dir, subdir, filename))
+def _test_does_storage_object_exist():
+ gs = gs_utils.GSUtils()
+ cases = (('gs_utils_manualtest/4843645167453050644/subdir/file1', True),
+ ('gs_utils_manualtest', True),
+ ('bogus', False))
+ for obj, expect in cases:
+ msg = 'expected exists(%s) to be %s' % (
+ '/'.join(('gs:/', TEST_BUCKET, obj)), expect)
+ assert gs.does_storage_object_exist(TEST_BUCKET, obj) == expect, msg
+
+
if __name__ == '__main__':
_test_static_methods()
_test_upload_if_multiple_files()
@@ -395,5 +406,6 @@
_test_public_read()
_test_authenticated_round_trip()
_test_dir_upload_and_download()
+ _test_does_storage_object_exist()
# TODO(epoger): Add _test_unauthenticated_access() to make sure we raise
# an exception when we try to access without needed credentials.