fix(gl): make doctor exit non-zero on Fail-class checks (#357) - #391
fix(gl): make doctor exit non-zero on Fail-class checks (#357)#391Ayush7614 wants to merge 2 commits into
Conversation
gl doctor printed per-row status and 'Some checks failed' prose, but its exit code was always 0. A diagnostic whose exit status cannot express failure is a trap waiting for the first 'gl doctor && ...' to land somewhere it should not (Gitlawb#357). Three changes: 1. Re-tier the 'GITLAWB_NODE unset' check from Fail to Warn. The CLI's --node flag defaults to https://node.gitlawb.com (PUBLIC_NODE) and the CLI works fine without the env var, so an unset env is advisory, not a failure. Without this re-tier the obvious 'return non-zero on any failure' change would have flipped gl doctor to exit 1 on a stock working install, which is exactly the regression the issue warns against. 2. Route the exit-code decision through a new has_failures(&[Check]) helper: exit 1 if and only if at least one row is Fail-class. Warn-class rows (iCaptcha offline, version drift, shell-alias shadowing, GITLAWB_NODE unset) keep the process at exit 0 because those conditions are still printed to the user and the obvious '&& pipeline' pattern stays valid. Use std::process::exit(1) rather than returning Err so anyhow's error frame does not duplicate the user-facing summary that already prints. 3. Three unit tests pin the new predicate against the three regimes: all-Ok, warn-only, and a single Fail row tripping the exit. The warn-only case is the regression guard for the re-tier: if anyone flips GITLAWB_NODE back to Fail, exit_predicate_is_false_for_warn_only fails too, so the two halves of the fix cannot drift apart. Verified end-to-end against the public gitlawb node: * unset GITLAWB_NODE, missing identity/registration -> exit 1 * unset GITLAWB_NODE, full healthy install -> exit 0 (warn) * missing git-remote-gitlawb -> exit 1
|
Warning Review limit reachedNext included review available in 59 minutes. View limit detailsLimit details: You’ve used the included review currently available. This review ran on the open-source allowance, not this organization's plan, because the pull request author doesn't have an assigned seat. Waiting won't change this — ask an organization admin to assign them a seat, or add seats in Billing if every seat is already assigned, then retry. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (2)
Comment |
beardthelion
left a comment
There was a problem hiding this comment.
Core is right: the exit gate works, the re-tier is the one #357 asked for, and the tier lists match the issue. One ask before this merges.
Findings
- [P2] Pin the exit wiring, not just the predicate
crates/gl/src/doctor.rs:325
The three added tests asserthas_failuresover hand-builtVec<Check>, so they never touch thestd::process::exit(1)call or theCheck::warnre-tier. I deleted the exit gate outright andcargo test -p gl doctor::stayed at 19 passed / 0 failed; a binary probe on the same two trees gave exit 1 pristine and exit 0 gutted, so the mutation is behavior-changing and the suite cannot see it. Same for the re-tier: flippingGITLAWB_NODEback toCheck::failleavesexit_predicate_is_false_for_warn_onlygreen, because that test builds its own warn rows rather than reading the onesrunwrites. An integration test undercrates/gl/tests/drivingenv!("CARGO_BIN_EXE_gl")with a temp--dirand--node http://127.0.0.1:1closes the first half; I wrote it, confirmed it passes on your head and fails when the exit gate is removed, andtempfileis already agldev-dependency so it costs no new dep. For the re-tier half, extracting the env-classification arm into a small function returning aCheckwould let a unit test pin Warn directly.
Not asks
The GITLAWB_NODE re-tier stands as you wrote it. One thing that surfaced underneath it is mine, not yours: git-remote-gitlawb falls back to http://127.0.0.1:7545 when the env is unset (crates/git-remote-gitlawb/src/main.rs:68) while every gl subcommand defaults to https://node.gitlawb.com, so on a stock install doctor probes and greenlights a node the transport will never contact and exits 0 while pushes are broken. That predates this PR and #357 did not confront it. I will file it separately rather than hang it on this change.
Verified here: full diff at base bfc44f9, both production changes mutated one at a time with the suite re-run, binary exit codes driven end to end on a broken install and on an unset-env install, doctor::run callers grepped (crates/gl/src/main.rs:171 is the only one, and nothing in-repo consumes the exit status), and the gl vs git-remote-gitlawb node defaults read side by side.
- Extract GITLAWB_NODE env classification into gitlawb_node_env_check() so unit tests can pin the Warn tier directly; the previous has_failures-only tests built their own Check::warn rows and could not see a re-tier back to Fail. - Add three unit tests for the extracted helper (unset/empty is Warn, set is Pass, loopback is Pass). - Add integration probe crates/gl/tests/doctor_exit.rs that drives the real binary with a temp --dir and --node http://127.0.0.1:1 and asserts exit 1. Deleting the std::process::exit(1) gate keeps the unit suite green but breaks this probe, closing the gap reviewer noted. Co-authored-by: review fix for Gitlawb#391
|
Thanks for the review @beardthelion Addressed review feedback (pushed P2 – Pin exit wiring, not just predicate
Verification: Thanks for the detailed mutation notes – both halves (exit gate + re-tier) are now independently load-bearing. |
Addressed on 787acea: exit wiring probe and GITLAWB_NODE Warn tier pinned.
beardthelion
left a comment
There was a problem hiding this comment.
Re-reviewed head 787acea against base bfc44f92. The prior ask is landed: gitlawb_node_env_check pins the Warn tier directly, and crates/gl/tests/doctor_exit.rs drives the real gl binary for exit 1. I mutation-checked both guards (exit gate removal and re-tier flip each go RED). cargo test -p gl -- doctor:: doctor_exits is 22 unit + 1 integration green locally; CI is 12/12 on the push.
Not an ask, recorded only: the module doc at crates/gl/src/doctor.rs:6 still says check 3 requires a non-localhost URL; behavior is now Warn on unset/empty. Optional one-line doc fix, not blocking.
Not an ask, recorded only: with GITLAWB_NODE unset, doctor probes --node (default https://node.gitlawb.com) while git-remote-gitlawb falls back to 127.0.0.1:7545. That predates this PR; tracked separately (#394 class).
One process note, not a finding: rebasing may conflict with #331/#394 on doctor.rs.
Closes #357.
What
gl doctorprinted per-row✓/⚠/✗status and theSome checks failedprose, but its exit code was always 0 — a diagnostic whose exit status cannot express failure is a trap waiting for the firstgl doctor && ...to land somewhere it shouldn't (#357).Fix
Three changes in
crates/gl/src/doctor.rs:Re-tier
GITLAWB_NODEunset from Fail to Warn. The CLI's--nodeflag defaults tohttps://node.gitlawb.com(PUBLIC_NODE) and the CLI works fine without the env var, so an unset env is advisory, not a failure. Without this re-tier the obvious "return non-zero on any failure" change would have flippedgl doctorto exit 1 on a stock working install, which is exactly the regression the issue warns against.Route the exit-code decision through a new
has_failures(&[Check])helper: exit 1 if and only if at least one row is Fail-class. Warn-class rows (iCaptcha offline, version drift, shell-alias shadowing, GITLAWB_NODE unset) keep the process at exit 0 because those conditions are still printed to the user and the obvious&&pipeline pattern stays valid. Usestd::process::exit(1)directly rather than returningErrso anyhow's error frame does not duplicate the user-facing summary that already prints.Three unit tests pin the new predicate against the three regimes: all-Ok, warn-only, and a single Fail row tripping the exit. The warn-only case is the regression guard for the re-tier: if anyone flips
GITLAWB_NODEback to Fail,exit_predicate_is_false_for_warn_onlyfails too, so the two halves of the fix cannot drift apart.Why these tiers
Per the issue, the Fail-class checks are: identity missing or unparseable, registration missing or malformed, node unreachable or non-2xx,
git-remote-gitlawbabsent,gitabsent. The Warn-class checks are: iCaptcha reachability, shell-alias shadowing, version drift, and nowGITLAWB_NODEunset.Verification
End-to-end against the public gitlawb node (
/doctoris the binary):GITLAWB_NODE, no identity/registration✗identity,✗registration,⚠GITLAWB_NODE,✗git-remote-gitlawbGITLAWB_NODE, full healthy install✓x7,⚠GITLAWB_NODEgit-remote-gitlawbin PATH✗git-remote-gitlawb,✗gitThe first row is the new exit-on-Fail path; the second is the regression-guard for the re-tier; the third confirms the
githelper absence still fails the install.(Ignored the unrelated pre-existing
clippy::duplicated_attributesatcrates/gitlawb-node/src/api/ipfs.rs:2169— present onupstream/mainbefore this PR; not touched here.)