buncargo 1.0.26 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.d.ts +1 -12
- package/dist/bin.js +261 -252
- package/dist/cli/bin.d.ts +13 -0
- package/dist/cli/bin.js +315 -0
- package/dist/cli/commands/help.d.ts +1 -0
- package/dist/cli/commands/runtime.d.ts +5 -0
- package/dist/cli/commands/version.d.ts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +14 -0
- package/dist/cli/run-cli.d.ts +22 -0
- package/dist/cli.d.ts +1 -22
- package/dist/cli.js +5 -13
- package/dist/config/config.d.ts +1 -0
- package/dist/config/define-config.d.ts +13 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.js +15 -0
- package/dist/config/merge-configs.d.ts +3 -0
- package/dist/config/validate-config.d.ts +3 -0
- package/dist/config.d.ts +1 -72
- package/dist/config.js +12 -12
- package/dist/core/docker.d.ts +1 -74
- package/dist/core/docker.js +35 -26
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +123 -108
- package/dist/core/network.js +2 -2
- package/dist/core/ports.d.ts +22 -0
- package/dist/core/ports.js +5 -1
- package/dist/core/process.js +1 -1
- package/dist/core/tunnel.d.ts +33 -0
- package/dist/core/utils.js +2 -2
- package/dist/core/watchdog-runner.js +45 -42
- package/dist/core/watchdog.d.ts +1 -0
- package/dist/core/watchdog.js +4 -2
- package/dist/docker/index.d.ts +1 -0
- package/dist/docker/index.js +38 -0
- package/dist/docker/runtime.d.ts +87 -0
- package/dist/docker/runtime.js +37 -0
- package/dist/docker-compose/compose.d.ts +1 -0
- package/dist/docker-compose/generated-file.d.ts +7 -0
- package/dist/docker-compose/index.d.ts +3 -0
- package/dist/docker-compose/index.js +15 -0
- package/dist/docker-compose/model.d.ts +6 -0
- package/dist/docker-compose/services/clickhouse.d.ts +16 -0
- package/dist/docker-compose/services/define-docker-service.d.ts +41 -0
- package/dist/docker-compose/services/index.d.ts +23 -0
- package/dist/docker-compose/services/index.js +17 -0
- package/dist/docker-compose/services/postgres.d.ts +12 -0
- package/dist/docker-compose/services/redis.d.ts +12 -0
- package/dist/docker-compose/services/shared.d.ts +7 -0
- package/dist/docker-compose/yaml.d.ts +2 -0
- package/dist/environment/create-dev-environment.d.ts +23 -0
- package/dist/environment/index.d.ts +1 -0
- package/dist/environment/index.js +15 -0
- package/dist/environment/logging.d.ts +17 -0
- package/dist/environment/seeding.d.ts +9 -0
- package/dist/environment.d.ts +1 -23
- package/dist/environment.js +12 -14
- package/dist/index-045jksh5.js +147 -0
- package/dist/index-08wa79cs.js +125 -117
- package/dist/index-0kxnae3z.js +335 -0
- package/dist/index-1mdrf7nz.js +66 -0
- package/dist/index-1yvbwj4k.js +262 -242
- package/dist/index-23ev345g.js +475 -0
- package/dist/index-2ckr49sf.js +228 -0
- package/dist/index-2f47khe5.js +376 -369
- package/dist/index-2fr3g85b.js +220 -183
- package/dist/index-38xnzpa6.js +450 -0
- package/dist/index-3h3dhtf2.js +51 -43
- package/dist/index-42x95209.js +51 -43
- package/dist/index-4gp0az1g.js +145 -0
- package/dist/index-4xrxh8yv.js +72 -0
- package/dist/index-5gmws6ah.js +181 -0
- package/dist/index-5hka0tff.js +78 -76
- package/dist/index-5rfqps4b.js +3 -0
- package/dist/index-5t9jxqm0.js +428 -0
- package/dist/index-6c1w1xk5.js +101 -0
- package/dist/index-6fm7mvwj.js +118 -97
- package/dist/index-6srpc523.js +127 -128
- package/dist/index-731rzzfp.js +187 -0
- package/dist/index-75y4cg2z.js +51 -43
- package/dist/index-7ja4ywyj.js +126 -127
- package/dist/index-8bw1cmz4.js +531 -0
- package/dist/index-8hbbj1mp.js +120 -121
- package/dist/index-8xj2p5n5.js +145 -0
- package/dist/index-bj79tw5w.js +0 -0
- package/dist/index-bnk6nr0g.js +73 -0
- package/dist/index-brbbzyks.js +72 -0
- package/dist/index-c0dr6mcv.js +123 -0
- package/dist/index-cty0bcry.js +235 -218
- package/dist/index-d8tyv5se.js +228 -0
- package/dist/index-d9efy0n4.js +176 -150
- package/dist/index-etfmqjjf.js +427 -0
- package/dist/index-fb29934k.js +172 -0
- package/dist/index-g50jw1yf.js +72 -0
- package/dist/index-g6eb5wdw.js +118 -117
- package/dist/index-ggq3yryx.js +99 -95
- package/dist/index-h70tce00.js +177 -0
- package/dist/index-hkxtfqtc.js +333 -0
- package/dist/index-kf3dhser.js +146 -143
- package/dist/index-ma6tgdb2.js +500 -0
- package/dist/index-mam0bcyz.js +123 -0
- package/dist/index-mm412dkp.js +274 -0
- package/dist/index-n8v18aeb.js +0 -0
- package/dist/index-ndnmnsej.js +378 -371
- package/dist/index-p8wty0e2.js +389 -379
- package/dist/index-qfphr2fd.js +100 -0
- package/dist/index-qqmms8rs.js +51 -43
- package/dist/index-qw4093g2.js +51 -43
- package/dist/index-qzwpzjbx.js +121 -122
- package/dist/index-segbnm0h.js +146 -143
- package/dist/index-t0fj6gg1.js +112 -0
- package/dist/index-thdkwnv7.js +122 -0
- package/dist/index-tjbx2r2t.js +270 -0
- package/dist/index-tjqw9vtj.js +62 -54
- package/dist/index-vbpb89jy.js +248 -0
- package/dist/index-vhs88xhe.js +99 -95
- package/dist/index-w8zxnjka.js +249 -0
- package/dist/index-wk2na3t9.js +404 -0
- package/dist/index-wz9x8g7z.js +383 -373
- package/dist/index-x249gyde.js +388 -378
- package/dist/index-xkvd0nsd.js +187 -0
- package/dist/index-yedqxm1z.js +80 -0
- package/dist/index-zfjzzjkf.js +266 -0
- package/dist/index.d.ts +12 -8
- package/dist/index.js +66 -35
- package/dist/lint.d.ts +1 -46
- package/dist/lint.js +3 -7
- package/dist/loader/cache.d.ts +4 -0
- package/dist/loader/find-config-file.d.ts +2 -0
- package/dist/loader/index.d.ts +5 -0
- package/dist/loader/index.js +24 -0
- package/dist/loader/load-dev-env.d.ts +5 -0
- package/dist/loader/loader.d.ts +1 -0
- package/dist/loader.d.ts +1 -45
- package/dist/loader.js +22 -20
- package/dist/prisma/index.d.ts +1 -0
- package/dist/prisma/prisma.d.ts +29 -0
- package/dist/prisma.d.ts +1 -29
- package/dist/prisma.js +6 -10
- package/dist/src/bin.js +309 -0
- package/dist/src/cli.js +5 -0
- package/dist/src/config.js +15 -0
- package/dist/src/core/docker.js +38 -0
- package/dist/src/core/index.js +130 -0
- package/dist/src/core/network.js +9 -0
- package/dist/src/core/ports.js +23 -0
- package/dist/src/core/process.js +31 -0
- package/dist/src/core/utils.js +11 -0
- package/dist/src/core/watchdog-runner.js +69 -0
- package/dist/src/core/watchdog.js +28 -0
- package/dist/src/docker/runtime.js +37 -0
- package/dist/src/docker-compose/index.js +16 -0
- package/dist/src/docker-compose/services/index.js +17 -0
- package/dist/src/environment.js +12 -0
- package/dist/src/index.js +122 -0
- package/dist/src/lint.js +3 -0
- package/dist/src/loader.js +25 -0
- package/dist/src/prisma.js +6 -0
- package/dist/src/types.js +0 -0
- package/dist/typecheck/index.d.ts +1 -0
- package/dist/typecheck/index.js +7 -0
- package/dist/typecheck/typecheck.d.ts +46 -0
- package/dist/types/all-types.d.ts +501 -0
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/config.d.ts +6 -0
- package/dist/types/docker.d.ts +15 -0
- package/dist/types/environment.d.ts +8 -0
- package/dist/types/hooks.d.ts +9 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +0 -0
- package/dist/types/prisma.d.ts +1 -0
- package/dist/types.d.ts +1 -393
- package/package.json +145 -140
- package/readme.md +358 -105
- package/src/cli/bin.ts +77 -0
- package/src/cli/commands/help.ts +39 -0
- package/src/cli/commands/runtime.ts +72 -0
- package/src/cli/commands/version.ts +4 -0
- package/src/cli/index.ts +1 -0
- package/{cli.ts → src/cli/run-cli.ts} +95 -6
- package/src/config/define-config.ts +30 -0
- package/src/config/index.ts +3 -0
- package/src/config/merge-configs.ts +33 -0
- package/src/config/validate-config.ts +136 -0
- package/{core → src/core}/index.ts +2 -2
- package/{core → src/core}/ports.ts +68 -1
- package/{core → src/core}/process.ts +6 -2
- package/src/core/tunnel.ts +151 -0
- package/{core → src/core}/utils.ts +1 -0
- package/{core → src/core}/watchdog.ts +5 -1
- package/src/docker/index.ts +1 -0
- package/{core/docker.ts → src/docker/runtime.ts} +40 -4
- package/src/docker-compose/generated-file.ts +45 -0
- package/src/docker-compose/index.ts +7 -0
- package/src/docker-compose/model.ts +197 -0
- package/src/docker-compose/services/clickhouse.ts +79 -0
- package/src/docker-compose/services/define-docker-service.ts +109 -0
- package/src/docker-compose/services/index.ts +67 -0
- package/src/docker-compose/services/postgres.ts +60 -0
- package/src/docker-compose/services/redis.ts +48 -0
- package/src/docker-compose/services/shared.ts +79 -0
- package/src/docker-compose/yaml.ts +88 -0
- package/{environment.ts → src/environment/create-dev-environment.ts} +101 -146
- package/src/environment/index.ts +1 -0
- package/src/environment/logging.ts +101 -0
- package/src/environment/seeding.ts +57 -0
- package/{index.ts → src/index.ts} +49 -15
- package/src/loader/cache.ts +23 -0
- package/src/loader/find-config-file.ts +29 -0
- package/src/loader/index.ts +17 -0
- package/src/loader/load-dev-env.ts +38 -0
- package/src/prisma/index.ts +1 -0
- package/{prisma.ts → src/prisma/prisma.ts} +4 -2
- package/src/typecheck/index.ts +1 -0
- package/{types.ts → src/types/all-types.ts} +137 -6
- package/src/types/index.ts +1 -0
- package/bin.ts +0 -191
- package/config.ts +0 -194
- package/loader.ts +0 -126
- /package/{core → src/core}/network.ts +0 -0
- /package/{core → src/core}/watchdog-runner.ts +0 -0
- /package/{lint.ts → src/typecheck/typecheck.ts} +0 -0
package/readme.md
CHANGED
|
@@ -1,144 +1,280 @@
|
|
|
1
1
|
# Buncargo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Bun-first development environment toolkit that eliminates the friction of local dev setup. Define your entire dev stack in a single typed config file—Docker services, app servers, environment variables, migrations, and more.
|
|
4
|
+
|
|
5
|
+
## Why Buncargo?
|
|
6
|
+
|
|
7
|
+
**The problem**: Local development environments are fragile. Teams maintain separate `docker-compose.yml` files, scatter port assignments across `.env` files, manually manage container lifecycles, and struggle with port conflicts when working on multiple branches.
|
|
8
|
+
|
|
9
|
+
**The solution**: Buncargo provides a single source of truth for your dev environment. One `dev.config.ts` file defines everything. Type-safe. Auto-generated Docker Compose. Worktree-aware port isolation. Zero configuration drift.
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- **Single config file** — Define services, apps, ports, URLs, migrations, and hooks in one typed `dev.config.ts`
|
|
14
|
+
- **Auto-generated Docker Compose** — No manual compose files; buncargo generates them from your config
|
|
15
|
+
- **Worktree isolation** — Each git worktree gets unique ports and isolated containers automatically
|
|
16
|
+
- **Built-in service presets** — One-liner setup for Postgres, Redis, ClickHouse with health checks and URL templates
|
|
17
|
+
- **Custom service support** — Full Docker Compose escape hatch for any service
|
|
18
|
+
- **Dev server orchestration** — Start and monitor multiple app servers with health checks
|
|
19
|
+
- **Public tunnels** — Expose services via Cloudflare Quick Tunnels for webhook testing and mobile dev
|
|
20
|
+
- **Prisma integration** — Run Prisma commands with auto-injected `DATABASE_URL`
|
|
21
|
+
- **Lifecycle hooks** — Run migrations, seeders, or custom scripts at the right time
|
|
22
|
+
- **Programmatic API** — Access ports/URLs in tests or scripts
|
|
23
|
+
- **Watchdog auto-shutdown** — Containers stop automatically after inactivity
|
|
4
24
|
|
|
5
25
|
## Quick Start
|
|
6
26
|
|
|
7
|
-
### 1.
|
|
27
|
+
### 1. Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bun add -d buncargo
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Create `dev.config.ts`
|
|
8
34
|
|
|
9
35
|
```typescript
|
|
10
|
-
import { defineDevConfig } from 'buncargo'
|
|
36
|
+
import { defineDevConfig, service } from 'buncargo'
|
|
11
37
|
|
|
12
38
|
export default defineDevConfig({
|
|
13
39
|
projectPrefix: 'myapp',
|
|
14
40
|
|
|
15
41
|
services: {
|
|
16
|
-
postgres: {
|
|
17
|
-
|
|
18
|
-
healthCheck: 'pg_isready',
|
|
19
|
-
urlTemplate: ({ port }) => `postgresql://postgres:postgres@localhost:${port}/mydb`
|
|
20
|
-
},
|
|
21
|
-
redis: {
|
|
22
|
-
port: 6379,
|
|
23
|
-
healthCheck: 'redis-cli'
|
|
24
|
-
}
|
|
42
|
+
postgres: service.postgres({ database: 'mydb' }),
|
|
43
|
+
redis: service.redis(),
|
|
25
44
|
},
|
|
26
45
|
|
|
27
46
|
apps: {
|
|
28
47
|
api: {
|
|
29
48
|
port: 3000,
|
|
30
49
|
devCommand: 'bun run dev',
|
|
31
|
-
cwd: 'apps/backend'
|
|
50
|
+
cwd: 'apps/backend',
|
|
32
51
|
},
|
|
33
52
|
web: {
|
|
34
53
|
port: 5173,
|
|
35
54
|
devCommand: 'bun run dev',
|
|
36
|
-
cwd: 'apps/frontend'
|
|
37
|
-
}
|
|
55
|
+
cwd: 'apps/frontend',
|
|
56
|
+
},
|
|
38
57
|
},
|
|
39
58
|
|
|
40
59
|
envVars: (ports, urls) => ({
|
|
41
60
|
DATABASE_URL: urls.postgres,
|
|
42
61
|
REDIS_URL: urls.redis,
|
|
43
|
-
API_PORT: ports.api
|
|
62
|
+
API_PORT: ports.api,
|
|
44
63
|
}),
|
|
45
|
-
|
|
46
|
-
hooks: {
|
|
47
|
-
afterContainersReady: async (ctx) => {
|
|
48
|
-
await ctx.exec('bunx prisma migrate deploy', { cwd: 'packages/prisma' })
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
prisma: {
|
|
53
|
-
cwd: 'packages/prisma'
|
|
54
|
-
}
|
|
55
64
|
})
|
|
56
65
|
```
|
|
57
66
|
|
|
58
|
-
###
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
bunx buncargo dev # Start containers + dev servers
|
|
62
|
-
bunx buncargo dev --up-only # Start containers only
|
|
63
|
-
bunx buncargo dev --down # Stop containers
|
|
64
|
-
bunx buncargo dev --reset # Stop and remove volumes
|
|
65
|
-
bunx buncargo typecheck # Run TypeScript typecheck across workspaces
|
|
66
|
-
bunx buncargo prisma studio # Run prisma with correct DATABASE_URL
|
|
67
|
-
bunx buncargo env # Print ports/urls as JSON
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Or add scripts to `package.json`:
|
|
67
|
+
### 3. Add scripts to `package.json`
|
|
71
68
|
|
|
72
69
|
```json
|
|
73
70
|
{
|
|
74
71
|
"scripts": {
|
|
75
72
|
"dev": "bunx buncargo dev",
|
|
76
|
-
"dev:
|
|
77
|
-
"
|
|
73
|
+
"dev:up": "bunx buncargo dev --up-only",
|
|
74
|
+
"dev:down": "bunx buncargo dev --down",
|
|
75
|
+
"dev:reset": "bunx buncargo dev --reset",
|
|
76
|
+
"dev:expose": "bunx buncargo dev --expose",
|
|
78
77
|
"prisma": "bunx buncargo prisma"
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
80
|
```
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
### 4. Run
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
bun run dev
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Buncargo will:
|
|
89
|
+
1. Generate a Docker Compose file from your config
|
|
90
|
+
2. Start all containers and wait for health checks
|
|
91
|
+
3. Run any configured migrations
|
|
92
|
+
4. Start your dev servers
|
|
93
|
+
5. Print all ports and URLs
|
|
94
|
+
|
|
95
|
+
## CLI Commands
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
bunx buncargo dev # Start containers + dev servers
|
|
99
|
+
bunx buncargo dev --up-only # Start containers only (no dev servers)
|
|
100
|
+
bunx buncargo dev --down # Stop containers
|
|
101
|
+
bunx buncargo dev --reset # Stop containers and remove volumes
|
|
102
|
+
bunx buncargo dev --expose # Start with public tunnels for expose:true targets
|
|
103
|
+
bunx buncargo dev --expose=api # Expose specific targets
|
|
104
|
+
bunx buncargo dev --migrate # Run migrations only
|
|
105
|
+
bunx buncargo dev --seed # Run migrations and seeders
|
|
106
|
+
bunx buncargo prisma <args> # Run Prisma CLI with correct DATABASE_URL
|
|
107
|
+
bunx buncargo typecheck # Run TypeScript typecheck across workspaces
|
|
108
|
+
bunx buncargo env # Print ports/URLs as JSON
|
|
109
|
+
bunx buncargo help # Show help
|
|
110
|
+
bunx buncargo version # Show version
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Services
|
|
84
114
|
|
|
85
|
-
|
|
115
|
+
### Built-in Presets
|
|
116
|
+
|
|
117
|
+
Use `service.*` helpers for common databases with sensible defaults:
|
|
86
118
|
|
|
87
119
|
```typescript
|
|
88
|
-
|
|
120
|
+
services: {
|
|
121
|
+
postgres: service.postgres({ database: 'mydb' }),
|
|
122
|
+
redis: service.redis(),
|
|
123
|
+
clickhouse: service.clickhouse({ database: 'analytics' }),
|
|
124
|
+
}
|
|
125
|
+
```
|
|
89
126
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
127
|
+
Each preset includes:
|
|
128
|
+
- Default Docker image
|
|
129
|
+
- Health check configuration
|
|
130
|
+
- URL template (e.g., `postgresql://postgres:postgres@localhost:5432/mydb`)
|
|
131
|
+
- Volume for data persistence
|
|
132
|
+
|
|
133
|
+
### Custom Services
|
|
134
|
+
|
|
135
|
+
Use `service.custom()` for any Docker service:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
services: {
|
|
139
|
+
rabbitmq: service.custom({
|
|
140
|
+
port: 5672,
|
|
141
|
+
healthCheck: false,
|
|
142
|
+
docker: {
|
|
143
|
+
image: 'rabbitmq:3-management-alpine',
|
|
144
|
+
ports: ['${RABBITMQ_PORT:-5672}:5672', '15672:15672'],
|
|
145
|
+
environment: {
|
|
146
|
+
RABBITMQ_DEFAULT_USER: 'guest',
|
|
147
|
+
RABBITMQ_DEFAULT_PASS: 'guest',
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
}),
|
|
151
|
+
nats: service.custom({
|
|
152
|
+
port: 4222,
|
|
153
|
+
docker: {
|
|
154
|
+
image: 'nats:2-alpine',
|
|
155
|
+
ports: ['${NATS_PORT:-4222}:4222'],
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Apps
|
|
162
|
+
|
|
163
|
+
Define dev servers to run alongside containers:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
apps: {
|
|
167
|
+
api: {
|
|
168
|
+
port: 3000,
|
|
169
|
+
devCommand: 'bun run dev',
|
|
170
|
+
cwd: 'apps/backend',
|
|
171
|
+
healthEndpoint: '/health',
|
|
172
|
+
},
|
|
173
|
+
web: {
|
|
174
|
+
port: 5173,
|
|
175
|
+
devCommand: 'bun run dev',
|
|
176
|
+
cwd: 'apps/frontend',
|
|
177
|
+
healthEndpoint: '/',
|
|
178
|
+
},
|
|
179
|
+
}
|
|
94
180
|
```
|
|
95
181
|
|
|
96
|
-
##
|
|
182
|
+
## Environment Variables
|
|
97
183
|
|
|
98
|
-
|
|
184
|
+
The `envVars` function builds all env vars from computed ports and URLs:
|
|
99
185
|
|
|
100
|
-
|
|
186
|
+
```typescript
|
|
187
|
+
envVars: (ports, urls, { localIp, publicUrls }) => ({
|
|
188
|
+
DATABASE_URL: urls.postgres,
|
|
189
|
+
REDIS_URL: urls.redis,
|
|
190
|
+
API_PORT: ports.api,
|
|
191
|
+
EXPO_API_URL: `http://${localIp}:${ports.api}`,
|
|
192
|
+
WEBHOOK_URL: publicUrls.api ?? urls.api,
|
|
193
|
+
})
|
|
194
|
+
```
|
|
101
195
|
|
|
102
|
-
|
|
196
|
+
These are injected into:
|
|
197
|
+
- Docker Compose services
|
|
198
|
+
- Dev server processes
|
|
199
|
+
- Hook `exec()` calls
|
|
200
|
+
- Prisma commands
|
|
103
201
|
|
|
104
|
-
|
|
202
|
+
## Worktree Isolation
|
|
105
203
|
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
204
|
+
When working in git worktrees, buncargo automatically assigns unique port offsets (10-99) so each worktree has isolated:
|
|
205
|
+
- Ports (e.g., postgres on 5442 instead of 5432)
|
|
206
|
+
- Docker Compose project names
|
|
207
|
+
- Containers, networks, and volumes
|
|
110
208
|
|
|
111
|
-
|
|
209
|
+
This means you can run multiple branches simultaneously without conflicts.
|
|
112
210
|
|
|
113
|
-
|
|
211
|
+
To disable isolation and share state across worktrees:
|
|
114
212
|
|
|
115
213
|
```typescript
|
|
116
|
-
|
|
117
|
-
|
|
214
|
+
options: {
|
|
215
|
+
worktreeIsolation: false
|
|
216
|
+
}
|
|
118
217
|
```
|
|
119
218
|
|
|
120
|
-
|
|
219
|
+
## Public Tunnels
|
|
121
220
|
|
|
122
|
-
|
|
221
|
+
Expose local services to the internet using Cloudflare Quick Tunnels:
|
|
123
222
|
|
|
124
223
|
```typescript
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
224
|
+
services: {
|
|
225
|
+
postgres: service.postgres({ database: 'mydb' }),
|
|
226
|
+
},
|
|
227
|
+
apps: {
|
|
228
|
+
api: {
|
|
229
|
+
port: 3000,
|
|
230
|
+
devCommand: 'bun run dev',
|
|
231
|
+
expose: true, // Mark as exposable
|
|
232
|
+
},
|
|
130
233
|
}
|
|
131
234
|
```
|
|
132
235
|
|
|
133
|
-
|
|
236
|
+
```bash
|
|
237
|
+
bun run dev --expose # Expose all targets with expose: true
|
|
238
|
+
bun run dev --expose=api # Expose specific targets
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Public URLs are printed in the console and available via `publicUrls` in `envVars`:
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
envVars: (_ports, urls, { publicUrls }) => ({
|
|
245
|
+
WEBHOOK_URL: publicUrls.api ?? urls.api,
|
|
246
|
+
})
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Lifecycle Hooks
|
|
250
|
+
|
|
251
|
+
Run code at specific points in the startup/shutdown cycle:
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
hooks: {
|
|
255
|
+
afterContainersReady: async (ctx) => {
|
|
256
|
+
await ctx.exec('bunx prisma migrate deploy', { cwd: 'packages/prisma' })
|
|
257
|
+
},
|
|
258
|
+
beforeServers: async (ctx) => {
|
|
259
|
+
await ctx.exec('bun run seed')
|
|
260
|
+
},
|
|
261
|
+
afterServers: async (ctx) => {
|
|
262
|
+
console.log(`API running at ${ctx.urls.api}`)
|
|
263
|
+
},
|
|
264
|
+
beforeStop: async (ctx) => {
|
|
265
|
+
await ctx.exec('bun run cleanup', { throwOnError: false })
|
|
266
|
+
},
|
|
267
|
+
}
|
|
268
|
+
```
|
|
134
269
|
|
|
135
|
-
|
|
270
|
+
Hook context provides:
|
|
136
271
|
|
|
137
272
|
```typescript
|
|
138
273
|
interface HookContext {
|
|
139
274
|
projectName: string
|
|
140
275
|
ports: { postgres: number, api: number, ... }
|
|
141
276
|
urls: { postgres: string, api: string, ... }
|
|
277
|
+
publicUrls: { api?: string, ... }
|
|
142
278
|
root: string
|
|
143
279
|
isCI: boolean
|
|
144
280
|
portOffset: number
|
|
@@ -147,54 +283,171 @@ interface HookContext {
|
|
|
147
283
|
}
|
|
148
284
|
```
|
|
149
285
|
|
|
150
|
-
|
|
286
|
+
## Migrations and Seeding
|
|
151
287
|
|
|
152
|
-
|
|
288
|
+
### Migrations
|
|
153
289
|
|
|
154
|
-
|
|
290
|
+
Run migration commands after containers are healthy:
|
|
155
291
|
|
|
292
|
+
```typescript
|
|
293
|
+
migrations: [
|
|
294
|
+
{ name: 'prisma', command: 'bunx prisma migrate deploy', cwd: 'packages/prisma' },
|
|
295
|
+
{ name: 'clickhouse', command: 'bun run migrate:clickhouse' },
|
|
296
|
+
]
|
|
156
297
|
```
|
|
157
|
-
COMMANDS:
|
|
158
|
-
dev Start the development environment
|
|
159
|
-
typecheck Run TypeScript typecheck across workspaces
|
|
160
|
-
prisma <args> Run Prisma CLI with correct DATABASE_URL
|
|
161
|
-
env Print environment info as JSON
|
|
162
|
-
help Show help
|
|
163
|
-
version Show version
|
|
164
298
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
299
|
+
### Seeding
|
|
300
|
+
|
|
301
|
+
Seed the database with a check to avoid re-seeding:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
seed: {
|
|
305
|
+
command: 'bun run seed',
|
|
306
|
+
check: ({ checkTable }) => checkTable('User', 'postgres'),
|
|
307
|
+
}
|
|
171
308
|
```
|
|
172
309
|
|
|
173
|
-
##
|
|
310
|
+
## Prisma Integration
|
|
174
311
|
|
|
175
|
-
|
|
312
|
+
Configure Prisma to use the correct database URL:
|
|
176
313
|
|
|
177
314
|
```typescript
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
315
|
+
prisma: {
|
|
316
|
+
cwd: 'packages/prisma',
|
|
317
|
+
service: 'postgres', // Default: 'postgres'
|
|
318
|
+
urlEnvVar: 'DATABASE_URL', // Default: 'DATABASE_URL'
|
|
319
|
+
}
|
|
183
320
|
```
|
|
184
321
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
322
|
+
Then run Prisma commands through buncargo:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
bun run prisma migrate dev
|
|
326
|
+
bun run prisma studio
|
|
327
|
+
bun run prisma db push
|
|
328
|
+
```
|
|
189
329
|
|
|
190
|
-
|
|
330
|
+
Buncargo ensures the database container is running and injects the correct `DATABASE_URL` with worktree-aware ports.
|
|
191
331
|
|
|
192
|
-
|
|
332
|
+
## Programmatic API
|
|
193
333
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
334
|
+
Access the dev environment from code (useful for tests):
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
import { loadDevEnv } from 'buncargo'
|
|
338
|
+
|
|
339
|
+
const env = await loadDevEnv()
|
|
340
|
+
|
|
341
|
+
console.log(env.ports.postgres) // 5432 (or offset port)
|
|
342
|
+
console.log(env.urls.api) // http://localhost:3000
|
|
343
|
+
console.log(env.urls.postgres) // postgresql://postgres:postgres@localhost:5432/mydb
|
|
344
|
+
|
|
345
|
+
// Start/stop programmatically
|
|
346
|
+
await env.start()
|
|
347
|
+
await env.stop({ removeVolumes: true })
|
|
348
|
+
|
|
349
|
+
// Build env vars for subprocess
|
|
350
|
+
const envVars = env.buildEnvVars()
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Docker Compose Generation
|
|
354
|
+
|
|
355
|
+
Buncargo generates Docker Compose from your config. No external `docker-compose.yml` is read.
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
docker: {
|
|
359
|
+
generatedFile: '.buncargo/docker-compose.generated.yml',
|
|
360
|
+
writeStrategy: 'always', // or 'if-missing'
|
|
361
|
+
volumes: {
|
|
362
|
+
shared_cache: {},
|
|
363
|
+
},
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Health Checks
|
|
368
|
+
|
|
369
|
+
Built-in health check types:
|
|
370
|
+
|
|
371
|
+
| Type | Description |
|
|
372
|
+
|------|-------------|
|
|
373
|
+
| `pg_isready` | PostgreSQL readiness check |
|
|
374
|
+
| `redis-cli` | Redis PING check |
|
|
375
|
+
| `http` | HTTP endpoint check |
|
|
376
|
+
| `tcp` | TCP port check |
|
|
377
|
+
|
|
378
|
+
Or provide a custom health check function:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
healthCheck: async (port) => {
|
|
382
|
+
const res = await fetch(`http://localhost:${port}/health`)
|
|
383
|
+
return res.ok
|
|
384
|
+
}
|
|
200
385
|
```
|
|
386
|
+
|
|
387
|
+
## Watchdog Auto-Shutdown
|
|
388
|
+
|
|
389
|
+
When running via CLI, containers automatically stop after 10 minutes of inactivity. The watchdog monitors heartbeats and shuts down orphaned environments.
|
|
390
|
+
|
|
391
|
+
## Full Example
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
import { defineDevConfig, service } from 'buncargo'
|
|
395
|
+
|
|
396
|
+
export default defineDevConfig({
|
|
397
|
+
projectPrefix: 'platform',
|
|
398
|
+
|
|
399
|
+
services: {
|
|
400
|
+
postgres: service.postgres({ database: 'platform' }),
|
|
401
|
+
redis: service.redis(),
|
|
402
|
+
clickhouse: service.clickhouse({ database: 'platform' }),
|
|
403
|
+
},
|
|
404
|
+
|
|
405
|
+
apps: {
|
|
406
|
+
api: {
|
|
407
|
+
port: 3000,
|
|
408
|
+
expose: true,
|
|
409
|
+
devCommand: 'bun run dev',
|
|
410
|
+
cwd: 'apps/backend',
|
|
411
|
+
healthEndpoint: '/health',
|
|
412
|
+
},
|
|
413
|
+
web: {
|
|
414
|
+
port: 5173,
|
|
415
|
+
devCommand: 'bun run dev',
|
|
416
|
+
cwd: 'apps/frontend',
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
envVars: (ports, urls, { localIp, publicUrls }) => ({
|
|
421
|
+
DATABASE_URL: urls.postgres,
|
|
422
|
+
REDIS_URL: urls.redis,
|
|
423
|
+
CLICKHOUSE_URL: urls.clickhouse,
|
|
424
|
+
API_URL: urls.api,
|
|
425
|
+
VITE_API_URL: urls.api,
|
|
426
|
+
EXPO_API_URL: `http://${localIp}:${ports.api}`,
|
|
427
|
+
WEBHOOK_URL: publicUrls.api ?? urls.api,
|
|
428
|
+
}),
|
|
429
|
+
|
|
430
|
+
migrations: [
|
|
431
|
+
{ name: 'prisma', command: 'bunx prisma migrate deploy', cwd: 'packages/prisma' },
|
|
432
|
+
],
|
|
433
|
+
|
|
434
|
+
seed: {
|
|
435
|
+
command: 'bun run seed',
|
|
436
|
+
check: ({ checkTable }) => checkTable('User', 'postgres'),
|
|
437
|
+
},
|
|
438
|
+
|
|
439
|
+
prisma: {
|
|
440
|
+
cwd: 'packages/prisma',
|
|
441
|
+
},
|
|
442
|
+
|
|
443
|
+
hooks: {
|
|
444
|
+
afterContainersReady: async (ctx) => {
|
|
445
|
+
console.log(`Containers ready on port offset ${ctx.portOffset}`)
|
|
446
|
+
},
|
|
447
|
+
},
|
|
448
|
+
})
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## License
|
|
452
|
+
|
|
453
|
+
MIT
|
package/src/cli/bin.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CLI Entry Point for buncargo
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* bunx buncargo dev # Start containers + dev servers
|
|
8
|
+
* bunx buncargo dev --down # Stop containers
|
|
9
|
+
* bunx buncargo dev --reset # Stop + remove volumes
|
|
10
|
+
* bunx buncargo typecheck # Run TypeScript typecheck
|
|
11
|
+
* bunx buncargo prisma ... # Run prisma commands
|
|
12
|
+
* bunx buncargo help # Show help
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { showHelp } from "./commands/help";
|
|
16
|
+
import {
|
|
17
|
+
handleDev,
|
|
18
|
+
handleEnv,
|
|
19
|
+
handlePrisma,
|
|
20
|
+
handleTypecheck,
|
|
21
|
+
} from "./commands/runtime";
|
|
22
|
+
import { showVersion } from "./commands/version";
|
|
23
|
+
|
|
24
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
25
|
+
// Main
|
|
26
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
27
|
+
|
|
28
|
+
async function main(): Promise<void> {
|
|
29
|
+
const args = process.argv.slice(2);
|
|
30
|
+
const command = args[0];
|
|
31
|
+
const commandArgs = args.slice(1);
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
!command ||
|
|
35
|
+
command === "help" ||
|
|
36
|
+
command === "--help" ||
|
|
37
|
+
command === "-h"
|
|
38
|
+
) {
|
|
39
|
+
showHelp();
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (command === "version" || command === "--version" || command === "-v") {
|
|
44
|
+
showVersion();
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
switch (command) {
|
|
49
|
+
case "dev":
|
|
50
|
+
await handleDev(commandArgs);
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
case "typecheck":
|
|
54
|
+
await handleTypecheck();
|
|
55
|
+
break;
|
|
56
|
+
|
|
57
|
+
case "prisma":
|
|
58
|
+
await handlePrisma(commandArgs);
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case "env":
|
|
62
|
+
await handleEnv();
|
|
63
|
+
break;
|
|
64
|
+
|
|
65
|
+
default:
|
|
66
|
+
console.error(`❌ Unknown command: ${command}`);
|
|
67
|
+
console.error("");
|
|
68
|
+
console.error(' Run "bunx buncargo help" for available commands.');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
main().catch((error) => {
|
|
74
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
75
|
+
console.error(`❌ ${message}`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function showHelp(): void {
|
|
2
|
+
console.log(`
|
|
3
|
+
buncargo - Development environment CLI
|
|
4
|
+
|
|
5
|
+
USAGE:
|
|
6
|
+
bunx buncargo <command> [options]
|
|
7
|
+
|
|
8
|
+
COMMANDS:
|
|
9
|
+
dev Start the development environment
|
|
10
|
+
typecheck Run TypeScript typecheck across workspaces
|
|
11
|
+
prisma <args> Run Prisma CLI with correct DATABASE_URL
|
|
12
|
+
env Print environment info as JSON
|
|
13
|
+
help Show this help message
|
|
14
|
+
version Show version
|
|
15
|
+
|
|
16
|
+
EXAMPLES:
|
|
17
|
+
bunx buncargo dev # Start everything
|
|
18
|
+
bunx buncargo dev --expose # Public quick tunnel for expose:true targets
|
|
19
|
+
bunx buncargo dev --expose=api # Public quick tunnel for selected target
|
|
20
|
+
bunx buncargo dev --help # Show dev command options
|
|
21
|
+
bunx buncargo dev --down # Stop containers
|
|
22
|
+
bunx buncargo typecheck # Run typecheck
|
|
23
|
+
bunx buncargo prisma studio # Open Prisma Studio
|
|
24
|
+
bunx buncargo env # Get ports/urls as JSON
|
|
25
|
+
|
|
26
|
+
CONFIG:
|
|
27
|
+
Create a dev.config.ts with a default export:
|
|
28
|
+
|
|
29
|
+
import { defineDevConfig } from 'buncargo'
|
|
30
|
+
|
|
31
|
+
export default defineDevConfig({
|
|
32
|
+
projectPrefix: 'myapp',
|
|
33
|
+
services: { ... },
|
|
34
|
+
apps: { ... }
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
Run "bunx buncargo dev --help" for dev command options.
|
|
38
|
+
`);
|
|
39
|
+
}
|