Skip to content

fix(init): use prek when installing hooks if pre-commit is missing - #2065

Open
DSeaStar wants to merge 3 commits into
commitizen-tools:masterfrom
DSeaStar:fix/init-use-prek-installer
Open

fix(init): use prek when installing hooks if pre-commit is missing#2065
DSeaStar wants to merge 3 commits into
commitizen-tools:masterfrom
DSeaStar:fix/init-use-prek-installer

Conversation

@DSeaStar

Copy link
Copy Markdown

Description

cz init already treated prek as a valid hook installer (is_pre_commit_installed()), but the install step always ran pre-commit install. When only prek is on PATH, that raises FileNotFoundError.

This change:

  • Lists available installers (pre-commit, prek)
  • Uses the only one present
  • Asks which to use when both are installed
  • Invokes <installer> install --hook-type ...

Fixes #2018

Checklist

Was generative AI tooling used to co-author this PR?

  • Yes (please specify the tool below)

Generated-by: Cursor Grok following the guidelines

Code Changes

  • Add test cases to all the changes you introduce
  • Run uv run poe all locally to ensure this change passes linter check and tests
  • Manually test the changes:
    • Verify the feature/bug fix works as expected in real-world scenarios
    • Test edge cases and error conditions
    • Ensure backward compatibility is maintained
    • Document any manual testing steps performed
  • Update the documentation for the changes

Manual testing: unit tests cover only-prek, only-pre-commit, both (prompt), and neither (InitFailedError). ruff check and mypy pass on the touched files. I did not run the full interactive cz init UI in a throwaway repo.

Documentation Changes

  • Run uv run poe doc locally to ensure the documentation pages renders correctly
  • Check and fix any broken links (internal or external)

Docs change is a one-line note in docs/commands/init.md. I did not rebuild the full mkdocs site.

Expected Behavior

  • Only prek installed: cz init runs prek install
  • Only pre-commit installed: same as today (pre-commit install)
  • Both installed: prompt, then run the chosen installer
  • Neither installed: InitFailedError mentioning both tools

Steps to Test This Pull Request

  1. Install commitizen and prek only (no pre-commit on PATH)
  2. Run cz init and select a hook type
  3. Confirm hooks are installed via prek and no FileNotFoundError
  4. Repeat with only pre-commit, then with both (should prompt)

Additional Context

Owner-confirmed in #2018 (issue-status: wait-for-implementation). Desired behavior is from the issue: treat the two tools as interchangeable, auto-select when only one is present, ask when both are.

cz init already treated prek as installed, but always ran
`pre-commit install`, which raised FileNotFoundError when only prek
was on PATH. Use the available installer, and ask when both exist.

Fixes commitizen-tools#2018
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.25%. Comparing base (93c7b51) to head (bb343bc).
⚠️ Report is 6 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2065   +/-   ##
=======================================
  Coverage   98.24%   98.25%           
=======================================
  Files          61       61           
  Lines        2799     2815   +16     
=======================================
+ Hits         2750     2766   +16     
  Misses         49       49           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@woile woile left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, one comment only

ask when both are on PATH.
"""
installers = project_info.available_hook_installers()
if not installers:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the user doesn't have any installed and doesn't want to use any of these? Like myself.

Maybe if nothing is installed, it should prompt:

No pre-commit hook detected, skipping question

so users who want this know how to act accordingly (install pre-commit and retry).

What do you think?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — if neither pre-commit nor prek is installed we skip the question now and print that message.

DSeaStar and others added 2 commits August 14, 2026 16:56
If neither pre-commit nor prek is on PATH, skip the hook-type
question instead of failing init. Users who want hooks can
install a tool and retry.
The InitFailedError branch in _ask_hook_installer was flagged by
codecov as the only uncovered line of the PR. Add a test where the
installer is available during the hook-type question but disappears
before the install step, so the guard is exercised instead of
removed.
@DSeaStar

Copy link
Copy Markdown
Author

Addressed in c9ea08e: when neither pre-commit nor prek is on PATH, cz init now skips the hook question entirely and prints No pre-commit hook detected, skipping question, so users who want hooks know to install one and re-run.

I also noticed codecov flagged one uncovered line — the InitFailedError branch in _ask_hook_installer(). I kept it as a guard against the installer disappearing between the question and the install step (e.g. PATH change), and added a test for it in bb343bc instead of removing it.

Could you take another look when you get a chance? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cz init raises FileNotFoundError for pre-commit if only prek is installed

2 participants