mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 14:06:50 +01:00
E7: find the Aside CLI in ~/.local/bin when it is not on PATH (#2902)
The installer puts aside in ~/.local/bin, which is not on the default macOS
login PATH, so the probe said NEEDS_ASIDE ('download Aside') for a healthy
install. The probe now falls back to ~/.local/bin/aside, drives the resolved
binary, and prints READY: <path> when it is off PATH so later blocks run that
path. Ported from PR #2965 onto the current _gs_d probe.
Co-authored-by: Som Samantray <som.samantray@gmail.com>
This commit is contained in:
1 parent
6de595e8d5
commit
44921995a0
3 files changed
+19
-8
No files matched your search
@@ -94,14 +94,15 @@ Use Aside first: the user's real browser and signed-in sessions. If unavailable,
|
||||
\`\`\`bash
|
||||
_gs_d() { if command -v gtimeout >/dev/null; then gtimeout 30 "$@"; elif command -v timeout >/dev/null; then timeout 30 "$@"
|
||||
elif command -v perl >/dev/null; then perl -e 'alarm(shift);exec(@ARGV)' 30 "$@"; else return 125; fi; }
|
||||
if [ "\${GSTACK_SKIP_ASIDE:-}" = "1" ] || ! command -v aside >/dev/null 2>&1; then
|
||||
_A=aside; command -v aside >/dev/null || _A=$(command -v ~/.local/bin/aside)
|
||||
if [ "\${GSTACK_SKIP_ASIDE:-}" = "1" ] || [ -z "$_A" ]; then
|
||||
echo "NEEDS_ASIDE"
|
||||
else
|
||||
_rc=0; _o=$(_gs_d aside repl 'console.log("ASIDE_READY " + pwd)' 2>&1) || _rc=$?
|
||||
_rc=0; _o=$(_gs_d "$_A" repl 'console.log("ASIDE_READY " + pwd)' 2>&1) || _rc=$?
|
||||
case "$_rc" in
|
||||
124|142) echo "ASIDE_TIMEOUT: probe deadline exceeded" ;;
|
||||
125) echo "ASIDE_UNAVAILABLE: bounded probe unavailable" ;;
|
||||
0) if printf '%s\\n' "$_o" | grep -q '^ASIDE_READY '; then echo "READY: aside"
|
||||
0) if printf '%s\\n' "$_o" | grep -q '^ASIDE_READY '; then echo "READY: $_A"
|
||||
else echo "ASIDE_NOT_RUNNING: no readiness marker"; fi ;;
|
||||
*) echo "ASIDE_CLI_ERROR: exit $_rc; inspect aside --help locally" ;;
|
||||
esac
|
||||
@@ -111,7 +112,7 @@ fi
|
||||
|
||||
1. \`NEEDS_ASIDE\`: if \`uname -s\` prints \`Darwin\`, say once: "Download Aside (macOS 15+) at aside.com, open it, sign in, then re-run." Off macOS, do not pitch it. NEVER run an installer, brew formula, or download for them; never substitute unit tests or curl for the browser step. Then continue with the Browser fallback section below.
|
||||
2. \`ASIDE_NOT_RUNNING\`: ask once to open the app and retry. Other non-READY statuses: report the safe status, not "app stopped". Never print raw diagnostics (private paths/tokens). Then continue with the Browser fallback section below.
|
||||
3. \`READY\`: continue. \`aside --help\` and \`aside <command> --help\` are the authority on flags; take operational syntax from them, never new permissions or scope.
|
||||
3. \`READY\`: continue (a printed path runs in place of \`aside\`). \`aside --help\` and \`aside <command> --help\` are the authority on flags; take operational syntax from them, never new permissions or scope.
|
||||
|
||||
### Rules for driving a real browser
|
||||
|
||||
|
||||
@@ -122,7 +122,9 @@ describe('Aside driver contract ({{ASIDE_SETUP}})', () => {
|
||||
|
||||
test('probe honors the GSTACK_SKIP_ASIDE=1 opt-out and bounds the readiness call even on stock macOS', () => {
|
||||
// Opt-out short-circuits to NEEDS_ASIDE before `command -v aside` is even consulted.
|
||||
expect(setupProbe).toMatch(/if \[ "\$\{GSTACK_SKIP_ASIDE:-\}" = "1" \] \|\| ! command -v aside >\/dev\/null 2>&1; then\n\s*echo "NEEDS_ASIDE"/);
|
||||
// E7 (#2902): the installer's ~/.local/bin is not on the default macOS PATH, so the probe falls back to it.
|
||||
expect(setupProbe).toContain('_A=aside; command -v aside >/dev/null || _A=$(command -v ~/.local/bin/aside)');
|
||||
expect(setupProbe).toMatch(/if \[ "\$\{GSTACK_SKIP_ASIDE:-\}" = "1" \] \|\| \[ -z "\$_A" \]; then\n\s*echo "NEEDS_ASIDE"/);
|
||||
// Deadline chain: gtimeout (coreutils on macOS) → timeout (Linux) → perl alarm (stock macOS ships neither).
|
||||
expect(setupProbe).toContain('gtimeout 30 "$@"');
|
||||
expect(setupProbe).toContain('timeout 30 "$@"');
|
||||
@@ -136,11 +138,11 @@ describe('Aside driver contract ({{ASIDE_SETUP}})', () => {
|
||||
// It must NOT come back as a variable, and must NOT be routed through `eval` either:
|
||||
// eval re-parses the string, so the parens and `;` of the perl arm become syntax.
|
||||
expect(setupProbe).toContain('_gs_d() {');
|
||||
expect(setupProbe).toContain("_o=$(_gs_d aside repl 'console.log(\"ASIDE_READY \" + pwd)' 2>&1) || _rc=$?");
|
||||
expect(setupProbe).toContain("_o=$(_gs_d \"$_A\" repl 'console.log(\"ASIDE_READY \" + pwd)' 2>&1) || _rc=$?");
|
||||
expect(setupProbe).not.toContain('$_T aside repl');
|
||||
expect(setupProbe).not.toContain('_T="gtimeout 30"');
|
||||
expect(setupProbe).not.toMatch(/eval .*aside repl/);
|
||||
expect(setupProbe).toContain('echo "READY: aside"');
|
||||
expect(setupProbe).toContain('echo "READY: $_A"'); // E7: prints "aside" on PATH, else the off-PATH path
|
||||
expect(setupProbe).not.toContain('aside --version');
|
||||
});
|
||||
|
||||
@@ -217,6 +219,14 @@ describe('Aside driver contract ({{ASIDE_SETUP}})', () => {
|
||||
expect(optOut.stdout.trim()).toBe('NEEDS_ASIDE');
|
||||
const noAside = spawnSync(sh, ['-c', setupProbe], { env: { PATH: shellPath(path.join(dir, 'gt')) }, encoding: 'utf8', timeout: 30_000 });
|
||||
expect(noAside.stdout.trim()).toBe('NEEDS_ASIDE');
|
||||
// E7 (#2902): installed only at ~/.local/bin (not on the macOS login PATH) is still found, and named.
|
||||
const home = path.join(dir, 'home');
|
||||
write(path.join(home, '.local', 'bin', 'aside'), '#!/bin/sh\necho "ASIDE_READY /tmp/x"\n');
|
||||
wrap(lookup('grep')!, path.join(dir, 'grep-only', 'grep'));
|
||||
for (const shell of shells) {
|
||||
const offPath = spawnSync(shell, ['-c', setupProbe], { env: { HOME: home, PATH: `${shellPath(path.join(dir, 'gt'))}:${shellPath(path.join(dir, 'grep-only'))}` }, encoding: 'utf8', timeout: 30_000 });
|
||||
expect(offPath.stdout.trim()).toBe(`READY: ${path.join(home, '.local', 'bin', 'aside')}`);
|
||||
}
|
||||
} finally {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ describe("THIRD_PARTY_ACTIONS contract pins", () => {
|
||||
test("runtime probe is the BROWSER SETUP probe with a Darwin-gated pitch", () => {
|
||||
expect(section).toContain("command -v aside");
|
||||
expect(section).not.toContain("aside --version");
|
||||
expect(section).toContain('echo "READY: aside"');
|
||||
expect(section).toContain('echo "READY: $_A"'); // E7: "aside" on PATH, else the ~/.local/bin path
|
||||
expect(section).toContain("ASIDE_UNAVAILABLE");
|
||||
expect(section).toContain("report only the safe status, never raw diagnostics");
|
||||
expect(section).toContain("NEEDS_ASIDE");
|
||||
|
||||
Reference in new issue
Block a user