Skip to content

Commit becb708

Browse files
committed
chore: wip
1 parent 23f705a commit becb708

File tree

11 files changed

+407
-55
lines changed

11 files changed

+407
-55
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,23 @@ launchpad service enable postgres redis
283283
- **API & Backend**: Hasura, Keycloak
284284
- **Caching**: Memcached, Elasticsearch
285285

286+
#### Configure services in deps.yaml
287+
288+
Add services to your dependency file to auto-start when the project environment activates:
289+
290+
```yaml
291+
# deps.yaml
292+
dependencies:
293+
- node@22
294+
- postgresql@15
295+
296+
services:
297+
enabled: true
298+
autoStart:
299+
- postgres
300+
- redis
301+
```
302+
286303
#### Database Configuration
287304
288305
Customize database credentials for all database services:

docs/api/reference.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,71 @@ await dump('/path/to/project', { dryrun: false, quiet: false })
543543
// - Install [email protected] globally (individual flag)
544544
```
545545

546+
### Services in dependencies.yaml
547+
548+
Launchpad can read a `services` section from your dependency file to automatically start services on environment activation.
549+
550+
```yaml
551+
# deps.yaml
552+
dependencies:
553+
bun: ^1.2.19
554+
node: ^22.17.0
555+
php: ^8.4.11
556+
composer: ^2.8.10
557+
postgres: ^17.2.0
558+
redis: ^8.0.4
559+
560+
services:
561+
enabled: true
562+
autoStart:
563+
- postgres
564+
- redis
565+
```
566+
567+
At runtime, the environment generator detects `services.enabled` and starts each service in `autoStart`.
568+
569+
#### Inference shorthand
570+
571+
For Stacks & Laravel projects, you can also use a shorthand to infer services from `.env`:
572+
573+
```yaml
574+
# deps.yaml
575+
dependencies:
576+
php: ^8.4.11
577+
postgres: ^17.2.0
578+
redis: ^8.0.4
579+
580+
services:
581+
infer: true
582+
```
583+
584+
This will auto-start services based on `.env` (e.g., `DB_CONNECTION=pgsql` and `CACHE_DRIVER=redis``postgres` and `redis`).
585+
586+
Project-level post-setup commands can be configured via top-level `postSetup` in `launchpad.config.ts`:
587+
588+
```ts
589+
// launchpad.config.ts
590+
import type { LaunchpadConfig } from '@stacksjs/launchpad'
591+
592+
const config: LaunchpadConfig = {
593+
postSetup: {
594+
enabled: true,
595+
commands: [
596+
{
597+
name: 'migrate',
598+
command: 'php artisan migrate',
599+
description: 'Run database migrations',
600+
condition: 'hasUnrunMigrations',
601+
runInBackground: false,
602+
required: false,
603+
},
604+
],
605+
},
606+
}
607+
608+
export default config
609+
```
610+
546611
### Global Flag Resolution Examples
547612

548613
```typescript

docs/config.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,58 @@ dependencies:
338338

339339
This ensures that essential tools like shells, package managers, and system utilities are preserved during cleanup operations, preventing system breakage.
340340

341+
### Service Management in dependencies.yaml
342+
343+
Define services that should automatically start for your project:
344+
345+
```yaml
346+
# deps.yaml
347+
dependencies:
348+
bun: ^1.2.19
349+
node: ^22.17.0
350+
php: ^8.4.11
351+
composer: ^2.8.10
352+
postgres: ^17.2.0
353+
redis: ^8.0.4
354+
355+
services:
356+
enabled: true
357+
autoStart:
358+
- postgres
359+
- redis
360+
```
361+
362+
Behavior:
363+
- **enabled**: toggles service management for the project.
364+
- **autoStart**: array of service names to start automatically on environment activation.
365+
- Service names must match those in the Supported Services list (e.g. `postgres`, `redis`, `nginx`).
366+
367+
#### Inference shorthand
368+
369+
You can enable a shorthand for framework-based projects (e.g., Laravel) to infer services automatically:
370+
371+
```yaml
372+
# deps.yaml
373+
dependencies:
374+
php: ^8.4.11
375+
postgres: ^17.2.0
376+
redis: ^8.0.4
377+
378+
services:
379+
infer: true
380+
```
381+
382+
When enabled and a Laravel app is detected (`artisan` present), Launchpad will read `.env` and infer services:
383+
- `DB_CONNECTION=pgsql` → `postgres`
384+
- `DB_CONNECTION=mysql|mariadb` → `mysql`
385+
- `CACHE_DRIVER=redis` or `CACHE_STORE=redis` → `redis`
386+
- `CACHE_DRIVER=memcached` or `CACHE_STORE=memcached` → `memcached`
387+
388+
Environment toggles:
389+
- `LAUNCHPAD_FRAMEWORKS_ENABLED` (default: true)
390+
- `LAUNCHPAD_SERVICES_INFER` (default: true)
391+
- `LAUNCHPAD_LARAVEL_ENABLED` (default: true)
392+
341393
## Configuration Options
342394

