From 8cd4a44d025201e14c6a9f73c3d73bb4d2021644 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 13:46:21 +0200 Subject: [PATCH 01/12] Simplify definition of DAV_SERVERs --- .builds/archlinux.yaml | 6 +++--- .builds/tests-minimal.yaml | 6 +++--- .builds/tests-release.yaml | 7 +++---- Makefile | 5 ++++- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.builds/archlinux.yaml b/.builds/archlinux.yaml index 77dd24c..e9b9740 100644 --- a/.builds/archlinux.yaml +++ b/.builds/archlinux.yaml @@ -24,6 +24,7 @@ environment: BUILD: test CI: true CODECOV_TOKEN: b834a3c5-28fa-4808-9bdb-182210069c79 + DAV_SERVER: radicale xandikos REQUIREMENTS: release # TODO: ETESYNC_TESTS tasks: @@ -32,11 +33,10 @@ tasks: python setup.py build sudo pip install --no-index . sudo systemctl start docker - DAV_SERVER="radicale xandikos" make -e install-servers + make -e install-servers - test: | cd vdirsyncer # Non-system python is used for packages: export PATH=$PATH:~/.local/bin/ make -e ci-test - DAV_SERVER=radicale make -e ci-test-storage - DAV_SERVER=xandikos make -e ci-test-storage + make -e ci-test-storage diff --git a/.builds/tests-minimal.yaml b/.builds/tests-minimal.yaml index 7c54770..004ed9e 100644 --- a/.builds/tests-minimal.yaml +++ b/.builds/tests-minimal.yaml @@ -14,17 +14,17 @@ environment: BUILD: test CI: true CODECOV_TOKEN: b834a3c5-28fa-4808-9bdb-182210069c79 + DAV_SERVER: radicale xandikos REQUIREMENTS: minimal # TODO: ETESYNC_TESTS tasks: - setup: | cd vdirsyncer sudo systemctl start docker - DAV_SERVER="radicale xandikos" make -e install-test + make -e install-test - test: | cd vdirsyncer # Non-system python is used for packages: export PATH=$PATH:~/.local/bin/ make -e ci-test - DAV_SERVER=radicale make -e ci-test-storage - DAV_SERVER=xandikos make -e ci-test-storage + make -e ci-test-storage diff --git a/.builds/tests-release.yaml b/.builds/tests-release.yaml index 5e7fa05..380b45a 100644 --- a/.builds/tests-release.yaml +++ b/.builds/tests-release.yaml @@ -11,22 +11,21 @@ environment: BUILD: test CI: true CODECOV_TOKEN: b834a3c5-28fa-4808-9bdb-182210069c79 + DAV_SERVER: baikal radicale xandikos REQUIREMENTS: release # TODO: ETESYNC_TESTS tasks: - setup: | cd vdirsyncer sudo systemctl start docker - DAV_SERVER="radicale xandikos baikal" make -e install-test + make -e install-test make -e install-style - test: | cd vdirsyncer # Non-system python is used for packages: export PATH=$PATH:~/.local/bin/ make -e ci-test - DAV_SERVER=baikal make -e ci-test-storage - DAV_SERVER=radicale make -e ci-test-storage - DAV_SERVER=xandikos make -e ci-test-storage + make -e ci-test-storage - style: | cd vdirsyncer # Non-system python is used for packages: diff --git a/Makefile b/Makefile index 295631d..159e4b1 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,10 @@ ci-test: ci-test-storage: curl -s https://codecov.io/bash > $(CODECOV_PATH) - $(PYTEST) tests/storage/ + set -ex; \ + for server in $(DAV_SERVER); do \ + DAV_SERVER=$$server $(PYTEST) --cov-append tests/storage; \ + done bash $(CODECOV_PATH) -c -F storage test: From 299c699cb9de2d99aec46c3a950be287d71f6866 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 14:32:11 +0200 Subject: [PATCH 02/12] Manage test DAV servers as fixtures Rather than require manually starting them before tests, manage them as fixtures an initialise/destroy them as needed. --- .builds/archlinux.yaml | 1 - Makefile | 10 +-- tests/storage/conftest.py | 76 ++++++++++++++++++++++ tests/storage/servers/baikal/__init__.py | 2 +- tests/storage/servers/baikal/install.sh | 3 - tests/storage/servers/radicale/__init__.py | 8 ++- tests/storage/servers/radicale/install.sh | 3 - tests/storage/servers/xandikos/__init__.py | 8 ++- tests/storage/servers/xandikos/install.sh | 3 - 9 files changed, 92 insertions(+), 22 deletions(-) delete mode 100644 tests/storage/servers/baikal/install.sh delete mode 100644 tests/storage/servers/radicale/install.sh delete mode 100644 tests/storage/servers/xandikos/install.sh diff --git a/.builds/archlinux.yaml b/.builds/archlinux.yaml index e9b9740..9e50858 100644 --- a/.builds/archlinux.yaml +++ b/.builds/archlinux.yaml @@ -33,7 +33,6 @@ tasks: python setup.py build sudo pip install --no-index . sudo systemctl start docker - make -e install-servers - test: | cd vdirsyncer # Non-system python is used for packages: diff --git a/Makefile b/Makefile index 159e4b1..35c042d 100644 --- a/Makefile +++ b/Makefile @@ -62,15 +62,7 @@ test: all: $(error Take a look at https://vdirsyncer.pimutils.org/en/stable/tutorial.html#installation) -install-servers: - set -ex; \ - for server in $(DAV_SERVER); do \ - if [ -f $(TESTSERVER_BASE)$$server/install.sh ]; then \ - (cd $(TESTSERVER_BASE)$$server && sh install.sh); \ - fi \ - done - -install-test: install-servers install-dev +install-test: install-dev pip install -Ur test-requirements.txt set -xe && if [ "$$REQUIREMENTS" = "devel" ]; then \ pip install -U --force-reinstall \ diff --git a/tests/storage/conftest.py b/tests/storage/conftest.py index 96f0414..74b8d04 100644 --- a/tests/storage/conftest.py +++ b/tests/storage/conftest.py @@ -1,6 +1,82 @@ +import contextlib +import subprocess +import time import uuid import pytest +import requests + + +def wait_for_container(url): + """Wait for a container to initialise. + + Polls a URL every 100ms until the server responds. + """ + # give the server 5 seconds to settle + for _ in range(50): + print(_) + + try: + response = requests.get(url) + response.raise_for_status() + except requests.ConnectionError: + pass + else: + return + + time.sleep(0.1) + + pytest.exit( + "Server did not initialise in 5 seconds.\n" + "WARNING: There may be a stale docker container still running." + ) + + +@contextlib.contextmanager +def dockerised_server(name, container_port, exposed_port): + """Run a dockerised DAV server as a contenxt manager.""" + container_id = None + url = f"http://127.0.0.1:{exposed_port}/" + + try: + # Hint: This will block while the pull happends, and only return once + # the container has actually started. + output = subprocess.check_output( + [ + "docker", + "run", + "--detach", + "--publish", + f"{exposed_port}:{container_port}", + f"whynothugo/vdirsyncer-devkit-{name}", + ] + ) + + container_id = output.decode().strip() + wait_for_container(url) + + yield url + finally: + if container_id: + subprocess.check_output(["docker", "kill", container_id]) + + +@pytest.fixture(scope="session") +def baikal_server(): + with dockerised_server("baikal", "80", "8002"): + yield + + +@pytest.fixture(scope="session") +def radicale_server(): + with dockerised_server("radicale", "8001", "8001"): + yield + + +@pytest.fixture(scope="session") +def xandikos_server(): + with dockerised_server("xandikos", "8000", "8000"): + yield @pytest.fixture diff --git a/tests/storage/servers/baikal/__init__.py b/tests/storage/servers/baikal/__init__.py index 88c3e90..7547e07 100644 --- a/tests/storage/servers/baikal/__init__.py +++ b/tests/storage/servers/baikal/__init__.py @@ -3,7 +3,7 @@ import pytest class ServerMixin: @pytest.fixture - def get_storage_args(self, request, tmpdir, slow_create_collection): + def get_storage_args(self, request, tmpdir, slow_create_collection, baikal_server): def inner(collection="test"): base_url = "http://127.0.0.1:8002/" args = { diff --git a/tests/storage/servers/baikal/install.sh b/tests/storage/servers/baikal/install.sh deleted file mode 100644 index 44f3c95..0000000 --- a/tests/storage/servers/baikal/install.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -docker run -d -p 8002:80 whynothugo/vdirsyncer-devkit-baikal diff --git a/tests/storage/servers/radicale/__init__.py b/tests/storage/servers/radicale/__init__.py index b3b59bb..fb97ab2 100644 --- a/tests/storage/servers/radicale/__init__.py +++ b/tests/storage/servers/radicale/__init__.py @@ -3,7 +3,13 @@ import pytest class ServerMixin: @pytest.fixture - def get_storage_args(self, request, tmpdir, slow_create_collection): + def get_storage_args( + self, + request, + tmpdir, + slow_create_collection, + radicale_server, + ): def inner(collection="test"): url = "http://127.0.0.1:8001/" args = { diff --git a/tests/storage/servers/radicale/install.sh b/tests/storage/servers/radicale/install.sh deleted file mode 100644 index fdeaff9..0000000 --- a/tests/storage/servers/radicale/install.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -docker run -d -p 8001:8001 whynothugo/vdirsyncer-devkit-radicale diff --git a/tests/storage/servers/xandikos/__init__.py b/tests/storage/servers/xandikos/__init__.py index b0e6451..ece5de0 100644 --- a/tests/storage/servers/xandikos/__init__.py +++ b/tests/storage/servers/xandikos/__init__.py @@ -3,7 +3,13 @@ import pytest class ServerMixin: @pytest.fixture - def get_storage_args(self, request, tmpdir, slow_create_collection): + def get_storage_args( + self, + request, + tmpdir, + slow_create_collection, + xandikos_server, + ): def inner(collection="test"): url = "http://127.0.0.1:8000/" args = {"url": url} diff --git a/tests/storage/servers/xandikos/install.sh b/tests/storage/servers/xandikos/install.sh deleted file mode 100644 index aa7b089..0000000 --- a/tests/storage/servers/xandikos/install.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -docker run -d -p 8000:8000 whynothugo/vdirsyncer-devkit-xandikos From 8e8c1d57199876e38474cc680d704e1b0bf5ca6b Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 14:36:30 +0200 Subject: [PATCH 03/12] Update docs on test DAV servers --- docs/contributing.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 29e24b7..73175c7 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -100,14 +100,13 @@ The ``Makefile`` has a lot of options that allow you to control which tests are run, and which servers are tested. Take a look at its code where they are all initialized and documented. -For example, to test xandikos, first run the server itself:: - - docker run -p 8000:8000 whynothugo/vdirsyncer-devkit-xandikos - -Then run the tests specifying this ``DAV_SERVER``, run:: +To tests against a specific DAV server, use ``DAV_SERVER``:: make DAV_SERVER=xandikos test +The server will be initialised in a docker container and terminated at the end +of the test suite. + If you have any questions, feel free to open issues about it. Structure of the testsuite From 7b0d6671dae498c9717cbc925dc9d1a1b00bee6b Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 14:39:23 +0200 Subject: [PATCH 04/12] Delete unused variable --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 35c042d..88b2e0c 100644 --- a/Makefile +++ b/Makefile @@ -36,8 +36,6 @@ ifeq ($(ETESYNC_TESTS), true) endif PYTEST = py.test $(PYTEST_ARGS) - -export TESTSERVER_BASE := ./tests/storage/servers/ CODECOV_PATH = /tmp/codecov.sh ci-test: From 39ccc168b21c765fe180829df128879879d77341 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 14:39:33 +0200 Subject: [PATCH 05/12] Show a useful help message by default --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 88b2e0c..ad4528c 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,9 @@ endif PYTEST = py.test $(PYTEST_ARGS) CODECOV_PATH = /tmp/codecov.sh +all: + $(error Take a look at https://vdirsyncer.pimutils.org/en/stable/tutorial.html#installation) + ci-test: curl -s https://codecov.io/bash > $(CODECOV_PATH) $(PYTEST) tests/unit/ @@ -57,9 +60,6 @@ ci-test-storage: test: $(PYTEST) -all: - $(error Take a look at https://vdirsyncer.pimutils.org/en/stable/tutorial.html#installation) - install-test: install-dev pip install -Ur test-requirements.txt set -xe && if [ "$$REQUIREMENTS" = "devel" ]; then \ From 3bf4bd079d28b41d67f5253e3afc408625a3cfd5 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 14:47:15 +0200 Subject: [PATCH 06/12] Tidy up CI build definitions --- .builds/archlinux.yaml | 4 +--- .builds/tests-minimal.yaml | 2 +- .builds/tests-release.yaml | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.builds/archlinux.yaml b/.builds/archlinux.yaml index 9e50858..f7ad850 100644 --- a/.builds/archlinux.yaml +++ b/.builds/archlinux.yaml @@ -29,13 +29,11 @@ environment: # TODO: ETESYNC_TESTS tasks: - setup: | + sudo systemctl start docker cd vdirsyncer python setup.py build sudo pip install --no-index . - sudo systemctl start docker - test: | cd vdirsyncer - # Non-system python is used for packages: - export PATH=$PATH:~/.local/bin/ make -e ci-test make -e ci-test-storage diff --git a/.builds/tests-minimal.yaml b/.builds/tests-minimal.yaml index 004ed9e..dec4ba0 100644 --- a/.builds/tests-minimal.yaml +++ b/.builds/tests-minimal.yaml @@ -19,8 +19,8 @@ environment: # TODO: ETESYNC_TESTS tasks: - setup: | - cd vdirsyncer sudo systemctl start docker + cd vdirsyncer make -e install-test - test: | cd vdirsyncer diff --git a/.builds/tests-release.yaml b/.builds/tests-release.yaml index 380b45a..05d838a 100644 --- a/.builds/tests-release.yaml +++ b/.builds/tests-release.yaml @@ -16,10 +16,9 @@ environment: # TODO: ETESYNC_TESTS tasks: - setup: | - cd vdirsyncer sudo systemctl start docker - make -e install-test - make -e install-style + cd vdirsyncer + make -e install-test -e install-style - test: | cd vdirsyncer # Non-system python is used for packages: From 8d62ac42793b03c4b60141a97d03760fb35483b3 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 14:48:56 +0200 Subject: [PATCH 07/12] Pin the maximum version of click We're likely won't be compatible with 9.0. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 43b6b36..0305896 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ from setuptools import setup requirements = [ # https://github.com/mitsuhiko/click/issues/200 - "click>=5.0", + "click>=5.0,<9.0", "click-log>=0.3.0, <0.4.0", # https://github.com/pimutils/vdirsyncer/issues/478 "click-threading>=0.5", From 57d662cba1b5a9a177beb00b406d6bc86db79538 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 15:04:07 +0200 Subject: [PATCH 08/12] Drop make target for development packages We no longer track compat with unreleased packages. Too many variations and too much complexity. `vdirsyncer` only works with released packages. --- Makefile | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Makefile b/Makefile index ad4528c..0104ff1 100644 --- a/Makefile +++ b/Makefile @@ -62,12 +62,6 @@ test: install-test: install-dev pip install -Ur test-requirements.txt - set -xe && if [ "$$REQUIREMENTS" = "devel" ]; then \ - pip install -U --force-reinstall \ - git+https://github.com/DRMacIver/hypothesis \ - git+https://github.com/kennethreitz/requests \ - git+https://github.com/pytest-dev/pytest; \ - fi [ -z "$(TEST_EXTRA_PACKAGES)" ] || pip install $(TEST_EXTRA_PACKAGES) install-style: install-docs install-dev @@ -99,11 +93,7 @@ install-dev: pip install -U pip setuptools wheel pip install -e . [ "$(ETESYNC_TESTS)" = "false" ] || pip install -Ue .[etesync] - set -xe && if [ "$(REQUIREMENTS)" = "devel" ]; then \ - pip install -U --force-reinstall \ - git+https://github.com/mitsuhiko/click \ - git+https://github.com/kennethreitz/requests; \ - elif [ "$(REQUIREMENTS)" = "minimal" ]; then \ + set -xe && if [ "$(REQUIREMENTS)" = "minimal" ]; then \ pip install -U --force-reinstall $$(python setup.py --quiet minimal_requirements); \ fi From 86535a9db326c1152f9dbba6ca9d20b10cf2e1ab Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 15:08:17 +0200 Subject: [PATCH 09/12] Merge test dependencies into dev dependencies --- .builds/tests-minimal.yaml | 2 +- .builds/tests-release.yaml | 2 +- Makefile | 5 +---- docs/contributing.rst | 4 ++-- docs/packaging.rst | 4 ++-- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.builds/tests-minimal.yaml b/.builds/tests-minimal.yaml index dec4ba0..afeba0b 100644 --- a/.builds/tests-minimal.yaml +++ b/.builds/tests-minimal.yaml @@ -21,7 +21,7 @@ tasks: - setup: | sudo systemctl start docker cd vdirsyncer - make -e install-test + make -e install-dev - test: | cd vdirsyncer # Non-system python is used for packages: diff --git a/.builds/tests-release.yaml b/.builds/tests-release.yaml index 05d838a..9766b50 100644 --- a/.builds/tests-release.yaml +++ b/.builds/tests-release.yaml @@ -18,7 +18,7 @@ tasks: - setup: | sudo systemctl start docker cd vdirsyncer - make -e install-test -e install-style + make -e install-dev -e install-style - test: | cd vdirsyncer # Non-system python is used for packages: diff --git a/Makefile b/Makefile index 0104ff1..cf708f4 100644 --- a/Makefile +++ b/Makefile @@ -60,10 +60,6 @@ ci-test-storage: test: $(PYTEST) -install-test: install-dev - pip install -Ur test-requirements.txt - [ -z "$(TEST_EXTRA_PACKAGES)" ] || pip install $(TEST_EXTRA_PACKAGES) - install-style: install-docs install-dev pip install pre-commit @@ -92,6 +88,7 @@ release-deb: install-dev: pip install -U pip setuptools wheel pip install -e . + pip install -Ur test-requirements.txt $(TEST_EXTRA_PACKAGES) [ "$(ETESYNC_TESTS)" = "false" ] || pip install -Ue .[etesync] set -xe && if [ "$(REQUIREMENTS)" = "minimal" ]; then \ pip install -U --force-reinstall $$(python setup.py --quiet minimal_requirements); \ diff --git a/docs/contributing.rst b/docs/contributing.rst index 73175c7..3bb6068 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -87,8 +87,8 @@ virtualenv_ and run this inside of it:: # Install git commit hook for some extra linting and checking pre-commit install - # install test dependencies - make install-test + # Install development dependencies + make install-dev Then you can run:: diff --git a/docs/packaging.rst b/docs/packaging.rst index d4a81bb..8923f33 100644 --- a/docs/packaging.rst +++ b/docs/packaging.rst @@ -41,9 +41,9 @@ repository or PyPI package. Trying to e.g. run ``pytest`` directly will require a lot of environment variables to be set (for configuration) and you probably don't want to deal with that. -You can install the testing dependencies with:: +You can install the all development dependencies with:: - make install-test + make install-dev You probably don't want this since it will use pip to download the dependencies. Alternatively you can find the testing dependencies in From 808e01f9c808f1b2fc47cbbbf705bafb6f67e51b Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 15:11:49 +0200 Subject: [PATCH 10/12] =?UTF-8?q?DAVDroid=20is=20now=20called=20DAVx?= =?UTF-8?q?=E2=81=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/when.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/when.rst b/docs/when.rst index a7ae997..17905f7 100644 --- a/docs/when.rst +++ b/docs/when.rst @@ -50,7 +50,7 @@ program chosen: * Such a setup doesn't work at all with smartphones. Vdirsyncer, on the other hand, synchronizes with CardDAV/CalDAV servers, which can be accessed with - e.g. DAVDroid_ or the apps by dmfs_. + e.g. DAVx⁵_ or the apps by dmfs_. -.. _DAVDroid: http://davdroid.bitfire.at/ +.. _DAVx⁵: https://www.davx5.com/ .. _dmfs: https://dmfs.org/ From 77d64ddc2c0f87a3d3a5c5693948d4ce3e62c55a Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 15:12:48 +0200 Subject: [PATCH 11/12] Always check link as part of building docs --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index cf708f4..ca7051d 100644 --- a/Makefile +++ b/Makefile @@ -74,8 +74,6 @@ install-docs: docs: cd docs && make html - -linkcheck: sphinx-build -W -b linkcheck ./docs/ ./docs/_build/linkcheck/ release-deb: From d95a8264f46dcf1a9e8e23624c8c03a293d72cd2 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Sat, 12 Jun 2021 15:13:16 +0200 Subject: [PATCH 12/12] Merge style dependencies into dev dependencies --- .builds/tests-release.yaml | 2 +- Makefile | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.builds/tests-release.yaml b/.builds/tests-release.yaml index 9766b50..793c044 100644 --- a/.builds/tests-release.yaml +++ b/.builds/tests-release.yaml @@ -18,7 +18,7 @@ tasks: - setup: | sudo systemctl start docker cd vdirsyncer - make -e install-dev -e install-style + make -e install-dev -e install-docs - test: | cd vdirsyncer # Non-system python is used for packages: diff --git a/Makefile b/Makefile index ca7051d..632d319 100644 --- a/Makefile +++ b/Makefile @@ -60,9 +60,6 @@ ci-test-storage: test: $(PYTEST) -install-style: install-docs install-dev - pip install pre-commit - style: pre-commit run --all ! git grep -i syncroniz */* @@ -87,6 +84,7 @@ install-dev: pip install -U pip setuptools wheel pip install -e . pip install -Ur test-requirements.txt $(TEST_EXTRA_PACKAGES) + pip install pre-commit [ "$(ETESYNC_TESTS)" = "false" ] || pip install -Ue .[etesync] set -xe && if [ "$(REQUIREMENTS)" = "minimal" ]; then \ pip install -U --force-reinstall $$(python setup.py --quiet minimal_requirements); \