Skip to content
This repository was archived by the owner on Apr 27, 2026. It is now read-only.

Commit bd4d659

Browse files
pjcdawkinsclaude
andcommitted
Adapt for external PHP builds
PHP binaries are now downloaded from upsun/cli-php-builds releases instead of being built locally. This decouples PHP builds from CLI releases and simplifies the build process. Changes: - Makefile: Replace local build targets with download targets - php_manager_windows.go: Simplify to use static binary (no ZIP/DLLs) - CLAUDE.md: Update build documentation - Remove ext/ submodule and build-php-brew.sh 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7015c47 commit bd4d659

7 files changed

Lines changed: 200 additions & 184 deletions

File tree

.gitmodules

Lines changed: 0 additions & 3 deletions
This file was deleted.

CLAUDE.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
The Upsun CLI is a Go-based command-line interface for Upsun (formerly Platform.sh). The CLI is a hybrid system that wraps a legacy PHP CLI while providing new Go-based commands. It supports multiple vendors through build tags and configuration files.
8+
9+
## Build and Test Commands
10+
11+
Build a single binary for your platform:
12+
```bash
13+
make single
14+
```
15+
16+
Build a snapshot for all platforms:
17+
```bash
18+
make snapshot
19+
```
20+
21+
Run tests:
22+
```bash
23+
make test
24+
# or directly:
25+
GOEXPERIMENT=jsonv2 go test -v -race -cover -count=1 ./...
26+
```
27+
28+
Run linters:
29+
```bash
30+
make lint
31+
# or individual linters:
32+
make lint-gomod
33+
make lint-golangci
34+
```
35+
36+
Format code:
37+
```bash
38+
go fmt ./...
39+
```
40+
41+
Tidy dependencies:
42+
```bash
43+
go mod tidy
44+
```
45+
46+
Run a single test:
47+
```bash
48+
go test -v -run TestName ./path/to/package
49+
```
50+
51+
## Architecture
52+
53+
### Hybrid CLI System
54+
55+
The CLI operates as a wrapper around a legacy PHP CLI:
56+
- Go layer: Handles new commands (init, list, version, config:install, project:convert) and core infrastructure
57+
- PHP layer: Legacy commands are proxied through `internal/legacy/CLIWrapper`
58+
- The PHP CLI (platform.phar) is embedded at build time via go:embed
59+
60+
### Key Components
61+
62+
**Entry Point**: `cmd/platform/main.go`
63+
- Loads configuration from YAML (embedded or external)
64+
- Sets up Viper for environment variable handling
65+
- Delegates to commands package
66+
67+
**Commands**: `commands/`
68+
- `root.go`: Root command that sets up the Cobra CLI and delegates to legacy CLI when needed
69+
- Native Go commands: init, list, version, config:install, project:convert, completion
70+
- Unrecognized commands are passed to the legacy PHP CLI
71+
72+
**Configuration**: `internal/config/`
73+
- `schema.go`: Config struct definition with validation tags
74+
- Supports vendorization through embedded YAML configs (config_upsun.go, config_platformsh.go, config_vendor.go)
75+
- Uses build tags to select which config is embedded
76+
- Config can be loaded from external files for testing/development
77+
78+
**Legacy Integration**: `internal/legacy/`
79+
- `legacy.go`: CLIWrapper that manages PHP binary and phar execution
80+
- PHP binaries are embedded per platform via go:embed and build tags
81+
- Uses file locking to prevent concurrent initialization
82+
- Copies PHP binary and phar to cache directory on first run
83+
84+
**API Client**: `internal/api/`
85+
- HTTP client for interacting with Platform.sh/Upsun API
86+
- Handles authentication, organizations, and resource management
87+
88+
**Authentication**: `internal/auth/`
89+
- JWT handling and OAuth2 flow
90+
- Custom transport for API authentication
91+
92+
**Project Initialization**: `internal/init/`
93+
- AI-powered project configuration generation
94+
- Integrates with whatsun library for codebase analysis
95+
96+
### Build System
97+
98+
**Multi-Vendor Support**:
99+
- Uses Go build tags (platform, upsun, vendor) to compile different binaries
100+
- Configuration is embedded at compile time
101+
- GoReleaser builds multiple variants (platform, upsun, vendor-specific)
102+
103+
**PHP Binary Handling**:
104+
- PHP binaries are downloaded from [upsun/cli-php-builds](https://github.com/upsun/cli-php-builds) releases
105+
- All platforms use static binaries built with [static-php-cli](https://github.com/crazywhalecc/static-php-cli)
106+
- Supported platforms: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64
107+
- Extensions included: curl, filter, openssl, pcntl (Unix), phar, posix (Unix), zlib
108+
- Windows requires `cacert.pem` for OpenSSL (embedded separately)
109+
110+
**Downloading PHP Binaries**:
111+
```bash
112+
# Download PHP for current platform only (for development)
113+
make php
114+
115+
# Download all PHP binaries (for release builds)
116+
make download-php
117+
```
118+
119+
**Upgrading PHP Version**:
120+
1. Trigger the build workflow at [upsun/cli-php-builds](https://github.com/upsun/cli-php-builds/actions) with the new PHP version
121+
2. Update `PHP_VERSION` in the Makefile
122+
3. Run `make php` to download the new binary
123+
4. Test and release
124+
125+
## Development Notes
126+
127+
### Testing
128+
129+
Tests use github.com/stretchr/testify for assertions. Table-driven tests are preferred with a "cases" slice containing simple test case structs.
130+
131+
### Configuration
132+
133+
The CLI uses Viper for configuration. Environment variables use the prefix defined in the config (UPSUN_CLI_ or PLATFORM_CLI_). The prefix is set in the config YAML.
134+
135+
### Legacy CLI Interaction
136+
137+
When the root command receives arguments it doesn't recognize, it passes them to the legacy PHP CLI via CLIWrapper.Exec(). The PHP binary and phar are extracted to a cache directory on first use.
138+
139+
### Vendorization
140+
141+
To build a vendor-specific CLI:
142+
```bash
143+
make vendor-snapshot VENDOR_NAME='Vendor Name' VENDOR_BINARY='vendorcli'
144+
make vendor-release VENDOR_NAME='Vendor Name' VENDOR_BINARY='vendorcli'
145+
```
146+
147+
This requires a config file at `internal/config/embedded-config.yaml` (downloaded at build time).
148+
149+
### Version Information
150+
151+
Version information is injected at build time via ldflags:
152+
- `internal/config.Version`: Git tag/version
153+
- `internal/config.Commit`: Git commit hash
154+
- `internal/config.Date`: Build date
155+
- `internal/legacy.PHPVersion`: PHP version embedded
156+
- `internal/legacy.LegacyCLIVersion`: Legacy CLI version embedded
157+
158+
### Update Checks
159+
160+
The CLI checks for updates from GitHub releases (when Wrapper.GitHubRepo is set in config). This runs in a background goroutine and prints a message after command execution.

Makefile

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
PHP_VERSION = 8.2.29
1+
PHP_VERSION = 8.4.16
22
LEGACY_CLI_VERSION = 4.28.2
33

44
GORELEASER_ID ?= upsun
@@ -7,10 +7,6 @@ ifeq ($(GOOS), darwin)
77
GORELEASER_ID=$(GORELEASER_ID)-macos
88
endif
99

10-
# The OpenSSL version must be compatible with the PHP version.
11-
# See: https://www.php.net/manual/en/openssl.requirements.php
12-
OPENSSL_VERSION = 1.1.1t
13-
1410
GOOS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
1511
GOARCH := $(shell uname -m)
1612
ifeq ($(GOARCH), x86_64)
@@ -20,45 +16,55 @@ ifeq ($(GOARCH), aarch64)
2016
GOARCH=arm64
2117
endif
2218

23-
PHP_BINARY_PATH := internal/legacy/archives/php_$(GOOS)_$(GOARCH)
2419
VERSION := $(shell git describe --always)
2520

2621
# Tooling versions
2722
GORELEASER_VERSION=v2.12.0
2823

29-
internal/legacy/archives/platform.phar:
30-
curl -L https://github.com/platformsh/legacy-cli/releases/download/v$(LEGACY_CLI_VERSION)/platform.phar -o internal/legacy/archives/platform.phar
24+
# PHP binaries are downloaded from cli-php-builds releases.
25+
# See: https://github.com/upsun/cli-php-builds
26+
PHP_BUILDS_REPO = upsun/cli-php-builds
27+
PHP_RELEASE_URL = https://github.com/$(PHP_BUILDS_REPO)/releases/download/php-$(PHP_VERSION)
3128

32-
internal/legacy/archives/php_windows_amd64: internal/legacy/archives/php_windows.zip internal/legacy/archives/cacert.pem
29+
internal/legacy/archives/platform.phar:
30+
mkdir -p internal/legacy/archives
31+
curl -fSL https://github.com/platformsh/legacy-cli/releases/download/v$(LEGACY_CLI_VERSION)/platform.phar -o internal/legacy/archives/platform.phar
3332

33+
# Download PHP binary for the current platform.
3434
internal/legacy/archives/php_darwin_$(GOARCH):
35-
bash build-php-brew.sh $(GOOS) $(PHP_VERSION) $(OPENSSL_VERSION)
36-
mv -f $(GOOS)/php-$(PHP_VERSION)/sapi/cli/php $(PHP_BINARY_PATH)
37-
rm -rf $(GOOS)
35+
mkdir -p internal/legacy/archives
36+
curl -fSL "$(PHP_RELEASE_URL)/php-$(PHP_VERSION)-darwin-$(GOARCH)" -o $@
37+
chmod +x $@
3838

3939
internal/legacy/archives/php_linux_$(GOARCH):
4040
mkdir -p internal/legacy/archives
41-
cp ext/craft.yml ext/static-php-cli/craft.yml
42-
cd ext/static-php-cli && SPC_USE_ARCH=$(GOARCH) ./bin/spc-alpine-docker craft craft.yml
43-
cp ext/static-php-cli/buildroot/bin/php $(PHP_BINARY_PATH)
44-
45-
PHP_WINDOWS_REMOTE_FILENAME := "php-$(PHP_VERSION)-nts-Win32-vs16-x64.zip"
46-
internal/legacy/archives/php_windows.zip:
47-
( \
48-
set -e ;\
49-
mkdir -p internal/legacy/archives ;\
50-
cd internal/legacy/archives ;\
51-
curl -f "https://windows.php.net/downloads/releases/$(PHP_WINDOWS_REMOTE_FILENAME)" > php_windows.zip ;\
52-
curl -f https://windows.php.net/downloads/releases/sha256sum.txt | grep "$(PHP_WINDOWS_REMOTE_FILENAME)" | sed s/"$(PHP_WINDOWS_REMOTE_FILENAME)"/"php_windows.zip"/g > php_windows.zip.sha256 ;\
53-
sha256sum -c php_windows.zip.sha256 ;\
54-
)
41+
curl -fSL "$(PHP_RELEASE_URL)/php-$(PHP_VERSION)-linux-$(GOARCH)" -o $@
42+
chmod +x $@
43+
44+
internal/legacy/archives/php_windows_amd64: internal/legacy/archives/php_windows.exe internal/legacy/archives/cacert.pem
45+
46+
internal/legacy/archives/php_windows.exe:
47+
mkdir -p internal/legacy/archives
48+
curl -fSL "$(PHP_RELEASE_URL)/php-$(PHP_VERSION)-windows-amd64.exe" -o $@
5549

5650
.PHONY: internal/legacy/archives/cacert.pem
5751
internal/legacy/archives/cacert.pem:
5852
mkdir -p internal/legacy/archives
59-
curl https://curl.se/ca/cacert.pem > internal/legacy/archives/cacert.pem
53+
curl -fSL https://curl.se/ca/cacert.pem -o internal/legacy/archives/cacert.pem
6054

61-
php: $(PHP_BINARY_PATH)
55+
# Download all PHP binaries (for release builds).
56+
.PHONY: download-php
57+
download-php:
58+
mkdir -p internal/legacy/archives
59+
curl -fSL "$(PHP_RELEASE_URL)/php-$(PHP_VERSION)-linux-amd64" -o internal/legacy/archives/php_linux_amd64
60+
curl -fSL "$(PHP_RELEASE_URL)/php-$(PHP_VERSION)-linux-arm64" -o internal/legacy/archives/php_linux_arm64
61+
curl -fSL "$(PHP_RELEASE_URL)/php-$(PHP_VERSION)-darwin-amd64" -o internal/legacy/archives/php_darwin_amd64
62+
curl -fSL "$(PHP_RELEASE_URL)/php-$(PHP_VERSION)-darwin-arm64" -o internal/legacy/archives/php_darwin_arm64
63+
curl -fSL "$(PHP_RELEASE_URL)/php-$(PHP_VERSION)-windows-amd64.exe" -o internal/legacy/archives/php_windows.exe
64+
curl -fSL https://curl.se/ca/cacert.pem -o internal/legacy/archives/cacert.pem
65+
chmod +x internal/legacy/archives/php_linux_* internal/legacy/archives/php_darwin_*
66+
67+
php: internal/legacy/archives/php_$(GOOS)_$(GOARCH)
6268

6369
.PHONY: goreleaser
6470
goreleaser:

build-php-brew.sh

Lines changed: 0 additions & 44 deletions
This file was deleted.

ext/craft.yml

Lines changed: 0 additions & 32 deletions
This file was deleted.

ext/static-php-cli

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)