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
6 changes: 4 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ This repository is a PHP monorepo containing many packages under `src/`. This gu
- Prefer minimal, targeted changes; avoid refactors beyond the task scope.
- Never edit anything under any `vendor/` directory or generated artifacts like `dist/`.
- Maintain backward compatibility for public APIs unless explicitly instructed otherwise.
- Update relevant docs under `docs/` when behavior or public APIs change.
- Update relevant docs under `docs/` when behavior, commands, or public APIs change.
- When adding flags or changing CLI behavior, update command help and the related
pages under `docs/tools/` (e.g., Chorale) and link new pages in `docs/SUMMARY.md`.
- Keep code style consistent; use provided tooling to format, lint, and check types.

## Setup
Expand Down Expand Up @@ -70,4 +72,4 @@ This repository is a PHP monorepo containing many packages under `src/`. This gu
- Build passes: `make test` (optionally with coverage).
- Code quality passes: `make php-cs-fixer`, `make psalm`, and (if applicable) `make upgrade-code`.
- Docs updated where needed.
- No changes to `vendor/` or generated artifacts.
- No changes to `vendor/` or generated artifacts.
9 changes: 9 additions & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
## 🔧 Tools

* [Chorale](tools/chorale.md)
* [Commands](tools/chorale/commands/README.md)
* [Setup](tools/chorale/commands/setup.md)
* [Plan](tools/chorale/commands/plan.md)
* [Apply](tools/chorale/commands/apply.md)
* [Run](tools/chorale/commands/run.md)
* [Concepts](tools/chorale/concepts.md)
* [Configuration](tools/chorale/config.md)
* [Mirroring & Overrides](tools/chorale/mirroring.md)
* [Rule Matrix & Examples](tools/chorale/rules-matrix.md)

## Symfony Bundles

Expand Down
14 changes: 10 additions & 4 deletions docs/tools/chorale.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ Run the commands from the project root:

```bash
# create chorale.yaml by scanning packages
php bin/chorale setup
chorale setup

# preview changes without modifying files
php bin/chorale plan --json > plan.json
chorale plan --json > plan.json

# apply an exported plan
php bin/chorale apply --file plan.json
chorale apply --file plan.json

# build and apply a plan in one go
php bin/chorale run
chorale run
```

Chorale automatically merges all package `composer.json` files into the root `composer.json` so the monorepo can be installed as a single package. Any dependency conflicts are recorded under the `extra.chorale.dependency-conflicts` section for review.
Expand All @@ -35,3 +35,9 @@ Chorale automatically merges all package `composer.json` files into the root `co
- `plan` – build a plan for splitting packages and root updates.
- `run` – build and immediately apply a plan.
- `apply` – execute steps from a JSON plan file.

See also:
- Commands: tools/chorale/commands/README.md
- Core concepts: tools/chorale/concepts.md
- Configuration and chorale.yaml: tools/chorale/config.md
- Composer mirroring and overrides: tools/chorale/mirroring.md
10 changes: 10 additions & 0 deletions docs/tools/chorale/commands/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Chorale Commands

This section documents each Chorale CLI command in detail.

- Setup: initializes or updates `chorale.yaml` by scanning packages.
- Plan: builds a dry‑run plan of steps.
- Apply: applies steps from a JSON plan file.
- Run: builds and applies a plan in one command.

See also the configuration reference and rule matrix for how values are computed.
42 changes: 42 additions & 0 deletions docs/tools/chorale/commands/apply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Apply Command

Applies steps from a JSON plan previously exported by `chorale plan --json`.

## Usage

```bash
chorale apply --file plan.json [--project-root PATH]
```

## Options

- `--project-root=PATH`: Override project root (defaults to current directory)
- `--file=FILE` (or `-f`): Path to JSON plan file (default: `plan.json`)

## Examples

```bash
# Apply a plan from the current directory
chorale apply --file plan.json

# Apply a plan from a different root
chorale apply --project-root /path/to/repo --file /tmp/plan.json
```

## Plan File Format (pretty‑printed)

The plan file is the JSON output produced by `chorale plan --json`:

```json
{
"version": 1,
"steps": [
{
"type": "package-version-update",
"name": "sonsofphp/cache",
"version": "1.2.3"
}
],
"noop": {}
}
```
127 changes: 127 additions & 0 deletions docs/tools/chorale/commands/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Chorale Plan Command

The `plan` command is an advanced dry‑run that inspects your monorepo and prints exactly what would change — without writing anything. Use it to understand and validate changes before applying them.

## Summary

- Checks package versions against the monorepo root version
- Computes package `composer.json` edits via the rule engine
- Updates the root `composer.json` (require/replace) as an aggregator
- Merges package dependencies into the root (with conflicts reported)
- Decides which packages need a split (and why)

## Usage

```bash
chorale plan [<vendor/name>] [options]
```

- `<vendor/name>`: Optional composer package name to focus on a single package
(e.g., `sonsofphp/cache`). This reduces noise for large monorepos.

## Options

- Verbosity levels control detail:
- default: concise one‑line summaries
- `-v`: detailed blocks (per‑section details)
- `-vv`: detailed blocks + no‑op summaries
- `-vvv`: everything above plus full JSON plan printed at the end
- `--composer-only`: Only include composer-related steps; exclude split steps
- `--show-all`: Include no‑op summaries (same as `-vv` or higher)
- `--json`: Output as JSON; ideal for `apply` or external tooling
- `--project-root=PATH`: Explicit project root (defaults to current directory)
- `--paths=DIR ...`: Limit discovery to specific package path(s)
- `--force-split`: Plan split steps even if content appears unchanged
- `--verify-remote`: Verify remote state if local lockfiles are missing/stale
- `--strict`: Exit non‑zero when issues are detected (e.g., conflicts, missing root version)

## Examples

```bash
# Concise one‑liners (default)
chorale plan

# Detailed output
chorale plan -v

# Detailed + show no‑ops
chorale plan -vv

# Show full JSON at the end (also printed as human output first)
chorale plan -vvv

# JSON output for apply
chorale plan --json > plan.json

# Focus on one package by composer name
chorale plan sonsofphp/cache

# Focused + detailed
chorale plan sonsofphp/cache -v

# Limit discovery to a folder (path)
chorale plan --paths src/SonsOfPHP/Component/Cache
```

## Output Breakdown

Plan output is grouped by step type:

- `Split steps`: Shows package path → repo, splitter, branch, tag strategy, and reasons
- `Package versions`: Shows the package name, target version, previous version, and reason
- `Package metadata`: Lists keys to mirror and pretty‑prints the exact `apply` JSON block
- `Root composer: aggregator`: Prints the final `require` and `replace` maps
- `Root composer: dependency merge`: Prints merged `require` and `require‑dev`, plus conflicts
- `Root composer: maintenance`: Maintenance actions like `validate`

### Delta Notation

Composer maps show a delta summary:

```
[+added/-removed/~changed]
```

This is printed inline in summaries and also included in JSON under `meta` as
`delta_require`, `delta_replace`, and `delta_require_dev` where applicable.

## JSON Schema (version 1)

The `--json` output contains:

- `steps`: Array of step objects with type‑specific fields
- `noop`: Optional summary of skipped groups when `--show-all` is used
- `meta`: For root steps, delta objects summarizing changes

Example snippet (root update):

```json
{
"type": "composer-root-update",
"root": "sonsofphp/monorepo",
"root_version": "1.2.3",
"require": {
"sonsofphp/cache": "1.2.3"
},
"replace": {
"sonsofphp/cache": "1.2.3"
},
"meta": {
"delta_require": {
"added": 1,
"removed": 0,
"changed": 0
},
"delta_replace": {
"added": 1,
"removed": 0,
"changed": 0
}
}
}
```

## Tips

- Combine the positional `<vendor/name>` with `--json` to isolate and export a single package’s plan.
- For CI checks, run with `--strict` so the command exits non‑zero when action is required.
28 changes: 28 additions & 0 deletions docs/tools/chorale/commands/run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Run Command

Builds a plan and applies it in one step. Equivalent to `chorale plan` followed by `chorale apply`.

## Usage

```bash
chorale run [options]
```

## Options

- `--project-root=PATH`: Override project root (defaults to current directory)
- `--paths=DIR ...`: Limit discovery to specific package paths
- `--force-split`: Plan split steps even if content appears unchanged
- `--verify-remote`: Verify remote state if lockfiles are missing/stale
- `--strict`: Exit non‑zero on issues (e.g., missing root version, conflicts)
- `--show-all`: Include no‑op summaries in output

## Examples

```bash
# Standard run
chorale run