343395
### General Options
@@ -391,6 +443,34 @@ This ensures that essential tools like shells, package managers, and system util
391443
| `services.autoRestart` | boolean | `true` | Auto-restart failed services |
392444
| `services.startupTimeout` | number | `30` | Service startup timeout in seconds |
393445
| `services.shutdownTimeout` | number | `10` | Service shutdown timeout in seconds |
446+
| `services.infer` | boolean | `true` | Derive services to auto-start from framework configuration |
447+
448+
### Post-Setup Commands
449+
450+
Configure commands to run after the environment is prepared (independent of services):
451+
452+
```ts
453+
// launchpad.config.ts
454+
import type { LaunchpadConfig } from '@stacksjs/launchpad'
455+
456+
const config: LaunchpadConfig = {
457+
postSetup: {
458+
enabled: true,
459+
commands: [
460+
{
461+
name: 'migrate',
462+
command: 'php artisan migrate',
463+
description: 'Run database migrations',
464+
condition: 'hasUnrunMigrations',
465+
runInBackground: false,
466+
required: false,
467+
},
468+
],
469+
},
470+
}
471+
472+
export default config
473+
```
394474

395475
## Environment Variables
396476

docs/examples.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -838,9 +838,11 @@ dependencies:
838838
839839
840840
services:
841-
- postgres
842-
- redis
843-
- nginx
841+
enabled: true
842+
autoStart:
843+
- postgres
844+
- redis
845+
- nginx
844846
845847
env:
846848
DATABASE_URL: postgresql://localhost:5432/myapp

docs/features/service-management.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,53 @@ launchpad service list
3535
launchpad service restart redis
3636
```
3737

38+
## Configure Services in dependencies.yaml
39+
40+
You can declare services in your project `deps.yaml`/`dependencies.yaml` to auto-start when your environment activates:
41+
42+
```yaml
43+
# deps.yaml
44+
dependencies:
45+
bun: ^1.2.19
46+
node: ^22.17.0
47+
php: ^8.4.11
48+
composer: ^2.8.10
49+
postgres: ^17.2.0
50+
redis: ^8.0.4
51+
52+
services:
53+
enabled: true
54+
autoStart:
55+
- postgres
56+
- redis
57+
```
58+
59+
### Shorthand: services.infer: true
60+
61+
For Stacks & Laravel projects, you can enable a shorthand that auto-detects DB & cache from your `.env` and auto-starts the right services:
62+
63+
```yaml
64+
# deps.yaml
65+
dependencies:
66+
php: ^8.4.11
67+
postgres: ^17.2.0
68+
redis: ^8.0.4
69+
70+
# Shorthand that infers services from Stacks/Laravel .env
71+
services:
72+
infer: true
73+
```
74+
75+
Behavior:
76+
- Reads `DB_CONNECTION` and `CACHE_DRIVER` or `CACHE_STORE` from `.env` when a Stacks or Laravel app is detected (`buddy` or `artisan` present).
77+
- Maps to services: `pgsql` → `postgres`, `mysql`/`mariadb` → `mysql`, `redis` → `redis`, `memcached` → `memcached`.
78+
- Equivalent to specifying `services.enabled: true` with an `autoStart` list of detected services.
79+
- Can be disabled via env: set `LAUNCHPAD_AUTO_START_FROM_FRAMEWORK=false`.
80+
81+
Notes:
82+
- **services.enabled**: turn service management on for the project.
83+
- **services.autoStart**: list of services to start automatically (supported values are listed below in Available Services). These start when the environment activates (e.g. upon `cd` into the project with shell integration).
84+
3885
## Available Services
3986

4087
Launchpad includes pre-configured definitions for these services:
@@ -699,14 +746,16 @@ Services are automatically initialized on first start:
699746
Service management integrates well with project environments:
700747

701748
```yaml
702-
# dependencies.yaml
749+
# deps.yaml
703750
dependencies:
704751
- node@22
705752
- postgresql@15
706753
707754
services:
708-
- postgres
709-
- redis
755+
enabled: true
756+
autoStart:
757+
- postgres
758+
- redis
710759
711760
env:
712761
DATABASE_URL: postgresql://localhost:5432/myapp

