Skip to content
Merged
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
23 changes: 18 additions & 5 deletions .eddy/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,27 @@ A broken block fails quietly. Every file stays valid, and `composer update-snaps

`TemplateMarkersTest` checks all 5 rules across the template.

In Markdown, open a block with the blank line that separates it from the text before it, the way `CONTRIBUTING.dist.md` does. A removed block then takes its blank line with it, where a blank line on each side of it would leave a double blank line behind. `InstallProcessTest` checks the generated `AGENTS.md`, `CONTRIBUTING.md` and `README.md` for that across the command wrapper and Drupal major selections.

### Text rendered from the answers

A block removes whole lines, so it can't trim a line that names several options. `install.php` renders those lines instead. The template holds the text for every option, and `install.php` replaces it with the same function's text for the selected options:

- `core_version_requirement()` renders `core_version_requirement` in `your_extension.info.yml`, such as `^10 || ^11` for Drupal 10 and 11.
- `phpunit_config_comment()` renders the comment that opens `phpunit.xml`. It leaves out a major with a `phpunit.d<major>.xml` of its own, which `eddy-assemble` uses for that major instead, so with Drupal 10 and 11 selected it names Drupal 11 only.
- `command_wrapper_text()` renders "`make` or `ahoy`", and "`make build` or `ahoy build`" for the `build`, `lint` and `test` commands. Ahoy alone turns them into "`ahoy`" and "`ahoy build`". Without a wrapper, these phrases sit in `DEV_COMMAND_WRAPPER` blocks, and "The command wrappers and CI run it" in `AGENTS.md` becomes "CI runs it".

A replacement finds nothing once the template text drifts from the every-option rendering, and the text then ships unrendered. `InstallProcessTest` renders each one for every selection, so it fails when a template edit breaks a replacement. A new phrase that names both wrappers needs its command added to `process_command_wrapper_text()`.

### Adding a Drupal major

1. In `install.php`, add the major to `drupal_version_options()` and to the `INSTALL_DRUPAL_VERSION` entry of `print_help()`.
2. Add a `DRUPAL_<major>` block wherever the existing majors have one. `git grep -n '#;< DRUPAL_'` lists them: today that's the `lint` and `test` matrices in `.github/workflows/test.yml` and the badges in `README.dist.md`.
3. To have the major start checked, add it to `drupal_version_default()` and update the defaults that `print_help()` and `README.md` name. Then set `extra.eddy.drupal-version` in `composer.dev.json` to the highest major `drupal_version_default()` returns: `InstallHelpersTest` fails until they agree.
4. Review `.eddy/tooling/src/eddy-assemble`. It picks the PHPUnit, `symfony/phpunit-bridge` and Rector constraints by major, and it uses `phpunit.d<major>.xml` in place of `phpunit.xml` when that file exists.
5. Update `README.md` where it lists the majors (the badges, the CI job table and the branch protection table) and the matrix line in `AGENTS.md`.
6. Update the expected majors in `InstallHelpersTest` and the Drupal data providers in `InstallProcessTest`, add a `d<major>_only` dataset to `InstallTest`, then regenerate the snapshot fixtures.
2. Add a `DRUPAL_<major>` block wherever the existing majors have one. `git grep -n '#;< DRUPAL_'` lists them: today that's the `lint` and `test` matrices in `.github/workflows/test.yml`, the badges in `README.dist.md` and the matrix list in `AGENTS.md`.
3. Add the major to `core_version_requirement` in `your_extension.info.yml`, and to the comment that opens `phpunit.xml` unless the major gets a `phpunit.d<major>.xml` of its own (see [Text rendered from the answers](#text-rendered-from-the-answers)).
4. To have the major start checked, add it to `drupal_version_default()` and update the defaults that `print_help()` and `README.md` name. Then set `extra.eddy.drupal-version` in `composer.dev.json` to the highest major `drupal_version_default()` returns: `InstallHelpersTest` fails until they agree.
5. Review `.eddy/tooling/src/eddy-assemble`. It picks the PHPUnit, `symfony/phpunit-bridge` and Rector constraints by major, and it uses `phpunit.d<major>.xml` in place of `phpunit.xml` when that file exists.
6. Update `README.md` where it lists the majors: the badges, the CI job table and the branch protection table.
7. Update the expected majors in `InstallHelpersTest` and the Drupal data providers in `InstallProcessTest`, add a `d<major>_only` dataset to `InstallTest`, then regenerate the snapshot fixtures.

### Adding a development tool

Expand Down
3 changes: 0 additions & 3 deletions .eddy/tests/fixtures/install/_baseline/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,3 @@ indent_size = 2

[*.xml]
indent_size = 4

[Makefile*]
indent_style = tab
18 changes: 9 additions & 9 deletions .eddy/tests/fixtures/install/_baseline/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ This file provides guidance to AI agents when working with code in this reposito

## Overview

This is a Force Crystal template for creating contributed modules or themes. The project provides a complete development environment with CI configuration, testing setup, and deployment automation for publishing to Drupal.org.
Force Crystal (`force_crystal`) is a Drupal module. The project provides a complete development environment with CI configuration, testing setup, and deployment automation for publishing to Drupal.org.

## Development Commands

**HARD RULE - use the provided command wrappers, never the tool binaries directly.** When `make` or `ahoy` exposes a command for a task, use that command; do not call the underlying binary directly. Each wrapper `chdir`s into `build/` and runs the tool with the config, plugins, and environment that CI uses, so a raw invocation from the repository root silently diverges from CI - it can pass locally while CI fails (or vice versa), or crash outright when a relative path resolves against the wrong directory. If no wrapped command covers what you need, extend the `make` / `ahoy` target rather than making a one-off raw call; if that is not feasible, stop and ask.

**HARD RULE - use the provided command wrappers, never the tool binaries directly.** When `ahoy` exposes a command for a task, use that command; do not call the underlying binary directly. Each wrapper `chdir`s into `build/` and runs the tool with the config, plugins, and environment that CI uses, so a raw invocation from the repository root silently diverges from CI - it can pass locally while CI fails (or vice versa), or crash outright when a relative path resolves against the wrong directory. If no wrapped command covers what you need, extend the `ahoy` target rather than making a one-off raw call; if that is not feasible, stop and ask.

Run each tool through its `ahoy` wrapper, never the binary directly:

Expand All @@ -25,8 +24,7 @@ Run each tool through its `ahoy` wrapper, never the binary directly:

### Build and Environment Management


**Using Ahoy (alternative):**
**Using Ahoy:**
- `ahoy build` - Complete build process
- `ahoy assemble` - Assemble codebase
- `ahoy start` - Start development server
Expand Down Expand Up @@ -90,10 +88,10 @@ Run each tool through its `ahoy` wrapper, never the binary directly:

## Development Workflow

1. Build environment: `make build` or `ahoy build`
1. Build environment: `ahoy build`
2. Develop Force Crystal code in `src/`
3. Check standards: `make lint` or `ahoy lint`
4. Run tests: `make test` or `ahoy test`
3. Check standards: `ahoy lint`
4. Run tests: `ahoy test`
5. Access site at http://localhost:8000

## Code Quality Tools
Expand All @@ -107,7 +105,9 @@ Run each tool through its `ahoy` wrapper, never the binary directly:
## CI/CD Support

- **GitHub Actions**: `.github/workflows/test.yml` and deployment
- **Matrix testing**: PHP 8.3-8.5, Drupal 10-12
- **Matrix testing**:
- Drupal 10 on PHP 8.3-8.4
- Drupal 11 on PHP 8.3-8.5
- **Automated deployment**: Mirror to Drupal.org after CI passes

## Important Notes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Force Crystal
type: module
description: Force Crystal example.
package: Testing
core_version_requirement: ^10 || ^11 || ^12
core_version_requirement: ^10 || ^11

dependencies:
- drupal:config
Expand Down
2 changes: 1 addition & 1 deletion .eddy/tests/fixtures/install/_baseline/phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Drupal 11 and 12 PHPUnit configuration. -->
<!-- Drupal 11 PHPUnit configuration. -->
<!-- For how to customize PHPUnit configuration, see web/core/tests/README.md. -->
<!-- TODO set checkForUnintentionallyCoveredCode="true" once https://www.drupal.org/node/2626832 is resolved. -->
<!-- PHPUnit expects functional tests to be run with either a privileged user
Expand Down
8 changes: 8 additions & 0 deletions .eddy/tests/fixtures/install/d10_only/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@@ -107,7 +107,6 @@
- **GitHub Actions**: `.github/workflows/test.yml` and deployment
- **Matrix testing**:
- Drupal 10 on PHP 8.3-8.4
- - Drupal 11 on PHP 8.3-8.5
- **Automated deployment**: Mirror to Drupal.org after CI passes

## Important Notes
9 changes: 9 additions & 0 deletions .eddy/tests/fixtures/install/d10_only/force_crystal.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@@ -2,7 +2,7 @@
type: module
description: Force Crystal example.
package: Testing
-core_version_requirement: ^10 || ^11
+core_version_requirement: ^10

dependencies:
- drupal:config
7 changes: 7 additions & 0 deletions .eddy/tests/fixtures/install/d10_only/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Drupal 11 PHPUnit configuration. -->
+<!-- PHPUnit configuration. -->
<!-- For how to customize PHPUnit configuration, see web/core/tests/README.md. -->
<!-- TODO set checkForUnintentionallyCoveredCode="true" once https://www.drupal.org/node/2626832 is resolved. -->
<!-- PHPUnit expects functional tests to be run with either a privileged user
8 changes: 8 additions & 0 deletions .eddy/tests/fixtures/install/d11_only/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@@ -106,7 +106,6 @@

- **GitHub Actions**: `.github/workflows/test.yml` and deployment
- **Matrix testing**:
- - Drupal 10 on PHP 8.3-8.4
- Drupal 11 on PHP 8.3-8.5
- **Automated deployment**: Mirror to Drupal.org after CI passes

9 changes: 9 additions & 0 deletions .eddy/tests/fixtures/install/d11_only/force_crystal.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@@ -2,7 +2,7 @@
type: module
description: Force Crystal example.
package: Testing
-core_version_requirement: ^10 || ^11
+core_version_requirement: ^11

dependencies:
- drupal:config
10 changes: 10 additions & 0 deletions .eddy/tests/fixtures/install/d12_only/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@@ -106,8 +106,7 @@

- **GitHub Actions**: `.github/workflows/test.yml` and deployment
- **Matrix testing**:
- - Drupal 10 on PHP 8.3-8.4
- - Drupal 11 on PHP 8.3-8.5
+ - Drupal 12 on PHP 8.5
- **Automated deployment**: Mirror to Drupal.org after CI passes

## Important Notes
9 changes: 9 additions & 0 deletions .eddy/tests/fixtures/install/d12_only/force_crystal.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@@ -2,7 +2,7 @@
type: module
description: Force Crystal example.
package: Testing
-core_version_requirement: ^10 || ^11
+core_version_requirement: ^12

dependencies:
- drupal:config
7 changes: 7 additions & 0 deletions .eddy/tests/fixtures/install/d12_only/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Drupal 11 PHPUnit configuration. -->
+<!-- Drupal 12 PHPUnit configuration. -->
<!-- For how to customize PHPUnit configuration, see web/core/tests/README.md. -->
<!-- TODO set checkForUnintentionallyCoveredCode="true" once https://www.drupal.org/node/2626832 is resolved. -->
<!-- PHPUnit expects functional tests to be run with either a privileged user
7 changes: 7 additions & 0 deletions .eddy/tests/fixtures/install/gha_both_wrappers/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@@ -24,3 +24,6 @@

[*.xml]
indent_size = 4
+
+[Makefile*]
+indent_style = tab
36 changes: 27 additions & 9 deletions .eddy/tests/fixtures/install/gha_both_wrappers/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
@@ -10,7 +10,18 @@
@@ -8,8 +8,20 @@

**HARD RULE - use the provided command wrappers, never the tool binaries directly.** When `make` or `ahoy` exposes a command for a task, use that command; do not call the underlying binary directly. Each wrapper `chdir`s into `build/` and runs the tool with the config, plugins, and environment that CI uses, so a raw invocation from the repository root silently diverges from CI - it can pass locally while CI fails (or vice versa), or crash outright when a relative path resolves against the wrong directory. If no wrapped command covers what you need, extend the `make` / `ahoy` target rather than making a one-off raw call; if that is not feasible, stop and ask.
## Development Commands

+Run each tool through its `make` wrapper, never the binary directly:
-**HARD RULE - use the provided command wrappers, never the tool binaries directly.** When `ahoy` exposes a command for a task, use that command; do not call the underlying binary directly. Each wrapper `chdir`s into `build/` and runs the tool with the config, plugins, and environment that CI uses, so a raw invocation from the repository root silently diverges from CI - it can pass locally while CI fails (or vice versa), or crash outright when a relative path resolves against the wrong directory. If no wrapped command covers what you need, extend the `ahoy` target rather than making a one-off raw call; if that is not feasible, stop and ask.
+**HARD RULE - use the provided command wrappers, never the tool binaries directly.** When `make` or `ahoy` exposes a command for a task, use that command; do not call the underlying binary directly. Each wrapper `chdir`s into `build/` and runs the tool with the config, plugins, and environment that CI uses, so a raw invocation from the repository root silently diverges from CI - it can pass locally while CI fails (or vice versa), or crash outright when a relative path resolves against the wrong directory. If no wrapped command covers what you need, extend the `make` or `ahoy` target rather than making a one-off raw call; if that is not feasible, stop and ask.

+Run each tool through its `make` wrapper, never the binary directly:
+
+- **PHPCS / PHPCBF**: `make lint` / `make lint-fix` - never `vendor/bin/phpcs` or `vendor/bin/phpcbf`.
+- **PHPStan**: `make lint` - never `vendor/bin/phpstan`.
+- **Rector**: `make lint` (dry-run) / `make lint-fix` - never `vendor/bin/rector`.
Expand All @@ -17,21 +20,22 @@
Run each tool through its `ahoy` wrapper, never the binary directly:

- **PHPCS / PHPCBF**: `ahoy lint` / `ahoy lint-fix` - never `vendor/bin/phpcs` or `vendor/bin/phpcbf`.
@@ -25,6 +36,13 @@
@@ -24,6 +36,14 @@

### Build and Environment Management

+**Using Make (default):**
+**Using Make:**
+- `make build` - Complete build (stop → assemble → start → provision)
+- `make assemble` - Assemble codebase with dependencies
+- `make start` - Start PHP development server
+- `make stop` - Stop development server
+- `make provision` - Install/provision Drupal site
+- `make reset` - Clean build directory, logs and installed tooling (aliases: `make delete`, `make destroy`)
**Using Ahoy (alternative):**
+
**Using Ahoy:**
- `ahoy build` - Complete build process
@@ -37,10 +55,20 @@
- `ahoy assemble` - Assemble codebase
@@ -35,10 +55,20 @@
### Code Quality

**Linting:**
Expand All @@ -52,7 +56,7 @@
- `ahoy test` - Run all tests
- `ahoy test-unit` - Run unit tests only
- `ahoy test-kernel` - Run kernel tests only
@@ -52,11 +80,14 @@
@@ -50,11 +80,14 @@

### Drupal Commands

Expand All @@ -67,3 +71,17 @@
- `ahoy info` - Print a read-only summary of PHP/Drupal/Composer/Drush/Node/npm versions, webserver host/port (with source), site URL, XDebug state, WebDriver port, build directory, database path, and active profile. (alias: `ahoy describe`)

## Project Structure
@@ -88,10 +121,10 @@

## Development Workflow

-1. Build environment: `ahoy build`
+1. Build environment: `make build` or `ahoy build`
2. Develop Force Crystal code in `src/`
-3. Check standards: `ahoy lint`
-4. Run tests: `ahoy test`
+3. Check standards: `make lint` or `ahoy lint`
+4. Run tests: `make test` or `ahoy test`
5. Access site at http://localhost:8000

## Code Quality Tools
7 changes: 7 additions & 0 deletions .eddy/tests/fixtures/install/gha_makefile/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@@ -24,3 +24,6 @@

[*.xml]
indent_size = 4
+
+[Makefile*]
+indent_style = tab
Loading
Loading