@ -20,9 +20,9 @@ won't be properly maintained. See http://crbug.com/323300.
from __future__ import print_function
import argparse
import hashlib
import json
import optparse
import os
import platform
import shutil
@ -187,7 +187,7 @@ def CalculateHash(root, expected_hash):
# Save the timestamp file if the calculated hash is the expected one.
# The expected hash may be shorter, to reduce path lengths, in which case just
# compare that many characters.
if expected_hash and digest . hexdigest ( ) [ : len ( expected_hash ) ] == expected_hash :
if expected_hash and digest . hexdigest ( ) . startswith ( expected_hash ) :
SaveTimestampsAndHash ( root , digest . hexdigest ( ) )
# Return the (potentially truncated) expected_hash.
return expected_hash
@ -451,19 +451,24 @@ def EnableCrashDumpCollection():
def main ( ) :
parser = optparse . OptionParser ( description = sys . modules [ __name__ ] . __doc__ )
parser . add_option ( ' --output-json ' , metavar = ' FILE ' ,
help = ' write information about toolchain to FILE ' )
parser . add_option ( ' --force ' , action = ' store_true ' ,
help = ' force script to run on non-Windows hosts ' )
parser . add_option ( ' --no-download ' , action = ' store_true ' ,
help = ' configure if present but don \' t download ' )
parser . add_option ( ' --toolchain-dir ' ,
default = os . getenv ( ENV_TOOLCHAIN_ROOT , BASEDIR ) ,
help = ' directory to install toolchain into ' )
options , args = parser . parse_args ( )
if not ( sys . platform . startswith ( ( ' cygwin ' , ' win32 ' ) ) or options . force ) :
parser = argparse . ArgumentParser (
description = __doc__ ,
formatter_class = argparse . RawDescriptionHelpFormatter ,
)
parser . add_argument ( ' --output-json ' , metavar = ' FILE ' ,
help = ' write information about toolchain to FILE ' )
parser . add_argument ( ' --force ' , action = ' store_true ' ,
help = ' force script to run on non-Windows hosts ' )
parser . add_argument ( ' --no-download ' , action = ' store_true ' ,
help = ' configure if present but don \' t download ' )
parser . add_argument ( ' --toolchain-dir ' ,
default = os . getenv ( ENV_TOOLCHAIN_ROOT , BASEDIR ) ,
help = ' directory to install toolchain into ' )
parser . add_argument ( ' desired_hash ' , metavar = ' desired-hash ' ,
help = ' toolchain hash to download ' )
args = parser . parse_args ( )
if not ( sys . platform . startswith ( ( ' cygwin ' , ' win32 ' ) ) or args . force ) :
return 0
if sys . platform == ' cygwin ' :
@ -472,18 +477,14 @@ def main():
return subprocess . check_output ( [ ' cygpath ' , ' -w ' , path ] ) . strip ( )
python = os . path . join ( DEPOT_TOOLS_PATH , ' python.bat ' )
cmd = [ python , winpath ( __file__ ) ]
if option s. output_json :
cmd . extend ( [ ' --output-json ' , winpath ( option s. output_json ) ] )
cmd . extend( args )
if arg s. output_json :
cmd . extend ( [ ' --output-json ' , winpath ( arg s. output_json ) ] )
cmd . append( args . desired_hash )
sys . exit ( subprocess . call ( cmd ) )
assert sys . platform != ' cygwin '
if len ( args ) == 0 :
sys . exit ( ' Desired hash is required. ' )
desired_hash = args [ 0 ]
# Create our toolchain destination and "chdir" to it.
toolchain_dir = os . path . abspath ( option s. toolchain_dir )
toolchain_dir = os . path . abspath ( args . toolchain_dir )
if not os . path . isdir ( toolchain_dir ) :
os . makedirs ( toolchain_dir )
os . chdir ( toolchain_dir )
@ -493,7 +494,7 @@ def main():
target_dir = ' vs_files '
if not os . path . isdir ( target_dir ) :
os . mkdir ( target_dir )
toolchain_target_dir = os . path . join ( target_dir , desired_hash)
toolchain_target_dir = os . path . join ( target_dir , args. desired_hash)
abs_toolchain_target_dir = os . path . abspath ( toolchain_target_dir )
@ -504,8 +505,8 @@ def main():
# directly calling "gclient runhooks" will also run it, so we cache
# based on timestamps to make that case fast.
current_hashes = CalculateToolchainHashes ( target_dir , True )
if desired_hash not in current_hashes :
if option s. no_download :
if args. desired_hash not in current_hashes :
if arg s. no_download :
raise SystemExit ( ' Toolchain is out of date. Run " gclient runhooks " to '
' update the toolchain, or set '
' DEPOT_TOOLS_WIN_TOOLCHAIN=0 to use the locally '
@ -539,10 +540,10 @@ def main():
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 ( ' desired_hash: %s ' % args. desired_hash)
sys . stdout . flush ( )
DoTreeMirror ( toolchain_target_dir , desired_hash)
DoTreeMirror ( toolchain_target_dir , args. desired_hash)
got_new_toolchain = True
@ -555,26 +556,18 @@ def main():
else :
win_sdk = os . path . join ( abs_toolchain_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 :
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 ' )
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 :
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 )
data = {
' path ' : abs_toolchain_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 ' ) ,
' runtime_dirs ' : [
os . path . join ( abs_toolchain_target_dir , ' sys64 ' ) ,
@ -587,17 +580,17 @@ def main():
if got_new_toolchain :
current_hashes = CalculateToolchainHashes ( target_dir , False )
if desired_hash not in current_hashes :
if args. desired_hash not in current_hashes :
print (
' Got wrong hash after pulling a new toolchain. '
' Wanted \' %s \' , got one of \' %s \' . ' % (
desired_hash, ' , ' . join ( current_hashes ) ) , file = sys . stderr )
args. desired_hash, ' , ' . join ( current_hashes ) ) , file = sys . stderr )
return 1
SaveTimestampsAndHash ( target_dir , desired_hash)
SaveTimestampsAndHash ( target_dir , args. desired_hash)
if option s. output_json :
if arg s. output_json :
shutil . copyfile ( os . path . join ( target_dir , ' .. ' , ' data.json ' ) ,
option s. output_json )
arg s. output_json )
EnableCrashDumpCollection ( )