自定义pre-commit钩子调用just命令报错:误将暂存文件识别为recipe
自定义pre-commit钩子调用just命令时,暂存文件被误识别为recipe导致失败
问题
在自定义pre-commit钩子中引用just命令时,just错误地将暂存的Python文件识别为recipe,导致ruff-lint和ruff-format钩子执行失败,提示Justfile中不存在对应文件的recipe。目前将钩子entry替换为直接的poetry命令可正常运行,但希望继续使用just命令。
报错详情
trim trailing whitespace.................................................Passed fix end of files.........................................................Passed check yaml...............................................................Passed check toml...............................................................Passed ruff (linter)............................................................Failed - hook id: ruff-lint - exit code: 1 error: Justfile does not contain recipes `folder_1/src/alembic/versions/fb4554c0e46f_first_commit.py`, `folder_1/src/alembic/env.py`, `folder_1/src/crud/user.py`, or `config.py`. ruff (formatter).........................................................Failed - hook id: ruff-format - exit code: 1 error: Justfile does not contain recipes `folder_1/src/alembic/versions/fb4554c0e46f_first_commit.py`, `folder_1/src/alembic/env.py`, `folder_1/src/crud/user.py`, or `config.py`.
项目目录结构(相关部分)
|-- folder_1 |-- src |-- alembic | |-- env.py | |-- versions | |-- fb4554c0e46f_first_commit.py |-- crud | |-- user.py ... |-- folder_2 |-- src ... .pre-commit-config.yaml config.py justfile poetry.lock pyproject.toml
配置文件
.pre-commit-config.yaml
default_language_version: python: python3.10 repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-toml - repo: local hooks: - id: ruff-lint name: ruff (linter) entry: just ruff-fix language: system types: [python] - id: ruff-format name: ruff (formatter) entry: just ruff-format language: system types: [python]
justfile
help: @just --list install: @echo "🚀 Installing dependencies" @poetry install --with dev install-pre-commit: @echo "🚀 Setting up the hooks" @poetry run pre-commit install check-project: @echo "🚀 Checking consistency between poetry.lock and pyproject.toml" @poetry check --lock @echo "🚀 Running the hooks against all files" @poetry run pre-commit run --all-files ruff: @echo "🚀 Linting the project with Ruff" @poetry run ruff check . ruff-show-violations: @echo "🚀 Linting the project with Ruff and show violations" @poetry run ruff check --output-format="grouped" . ruff-fix: @echo "🚀 Linting the project with Ruff and autofix violations (where possible)" @poetry run ruff check --fix . ruff-format: @echo "🚀 Formatting the code with Ruff" @poetry run ruff format . ruff-format-check: @echo "🚀 Listing files Ruff would reformat" @poetry run ruff format --check . lint-and-format: ruff-fix ruff-format
版本信息
$ just --version just 1.23.0 $ pre-commit --version pre-commit 3.7.0
解决方案
问题根源是pre-commit会将暂存的文件路径作为参数传递给钩子的entry命令,而just默认会把这些额外参数当作要执行的recipe名称,导致识别错误。以下两种方法可解决:
方法1:用--分隔just命令与额外参数
修改.pre-commit-config.yaml中的钩子entry,在just recipe名称后添加--,让just将后续参数传递给recipe内部的命令,而非当作新recipe:
# 修改后的ruff-lint钩子 - id: ruff-lint name: ruff (linter) entry: just ruff-fix -- language: system types: [python] # 修改后的ruff-format钩子 - id: ruff-format name: ruff (formatter) entry: just ruff-format -- language: system types: [python]
方法2:修改justfile让recipe接收参数
调整justfile中的ruff-fix和ruff-format recipe,使其接受参数并传递给ruff命令,这样既可以处理pre-commit传递的指定文件,也能保持全局执行的能力:
ruff-fix *args: @echo "🚀 Linting the project with Ruff and autofix violations (where possible)" @poetry run ruff check --fix {{ args | join(" ") }} . ruff-format *args: @echo "🚀 Formatting the code with Ruff" @poetry run ruff format {{ args | join(" ") }} .
当没有传递参数时,{{ args | join(" ") }}会是空字符串,不影响原有全局执行逻辑;当pre-commit传递文件路径时,这些路径会被传递给ruff,只处理指定文件。
内容的提问来源于stack exchange,提问作者amiola
相关产品推荐
相关产品推荐

