在子文件夹中使用 setup.cfg 预提交 flake8

Pre-commit flake8 with setup.cfg in subfolder

我使用 flake8 和一堆插件(flake8-docstringsflake8-isortflake8-black)。我已将它们全部预安装到 venv.

要检查我的回购 pre-commit:

├── foo
│   ├── pyproject.toml
│   ├── setup.cfg
│   └── (the package)
├── bar
│   ├── pyproject.toml
│   ├── setup.cfg
│   └── (the package)
└── venv

我想通过 pre-commit 为两个包调用 flake8

这是我目前的做法:

---
repos:
  - repo: local
    hooks:
      - id: flake8-foo
        name: Run flake8 in foo package
        entry: bash -c "cd foo && flake8"
        language: python
      - id: flake8-bar
        name: Run flake8 in bar package
        entry: bash -c "cd bar && flake8"
        language: python

当我 运行 pre-commit run --all-files 并且 foo 中出现错误时,它多次打印相同的输出:

./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
./path/in/foo/to/file.py:49:1: D401 First line should be in imperative mood
  1. 有没有更好的方法来解决这个问题?
    • 不,我不愿意将包拆分到它们自己的存储库中
  2. 如何让错误消息只打印一次?

pre-commit 按设计对 文件 进行操作,它还经过优化以将针对文件的 运行 秒 linter 批处理到多个进程中

这里发生的事情是您的配置 运行 宁 bash -c "cd bar && flake8" file1 file2 file3

的多个调用(每个处理器约 1 个)等

幸运的是,您可以使用一个设置来为您解决此问题:

这样:

---
repos:
  - repo: local
    hooks:
      - id: flake8-foo
        name: Run flake8 in foo package
        entry: bash -c "cd foo && flake8"
        language: python
        pass_filenames: false
        files: ^foo/
        types: [python]
      - id: flake8-bar
        name: Run flake8 in bar package
        entry: bash -c "cd bar && flake8"
        language: python
        pass_filenames: false
        files: ^bar/
        types: [python]

就是说,您通过 repo: local 挂钩失去了框架的大部分优势:

  • 预提交不管理工具的安装(您的每个开发人员都必须单独安装特定版本的工具)
  • 没有进行任何基于文件名的优化
    • 如果您只更改一个文件,那么您目前正在检查整个存储库两次
    • 在合并冲突期间,预提交优化哪些文件 运行(不是整个 repo)
    • 以及更多

我建议你的 monorepo 设置仍然以正常方式调用 flake8 但利用 --config 这样它就可以对付你的子回购:

repos:
-   repo: https://gitlab.com/pycqa/flake8
    rev: 3.8.4
    hooks:
    -   id: flake8
        name: flake8 ./foo/
        alias: flake8-foo
        files: ^foo/
        args: [--config, foo/setup.cfg]
    -   id: flake8
        name: flake8 ./bar/
        alias: flake8-bar
        files: ^bar/
        args: [--config, bar/setup.cfg]

免责声明:我是 pre-commit 的作者和 flake8 的当前维护者