From 902b72ba1a848ae5b7d0146e9c2942681e58ff11 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 22 Mar 2017 08:50:54 -0700 Subject: [PATCH] Constrain core dependencies to core versions (#6738) * Require at least pip 7.1 * Write and use constraint files for packages * Update gen_requirements_all.py --- homeassistant/const.py | 1 + homeassistant/package_constraints.txt | 9 +++++ homeassistant/setup.py | 9 +++-- homeassistant/util/package.py | 6 +++- requirements_all.txt | 2 +- script/gen_requirements_all.py | 51 +++++++++++++++++++++------ setup.py | 2 +- 7 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 homeassistant/package_constraints.txt diff --git a/homeassistant/const.py b/homeassistant/const.py index f9e6afe7d9b..6c36dc4bda2 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -7,6 +7,7 @@ __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) REQUIRED_PYTHON_VER_WIN = (3, 5, 2) +CONSTRAINT_FILE = 'package_constraints.txt' PROJECT_NAME = 'Home Assistant' PROJECT_PACKAGE_NAME = 'homeassistant' diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt new file mode 100644 index 00000000000..cc8280bd6c5 --- /dev/null +++ b/homeassistant/package_constraints.txt @@ -0,0 +1,9 @@ +requests>=2,<3 +pyyaml>=3.11,<4 +pytz>=2016.10 +pip>=7.1.0 +jinja2>=2.9.5 +voluptuous==0.9.3 +typing>=3,<4 +aiohttp==1.3.5 +async_timeout==1.2.0 diff --git a/homeassistant/setup.py b/homeassistant/setup.py index 4a4737dab03..faf412a4e86 100644 --- a/homeassistant/setup.py +++ b/homeassistant/setup.py @@ -2,6 +2,7 @@ import asyncio import logging import logging.handlers +import os from types import ModuleType from typing import Optional, Dict @@ -12,7 +13,8 @@ import homeassistant.core as core import homeassistant.loader as loader import homeassistant.util.package as pkg_util from homeassistant.util.async import run_coroutine_threadsafe -from homeassistant.const import EVENT_COMPONENT_LOADED, PLATFORM_FORMAT +from homeassistant.const import ( + EVENT_COMPONENT_LOADED, PLATFORM_FORMAT, CONSTRAINT_FILE) _LOGGER = logging.getLogger(__name__) @@ -74,7 +76,10 @@ def _async_process_requirements(hass: core.HomeAssistant, name: str, def pip_install(mod): """Install packages.""" - return pkg_util.install_package(mod, target=hass.config.path('deps')) + return pkg_util.install_package( + mod, target=hass.config.path('deps'), + constraints=os.path.join(os.path.dirname(__file__), + CONSTRAINT_FILE)) with (yield from pip_lock): for req in requirements: diff --git a/homeassistant/util/package.py b/homeassistant/util/package.py index 6f632f47dbe..9a4fa038cfe 100644 --- a/homeassistant/util/package.py +++ b/homeassistant/util/package.py @@ -15,7 +15,8 @@ INSTALL_LOCK = threading.Lock() def install_package(package: str, upgrade: bool=True, - target: Optional[str]=None) -> bool: + target: Optional[str]=None, + constraints: Optional[str]=None) -> bool: """Install a package on PyPi. Accepts pip compatible package strings. Return boolean if install successful. @@ -32,6 +33,9 @@ def install_package(package: str, upgrade: bool=True, if target: args += ['--target', os.path.abspath(target)] + if constraints is not None: + args += ['--constraint', constraints] + try: return subprocess.call(args) == 0 except subprocess.SubprocessError: diff --git a/requirements_all.txt b/requirements_all.txt index 4937153bd73..60352b4febb 100755 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2,7 +2,7 @@ requests>=2,<3 pyyaml>=3.11,<4 pytz>=2016.10 -pip>=7.0.0 +pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.9.3 typing>=3,<4 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index bb7307c7281..16493dc884e 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -38,6 +38,10 @@ URL_PIN = ('https://home-assistant.io/developers/code_review_platform/' '#1-requirements') +CONSTRAINT_PATH = os.path.join(os.path.dirname(__file__), + '../homeassistant/package_constraints.txt') + + def explore_module(package, explore_children): """Explore the modules.""" module = importlib.import_module(package) @@ -124,18 +128,35 @@ def gather_modules(): return ''.join(output) -def write_file(data): +def gather_constraints(): + """Construct output for constraint file.""" + return '\n'.join(core_requirements() + ['']) + + +def write_requirements_file(data): """Write the modules to the requirements_all.txt.""" with open('requirements_all.txt', 'w+', newline="\n") as req_file: req_file.write(data) -def validate_file(data): +def write_constraints_file(data): + """Write constraints to a file.""" + with open(CONSTRAINT_PATH, 'w+', newline="\n") as req_file: + req_file.write(data) + + +def validate_requirements_file(data): """Validate if requirements_all.txt is up to date.""" with open('requirements_all.txt', 'r') as req_file: return data == ''.join(req_file) +def validate_constraints_file(data): + """Validate if constraints is up to date.""" + with open(CONSTRAINT_PATH, 'r') as req_file: + return data == ''.join(req_file) + + def main(): """Main section of the script.""" if not os.path.isfile('requirements_all.txt'): @@ -147,15 +168,25 @@ def main(): if data is None: sys.exit(1) - if sys.argv[-1] == 'validate': - if validate_file(data): - sys.exit(0) - print("******* ERROR") - print("requirements_all.txt is not up to date") - print("Please run script/gen_requirements_all.py") - sys.exit(1) + constraints = gather_constraints() - write_file(data) + if sys.argv[-1] == 'validate': + if not validate_requirements_file(data): + print("******* ERROR") + print("requirements_all.txt is not up to date") + print("Please run script/gen_requirements_all.py") + sys.exit(1) + + if not validate_constraints_file(constraints): + print("******* ERROR") + print("home-assistant/package_constraints.txt is not up to date") + print("Please run script/gen_requirements_all.py") + sys.exit(1) + + sys.exit(0) + + write_requirements_file(data) + write_constraints_file(constraints) if __name__ == '__main__': diff --git a/setup.py b/setup.py index d70011820c3..0f2c6e6d876 100755 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ REQUIRES = [ 'requests>=2,<3', 'pyyaml>=3.11,<4', 'pytz>=2016.10', - 'pip>=7.0.0', + 'pip>=7.1.0', 'jinja2>=2.9.5', 'voluptuous==0.9.3', 'typing>=3,<4',