GRM-20: refactor: rework all scripts to use click and i18n
CI / lint (push) Has been cancelled
CI / unit-tests (push) Has been cancelled
CI / molecule-tests (push) Has been cancelled
Post-merge Vikunja update / vikunja (push) Has been cancelled

- Replace argparse/print/sys.exit with click commands and ClickException
- Translate all user-facing messages via _()
- Add friendly Oops! / Nice! prompts
- Wrap HTTP errors in all scripts with user-friendly translated messages
- Update all unit tests to use CliRunner and expect ClickException
- Add 100% branch coverage for new HTTP error handling branches
- Add missing translation keys to i18n.py
- Fix pre-commit hook to use venv Python for validate_commit_msg.py
This commit is contained in:
Emil Simeonov
2026-06-19 20:11:20 +02:00
parent b2acaefaf9
commit 790b5c3769
11 changed files with 550 additions and 220 deletions
+30 -20
View File
@@ -5,7 +5,7 @@ import subprocess
import tempfile
from unittest.mock import patch
import pytest
from click.testing import CliRunner
from scripts.validate_commit_msg import CONVENTIONAL_RE, TASK_ID_RE, first_line, get_branch, main
@@ -73,50 +73,60 @@ class TestMain:
def test_rejects_task_id_on_feature_branch(self) -> None:
msg_path = self._write_msg("GRM-19: feat: add feature")
with patch("scripts.validate_commit_msg.get_branch", return_value="GRM-19"):
with pytest.raises(SystemExit) as exc:
main(["validate_commit_msg.py", msg_path])
assert exc.value.code == 1
runner = CliRunner()
result = runner.invoke(main, [msg_path])
assert result.exit_code == 1
assert "task ID" in result.output
def test_accepts_conventional_on_feature_branch(self) -> None:
msg_path = self._write_msg("feat: add feature")
with patch("scripts.validate_commit_msg.get_branch", return_value="GRM-19"):
main(["validate_commit_msg.py", msg_path])
runner = CliRunner()
result = runner.invoke(main, [msg_path])
assert result.exit_code == 0
def test_accepts_valid_master_commit(self) -> None:
msg_path = self._write_msg("GRM-19: feat: add feature")
with patch("scripts.validate_commit_msg.get_branch", return_value="master"):
main(["validate_commit_msg.py", msg_path])
runner = CliRunner()
result = runner.invoke(main, [msg_path])
assert result.exit_code == 0
def test_rejects_master_without_task_id(self) -> None:
msg_path = self._write_msg("feat: add feature")
with patch("scripts.validate_commit_msg.get_branch", return_value="master"):
with pytest.raises(SystemExit) as exc:
main(["validate_commit_msg.py", msg_path])
assert exc.value.code == 1
runner = CliRunner()
result = runner.invoke(main, [msg_path])
assert result.exit_code == 1
assert "task ID" in result.output
def test_rejects_master_with_non_conventional_after_task_id(self) -> None:
msg_path = self._write_msg("GRM-19: random message")
with patch("scripts.validate_commit_msg.get_branch", return_value="master"):
with pytest.raises(SystemExit) as exc:
main(["validate_commit_msg.py", msg_path])
assert exc.value.code == 1
runner = CliRunner()
result = runner.invoke(main, [msg_path])
assert result.exit_code == 1
assert "conventional" in result.output
def test_rejects_non_conventional_on_feature_branch(self) -> None:
msg_path = self._write_msg("random message")
with patch("scripts.validate_commit_msg.get_branch", return_value="feature"):
with pytest.raises(SystemExit) as exc:
main(["validate_commit_msg.py", msg_path])
assert exc.value.code == 1
runner = CliRunner()
result = runner.invoke(main, [msg_path])
assert result.exit_code == 1
assert "conventional" in result.output
def test_accepts_multiline_conventional(self) -> None:
msg_path = self._write_msg("feat: add feature\n\nBody text.\nMore text.")
with patch("scripts.validate_commit_msg.get_branch", return_value="feature"):
main(["validate_commit_msg.py", msg_path])
runner = CliRunner()
result = runner.invoke(main, [msg_path])
assert result.exit_code == 0
def test_usage_message_without_args(self) -> None:
with pytest.raises(SystemExit) as exc:
main([])
assert exc.value.code == 1
runner = CliRunner()
result = runner.invoke(main, [])
assert result.exit_code == 2
def test_main_module_block() -> None:
@@ -135,6 +145,6 @@ def test_main_module_block() -> None:
source = source.replace('if __name__ == "__main__":\n main()\n', "")
namespace = dict(vcm.__dict__)
exec(compile(source, vcm.__file__, "exec"), namespace)
namespace["main"](["validate_commit_msg.py", msg_path])
namespace["main"]([msg_path], standalone_mode=False)
os.unlink(msg_path)