|
| 1 | +--- |
| 2 | +description: Script authoring conventions -- file organization, structure, lib/ utilities |
| 3 | +paths: |
| 4 | + - "scripts/**/*.ts" |
| 5 | +alwaysApply: false |
| 6 | +--- |
| 7 | + |
| 8 | +Scripts live in `scripts/` and are invoked via `bun run scripts/<name>.ts`. Follow the conventions below when adding or modifying scripts. |
| 9 | + |
| 10 | +## File organization |
| 11 | + |
| 12 | +**Top-level scripts** (`scripts/*.ts`) are standalone entry points. Each script handles one task (running tests, creating snapshots, building binaries, signing, etc.) and is wired to a `package.json` script where appropriate. |
| 13 | + |
| 14 | +**`scripts/lib/`** contains shared utilities consumed by multiple top-level scripts. Each file focuses on a single domain (e.g., `op.ts` for 1Password, `npm.ts` for the npm registry, `targets.ts` for platform targets). Move logic into `lib/` only when it is imported by more than one top-level script; otherwise keep it inline. |
| 15 | + |
| 16 | +**Test files** (`scripts/**/*.test.ts`) are co-located next to the module they test and follow the `bun:test` conventions in `rules/testing.md`. |
| 17 | + |
| 18 | +## Script structure |
| 19 | + |
| 20 | +Every top-level script follows this order: |
| 21 | + |
| 22 | +1. **JSDoc header** -- block comment describing what the script does, with `Usage:` examples. |
| 23 | +2. **Imports** -- Bun-first APIs preferred (`Bun.spawn`/`Bun.spawnSync` over `child_process`, `Bun.file`/`Bun.write` over `node:fs`). Node.js builtins are fine when Bun has no equivalent (`parseArgs` from `node:util`, `resolve` from `node:path`). |
| 24 | +3. **CLI argument parsing** -- `parseArgs` from `node:util` with `strict: true`. All options in a single call near the top. Validate required arguments immediately after, exit early with `process.exit(1)` and a clear error message on invalid input. |
| 25 | +4. **Core logic** -- `Bun.spawn` for async subprocesses, `Bun.spawnSync` for synchronous. Check exit codes explicitly. Use `try/finally` when temporary state (config files, temp dirs) needs cleanup. |
| 26 | +5. **Exit handling** -- call `process.exit(1)` for expected failures (e.g., "no test files found"). Do not throw unhandled errors for anticipated failure paths. |
| 27 | + |
| 28 | +See `scripts/run-tests.ts` as a reference implementation. |
| 29 | + |
| 30 | +## `lib/` utility conventions |
| 31 | + |
| 32 | +- **No side effects on import.** Importing a `lib/` module must not trigger work (no top-level `await`, no process spawns at module scope). |
| 33 | +- **JSDoc header** describing the module's domain and constraints. |
| 34 | +- **Export explicit TypeScript types** for structured data (`Target`, etc.) alongside the functions that produce or consume them. |
| 35 | +- **Co-locate constants** with the types they relate to (e.g., `SCOPE` and `PKG_PREFIX` live in `targets.ts`). |
| 36 | +- **Same Bun-first API preferences** as top-level scripts (`Bun.spawn`, `Bun.$`, `Bun.file`). |
0 commit comments