This repository is the php-opencloud/openstack SDK: a PHP client for multiple OpenStack services. The public entry point is src/OpenStack.php, which creates versioned service objects through shared builder logic in src/Common/.
The project follows semantic versioning and still supports PHP ^7.2.5 || ^8.0. Keep changes narrowly scoped and avoid API breaks unless the task explicitly requires them.
src/Common/: shared API, resource, service, auth, error, JSON-schema, and transport infrastructure.<Service>/<version>/: versioned SDK surface for each OpenStack service. Most service folders contain:Api.php: declarative operation definitions (method,path,params, optionaljsonKey)Params.php: parameter schemas and wire-format metadataService.php: top-level user-facing service methodsModels/: resource classes with behavior and hydration rules
tests/unit/: mocked unit tests, usually mirroring thesrc/namespace layout.tests/sample/: integration-style tests that execute files fromsamples/.samples/: runnable examples; these double as integration-test inputs.doc/: Sphinx/reStructuredText documentation..github/workflows/: CI definitions for formatting, unit tests, and integration tests.
When adding or changing SDK functionality, preserve the existing layering:
- Define or update the REST operation in
Api.php. - Add or reuse parameter definitions in
Params.php. - Expose the behavior from
Service.phpif it is part of the top-level service API. - Implement resource behavior in
Models/*when the operation belongs on a model instance. - Add unit tests and, for user-facing flows, a sample plus sample test when practical.
Specific patterns used throughout the codebase:
Service.phpmethods are intentionally thin. They usually create a model, populate it, or delegate toenumerate(...).- Resource classes commonly extend
OpenStack\Common\Resource\OperatorResource, set$resourceKey,$resourcesKey, and$markerKey, and useexecute(...)pluspopulateFromResponse(...). - API field renames are handled with
$aliasesandAliasobjects instead of ad hoc mapping code. - Operation option arrays are documented with
{@see \Namespace\Api::methodName}docblocks. Keep those references accurate when signatures change. - Reuse shared abstractions in
src/Common/before introducing service-specific helpers.
The SDK is tested against PHP 7.2 through 8.4 in CI. Do not introduce syntax or standard-library dependencies that require newer PHP versions than 7.2.5.
In practice, avoid:
- union types
- attributes
- constructor property promotion
- enums
matchreadonly- typed properties
- named arguments in code examples or tests
Follow the surrounding file for declare(strict_types=1);. Many src/ files use it, but not every file in the repository does.
There are no Composer scripts in this repository; run tools directly from vendor/bin.
Primary local checks:
composer install
vendor/bin/parallel-lint --exclude vendor .
vendor/bin/phpunit --configuration phpunit.xml.dist
vendor/bin/php-cs-fixer fix --dry-run --diffAdditional checks when relevant:
composer normalize
vendor/bin/phpunit --configuration phpunit.sample.xml.distNotes:
- CI runs unit tests against both lowest and highest dependency sets, so avoid relying on the latest transitive behavior only.
- Integration tests require a live OpenStack environment, the environment variables from
env_test.sh.dist, and an image namedcirros. php-cs-fixeris configured forsrc/,samples/, and.php-cs-fixer.dist.php; tests are not auto-formatted by that config, so keep test edits manually consistent with surrounding code.
Unit tests usually extend tests/unit/TestCase.php.
Follow the existing test style:
- set
rootFixturesDirinsetUp()when the test uses fixture responses - use
mockRequest(...)to assert HTTP method, path, body, headers, and returned response - store larger or realistic HTTP responses as
.respfiles under a nearbyFixtures/directory - mirror the production namespace and folder layout where possible
Prefer adding focused tests around the exact operation being changed instead of broad cross-service rewrites.
samples/ are executable examples and are also exercised by tests/sample/. When you add a new user-facing capability, consider whether it should have:
- a sample under the matching service/version folder in
samples/ - a corresponding sample test under
tests/sample/ - documentation in
doc/services/if the feature is part of the supported public workflow
All code snippets used in the docs must live in samples/ rather than being maintained only inline in .rst files, and they must be covered by the sample test suite.
Sample tests typically create a temporary PHP file from a template and require_once it, so keep samples self-contained and readable.
User docs live in doc/ and use Sphinx plus reStructuredText. If a change affects public behavior, examples, or supported options, update docs as needed.
Typical doc build:
pip install -r doc/requirements.txt
make -C doc html- Prefer small, service-scoped changes over broad refactors.
- Preserve public method names and option shapes unless the task explicitly calls for a breaking change.
- Keep docblocks accurate for public APIs and option arrays.
- Reuse existing fixtures, sample patterns, and helper methods before inventing new ones.
- If
composer.jsonchanges, runcomposer normalizebecause CI auto-normalizes that file.