Introduce a typed shell option so hooks can opt into multiline shell-source execution without changing the default direct argv behavior. Shell adapters write entry content to temporary scripts and pass hook args and filenames through shell-specific argument conventions like "".
TOML 1.1 is not yet universally available. This hit me on Visual Studio
Code using [Even Better
TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml).
While this issue does not affect `prek` directly, users may encounter
errors on their IDE/editor and wonder what is going on.
Current Ruby support can only use Ruby interpreters which are already
installed on the system, although it goes to great lengths to find
interpreters installed by a variety of Ruby managers. This change adds
support for installing new interpreters using the binaries delivered by
the `rv` team. `rv` only provide installers for versions of Ruby still
actively supported (so they don't offer version 3.1, for example), and
only build for a subset of all Ruby-supported platforms. If users need
an unsupported version of Ruby or wish to use an unsupported platform,
they will be prompted to download and install a version of Ruby
manually.
`rv` bundles are named according to the platform, currently including
these components in the filename:
- x86_64_linux
- arm64_linux
- x86_64_linux_musl
- arm64_linux_musl
- ventura (used for macOS on x86_64)
- arm64_sonoma (used for macOS on 64-bit ARM)
If and when upstream `rv` changes these names, the detection code will
need to be updated to match. In particular, this includes the use of
macOS codenames, as if `rv` stop releasing a 'sonoma' package, this will
block installing the macOS versions of Ruby. Currently `rv` seem to be
attempting to keep these codenames, as they already rename their x86_64
builds from 'sequoia' (macOS 15) to 'ventura' (macOS 13). Adding a new
CPU architecture (such as RISC-V) would also need changes, but wouldn't
break existing platform support.
Ruby versions are found by querying the GitHub Releases API, searching
the options returned for an installer that matches the platform and
version requirements, then, if found, downloading and unpacking into the
`prek` tools folder. The `PREK_RUBY_MIRROR` environment variable can be
used to point to a different source for installers, for example to
support mirrors or air-gapped CI environments. Mirrors need to follow
the GitHub URL patterns, but note that although the GitHub hostname
changes between `api.github.com` and `github.com` as needed, any
non-GitHub mirror server will not be remapped in this manner. Where Ruby
is being downloaded from GitHub (either from the upstream `rv` or a
mirror), this remapping does occur, and any `GITHUB_TOKEN` will be sent
with the requests. This both limits impact of rate limiting, and also
allows a private GitHub repository to be used (e.g. for a vetted subset
of `rv` rubies to be mirrored). Note that GitHub tokens will only be
sent to mirrors which are hosted on GitHub.
To allow for passing the `GITHUB_TOKEN` in download requests, the
generic `download_and_extract` function is now a wrapper over a version
which takes an extension function, with the default function not
extending the request. The Ruby code will add the GitHub token if the
request is to GitHub.
Closes#43Closes#765
---------
Co-authored-by: Jo <10510431+j178@users.noreply.github.com>
Setting `pass_filenames: n` limits each hook invocation to at most `n`
filenames, with multiple parallel invocations for larger file sets. This
mirrors the `-n` flag of `xargs` and is useful for tools that can only
process a limited number of files per invocation (typically, if a limit
applies, it is 1).
The existing boolean behaviour is preserved: `true` passes all filenames
(default) and `false` passes none. So this is a backwards compatible
change.
Resolves: #1471
---------
Signed-off-by: JP-Ellis <josh@jpellis.me>
## Summary
- Add `PREK_MAX_CONCURRENCY` environment variable to cap the maximum
number of concurrent hooks
- Value is floored at 1; values above CPU count are allowed (useful for
I/O-bound hooks)
- Invalid values show a user-visible warning and fall back to CPU count
- `PREK_NO_CONCURRENCY` takes precedence when both are set
## Motivation
When `ulimit -n` is low, concurrent hook execution can exhaust file
descriptors. This provides an environment variable to limit concurrency.
For #1696
## Test plan
- [x] `mise run lint` — no warnings
- [x] `mise run test` — all tests pass
- [x] Unit tests for `resolve_concurrency`: valid value, above CPU
count, zero floors to 1, invalid string, empty string, unset,
no_concurrency, no_concurrency overrides max
Co-authored-by: Claude <noreply@anthropic.com>
Trace-level `Executing ...` lines currently truncate command arguments
at a hardcoded 120 characters, which hides critical details when
debugging hooks (notably `docker_image` entrypoint/args). This change
introduces a configurable truncate limit while preserving existing
default behavior.
- **Config surface: new env var**
- Added `PREK_LOG_TRUNCATE_LIMIT` to `prek-consts` (`EnvVars`).
- **Runtime behavior in command logging**
- Updated `Cmd` display formatting in `crates/prek/src/process.rs` to
read truncation limit from `PREK_LOG_TRUNCATE_LIMIT`.
- Cached the resolved truncate limit with `LazyLock` so env parsing
happens once.
- Kept default at `120` when unset/invalid.
- Treated `0` as invalid and fallback to default to avoid degenerate
output.
- **Documentation**
- Added `PREK_LOG_TRUNCATE_LIMIT` to `docs/configuration.md` under
environment variables, including default and intent.
- **Focused unit coverage**
- Added tests for:
- env var value parsing (valid/invalid/zero),
- env-based resolution behavior,
- cached-limit behavior via `LazyLock`,
- env restoration guard to avoid cross-test env leakage.
```rust
const DEFAULT_COMMAND_LOG_TRUNCATE_LIMIT: usize = 120;
static COMMAND_LOG_TRUNCATE_LIMIT: LazyLock<usize> =
LazyLock::new(command_log_truncate_limit_from_env);
fn command_log_truncate_limit() -> usize {
*COMMAND_LOG_TRUNCATE_LIMIT
}
```
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>Do not truncate trace run executions</issue_title>
> <issue_description>### Summary
>
> I was trying to debug a docker_image hook execution and was delighted
to note the --log-file option.
>
> However, turns out that the "Executing" TRACE run lines are truncated
with `[...]` before showing the part I'm actually interested in (a case
of tweaking entrypoints and arguments).
>
> I'd suggest not truncating these lines in the trace log at all, or
providing an option not to truncate.
>
> ### Willing to submit a PR?
>
> - [ ] Yes — I’m willing to open a PR to fix this.
>
> ### Platform
>
> Ubuntu 25.10 amd64
>
> ### Version
>
> 0.3.2
>
> ### .pre-commit-config.yaml
>
> N/A
>
> ### Log file
>
> ```
> 2026-02-20T10:17:47.223740Z TRACE run{hook_id=...
language=docker_image}: Executing `cd ... && docker run --rm --tty
--user 1000:1000 --init --volume ...:/src:rw,Z --workdir /src
--entrypoint ... --network [...]`
> ```</issue_description>
>
> <agent_instructions>Add a new env var to prek-consts, controlling the
command line log truncate limit in process.rs, current it is hardcoded
to 120. Document it in docs/configuration.md env vars
section.</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesj178/prek#1678
<!-- START COPILOT CODING AGENT TIPS -->
---
🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: j178 <10510431+j178@users.noreply.github.com>
Previously, in a setup that looks like
```
.
├── .pre-commit-config.yaml # setting A (root)
└── mynestedrepo
├── .pre-commit-config.yaml # setting B (nested repo)
└── tobeexcluded
└── nodonttrackthis.md
```
`mynestedrepo` is a nested folder using the **workspace** feature with a
nested `.pre-commit-config.yaml`. Ideally (especially in a monorepo
setup), it shouldn't need to care about any folder level above it.
Previously, if `mynestedrepo/.pre-commit-config.yaml` B contains
```yaml
exclude: (^tobeexcluded/)
repos:
...
```
one would expect `mynestedrepo/tobeexcluded` to be excluded. However,
the path passed from the filename filter previously uses the full path,
so it will still modify the `nodonttrackthis.md` file even though it
should be excluded.
Currently, the inner settings exclude pattern needs to specify either
`(^mynestedrepo/tobeexcluded/)` (which is not ideal if we want the inner
repo to be agnoistic to any folder above it) or `(tobeexcluded/)` (which
risk excluding some wanted folder if the exclude pattern is generic).
This PR makes it so that only the inner relative path is passed to the
filename filter.
----
i.e., instead of passing
`mynestedrepo/tobeexcluded/nodonttrackthis.md`
we pass
`tobeexcluded/nodonttrackthis.md`
to the inner project instead
---------
Signed-off-by: Tin Lai <tin@tinyiu.com>
Co-authored-by: Jo <10510431+j178@users.noreply.github.com>
* feat(bun): add Bun language support
* test(bun): add integration tests for Bun language support
Add three integration tests covering the key functionality:
- basic_bun: simple hook execution using bun -e
- additional_dependencies: verify deps installed via bunx cowsay
- language_version: test version specification with language_version: "1"
The additional_dependencies test runs twice to verify health_check and
cache reuse works correctly.
* docs: add Bun to supported languages documentation
- Add Bun to toolchain list in README features section
- Add Bun to managed toolchain downloads list in languages.md
- Add full Bun language section with version format documentation
* ci: add Bun setup to test jobs
* feat(bun): use GITHUB_TOKEN to avoid API rate limits
When listing Bun versions from GitHub releases, use the GITHUB_TOKEN
environment variable if available to authenticate requests. This
increases the rate limit from 60 to 5,000 requests/hour.
GITHUB_TOKEN is automatically set in GitHub Actions workflows.
* fix(bun): use consistent bin_dir path on all platforms
Bun installs global packages to $BUN_INSTALL/bin/ on all platforms,
so bin_dir should always return prefix/bin. The Windows special case
was incorrectly copied from Node (which uses npm's different install
structure).
* Add toolchain download test
* Add tests
---------
Co-authored-by: Jo <10510431+j178@users.noreply.github.com>
* Add `env` to set environment variables for hooks (#1279)
This key is not supported by `pre-commit`.
* DO NOT MERGE: use my fork of prek-test-repos/script-hooks
* Update test
---------
Co-authored-by: Jo <10510431+j178@users.noreply.github.com>
* feat: container runtime selection
use both docker and podman runtimes
1. if only docker on path use docker runtime
2. if only podman on path use podman runtime
3. to specify runtime use PREK_CONTAINER_RUNTIME
Signed-off-by: Steven Taylor <steven@taylormuff.co.uk>
* Tweak detection
---------
Signed-off-by: Steven Taylor <steven@taylormuff.co.uk>
Co-authored-by: Jo <10510431+j178@users.noreply.github.com>