Skip to content
Open
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
2 changes: 1 addition & 1 deletion .apm/instructions/architecture.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ docs/architecture/ # Architecture documents (backend, drag-and-drop)
## PHP Testing

- PHPUnit 11 — runs inside Docker via `make test`
- PHPUnit config: `.docker/app/phpunit.xml.dist` (defines `unit`, `integration`, `functional`, and `fluent` testsuites, selected via `--testsuite` flag)
- PHPUnit config: `.docker/app/phpunit.xml.dist` (defines `unit`, `integration`, `functional`, `fluent`, and `kfc` testsuites, selected via `--testsuite` flag; `fluent` and `kfc` require the optional-modules env — `make test-modules`)
- Test namespace: `WeDevelop\Grid\Tests\` → `tests/` (Unit/ + Integration/)

## Static Analysis
Expand Down
2 changes: 1 addition & 1 deletion .apm/instructions/commands.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ applyTo: "**/*"
| `make test-unit` | Run PHP unit tests (no database/framework) |
| `make test-integration` | Run PHP integration tests (full SilverStripe env) |
| `make test-functional` | Run PHP functional tests (HTTP/controller tests) |
| `make test-fluent` | Run integration + functional + fluent tests in Fluent env |
| `make test-modules` | Run integration + functional + fluent + kfc tests in the optional-modules env (Fluent + keys-for-cache installed) |
| `make test-js` | Run JavaScript tests (Vitest, no Docker needed) |
| `make coverage` | Merged PHP coverage report (HTML + Clover) |
| `make coverage-unit` | PHP unit test coverage only |
Expand Down
1 change: 1 addition & 0 deletions .apm/instructions/gotchas.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ applyTo: "**/*"
## Tooling

- **CLAUDE.md and AGENTS.md are regenerated from `.apm/instructions/` on every `apm compile`** — direct edits to the generated files get overwritten silently. Edit the APM sources instead.
- **Editing a single-file bind mount (e.g. `composer.json`) while dev containers run breaks it inside the container.** `.docker/compose.yml` mounts individual host files (notably `../composer.json:/module/composer.json:ro`) into both `app` and `app-modules`. A single-file bind mount is pinned to the host file's inode; saving the file via atomic replace (write-temp + rename — what most editors and tooling do) swaps the inode, so the mount inside an already-running container goes stale and `/module/composer.json` reads as "No such file or directory". This surfaces as `ModuleResourceLoader` throwing `InvalidArgumentException: Can't find module 'wedevelopnl/silverstripe-grid'`, cascading into many unrelated-looking test errors (FixtureLoaderTest, ColumnWidthPickerFieldTest, FixtureControllerTest, …) — classes still autoload (separate from the module manifest), so only resource-resolution paths break. Fix: `docker compose -f .docker/compose.yml [--profile modules] up -d --force-recreate --wait <service>` to re-resolve the mount. Not a code bug and not a CI problem (CI starts containers fresh after checkout). After editing `composer.json` while containers are up, `--force-recreate` before trusting test results.
2 changes: 1 addition & 1 deletion .docker/app/composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_comment": "Keep in sync with composer.fluent.json (adds Fluent dependency)",
"_comment": "Keep in sync with composer.modules.json (which adds the optional Fluent and keys-for-cache dependencies)",
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"_comment": "Fluent variant of composer.json — keep in sync, only difference is tractorcow/silverstripe-fluent in require",
"_comment": "Optional-modules variant of composer.json — keep in sync with composer.json; adds tractorcow/silverstripe-fluent and silverstripe-terraformers/keys-for-cache to require",
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"silverstripe/recipe-cms": "^6.0",
"silverstripe-terraformers/keys-for-cache": "^3.0",
"tractorcow/silverstripe-fluent": "^8.0",
"wedevelopnl/silverstripe-grid": "*"
},
Expand Down
4 changes: 4 additions & 0 deletions .docker/app/phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
<testsuite name="integration">
<directory>vendor/wedevelopnl/silverstripe-grid/tests/Integration</directory>
<exclude>vendor/wedevelopnl/silverstripe-grid/tests/Integration/Fluent</exclude>
<exclude>vendor/wedevelopnl/silverstripe-grid/tests/Integration/KeysForCache</exclude>
</testsuite>
<testsuite name="functional">
<directory>vendor/wedevelopnl/silverstripe-grid/tests/Functional</directory>
</testsuite>
<testsuite name="fluent">
<directory>vendor/wedevelopnl/silverstripe-grid/tests/Integration/Fluent</directory>
</testsuite>
<testsuite name="kfc">
<directory>vendor/wedevelopnl/silverstripe-grid/tests/Integration/KeysForCache</directory>
</testsuite>
</testsuites>
<source>
<include>
Expand Down
12 changes: 6 additions & 6 deletions .docker/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ services:
SS_PHPUNIT_FLUSH: 1
SS_GRID_ADAPTER: ${SS_GRID_ADAPTER}

