Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package prek for openSUSE:Factory checked in 
at 2025-11-27 15:21:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/prek (Old)
 and      /work/SRC/openSUSE:Factory/.prek.new.14147 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "prek"

Thu Nov 27 15:21:08 2025 rev:4 rq:1320281 version:0.2.19

Changes:
--------
--- /work/SRC/openSUSE:Factory/prek/prek.changes        2025-11-24 
14:10:19.156119951 +0100
+++ /work/SRC/openSUSE:Factory/.prek.new.14147/prek.changes     2025-11-27 
15:22:33.907520108 +0100
@@ -1,0 +2,13 @@
+Thu Nov 27 06:03:24 UTC 2025 - Johannes Kastl 
<[email protected]>
+
+- Update to version 0.2.19:
+  * Performance
+    - Simplify fix_byte_order_marker hook (#1136)
+    - Simplify trailing-whitespace hook to improve performance
+      (#1135)
+  * Bug fixes
+    - Close stdin for hook subcommands (#1155)
+    - Fix parsing Python interpreter info containing non-UTF8 chars
+      (#1141)
+
+-------------------------------------------------------------------

Old:
----
  prek-0.2.18.obscpio

New:
----
  prek-0.2.19.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ prek.spec ++++++
--- /var/tmp/diff_new_pack.M2M58N/_old  2025-11-27 15:22:37.587675307 +0100
+++ /var/tmp/diff_new_pack.M2M58N/_new  2025-11-27 15:22:37.639677500 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           prek
-Version:        0.2.18
+Version:        0.2.19
 Release:        0
 Summary:        Reimagined version of pre-commit, built in Rust
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.M2M58N/_old  2025-11-27 15:22:38.035694201 +0100
+++ /var/tmp/diff_new_pack.M2M58N/_new  2025-11-27 15:22:38.087696395 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/j178/prek.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v0.2.18</param>
+    <param name="revision">v0.2.19</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.M2M58N/_old  2025-11-27 15:22:38.291704998 +0100
+++ /var/tmp/diff_new_pack.M2M58N/_new  2025-11-27 15:22:38.327706516 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/j178/prek.git</param>
-              <param 
name="changesrevision">5c9fce63be2dd3740137b7973721377baa80588d</param></service></servicedata>
+              <param 
name="changesrevision">bdc40e36aa85f868ed9a8ddbbde1e3d6372cfa75</param></service></servicedata>
 (No newline at EOF)
 

++++++ prek-0.2.18.obscpio -> prek-0.2.19.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/CHANGELOG.md new/prek-0.2.19/CHANGELOG.md
--- old/prek-0.2.18/CHANGELOG.md        2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/CHANGELOG.md        2025-11-26 10:14:35.000000000 +0100
@@ -1,5 +1,25 @@
 # Changelog
 
+## 0.2.19
+
+Released on 2025-11-26.
+
+### Performance
+
+- Simplify `fix_byte_order_marker` hook 
([#1136](https://github.com/j178/prek/pull/1136))
+- Simplify `trailing-whitespace` hook to improve performance 
([#1135](https://github.com/j178/prek/pull/1135))
+
+### Bug fixes
+
+- Close stdin for hook subcommands 
([#1155](https://github.com/j178/prek/pull/1155))
+- Fix parsing Python interpreter info containing non-UTF8 chars 
([#1141](https://github.com/j178/prek/pull/1141))
+
+### Contributors
+
+- @chilin0525
+- @nblock
+- @j178
+
 ## 0.2.18
 
 Released on 2025-11-21.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/Cargo.lock new/prek-0.2.19/Cargo.lock
--- old/prek-0.2.18/Cargo.lock  2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/Cargo.lock  2025-11-26 10:14:35.000000000 +0100
@@ -183,9 +183,9 @@
 
 [[package]]
 name = "async-compression"
-version = "0.4.33"
+version = "0.4.34"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "93c1f86859c1af3d514fa19e8323147ff10ea98684e6c7b307912509f50e67b2"
+checksum = "0e86f6d3dc9dc4352edeea6b8e499e13e3f5dc3b964d7ca5fd411415a3498473"
 dependencies = [
  "compression-codecs",
  "compression-core",
@@ -453,9 +453,9 @@
 
 [[package]]
 name = "compression-codecs"
-version = "0.4.32"
+version = "0.4.33"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "680dc087785c5230f8e8843e2e57ac7c1c90488b6a91b88caa265410568f441b"
+checksum = "302266479cb963552d11bd042013a58ef1adc56768016c8b82b4199488f2d4ad"
 dependencies = [
  "compression-core",
  "flate2",
@@ -465,9 +465,9 @@
 
 [[package]]
 name = "compression-core"
-version = "0.4.30"
+version = "0.4.31"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "3a9b614a5787ef0c8802a55766480563cb3a93b435898c422ed2a359cf811582"
+checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d"
 
 [[package]]
 name = "console"
@@ -997,12 +997,11 @@
 
 [[package]]
 name = "http"
-version = "1.3.1"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
+checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
 dependencies = [
  "bytes",
- "fnv",
  "itoa",
 ]
 
@@ -1825,7 +1824,7 @@
 
 [[package]]
 name = "prek"
-version = "0.2.18"
+version = "0.2.19"
 dependencies = [
  "anstream",
  "anstyle-query",
@@ -1895,14 +1894,14 @@
 
 [[package]]
 name = "prek-consts"
-version = "0.2.18"
+version = "0.2.19"
 dependencies = [
  "tracing",
 ]
 
 [[package]]
 name = "prek-pty"
-version = "0.2.18"
+version = "0.2.19"
 dependencies = [
  "rustix",
  "tokio",
@@ -2444,9 +2443,9 @@
 
 [[package]]
 name = "signal-hook-registry"
-version = "1.4.6"
+version = "1.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
+checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad"
 dependencies = [
  "libc",
 ]
@@ -2562,9 +2561,9 @@
 
 [[package]]
 name = "syn"
-version = "2.0.110"
+version = "2.0.111"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
+checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2830,9 +2829,9 @@
 
 [[package]]
 name = "tower-http"
-version = "0.6.6"
+version = "0.6.7"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
+checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456"
 dependencies = [
  "bitflags 2.10.0",
  "bytes",
@@ -3557,18 +3556,18 @@
 
 [[package]]
 name = "zerocopy"
-version = "0.8.28"
+version = "0.8.30"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90"
+checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c"
 dependencies = [
  "zerocopy-derive",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.8.28"
+version = "0.8.30"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26"
+checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5"
 dependencies = [
  "proc-macro2",
  "quote",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/Cargo.toml new/prek-0.2.19/Cargo.toml
--- old/prek-0.2.18/Cargo.toml  2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/Cargo.toml  2025-11-26 10:14:35.000000000 +0100
@@ -2,15 +2,15 @@
 members = ["crates/*"]
 
 [workspace.package]
-version = "0.2.18"
+version = "0.2.19"
 edition = "2024"
 repository = "https://github.com/j178/prek";
 homepage = "https://prek.j178.dev/";
 license = "MIT"
 
 [workspace.dependencies]
-prek-consts = { path = "crates/prek-consts", version = "0.2.18" }
-prek-pty = { path = "crates/prek-pty", version = "0.2.18" }
+prek-consts = { path = "crates/prek-consts", version = "0.2.19" }
+prek-pty = { path = "crates/prek-pty", version = "0.2.19" }
 
 rustix = { version = "1.0.8", features = ["pty", "process", "fs", "termios"] }
 thiserror = { version = "2.0.11" }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/README.md new/prek-0.2.19/README.md
--- old/prek-0.2.18/README.md   2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/README.md   2025-11-26 10:14:35.000000000 +0100
@@ -58,7 +58,7 @@
 
 <!-- linux-standalone-install:start -->
 ```bash
-curl --proto '=https' --tlsv1.2 -LsSf 
https://github.com/j178/prek/releases/download/v0.2.18/prek-installer.sh | sh
+curl --proto '=https' --tlsv1.2 -LsSf 
https://github.com/j178/prek/releases/download/v0.2.19/prek-installer.sh | sh
 ```
 <!-- linux-standalone-install:end -->
 
@@ -66,7 +66,7 @@
 
 <!-- windows-standalone-install:start -->
 ```powershell
-powershell -ExecutionPolicy ByPass -c "irm 
https://github.com/j178/prek/releases/download/v0.2.18/prek-installer.ps1 | iex"
+powershell -ExecutionPolicy ByPass -c "irm 
https://github.com/j178/prek/releases/download/v0.2.19/prek-installer.ps1 | iex"
 ```
 <!-- windows-standalone-install:end -->
 
@@ -307,6 +307,7 @@
 - [iceberg-python](https://github.com/apache/iceberg-python/pull/2533)
 - [msgspec](https://github.com/jcrist/msgspec/pull/918)
 - [humanize](https://github.com/python-humanize/humanize/pull/276)
+- [nf-core](https://github.com/nf-core/tools/pull/3899)
 
 <!-- why:end -->
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/docs/builtin.md 
new/prek-0.2.19/docs/builtin.md
--- old/prek-0.2.18/docs/builtin.md     2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/docs/builtin.md     2025-11-26 10:14:35.000000000 +0100
@@ -12,7 +12,7 @@
 When you use a standard configuration pointing to a supported repository (like 
`https://github.com/pre-commit/pre-commit-hooks`), `prek` automatically detects 
this and runs its internal Rust implementation instead of the Python version 
defined in the repository.
 
 The fast path is activated when the `repo` URL matches 
`https://github.com/pre-commit/pre-commit-hooks`. No need to change anything in 
your configuration.
-Not that the `rev` field is ignored for detection purposes.
+Note that the `rev` field is ignored for detection purposes.
 
 This provides a speed boost while keeping your configuration compatible with 
the original `pre-commit` tool.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/docs/installation.md 
new/prek-0.2.19/docs/installation.md
--- old/prek-0.2.18/docs/installation.md        2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/docs/installation.md        2025-11-26 10:14:35.000000000 
+0100
@@ -127,7 +127,7 @@
 ### Zsh
 
 ```bash
-COMPLETE=zsh prek completion > "${fpath[1]}/_prek"
+COMPLETE=zsh prek > "${fpath[1]}/_prek"
 ```
 
 ### Fish
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/docs/workspace.md 
new/prek-0.2.19/docs/workspace.md
--- old/prek-0.2.18/docs/workspace.md   2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/docs/workspace.md   2025-11-26 10:14:35.000000000 +0100
@@ -89,7 +89,7 @@
 2. `src/`
 3. `docs/`
 4. `frontend/`
-5. `my-monorepo/` (root, last)
+5. `./` (root, last)
 
 This ensures that more specific configurations (deeper projects) take 
precedence over general ones.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/mise.toml new/prek-0.2.19/mise.toml
--- old/prek-0.2.18/mise.toml   2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/mise.toml   2025-11-26 10:14:35.000000000 +0100
@@ -7,14 +7,6 @@
 # For snapshot testing
 cargo-insta = "latest"
 "cargo:cargo-nextest" = "latest"
-# For pre-commit hooks
-prek = "latest"
-
-# Toolchains used in the integration tests.
-python = ["3.12"]
-node = ["20"]
-go = ["1.24"]
-ruby = ["3.4"]
 
 [tasks.lint]
 description = "Run formatting and linting"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/pyproject.toml 
new/prek-0.2.19/pyproject.toml
--- old/prek-0.2.18/pyproject.toml      2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/pyproject.toml      2025-11-26 10:14:35.000000000 +0100
@@ -1,6 +1,6 @@
 [project]
 name = "prek"
-version = "0.2.18"
+version = "0.2.19"
 description = "Better `pre-commit`, re-engineered in Rust"
 authors = [{ name = "j178", email = "[email protected]" }]
 requires-python = ">=3.8"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/cli/run/filter.rs 
new/prek-0.2.19/src/cli/run/filter.rs
--- old/prek-0.2.18/src/cli/run/filter.rs       2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/src/cli/run/filter.rs       2025-11-26 10:14:35.000000000 
+0100
@@ -4,12 +4,11 @@
 use fancy_regex::Regex;
 use itertools::{Either, Itertools};
 use path_clean::PathClean;
-use rayon::iter::{IntoParallelRefIterator, ParallelBridge, ParallelIterator};
+use prek_consts::env_vars::EnvVars;
+use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
 use rustc_hash::FxHashSet;
 use tracing::{debug, error, instrument};
 
-use prek_consts::env_vars::EnvVars;
-
 use crate::config::Stage;
 use crate::git::GIT_ROOT;
 use crate::hook::Hook;
@@ -44,10 +43,6 @@
         }
         true
     }
-
-    pub(crate) fn for_hook(hook: &'a Hook) -> Self {
-        Self::new(hook.files.as_deref(), hook.exclude.as_deref())
-    }
 }
 
 /// Filter files by tags.
@@ -102,20 +97,15 @@
         );
 
         // TODO: support orphaned project, which does not share files with its 
parent project.
-        let mut filenames = filenames
-            .enumerate()
-            .par_bridge()
-            .map(|(i, p)| (i, p.as_path()))
-            .filter(|(_, filename)| filter.filter(filename))
+        let filenames = filenames
+            .map(PathBuf::as_path)
             // Collect files that are inside the hook project directory.
-            .filter(|(_, filename)| 
filename.starts_with(project.relative_path()))
+            .filter(|filename| filename.starts_with(project.relative_path()))
+            .filter(|filename| filter.filter(filename))
             .collect::<Vec<_>>();
 
-        // Keep filename order consistent
-        filenames.sort_by_key(|&(i, _)| i);
-
         Self {
-            filenames: filenames.into_iter().map(|(_, p)| p).collect(),
+            filenames,
             filename_prefix: project.relative_path(),
         }
     }
@@ -152,7 +142,8 @@
     #[instrument(level = "trace", skip_all, fields(hook = ?hook.id))]
     pub(crate) fn for_hook(&self, hook: &Hook) -> Vec<&Path> {
         // Filter by hook `files` and `exclude` patterns.
-        let filter = FilenameFilter::for_hook(hook);
+        let filter = FilenameFilter::new(hook.files.as_deref(), 
hook.exclude.as_deref());
+
         let filenames = self.filenames.par_iter().filter(|filename| {
             if let Ok(stripped) = filename.strip_prefix(self.filename_prefix) {
                 filter.filter(stripped)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/config.rs 
new/prek-0.2.19/src/config.rs
--- old/prek-0.2.18/src/config.rs       2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/config.rs       2025-11-26 10:14:35.000000000 +0100
@@ -674,67 +674,38 @@
 
     for (repo_idx, repo) in config.repos.iter().enumerate() {
         let repo_prefix = format!("repos[{repo_idx}]");
-        match repo {
-            Repo::Remote(remote) => {
-                push_unused_paths(
-                    &mut paths,
-                    &repo_prefix,
-                    remote._unused_keys.keys().map(String::as_str),
-                );
-                for (hook_idx, hook) in remote.hooks.iter().enumerate() {
-                    let hook_prefix = 
format!("{repo_prefix}.hooks[{hook_idx}]");
-                    push_unused_paths(
-                        &mut paths,
-                        &hook_prefix,
-                        hook.options._unused_keys.keys().map(String::as_str),
-                    );
-                }
-            }
-            Repo::Local(local) => {
-                push_unused_paths(
-                    &mut paths,
-                    &repo_prefix,
-                    local._unused_keys.keys().map(String::as_str),
-                );
-                for (hook_idx, hook) in local.hooks.iter().enumerate() {
-                    let hook_prefix = 
format!("{repo_prefix}.hooks[{hook_idx}]");
-                    push_unused_paths(
-                        &mut paths,
-                        &hook_prefix,
-                        hook.options._unused_keys.keys().map(String::as_str),
-                    );
-                }
-            }
-            Repo::Meta(meta) => {
-                push_unused_paths(
-                    &mut paths,
-                    &repo_prefix,
-                    meta._unused_keys.keys().map(String::as_str),
-                );
-                for (hook_idx, hook) in meta.hooks.iter().enumerate() {
-                    let hook_prefix = 
format!("{repo_prefix}.hooks[{hook_idx}]");
-                    push_unused_paths(
-                        &mut paths,
-                        &hook_prefix,
-                        hook.0.options._unused_keys.keys().map(String::as_str),
-                    );
-                }
-            }
-            Repo::Builtin(builtin) => {
-                push_unused_paths(
-                    &mut paths,
-                    &repo_prefix,
-                    builtin._unused_keys.keys().map(String::as_str),
-                );
-                for (hook_idx, hook) in builtin.hooks.iter().enumerate() {
-                    let hook_prefix = 
format!("{repo_prefix}.hooks[{hook_idx}]");
-                    push_unused_paths(
-                        &mut paths,
-                        &hook_prefix,
-                        hook.0.options._unused_keys.keys().map(String::as_str),
-                    );
-                }
-            }
+        let (repo_unused_keys, hooks_options): (_, Box<dyn Iterator<Item = 
&HookOptions>>) =
+            match repo {
+                Repo::Remote(remote) => (
+                    &remote._unused_keys,
+                    Box::new(remote.hooks.iter().map(|h| &h.options)),
+                ),
+                Repo::Local(local) => (
+                    &local._unused_keys,
+                    Box::new(local.hooks.iter().map(|h| &h.options)),
+                ),
+                Repo::Meta(meta) => (
+                    &meta._unused_keys,
+                    Box::new(meta.hooks.iter().map(|h| &h.0.options)),
+                ),
+                Repo::Builtin(builtin) => (
+                    &builtin._unused_keys,
+                    Box::new(builtin.hooks.iter().map(|h| &h.0.options)),
+                ),
+            };
+
+        push_unused_paths(
+            &mut paths,
+            &repo_prefix,
+            repo_unused_keys.keys().map(String::as_str),
+        );
+        for (hook_idx, options) in hooks_options.enumerate() {
+            let hook_prefix = format!("{repo_prefix}.hooks[{hook_idx}]");
+            push_unused_paths(
+                &mut paths,
+                &hook_prefix,
+                options._unused_keys.keys().map(String::as_str),
+            );
         }
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/git.rs new/prek-0.2.19/src/git.rs
--- old/prek-0.2.18/src/git.rs  2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/git.rs  2025-11-26 10:14:35.000000000 +0100
@@ -591,6 +591,10 @@
 /// Return a list of absolute paths of all git submodules in the repository.
 #[instrument(level = "trace")]
 pub(crate) fn list_submodules(git_root: &Path) -> Result<Vec<PathBuf>, Error> {
+    if !git_root.join(".gitmodules").exists() {
+        return Ok(vec![]);
+    }
+
     let git = GIT.as_ref().map_err(|&e| Error::GitNotFound(e))?;
     let output = std::process::Command::new(git)
         .current_dir(git_root)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prek-0.2.18/src/hooks/pre_commit_hooks/fix_byte_order_marker.rs 
new/prek-0.2.19/src/hooks/pre_commit_hooks/fix_byte_order_marker.rs
--- old/prek-0.2.18/src/hooks/pre_commit_hooks/fix_byte_order_marker.rs 
2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/hooks/pre_commit_hooks/fix_byte_order_marker.rs 
2025-11-26 10:14:35.000000000 +0100
@@ -1,9 +1,8 @@
-use std::io::Write;
 use std::path::Path;
 
 use anyhow::Result;
 use futures::StreamExt;
-use tokio::io::{AsyncReadExt, AsyncSeekExt};
+use tokio::io::AsyncReadExt;
 
 use crate::hook::Hook;
 use crate::run::CONCURRENCY;
@@ -34,54 +33,18 @@
 async fn fix_file(file_base: &Path, filename: &Path) -> Result<(i32, Vec<u8>)> 
{
     let file_path = file_base.join(filename);
 
-    // First, just peek at the first 3 bytes to check for BOM
     let mut file = fs_err::tokio::File::open(&file_path).await?;
     let mut bom_buffer = [0u8; 3];
 
-    // Read up to 3 bytes (file might be shorter)
     let bytes_read = file.read(&mut bom_buffer).await?;
 
-    // If file is too short or doesn't start with BOM, no changes needed
     if bytes_read < 3 || bom_buffer != UTF8_BOM {
         return Ok((0, Vec::new()));
     }
 
-    // File has BOM - now we need to remove it
-    let metadata = file.metadata().await?;
-    let file_size = metadata.len();
-
-    if file_size == 3 {
-        // File is only BOM, just truncate it
-        drop(file);
-        fs_err::tokio::write(&file_path, b"").await?;
-    } else if file_size <= 64 * 1024 {
-        // For small files (≤64KB), use the simple approach
-        drop(file);
-        let content = fs_err::tokio::read(&file_path).await?;
-        fs_err::tokio::write(&file_path, &content[3..]).await?;
-    } else {
-        // For large files, use streaming to avoid loading everything into 
memory
-        // Create a unique temporary filename in the scratch directory
-        let mut temp_file = tempfile::NamedTempFile::new()?;
-
-        // Reset to position 3 (after BOM)
-        file.seek(std::io::SeekFrom::Start(3)).await?;
-
-        let mut buffer = vec![0u8; BUFFER_SIZE];
-
-        loop {
-            let bytes_read = file.read(&mut buffer).await?;
-            if bytes_read == 0 {
-                break;
-            }
-            temp_file.write_all(&buffer[..bytes_read])?;
-        }
-
-        drop(file);
-        temp_file.flush()?;
-
-        crate::fs::rename_or_copy(&temp_file.into_temp_path(), 
&file_path).await?;
-    }
+    let mut content = Vec::new();
+    file.read_to_end(&mut content).await?;
+    fs_err::tokio::write(&file_path, &content).await?;
 
     Ok((
         1,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prek-0.2.18/src/hooks/pre_commit_hooks/fix_trailing_whitespace.rs 
new/prek-0.2.19/src/hooks/pre_commit_hooks/fix_trailing_whitespace.rs
--- old/prek-0.2.18/src/hooks/pre_commit_hooks/fix_trailing_whitespace.rs       
2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/hooks/pre_commit_hooks/fix_trailing_whitespace.rs       
2025-11-26 10:14:35.000000000 +0100
@@ -6,14 +6,11 @@
 use bstr::ByteSlice;
 use clap::Parser;
 use futures::StreamExt;
-use tempfile::NamedTempFile;
-use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter};
 
 use crate::hook::Hook;
 use crate::run::CONCURRENCY;
 
 const MARKDOWN_LINE_BREAK: &[u8] = b"  ";
-const BUFFER_SIZE_THRESHOLD: usize = 64 * 1024; // 64KB
 
 #[derive(Clone)]
 struct Chars(Vec<char>);
@@ -128,16 +125,12 @@
     };
 
     let file_path = file_base.join(filename);
-    let file = fs_err::tokio::File::open(&file_path).await?;
-    let file_len = file.metadata().await?.len();
+    let content = fs_err::tokio::read(&file_path).await?;
 
-    let mut buf_writer = create_buffer(usize::try_from(file_len)?)?;
-    let mut buf_reader = BufReader::new(file);
-
-    let mut line = Vec::new();
+    let mut output = Vec::with_capacity(content.len());
     let mut modified = false;
-    while buf_reader.read_until(b'\n', &mut line).await? != 0 {
-        let line_ending = detect_line_ending(&line);
+    for line in content.split_inclusive(|&b| b == b'\n') {
+        let line_ending = detect_line_ending(line);
         let mut trimmed = &line[..line.len() - line_ending.len()];
 
         let markdown_end = needs_markdown_break(is_markdown, trimmed);
@@ -151,115 +144,24 @@
             trimmed = trimmed.trim_end_with(|c| chars.contains(&c));
         }
 
-        buf_writer.write(trimmed).await?;
+        output.extend_from_slice(trimmed);
         if markdown_end {
-            buf_writer.write(MARKDOWN_LINE_BREAK).await?;
+            output.extend_from_slice(MARKDOWN_LINE_BREAK);
             modified |= trimmed.len() + MARKDOWN_LINE_BREAK.len() + 
line_ending.len() != line.len();
         } else {
             modified |= trimmed.len() + line_ending.len() != line.len();
         }
-        buf_writer.write(line_ending).await?;
-        line.clear();
+        output.extend_from_slice(line_ending);
     }
 
-    drop(buf_reader);
     if modified {
-        buf_writer.flush_to_file(&file_path).await?;
+        fs_err::tokio::write(&file_path, &output).await?;
         Ok((1, format!("Fixing {}\n", filename.display()).into_bytes()))
     } else {
-        drop(buf_writer);
         Ok((0, Vec::new()))
     }
 }
 
-trait AsyncWriteBuffer {
-    async fn write(&mut self, data: &[u8]) -> Result<()>;
-    async fn flush_to_file(&mut self, filename: &Path) -> Result<()>;
-}
-
-struct MemoryBuffer(Vec<u8>);
-
-impl MemoryBuffer {
-    pub fn new(mut file_len: usize) -> Self {
-        if file_len > BUFFER_SIZE_THRESHOLD {
-            file_len = BUFFER_SIZE_THRESHOLD;
-        }
-        Self(Vec::with_capacity(file_len))
-    }
-}
-
-impl AsyncWriteBuffer for MemoryBuffer {
-    async fn write(&mut self, data: &[u8]) -> Result<()> {
-        self.0.extend_from_slice(data);
-        Ok(())
-    }
-
-    async fn flush_to_file(&mut self, filename: &Path) -> Result<()> {
-        fs_err::tokio::write(filename, &self.0).await?;
-        Ok(())
-    }
-}
-
-struct TempFileBuffer {
-    buf_writer: BufWriter<tokio::fs::File>,
-    named_temp_file: NamedTempFile,
-}
-
-impl TempFileBuffer {
-    pub fn new() -> Result<Self> {
-        let named_temp_file = NamedTempFile::new()?;
-        let temp_file = tokio::fs::File::from_std(named_temp_file.reopen()?);
-        let buf_writer = BufWriter::new(temp_file);
-
-        Ok(Self {
-            buf_writer,
-            named_temp_file,
-        })
-    }
-}
-
-impl AsyncWriteBuffer for TempFileBuffer {
-    async fn write(&mut self, data: &[u8]) -> Result<()> {
-        self.buf_writer.write_all(data).await?;
-        Ok(())
-    }
-
-    async fn flush_to_file(&mut self, filename: &Path) -> Result<()> {
-        self.buf_writer.flush().await?;
-        crate::fs::rename_or_copy(self.named_temp_file.path(), 
Path::new(filename)).await?;
-        Ok(())
-    }
-}
-
-enum Buffer {
-    Memory(MemoryBuffer),
-    Temp(TempFileBuffer),
-}
-
-impl AsyncWriteBuffer for Buffer {
-    async fn write(&mut self, data: &[u8]) -> Result<()> {
-        match self {
-            Buffer::Memory(b) => b.write(data).await,
-            Buffer::Temp(b) => b.write(data).await,
-        }
-    }
-
-    async fn flush_to_file(&mut self, filename: &Path) -> Result<()> {
-        match self {
-            Buffer::Memory(b) => b.flush_to_file(filename).await,
-            Buffer::Temp(b) => b.flush_to_file(filename).await,
-        }
-    }
-}
-
-fn create_buffer(file_len: usize) -> Result<Buffer> {
-    if file_len <= BUFFER_SIZE_THRESHOLD {
-        Ok(Buffer::Memory(MemoryBuffer::new(file_len)))
-    } else {
-        Ok(Buffer::Temp(TempFileBuffer::new()?))
-    }
-}
-
 fn detect_line_ending(line: &[u8]) -> &[u8] {
     if line.ends_with(b"\r\n") {
         b"\r\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/docker.rs 
new/prek-0.2.19/src/languages/docker.rs
--- old/prek-0.2.18/src/languages/docker.rs     2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/src/languages/docker.rs     2025-11-26 10:14:35.000000000 
+0100
@@ -4,7 +4,7 @@
 use std::fs;
 use std::hash::{Hash, Hasher};
 use std::path::{Path, PathBuf};
-use std::process::Command;
+use std::process::{Command, Stdio};
 use std::str::FromStr;
 use std::sync::{Arc, LazyLock};
 
@@ -462,6 +462,7 @@
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/docker_image.rs 
new/prek-0.2.19/src/languages/docker_image.rs
--- old/prek-0.2.18/src/languages/docker_image.rs       2025-11-21 
13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/languages/docker_image.rs       2025-11-26 
10:14:35.000000000 +0100
@@ -1,4 +1,5 @@
 use std::path::Path;
+use std::process::Stdio;
 use std::sync::Arc;
 
 use anyhow::Result;
@@ -42,6 +43,7 @@
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/golang/golang.rs 
new/prek-0.2.19/src/languages/golang/golang.rs
--- old/prek-0.2.18/src/languages/golang/golang.rs      2025-11-21 
13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/languages/golang/golang.rs      2025-11-26 
10:14:35.000000000 +0100
@@ -1,5 +1,6 @@
 use std::ops::Deref;
 use std::path::{Path, PathBuf};
+use std::process::Stdio;
 use std::sync::Arc;
 
 use anyhow::Context;
@@ -143,13 +144,14 @@
             let mut output = Cmd::new(&entry[0], "go hook")
                 .current_dir(hook.work_dir())
                 .args(&entry[1..])
-                .env("PATH", &new_path)
+                .env(EnvVars::PATH, &new_path)
                 .env(EnvVars::GOTOOLCHAIN, "local")
                 .env(EnvVars::GOBIN, &go_bin)
                 .envs(go_envs.iter().copied())
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .pty_output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/lua.rs 
new/prek-0.2.19/src/languages/lua.rs
--- old/prek-0.2.18/src/languages/lua.rs        2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/src/languages/lua.rs        2025-11-26 10:14:35.000000000 
+0100
@@ -1,4 +1,5 @@
 use std::path::{Path, PathBuf};
+use std::process::Stdio;
 use std::sync::Arc;
 
 use anyhow::{Context, Result};
@@ -144,12 +145,13 @@
             let mut output = Cmd::new(&entry[0], "run lua command")
                 .current_dir(hook.work_dir())
                 .args(&entry[1..])
-                .env("PATH", &new_path)
+                .env(EnvVars::PATH, &new_path)
                 .env(EnvVars::LUA_PATH, &lua_path)
                 .env(EnvVars::LUA_CPATH, &lua_cpath)
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .pty_output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/mod.rs 
new/prek-0.2.19/src/languages/mod.rs
--- old/prek-0.2.18/src/languages/mod.rs        2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/src/languages/mod.rs        2025-11-26 10:14:35.000000000 
+0100
@@ -16,7 +16,6 @@
 use crate::hook::{Hook, InstallInfo, InstalledHook, Repo};
 use crate::identify::parse_shebang;
 use crate::store::Store;
-use crate::version::version;
 use crate::{archive, hooks, warn_user_once};
 
 mod docker;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/node/node.rs 
new/prek-0.2.19/src/languages/node/node.rs
--- old/prek-0.2.18/src/languages/node/node.rs  2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/src/languages/node/node.rs  2025-11-26 10:14:35.000000000 
+0100
@@ -1,6 +1,7 @@
 use std::borrow::Cow;
 use std::env::consts::EXE_EXTENSION;
 use std::path::{Path, PathBuf};
+use std::process::Stdio;
 use std::sync::Arc;
 
 use anyhow::{Context, Result};
@@ -112,7 +113,7 @@
                 .arg("--no-audit")
                 .arg("--install-links")
                 .args(&*deps)
-                .env("PATH", new_path)
+                .env(EnvVars::PATH, new_path)
                 .env(EnvVars::NPM_CONFIG_PREFIX, &info.env_path)
                 .env_remove(EnvVars::NPM_CONFIG_USERCONFIG)
                 .env(EnvVars::NODE_PATH, &lib_dir)
@@ -162,13 +163,14 @@
             let mut output = Cmd::new(&entry[0], "node hook")
                 .current_dir(hook.work_dir())
                 .args(&entry[1..])
-                .env("PATH", &new_path)
+                .env(EnvVars::PATH, &new_path)
                 .env(EnvVars::NPM_CONFIG_PREFIX, env_dir)
                 .env_remove(EnvVars::NPM_CONFIG_USERCONFIG)
                 .env(EnvVars::NODE_PATH, lib_dir(env_dir))
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .pty_output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/python/python.rs 
new/prek-0.2.19/src/languages/python/python.rs
--- old/prek-0.2.18/src/languages/python/python.rs      2025-11-21 
13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/languages/python/python.rs      2025-11-26 
10:14:35.000000000 +0100
@@ -1,11 +1,12 @@
 use std::env::consts::EXE_EXTENSION;
 use std::path::{Path, PathBuf};
+use std::process::Stdio;
 use std::sync::Arc;
 
 use anyhow::{Context, Result};
-use tracing::{debug, trace};
-
 use prek_consts::env_vars::EnvVars;
+use serde::Deserialize;
+use tracing::{debug, trace};
 
 use crate::cli::reporter::HookInstallReporter;
 use crate::hook::InstalledHook;
@@ -28,10 +29,19 @@
 }
 
 pub(crate) async fn query_python_info(python: &Path) -> Result<PythonInfo> {
+    #[derive(Deserialize)]
+    struct QueryPythonInfo {
+        version: semver::Version,
+        base_exec_prefix: PathBuf,
+    }
+
     static QUERY_PYTHON_INFO: &str = indoc::indoc! {r#"
-    import sys
-    
print(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
-    print(sys.base_exec_prefix)
+    import sys, json
+    info = {
+        "version": ".".join(map(str, sys.version_info[:3])),
+        "base_exec_prefix": sys.base_exec_prefix,
+    }
+    print(json.dumps(info))
     "#};
 
     let stdout = Cmd::new(python, "python -c")
@@ -43,22 +53,12 @@
         .await?
         .stdout;
 
-    let stdout = String::from_utf8(stdout).context("Failed to parse Python 
info output")?;
-    let mut lines = stdout.lines();
-    let version = lines
-        .next()
-        .context("Failed to get Python version")?
-        .to_string()
-        .parse()
-        .context("Failed to parse Python version")?;
-    let base_exec_prefix = lines
-        .next()
-        .context("Failed to get Python base_exec_prefix")?
-        .to_string();
-    let python_exec = python_exec(Path::new(&base_exec_prefix));
+    let info: QueryPythonInfo =
+        serde_json::from_slice(&stdout).context("Failed to parse Python info 
JSON")?;
+    let python_exec = python_exec(&info.base_exec_prefix);
 
     Ok(PythonInfo {
-        version,
+        version: info.version,
         python_exec,
     })
 }
@@ -192,6 +192,7 @@
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .pty_output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/python/version.rs 
new/prek-0.2.19/src/languages/python/version.rs
--- old/prek-0.2.18/src/languages/python/version.rs     2025-11-21 
13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/languages/python/version.rs     2025-11-26 
10:14:35.000000000 +0100
@@ -4,7 +4,6 @@
 use std::str::FromStr;
 
 use crate::hook::InstallInfo;
-use crate::languages::version;
 use crate::languages::version::{Error, try_into_u64_slice};
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -33,7 +32,7 @@
 /// - `/path/to/python3.12`
 // TODO: support version like `3.8b1`, `3.8rc2`, `python3.8t`, `python3.8-64`, 
`pypy3.8`.
 impl FromStr for PythonRequest {
-    type Err = version::Error;
+    type Err = Error;
 
     fn from_str(request: &str) -> Result<Self, Self::Err> {
         if request.is_empty() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/ruby/installer.rs 
new/prek-0.2.19/src/languages/ruby/installer.rs
--- old/prek-0.2.18/src/languages/ruby/installer.rs     2025-11-21 
13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/languages/ruby/installer.rs     2025-11-26 
10:14:35.000000000 +0100
@@ -361,11 +361,8 @@
         .output()
         .await?;
 
-    let output_str = String::from_utf8(output.stdout)?;
-    let mut lines = output_str.lines();
-
+    let mut lines = str::from_utf8(&output.stdout)?.lines();
     let engine = lines.next().unwrap_or("ruby").to_string();
-
     let version_str = lines.next().context("No version in Ruby 
output")?.trim();
 
     let version = semver::Version::parse(version_str)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/ruby/ruby.rs 
new/prek-0.2.19/src/languages/ruby/ruby.rs
--- old/prek-0.2.18/src/languages/ruby/ruby.rs  2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/src/languages/ruby/ruby.rs  2025-11-26 10:14:35.000000000 
+0100
@@ -1,4 +1,5 @@
 use std::path::{Path, PathBuf};
+use std::process::Stdio;
 use std::sync::Arc;
 
 use anyhow::{Context, Result};
@@ -109,8 +110,8 @@
             .output()
             .await?;
 
-        let version_str = String::from_utf8(output.stdout)?.trim().to_string();
-        let actual_version = semver::Version::parse(&version_str)
+        let version_str = str::from_utf8(&output.stdout)?.trim();
+        let actual_version = semver::Version::parse(version_str)
             .with_context(|| format!("Failed to parse Ruby version: 
{version_str}"))?;
 
         if actual_version != info.language_version {
@@ -171,6 +172,7 @@
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .pty_output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/script.rs 
new/prek-0.2.19/src/languages/script.rs
--- old/prek-0.2.18/src/languages/script.rs     2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/src/languages/script.rs     2025-11-26 10:14:35.000000000 
+0100
@@ -1,4 +1,5 @@
 use std::path::Path;
+use std::process::Stdio;
 use std::sync::Arc;
 
 use anyhow::Result;
@@ -52,6 +53,7 @@
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .pty_output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/languages/system.rs 
new/prek-0.2.19/src/languages/system.rs
--- old/prek-0.2.18/src/languages/system.rs     2025-11-21 13:41:20.000000000 
+0100
+++ new/prek-0.2.19/src/languages/system.rs     2025-11-26 10:14:35.000000000 
+0100
@@ -1,4 +1,5 @@
 use std::path::Path;
+use std::process::Stdio;
 use std::sync::Arc;
 
 use anyhow::Result;
@@ -42,6 +43,7 @@
                 .args(&hook.args)
                 .args(batch)
                 .check(false)
+                .stdin(Stdio::null())
                 .pty_output()
                 .await?;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/process.rs 
new/prek-0.2.19/src/process.rs
--- old/prek-0.2.18/src/process.rs      2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/process.rs      2025-11-26 10:14:35.000000000 +0100
@@ -195,9 +195,9 @@
         }
 
         let (mut pty, pts) = prek_pty::open()?;
-        let (stdin, stdout, stderr) = pts.setup_subprocess()?;
+        let (_, stdout, stderr) = pts.setup_subprocess()?;
 
-        self.inner.stdin(stdin);
+        self.inner.stdin(Stdio::null());
         self.inner.stdout(stdout);
         self.inner.stderr(stderr);
 
@@ -482,7 +482,7 @@
             }
             write!(f, " {}", arg.to_string_lossy())?;
             len += arg.len() + 1;
-            if len > 100 {
+            if len > 120 {
                 write!(f, " [...]",)?;
                 break;
             }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/run.rs new/prek-0.2.19/src/run.rs
--- old/prek-0.2.18/src/run.rs  2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/run.rs  2025-11-26 10:14:35.000000000 +0100
@@ -117,11 +117,11 @@
         let max_per_batch = max(4, filenames.len().div_ceil(concurrency));
         let mut max_cli_length = platform_max_cli_length();
 
-        let entry_lower = &entry[0].to_ascii_lowercase();
+        let cmd = Path::new(&entry[0]);
         if cfg!(windows)
-            && [".bat", ".cmd"]
-                .iter()
-                .any(|ext| entry_lower.ends_with(ext))
+            && cmd.extension().is_some_and(|ext| {
+                ext.eq_ignore_ascii_case("cmd") || 
ext.eq_ignore_ascii_case("bat")
+            })
         {
             // Reduce max length for batch files on Windows due to cmd.exe 
limitations.
             // 1024 is additionally subtracted to give headroom for further
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/src/workspace.rs 
new/prek-0.2.19/src/workspace.rs
--- old/prek-0.2.18/src/workspace.rs    2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/src/workspace.rs    2025-11-26 10:14:35.000000000 +0100
@@ -22,7 +22,6 @@
 use crate::git::GIT_ROOT;
 use crate::hook::{self, Hook, HookBuilder, Repo};
 use crate::store::{CacheBucket, Store};
-use crate::workspace::Error::MissingPreCommitConfig;
 use crate::{git, store, warn_user};
 
 #[derive(Error, Debug)]
@@ -554,7 +553,7 @@
             .ancestors()
             .take_while(|p| git_root.parent().map(|root| *p != 
root).unwrap_or(true))
             .find(|p| p.join(CONFIG_FILE).is_file() || 
p.join(ALT_CONFIG_FILE).is_file())
-            .ok_or(MissingPreCommitConfig)?
+            .ok_or(Error::MissingPreCommitConfig)?
             .to_path_buf();
 
         debug!("Found workspace root at `{}`", workspace_root.display());
@@ -634,7 +633,7 @@
             projects.retain(|p| selectors.matches_path(p.relative_path()));
         }
         if projects.is_empty() {
-            return Err(MissingPreCommitConfig);
+            return Err(Error::MissingPreCommitConfig);
         }
 
         let mut workspace = Self { root, projects };
@@ -651,7 +650,10 @@
         let projects = Mutex::new(Ok(Vec::new()));
 
         let git_root = GIT_ROOT.as_ref().map_err(|e| Error::Git(e.into()))?;
-        let submodules = git::list_submodules(git_root).unwrap_or_default();
+        let submodules = git::list_submodules(git_root).unwrap_or_else(|e| {
+            error!("Failed to list git submodules: {e}");
+            Vec::new()
+        });
 
         ignore::WalkBuilder::new(root)
             .follow_links(false)
@@ -721,7 +723,7 @@
 
         let projects = projects.into_inner().unwrap()?;
         if projects.is_empty() {
-            return Err(MissingPreCommitConfig);
+            return Err(Error::MissingPreCommitConfig);
         }
 
         Ok(projects)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prek-0.2.18/tests/run.rs new/prek-0.2.19/tests/run.rs
--- old/prek-0.2.18/tests/run.rs        2025-11-21 13:41:20.000000000 +0100
+++ new/prek-0.2.19/tests/run.rs        2025-11-26 10:14:35.000000000 +0100
@@ -2500,3 +2500,48 @@
       caused by: Failed to parse entry: entry is empty
     ");
 }
+
+/// Test that hooks are run with stdin closed.
+#[test]
+fn run_with_stdin_closed() {
+    let context = TestContext::new();
+    context.init_project();
+    context.write_pre_commit_config(indoc::indoc! {r#"
+        repos:
+          - repo: local
+            hooks:
+              - id: check-stdin
+                name: check-stdin
+                language: python
+                entry: python -c 'import sys; sys.stdin.read(); print("STDIN 
closed")'
+                pass_filenames: false
+                verbose: true
+    "#});
+    context.git_add(".");
+
+    cmd_snapshot!(context.filters(), context.run(), @r"
+    success: true
+    exit_code: 0
+    ----- stdout -----
+    
check-stdin..............................................................Passed
+    - hook id: check-stdin
+    - duration: [TIME]
+
+      STDIN closed
+
+    ----- stderr -----
+    ");
+
+    cmd_snapshot!(context.filters(), 
context.run().arg("--color").arg("always"), @r"
+    success: true
+    exit_code: 0
+    ----- stdout -----
+    
check-stdin..............................................................Passed
+    - hook id: check-stdin
+    - duration: [TIME]
+
+      STDIN closed
+
+    ----- stderr -----
+    ");
+}

++++++ prek.obsinfo ++++++
--- /var/tmp/diff_new_pack.M2M58N/_old  2025-11-27 15:22:39.719765222 +0100
+++ /var/tmp/diff_new_pack.M2M58N/_new  2025-11-27 15:22:39.787768089 +0100
@@ -1,5 +1,5 @@
 name: prek
-version: 0.2.18
-mtime: 1763728880
-commit: 5c9fce63be2dd3740137b7973721377baa80588d
+version: 0.2.19
+mtime: 1764148475
+commit: bdc40e36aa85f868ed9a8ddbbde1e3d6372cfa75
 

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/prek/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.prek.new.14147/vendor.tar.zst differ: char 7, line 1

Reply via email to