Skip to content

Comments

Add upgrade suggestion option in config#1490

Closed
hofbi wants to merge 2 commits intoj178:masterfrom
hofbi:upgrade-suggestion
Closed

Add upgrade suggestion option in config#1490
hofbi wants to merge 2 commits intoj178:masterfrom
hofbi:upgrade-suggestion

Conversation

@hofbi
Copy link

@hofbi hofbi commented Jan 29, 2026

Currently if the minimum prek version does not match, a user sees something like

Required minimum prek version `0.3.0` is greater than current version `0.2.30`. Please consider updating prek.

It would be nice to give the user a more concrete action to fix this error. To do so, I am adding an optional filed to the config named prek_upgrade_suggestion. This allows specifying an extra message like Please run 'uv tool install prek' or Please run prek self upgrade which is shown on top of the error message above.

@codecov
Copy link

codecov bot commented Jan 29, 2026

Codecov Report

❌ Patch coverage is 88.70968% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.41%. Comparing base (7640685) to head (5564756).
⚠️ Report is 33 commits behind head on master.

Files with missing lines Patch % Lines
crates/prek/src/config.rs 88.52% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1490      +/-   ##
==========================================
- Coverage   91.51%   91.41%   -0.10%     
==========================================
  Files          87       87              
  Lines       18153    18210      +57     
==========================================
+ Hits        16612    16647      +35     
- Misses       1541     1563      +22     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@prek-ci-bot
Copy link

prek-ci-bot bot commented Jan 29, 2026

📦 Cargo Bloat Comparison

Binary size change: +0.00% (22.5 MiB → 22.5 MiB)

Expand for cargo-bloat output

Head Branch Results

 File  .text    Size           Crate Name
 0.3%   0.8% 75.6KiB           prek? <prek::cli::Command as clap_builder::derive::Subcommand>::augment_subcommands
 0.3%   0.6% 59.7KiB            prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.2%   0.6% 56.3KiB            prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.2%   0.5% 43.4KiB            prek prek::identify::by_extension::{{closure}}
 0.2%   0.5% 43.3KiB            prek prek::run::{{closure}}
 0.2%   0.4% 41.7KiB            prek prek::cli::run::run::run::{{closure}}
 0.2%   0.4% 40.9KiB            prek prek::languages::<impl prek::config::Language>::install::{{closure}}
 0.1%   0.3% 31.7KiB           prek? <prek::cli::RunArgs as clap_builder::derive::Args>::augment_args
 0.1%   0.2% 22.2KiB            prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 21.0KiB    clap_builder clap_builder::parser::parser::Parser::get_matches_with
 0.1%   0.2% 20.8KiB            prek prek::archive::unzip::{{closure}}
 0.1%   0.2% 20.2KiB            prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 20.0KiB cargo_metadata? <cargo_metadata::_::<impl serde_core::de::Deserialize for cargo_metadata::Package>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map
 0.1%   0.2% 19.5KiB            prek <prek::languages::ruby::ruby::Ruby as prek::languages::LanguageImpl>::install::{{closure}}
 0.1%   0.2% 19.5KiB            prek prek::cli::run::filter::collect_files_from_args::{{closure}}
 0.1%   0.2% 19.1KiB            prek prek::cli::run::filter::collect_files_from_args::{{closure}}
 0.1%   0.2% 18.6KiB            ring ring_core_0_17_14__x25519_ge_frombytes_vartime
 0.1%   0.2% 18.4KiB            prek prek::hook::HookBuilder::build::{{closure}}
 0.1%   0.2% 18.4KiB            prek prek::hook::HookBuilder::build::{{closure}}
 0.1%   0.2% 18.4KiB            prek prek::hook::HookBuilder::build::{{closure}}
36.8%  91.6%  8.3MiB                 And 20041 smaller methods. Use -n N to show more.
40.2% 100.0%  9.1MiB                 .text section size, the file size is 22.5MiB