app-fluent:
profiles: [fluent]
app-modules:
profiles: [modules]
build:
context: .
dockerfile: Dockerfile
args:
PHP_VERSION: ${PHP_VERSION:-8.3}
COMPOSER_FILE: app/composer.fluent.json
COMPOSER_FILE: app/composer.modules.json
volumes:
- ../composer.json:/module/composer.json:ro
- ../src:/module/src
Expand All @@ -59,7 +59,7 @@ services:
- ../lang:/module/lang
- ../templates:/module/templates:ro
- ../coverage:/app/coverage
- vendor-fluent:/app/vendor
- vendor-modules:/app/vendor
healthcheck:
test: test -f /tmp/.app-ready
interval: 3s
Expand All @@ -70,7 +70,7 @@ services:
condition: service_healthy
environment:
SS_DATABASE_SERVER: db
SS_DATABASE_NAME: silverstripe_fluent
SS_DATABASE_NAME: silverstripe_modules
SS_DATABASE_USERNAME: silverstripe
SS_DATABASE_PASSWORD: silverstripe
SS_DEFAULT_ADMIN_USERNAME: admin
Expand Down Expand Up @@ -98,5 +98,5 @@ services:

volumes:
vendor:
vendor-fluent:
vendor-modules:
db-data:
1 change: 0 additions & 1 deletion .docker/db-init/create-fluent-db.sql

This file was deleted.

1 change: 1 addition & 0 deletions .docker/db-init/create-modules-db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE DATABASE IF NOT EXISTS `silverstripe_modules`;
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,18 @@ jobs:
php: ['8.3', '8.4', '8.5']
env:
PHP_VERSION: ${{ matrix.php }}
COMPOSE: docker compose -f .docker/compose.yml --profile fluent
COMPOSE: docker compose -f .docker/compose.yml --profile modules
steps:
- uses: actions/checkout@v4
- run: make .docker/.env
- run: $COMPOSE up -d --build --wait
name: Start services
- run: >-
$COMPOSE exec app-fluent vendor/bin/phpunit
$COMPOSE exec app-modules vendor/bin/phpunit
--log-junit coverage/junit.xml
--coverage-clover coverage/clover.xml
name: Run all tests with coverage
- run: $COMPOSE exec app-fluent vendor/bin/coverage-check coverage/clover.xml 90
- run: $COMPOSE exec app-modules vendor/bin/coverage-check coverage/clover.xml 90
name: Check coverage threshold (90%)
- uses: dorny/test-reporter@v1
if: always()
Expand Down
20 changes: 5 additions & 15 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# AGENTS.md
<!-- Generated by APM CLI from distributed .apm/ primitives -->
<!-- Build ID: 0587d45ab656 -->
<!-- APM Version: 0.12.1 -->
<!-- Source: local -->
<!-- Build ID: ae7d61c44de0 -->
<!-- APM Version: 0.20.0 -->

## Files matching `**/*`

<!-- Source: local .apm/instructions/architecture.instructions.md -->
# Architecture

