Index: win_toolchain/get_toolchain_if_necessary.py |
diff --git a/win_toolchain/get_toolchain_if_necessary.py b/win_toolchain/get_toolchain_if_necessary.py |
index 010a0ad23c12c11fff14e8b77954c4575f26d730..0b6e62d726b88f1628cc6e43973adc322423470c 100755 |
--- a/win_toolchain/get_toolchain_if_necessary.py |
+++ b/win_toolchain/get_toolchain_if_necessary.py |
@@ -80,26 +80,19 @@ |
return sorted(file_list, key=lambda s: s.replace('/', '\\')) |
-def MakeTimestampsFileName(root, sha1): |
- return os.path.join(root, os.pardir, '%s.timestamps' % sha1) |
- |
- |
-def CalculateHash(root, expected_hash): |
+def MakeTimestampsFileName(root): |
+ return os.path.join(root, '..', '.timestamps') |
+ |
+ |
+def CalculateHash(root): |
"""Calculates the sha1 of the paths to all files in the given |root| and the |
- contents of those files, and returns as a hex string. |
- |
- |expected_hash| is the expected hash value for this toolchain if it has |
- already been installed. |
- """ |
- if expected_hash: |
- full_root_path = os.path.join(root, expected_hash) |
- else: |
- full_root_path = root |
- file_list = GetFileList(full_root_path) |
- # Check whether we previously saved timestamps in $root/../{sha1}.timestamps. |
- # If we didn't, or they don't match, then do the full calculation, otherwise |
+ contents of those files, and returns as a hex string.""" |
+ file_list = GetFileList(root) |
+ |
+ # Check whether we previously saved timestamps in $root/../.timestamps. If |
+ # we didn't, or they don't match, then do the full calculation, otherwise |
# return the saved value. |
- timestamps_file = MakeTimestampsFileName(root, expected_hash) |
+ timestamps_file = MakeTimestampsFileName(root) |
timestamps_data = {'files': [], 'sha1': ''} |
if os.path.exists(timestamps_file): |
with open(timestamps_file, 'rb') as f: |
@@ -110,13 +103,9 @@ |
pass |
matches = len(file_list) == len(timestamps_data['files']) |
- # Don't check the timestamp of the version file as we touch this file to |
- # indicates which versions of the toolchain are still being used. |
- vc_dir = os.path.join(full_root_path, 'VC').lower() |
if matches: |
for disk, cached in zip(file_list, timestamps_data['files']): |
- if disk != cached[0] or ( |
- disk != vc_dir and os.path.getmtime(disk) != cached[1]): |
+ if disk != cached[0] or os.stat(disk).st_mtime != cached[1]: |
matches = False |
break |
if matches: |
@@ -124,36 +113,21 @@ |
digest = hashlib.sha1() |
for path in file_list: |
- path_without_hash = str(path).replace('/', '\\') |
- if expected_hash: |
- path_without_hash = path_without_hash.replace( |
- os.path.join(root, expected_hash), root) |
- digest.update(path_without_hash) |
+ digest.update(str(path).replace('/', '\\')) |
with open(path, 'rb') as f: |
digest.update(f.read()) |
return digest.hexdigest() |
-def CalculateToolchainHashes(root): |
- """Calculate the hash of the different toolchains installed in the |root| |
- directory.""" |
- hashes = [] |
- dir_list = [ |
- d for d in os.listdir(root) if os.path.isdir(os.path.join(root, d))] |
- for d in dir_list: |
- hashes.append(CalculateHash(root, d)) |
- return hashes |
- |
- |
def SaveTimestampsAndHash(root, sha1): |
"""Saves timestamps and the final hash to be able to early-out more quickly |
next time.""" |
- file_list = GetFileList(os.path.join(root, sha1)) |
+ file_list = GetFileList(root) |
timestamps_data = { |
- 'files': [[f, os.path.getmtime(f)] for f in file_list], |
+ 'files': [[f, os.stat(f).st_mtime] for f in file_list], |
'sha1': sha1, |
} |
- with open(MakeTimestampsFileName(root, sha1), 'wb') as f: |
+ with open(MakeTimestampsFileName(root), 'wb') as f: |
json.dump(timestamps_data, f) |
@@ -261,64 +235,6 @@ |
zf.extractall(target_dir) |
if temp_dir: |
RmDir(temp_dir) |
- |
- |
-def RemoveToolchain(root, sha1, delay_before_removing): |
- """Remove the |sha1| version of the toolchain from |root|.""" |
- toolchain_target_dir = os.path.join(root, sha1) |
- if delay_before_removing: |
- DelayBeforeRemoving(toolchain_target_dir) |
- if sys.platform == 'win32': |
- # These stay resident and will make the rmdir below fail. |
- kill_list = [ |
- 'mspdbsrv.exe', |
- 'vctip.exe', # Compiler and tools experience improvement data uploader. |
- ] |
- for process_name in kill_list: |
- with open(os.devnull, 'wb') as nul: |
- subprocess.call(['taskkill', '/f', '/im', process_name], |
- stdin=nul, stdout=nul, stderr=nul) |
- if os.path.isdir(toolchain_target_dir): |
- RmDir(toolchain_target_dir) |
- |
- timestamp_file = MakeTimestampsFileName(root, sha1) |
- if os.path.exists(timestamp_file): |
- os.remove(timestamp_file) |
- |
- |
-def RemoveUnusedToolchains(root): |
- """Remove the versions of the toolchain that haven't been used recently.""" |
- valid_toolchains = [] |
- dirs_to_remove = [] |
- |
- for d in os.listdir(root): |
- full_path = os.path.join(root, d) |
- if os.path.isdir(full_path): |
- if not os.path.exists(MakeTimestampsFileName(root, d)): |
- dirs_to_remove.append(d) |
- else: |
- vc_dir = os.path.join(full_path, 'VC') |
- valid_toolchains.append((os.path.getmtime(vc_dir), d)) |
- elif os.path.isfile(full_path): |
- os.remove(full_path) |
- |
- for d in dirs_to_remove: |
- print ('Removing %s as it doesn\'t correspond to any known toolchain.' % |
- os.path.join(root, d)) |
- # Use the RemoveToolchain function to remove these directories as they might |
- # contain an older version of the toolchain. |
- RemoveToolchain(root, d, False) |
- |
- # Remove the versions of the toolchains that haven't been used in the past 30 |
- # days. |
- toolchain_expiration_time = 60 * 60 * 24 * 30 |
- for toolchain in valid_toolchains: |
- toolchain_age_in_sec = time.time() - toolchain[0] |
- if toolchain_age_in_sec > toolchain_expiration_time: |
- print ('Removing version %s of the Win toolchain has it hasn\'t been used' |
- ' in the past %d days.' % (toolchain[1], |
- toolchain_age_in_sec / 60 / 60 / 24)) |
- RemoveToolchain(root, toolchain[1], True) |
def GetInstallerName(): |
@@ -413,9 +329,10 @@ |
sys.exit(subprocess.call(cmd)) |
assert sys.platform != 'cygwin' |
- if len(args) == 0: |
- sys.exit('Desired hash is required.') |
- desired_hash = args[0] |
+ # We assume that the Pro hash is the first one. |
+ desired_hashes = args |
+ if len(desired_hashes) == 0: |
+ sys.exit('Desired hashes are required.') |
# Move to depot_tools\win_toolchain where we'll store our files, and where |
# the downloader script is. |
@@ -425,11 +342,7 @@ |
target_dir = os.path.normpath(os.path.join(toolchain_dir, 'vs_files')) |
else: |
target_dir = os.path.normpath(os.path.join(toolchain_dir, 'vs2013_files')) |
- if not os.path.isdir(target_dir): |
- os.mkdir(target_dir) |
- toolchain_target_dir = os.path.join(target_dir, desired_hash) |
- |
- abs_toolchain_target_dir = os.path.abspath(toolchain_target_dir) |
+ abs_target_dir = os.path.abspath(target_dir) |
got_new_toolchain = False |
@@ -437,8 +350,8 @@ |
# Typically this script is only run when the .sha1 one file is updated, but |
# directly calling "gclient runhooks" will also run it, so we cache |
# based on timestamps to make that case fast. |
- current_hashes = CalculateToolchainHashes(target_dir) |
- if desired_hash not in current_hashes: |
+ current_hash = CalculateHash(target_dir) |
+ if current_hash not in desired_hashes: |
should_use_gs = False |
if (HaveSrcInternalAccess() or |
LooksLikeGoogler() or |
@@ -452,62 +365,68 @@ |
'build-instructions-windows\n\n') |
return 1 |
print('Windows toolchain out of date or doesn\'t exist, updating (Pro)...') |
- print(' current_hashes: %s' % ', '.join(current_hashes)) |
- print(' desired_hash: %s' % desired_hash) |
+ print(' current_hash: %s' % current_hash) |
+ print(' desired_hashes: %s' % ', '.join(desired_hashes)) |
sys.stdout.flush() |
- |
- DoTreeMirror(toolchain_target_dir, desired_hash) |
+ DelayBeforeRemoving(target_dir) |
+ if sys.platform == 'win32': |
+ # These stay resident and will make the rmdir below fail. |
+ kill_list = [ |
+ 'mspdbsrv.exe', |
+ 'vctip.exe', # Compiler and tools experience improvement data uploader. |
+ ] |
+ for process_name in kill_list: |
+ with open(os.devnull, 'wb') as nul: |
+ subprocess.call(['taskkill', '/f', '/im', process_name], |
+ stdin=nul, stdout=nul, stderr=nul) |
+ if os.path.isdir(target_dir): |
+ RmDir(target_dir) |
+ |
+ DoTreeMirror(target_dir, desired_hashes[0]) |
got_new_toolchain = True |
- win_sdk = os.path.join(abs_toolchain_target_dir, 'win_sdk') |
+ win_sdk = os.path.join(abs_target_dir, 'win_sdk') |
try: |
- version_file = os.path.join(toolchain_target_dir, 'VS_VERSION') |
- vc_dir = os.path.join(toolchain_target_dir, 'VC') |
- with open(version_file, 'rb') as f: |
+ with open(os.path.join(target_dir, 'VS_VERSION'), 'rb') as f: |
vs_version = f.read().strip() |
- # Touch the VC directory so we can use its timestamp to know when this |
- # version of the toolchain has been used for the last time. |
- os.utime(vc_dir, None) |
except IOError: |
# Older toolchains didn't have the VS_VERSION file, and used 'win8sdk' |
# instead of just 'win_sdk'. |
vs_version = '2013' |
- win_sdk = os.path.join(abs_toolchain_target_dir, 'win8sdk') |
+ win_sdk = os.path.join(abs_target_dir, 'win8sdk') |
data = { |
- 'path': abs_toolchain_target_dir, |
+ 'path': abs_target_dir, |
'version': vs_version, |
'win_sdk': win_sdk, |
# Added for backwards compatibility with old toolchain packages. |
'win8sdk': win_sdk, |
- 'wdk': os.path.join(abs_toolchain_target_dir, 'wdk'), |
+ 'wdk': os.path.join(abs_target_dir, 'wdk'), |
'runtime_dirs': [ |
- os.path.join(abs_toolchain_target_dir, 'sys64'), |
- os.path.join(abs_toolchain_target_dir, 'sys32'), |
+ os.path.join(abs_target_dir, 'sys64'), |
+ os.path.join(abs_target_dir, 'sys32'), |
], |
} |
with open(os.path.join(target_dir, '..', 'data.json'), 'w') as f: |
json.dump(data, f) |
if got_new_toolchain: |
- current_hashes = CalculateToolchainHashes(target_dir) |
- if desired_hash not in current_hashes: |
+ current_hash = CalculateHash(target_dir) |
+ if current_hash not in desired_hashes: |
print >> sys.stderr, ( |
'Got wrong hash after pulling a new toolchain. ' |
- 'Wanted \'%s\', got one of \'%s\'.' % ( |
- desired_hash, ', '.join(current_hashes))) |
+ 'Wanted one of \'%s\', got \'%s\'.' % ( |
+ ', '.join(desired_hashes), current_hash)) |
return 1 |
- SaveTimestampsAndHash(target_dir, desired_hash) |
+ SaveTimestampsAndHash(target_dir, current_hash) |
if options.output_json: |
shutil.copyfile(os.path.join(target_dir, '..', 'data.json'), |
options.output_json) |
if os.environ.get('GYP_MSVS_VERSION') == '2015': |
- InstallUniversalCRTIfNeeded(abs_toolchain_target_dir) |
- |
- RemoveUnusedToolchains(target_dir) |
+ InstallUniversalCRTIfNeeded(abs_target_dir) |
return 0 |