mirror of https://github.com/garrytan/gstack.git
Merge 01a50e0503 into a3259400a3
This commit is contained in:
commit
d0e88148fa
34
setup
34
setup
|
|
@ -3,6 +3,40 @@
|
||||||
set -e
|
set -e
|
||||||
umask 077 # Restrict new files to owner-only (0o600 files, 0o700 dirs)
|
umask 077 # Restrict new files to owner-only (0o600 files, 0o700 dirs)
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
gstack setup — install gstack skills + build browse binary
|
||||||
|
|
||||||
|
Usage: ./setup [options]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--host <name> Install for a specific host (claude, codex, kiro, factory,
|
||||||
|
opencode, openclaw, hermes, gbrain, auto). Default: claude.
|
||||||
|
--prefix Install skills with the gstack- prefix (e.g. /gstack-review).
|
||||||
|
--no-prefix Install skills with short names (e.g. /review). Default.
|
||||||
|
--team Switch to team mode (per-repo gstack with auto-update).
|
||||||
|
--no-team Force solo install even if a team-mode repo is detected.
|
||||||
|
-q, --quiet Suppress progress output.
|
||||||
|
-h, --help Show this help and exit.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
./setup # solo install for Claude Code
|
||||||
|
./setup --host codex # install for OpenAI Codex CLI
|
||||||
|
./setup --team # team mode for a shared repo
|
||||||
|
./setup --no-prefix # use short slash-command names
|
||||||
|
|
||||||
|
Docs: https://github.com/garrytan/gstack
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Short-circuit on -h/--help before any environment checks so users can
|
||||||
|
# discover flags even without bun installed.
|
||||||
|
for _arg in "$@"; do
|
||||||
|
case "$_arg" in
|
||||||
|
-h|--help) usage; exit 0 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
if ! command -v bun >/dev/null 2>&1; then
|
if ! command -v bun >/dev/null 2>&1; then
|
||||||
echo "Error: bun is required but not installed." >&2
|
echo "Error: bun is required but not installed." >&2
|
||||||
echo "Install with checksum verification:" >&2
|
echo "Install with checksum verification:" >&2
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
import { describe, test, expect } from 'bun:test';
|
||||||
|
import { spawnSync } from 'child_process';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
const ROOT = path.resolve(import.meta.dir, '..');
|
||||||
|
const SETUP_SCRIPT = path.join(ROOT, 'setup');
|
||||||
|
|
||||||
|
describe('setup: --help flag (#1133)', () => {
|
||||||
|
test('setup script defines a usage() function', () => {
|
||||||
|
const content = fs.readFileSync(SETUP_SCRIPT, 'utf-8');
|
||||||
|
expect(content).toMatch(/^usage\(\)\s*\{/m);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setup script short-circuits on -h/--help before env checks', () => {
|
||||||
|
const content = fs.readFileSync(SETUP_SCRIPT, 'utf-8');
|
||||||
|
const helpIdx = content.search(/-h\|--help\)\s*usage;\s*exit 0/);
|
||||||
|
const bunCheckIdx = content.indexOf('command -v bun');
|
||||||
|
expect(helpIdx).toBeGreaterThan(-1);
|
||||||
|
expect(bunCheckIdx).toBeGreaterThan(-1);
|
||||||
|
// --help must be handled before the bun availability check so the flag
|
||||||
|
// works on machines that haven't installed bun yet.
|
||||||
|
expect(helpIdx).toBeLessThan(bunCheckIdx);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('usage text documents every supported flag', () => {
|
||||||
|
const content = fs.readFileSync(SETUP_SCRIPT, 'utf-8');
|
||||||
|
const usageMatch = content.match(/usage\(\)\s*\{[\s\S]*?\n\}/);
|
||||||
|
expect(usageMatch).toBeTruthy();
|
||||||
|
const usage = usageMatch![0];
|
||||||
|
for (const flag of [
|
||||||
|
'--host',
|
||||||
|
'--prefix',
|
||||||
|
'--no-prefix',
|
||||||
|
'--team',
|
||||||
|
'--no-team',
|
||||||
|
'--quiet',
|
||||||
|
'--help',
|
||||||
|
]) {
|
||||||
|
expect(usage).toContain(flag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('./setup --help exits 0, prints usage, and does not run installer', () => {
|
||||||
|
const res = spawnSync('bash', [SETUP_SCRIPT, '--help'], {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
timeout: 5000,
|
||||||
|
});
|
||||||
|
expect(res.status).toBe(0);
|
||||||
|
expect(res.stdout).toContain('Usage:');
|
||||||
|
expect(res.stdout).toContain('gstack setup');
|
||||||
|
// Hard guarantee it short-circuited — none of the install-side output appears.
|
||||||
|
expect(res.stdout).not.toMatch(/Installing|bun install|Building|gen:skill-docs/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('./setup -h is equivalent to ./setup --help', () => {
|
||||||
|
const res = spawnSync('bash', [SETUP_SCRIPT, '-h'], {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
timeout: 5000,
|
||||||
|
});
|
||||||
|
expect(res.status).toBe(0);
|
||||||
|
expect(res.stdout).toContain('Usage:');
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue