mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-10 18:50:18 +01:00
fix: pre-landing review fixes
The doctor's in-process config read reselected the state root after the doctor set GSTACK_STATE_ROOT, so --check and --json printed 'selected by GSTACK_STATE_ROOT' whatever selected the root. cfg now keeps _gstack_sr_var. Adds the regression test, a CRLF/blank/200-byte launch-probe detail test, and corrects the clamp comment. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
115355a38b
commit
0e2e112182
3 files changed
+24
-2
No files matched your search
+2
-2
@@ -93,14 +93,14 @@ row() {
|
||||
sq() { printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"; }
|
||||
|
||||
# clamp CHARSET MAX — stdin's first line reduced to CHARSET, at most MAX chars.
|
||||
# Builtins only, bytewise like tr and cut: every caller pipes into it, and on
|
||||
# Builtins only, bytewise like tr and cut: every caller feeds it stdin, and on
|
||||
# Windows a head | tr | cut chain costs three process starts (~60 ms).
|
||||
clamp() { local LC_ALL=C line pat="[^$1]"; IFS= read -r line; line=${line//$pat/}; printf '%s' "${line:0:$2}"; }
|
||||
|
||||
# cfg KEY DEFAULT — sets _cfg to KEY as `gstack-config get` reads it, or DEFAULT
|
||||
# (gstack-config's own default) when unset. In-process through
|
||||
# gstack-state-root.sh, sourced below: a gstack-config start costs ~200 ms on Windows.
|
||||
cfg() { gstack_config_select "$1" 2>/dev/null; _cfg="${_gstack_cfg_value:-$2}"; }
|
||||
cfg() { local sr_var=${_gstack_sr_var-}; gstack_config_select "$1" 2>/dev/null; _gstack_sr_var=$sr_var; _cfg="${_gstack_cfg_value:-$2}"; }
|
||||
|
||||
# epoch_of VALUE — epoch seconds for an epoch or an ISO-8601 UTC time; "" otherwise.
|
||||
epoch_of() {
|
||||
|
||||
@@ -507,6 +507,20 @@ describe('gstack-doctor --check', () => {
|
||||
expect(probeCalls(f)).not.toContain('probe-model');
|
||||
});
|
||||
|
||||
// Value: protects=the --check state-root row names the variable that selected the root, after earlier rows read config;
|
||||
// fails_when=an in-process config read reselects the root from the doctor's own GSTACK_STATE_ROOT;
|
||||
// why_new=every other fixture sets GSTACK_STATE_ROOT itself, so a wrong "selected by" still reads GSTACK_STATE_ROOT; seam=none;
|
||||
// no_claim=CLAUDE_PLUGIN_DATA and default selection (GSTACK_HOME stands in for every selector other than GSTACK_STATE_ROOT)
|
||||
test('the state-root row names GSTACK_HOME when GSTACK_HOME selected the root, in text and JSON', () => {
|
||||
const f = makeFixture();
|
||||
installCodex(f);
|
||||
const byHome = { GSTACK_STATE_ROOT: '', GSTACK_HOME: f.state };
|
||||
const r = row(f, [], byHome);
|
||||
expect(r.rows['state-root'].rest, r.out).toContain('(selected by GSTACK_HOME;');
|
||||
const json = JSON.parse(doctor(f, ['--json'], byHome).out);
|
||||
expect(json.rows.find((x: { id: string }) => x.id === 'state-root').detail).toContain('(selected by GSTACK_HOME;');
|
||||
});
|
||||
|
||||
test('--for autoplan: healthy Capy machine with Claude subagents as the outside voice and no Codex CLI passes', () => {
|
||||
const f = makeFixture();
|
||||
installCodex(f);
|
||||
|
||||
@@ -51,6 +51,14 @@ describe.skipIf(process.platform === 'win32')('gstack-launch-probe.sh classifica
|
||||
expect(probe(fakeBinary('echo "Unknown argument: --version" >&2; exit 3'))).toEqual({ state: 'broken', detail: 'exit 3: Unknown argument: --version' });
|
||||
});
|
||||
|
||||
// Value: protects=the detail is the first non-blank line with CRs dropped, cut to 200 bytes (Windows CRLF output);
|
||||
// fails_when=the builtin line picker keeps a CR, returns a blank line or cuts at another length;
|
||||
// why_new=every other case prints one clean LF line; seam=none; no_claim=real Git Bash output (a sh fake prints the bytes)
|
||||
test('a broken binary\'s detail is its first non-blank line, CRs dropped, at most 200 bytes', () => {
|
||||
const long = 'y'.repeat(250);
|
||||
expect(probe(fakeBinary(`printf '\\r\\n \\n\\t\\r\\n${long}\\r\\nnext\\n'; exit 3`))).toEqual({ state: 'broken', detail: `exit 3: ${'y'.repeat(200)}` });
|
||||
});
|
||||
|
||||
test('an absent binary is missing', () => {
|
||||
expect(probe(fakeBinary(null)).state).toBe('missing');
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user