ewjoachim / poetry-to-pre-commit

A pre-commit hook for syncing version numbers between poetry.lock and .pre-commit-config.yaml
MIT License
0 stars 1 forks source link

Poetry to Pre-Commit: a pre-commit hook to sync .pre-commit-config.yaml versions from Poetry

GitHub Repository Continuous Integration Coverage badge MIT License Contributor Covenant

Poetry to Pre-commit is a set of 2 pre-commit hooks:

Installation & Usage

# .pre-commit-config.yaml
repos:
  # ...
  - repo: https://github.com/ewjoachim/poetry-to-pre-commit
    rev: "<current release>"
    hooks:
      # Use this hook to ensure that the versions of the repos are synced
      - id: sync-repos
        # All the arguments are optional
        args: [
            # You may skip some projects if you want, they won't be updated
            "--skip=some_project",
            "--skip=another_project",
            # You can specify that a given hook id (like "pyright-python")
            # should be mapped to a given PyPI package name (like "pyright")
            "--map",
            "pyright-python=pyright",
            "--map",
            "ruff-pre-commit=ruff",
          ]

      # Use this hook to sync a specific hook with a Poetry group, adding all
      # the dependencies of the group as additional_dependencies
      - id: sync-hooks-additional-dependencies
        # "mypy" is the id of a pre-commit hook
        # "types" is the name of your poetry group containing typing dependencies
        # "main" is the automated name associated with the "default" poetry dependencies
        # `--no-new-deps` will update or remove dependencies, but not add any new one.
        args: ["--bind", "mypy=types,main", "--no-new-deps"]

How it works

sync-repos

This hook will look for all the repo keys in your .pre-commit-config.yaml, extract the repository name (the part after the last /), potentially remove the mirrors- prefix, potentially map to a different name you might have provided through --map, (skipping the names provided by --skip) and then look for the corresponding package in your poetry.lock. If it finds it, then back in the .pre-commit-config.yaml, it will update the rev key to the version found in the poetry.lock. If the rev was previously starting with a v, then the new version will also start with a v (that's because rev in .pre-commit-config.yaml refer to a git tag name which often but not always has a leading v, whereas the version in poetry.lock is a PEP-440 version number, and never has a leading v).

sync-hooks-additional-dependencies_cli

This hook will iterate over all the --bind {pre-commit-hook}={poetry_groups} arguments you provided, and for each of them, it will look for the corresponding groups in your pyproject.toml. If it finds it, then it will look for the version of all the dependencies of these groups in your poetry.lock. In .pre-commit-config.yaml, it will identify the corresponding hook, and set the additional_dependencies key to the list sorted of all the dependencies. If you pass the option --no-new-deps, packages that are already in your pre-commit config file will be updated or removed (if they are not listed in any of the considered poetry dependencies' groups), but no new packages will be added. You can use this to avoid installing unecessary dependencies in the pre-commit environment, e.g. if mypy does not need all of them to type check your project.

Credit where it's due

This project is heavily inspired by sync_with_poetry. I wanted to add the sync-hook-with-group, and to test a different approach for the implementation (using poetry as a lib instead of parsing the lock file ourselves, using ruamel rather than regex for roundtrip yaml). While all the code in the repo is original, the insipration is strong enough that I kept the original author, @floatingpurr, in the LICENSE file. Thank you, @floatingpurr!