feat(xce-test-rc-file): task 2.2 wire rc-file loading into xce_test startup

Adds the integration call site in main(), between g_continue_on_error's
computation and the read loop: unless --norc is given, resolve the rc-file
path and load it through preprocess_and_run (the same command-execution
path used for typed/piped input). A NULL path (no XDG/HOME) or missing
file falls through silently to the read loop. A failing rc-file command
under scripted/piped abort-on-first-failure mode short-circuits straight
to the existing g_session_failed exit-code convention, never entering the
read loop -- so a piped script's own commands never run after an rc-file
failure. Verified end-to-end against the built binary, including a real
pty for the interactive path, in both the failure and success cases.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgYRU3zDTqNGV5Jk8aiKLg
This commit is contained in:
Rongsong Shen 2026-08-26 16:06:47 +00:00
parent 68fcd657d6
commit e863d69993
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
2 changed files with 24 additions and 1 deletions

View file

@ -24,7 +24,7 @@
- _Requirements: 2.1, 2.2_
- _Boundary: test.c::options[]/parse_opt_
- [ ] 2.2 Wire rc-file loading into xce_test startup for both interactive and scripted sessions
- [x] 2.2 Wire rc-file loading into xce_test startup for both interactive and scripted sessions
- After xce_test determines whether the session is interactive or scripted and before it reads the first line of its normal session, resolve and load the rc file unless the skip flag was given, using the session's existing command-execution path as the per-line runner
- When rc-file loading signals a stop, exit using the session's existing pass/fail exit-code convention without entering the normal session loop
- Observable: a valid rc file's settings/context are visible once the normal session begins, in both a piped run and an interactive run; the same is confirmed absent when the skip flag is given

View file

@ -30,6 +30,7 @@
#include "snapdiff.h" /* byte-level checkpoint-file comparator (cmd_snapdiff) */
#include "snapverify.h" /* offline checkpoint-file structural validator (cmd_snapverify) */
#include "configcompare.h" /* cross-member active-config comparator (cmd_configcompare) */
#include "rcfile.h" /* startup rc-file path resolution + loading (xce-test-rc-file task 2.2) */
#include "resval_typeresolve.h" /* resval_resolve_type (resource-value-verification task 2.1) */
#include "xce/cluster.h" /* xce_parse_peers, xce_cluster_config_t */
#include "xce/types.h"
@ -4485,6 +4486,28 @@ int main(int argc, char* argv[])
g_interactive = isatty(STDIN_FILENO);
g_continue_on_error = g_interactive ? 1 : 0;
/* xce-test-rc-file task 2.2: auto-load $XDG_CONFIG_HOME/xce_test/rc (or
* $HOME/.config/xce_test/rc) before the read loop starts, for both
* interactive and scripted sessions alike -- unless --norc was given.
* A missing/unresolvable rc file is silent (Req 1.3); a failing rc-file
* line is handled entirely by preprocess_and_run's existing abort/continue
* accounting (Req 3) -- an abort short-circuits straight to the same
* exit-code convention used at the bottom of this function, skipping the
* read loop entirely (Req 1.4/3.3). */
if (!arguments.norc) {
char* rcpath = rcfile_resolve_path();
if (rcpath != NULL) {
int rcrc = rcfile_load(rcpath, preprocess_and_run);
free(rcpath);
if (rcrc) {
return g_session_failed ? 1 : 0;
}
}
}
while (!done) {
char* s;
int rc;