owenrusk.dev

casebench

test cases straight onto the board.

git clone https://owenrusk.dev/casebench.git

commit 9179d6c1f924eae122db7d4086ffccd8a71727d7
parent 1f4702d0b6bf1723a5435af631fec938240a47d9
author Owen Rusk <owen@papermothgames.com>
date   2025-11-18 20:41:17 -0600
lock: ask for the answers when --answer is left out

keeps them out of shell history.
casebench/cli.py+11-2
diff --git a/casebench/cli.py b/casebench/cli.py
index 7880a8f..cc62d78 100644
--- a/casebench/cli.py
+++ b/casebench/cli.py
@@ -1,4 +1,5 @@
 import argparse
+import getpass
 import os
 import sys
 from pathlib import Path
@@ -31,7 +32,7 @@ def parser() -> argparse.ArgumentParser:
 
     locker = sub.add_parser("lock", help="lock a case behind one or more answers")
     locker.add_argument("case")
-    locker.add_argument("--answer", action="append", required=True, help="one per line of the lock")
+    locker.add_argument("--answer", action="append", help="one per line of the lock; asked for if left out")
     locker.add_argument("--rest", default="3/60", help="tries/minutes: after that many wrong tries in a row, take nothing for that long (default: 3/60)")
     locker.add_argument("--text", default="locked.", help="what the lock says (default: locked.)")
     locker.add_argument("--player", required=True)
@@ -112,11 +113,19 @@ def run_note(store: Store, args: argparse.Namespace) -> None:
 def run_lock(store: Store, args: argparse.Namespace) -> None:
     who = player(store, args.player)
     on_board(store, who, args.case)
-    new = lock.make(args.answer, lock.parse_rest(args.rest), args.text)
+    new = lock.make(args.answer or ask(), lock.parse_rest(args.rest), args.text)
     store.lock(who, args.case, new)
     print(f"{who.handle}: locked {args.case}")
 
 
+def ask() -> list[str]:
+    # answers typed here stay out of the shell's history. an empty line ends them.
+    answers = []
+    while answer := getpass.getpass(f"line {len(answers) + 1}: "):
+        answers.append(answer)
+    return answers
+
+
 def run_unlock(store: Store, args: argparse.Namespace) -> None:
     who = player(store, args.player)
     if not store.unlock(who, args.case):