packages/launchpad/src/config.ts

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ export const defaultConfig: LaunchpadConfig = {
5050
useRegistry: true,
5151
installMethod: 'curl',
5252
installPath: getDefaultInstallPath(),
53+
postSetup: {
54+
enabled: process.env.LAUNCHPAD_POST_SETUP_ENABLED === 'true',
55+
commands: [],
56+
},
5357
services: {
5458
enabled: process.env.LAUNCHPAD_SERVICES_ENABLED !== 'false',
5559
dataDir: process.env.LAUNCHPAD_SERVICES_DATA_DIR || path.join(homedir(), '.local', 'share', 'launchpad', 'services'),
@@ -58,6 +62,7 @@ export const defaultConfig: LaunchpadConfig = {
5862
autoRestart: process.env.LAUNCHPAD_SERVICES_AUTO_RESTART !== 'false',
5963
startupTimeout: Number.parseInt(process.env.LAUNCHPAD_SERVICES_STARTUP_TIMEOUT || '30', 10),
6064
shutdownTimeout: Number.parseInt(process.env.LAUNCHPAD_SERVICES_SHUTDOWN_TIMEOUT || '10', 10),
65+
infer: process.env.LAUNCHPAD_SERVICES_INFER !== 'false',
6166
database: {
6267
username: process.env.LAUNCHPAD_DB_USERNAME || 'root',
6368
password: process.env.LAUNCHPAD_DB_PASSWORD || 'password',
@@ -68,43 +73,6 @@ export const defaultConfig: LaunchpadConfig = {
6873
laravel: {
6974
enabled: process.env.LAUNCHPAD_LARAVEL_ENABLED !== 'false',
7075
autoDetect: process.env.LAUNCHPAD_LARAVEL_AUTO_DETECT !== 'false',
71-
postSetup: {
72-
enabled: process.env.LAUNCHPAD_LARAVEL_POST_SETUP !== 'false',
73-
commands: [
74-
{
75-
name: 'migrate',
76-
command: 'php artisan migrate',
77-
description: 'Run database migrations',
78-
condition: 'hasUnrunMigrations',
79-
runInBackground: false,
80-
required: false,
81-
},
82-
{
83-
name: 'seed',
84-
command: 'php artisan db:seed',
85-
description: 'Seed the database with sample data',
86-
condition: 'hasSeeders',
87-
runInBackground: false,
88-
required: false,
89-
},
90-
{
91-
name: 'storage-link',
92-
command: 'php artisan storage:link',
93-
description: 'Create symbolic link for storage',
94-
condition: 'needsStorageLink',
95-
runInBackground: false,
96-
required: false,
97-
},
98-
{
99-
name: 'optimize',
100-
command: 'php artisan optimize',
101-
description: 'Optimize Laravel for production',
102-
condition: 'isProduction',
103-
runInBackground: false,
104-
required: false,
105-
},
106-
],
107-
},
10876
},
10977
stacks: {
11078
enabled: process.env.LAUNCHPAD_STACKS_ENABLED !== 'false',

packages/launchpad/src/dev/dump.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ export async function detectLaravelProject(dir: string): Promise<{ isLaravel: bo
199199
// Ignore errors checking migrations
200200
}
201201

202-
// Execute post-setup commands if enabled (skip in shell integration; handled later with full env)
203-
const laravelConfig = config.services?.frameworks?.laravel
204-
if (laravelConfig?.postSetup?.enabled && process.env.LAUNCHPAD_SHELL_INTEGRATION !== '1') {
205-
const postSetupResults = await executepostSetup(dir, laravelConfig.postSetup.commands || [])
202+
// Execute project-level post-setup commands if enabled (skip in shell integration)
203+
const projectPostSetup = config.postSetup
204+
if (projectPostSetup?.enabled && process.env.LAUNCHPAD_SHELL_INTEGRATION !== '1') {
205+
const postSetupResults = await executepostSetup(dir, projectPostSetup.commands || [])
206206
suggestions.push(...postSetupResults)
207207
}
208208

@@ -1205,8 +1205,8 @@ async function createPhpShimsAfterInstall(envDir: string): Promise<void> {
12051205
*/
12061206
async function maybeRunLaravelPostSetup(projectDir: string, envDir: string, _isShellIntegration: boolean): Promise<void> {
12071207
try {
1208-
const laravelConfig = config.services?.frameworks?.laravel
1209-
if (!laravelConfig?.postSetup?.enabled) {
1208+
const projectPostSetup = config.postSetup
1209+
if (!projectPostSetup?.enabled) {
12101210
return
12111211
}
12121212

@@ -1225,7 +1225,7 @@ async function maybeRunLaravelPostSetup(projectDir: string, envDir: string, _isS
12251225
catch {}
12261226

12271227
// Execute and mark
1228-
const results = await executepostSetup(projectDir, laravelConfig.postSetup.commands || [])
1228+
const results = await executepostSetup(projectDir, projectPostSetup.commands || [])
12291229
if ((results && results.length > 0) || true) {
12301230
try {
12311231
fs.writeFileSync(markerFile, new Date().toISOString())

0 commit comments

Comments
 (0)