From 2b46f96e30a36860c9beb968ef3098d4acc7451d Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Fri, 9 Oct 2026 22:54:46 -0500 Subject: [PATCH] chore: replace em and en dashes with ASCII throughout An em dash cannot be typed on a standard keyboard without a numeric-alt or IME sequence, so every occurrence was machine-written rather than authored. They also propagate by copy, since the preset artifacts are copied between packages. Replacement is context-aware rather than a blind substitution: | Pattern | Becomes | |---|---| | Markdown heading or bold label followed by a dash | a colon | | Anything else mid-sentence | a spaced ASCII hyphen | | Numeric ranges | a bare hyphen | Documentation and comment text, plus two console status strings that are noted separately. Signed-off-by: Joey Smith Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .devcontainer/devcontainer.json | 2 +- .github/copilot-instructions.md | 28 ++++++++++++------------- Dockerfile | 2 +- compose.yml | 14 ++++++------- src/SchemaFactory.php | 4 ++-- src/Session/PhpDbSessionPersistence.php | 4 ++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 90bff64..94cd7e1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ // Webware alignment Dev Container. // -// This is a thin wrapper around compose.yml — it reuses the `tooling` service +// This is a thin wrapper around compose.yml - it reuses the `tooling` service // rather than defining a parallel environment, so VS Code and plain // `docker compose` users share the exact same container. Non-VS Code // developers are not orphaned: they use `docker compose up -d` + diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index dc7d6fe..2437a9c 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,12 +1,12 @@ -# webware/webware-phpdb — Copilot Agent Instructions +# webware/webware-phpdb: Copilot Agent Instructions -## Read this before acting — fleet working agreements +## Read this before acting: fleet working agreements `vendor/webware/webware-tools/agent-working-agreements.md` is authoritative for how work is done in this fleet, and it overrides anything else in this file or in any local note. Read it before acting, and again before reporting. The non-negotiables: -- Do exactly the scope asked — only the files, branches and repositories named. No adjacent edits, +- Do exactly the scope asked - only the files, branches and repositories named. No adjacent edits, no cleanup, no onboarding, no surveys. - Anything else you notice gets one line at most, with no proposed fix. - Never close a reply with a condensed restatement of it, and never present an inference as a @@ -26,11 +26,11 @@ always a dependency, so this file does not need to be duplicated per package. Mago distinguishes what a `*::class` string may reference: -- `class-string` — a concrete **class** -- `interface-string` — an **interface** -- `enum-string` — an **enum** -- `trait-string` — a **trait** -- `class-like-string` — any of class / interface / enum +- `class-string` - a concrete **class** +- `interface-string` - an **interface** +- `enum-string` - an **enum** +- `trait-string` - a **trait** +- `class-like-string` - any of class / interface / enum Webware aliases against interfaces and builds to interfaces, so prefer the precise form: @@ -47,22 +47,22 @@ PHPUnit 13 enforces a strict separation between mocks and stubs. Violating these - **Use `createStub()`** when the test double only needs to return values (`method()->willReturn()`, `method()->willReturnCallback()`). No expectations are configured. - **Use `createMock()`** only when the test verifies behavior with `expects()` (e.g. `expects($this->once())`, `expects($this->never())`). -- **Never** call `createMock()` without also calling `expects()` on at least one method — PHPUnit 13 will issue a notice. +- **Never** call `createMock()` without also calling `expects()` on at least one method - PHPUnit 13 will issue a notice. - **Remove** `/** @var ClassName&MockObject */` annotations and `MockObject` intersection types on variables created with `createStub()`. - **Remove** the `use PHPUnit\Framework\MockObject\MockObject;` import from any file where no `createMock()` + `expects()` usage remains. ### Examples ```php -// CORRECT — stub returns value, no expectations +// CORRECT - stub returns value, no expectations $container = $this->createStub(ContainerInterface::class); $container->method('get')->willReturnCallback(static fn(string $id): mixed => ...); -// CORRECT — mock verifies behavior with expects() +// CORRECT - mock verifies behavior with expects() $handler = $this->createMock(ErrorHandler::class); $handler->expects($this->once())->method('attachListener'); -// WRONG — createMock() with no expects() triggers PHPUnit notice +// WRONG - createMock() with no expects() triggers PHPUnit notice $logger = $this->createMock(Logger::class); $logger->method('withName')->willReturn($logger); // should be createStub() ``` @@ -71,6 +71,6 @@ $logger->method('withName')->willReturn($logger); // should be createStub() `phpunit.xml.dist` has `requireCoverageMetadata="true"`. Every test class **must** have: -1. `#[CoversClass(ClassName::class)]` — one per source class under test. -2. `#[CoversMethod(ClassName::class, 'methodName')]` — one per public/protected method exercised. +1. `#[CoversClass(ClassName::class)]` - one per source class under test. +2. `#[CoversMethod(ClassName::class, 'methodName')]` - one per public/protected method exercised. 3. `use PHPUnit\Framework\Attributes\CoversClass;` and `use PHPUnit\Framework\Attributes\CoversMethod;` imports. diff --git a/Dockerfile b/Dockerfile index 7e9cea2..4ff0c47 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ # # Builds a self-contained, interactive PHP development environment carrying # the Webware toolchain: PHP CLI, Composer, Mago, and Xdebug. Developers work -# inside this container — either through the VS Code Dev Container (backed by +# inside this container: either through the VS Code Dev Container (backed by # compose.yml) or by `docker compose up -d` + `docker compose exec tooling`. # The host machine (Windows, WSL, Linux, or macOS) never needs a native PHP # toolchain. diff --git a/compose.yml b/compose.yml index f6a61c3..2a7a5a1 100644 --- a/compose.yml +++ b/compose.yml @@ -9,7 +9,7 @@ # This compose file is the single source of truth for the environment. Two # ways to use it: # -# 1. VS Code Dev Container — "Reopen in Container" uses +# 1. VS Code Dev Container: "Reopen in Container" uses # .devcontainer/devcontainer.json, which is *backed by* this file (it # references the `tooling` service rather than defining its own). # @@ -24,7 +24,7 @@ # Packages whose tests need MySQL uncomment the `mysql` service below (and the # `phpmyadmin` web UI if wanted), plus the `depends_on` block on `tooling`. The # `mysql` service mirrors the `db_image` package parameter used by CI, and is -# reachable from `tooling` as host `mysql` on port 3306 — matching the PhpDb +# reachable from `tooling` as host `mysql` on port 3306: matching the PhpDb # `mysql.local.php` connection convention. Packages that need a different # engine add an equivalent service here (postgres, mariadb, ...) mirroring # their own `db-image` parameter. @@ -56,13 +56,13 @@ services: - "host.docker.internal:host-gateway" volumes: # Bind-mount the source so edits are visible on both the host and the - # container. vendor/ is NOT overridden — it is the host's own copy. + # container. vendor/ is NOT overridden - it is the host's own copy. # Composer/installs inside the container write straight into the # developer's working tree on disk. - .:/app # The Composer cache lives in a named volume (Linux-native I/O, fast on # Windows) so downloads survive container rebuilds. It is only a cache - # — the developer's real artifacts all live on the host. + # - the developer's real artifacts all live on the host. - composer-cache:/tmp/composer-cache # Uncomment when the package's tests need MySQL (see the `mysql` service # below). Ensures the database is ready before the shell attaches. @@ -72,7 +72,7 @@ services: working_dir: /app # ------------------------------------------------------------------------- - # MySQL (optional) — uncomment this whole block for packages whose tests + # MySQL (optional) - uncomment this whole block for packages whose tests # need a MySQL database (e.g. webware-acl via php-db/phpdb-mysql). # # Mirror the spec's `db_image` / `db_env_json` / `db_port` Package Parameters @@ -81,7 +81,7 @@ services: # credentials below. Adjust MYSQL_DATABASE / MYSQL_USER / MYSQL_PASSWORD to # the package's test-database convention. MYSQL_ALLOW_EMPTY_PASSWORD keeps # the test-only database free of a root password and in sync with the CI - # `db_env_json` — remove it if the package pins a root password instead. + # `db_env_json` - remove it if the package pins a root password instead. # ------------------------------------------------------------------------- # mysql: # image: mysql:9.7 @@ -101,7 +101,7 @@ services: # # survives `docker compose down` (use `down -v` to wipe it). # - mysql-data:/var/lib/mysql # - # # phpMyAdmin — optional web UI for the `mysql` service above. Reachable at + # # phpMyAdmin - optional web UI for the `mysql` service above. Reachable at # # http://localhost:8080 (log in as root with an empty password, or with # # the MYSQL_USER / MYSQL_PASSWORD credentials). Uncomment alongside # # `mysql`. diff --git a/src/SchemaFactory.php b/src/SchemaFactory.php index 163b27d..9ebd4e0 100644 --- a/src/SchemaFactory.php +++ b/src/SchemaFactory.php @@ -18,8 +18,8 @@ * The factory is schema-driven: the {@see SchemaInterface} enum supplies the * unprefixed table name (its backing value) and, through the * {@see SchemaInterface::NAME} constant, the enum-wide schema identifier. - * Configuration — supplied under the `SchemaInterface::class` top-level config - * key — layers app-wide defaults and per-table overrides on top of it. + * Configuration - supplied under the `SchemaInterface::class` top-level config + * key - layers app-wide defaults and per-table overrides on top of it. * * Live identifier precedence, highest first: * diff --git a/src/Session/PhpDbSessionPersistence.php b/src/Session/PhpDbSessionPersistence.php index 0631e0d..44bc738 100644 --- a/src/Session/PhpDbSessionPersistence.php +++ b/src/Session/PhpDbSessionPersistence.php @@ -135,7 +135,7 @@ public function initializeSessionFromRequest(ServerRequestInterface $request): S $row = $this->sql->prepareStatementForSqlObject($select)->execute()?->current(); if (! is_array($row)) { - // Session not found or expired — return empty session keeping same ID. + // Session not found or expired - return empty session keeping same ID. // Browser already holds the cookie; on write it will upsert. return new Session([], $id); } @@ -150,7 +150,7 @@ public function initializeSessionFromRequest(ServerRequestInterface $request): S #[Override] public function persistSession(SessionInterface $session, ResponseInterface $response): ResponseInterface { - // Retrieve the session ID — uses SessionIdentifierAwareInterface (1.x); + // Retrieve the session ID - uses SessionIdentifierAwareInterface (1.x); // getId() moves to SessionInterface in 2.0. $id = $this->idOf($session);