144 lines
5.8 KiB
Python
144 lines
5.8 KiB
Python
# 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 <http://webkit.org/b/42080>.
|
|
|
|
# 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)
|