fix(client): flush the device code, or nobody ever sees it
Hit for real driving a first sign-in: `granthi-sync link` run through anything that is not a terminal -- a wrapper, a pipe, `| tee setup.log` -- printed NOTHING, while the code it was holding silently expired five minutes later. Python buffers stdout when stdout is not a tty, and the two prints carrying the verification URL and the user code did not flush. They flush now. One regression test asserts both are printed with flush=True, because this fails silently and only under redirection, which is exactly the condition a test would otherwise never reproduce. 204 tests (was 203).
This commit is contained in:
@@ -599,8 +599,13 @@ def device_flow():
|
||||
form={"client_id": DEVICE_CLIENT_ID, "scope": DEVICE_SCOPE})
|
||||
if status != 200:
|
||||
raise SystemExit(f"device authorization failed (HTTP {status}): {resp}")
|
||||
print(f"\nTo link this device, open:\n\n {resp.get('verification_uri_complete') or resp.get('verification_uri')}\n")
|
||||
print(f"and enter code: {resp['user_code']}\n")
|
||||
# flush=True is not cosmetic. Python buffers stdout when it is not a
|
||||
# terminal, so `granthi-sync link | tee setup.log`, a wrapper script, or
|
||||
# anything capturing output shows NOTHING while the code silently expires
|
||||
# five minutes later. Hit for real on 2026-08-23 driving a first sign-in.
|
||||
print(f"\nTo link this device, open:\n\n {resp.get('verification_uri_complete') or resp.get('verification_uri')}\n",
|
||||
flush=True)
|
||||
print(f"and enter code: {resp['user_code']}\n", flush=True)
|
||||
interval = int(resp.get("interval", 5))
|
||||
deadline = time.time() + int(resp.get("expires_in", 300))
|
||||
while time.time() < deadline:
|
||||
|
||||
Reference in New Issue
Block a user