在子文件夹

问题描述

我将 Flake8 与一堆插件Flake8-docstringsFlake8-isortFlake8-black)一起使用。我已将它们全部预安装到 venv 中。

要与 pre-commit 检查我的存储库:

  • 文件夹有两个包
  • 每个都有自己的
    • pyproject.toml(配置 blackisort
    • setup.cfg(配置 Flake8pydocstyle
├── foo
│   ├── pyproject.toml
│   ├── setup.cfg
│   └── (the package)
├── bar
│   ├── pyproject.toml
│   ├── setup.cfg
│   └── (the package)
└── venv
@H_502_43@

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

这是我目前的做法:

---
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
@H_502_43@

当我运行 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
@H_502_43@
  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 钩子会失去框架的大部分优势:

  • 预提交不管理工具的安装(您的每个开发人员都必须单独安装特定版本的工具)
  • 没有发生任何基于文件名的优化
    • 如果您只更改一个文件,则您当前正在对整个存储库进行 两次
    • 在合并冲突期间,预提交会优化要运行的文件(而不是整个存储库)
    • 还有更多

对于您的 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 的当前维护者