惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Tailwind CSS Blog
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
GbyAI
GbyAI
爱范儿
爱范儿
量子位
Martin Fowler
Martin Fowler
V
V2EX
博客园 - 三生石上(FineUI控件)
I
InfoQ
MongoDB | Blog
MongoDB | Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
Netflix TechBlog - Medium
D
DataBreaches.Net
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Last Week in AI
Last Week in AI
U
Unit 42
Apple Machine Learning Research
Apple Machine Learning Research
H
Help Net Security
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
Engineering at Meta
Engineering at Meta

jdhao's digital space

Conversion between base64 and OpenCV or PIL Image 腾讯云对象存储博客图床开启 CDN 加速(不需要购买额外域名) Search and Replace in Multiple Files in Vim/Neovim Change Table Column Width in LaTeX Image or Table Side by Side in LaTeX LaTeX 并排显示图像或表格 Firenvim: Neovim inside Your Browser Content inside HTML tags missing in Latest Hugo? Creating Markdown Front Matter with Ultisnips Labelme JSON 标注格式转 voc XML 格式 Nifty Nvim Techniques That Make My Life Easier -- Series 6 macOS 下如何为视频制作字幕 Running Command Asynchronously inside Neovim Resolving Merge Conflict after Git Stash Pop Pylint: command not found? A Hands-on Experience with Neovim's Built-in LSP Support How to Convert PDF to Images with Imagemagick 互联网上常用缩略语集锦 File Backup in Neovim Converting PDF Pages to Images with Poppler Nifty Nvim Techniques That Make My Life Easier -- Series 5 Neovim Configuration for System-wide Use How to sort a list of tuple or list in Python -- lambda or itemgetter? Building A Vim Statusline from Scratch 人类第一颗原子弹爆炸始末 Distributed Training in PyTorch with Horovod Learning Expect Programming Essential Knowledge about SSH Nifty LaTeX Techniques -- Series 1 更改 Adsense 邮寄地址,重新寄送 PIN
Pre-commit Setup for Your Project
2026-04-15 · via jdhao's digital space

We have a Python project where there are several developers, and we have a mature CI pipeline to do code linting, formatting check for python, yaml, json, and testing etc. The problem with CI pipeline is that you can only get feedback after you commit your code and push to the remote repo. The feedback is not instant and may be delayed for several minutes. If there are some linting issues, you then need to fix the issue and make another commit. This is also making the PR history messy.

For me personally, I have configured my Neovim to show linting issues, and also format after save. I can not enforce other developers the same local setup as me, because different developers are using different local environment (editor, OS, and terminal).

After some research, I think pre-commit is a good solution for this. Basically, it will manage and run a list of hooks before you commit your code. If there are some issues with your code, you can not commit your code. This will force the developers to fix the issue before they even hit the CI pipeline.

Install and set up#

To integrate pre-commit into a project managed by uv:

Note that we use --dev here, because pre-commit is only needed for development, not necessary for the running of the project/application itself.

Then create .pre-commit-config.yaml in the project root. Add your configuration for pre-commit hooks there, something like this:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: check-added-large-files

and then install the hooks:

uv run pre-commit install

Local repo/hooks#

Usually, for pre-commit, we use the hooks provided by some remote repositories. For our project, since we already declare black, ruff and uv as dependencies, we do not really want to install another set of tools somewhere else.

For this, we need to set repo to local:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-added-large-files
  # the following are local hooks, the repo is local
  - repo: local
    hooks:
      - id: black
        name: black-format-check
        entry: uv run black --check ./
        pass_filenames: false
        language: system
        types: [python]

Configuring hooks#

All config options for a hook can be found here.

This is a valid local hook:

- id: black
  name: black-format-check
  entry: uv run black --check ./
  pass_filenames: false
  language: system
  types: [python]

For local hook, you can set the language to system. Then pre-commit will not try to set up the environment to run this hook.

pass file names or not?#

By default, pre-commit will pass file names to each hook entry, but for some hooks, they do not work that way. If you pass the file names to those hook, they will error out or have strange behavior. For example, for ruff, we usually just check the whole project, not a single file. You can set up a ruff-linting hook like this:

- id: ruff
  name: ruff-linting
  entry: uv run ruff check app/
  pass_filenames: false
  language: system
  types: [python]

Warning

The option pass_filenames: false is crucial here. Without this, it seems that ruff will not fully follow the pyproject.toml, see this github issue.

This is not essentially a pre-commit issue, but a ruff “issue”/feature? If you ignore a file in ruff config, but pass it explicitly to ruff, ruff is still going to check it.

#pyproject.toml

[tool.ruff]
exclude = ["my_file.py"]

If you run ruff check my_file.py, ruff will report issues in this file.

Running pre-commit in pipeline#

If you do not want to separate steps in your CI pipeline for different checks, using pre-commit in the CI is also a good idea.

Basically, in one of the CI step, we need to run the following command:

uv run pre-commit run --all-files

You may also consider caching the pre-commit cache to speed up pipeline, if you use a lot of external repos for the hooks. See also the official doc on managing CI caches.

Use uv under the hood to manage pre-commit env?#

This is also possible, see pre-commit-uv and also this post. The author seems to be not interested to add support directly for uv to manage the virtual env, see this closed PR.

References#