```
Expand Down Expand Up @@ -77,7 +75,7 @@ docs/architecture/ # Architecture documents (backend, drag-and-drop)
## PHP Testing

- PHPUnit 11 — runs inside Docker via `make test`
- PHPUnit config: `.docker/app/phpunit.xml.dist` (defines `unit`, `integration`, `functional`, and `fluent` testsuites, selected via `--testsuite` flag)
- PHPUnit config: `.docker/app/phpunit.xml.dist` (defines `unit`, `integration`, `functional`, `fluent`, and `kfc` testsuites, selected via `--testsuite` flag; `fluent` and `kfc` require the optional-modules env — `make test-modules`)
- Test namespace: `WeDevelop\Grid\Tests\` → `tests/` (Unit/ + Integration/)

## Static Analysis
Expand All @@ -97,14 +95,12 @@ docs/architecture/ # Architecture documents (backend, drag-and-drop)
- `FlipTypeControlToUseExclusiveTypeRector` — `$x !== null` on a typed `?Foo` property is more honest about intent than `$x instanceof Foo`
- `PostIncDecToPreIncDecRector` — pure micro-style, codebase consistently uses post-increment

<!-- Source: local .apm/instructions/code-style.instructions.md -->
# Code Style

- 4 spaces: PHP, `composer.json`
- 2 spaces: YML, JS, TS, TSX, JSON, CSS, SCSS (enforced via `.editorconfig`)
- LF line endings, UTF-8, trailing newline

<!-- Source: local .apm/instructions/commands.instructions.md -->
# Commands

## npm
Expand Down Expand Up @@ -144,7 +140,7 @@ docs/architecture/ # Architecture documents (backend, drag-and-drop)
| `make test-unit` | Run PHP unit tests (no database/framework) |
| `make test-integration` | Run PHP integration tests (full SilverStripe env) |
| `make test-functional` | Run PHP functional tests (HTTP/controller tests) |
| `make test-fluent` | Run integration + functional + fluent tests in Fluent env |
| `make test-modules` | Run integration + functional + fluent + kfc tests in the optional-modules env (Fluent + keys-for-cache installed) |
| `make test-js` | Run JavaScript tests (Vitest, no Docker needed) |
| `make coverage` | Merged PHP coverage report (HTML + Clover) |
| `make coverage-unit` | PHP unit test coverage only |
Expand All @@ -163,7 +159,6 @@ docs/architecture/ # Architecture documents (backend, drag-and-drop)
| `make qa` | Full QA suite (PHPStan + Rector + PHP coverage + JS QA, parallel) |
| `make qa-js` | JavaScript QA (Biome + Stylelint + typecheck + Vitest + vite build) |

<!-- Source: local .apm/instructions/docker.instructions.md -->
# Docker Dev Environment

- `make up` auto-generates `.docker/.env` if missing — no manual step needed
Expand All @@ -173,7 +168,6 @@ docs/architecture/ # Architecture documents (backend, drag-and-drop)
- Default admin credentials: `admin`/`admin`
- Use `make up`/`make down` to manage services (see Commands)

<!-- Source: local .apm/instructions/element-hierarchy.instructions.md -->
# Element Hierarchy

## Structure
Expand Down Expand Up @@ -295,7 +289,6 @@ YAML fixtures are written **top-down** (page → section → row → column →

See [docs/testing/e2e-fixtures.md](../../docs/testing/e2e-fixtures.md) for the full protocol (YAML schema, post-actions, URL segment conventions, the `FixtureController` HTTP endpoint).

<!-- Source: local .apm/instructions/gotchas.instructions.md -->
# Gotchas

## Grid Domain
Expand Down Expand Up @@ -328,8 +321,8 @@ See [docs/testing/e2e-fixtures.md](../../docs/testing/e2e-fixtures.md) for the f
## Tooling

- **CLAUDE.md and AGENTS.md are regenerated from `.apm/instructions/` on every `apm compile`** — direct edits to the generated files get overwritten silently. Edit the APM sources instead.
- **Editing a single-file bind mount (e.g. `composer.json`) while dev containers run breaks it inside the container.** `.docker/compose.yml` mounts individual host files (notably `../composer.json:/module/composer.json:ro`) into both `app` and `app-modules`. A single-file bind mount is pinned to the host file's inode; saving the file via atomic replace (write-temp + rename — what most editors and tooling do) swaps the inode, so the mount inside an already-running container goes stale and `/module/composer.json` reads as "No such file or directory". This surfaces as `ModuleResourceLoader` throwing `InvalidArgumentException: Can't find module 'wedevelopnl/silverstripe-grid'`, cascading into many unrelated-looking test errors (FixtureLoaderTest, ColumnWidthPickerFieldTest, FixtureControllerTest, …) — classes still autoload (separate from the module manifest), so only resource-resolution paths break. Fix: `docker compose -f .docker/compose.yml [--profile modules] up -d --force-recreate --wait <service>` to re-resolve the mount. Not a code bug and not a CI problem (CI starts containers fresh after checkout). After editing `composer.json` while containers are up, `--force-recreate` before trusting test results.

<!-- Source: local .apm/instructions/grid-adapter.instructions.md -->
# Grid Adapter System

Grid adapters translate the abstract grid model (viewports, column widths, offsets, visibility) into CSS framework-specific class names. All consumers depend on `GridAdapterInterface`, never on a concrete adapter.
Expand Down Expand Up @@ -369,7 +362,6 @@ The adapter is entirely configuration-driven. `GridAdapter` is a single concrete

For the full property reference, sprintf arg tables, implementation walkthrough, and content layout details, see `docs/architecture/grid-adapter.md`.

<!-- Source: local .apm/instructions/project-overview.instructions.md -->
# Project Overview

SilverStripe Grid — a grid-based content block system for SilverStripe 6 CMS providing structured Section > Row > Column layouts with configurable CSS framework adapters (Bootstrap, Tailwind, Bulma).
Expand All @@ -386,7 +378,6 @@ Package: `wedevelopnl/silverstripe-grid` (type: `silverstripe-vendormodule`)

## Files matching `**/*.php`

<!-- Source: local .apm/instructions/php-conventions.instructions.md -->
# PHP Conventions

## SilverStripe Dependency Injection
Expand Down Expand Up @@ -439,7 +430,6 @@ Use the narrowest PHPStan PHPDoc type that matches the domain constraint. Prefer

## Files matching `**/*.{ts,tsx}`

<!-- Source: local .apm/instructions/typescript-conventions.instructions.md -->
# TypeScript & React Conventions

## Stack
Expand Down
Loading
Loading