mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-07 16:55:38 +08:00
feat(docs): add agent guide, build class patterns, log triage, and AI instructions
This commit is contained in:
55
.github/skills/staticphp-package-maintenance/SKILL.md
vendored
Normal file
55
.github/skills/staticphp-package-maintenance/SKILL.md
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
name: staticphp-package-maintenance
|
||||
description: Maintain StaticPHP v3 packages and artifacts. Use when adding, modifying, reviewing, or validating config under config/pkg or config/artifact; package classes under src/Package; extension/library/target/tool dependencies; PHP configure args; build hooks; package metadata; or related tests and docs.
|
||||
---
|
||||
|
||||
# StaticPHP Package Maintenance
|
||||
|
||||
## Overview
|
||||
|
||||
Use this skill to make focused package changes without re-reading the entire repository. StaticPHP v3 separates declarative package/artifact YAML from package-specific PHP build logic; prefer config-only edits unless current patterns require a class.
|
||||
|
||||
## Quick Workflow
|
||||
|
||||
1. Identify the package kind and exact name.
|
||||
- Extension: `config/pkg/ext/ext-name.yml`, class `src/Package/Extension/name.php`.
|
||||
- Library: `config/pkg/lib/name.yml`, class `src/Package/Library/name.php`.
|
||||
- Target or virtual target: `config/pkg/target/name.yml`, class `src/Package/Target/name.php`.
|
||||
- Tool: `config/pkg/tool/name.yml`, class `src/Package/Tool/name.php`.
|
||||
- Shared/custom artifact: `config/artifact/name.yml`, class `src/Package/Artifact/name.php`.
|
||||
|
||||
2. Search for the closest existing package before designing anything new.
|
||||
- Similar build system: `rg "#\\[BuildFor|UnixCMakeExecutor|UnixAutoconfExecutor|WindowsCMakeExecutor" src/Package`.
|
||||
- Similar config fields: `rg "static-libs|pkg-configs|arg-type|depends@" config/pkg`.
|
||||
- Similar download type: `rg "type: ghrel|type: pecl|type: pie|type: git|binary: hosted" config`.
|
||||
|
||||
3. Read `references/package-reference.md` when changing YAML fields, artifact definitions, package naming, dependencies, platform suffixes, or validation expectations.
|
||||
|
||||
4. Read `references/build-class-patterns.md` when PHP build logic, attributes, lifecycle hooks, custom configure args, source patching, or executor usage is needed.
|
||||
|
||||
5. Validate narrowly, then broadly if risk warrants it.
|
||||
- Config lint: `php bin/spc dev:lint-config`
|
||||
- Focused tests: `vendor/bin/phpunit tests/StaticPHP/Config tests/StaticPHP/Registry tests/StaticPHP/Util/DependencyResolverTest.php --no-coverage`
|
||||
- Full project checks: `composer test`, `composer analyse`
|
||||
|
||||
## Editing Rules
|
||||
|
||||
- Treat `config/pkg/*` and `config/artifact/*` as the source of package truth; package classes augment behavior.
|
||||
- Use platform suffix fields for declarative OS differences: `@unix`, `@linux`, `@macos`, `@windows`.
|
||||
- Add a PHP class only for custom build stages, validation, hook behavior, patches, or custom configure arguments.
|
||||
- Keep extension dependencies prefixed with `ext-`; libraries, tools, and targets use their package names.
|
||||
- Prefer existing helpers such as `UnixAutoconfExecutor`, `UnixCMakeExecutor`, `WindowsCMakeExecutor`, `shell()`, `cmd()`, and `FileSystem`.
|
||||
- Do not modify build outputs (`buildroot/`, `source/`, `downloads/`, `pkgroot/`) to fix package definitions.
|
||||
- If upstream metadata changes, update license metadata and smoke-test/display names when relevant.
|
||||
|
||||
## Common Task Paths
|
||||
|
||||
- Add a new PECL extension: define `config/pkg/ext/ext-name.yml` with `type: php-extension`, `artifact.source.type: pecl`, dependencies, and `php-extension.arg-type`; add a class only if configure args, patches, or hooks are non-standard.
|
||||
- Add a library: define `config/pkg/lib/name.yml` with artifact, dependencies, and install verification fields (`headers`, `static-libs`, `pkg-configs`, `static-bins`); add build class methods by OS.
|
||||
- Fix an existing package build: start from the failing package config/class, then inspect dependencies and hooks targeting that package before changing shared core code.
|
||||
- Update a version source: prefer artifact fields that support update checking (`ghrel`, `ghtar`, `ghtagtar`, `git` with regex, `filelist`, `pecl`, `pie`) over hard-coded URLs when upstream supports it.
|
||||
|
||||
## Resources
|
||||
|
||||
- `references/package-reference.md`: YAML package/artifact model, naming, fields, validation, and commands.
|
||||
- `references/build-class-patterns.md`: PHP package attributes, stages, hooks, executors, and class patterns.
|
||||
4
.github/skills/staticphp-package-maintenance/agents/openai.yaml
vendored
Normal file
4
.github/skills/staticphp-package-maintenance/agents/openai.yaml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "StaticPHP Package Maintenance"
|
||||
short_description: "Add, update, and validate StaticPHP v3 package definitions."
|
||||
default_prompt: "Use $staticphp-package-maintenance to add, modify, or review StaticPHP package and artifact definitions."
|
||||
143
.github/skills/staticphp-package-maintenance/references/build-class-patterns.md
vendored
Normal file
143
.github/skills/staticphp-package-maintenance/references/build-class-patterns.md
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
# StaticPHP Build Class Patterns
|
||||
|
||||
## Contents
|
||||
|
||||
- When a class is needed
|
||||
- Package attributes
|
||||
- Stage and hook behavior
|
||||
- Executor choices
|
||||
- Common patterns
|
||||
- Failure-safe edits
|
||||
|
||||
## When a Class Is Needed
|
||||
|
||||
Do not add a PHP package class for simple metadata. Use YAML alone when StaticPHP can infer the configure args, dependencies, and verification.
|
||||
|
||||
Add or update a class when the package needs:
|
||||
|
||||
- OS-specific build commands.
|
||||
- Custom validation before building.
|
||||
- Custom PHP configure arguments.
|
||||
- Patches or file edits before build.
|
||||
- Hooks into another package's stage.
|
||||
- Custom source/binary download or extraction logic.
|
||||
- Package info shown by dev tooling.
|
||||
|
||||
Package classes live in `src/Package/*` and are discovered through PSR-4 plus attributes. Config must exist first; `PackageLoader` throws if an attribute references an undefined package.
|
||||
|
||||
## Package Attributes
|
||||
|
||||
Class-level package attributes:
|
||||
|
||||
- `#[Extension('curl')]` maps to package `ext-curl` if the prefix is omitted.
|
||||
- `#[Library('openssl')]`
|
||||
- `#[Target('php')]`
|
||||
- `#[Tool('zig')]`
|
||||
|
||||
Method-level attributes:
|
||||
|
||||
- `#[BuildFor('Linux'|'Darwin'|'Windows')]`: registers the `build` stage for that OS.
|
||||
- `#[Stage('name')]`: registers a named stage; defaults to the method name when omitted.
|
||||
- `#[BeforeStage('package', 'stage', 'only-when-package-resolved')]`: hook before a target package stage.
|
||||
- `#[AfterStage('package', 'stage', 'only-when-package-resolved')]`: hook after a target package stage.
|
||||
- `#[PatchBeforeBuild]`: runs once before package build unless `.spc-patched` exists; return `true` to write that marker.
|
||||
- `#[CustomPhpConfigureArg('Linux')]`: supplies custom extension configure args.
|
||||
- `#[Validate]`: validates environment/source assumptions.
|
||||
- `#[Info]`: returns package information for tooling.
|
||||
- `#[InitPackage]`: runs while loading a package class.
|
||||
- `#[ResolveBuild]`: target package callback for resolving build dependencies.
|
||||
- `#[ConditionalOn(SomeClass::class)]`: conditionally enables before/after hooks only when DI has the class.
|
||||
|
||||
## Stage and Hook Behavior
|
||||
|
||||
`PackageBuilder::buildPackage()` does:
|
||||
|
||||
1. Ensure build directories exist.
|
||||
2. Skip if already installed unless forced.
|
||||
3. Ensure source exists for non-virtual packages.
|
||||
4. Emit `PatchBeforeBuild` callbacks.
|
||||
5. Run the `build` stage.
|
||||
6. Install license data.
|
||||
7. Record tool package versions where relevant.
|
||||
|
||||
`Package::runStage()` wraps a stage with:
|
||||
|
||||
1. `BeforeStage` callbacks.
|
||||
2. The stage method itself.
|
||||
3. `AfterStage` callbacks.
|
||||
|
||||
SPC exceptions bind package and stage metadata. Preserve that behavior by throwing existing `SPCException` subclasses instead of raw exceptions when adding new failure paths.
|
||||
|
||||
## Executor Choices
|
||||
|
||||
Use existing executors where possible:
|
||||
|
||||
- `UnixAutoconfExecutor`: for Unix packages using `./configure && make && make install`. It injects default static flags and copies `config.log` into SPC logs on failure.
|
||||
- `UnixCMakeExecutor`: for Unix CMake packages. It writes toolchain settings and copies CMake configure/error/output logs on failure.
|
||||
- `WindowsCMakeExecutor`: for Windows CMake packages.
|
||||
- `shell()->cd(...)->initializeEnv($pkg)`: for custom Unix command chains.
|
||||
- `cmd()->cd(...)`: for Windows command chains.
|
||||
|
||||
Prefer `FileSystem` helpers for file edits and copies so behavior stays consistent.
|
||||
|
||||
## Common Patterns
|
||||
|
||||
Minimal library class:
|
||||
|
||||
```php
|
||||
#[Library('example')]
|
||||
class example
|
||||
{
|
||||
#[BuildFor('Linux')]
|
||||
public function build(LibraryPackage $pkg): void
|
||||
{
|
||||
(new UnixAutoconfExecutor($pkg))
|
||||
->configure()
|
||||
->make();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Extension hook into PHP build:
|
||||
|
||||
```php
|
||||
#[Extension('curl')]
|
||||
class curl
|
||||
{
|
||||
#[BeforeStage('php', [php::class, 'makeForWindows'], 'ext-curl')]
|
||||
public function patchBeforePhpBuild(): void
|
||||
{
|
||||
// Adjust env, generated build files, or linker flags.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Validation:
|
||||
|
||||
```php
|
||||
#[Validate]
|
||||
public function validate(): void
|
||||
{
|
||||
if (SystemTarget::getTargetOS() === 'Windows' && WindowsUtil::findCommand('perl.exe') === null) {
|
||||
throw new EnvironmentException('You need to install perl first!');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Custom configure args should be used when YAML `arg-type` is `custom` or when args need package/install context:
|
||||
|
||||
```php
|
||||
#[CustomPhpConfigureArg('Linux')]
|
||||
public function configureArg(PhpExtensionPackage $ext): string
|
||||
{
|
||||
return '--with-example=' . $ext->getBuildRootPath();
|
||||
}
|
||||
```
|
||||
|
||||
## Failure-Safe Edits
|
||||
|
||||
- Make hooks conditional with the third `BeforeStage`/`AfterStage` argument when a dependency must be resolved before the hook should run.
|
||||
- Keep platform-specific code under matching `#[BuildFor]` methods rather than branching heavily inside one method.
|
||||
- If a patch changes upstream source, place patch files in `src/globals/patch/` and describe them with `#[PatchDescription]` where appropriate.
|
||||
- If a class only mutates environment variables for another package, search for existing hooks first to avoid duplicate linker flags.
|
||||
- After adding attributes, run registry/config tests because invalid stages and unknown packages are caught during loading.
|
||||
157
.github/skills/staticphp-package-maintenance/references/package-reference.md
vendored
Normal file
157
.github/skills/staticphp-package-maintenance/references/package-reference.md
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
# StaticPHP Package Reference
|
||||
|
||||
## Contents
|
||||
|
||||
- Package locations
|
||||
- Package types
|
||||
- Artifact model
|
||||
- Common YAML fields
|
||||
- PHP extension fields
|
||||
- Platform suffixes
|
||||
- Validation and tests
|
||||
|
||||
## Package Locations
|
||||
|
||||
StaticPHP v3 keeps package metadata in YAML and behavior in PHP classes.
|
||||
|
||||
| Kind | YAML | PHP class namespace | Typical attribute |
|
||||
|---|---|---|---|
|
||||
| PHP extension | `config/pkg/ext/ext-name.yml` | `Package\Extension` | `#[Extension('name')]` |
|
||||
| Library | `config/pkg/lib/name.yml` | `Package\Library` | `#[Library('name')]` |
|
||||
| Target | `config/pkg/target/name.yml` | `Package\Target` | `#[Target('name')]` |
|
||||
| Virtual target | `config/pkg/target/name.yml` | `Package\Target` | `#[Target('name')]` |
|
||||
| Tool | `config/pkg/tool/name.yml` | `Package\Tool` | `#[Tool('name')]` |
|
||||
| Custom artifact | `config/artifact/name.yml` | `Package\Artifact` | artifact attributes |
|
||||
|
||||
Prefer one package per YAML file unless an existing file groups related definitions. Match nearby naming and ordering.
|
||||
|
||||
## Package Types
|
||||
|
||||
`php-extension` packages describe PHP extensions. Config package names must use the `ext-` prefix. Dependencies on extensions also use `ext-`.
|
||||
|
||||
`library` packages describe buildable dependency libraries. They usually define source artifacts plus verification fields such as headers, static libraries, pkg-config files, or binaries.
|
||||
|
||||
`target` packages represent final build outputs and inherit the library-style fields. StaticPHP automatically exposes build commands for targets.
|
||||
|
||||
`virtual-target` packages are abstract dependency/build scheduling nodes. They may omit `artifact`.
|
||||
|
||||
`tool` packages are helper programs or toolchains installed into `pkgroot/` or used by builds.
|
||||
|
||||
## Artifact Model
|
||||
|
||||
Artifacts define downloadable source archives or prebuilt binaries. Use inline artifacts for simple one-package sources and `config/artifact/*.yml` for shared, complex, or custom artifacts.
|
||||
|
||||
Top-level artifact sections:
|
||||
|
||||
- `source`: source archive, git checkout, PECL/PIE package, local directory, or custom source.
|
||||
- `binary`: prebuilt binary by platform, or aliases such as `hosted`/`custom`.
|
||||
- `metadata`: `license`, `license-files`, and `source-root`.
|
||||
|
||||
Common source types:
|
||||
|
||||
- `url`: fixed URL; supports `filename`, `version`, and `extract`.
|
||||
- `git`: repository source; use `rev` for a fixed branch/tag/commit or `regex` with named `version` capture for update checks.
|
||||
- `ghrel`: GitHub release asset by regex filename match.
|
||||
- `ghtar`: generated GitHub release tarball.
|
||||
- `ghtagtar`: generated GitHub tag tarball.
|
||||
- `filelist`: scrape a download index and extract version/filename with regex.
|
||||
- `pecl`: PECL extension by name.
|
||||
- `pie`: Packagist PIE extension by `vendor/package`.
|
||||
- `php-release`: official PHP source selected by build PHP version.
|
||||
- `local`: local source directory for development/offline use.
|
||||
- `custom`: PHP artifact class handles source or binary logic.
|
||||
|
||||
Use `metadata.source-root` when the actual build directory is inside an extracted subdirectory.
|
||||
|
||||
Use `metadata.license-files` for source licenses. `@/file.txt` points to bundled license files in `src/globals/licenses/`.
|
||||
|
||||
## Common YAML Fields
|
||||
|
||||
Shared fields:
|
||||
|
||||
- `type`: required package type.
|
||||
- `description`: optional human-readable package description.
|
||||
- `license`: package-level license annotation where applicable.
|
||||
- `lang`: implementation language such as `c` or `c++`.
|
||||
- `frameworks`: macOS framework tags.
|
||||
- `artifact`: string reference or inline artifact object. Required for `library` and `target`; optional for built-in extensions and virtual targets.
|
||||
- `depends`: hard dependencies.
|
||||
- `suggests`: optional dependencies.
|
||||
|
||||
Library, target, and tool verification/installation fields:
|
||||
|
||||
- `headers`: expected files/directories under `buildroot/include`.
|
||||
- `static-libs`: expected static libraries under `buildroot/lib`.
|
||||
- `pkg-configs`: expected `.pc` files under `buildroot/lib/pkgconfig`.
|
||||
- `static-bins`: expected executables under `buildroot/bin`.
|
||||
- `path`: directories appended to PATH after install.
|
||||
- `env`: environment variables set after install.
|
||||
- `append-env`: values appended to existing environment variables.
|
||||
|
||||
Path placeholders in `path`, `env`, and `append-env`:
|
||||
|
||||
- `{build_root_path}`: `buildroot/`
|
||||
- `{pkg_root_path}`: `pkgroot/`
|
||||
- `{working_dir}`: repository or working directory
|
||||
- `{download_path}`: `downloads/`
|
||||
- `{source_path}`: `source/`
|
||||
- `{spc_msys2_path}`: MSYS2 root on Windows
|
||||
|
||||
## PHP Extension Fields
|
||||
|
||||
Extension-specific fields live under `php-extension`.
|
||||
|
||||
- `arg-type`: configure argument behavior. Built-ins include `enable`, `enable-path`, `with`, `with-path`, `custom`, and `none`. Full strings are allowed.
|
||||
- `zend-extension`: true for Zend extensions such as opcache/xdebug.
|
||||
- `build-shared`: whether shared builds are allowed.
|
||||
- `build-static`: whether static builds are allowed.
|
||||
- `build-with-php`: true when built inside the PHP source tree.
|
||||
- `display-name`: value used for `php --ri` smoke tests and license display; empty string skips the `--ri` check.
|
||||
- `os`: allowed OS families: `Linux`, `Darwin`, `Windows`.
|
||||
|
||||
Configure string placeholders:
|
||||
|
||||
- `@build_root_path@`: absolute buildroot path.
|
||||
- `@shared_suffix@`: `=shared` in shared builds, empty in static builds.
|
||||
- `@shared_path_suffix@`: `=shared,{buildroot}` in shared builds, `={buildroot}` in static builds.
|
||||
|
||||
## Platform Suffixes
|
||||
|
||||
Many fields support platform suffixes:
|
||||
|
||||
- `@unix`: Linux and macOS.
|
||||
- `@linux`: Linux only.
|
||||
- `@macos`: macOS only.
|
||||
- `@windows`: Windows only.
|
||||
|
||||
For Linux, specific fields override generic fields in this order: `field@linux`, then `field@unix`, then `field`.
|
||||
|
||||
Use suffixes for declarative differences in dependencies, headers, libraries, pkg-configs, extension args, and suggestions.
|
||||
|
||||
## Validation and Tests
|
||||
|
||||
Run config validation for most package edits:
|
||||
|
||||
```bash
|
||||
php bin/spc dev:lint-config
|
||||
```
|
||||
|
||||
Run focused tests after config or registry changes:
|
||||
|
||||
```bash
|
||||
vendor/bin/phpunit tests/StaticPHP/Config tests/StaticPHP/Registry tests/StaticPHP/Util/DependencyResolverTest.php --no-coverage
|
||||
```
|
||||
|
||||
Run broader checks for framework or class changes:
|
||||
|
||||
```bash
|
||||
composer test
|
||||
composer analyse
|
||||
```
|
||||
|
||||
Build commands are expensive. Use them for user-provided repros, package-specific fixes, or when validation cannot prove the behavior:
|
||||
|
||||
```bash
|
||||
php bin/spc build:libs "openssl,curl" -vvv
|
||||
php bin/spc build:php "bcmath,openssl,curl" --build-cli -vvv
|
||||
```
|
||||
Reference in New Issue
Block a user