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>
This commit is contained in:
parent
05d2480f5e
commit
ce2ca60268
5 changed files with 175 additions and 6 deletions
150
CLAUDE.md
Normal file
150
CLAUDE.md
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
# 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
|
||||
23
Taskfile.yml
Normal file
23
Taskfile.yml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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}}
|
||||
4
cmd.go
4
cmd.go
|
|
@ -9,10 +9,6 @@ import (
|
|||
"forge.lthn.ai/core/go/pkg/io"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cli.RegisterCommands(AddPHPCommands)
|
||||
}
|
||||
|
||||
// DefaultMedium is the default filesystem medium used by the php package.
|
||||
// It defaults to io.Local (unsandboxed filesystem access).
|
||||
// Use SetMedium to change this for testing or sandboxed operation.
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -32,6 +32,7 @@ require (
|
|||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/gammazero/deque v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/klauspost/compress v1.18.4 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
|
|
|
|||
3
go.sum
3
go.sum
|
|
@ -49,8 +49,7 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
|||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
|
|
|
|||
Reference in a new issue