14311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch# Copyright (c) 2013 The Chromium Authors. All rights reserved. 2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)# found in the LICENSE file. 4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import os 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import re 6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import sys 7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)def _SyncFilesToCloud(input_api, output_api): 10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) """Searches for .sha1 files and uploads them to Cloud Storage. 11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) It validates all the hashes and skips upload if not necessary. 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) """ 14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) # Because this script will be called from a magic PRESUBMIT demon, 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) # avoid angering it; don't pollute its sys.path. 16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) old_sys_path = sys.path 17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) try: 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sys.path = [os.path.join(os.pardir, os.pardir, 'telemetry')] + sys.path 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) from telemetry.page import cloud_storage 20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) finally: 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sys.path = old_sys_path 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 234311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch hashes_in_cloud_storage = cloud_storage.List(cloud_storage.DEFAULT_BUCKET) 24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) results = [] 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for hash_path in input_api.AbsoluteLocalPaths(): 27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_path, extension = os.path.splitext(hash_path) 28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if extension != '.sha1': 29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) with open(hash_path, 'rb') as f: 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_hash = f.read(1024).rstrip() 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if file_hash in hashes_in_cloud_storage: 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) results.append(output_api.PresubmitNotifyResult( 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 'File already in Cloud Storage, skipping upload: %s' % hash_path)) 36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue 37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if not re.match('^([A-Za-z0-9]{40})$', file_hash): 39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) results.append(output_api.PresubmitError( 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 'Hash file does not contain a valid SHA-1 hash: %s' % hash_path)) 41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if not os.path.exists(file_path): 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) results.append(output_api.PresubmitError( 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 'Hash file exists, but file not found: %s' % hash_path)) 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if cloud_storage.GetHash(file_path) != file_hash: 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) results.append(output_api.PresubmitError( 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 'Hash file does not match file\'s actual hash: %s' % hash_path)) 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) try: 524311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch cloud_storage.Insert(cloud_storage.DEFAULT_BUCKET, file_hash, file_path) 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) except cloud_storage.CloudStorageError: 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) results.append(output_api.PresubmitError( 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 'Unable to upload to Cloud Storage: %s' % hash_path)) 56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return results 58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)def CheckChangeOnCommit(input_api, output_api): 61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) results = [] 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) results += _SyncFilesToCloud(input_api, output_api) 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return results 64