Skip to content

feat(dev): mirrorstack dev — run a module locally with docker pg#19

Merged
I-am-nothing merged 2 commits into
mainfrom
feat/dev-shell
May 5, 2026
Merged

feat(dev): mirrorstack dev — run a module locally with docker pg#19
I-am-nothing merged 2 commits into
mainfrom
feat/dev-shell

Conversation

@I-am-nothing

Copy link
Copy Markdown
Contributor

Summary

New top-level subcommand. Brings up a vendored Postgres via docker-compose, spawns the user's `go run .`, line-prefixes its output, and tears down on Ctrl-C.

Flow

```
$ cd my-module
$ mirrorstack dev
✓ bootstrapped docker-compose.yml
[+] Running 2/2
✔ Network mymod_default Created
✔ Container mirrorstack-dev-pg Healthy
✓ module running — Ctrl-C to stop
module │ mirrorstack: my-module module (My Mod) listening on :8080

^C
[+] Running 2/2
✔ Container mirrorstack-dev-pg Removed
✔ Network mymod_default Removed
```

Flags

Flag Default Notes
`--dir ` cwd Where main.go lives
`--no-compose` off Use your own running pg; requires `MS_LOCAL_DB_URL`
`--db-url ` bundled Override the default; highest precedence

Port choice

Bundled Postgres binds host port 5433 (not 5432). Lets `mirrorstack dev` co-exist with api-platform's own `docker-compose.yml` (which uses 5432) when developing platform + module side by side. Comment in the template explains.

Not in scope

  • WSS tunnel client — separate PR. Module runs as a plain HTTP server on its own port for now.
  • Graceful SIGTERM-then-SIGKILL — current shutdown is `child.kill()` (SIGKILL on unix). Reviewer flagged this for Go modules mid-DB-write; queued as a follow-up since it requires an extra dep (libc/nix) and Windows divergence handling. Acceptable for v1: a dev shell where the user owns the DB and restarts are cheap.

Test plan

  • `cargo test` — 33 tests pass (8 new for dev)
  • `cargo clippy --all-targets -- -D warnings` clean
  • `cargo fmt --all -- --check` clean
  • Manual end-to-end: scaffold a module, `mirrorstack dev`, hit `localhost:8080/health`, Ctrl-C, confirm container is gone

/simplify pass

Three reviewers ran in parallel. Five fixes applied:

  • `docker compose up --wait` (was: 500ms client-side polling loop) — drops ~30 lines, removes brittle JSON-substring check
  • `compose down` now surfaces non-zero exit (was: silent leak)
  • Boolean trap in `forward_lines(to_stderr)` → `forward_stdout`/`forward_stderr` thin wrappers around a closure-driven inner
  • `line_prefix` visibility: `pub(crate)` → `pub(super)` (only used inside dev/)
  • Template comment + `DEFAULT_DB_URL` flagged port collision with api-platform; switched to 5433

🤖 Generated with Claude Code

I-am-nothing and others added 2 commits May 6, 2026 01:22
New top-level subcommand. Lifecycle:
  1. Bootstrap docker-compose.yml in cwd if missing (vendored template)
  2. docker compose up -d --wait — server-side healthcheck blocking
  3. Spawn `go run .` with MS_LOCAL_DB_URL injected
  4. Stream stdout/stderr through a labeled prefix
  5. On Ctrl-C: child.kill(), then docker compose down

Bundled Postgres binds host port 5433 (not 5432) so it can coexist with
api-platform's own postgres on 5432 — devs can run platform + module
side by side without port juggling.

Flags:
- --dir <path>: module dir (default cwd)
- --no-compose: skip docker, use the user's own pg (requires MS_LOCAL_DB_URL)
- --db-url <url>: override the default (highest precedence)

No WSS tunnel yet — module runs as a plain HTTP server on its own port.
A follow-up PR layers the tunnel registration on top so deployed-mode
calls back to localhost can be exercised.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The module docs claimed "graceful SIGTERM" but the code calls
child.kill() — SIGKILL on unix, TerminateProcess on windows. Tightened
the wording so docs and code agree, and queued the SIGTERM-first
escalation as a follow-up note inside the file.

No behavior change.
@I-am-nothing I-am-nothing merged commit 20ccff7 into main May 5, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant