- Remove init() registration, use cli.Main() pattern - Build-tag FrankenPHP files (cgo/!cgo) - Add Taskfile.yml - Add CLAUDE.md Co-Authored-By: Virgil <virgil@lethean.io>
150 lines
4.7 KiB
Markdown
150 lines
4.7 KiB
Markdown
# CLAUDE.md — core/go-php
|
|
|
|
## What This Is
|
|
|
|
Standalone `core-php` binary for PHP/Laravel development. Merges the FrankenPHP handler (CGO) with PHP dev CLI commands (pure Go). Produces a single binary that `core` can invoke as a subprocess.
|
|
|
|
**Module path**: `forge.lthn.ai/core/go-php`
|
|
**Binary**: `cmd/core-php/main.go` → `./bin/core-php`
|
|
**Pattern**: `cli.Main()` + `cli.WithCommands("php", php.AddPHPCommands)`
|
|
|
|
## Build
|
|
|
|
```bash
|
|
# Dev tooling only (no FrankenPHP, no CGO needed)
|
|
CGO_ENABLED=0 go build -o ./bin/core-php ./cmd/core-php
|
|
CGO_ENABLED=0 go test ./...
|
|
|
|
# With FrankenPHP (needs PHP-ZTS + CGO)
|
|
go build -o ./bin/core-php ./cmd/core-php
|
|
```
|
|
|
|
## Current State
|
|
|
|
- All code merged from `core/php` + `core/go-php` into single module
|
|
- Entry point exists at `cmd/core-php/main.go`
|
|
- Tests pass (`CGO_ENABLED=0 go test ./...`)
|
|
- `init()` in `cmd.go` still calls `cli.RegisterCommands()` — needs removing (standalone binary pattern)
|
|
- No Taskfile yet
|
|
- No CLAUDE.md until now
|
|
- FrankenPHP handler files: `handler.go`, `bridge.go`, `extract.go`, `env.go`
|
|
- FrankenPHP serve command: `cmd_serve_frankenphp.go` (exists, needs build tags)
|
|
- Dev CLI commands: `cmd_dev.go`, `cmd_build.go`, `cmd_deploy.go`, `cmd_ci.go`, `cmd_quality.go`, `cmd_packages.go`, `cmd_qa_runner.go`
|
|
|
|
## Why This Matters
|
|
|
|
Completing go-php unblocks a chain:
|
|
1. `core/go-php` done → `core/php` namespace freed
|
|
2. `core/php-framework` relocates to `core/php` (matching `core/go` pattern)
|
|
3. `core/ts` created from Deno prototype (the original seed project)
|
|
|
|
## Plan — Tasks To Complete
|
|
|
|
### Task 1: Clean up `init()` registration
|
|
|
|
**File**: `cmd.go`
|
|
|
|
Remove `init()` that calls `cli.RegisterCommands()`. The standalone binary uses `cli.Main()` directly — `init()` registration is the old pattern for when this was a library imported by the main `core` binary.
|
|
|
|
Keep `AddPHPCommands` exported (the entry point calls it).
|
|
|
|
**Verify**: `CGO_ENABLED=0 go build -o ./bin/core-php ./cmd/core-php && ./bin/core-php php --help`
|
|
|
|
### Task 2: Build-tag the FrankenPHP files
|
|
|
|
FrankenPHP requires CGO + PHP-ZTS headers. Files that import `github.com/dunglas/frankenphp` need build tags so the binary compiles without them.
|
|
|
|
**Files needing `//go:build cgo`**:
|
|
- `handler.go`
|
|
- `bridge.go`
|
|
- `cmd_serve_frankenphp.go`
|
|
- Any file importing FrankenPHP
|
|
|
|
**Create stubs** (`//go:build !cgo`):
|
|
- `cmd_serve_frankenphp_nocgo.go` — prints "requires CGO + PHP-ZTS"
|
|
- `handler_nocgo.go` — nil/noop exports if other files reference Handler
|
|
|
|
**Verify**: `CGO_ENABLED=0 go build ./...` AND `CGO_ENABLED=0 go test ./...`
|
|
|
|
### Task 3: Add Taskfile.yml
|
|
|
|
Based on the BugSETI pattern (`/Users/snider/Code/host-uk/core/cmd/bugseti/Taskfile.yml`):
|
|
|
|
```yaml
|
|
version: '3'
|
|
|
|
tasks:
|
|
build:
|
|
desc: Build core-php binary
|
|
cmds:
|
|
- CGO_ENABLED=0 go build -o ./bin/core-php ./cmd/core-php
|
|
|
|
build-frankenphp:
|
|
desc: Build with FrankenPHP support (needs PHP-ZTS)
|
|
cmds:
|
|
- go build -o ./bin/core-php ./cmd/core-php
|
|
|
|
test:
|
|
desc: Run tests
|
|
cmds:
|
|
- CGO_ENABLED=0 go test ./...
|
|
|
|
run:
|
|
desc: Build and run
|
|
cmds:
|
|
- task: build
|
|
- ./bin/core-php {{.CLI_ARGS}}
|
|
```
|
|
|
|
### Task 4: Verify all commands register
|
|
|
|
Run `./bin/core-php php --help` and confirm all subcommands appear:
|
|
- `dev` — Laravel dev server (FrankenPHP + Vite + Horizon)
|
|
- `build` — Docker/production builds
|
|
- `deploy` — Deployment commands
|
|
- `ci` — CI pipeline
|
|
- `quality` / `qa` — Code quality (Pint, PHPStan)
|
|
- `packages` — Composer package management
|
|
- `serve` — FrankenPHP server (CGO only)
|
|
|
|
### Task 5: Push to forge
|
|
|
|
```bash
|
|
git add -A
|
|
git commit -m "feat: standalone core-php binary with build tags
|
|
|
|
- Remove init() registration, use cli.Main() pattern
|
|
- Build-tag FrankenPHP files (cgo/!cgo)
|
|
- Add Taskfile.yml
|
|
- Add CLAUDE.md
|
|
|
|
Co-Authored-By: Virgil <virgil@lethean.io>"
|
|
|
|
git push origin main
|
|
```
|
|
|
|
**Remote**: `ssh://git@forge.lthn.ai:2223/core/go-php.git`
|
|
|
|
## Coding Standards
|
|
|
|
- **UK English** in comments and docs
|
|
- **Strict error handling**: wrap with context, no silent swallows
|
|
- **Test naming**: `_Good`, `_Bad`, `_Ugly` suffix pattern
|
|
- **No init()**: standalone binary pattern uses `cli.Main()` + `cli.WithCommands()`
|
|
- **License**: EUPL-1.2
|
|
- **Co-author**: `Co-Authored-By: Virgil <virgil@lethean.io>`
|
|
|
|
## Key Dependencies
|
|
|
|
| Package | Role |
|
|
|---------|------|
|
|
| `forge.lthn.ai/core/cli` | CLI framework (cobra + bubbletea TUI) |
|
|
| `forge.lthn.ai/core/go` | Core framework (services, DI) |
|
|
| `forge.lthn.ai/core/go-i18n` | Internationalisation |
|
|
| `github.com/dunglas/frankenphp` | PHP-in-Go (CGO, optional) |
|
|
|
|
## Reference
|
|
|
|
- CLI pattern: `/Users/snider/Code/host-uk/cli/main.go`
|
|
- BugSETI Taskfile: `/Users/snider/Code/host-uk/core/cmd/bugseti/Taskfile.yml`
|
|
- FrankenPHP native app: see `frankenphp-native.md` in memory
|