From bfd9753314a4d508c2908819900abe445c1b55dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Nejus?= Date: Tue, 28 May 2024 11:35:17 +0100 Subject: [PATCH] Remove tox Unfortunately tox does not play very nicely with Poetry. Tox was mostly useful since it managed virtual environments, however now this is done by Poetry. Thus we do not anymore need it since we can run our commands using `poetry run`. I have extended the internal helper tool 'project' with those commands that have previously been run using tox. --- .github/workflows/ci.yaml | 16 ++-- .github/workflows/formatting_check.yml | 17 +++- .github/workflows/integration_test.yaml | 12 +-- CONTRIBUTING.rst | 49 +++++++----- poetry.lock | 100 ++++++++++++++++++++++-- pyproject.toml | 4 + tox.ini | 67 ---------------- 7 files changed, 153 insertions(+), 112 deletions(-) delete mode 100644 tox.ini diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a4c488000..46ab2b203 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -39,24 +39,22 @@ jobs: sudo apt install ffmpeg poetry install --extras replaygain - - name: Test older Python versions with tox + - name: Test older Python versions if: matrix.python-version != '3.x' - run: | - tox -e py-test + run: poetry run project test - name: Upload code coverage if: matrix.python-version == '3.8' && matrix.platform == 'ubuntu-latest' continue-on-error: true run: codecov - - name: Test latest Python version with tox and mypy + - name: Check types if: matrix.python-version == '3.x' # continue-on-error is not ideal since it doesn't give a visible # warning, but there doesn't seem to be anything better: # https://github.com/actions/toolkit/issues/399 continue-on-error: true - run: | - tox -vv -e py-mypy + run: poetry run project check-types test-docs: runs-on: ubuntu-latest @@ -82,8 +80,8 @@ jobs: - name: Add problem matcher run: echo "::add-matcher::.github/sphinx-problem-matcher.json" - - name: Build and check docs using tox - run: tox -e docs + - name: Build and check docs + run: poetry run project docs lint: runs-on: ubuntu-latest @@ -107,4 +105,4 @@ jobs: run: echo "::add-matcher::.github/flake8-problem-matcher.json" - name: Lint with flake8 - run: tox -e py-lint + run: poetry run project lint diff --git a/.github/workflows/formatting_check.yml b/.github/workflows/formatting_check.yml index 76154fe4d..fda4890d1 100644 --- a/.github/workflows/formatting_check.yml +++ b/.github/workflows/formatting_check.yml @@ -5,10 +5,19 @@ jobs: formatting_check: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + + - name: Install Poetry + run: pipx install poetry + + - name: Set up Python 3.x + uses: actions/setup-python@v5 + with: + python-version: 3.8 + cache: poetry + - name: Install dependencies - uses: actions/checkout@v3 + run: poetry install - name: Run formatting check - uses: paolorechia/pox@v1.0.1 - with: - tox_env: "format_check" + run: poetry run project check-format diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index d19d267a3..bb234df23 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -2,7 +2,7 @@ name: integration tests on: workflow_dispatch: schedule: - - cron: '0 0 * * SUN' # run every Sunday at midnight + - cron: "0 0 * * SUN" # run every Sunday at midnight jobs: test_integration: runs-on: ubuntu-latest @@ -23,13 +23,13 @@ jobs: pip install poetry poetry install - - name: Test with tox - run: | - tox -e int + - name: Test + env: + INTEGRATION_TEST: 1 + run: poetry run project test - name: Check external links in docs - run: | - tox -e links + run: poetry run project check-docs-links - name: Notify on failure if: ${{ failure() }} diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 785b97892..e54076ba0 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -62,8 +62,10 @@ Programming information in the `“For Developers” section of the docs `__. -Tools -^^^^^ +.. _development-tools: + +Development Tools +^^^^^^^^^^^^^^^^^ In order to develop beets, you will need a few tools installed: @@ -88,6 +90,8 @@ Install `poetry`_ and `poethepoet`_ using `pipx`_:: .. _pipx: https://pipx.pypa.io/stable .. _pipx-installation-instructions: https://pipx.pypa.io/stable/installation/ +.. _getting-the-source: + Getting the Source ^^^^^^^^^^^^^^^^^^ @@ -203,8 +207,7 @@ request and your code will ship in no time. listed. 6. Add a changelog entry to ``docs/changelog.rst`` near the top of the document. -7. Run the tests and style checker. The easiest way to run the tests is - to use `tox`_. For more information on running tests, see :ref:`testing`. +7. Run the tests and style checker, see :ref:`testing`. 8. Push to your fork and open a pull request! We’ll be in touch shortly. 9. If you add commits to a pull request, please add a comment or re-request a review after you push them since GitHub doesn’t @@ -273,9 +276,9 @@ Style We follow `black`_ formatting and `google's docstring format`_. -You can use ``tox -e lint`` to check your code for any style errors. -Running ``tox -e format`` will automatically format your code according -to the specifications required by the project. +Use ``poe check-format`` and ``poe lint`` to check your code for style and +linting errors. Running ``poe format`` will automatically format your code +according to the specifications required by the project. .. _black: https://black.readthedocs.io/en/stable/ .. _google's docstring format: https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings @@ -330,31 +333,36 @@ Testing Running the Tests ----------------- -To run the tests for multiple Python versions, compile the docs, and -check style, use `tox`_. Just type ``tox`` or use something like -``tox -e py38`` to test a specific configuration. You can use the -``--parallel`` flag to make this go faster. +Use ``poe`` to run tests:: + + $ poe test [pytest options] You can disable a hand-selected set of "slow" tests by setting the -environment variable SKIP_SLOW_TESTS before running them. +environment variable ``SKIP_SLOW_TESTS``, for example:: -Other ways to run the tests: - -- ``python testall.py`` (ditto) -- ``python -m unittest discover -p 'test_*'`` (ditto) -- `pytest`_ + $ SKIP_SLOW_TESTS=1 poe test Coverage ^^^^^^^^ -``tox -e cov`` will add coverage info for tests: Coverage is pretty low -still -- see the current status on `Codecov`_. +Coverage is measured automatically when running the tests. If you find it takes +a while to calculate, disable it:: + + $ poe test --no-cov + +You are welcome to explore coverage by opening the HTML report in +``.reports/html/index.html``. + +Note that for each covered line the report shows **which tests cover it** +(expand the list on the right-hand side of the affected line). + +You can find project coverage status on `Codecov`_. Red Flags ^^^^^^^^^ The `pytest-random`_ plugin makes it easy to randomize the order of -tests. ``py.test test --random`` will occasionally turn up failing tests +tests. ``poe test --random`` will occasionally turn up failing tests that reveal ordering dependencies—which are bad news! Test Dependencies @@ -396,7 +404,6 @@ others. See `unittest.mock`_ for more info. .. _Codecov: https://codecov.io/github/beetbox/beets .. _pytest-random: https://github.com/klrmn/pytest-random -.. _tox: https://tox.readthedocs.io/en/latest/ .. _pytest: https://docs.pytest.org/en/stable/ .. _pyproject.toml: https://github.com/beetbox/beets/tree/master/pyproject.toml .. _test: https://github.com/beetbox/beets/tree/master/test diff --git a/poetry.lock b/poetry.lock index 90b39993e..31b9ea742 100644 --- a/poetry.lock +++ b/poetry.lock @@ -134,6 +134,52 @@ soupsieve = ">1.2" html5lib = ["html5lib"] lxml = ["lxml"] +[[package]] +name = "black" +version = "24.2.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, + {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, + {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, + {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, + {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, + {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, + {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, + {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, + {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, + {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, + {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, + {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, + {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, + {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, + {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, + {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, + {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, + {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, + {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, + {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, + {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, + {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "brotli" version = "1.1.0" @@ -383,13 +429,13 @@ requests = ">=2.7.9" [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.6" description = "Cross-platform colored terminal text." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] [[package]] @@ -766,6 +812,23 @@ files = [ {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.dependencies] +colorama = {version = ">=0.4.6", optional = true, markers = "extra == \"colors\""} + +[package.extras] +colors = ["colorama (>=0.4.6)"] + [[package]] name = "itsdangerous" version = "2.0.1" @@ -1259,6 +1322,17 @@ files = [ {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + [[package]] name = "pep8-naming" version = "0.12.1" @@ -1353,6 +1427,22 @@ files = [ docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + [[package]] name = "pluggy" version = "1.0.0" @@ -2628,4 +2718,4 @@ web = ["flask", "flask-cors"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4" -content-hash = "697ebfc73bb20e4bf4ee41f639847212384102601d94b0231374f41e6932e5bd" +content-hash = "979ae1e0d13b43d98dde8c1506d338981d1babd82202b05082165ba73aa9ce79" diff --git a/pyproject.toml b/pyproject.toml index 5f12b7787..22adff8ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,6 +84,10 @@ reflink = "*" requests_oauthlib = "*" responses = ">=0.3.0" +[tool.poetry.group.format.dependencies] +isort = { version = "<5.14", extras = ["colors"] } +black = "<24.3" + [tool.poetry.group.lint.dependencies] flake8 = "*" flake8-docstrings = "*" diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 9ab1ba613..000000000 --- a/tox.ini +++ /dev/null @@ -1,67 +0,0 @@ -# Tox (http://tox.testrun.org/) is a tool for running tests -# in multiple virtualenvs. This configuration file will run the -# test suite on all supported python versions. To use it, "pip install tox" -# and then run "tox" from this directory. - -[tox] -envlist = py38-{cov,lint,mypy}, docs, format, format_check - -[_test] -deps = .[test] - -[_lint] -deps = .[lint] -files = beets beetsplug beet test setup.py docs - -[_mypy] -deps = - .[mypy] - .[test] - -[testenv] -deps = - {test,cov}: {[_test]deps} - lint: {[_lint]deps} - mypy: {[_mypy]deps} -passenv = INTEGRATION_TEST -commands = - test: python -m pytest {posargs} - lint: python -m flake8 {posargs} {[_lint]files} - mypy: mypy - -[testenv:docs] -basepython = python3.10 -deps = - sphinx>=5 - pydata_sphinx_theme -commands = sphinx-build -W -q -b html docs {envtmpdir}/html {posargs} - -# checks all links in the docs -[testenv:links] -deps = sphinx -allowlist_externals = /bin/bash -commands = /bin/bash -c '! sphinx-build -b linkcheck docs {envtmpdir}/linkcheck | grep "broken\s"' - -[testenv:int] -deps = {[_test]deps} -setenv = INTEGRATION_TEST = 1 -passenv = GITHUB_ACTIONS -commands = python -bb -m pytest {posargs} - -[testenv:format] -deps = - isort==5.13.2 - black==24.2.0 -skip_install = True -commands = - isort beets beetsplug test - black beets beetsplug test - -[testenv:format_check] -deps = - isort==5.13.2 - black==24.2.0 -skip_install = True -commands = - isort beets beetsplug test --check --diff - black beets beetsplug test --check --diff