emrg: converge Windows stop logic into emrg stop (Python), delete stop-emrg.cmd - #811
Conversation
…p-emrg.cmd
Host rant 2026-08-17T10:32:27: '不要 stop-emrg.cmd 了,所有动作都在 emrg stop
命令里完成' — Windows upgrade installs kept failing (had to restart the OS)
because stop logic was split across cmd+PowerShell (stop-emrg.cmd) and
Python (emrg stop), with emrg stop missing key actions.
- New emrg/_stop_all.py (pure stdlib, no emrg imports): ws protocol shutdown
-> ~/.emrg/emrgd.pid fallback -> SIGTERM/taskkill /F, GUI EMRG.exe graceful
+ unconditional /F, TUI CIM filter (python.exe|pythonw.exe -m emrg, not
emrg.server), bundled-git install\git\ prefix kill (Windows), verify
residual scan + exit 1 with named residual list. Runs standalone with the
runtime python (Inno extracts the single file to {tmp}).
- emrg/__main__.py: 'emrg stop' delegates to emrg._stop_all.stop_all() and
sys.exit() propagates the code; matcher helpers delegate to _stop_all
(single source of truth).
- Delete bin/stop-emrg.cmd; build-runtime.sh ships bin/stop_all.py instead
(CRLF loop now covers only emrg.cmd/emrgd.cmd).
- make-installer.sh: [Files] dontcopy stop_all.py; PrepareToInstall probes
{app}\bin\python-dist\python.exe (fallback python3.13.exe, R90 layout),
runs it via cmd /c with > log 2>&1 (R125 log display preserved), clean
install skips; abort message updated to 'emrg stop exit code'.
- test.yml iscc compile gate stub: stop_all.py.
- Tests: rewrite tests/test_installer_stop.py (stop-emrg.cmd deleted wiring),
add tests/test_stop_all.py (pure-stdlib, matching, exit-code semantics).
pytest 834 -> 851, Agent.md synced.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle (self-review): pure-stdlib emrg/_stop_all.py is the single source of truth (runs via emrg stop, python -m emrg._stop_all, and standalone in the installer with the runtime python). Exit-code passthrough (sys.exit(_stop_all())), daemon pid-file fallback, bundled-git prefix kill, verify + residual list all ported from stop-emrg.cmd; PrepareToInstall probes python-dist python (never depends on the old version's emrg stop) and keeps the R125 log-display via cmd /c redirection. stop-emrg.cmd fully removed from bin/build-runtime/make-installer/test.yml. pytest 851 green + test-windows pass (iscc gate compiles the .iss).
|
I tested PR #811 end-to-end (checked out Verified
Findings (non-blocking)
Overall the converge looks correct and the installer pre-stop should behave identically to the host-verified v2. |
…daemon grace pm25coder #811 review findings: 1. A user-invoked `emrg stop` runs as `python.exe -m emrg stop`, which matches the TUI CIM filter (`-m emrg` and not `emrg.server`) → Stop-Process -Force killed the CLI itself at the TUI step, so stop_bundled_git + verify never ran and the exit-code contract was lost. Fix: pass the invoking PID into the PowerShell filter and exclude it ($_.ProcessId -ne <pid>), mirroring the POSIX branch's own_pid guard. The installer path is unaffected (stop_all.py runs as a plain script). 2. Daemon grace window restored 3s → 10s (60 x 0.15s) to match the host-verified stop-emrg.cmd v2 semantics — a busy daemon mid-tool-loop needs the full window before the taskkill /F fallback. Wiring test extended to pin the ProcessId exclusion (textual).
|
Addressed the review findings (commit 463f8fb pushed):
|
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle (post-fix): commit 463f8fb addresses pm25coder's findings — the Windows TUI CIM filter now excludes the invoking PID ($_.ProcessId -ne ), so a user-run emrg stop no longer kills itself at the TUI step and stop_bundled_git + verify + exit-code contract survive; daemon grace window restored 3s→10s (60×0.15s) matching host-verified v2. Wiring test pins the exclusion. pytest 851 green + CI test + test-windows PASS on head.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 2 (re-verify): head 463f8fb (post-fix), CI test + test-windows PASS. The ProcessId exclusion + 10s grace window address pm25coder's findings; wiring test pins the exclusion. 851 collected (850 passed + 1 skipped) locally.
|
I re-tested PR #811 at the new head What I verified
The bug ps_cmd = (
"Get-CimInstance Win32_Process | "
"Where-Object { $_.ProcessId -ne {own} -and "
...
"ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"
).format(own=own)
Why CI doesn't catch it
Suggested fix |
….md count 851→858) Master advanced with #811 (stop_all tests → 851); this branch adds 7 vibe-check tests → 858. Resolved the Agent.md pytest-count conflict.
Closes host rant 2026-08-17T10:32:27 — "不要 stop-emrg.cmd 了,所有动作都在 emrg stop 命令里完成" (don't use stop-emrg.cmd anymore; do everything in the
emrg stopcommand).Problem
Windows upgrade installs kept failing and required a full OS restart. Stop logic was split across two implementations:
bin/stop-emrg.cmd(cmd + PowerShell) — ran by the Inno installer'sPrepareToInstallemrg stop(Python,emrg/__main__.py) — the official CLI entry, but missing the critical actions (bundled-git kill, daemon pid-file fallback, residual verification, non-zero exit code)Changes
emrg/_stop_all.py— pure standard library (no emrg imports), single source of truth, runs in all three contexts (emrg stop,python -m emrg._stop_all, and standalone with the runtime Python inside the installer):shutdown→~/.emrg/emrgd.pidfallback → SIGTERM /taskkill /F /PID→ 3s poll; port file cleaned once deadtaskkill /IM EMRG.exegraceful → unconditional/F(host 01:27:07Z lesson)python.exe|pythonw.exerunning-m emrg(excludingemrg.server) — covers the windowless pythonw daemoninstall\git\prefix kill (git/ssh/plink/bash + fallback prefix full-kill)name (pid N))emrg/__main__.py:emrg stopdelegates tostop_all()andsys.exit()propagates the code; matcher helpers delegate to_stop_all(single source of truth).bin/stop-emrg.cmd;build-runtime.shshipsbin/stop_all.pyinstead (CRLF loop now covers onlyemrg.cmd/emrgd.cmd).make-installer.sh:[Files] dontcopy→stop_all.py;PrepareToInstallprobes{app}\bin\python-dist\python.exe(fallbackpython3.13.exe, R90 layout — never depends on the old version'semrg stop), runs it viacmd /c ... > log 2>&1(R125 log-display preserved), skips on clean install; abort message updated to "emrg stop exit code".test.ymliscc compile gate stub →stop_all.py.tests/test_installer_stop.pyrewritten for the new wiring; newtests/test_stop_all.py(pure-stdlib import guard, process matching pos/neg, pid-file parsing, ws shutdown failure paths, exit-code semantics). pytest 834 → 851, Agent.md synced.Verification
uv run pytest tests/— 851 collected, all green (incl. doc-count guard)bash packaging/build-runtime.sh— runtime shipsbin/stop_all.py, nostop-emrg.cmdpython -m emrg --help/emrg stop -h— updated help textemrg.isscompiles under the CI iscc gate (Windows runner)emrg stopbehavior unchanged (ps scan + SIGTERM/SIGKILL)