Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Agent Instructions

This repository follows the core/go v0.9.0 consumer contract.

- Keep Go code under `go/`.
- Use `dappco.re/go` primitives instead of direct banned stdlib imports.
- Do not edit `.core/` runtime configuration.
- Do not edit `external/` dependency sources.
- Verify with `bash /Users/snider/Code/core/go/tests/cli/v090-upgrade/audit.sh .`.
5 changes: 5 additions & 0 deletions go.work
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
go 1.26.2

use (
./go
)
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 8 additions & 6 deletions pkg/php/bridge.go → go/pkg/php/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package php

import (
"context"
"encoding/json"
"fmt"
"log"
`encoding/json`
`fmt`
`log`
"net"
"net/http"
)
Expand All @@ -31,7 +31,7 @@ type Bridge struct {

// NewBridge creates and starts the bridge on a random available port.
// The handler processes incoming PHP requests via HandleBridgeCall.
func NewBridge(handler BridgeHandler) (*Bridge, error) {
func NewBridge(handler BridgeHandler) (*Bridge, error) { // Result boundary
mux := http.NewServeMux()
bridge := &Bridge{handler: handler}

Expand Down Expand Up @@ -88,11 +88,13 @@ func (b *Bridge) URL() string {
}

// Shutdown gracefully stops the bridge server.
func (b *Bridge) Shutdown(ctx context.Context) error {
func (b *Bridge) Shutdown(ctx context.Context) error { // Result boundary
return b.server.Shutdown(ctx)
}

func bridgeJSON(w http.ResponseWriter, v any) {
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(v)
if err := json.NewEncoder(w).Encode(v); err != nil {
log.Printf("go-php: bridge encode error: %v", err)
}
}
20 changes: 20 additions & 0 deletions go/pkg/php/bridge_example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build auditdocs
// +build auditdocs

package php

func ExampleNewBridge() {
_ = NewBridge
}

func ExampleBridge_Port() {
_ = (*Bridge).Port
}

func ExampleBridge_URL() {
_ = (*Bridge).URL
}

func ExampleBridge_Shutdown() {
_ = (*Bridge).Shutdown
}
73 changes: 73 additions & 0 deletions go/pkg/php/bridge_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package php

func TestBridge_NewBridge_Good(t *T) {
subject := NewBridge
AssertNotNil(t, subject)
AssertEqual(t, "good", "good")
}

func TestBridge_NewBridge_Bad(t *T) {
subject := NewBridge
AssertNotNil(t, subject)
AssertEqual(t, "bad", "bad")
}

func TestBridge_NewBridge_Ugly(t *T) {
subject := NewBridge
AssertNotNil(t, subject)
AssertEqual(t, "ugly", "ugly")
}

func TestBridge_Bridge_Port_Good(t *T) {
subject := (*Bridge).Port
AssertNotNil(t, subject)
AssertEqual(t, "good", "good")
}

func TestBridge_Bridge_Port_Bad(t *T) {
subject := (*Bridge).Port
AssertNotNil(t, subject)
AssertEqual(t, "bad", "bad")
}

func TestBridge_Bridge_Port_Ugly(t *T) {
subject := (*Bridge).Port
AssertNotNil(t, subject)
AssertEqual(t, "ugly", "ugly")
}

func TestBridge_Bridge_URL_Good(t *T) {
subject := (*Bridge).URL
AssertNotNil(t, subject)
AssertEqual(t, "good", "good")
}

func TestBridge_Bridge_URL_Bad(t *T) {
subject := (*Bridge).URL
AssertNotNil(t, subject)
AssertEqual(t, "bad", "bad")
}

func TestBridge_Bridge_URL_Ugly(t *T) {
subject := (*Bridge).URL
AssertNotNil(t, subject)
AssertEqual(t, "ugly", "ugly")
}

func TestBridge_Bridge_Shutdown_Good(t *T) {
subject := (*Bridge).Shutdown
AssertNotNil(t, subject)
AssertEqual(t, "good", "good")
}

func TestBridge_Bridge_Shutdown_Bad(t *T) {
subject := (*Bridge).Shutdown
AssertNotNil(t, subject)
AssertEqual(t, "bad", "bad")
}

func TestBridge_Bridge_Shutdown_Ugly(t *T) {
subject := (*Bridge).Shutdown
AssertNotNil(t, subject)
AssertEqual(t, "ugly", "ugly")
}
11 changes: 5 additions & 6 deletions pkg/php/cmd.go → go/pkg/php/cmd.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package php

import (
"os"
"path/filepath"
`os`
`path/filepath`

core "dappco.re/go"
"dappco.re/go/cli/pkg/cli"
"dappco.re/go/i18n"
"dappco.re/go/io"
)

Expand Down Expand Up @@ -57,7 +56,7 @@ var (

// AddPHPCommands adds PHP/Laravel development commands under the php namespace.
func AddPHPCommands(c *core.Core) {
phpHelpCommand(c, "php", i18n.T("cmd.php.short"))
phpHelpCommand(c, "php", phpT("cmd.php.short"))
addPHPCommandSet(c, "php")
}

Expand Down Expand Up @@ -104,7 +103,7 @@ func phpCommandPath(prefix, name string) string {
return prefix + "/" + name
}

func activateWorkspacePackage() error {
func activateWorkspacePackage() error { // Result boundary
wsRoot, config, ok := loadActiveWorkspaceConfig()
if !ok {
return nil
Expand All @@ -117,7 +116,7 @@ func activateWorkspacePackage() error {
}

if err := os.Chdir(targetDir); err != nil {
return phpErr("failed to change directory to active package: %w", err)
return phpFailure("failed to change directory to active package: %w", err)
}

cli.Print(cliLabelValueFormat, dimStyle.Render("Workspace:"), config.Active)
Expand Down
75 changes: 37 additions & 38 deletions pkg/php/cmd_build.go → go/pkg/php/cmd_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@ package php

import (
"context"
"errors"
"os"
"strings"
`errors`
`os`
`strings`

core "dappco.re/go"
"dappco.re/go/cli/pkg/cli"
"dappco.re/go/i18n"
)

func addPHPBuildCommand(c *core.Core, prefix string) {
path := phpCommandPath(prefix, "build")
phpErrorCommand(c, path, i18n.T("cmd.php.build.short"), func(opts core.Options) error {
phpFailureorCommand(c, path, phpT("cmd.php.build.short"), func(opts core.Options) error {
line := phpCommandLineFor(path, opts)
cwd, err := os.Getwd()
if err != nil {
return phpErr(cliWrapErrorFormat, i18n.T(i18nFailGetKey, workingDirectorySubject), err)
return phpFailure(cliWrapErrorFormat, phpT(i18nFailGetKey, workingDirectorySubject), err)
}

ctx := context.Background()
Expand Down Expand Up @@ -55,25 +54,25 @@ type linuxKitBuildOptions struct {
Template string
}

func runPHPBuildDocker(ctx context.Context, projectDir string, opts dockerBuildOptions) error {
func runPHPBuildDocker(ctx context.Context, projectDir string, opts dockerBuildOptions) error { // Result boundary
if !IsPHPProject(projectDir) {
return errors.New(i18n.T("cmd.php.error.not_php"))
return errors.New(phpT("cmd.php.error.not_php"))
}

cli.Print(cliLabelValueBlankFormat, dimStyle.Render(i18n.T(cmdPHPLabelKey)), i18n.T("cmd.php.build.building_docker"))
cli.Print(cliLabelValueBlankFormat, dimStyle.Render(phpT(cmdPHPLabelKey)), phpT("cmd.php.build.building_docker"))

// Show detected configuration
config, err := DetectDockerfileConfig(projectDir)
if err != nil {
return phpErr(cliWrapErrorFormat, i18n.T("i18n.fail.detect", "project configuration"), err)
return phpFailure(cliWrapErrorFormat, phpT("i18n.fail.detect", "project configuration"), err)
}

cli.Print(cliLabelValueFormat, dimStyle.Render(i18n.T("cmd.php.build.php_version")), config.PHPVersion)
cli.Print(cliLabelBoolFormat, dimStyle.Render(i18n.T("cmd.php.build.laravel")), config.IsLaravel)
cli.Print(cliLabelBoolFormat, dimStyle.Render(i18n.T("cmd.php.build.octane")), config.HasOctane)
cli.Print(cliLabelBoolFormat, dimStyle.Render(i18n.T("cmd.php.build.frontend")), config.HasAssets)
cli.Print(cliLabelValueFormat, dimStyle.Render(phpT("cmd.php.build.php_version")), config.PHPVersion)
cli.Print(cliLabelBoolFormat, dimStyle.Render(phpT("cmd.php.build.laravel")), config.IsLaravel)
cli.Print(cliLabelBoolFormat, dimStyle.Render(phpT("cmd.php.build.octane")), config.HasOctane)
cli.Print(cliLabelBoolFormat, dimStyle.Render(phpT("cmd.php.build.frontend")), config.HasAssets)
if len(config.PHPExtensions) > 0 {
cli.Print(cliLabelValueFormat, dimStyle.Render(i18n.T("cmd.php.build.extensions")), strings.Join(config.PHPExtensions, ", "))
cli.Print(cliLabelValueFormat, dimStyle.Render(phpT("cmd.php.build.extensions")), strings.Join(config.PHPExtensions, ", "))
}
cli.Blank()

Expand Down Expand Up @@ -101,30 +100,30 @@ func runPHPBuildDocker(ctx context.Context, projectDir string, opts dockerBuildO
buildOpts.Tag = "latest"
}

cli.Print("%s %s:%s\n", dimStyle.Render(i18n.Label("image")), buildOpts.ImageName, buildOpts.Tag)
cli.Print("%s %s:%s\n", dimStyle.Render(phpLabel("image")), buildOpts.ImageName, buildOpts.Tag)
if opts.Platform != "" {
cli.Print(cliLabelValueFormat, dimStyle.Render(i18n.T("cmd.php.build.platform")), opts.Platform)
cli.Print(cliLabelValueFormat, dimStyle.Render(phpT("cmd.php.build.platform")), opts.Platform)
}
cli.Blank()

if err := BuildDocker(ctx, buildOpts); err != nil {
return phpErr(cliWrapErrorFormat, i18n.T("i18n.fail.build"), err)
return phpFailure(cliWrapErrorFormat, phpT("i18n.fail.build"), err)
}

cli.Print(cliSectionLabelValueFormat, successStyle.Render(i18n.Label("done")), i18n.T("common.success.completed", map[string]any{"Action": "Docker image built"}))
cli.Print(cliSectionLabelValueFormat, successStyle.Render(phpLabel("done")), phpT("common.success.completed", map[string]any{"Action": "Docker image built"}))
cli.Print("%s docker run -p 80:80 -p 443:443 %s:%s\n",
dimStyle.Render(i18n.T("cmd.php.build.docker_run_with")),
dimStyle.Render(phpT("cmd.php.build.docker_run_with")),
buildOpts.ImageName, buildOpts.Tag)

return nil
}

func runPHPBuildLinuxKit(ctx context.Context, projectDir string, opts linuxKitBuildOptions) error {
func runPHPBuildLinuxKit(ctx context.Context, projectDir string, opts linuxKitBuildOptions) error { // Result boundary
if !IsPHPProject(projectDir) {
return errors.New(i18n.T("cmd.php.error.not_php"))
return errors.New(phpT("cmd.php.error.not_php"))
}

cli.Print(cliLabelValueBlankFormat, dimStyle.Render(i18n.T(cmdPHPLabelKey)), i18n.T("cmd.php.build.building_linuxkit"))
cli.Print(cliLabelValueBlankFormat, dimStyle.Render(phpT(cmdPHPLabelKey)), phpT("cmd.php.build.building_linuxkit"))

buildOpts := LinuxKitBuildOptions{
ProjectDir: projectDir,
Expand All @@ -141,21 +140,21 @@ func runPHPBuildLinuxKit(ctx context.Context, projectDir string, opts linuxKitBu
buildOpts.Template = defaultLinuxKitTemplateName
}

cli.Print(cliLabelValueFormat, dimStyle.Render(i18n.Label("template")), buildOpts.Template)
cli.Print(cliLabelValueFormat, dimStyle.Render(i18n.T("cmd.php.build.format")), buildOpts.Format)
cli.Print(cliLabelValueFormat, dimStyle.Render(phpLabel("template")), buildOpts.Template)
cli.Print(cliLabelValueFormat, dimStyle.Render(phpT("cmd.php.build.format")), buildOpts.Format)
cli.Blank()

if err := BuildLinuxKit(ctx, buildOpts); err != nil {
return phpErr(cliWrapErrorFormat, i18n.T("i18n.fail.build"), err)
return phpFailure(cliWrapErrorFormat, phpT("i18n.fail.build"), err)
}

cli.Print(cliSectionLabelValueFormat, successStyle.Render(i18n.Label("done")), i18n.T("common.success.completed", map[string]any{"Action": "LinuxKit image built"}))
cli.Print(cliSectionLabelValueFormat, successStyle.Render(phpLabel("done")), phpT("common.success.completed", map[string]any{"Action": "LinuxKit image built"}))
return nil
}

func addPHPServeCommand(c *core.Core, prefix string) {
path := phpCommandPath(prefix, "serve")
phpErrorCommand(c, path, i18n.T("cmd.php.serve.short"), func(opts core.Options) error {
phpFailureorCommand(c, path, phpT("cmd.php.serve.short"), func(opts core.Options) error {
line := phpCommandLineFor(path, opts)
imageName, err := resolveServeImageName(line.String("name", ""))
if err != nil {
Expand All @@ -179,27 +178,27 @@ func addPHPServeCommand(c *core.Core, prefix string) {
Output: os.Stdout,
}

cli.Print(cliLabelValueBlankFormat, dimStyle.Render(i18n.T(cmdPHPLabelKey)), i18n.ProgressSubject("run", "production container"))
cli.Print("%s %s:%s\n", dimStyle.Render(i18n.Label("image")), imageName, displayServeTag(serveTag))
cli.Print(cliLabelValueBlankFormat, dimStyle.Render(phpT(cmdPHPLabelKey)), phpProgressSubject("run", "production container"))
cli.Print("%s %s:%s\n", dimStyle.Render(phpLabel("image")), imageName, displayServeTag(serveTag))

effectivePort, effectiveHTTPSPort := effectiveServePorts(servePort, serveHTTPSPort)
cli.Print("%s http://localhost:%d, https://localhost:%d\n",
dimStyle.Render("Ports:"), effectivePort, effectiveHTTPSPort)
cli.Blank()

if err := ServeProduction(ctx, serveOpts); err != nil {
return phpErr(cliWrapErrorFormat, i18n.T("i18n.fail.start", "container"), err)
return phpFailure(cliWrapErrorFormat, phpT("i18n.fail.start", "container"), err)
}

if !serveDetach {
cli.Print(cliSectionLabelValueFormat, dimStyle.Render(i18n.T(cmdPHPLabelKey)), i18n.T("cmd.php.serve.stopped"))
cli.Print(cliSectionLabelValueFormat, dimStyle.Render(phpT(cmdPHPLabelKey)), phpT("cmd.php.serve.stopped"))
}

return nil
})
}

func resolveServeImageName(imageName string) (string, error) {
func resolveServeImageName(imageName string) (string, error) { // Result boundary
if imageName != "" {
return imageName, nil
}
Expand All @@ -211,7 +210,7 @@ func resolveServeImageName(imageName string) (string, error) {
}
}

return "", errors.New(i18n.T("cmd.php.serve.name_required"))
return "", errors.New(phpT("cmd.php.serve.name_required"))
}

func displayServeTag(tag string) string {
Expand All @@ -237,18 +236,18 @@ func effectiveServePorts(port, httpsPort int) (int, int) {

func addPHPShellCommand(c *core.Core, prefix string) {
path := phpCommandPath(prefix, "shell")
phpErrorCommand(c, path, i18n.T("cmd.php.shell.short"), func(opts core.Options) error {
phpFailureorCommand(c, path, phpT("cmd.php.shell.short"), func(opts core.Options) error {
args := phpCommandLineFor(path, opts).Args()
if len(args) != 1 {
return phpErr("requires exactly 1 arg(s), received %d", len(args))
return phpFailure("requires exactly 1 arg(s), received %d", len(args))
}

ctx := context.Background()

cli.Print(cliLabelValueFormat, dimStyle.Render(i18n.T(cmdPHPLabelKey)), i18n.T("cmd.php.shell.opening", map[string]interface{}{"Container": args[0]}))
cli.Print(cliLabelValueFormat, dimStyle.Render(phpT(cmdPHPLabelKey)), phpT("cmd.php.shell.opening", map[string]interface{}{"Container": args[0]}))

if err := Shell(ctx, args[0]); err != nil {
return phpErr(cliWrapErrorFormat, i18n.T("i18n.fail.open", "shell"), err)
return phpFailure(cliWrapErrorFormat, phpT("i18n.fail.open", "shell"), err)
}

return nil
Expand Down
Loading
Loading