This repository has been archived on 2026-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
go-php/CLAUDE.md
Snider ce2ca60268
Some checks failed
Security Scan / security (push) Successful in 7s
Test / test (push) Failing after 1m22s
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>
2026-03-06 08:40:39 +00:00

4.7 KiB

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

# 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):

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

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