|
1 | | -Default to using Bun instead of Node.js. |
2 | | - |
3 | | -- Use `bun <file>` instead of `node <file>` or `ts-node <file>` |
4 | | -- Use `bun test` instead of `jest` or `vitest` |
5 | | -- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild` |
6 | | -- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install` |
7 | | -- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>` |
8 | | -- Use `bunx <package> <command>` instead of `npx <package> <command>` |
9 | | -- Bun automatically loads .env, so don't use dotenv. |
10 | | - |
11 | | -## APIs |
12 | | - |
13 | | -- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`. |
14 | | -- `bun:sqlite` for SQLite. Don't use `better-sqlite3`. |
15 | | -- `Bun.redis` for Redis. Don't use `ioredis`. |
16 | | -- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`. |
17 | | -- `WebSocket` is built-in. Don't use `ws`. |
18 | | -- Prefer `Bun.file` over `node:fs`'s readFile/writeFile |
19 | | -- Bun.$`ls` instead of execa. |
| 1 | +# BackItUp Development Guide |
| 2 | + |
| 3 | +BackItUp is a secure backup utility with glob patterns, tar.gz archives, local + S3 storage, Docker volume support, and safe cleanup. It's built with Bun and compiled to standalone binaries for cross-platform distribution. |
| 4 | + |
| 5 | +## Quick Reference |
| 6 | + |
| 7 | +```bash |
| 8 | +bun install # Install dependencies |
| 9 | +bun run dev # Development with hot reload |
| 10 | +bun test # Run tests |
| 11 | +bun run lint # Lint with oxlint |
| 12 | +bun run format # Format code with oxfmt |
| 13 | +bunx tsc --noEmit # Type check |
| 14 | +bun run build # Build standalone binary |
| 15 | +``` |
| 16 | + |
| 17 | +## Bun Runtime |
| 18 | + |
| 19 | +Use Bun instead of Node.js for everything: |
| 20 | + |
| 21 | +- `bun <file>` instead of `node` or `ts-node` |
| 22 | +- `bun test` instead of jest/vitest |
| 23 | +- `bun install` instead of npm/yarn/pnpm |
| 24 | +- `bun run <script>` instead of npm run |
| 25 | +- `bunx <pkg>` instead of npx |
| 26 | +- Bun auto-loads `.env` files (no dotenv needed) |
| 27 | + |
| 28 | +### Bun APIs |
| 29 | + |
| 30 | +- `Bun.file()` for file I/O (not `node:fs` readFile/writeFile) |
| 31 | +- `Bun.$\`cmd\`` for shell commands (not execa) |
| 32 | +- `bun:sqlite` for SQLite (not better-sqlite3) |
| 33 | +- `Bun.serve()` for HTTP/WebSocket servers |
| 34 | + |
| 35 | +## Project Structure |
| 36 | + |
| 37 | +``` |
| 38 | +src/ |
| 39 | +├── index.ts # CLI entry point, command routing |
| 40 | +├── types/ # TypeScript type definitions |
| 41 | +│ ├── config.ts # BackitupConfig, SourceConfig, etc. |
| 42 | +│ ├── backup.ts # BackupResult, BackupRecord |
| 43 | +│ ├── storage.ts # Storage interfaces |
| 44 | +│ └── database.ts # DB record types |
| 45 | +├── cli/ |
| 46 | +│ ├── commands/ # backup, cleanup, list, start, verify |
| 47 | +│ └── ui/ # prompts, formatters, output helpers |
| 48 | +├── core/ |
| 49 | +│ ├── backup/ # orchestrator, file-collector, archive-creator |
| 50 | +│ ├── cleanup/ # retention, validator, orchestrator |
| 51 | +│ └── scheduler/ # daemon, cron-parser |
| 52 | +├── config/ # loader, validator, resolver, inline options |
| 53 | +├── db/ # SQLite connection, repositories, migrations |
| 54 | +├── docker/ # volume backup, compose integration |
| 55 | +├── storage/ # local and S3 storage backends |
| 56 | +└── utils/ # logger, crypto, path, naming, format |
| 57 | +tests/ # Mirror of src/ structure |
| 58 | +``` |
| 59 | + |
| 60 | +## Code Style |
| 61 | + |
| 62 | +- **Linter:** oxlint (run with `bun run lint`) |
| 63 | +- **Formatter:** oxfmt with double quotes, space indentation |
| 64 | +- **TypeScript:** Strict mode, ESNext target, bundler module resolution |
| 65 | + |
| 66 | +### Conventions |
| 67 | + |
| 68 | +- Commands return `Promise<number>` (exit code) |
| 69 | +- Use `@clack/prompts` and `picocolors` for CLI UI |
| 70 | +- Types are defined in `src/types/` and exported via barrel files |
| 71 | +- Repositories follow pattern: `*-repository.ts` |
| 72 | +- Core logic is in orchestrator files |
20 | 73 |
|
21 | 74 | ## Testing |
22 | 75 |
|
23 | | -Use `bun test` to run tests. |
| 76 | +Tests live in `tests/` mirroring `src/` structure. |
24 | 77 |
|
25 | | -```ts#index.test.ts |
26 | | -import { test, expect } from "bun:test"; |
| 78 | +```ts |
| 79 | +import { describe, expect, test } from "bun:test"; |
27 | 80 |
|
28 | | -test("hello world", () => { |
29 | | - expect(1).toBe(1); |
| 81 | +describe("module", () => { |
| 82 | + test("does something", () => { |
| 83 | + expect(result).toBe(expected); |
| 84 | + }); |
30 | 85 | }); |
31 | 86 | ``` |
| 87 | + |
| 88 | +Run tests: `bun test` |
| 89 | + |
| 90 | +## CI/CD |
| 91 | + |
| 92 | +CI runs on push/PR to main (`.github/workflows/ci.yml`): |
| 93 | +1. Type check: `bunx tsc --noEmit` |
| 94 | +2. Lint: `bun run lint` |
| 95 | +3. Test: `bun test` |
| 96 | + |
| 97 | +Release runs on version tags (`.github/workflows/release.yml`): |
| 98 | +1. Same checks as CI |
| 99 | +2. Build binaries for linux-x64, linux-arm64, darwin-x64, darwin-arm64, windows-x64 |
| 100 | +3. Generate SHA256 checksums |
| 101 | +4. Create GitHub release |
| 102 | +5. Build and push Docker image to ghcr.io |
| 103 | + |
| 104 | +## Build Targets |
| 105 | + |
| 106 | +```bash |
| 107 | +bun run build # Current platform |
| 108 | +bun run build:linux-x64 # Linux x64 |
| 109 | +bun run build:linux-arm64 # Linux ARM64 |
| 110 | +bun run build:darwin-x64 # macOS Intel |
| 111 | +bun run build:darwin-arm64 # macOS Apple Silicon |
| 112 | +bun run build:windows-x64 # Windows x64 |
| 113 | +``` |
| 114 | + |
| 115 | +## Key Dependencies |
| 116 | + |
| 117 | +- `@clack/prompts` - Interactive CLI prompts |
| 118 | +- `picocolors` - Terminal colors (imported as `color`) |
| 119 | +- `cron-parser` - Cron expression parsing |
| 120 | +- `js-yaml` - YAML config parsing |
| 121 | + |
| 122 | +Dev: |
| 123 | +- `oxlint` - Linting |
| 124 | +- `oxfmt` - Formatting |
| 125 | + |
| 126 | +## Configuration Types |
| 127 | + |
| 128 | +Main config interface is `BackitupConfig` in `src/types/config.ts`: |
| 129 | + |
| 130 | +- `sources: Record<string, SourceConfig>` - Named backup sources |
| 131 | +- `local: LocalStorageConfig` - Local storage settings |
| 132 | +- `s3: S3StorageConfig` - S3/R2/MinIO settings |
| 133 | +- `schedules: Record<string, ScheduleConfig>` - Cron schedules with retention |
| 134 | +- `docker?: DockerConfig` - Docker volume backup settings |
| 135 | + |
| 136 | +## Common Tasks |
| 137 | + |
| 138 | +### Adding a new command |
| 139 | + |
| 140 | +1. Create `src/cli/commands/<name>.ts` |
| 141 | +2. Export `<name>Command(args: string[]): Promise<number>` |
| 142 | +3. Add case to switch in `src/index.ts` |
| 143 | +4. Add help text to `printHelp()` |
| 144 | + |
| 145 | +### Adding a new config option |
| 146 | + |
| 147 | +1. Add type to `src/types/config.ts` |
| 148 | +2. Update `src/config/defaults.ts` |
| 149 | +3. Update `src/config/validator.ts` |
| 150 | +4. If inline option, update `src/config/inline.ts` |
| 151 | + |
| 152 | +### Database changes |
| 153 | + |
| 154 | +1. Add migration to `src/db/migrations/` |
| 155 | +2. Update `src/db/migrations/index.ts` |
| 156 | +3. Update repository and mapper files as needed |
0 commit comments