From 0c04bbab207d5a41498384b1f4b046ff2c98ef3d Mon Sep 17 00:00:00 2001 From: TensorTemplar Date: Thu, 5 Mar 2026 08:35:58 +0200 Subject: [PATCH] fix stop hook triggering from certain files not cached properly, without file edits in between --- .coverage | Bin 69632 -> 0 bytes .gitignore | 3 + coverage.xml | 8994 --------------------- pyproject.toml | 2 +- src/slopometry/core/hook_handler.py | 60 +- src/slopometry/core/working_tree_state.py | 13 + tests/test_feedback_cache.py | 66 + 7 files changed, 87 insertions(+), 9051 deletions(-) delete mode 100644 .coverage delete mode 100644 coverage.xml diff --git a/.coverage b/.coverage deleted file mode 100644 index 84f5cdf249be6d78ce6e312e2679c05e587d0e9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69632 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 - - - - - /mnt/terradump/code/slopometry - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pyproject.toml b/pyproject.toml index 8f247b0..187ea0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "slopometry" -version = "2026.2.24.1" +version = "2026.3.4" description = "Opinionated code quality metrics for code agents and humans" readme = "README.md" requires-python = ">=3.13" diff --git a/src/slopometry/core/hook_handler.py b/src/slopometry/core/hook_handler.py index 5d213f5..fe3f6e3 100644 --- a/src/slopometry/core/hook_handler.py +++ b/src/slopometry/core/hook_handler.py @@ -255,59 +255,6 @@ def _handle_hook_internal( return 0 -def get_modified_python_files(working_directory: str | None) -> set[str]: - """Get modified Python files from git working tree. - - Uses `git diff --name-only` to get uncommitted changes (both staged and unstaged). - This is more reliable than transcript-based context coverage for detecting - which files the user has actually modified. - - Args: - working_directory: Path to git repository - - Returns: - Set of relative paths to modified Python files - - Raises: - ValueError: If working_directory is None or doesn't exist - RuntimeError: If git commands fail - """ - if not working_directory: - raise ValueError("working_directory is required for git diff") - - import subprocess - - working_dir = Path(working_directory) - if not working_dir.exists(): - raise ValueError(f"working_directory does not exist: {working_directory}") - - modified_files: set[str] = set() - - result = subprocess.run( - ["git", "diff", "--name-only", "--", "*.py"], - cwd=working_dir, - capture_output=True, - text=True, - timeout=10, - ) - if result.returncode != 0: - raise RuntimeError(f"git diff failed: {result.stderr}") - modified_files.update(line.strip() for line in result.stdout.strip().split("\n") if line.strip()) - - result = subprocess.run( - ["git", "diff", "--cached", "--name-only", "--", "*.py"], - cwd=working_dir, - capture_output=True, - text=True, - timeout=10, - ) - if result.returncode != 0: - raise RuntimeError(f"git diff --cached failed: {result.stderr}") - modified_files.update(line.strip() for line in result.stdout.strip().split("\n") if line.strip()) - - return modified_files - - def _get_feedback_cache_path(working_directory: str) -> Path: """Get path to the feedback cache file for a working directory.""" cache_dir = Path(working_directory) / ".slopometry" @@ -414,9 +361,10 @@ def handle_stop_event(session_id: str, parsed_input: "StopInput | SubagentStopIn # Get edited files from git (more reliable than transcript-based context coverage) try: - edited_files = get_modified_python_files(stats.working_directory) - except (ValueError, RuntimeError) as e: - logger.debug(f"Failed to get modified Python files: {e}") + wt_calculator = WorkingTreeStateCalculator(stats.working_directory, languages=None) + edited_files = wt_calculator.get_modified_source_file_paths() + except (ValueError, OSError) as e: + logger.debug(f"Failed to get modified source files: {e}") edited_files = set() # Smell feedback is stable (based on code state, not session activity) diff --git a/src/slopometry/core/working_tree_state.py b/src/slopometry/core/working_tree_state.py index ff4a953..2afb2f0 100644 --- a/src/slopometry/core/working_tree_state.py +++ b/src/slopometry/core/working_tree_state.py @@ -121,6 +121,19 @@ def _get_modified_source_files_from_git(self) -> list[Path]: return list(files) + def get_modified_source_file_paths(self) -> set[str]: + """Get relative paths of modified source files, filtered by ignore patterns. + + Combines git diff detection with should_ignore_path filtering to return + only legitimate source file changes. This is the public API for callers + that need relative-path strings (e.g., for smell scoping and cache keys). + + Returns: + Set of relative path strings for modified source files + """ + absolute_paths = self._get_modified_source_files_from_git() + return {str(p.relative_to(self.working_directory)) for p in absolute_paths} + def _get_modified_python_files_from_git(self) -> list[Path]: """Get Python files with uncommitted changes. diff --git a/tests/test_feedback_cache.py b/tests/test_feedback_cache.py index 4a6caa0..8e122fb 100644 --- a/tests/test_feedback_cache.py +++ b/tests/test_feedback_cache.py @@ -473,6 +473,72 @@ def test_feedback_cache__egg_info_directory_ignored(self): assert key_before == key_after, "*.egg-info directory should be ignored" +class TestGetModifiedSourceFilePathsFiltering: + """Tests for get_modified_source_file_paths() ignore filtering.""" + + def test_get_modified_source_file_paths__excludes_venv_files(self): + """Verify .venv Python files are excluded from modified source files.""" + with tempfile.TemporaryDirectory() as tmpdir: + tmppath = Path(tmpdir) + _init_git_repo(tmppath) + + # Create source file and venv file, commit both as tracked + (tmppath / "src").mkdir() + (tmppath / "src" / "app.py").write_text("def app(): pass") + (tmppath / ".venv").mkdir() + (tmppath / ".venv" / "lib.py").write_text("def lib(): pass") + _commit_all(tmppath) + + # Modify both files + (tmppath / "src" / "app.py").write_text("def app(): return 1") + (tmppath / ".venv" / "lib.py").write_text("def lib(): return 1") + + calculator = WorkingTreeStateCalculator(str(tmppath)) + modified = calculator.get_modified_source_file_paths() + + assert "src/app.py" in modified + assert ".venv/lib.py" not in modified + + def test_get_modified_source_file_paths__excludes_site_packages_files(self): + """Verify site-packages Python files are excluded from modified source files.""" + with tempfile.TemporaryDirectory() as tmpdir: + tmppath = Path(tmpdir) + _init_git_repo(tmppath) + + (tmppath / "app.py").write_text("def app(): pass") + (tmppath / "site-packages").mkdir() + (tmppath / "site-packages" / "pkg.py").write_text("def pkg(): pass") + _commit_all(tmppath) + + # Modify both + (tmppath / "app.py").write_text("def app(): return 1") + (tmppath / "site-packages" / "pkg.py").write_text("def pkg(): return 1") + + calculator = WorkingTreeStateCalculator(str(tmppath)) + modified = calculator.get_modified_source_file_paths() + + assert "app.py" in modified + assert "site-packages/pkg.py" not in modified + + def test_get_modified_source_file_paths__returns_relative_string_paths(self): + """Verify return type is set[str] with relative paths.""" + with tempfile.TemporaryDirectory() as tmpdir: + tmppath = Path(tmpdir) + _init_git_repo(tmppath) + (tmppath / "test.py").write_text("def foo(): pass") + _commit_all(tmppath) + + (tmppath / "test.py").write_text("def foo(): return 1") + + calculator = WorkingTreeStateCalculator(str(tmppath)) + modified = calculator.get_modified_source_file_paths() + + assert isinstance(modified, set) + for path in modified: + assert isinstance(path, str) + assert not Path(path).is_absolute() + + def test_feedback_cache__slopometry_dir_visibility_does_not_affect_key(): """Verify cache key is stable whether .slopometry/ is in gitignore or not.