# Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) # Copyright (C) 2018 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This module is required for Python to treat this directory as a package. """Autoinstalls third-party code required by WebKit.""" import codecs import json import os import re import sys import urllib2 import imp from collections import namedtuple from distutils import spawn webkitpy_path = os.path.join(os.path.dirname(__file__), '../../../Tools/Scripts/webkitpy') autoinstall_path = os.path.join(webkitpy_path, 'common/system/autoinstall.py') filesystem_path = os.path.join(webkitpy_path, 'common/system/filesystem.py') AutoInstaller = imp.load_source('autoinstall', autoinstall_path).AutoInstaller FileSystem = imp.load_source('filesystem', filesystem_path).FileSystem _THIRDPARTY_DIR = os.path.dirname(__file__) _AUTOINSTALLED_DIR = os.path.join(_THIRDPARTY_DIR, "autoinstalled") # Putting the autoinstall code into LaunchTime/thirdparty/__init__.py # ensures that no autoinstalling occurs until a caller imports from # webkitpy.thirdparty. This is useful if the caller wants to configure # logging prior to executing autoinstall code. # FIXME: If any of these servers is offline, webkit-patch breaks (and maybe # other scripts do, too). See . # We put auto-installed third-party modules in this directory-- # # LaunchTime/thirdparty/autoinstalled fs = FileSystem() fs.maybe_make_directory(_AUTOINSTALLED_DIR) init_path = fs.join(_AUTOINSTALLED_DIR, "__init__.py") if not fs.exists(init_path): fs.write_text_file(init_path, "") readme_path = fs.join(_AUTOINSTALLED_DIR, "README") if not fs.exists(readme_path): fs.write_text_file(readme_path, "This directory is auto-generated by WebKit and is " "safe to delete.\nIt contains needed third-party Python " "packages automatically downloaded from the web.") class AutoinstallImportHook(object): def __init__(self, filesystem=None): self._fs = filesystem or FileSystem() def _ensure_autoinstalled_dir_is_in_sys_path(self): # Some packages require that the are being put somewhere under a directory in sys.path. if not _AUTOINSTALLED_DIR in sys.path: sys.path.insert(0, _AUTOINSTALLED_DIR) def find_module(self, fullname, _): # This method will run before each import. See http://www.python.org/dev/peps/pep-0302/ if '.autoinstalled' not in fullname: return # Note: all of the methods must follow the "_install_XXX" convention in # order for autoinstall_everything(), below, to work properly. if '.tornado' in fullname: self._install_tornado() def _install_tornado(self): self._ensure_autoinstalled_dir_is_in_sys_path() self._install("https://files.pythonhosted.org/packages/45/ec/f2a03a0509bcfca336bef23a3dab0d07504893af34fd13064059ba4a0503/tornado-5.1.tar.gz", "tornado-5.1/tornado") @staticmethod def greater_than_equal_to_version(minimum, version): for i in xrange(len(minimum.split('.'))): if int(version.split('.')[i]) > int(minimum.split('.')[i]): return True if int(version.split('.')[i]) < int(minimum.split('.')[i]): return False return True def _install(self, url, url_subpath=None, target_name=None): installer = AutoInstaller(target_dir=_AUTOINSTALLED_DIR) installer.install(url=url, url_subpath=url_subpath, target_name=target_name) def get_latest_pypi_url(self, package_name, url_subpath_format='{name}-{version}/{lname}'): json_url = "https://pypi.python.org/pypi/%s/json" % package_name response = urllib2.urlopen(json_url) data = json.load(response) url = data['urls'][1]['url'] subpath = url_subpath_format.format(name=package_name, version=data['info']['version'], lname=package_name.lower()) return (url, subpath) def install_binary(self, url, name): self._install(url=url, target_name=name) directory = os.path.join(_AUTOINSTALLED_DIR, name) os.chmod(os.path.join(directory, name), 0755) open(os.path.join(directory, '__init__.py'), 'w+').close() _hook = AutoinstallImportHook() sys.meta_path.append(_hook) def autoinstall_everything(): install_methods = [method for method in dir(_hook.__class__) if method.startswith('_install_')] for method in install_methods: getattr(_hook, method)() def get_os_info(): import platform os_name = platform.system() os_type = platform.machine()[-2:] return (os_name, os_type)