From abe005b403ee2d45e1b01fde9724fd15cd0c250e Mon Sep 17 00:00:00 2001 From: Jiayuan Zhang Date: Fri, 10 Apr 2026 13:51:07 +0800 Subject: [PATCH] feat(dx): add `make dev` one-command local setup Simplifies local development from 3+ commands to a single `make dev` that auto-detects environment (main/worktree), creates env files, installs dependencies, starts PostgreSQL, runs migrations, and launches both backend and frontend. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 9 ++++-- CONTRIBUTING.md | 77 ++++++++++++++++++++----------------------------- Makefile | 8 +++-- README.md | 18 +++++------- scripts/dev.sh | 65 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 60 deletions(-) create mode 100755 scripts/dev.sh diff --git a/CLAUDE.md b/CLAUDE.md index af294b5e3..2f11ee186 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,7 +57,10 @@ The architecture relies on a strict split between server state and client state. ## Commands ```bash -# One-click setup & run +# One-command dev (auto-setup + start everything) +make dev # Auto-creates env, installs deps, starts DB, migrates, launches app + +# Explicit setup & run (if you prefer separate steps) make setup # First-time: ensure shared DB, create app DB, migrate make start # Start backend + frontend together make stop # Stop app processes for the current checkout @@ -73,7 +76,7 @@ pnpm lint # ESLint pnpm test # TS tests (Vitest, all packages + apps via turbo) # Backend (Go) -make dev # Run Go server (port 8080) +make server # Run Go server only (port 8080) make daemon # Run local daemon make build # Build server + CLI binaries to server/bin/ make cli ARGS="..." # Run multica CLI (e.g. make cli ARGS="config") @@ -113,6 +116,8 @@ CI runs on Node 22 and Go 1.26.1 with a `pgvector/pgvector:pg17` PostgreSQL serv All checkouts share one PostgreSQL container. Isolation is at the database level — each worktree gets its own DB name and unique ports via `.env.worktree`. Main checkouts use `.env`. +`make dev` auto-detects worktrees and handles everything. For explicit control: + ```bash make worktree-env # Generate .env.worktree with unique DB/ports make setup-worktree # Setup using .env.worktree diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0b8006fb..9f9817147 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,59 +94,52 @@ FORCE=1 make worktree-env ## First-Time Setup -### Main Checkout +### Quick Start (recommended) -From the main checkout: +From any checkout (main or worktree): + +```bash +make dev +``` + +This single command: + +- auto-detects whether you're in a main checkout or a worktree +- creates the appropriate env file (`.env` or `.env.worktree`) if it doesn't exist +- checks that prerequisites (Node.js, pnpm, Go, Docker) are installed +- installs JavaScript dependencies +- ensures the shared PostgreSQL container is running +- creates the application database if it does not exist +- runs all migrations +- starts both backend and frontend + +### Explicit Setup (advanced) + +If you prefer separate control over setup and startup: + +#### Main Checkout ```bash cp .env.example .env make setup-main -``` - -What `make setup-main` does: - -- installs JavaScript dependencies with `pnpm install` -- ensures the shared PostgreSQL container is running -- creates the application database if it does not exist -- runs all migrations against that database - -Start the app: - -```bash make start-main ``` -Stop the app processes: +Stop: ```bash make stop-main ``` -This does not stop PostgreSQL. - -### Worktree - -From the worktree directory: +#### Worktree ```bash make worktree-env make setup-worktree -``` - -What `make setup-worktree` does: - -- uses `.env.worktree` -- ensures the shared PostgreSQL container is running -- creates the worktree database if it does not exist -- runs migrations against the worktree database - -Start the worktree app: - -```bash make start-worktree ``` -Stop the worktree app processes: +Stop: ```bash make stop-worktree @@ -171,17 +164,15 @@ Use a worktree when you want isolated data and separate app ports. ```bash git worktree add ../multica-feature -b feat/my-change main cd ../multica-feature -make worktree-env -make setup-worktree -make start-worktree +make dev ``` After that, day-to-day commands are: ```bash -make start-worktree -make stop-worktree -make check-worktree +make dev # start (re-runs setup if needed, idempotent) +make stop-worktree # stop +make check-worktree # verify ``` ## Running Main and Worktree at the Same Time @@ -424,9 +415,7 @@ Warning: ### Stable Main Environment ```bash -cp .env.example .env -make setup-main -make start-main +make dev ``` ### Feature Worktree @@ -434,9 +423,7 @@ make start-main ```bash git worktree add ../multica-feature -b feat/my-change main cd ../multica-feature -make worktree-env -make setup-worktree -make start-worktree +make dev ``` ### Return to a Previously Configured Worktree diff --git a/Makefile b/Makefile index ad9c7a3eb..ca8736ec4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: dev daemon cli multica build test migrate-up migrate-down sqlc seed clean setup start stop check worktree-env setup-main start-main stop-main check-main setup-worktree start-worktree stop-worktree check-worktree db-up db-down +.PHONY: dev server daemon cli multica build test migrate-up migrate-down sqlc seed clean setup start stop check worktree-env setup-main start-main stop-main check-main setup-worktree start-worktree stop-worktree check-worktree db-up db-down MAIN_ENV_FILE ?= .env WORKTREE_ENV_FILE ?= .env.worktree @@ -122,8 +122,12 @@ check-worktree: # ---------- Individual commands ---------- -# Go server +# One-command dev: auto-setup env/deps/db/migrations, then start all services dev: + @bash scripts/dev.sh + +# Go server only +server: $(REQUIRE_ENV) @bash scripts/ensure-postgres.sh "$(ENV_FILE)" cd server && go run ./cmd/server diff --git a/README.md b/README.md index 908f422c0..8c2d024e2 100644 --- a/README.md +++ b/README.md @@ -58,15 +58,12 @@ The fastest way to get started — no setup required: **[multica.ai](https://mul ```bash git clone https://github.com/multica-ai/multica.git cd multica -cp .env.example .env -# Edit .env — at minimum, change JWT_SECRET - -docker compose up -d # Start PostgreSQL -cd server && go run ./cmd/migrate up && cd .. # Run migrations -make start # Start the app +make dev # auto-creates .env, installs deps, starts DB + migrations, launches app ``` -See the [Self-Hosting Guide](SELF_HOSTING.md) for full instructions. +That's it — `make dev` handles environment setup, dependency installation, database creation, migrations, and starts both the backend and frontend. Edit `.env` afterward to customize settings (e.g. `JWT_SECRET`). + +For explicit control over each step, see the [Self-Hosting Guide](SELF_HOSTING.md). ## CLI @@ -152,10 +149,9 @@ For contributors working on the Multica codebase, see the [Contributing Guide](C **Prerequisites:** [Node.js](https://nodejs.org/) v20+, [pnpm](https://pnpm.io/) v10.28+, [Go](https://go.dev/) v1.26+, [Docker](https://www.docker.com/) ```bash -pnpm install -cp .env.example .env -make setup -make start +make dev ``` +`make dev` auto-detects your environment (main checkout or worktree), creates the env file, installs dependencies, sets up the database, runs migrations, and starts all services. + See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development workflow, worktree support, testing, and troubleshooting. diff --git a/scripts/dev.sh b/scripts/dev.sh new file mode 100755 index 000000000..e83ffe672 --- /dev/null +++ b/scripts/dev.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$REPO_ROOT" + +# ---------- Check prerequisites ---------- +missing=() +command -v node >/dev/null 2>&1 || missing+=("node") +command -v pnpm >/dev/null 2>&1 || missing+=("pnpm") +command -v go >/dev/null 2>&1 || missing+=("go") +command -v docker >/dev/null 2>&1 || missing+=("docker") + +if [ ${#missing[@]} -gt 0 ]; then + echo "✗ Missing prerequisites: ${missing[*]}" + echo " Please install: Node.js v20+, pnpm v10.28+, Go v1.26+, Docker" + exit 1 +fi + +# ---------- Environment file ---------- +if [ -f .git ]; then + # Inside a git worktree (.git is a file, not a directory) + ENV_FILE=".env.worktree" + if [ ! -f "$ENV_FILE" ]; then + echo "==> Worktree detected. Generating $ENV_FILE..." + bash scripts/init-worktree-env.sh "$ENV_FILE" + fi +else + ENV_FILE=".env" + if [ ! -f "$ENV_FILE" ]; then + echo "==> Creating $ENV_FILE from .env.example..." + cp .env.example "$ENV_FILE" + fi +fi + +echo "==> Using $ENV_FILE" + +set -a +# shellcheck disable=SC1090 +. "$ENV_FILE" +set +a + +# ---------- Install dependencies ---------- +if [ ! -d node_modules ]; then + echo "==> Installing dependencies..." + pnpm install +fi + +# ---------- Database ---------- +bash scripts/ensure-postgres.sh "$ENV_FILE" + +echo "==> Running migrations..." +(cd server && go run ./cmd/migrate up) + +# ---------- Start services ---------- +echo "" +echo "✓ Ready. Starting services..." +echo " Backend: http://localhost:${PORT:-8080}" +echo " Frontend: http://localhost:${FRONTEND_PORT:-3000}" +echo "" + +trap 'kill 0' EXIT +(cd server && go run ./cmd/server) & +pnpm dev:web & +wait