# Limit scope and enable strict mode
chorale run --paths src/SonsOfPHP/Component/Cache --strict
```
65 changes: 65 additions & 0 deletions docs/tools/chorale/commands/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Setup Command

Initializes or updates `chorale.yaml` by scanning your repository for packages and applying sensible defaults.

## Usage

```bash
chorale setup [options]
```

## Options

- `--project-root=PATH`: Override project root (defaults to current directory)
- `--paths=DIR ...`: Limit discovery to specific paths (relative to root)
- `--discover-only`: Only scan and print results; do not write
- `--write`: Write without confirmation (pair with `--non-interactive` in CI)
- `--non-interactive`: Never prompt for confirmation
- `--accept-all`: Accept suggested adds/renames during interactive runs
- `--strict`: Treat warnings as errors (non‑zero exit)
- `--json`: Emit a machine‑readable JSON report

## Examples

```bash
# Interactive scan and write
chorale setup

# Discover only; do not write any changes
chorale setup --discover-only

# CI‑style non‑interactive write
chorale setup --write --non-interactive

# Limit discovery to a subset of paths
chorale setup --paths src/SonsOfPHP/Component/Cache src/SonsOfPHP/Component/Clock

# Strict mode with JSON report
chorale setup --json --strict > setup-report.json
```

## JSON Report (pretty‑printed)

Example shape of the JSON emitted by `--json` (fields omitted for brevity):

```json
{
"defaults": {
"repo_host": "github.com",
"repo_vendor": "sonsofphp",
"repo_name_template": "{name:kebab}",
"default_repo_template": "git@{repo_host}:{repo_vendor}/{name:kebab}.git"
},
"groups": {
"ok": ["src/SonsOfPHP/Component/Cache"],
"new": ["src/SonsOfPHP/Component/Clock"],
"renamed": [],
"drift": [],
"issues": [],
"conflicts": []
},
"actions": [
{ "type": "add", "path": "src/SonsOfPHP/Component/Clock" }
]
}
```
34 changes: 34 additions & 0 deletions docs/tools/chorale/concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Chorale Concepts

Chorale provides a small set of concepts to manage large monorepos predictably.

## Patterns and Targets

- `patterns`: Glob‑like rules that define which directories are considered packages.
- Supports `*`, `?`, and `**` wildcards.
- Example: `src/**/Cookie`, `src/SonsOfPHP/*`
- `targets`: Per‑package overrides keyed by path (e.g., repo vendor or template).

## Repository Rendering

Chorale generates repository URLs from a template with placeholders and filters:

- Placeholders: `{name}`, `{repo_host}`, `{repo_vendor}`, `{repo_name_template}`, `{default_repo_template}`, `{path}`, `{tag}`
- Filters: `raw`, `lower`, `upper`, `kebab`, `snake`, `camel`, `pascal`, `dot`
- Example: `{repo_host}:{repo_vendor}/{name:kebab}.git`

## Composer Sync

- Package metadata sync: The rule engine computes `apply` diffs for `composer.json` keys per package.
- Root aggregator: Builds `require`/`replace` maps for the root composer.json.
- Dependency merge: Merges package `require` and `require-dev` into the root, reporting conflicts.
- Delta notation: `+added/-removed/~changed` quickly summarizes map changes.

## Splitting

Split steps are planned when content changes or policy indicates a split is needed. Reasons are printed in the plan output and include content hashes, remote state, and policy options (force, tag strategy, branch).

## Strict Mode

Use `--strict` to make `plan` and `run` exit non‑zero when issues are detected (missing root version, dependency conflicts, etc.). This is useful in CI to gate merges.

Loading