Base Branch Results

 File  .text    Size           Crate Name
 0.3%   0.8% 71.7KiB           prek? <prek::cli::Command as clap_builder::derive::Subcommand>::augment_subcommands
 0.3%   0.6% 59.5KiB            prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.2%   0.6% 56.1KiB            prek prek::languages::<impl prek::config::Language>::run::{{closure}}::{{closure}}
 0.2%   0.5% 43.4KiB            prek prek::identify::by_extension::{{closure}}
 0.2%   0.5% 43.3KiB            prek prek::run::{{closure}}
 0.2%   0.4% 41.5KiB            prek prek::cli::run::run::run::{{closure}}
 0.2%   0.4% 40.8KiB            prek prek::languages::<impl prek::config::Language>::install::{{closure}}
 0.1%   0.3% 31.8KiB           prek? <prek::cli::RunArgs as clap_builder::derive::Args>::augment_args
 0.1%   0.2% 21.6KiB            prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 21.0KiB    clap_builder clap_builder::parser::parser::Parser::get_matches_with
 0.1%   0.2% 20.8KiB            prek prek::archive::unzip::{{closure}}
 0.1%   0.2% 20.0KiB cargo_metadata? <cargo_metadata::_::<impl serde_core::de::Deserialize for cargo_metadata::Package>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map
 0.1%   0.2% 19.4KiB            prek prek::cli::run::filter::collect_files_from_args::{{closure}}
 0.1%   0.2% 19.4KiB            prek prek::hooks::meta_hooks::MetaHooks::run::{{closure}}
 0.1%   0.2% 19.4KiB            prek prek::cli::run::filter::collect_files_from_args::{{closure}}
 0.1%   0.2% 19.3KiB            prek <prek::languages::ruby::ruby::Ruby as prek::languages::LanguageImpl>::install::{{closure}}
 0.1%   0.2% 18.6KiB            ring ring_core_0_17_14__x25519_ge_frombytes_vartime
 0.1%   0.2% 18.5KiB            prek prek::hook::HookBuilder::build::{{closure}}
 0.1%   0.2% 18.5KiB            prek prek::hook::HookBuilder::build::{{closure}}
 0.1%   0.2% 18.5KiB            prek prek::hook::HookBuilder::build::{{closure}}
36.9%  91.6%  8.3MiB                 And 20033 smaller methods. Use -n N to show more.
40.2% 100.0%  9.1MiB                 .text section size, the file size is 22.5MiB

@j178
Copy link
Owner

j178 commented Jan 30, 2026

Thanks for working on this. We’re pretty careful about adding new options, and I don’t think prek_upgrade_suggestion on its own is enough reason to create another one. Plus, I don’t think this suggestion really works, since the config writer doesn’t actually know how prek is installed on the user’s side.

@hofbi
Copy link
Author

hofbi commented Jan 30, 2026

Makes sense that you don't want to bloat prek with new options here.

Maybe to clarify the motivation a bit. When using prek on a large project, you typically have a well defined and automated way to setup a developers's environment. With that, we exactly know how developers have installed prek, so being able to give them a concrete command to run would be very useful.

Now if we think about "the config writer doesn’t actually know how prek is installed on the user’s side", would it be possible to get to know this? Because if we would know this somehow, we would not need the prek_upgrade_suggestion at all, but prek could automatically suggest the right thing to do.

@j178
Copy link
Owner

j178 commented Jan 31, 2026

would it be possible to get to know this

We could try using a heuristic to detect it — for example, if the current executable is in something like /opt/homebrew, we could suggest running brew upgrade. But that kind of detection is pretty fragile and only works in a few situations, I’m hesitant to add it.

@j178 j178 marked this pull request as draft January 31, 2026 05:39
@hofbi
Copy link
Author

hofbi commented Feb 1, 2026

If you run uv self update and uv was not installed by their own install script, they give you a similar vague message, but cannot tell you exactly what to do.

The main motivation here is that if prek is managed by some repository automation, developers might not know how prek was installed. So if the minimum prek version gets increased they have to figure out first how to update prek.

One alternative to adding this to the config would be an environment variable, but not sure if this is an improvement to the current approach 🤔 .

@j178
Copy link
Owner

j178 commented Feb 2, 2026

I tried adding an optional upgrade hint after the version using a semicolon in #1536 , like this:

minimum_prek_version: '0.2.0; Use `brew upgrade` to upgrade prek'

What do you think?

@hofbi
Copy link
Author

hofbi commented Feb 2, 2026

I tried adding an optional upgrade hint after the version using a semicolon in #1536 , like this:

minimum_prek_version: '0.2.0; Use `brew upgrade` to upgrade prek'

What do you think?

@j178 I like it. This option also came to my mind, but I was not sure if I could propose it or if it seems too much of an abuse of the version. So let's do that then. Thanks you!

@j178 j178 closed this in #1536 Feb 2, 2026
pull bot pushed a commit to Stars1233/prek that referenced this pull request Feb 2, 2026
@shaanmajid
Copy link
Collaborator

shaanmajid commented Feb 2, 2026

I think we should revert #1536. By modifying the type and behavior of minimum_prek_version, that PR is effectively a breaking change.

The purpose of minimum_prek_version is to warn users on older versions, but ironically, the new syntax crashes on any prek version before #1536 (<= 0.3.1), even when the version requirement is met.

MRE:

minimum_prek_version: '0.2.0; Use brew upgrade to upgrade prek'
repos:
  - repo: local
    hooks:
      - id: test
        name: test
        entry: echo hi
        language: system
$ uvx [email protected] run -a
error: Failed to parse `.pre-commit-config.yaml`
  caused by: unexpected character ';' after patch version number

Note that prek 0.3.0 is greater than minimum_prek_version: '0.2.0', yet it still errors. The feature defeats itself - old versions can't parse the new syntax, so they never reach the code that would display the upgrade hint.

In summary:

  1. Doesn't help users who need to upgrade (they crash before seeing the hint)
  2. Actively breaks users who don't need to upgrade (they meet the requirement but can't parse the syntax)

More broadly, I agree with @j178's earlier point:

I don't think this suggestion really works, since the config writer doesn't actually know how prek is installed on the user's side.


@hofbi I do agree this is a meaningful issue; I think we all can make the experience a bit better:

Individual projects:

  • Use project/environment managers (e.g. mise, uv, etc.) to enforce a consistent development environment and prek version for contributors
  • Document setup instructions in CONTRIBUTING.md
  • Enforce a stable prek version in CI (for example, using prek-action)

Hook maintainers:

  • Set minimum_prek_version in hook manifests when relying on specific prek features or behavior changes (though this is rare since most hooks target upstream pre-commit)

prek itself:

  • As mentioned earlier, detect the install method and suggest the correct upgrade command (but also, as mentioned earlier, this can be difficult...)

uv, for example, detects Homebrew installations by inspecting the executable path for /Cellar/uv/, and suggests the appropriate upgrade command. Notably, they only do this for Homebrew for now, but it is something we can implement:

$ uv self update
error: uv was installed through an external package manager and cannot update itself.

hint: You installed uv using Homebrew. To update uv, run `brew update && brew upgrade uv`

prek could take a similar approach. When prek self update fails (as it does today for managed installs):

$ prek self update
error: prek was installed through an external package manager, and self-update is not available.
       Please use your package manager to update prek.

We could enhance this to detect Homebrew and suggest brew upgrade prek. Similarly, when prek run fails due to minimum_prek_version:

$ prek run -a
error: Required minimum prek version `0.4.0` is greater than current version `0.3.1`.
       Please consider updating prek.

We could further suggest the appropriate upgrade command based on detected install method.

We could start conservatively with path heuristics (e.g., /Cellar/prek/ for Homebrew, /.cargo/bin/ for cargo) and expand over time with build-time feature flags for official packages or marker files / flags we can write during environment-specific installation steps. But even minimal detection would be more helpful than asking config authors to guess.

@shaanmajid
Copy link
Collaborator

I will try to get started on a PR for Homebrew and cargo detection...

j178 added a commit that referenced this pull request Feb 3, 2026
Detects how prek was installed (Homebrew or Cargo) by inspecting the
executable path, then provides actionable upgrade hints when:

- `prek self update` fails because prek wasn't installed via standalone
scripts
- `minimum_prek_version` isn't satisfied

Based largely on the approach uv implemented in
[astral-sh/uv#16838](astral-sh/uv#16838).

Detection heuristics:
- Homebrew: path contains `/Cellar/prek/`
- Cargo: path contains `/.cargo/bin/`

Example output:
```console
error: prek was installed via an external package manager and cannot self-update.
hint: You installed prek via Homebrew. To update, run brew update && brew upgrade prek
```

See discussion in #1490 for further context.

---------

Co-authored-by: Jo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants