diff options
author | Corey Farwell <coreyf@rwell.org> | 2015-08-08 18:27:03 -0400 |
---|---|---|
committer | Corey Farwell <coreyf@rwell.org> | 2015-08-08 18:48:02 -0400 |
commit | 33f78314d921d758cb47f64bdc002543d0b8fca0 (patch) | |
tree | 1049ecd60878afbb160063c2bb7174f9ce2bcbec /python | |
parent | b91320cb05ce03d2154ca41a141107c85726f9e7 (diff) | |
download | servo-33f78314d921d758cb47f64bdc002543d0b8fca0.tar.gz servo-33f78314d921d758cb47f64bdc002543d0b8fca0.zip |
Use one Python virtual environment for all mach commands
Prior to this commit:
* Our Python dependency story was a bit of a mess. We had complete
Python packages (wheels and directories) living in-tree, despite
not having any changes from upstream. This is particularly bad because
`setup.py` never gets run on these packages which could (sometimes
silently) unintended breakage.
* Python virtual environments (virtualenv) were only utilized for
testing web-platform tests
After this commit:
* A single virtualenv (`python/_virtualenv`) is activated upon *every*
call to mach
* A requirements file (`python/requirements.txt`) is added to describe
the dependencies needed by Python modules in `python/`. The child
commit immediately following this will remove all the dependencies
no longer needed in-tree (for the sake of keeping this commit
readable).
Relevant to https://github.com/servo/servo/issues/861
Fixes https://github.com/servo/servo/issues/6999
Diffstat (limited to 'python')
-rw-r--r-- | python/mach_bootstrap.py | 37 | ||||
-rw-r--r-- | python/requirements.txt | 12 | ||||
-rw-r--r-- | python/servo/testing_commands.py | 43 | ||||
-rw-r--r-- | python/tidy.py | 8 |
4 files changed, 50 insertions, 50 deletions
diff --git a/python/mach_bootstrap.py b/python/mach_bootstrap.py index 84de5b22b25..e04d1781bdd 100644 --- a/python/mach_bootstrap.py +++ b/python/mach_bootstrap.py @@ -6,7 +6,9 @@ from __future__ import print_function, unicode_literals import os import platform +import subprocess import sys +from distutils.spawn import find_executable SEARCH_PATHS = [ "python/mach", @@ -73,6 +75,39 @@ CATEGORIES = { } +def _get_exec(name, default=None): + path = find_executable(name) + if not path: + return default + return path + + +def _activate_virtualenv(topdir): + virtualenv_path = os.path.join(topdir, "python", "_virtualenv") + python = _get_exec("python2", "python") + + if not os.path.exists(virtualenv_path): + virtualenv = _get_exec("virtualenv2", "virtualenv") + subprocess.check_call([virtualenv, "-p", python, virtualenv_path]) + + activate_path = os.path.join(virtualenv_path, "bin", "activate_this.py") + execfile(activate_path, dict(__file__=activate_path)) + + # TODO: Right now, we iteratively install all the requirements by invoking + # `pip install` each time. If it were the case that there were conflicting + # requirements, we wouldn't know about them. Once + # https://github.com/pypa/pip/issues/988 is addressed, then we can just + # chain each of the requirements files into the same `pip install` call + # and it will check for conflicts. + requirements_paths = [ + os.path.join(topdir, "python", "requirements.txt"), + os.path.join(topdir, "tests", "wpt", "harness", "requirements.txt"), + os.path.join(topdir, "tests", "wpt", "harness", "requirements_servo.txt"), + ] + for path in requirements_paths: + subprocess.check_call(["pip", "install", "-q", "-r", path]) + + def bootstrap(topdir): topdir = os.path.abspath(topdir) @@ -84,6 +119,8 @@ def bootstrap(topdir): print('You are running Python', platform.python_version()) sys.exit(1) + _activate_virtualenv(topdir) + def populate_context(context, key=None): if key is None: return diff --git a/python/requirements.txt b/python/requirements.txt new file mode 100644 index 00000000000..a346c4dd579 --- /dev/null +++ b/python/requirements.txt @@ -0,0 +1,12 @@ +# 'mach' is not listed here because a new version hasn't been published to PyPi in a while + +blessings == 1.6 +mozdebug == 0.1 +mozinfo == 0.8 +mozlog == 3.0 +toml == 0.9.1 + +# For Python linting +flake8 == 2.4.1 +pep8 == 1.5.7 +pyflakes == 0.8.0 diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index 76e5bf9cb79..732db39a186 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -15,7 +15,6 @@ import os import os.path as path import subprocess from collections import OrderedDict -from distutils.spawn import find_executable from time import time from mach.registrar import Registrar @@ -237,7 +236,6 @@ class MachCommands(CommandBase): help="Run with a release build of servo") def test_wpt(self, **kwargs): self.ensure_bootstrapped() - self.ensure_wpt_virtualenv() hosts_file_path = path.join('tests', 'wpt', 'hosts') os.environ["hosts_file_path"] = hosts_file_path @@ -255,7 +253,6 @@ class MachCommands(CommandBase): parser=updatecommandline.create_parser()) def update_wpt(self, **kwargs): self.ensure_bootstrapped() - self.ensure_wpt_virtualenv() run_file = path.abspath(path.join("tests", "wpt", "update.py")) run_globals = {"__file__": run_file} execfile(run_file, run_globals) @@ -301,7 +298,6 @@ class MachCommands(CommandBase): help="Run with a release build of servo") def test_css(self, **kwargs): self.ensure_bootstrapped() - self.ensure_wpt_virtualenv() run_file = path.abspath(path.join("tests", "wpt", "run_css.py")) run_globals = {"__file__": run_file} @@ -320,45 +316,6 @@ class MachCommands(CommandBase): execfile(run_file, run_globals) return run_globals["update_tests"](**kwargs) - def ensure_wpt_virtualenv(self): - virtualenv_path = path.join("tests", "wpt", "_virtualenv") - python = self.get_exec("python2", "python") - - if not os.path.exists(virtualenv_path): - virtualenv = self.get_exec("virtualenv2", "virtualenv") - subprocess.check_call([virtualenv, "-p", python, virtualenv_path]) - - activate_path = path.join(virtualenv_path, "bin", "activate_this.py") - - execfile(activate_path, dict(__file__=activate_path)) - - try: - import wptrunner # noqa - from wptrunner.browsers import servo # noqa - except ImportError: - subprocess.check_call(["pip", "install", "-r", - path.join("tests", "wpt", "harness", "requirements.txt")]) - subprocess.check_call(["pip", "install", "-r", - path.join("tests", "wpt", "harness", "requirements_servo.txt")]) - try: - import blessings - except ImportError: - subprocess.check_call(["pip", "install", "blessings"]) - - # This is an unfortunate hack. Because mozlog gets imported by wptcommandline - # before the virtualenv is initalised it doesn't see the blessings module so we don't - # get coloured output. Setting the blessings global explicitly fixes that. - from mozlog.structured.formatters import machformatter - import blessings # noqa - machformatter.blessings = blessings - - def get_exec(self, name, default=None): - path = find_executable(name) - if not path: - return default - - return path - def jquery_test_runner(self, cmd, release, dev): self.ensure_bootstrapped() base_dir = path.abspath(path.join("tests", "jquery")) diff --git a/python/tidy.py b/python/tidy.py index 288ce8c5349..84a570f2d41 100644 --- a/python/tidy.py +++ b/python/tidy.py @@ -19,11 +19,6 @@ from licenseck import licenses filetypes_to_check = [".rs", ".rc", ".cpp", ".c", ".h", ".py", ".toml", ".webidl"] reftest_directories = ["tests/ref"] reftest_filetype = ".list" -python_dependencies = [ - "./python/dependencies/flake8-2.4.1-py2.py3-none-any.whl", - "./python/dependencies/pep8-1.5.7-py2.py3-none-any.whl", - "./python/dependencies/pyflakes-0.9.0-py2.py3-none-any.whl", -] ignored_files = [ # Upstream @@ -36,6 +31,7 @@ ignored_files = [ "python/toml/*", "components/script/dom/bindings/codegen/parser/*", "components/script/dom/bindings/codegen/ply/*", + "python/_virtualenv/*", # Generated and upstream code combined with our own. Could use cleanup "target/*", @@ -272,8 +268,6 @@ def get_reftest_names(line): def scan(): - sys.path += python_dependencies - all_files = collect_file_names() files_to_check = filter(should_check, all_files) |