blob: d19eb2d8f2c59736b72591e252cec1f43b03ce2b [file] [log] [blame]
# 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)