| #!/usr/bin/env python |
| # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Shim script for the SDK updater, to allow automatic updating. |
| |
| The purpose of this script is to be a shim which automatically updates |
| sdk_tools (the bundle containing the updater scripts) whenever this script is |
| run. |
| |
| When the sdk_tools bundle has been updated to the most recent version, this |
| script forwards its arguments to sdk_updater_main.py. |
| """ |
| |
| import os |
| import subprocess |
| from sdk_update_common import RenameDir, RemoveDir, Error |
| import sys |
| import tempfile |
| |
| |
| SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
| SDK_UPDATE_MAIN = os.path.join(SCRIPT_DIR, 'sdk_update_main.py') |
| SDK_ROOT_DIR = os.path.dirname(SCRIPT_DIR) |
| NACLSDK_SHELL_SCRIPT = os.path.join(SDK_ROOT_DIR, 'naclsdk') |
| if sys.platform.startswith('win'): |
| NACLSDK_SHELL_SCRIPT += '.bat' |
| SDK_TOOLS_DIR = os.path.join(SDK_ROOT_DIR, 'sdk_tools') |
| SDK_TOOLS_UPDATE_DIR = os.path.join(SDK_ROOT_DIR, 'sdk_tools_update') |
| |
| |
| def MakeSdkUpdateMainCmd(args): |
| """Returns a list of command line arguments to run sdk_update_main. |
| |
| Args: |
| args: A list of arguments to pass to sdk_update_main.py |
| Returns: |
| A new list that can be passed to subprocess.call, subprocess.Popen, etc. |
| """ |
| return [sys.executable, SDK_UPDATE_MAIN] + args |
| |
| |
| def UpdateSDKTools(args): |
| """Run sdk_update_main to update sdk_tools bundle. Return True if it is |
| updated. |
| |
| Args: |
| args: The arguments to pass to sdk_update_main.py. We need to keep this to |
| ensure sdk_update_main is called correctly; some parameters specify |
| URLS or directories to use. |
| Returns: |
| True if the sdk_tools bundle was updated. |
| """ |
| cmd = MakeSdkUpdateMainCmd(args + ['--update-sdk-tools']) |
| process = subprocess.Popen(cmd, stdout=subprocess.PIPE) |
| stdout, _ = process.communicate() |
| if process.returncode == 0: |
| return stdout.find('Updating bundle sdk_tools to version') != -1 |
| else: |
| # Updating sdk_tools could fail for any number of reasons. Regardless, it |
| # should be safe to try to run the user's command. |
| return False |
| |
| |
| def RenameSdkToolsDirectory(): |
| """Rename sdk_tools_update to sdk_tools.""" |
| # If there is no update directory, bail. |
| if not os.path.isdir(SDK_TOOLS_UPDATE_DIR): |
| return False |
| |
| try: |
| tempdir = tempfile.mkdtemp() |
| temp_sdktools = os.path.join(tempdir, 'sdk_tools') |
| try: |
| RenameDir(SDK_TOOLS_DIR, temp_sdktools) |
| except Error: |
| # The user is probably on Windows, and the directory is locked. |
| sys.stderr.write('Cannot rename directory "%s". Make sure no programs are' |
| ' viewing or accessing this directory and try again.\n' % ( |
| SDK_TOOLS_DIR,)) |
| sys.exit(1) |
| |
| try: |
| RenameDir(SDK_TOOLS_UPDATE_DIR, SDK_TOOLS_DIR) |
| except Error: |
| # Failed for some reason, move the old dir back. |
| try: |
| RenameDir(temp_sdktools, SDK_TOOLS_DIR) |
| except Error: |
| # Not much to do here. sdk_tools won't exist, but sdk_tools_update |
| # should. Hopefully running the batch script again will move |
| # sdk_tools_update -> sdk_tools and it will work this time... |
| sys.stderr.write('Unable to restore directory "%s" while auto-updating.' |
| 'Make sure no programs are viewing or accessing this directory and' |
| 'try again.\n' % (SDK_TOOLS_DIR,)) |
| sys.exit(1) |
| finally: |
| RemoveDir(tempdir) |
| |
| return True |
| |
| |
| def CheckRuntimeRequirements(): |
| if sys.platform.startswith('linux'): |
| if not os.path.exists('/lib/ld-linux.so.2'): |
| sys.stderr.write("""32-bit runtime environment was not found on this |
| system. Specifically the 32-bit dynamic loader which is needed by the NaCl |
| compilers was not found ('/lib/ld-linux.so.2'). On modern debian/ubuntu |
| systems this is included in the 'libc6:i386' package.\n""") |
| sys.exit(1) |
| |
| |
| def main(): |
| args = sys.argv[1:] |
| CheckRuntimeRequirements() |
| if UpdateSDKTools(args) and RenameSdkToolsDirectory(): |
| # Call the shell script, just in case this script was updated in the next |
| # version of sdk_tools |
| return subprocess.call([NACLSDK_SHELL_SCRIPT] + args) |
| else: |
| return subprocess.call(MakeSdkUpdateMainCmd(args)) |
| |
| |
| if __name__ == '__main__': |
| try: |
| sys.exit(main()) |
| except KeyboardInterrupt: |
| sys.exit(1) |