Fix and test handling of backslashes in hooks (#3909)

* Update hooks to use `read -r` and `printf`

This portably avoids any interpretation of backslash escapes by the
shell.

* Support running make_tc_task elsewhere

* Add a test for backslashes in task descriptions
This commit is contained in:
Dustin J. Mitchell 2025-07-08 02:40:34 -04:00 committed by GitHub
parent 7fdcdebd19
commit c639cc030d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 115 additions and 75 deletions

View file

@ -176,6 +176,34 @@ class TestHooksOnModify(TestCase):
hook.assertTriggeredCount(1)
hook.assertExitcode(0)
def test_onmodify_escaped_backslash(self):
"""on-modify-accept - a well-behaved, successful, on-modify hook."""
# Create a task with a slash-escaped tab in it, avoiding TaskWarrior to ensure
# the slash exists in the DB.
uuid = self.t.make_tc_task(description=r"tab\ttab", status="pending")
hookname = "on-modify-accept"
self.t.hooks.add_default(hookname, log=True)
# `task _get` shows the backslash-escape.
code, out, err = self.t(f"_get 1.description")
self.assertEqual(out.strip(), r"tab\ttab")
code, out, err = self.t(f"{uuid} append foo")
hook = self.t.hooks[hookname]
hook.assertTriggeredCount(1)
hook.assertExitcode(0)
logs = hook.get_logs()
for msg in logs["output"]["msgs"]:
print(msg)
self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK")
# `task _get` still shows the backslash-escape.
code, out, err = self.t(f"_get 1.description")
self.assertEqual(out.strip(), r"tab\ttab foo")
if __name__ == "__main__":
from simpletap import TAPTestRunner