-
-
Notifications
You must be signed in to change notification settings - Fork 150
AI support for contributors #1042
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mk-mxp
wants to merge
3
commits into
exercism:main
Choose a base branch
from
mk-mxp:ai-support
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ bin/configlet.exe | |
|
|
||
| /vendor/ | ||
| composer.lock | ||
| *.local.* | ||
|
|
||
| # IDE Files | ||
| .idea | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## What this repo is | ||
|
|
||
| This is the Exercism PHP track: the source of truth for every PHP exercise served on exercism.org. It is not an application — it's a curated set of independent exercise directories (practice + concept exercises), each containing a problem statement, a test suite, and a reference solution, plus tooling to keep them in sync with Exercism's cross-language `problem-specifications` and CI-verify that every reference solution actually passes its own tests. | ||
|
|
||
| ## Common commands | ||
|
|
||
| ```shell | ||
| composer install # install dependencies, fetches bin/configlet | ||
| composer ci # full local CI: configlet fmt + lint:check + tests:run — run before pushing | ||
| composer test:run # run every exercise's tests against its reference solution | ||
| composer test:run -- book-store # run tests for a single exercise (glob supported, e.g. "b*") | ||
| composer lint:check # phpcs — check PSR-12-derived style | ||
| composer lint:fix # phpcbf — autofix style issues | ||
| composer configlet:fmt # normalize exercise metadata files via configlet | ||
| ``` | ||
|
|
||
| `composer test:run` works by copying an exercise directory to a temp dir, overlaying the reference solution (`.meta/example.php` for practice exercises, `.meta/exemplar.php` for concept exercises) on top of the stub, stripping `markTestSkipped()` calls from the test file, and running PHPUnit directly (`bin/test.sh`). Always use `composer test:run -- <exercise-slug>` to test a single exercise rather than invoking `phpunit` directly — running the test file in place tests the stub, not the reference solution. | ||
|
|
||
| ## Repository layout | ||
|
|
||
| - `exercises/practice/<slug>/` — one dir per practice exercise: | ||
| - `<PascalName>.php` — stub the student fills in | ||
| - `<PascalName>Test.php` — PHPUnit test suite (student-facing) | ||
| - `.docs/introduction.md`, `.docs/instructions.md` — problem statement (often generated, see below) | ||
| - `.meta/example.php` — reference solution used by CI (may instead be a `.meta/example/` directory when the solution needs multiple files) | ||
| - `.meta/tests.toml` — auto-generated by `configlet sync`; controls which canonical test cases are included/excluded (`include = false`) and lets you attach a `comment` explaining a deviation. Hand edits other than `include`/`comment` get wiped on regeneration. | ||
| - `.meta/config.json` — per-exercise metadata (authors, files, etc.) | ||
| - `exercises/concept/<slug>/` — same idea but for concept exercises, which teach one specific language concept: | ||
| - reference solution is `.meta/exemplar.php` instead of `example.php` | ||
| - additional `.docs/hints.md` and `.meta/design.md` explaining pedagogical intent | ||
| - `.docs/introduction.md.tpl` may exist as the templated source for the generated `introduction.md`. A template pulls in one or more concepts' own `introduction.md` via `%{concept:<concept-slug>}` placeholders (see `concepts/<concept-name>/introduction.md`), and can add exercise-specific prose around those placeholders. **When a `.docs/introduction.md.tpl` exists, never hand-edit `.docs/introduction.md` directly — edit the `.tpl` and regenerate with `bin/configlet generate` (not `configlet fmt`, which will fail/overwrite it).** | ||
| - `concepts/<concept-name>/` — the concept glossary (`about.md`, `links.md`) that concept exercises reference by slug (e.g. `basic-syntax`, `arrays`); a concept exercise's `.meta/config.json` lists which concepts it teaches and which are prerequisites. | ||
| - `config.json` (repo root) — the master Exercism track manifest: registers every exercise, its UUID, concepts/prerequisites, difficulty, and the file-role patterns (`%{pascal_slug}.php`, etc.) `configlet` uses to generate per-exercise scaffolding. | ||
| - `bin/configlet` — the official Exercism tool (fetched via `bin/fetch-configlet`, run through `composer` scripts) that validates `config.json` against the exercise directories and formats metadata (`configlet fmt`, `configlet sync`, `configlet create`). | ||
| - `src/Exercism/Sniffs/` — a custom PHP_CodeSniffer sniff (`ExplainStrictTypesSniff`) enforced by `phpcs.xml` on top of PSR-12. | ||
| - `contribution/` — auxiliary, not-fully-maintained tooling (e.g. a Symfony-based test generator, a deprecated-exercise checker); treat as separate from the main track content. | ||
|
|
||
| ## Coding standard specifics (phpcs.xml) | ||
|
|
||
| Style is PSR-12 with these deviations: | ||
|
|
||
| - Namespace/multiple-class-per-file rules are relaxed (exercises are single-file, namespace-free by convention). | ||
| - `declare(strict_types=1)` is required on practice-exercise solution files but is explicitly excluded on `.meta/*.php` reference solutions, all `concept/*` exercises, and `hello-world`. | ||
| - The custom `ExplainStrictTypesSniff` requires strict-types declarations to carry an explanatory comment; it's excluded on test files, `.meta/*.php`, `src/*`, and `contribution/*.php`. | ||
| - `Squiz.Scope.MethodScope.Missing` is excluded for `concept/city-office` and `concept/windowing-system` (these intentionally use non-method function scope for teaching purposes). | ||
| - `use` statements must be alphabetically sorted. | ||
|
|
||
| ## Adding/modifying exercises | ||
|
|
||
| 1. Scaffold a new practice exercise: `bin/configlet create --practice-exercise <slug>` (creates `exercises/practice/<slug>/`). | ||
| 2. Write/edit `.meta/example.php` (or `exemplar.php` for concept exercises) and the test file; mark canonical test cases you deliberately skip in `.meta/tests.toml` with `include = false` (and a `comment` explaining why). | ||
| 3. There is a WIP test generator under `contribution/generator` (Symfony console app) usable via `composer -d contribution/generator install && contribution/generator/bin/console app:create-tests '<slug>'`, followed by `composer lint:fix`. | ||
| 4. If you change an exercise's difficulty or add a practice exercise, run `bin/order-exercises.sh` to reorder `config.json` accordingly (requires `jq`). | ||
| 5. If you add a new practice exercise that should stay in sync with `problem-specifications`, add its slug to `bin/auto-sync.txt` — `bin/auto-sync.sh` reads that list and runs `configlet sync` (update mode) only for the exercises named in it, so exercises left off the list are never auto-synced. | ||
| 6. Run `composer ci` before opening a PR — this is what GitHub Actions enforces (PHP 8.2–8.4 across Linux/Windows/macOS). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this directory. | ||
|
|
||
| ## Scope | ||
|
|
||
| This applies to `contribution/` only. It's a grab-bag of standalone maintainer tooling for the Exercism PHP track (see the parent `../CLAUDE.md` for the track itself) — not part of the track content shipped to students, not covered by the root `composer.json`/`phpcs.xml`, and not exercised by `composer ci`. | ||
|
|
||
| - `generator/` — a proof-of-concept Symfony console app that auto-generates exercise test files from `problem-specifications` canonical data, using `nikic/php-parser`. Has its own `composer.json` (PHP >=8.2, Symfony 7.0, PHPUnit 11) independent of the root project's dependencies. | ||
| - `checkDeprecatedExercises.php` — a standalone PHP script (no dependencies) with a hardcoded list of exercise slugs; it queries GitHub for a `.deprecated` marker on each in `exercism/problem-specifications` and reports which ones should be marked deprecated in the root `config.json` and then removed from the script's own list. | ||
|
|
||
| If a directory in here isn't listed above but shows up on disk anyway, check for a `CLAUDE.local.md` in this folder (gitignored, machine-specific) before assuming it's part of the project. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```shell | ||
| composer -d contribution/generator install # install the generator's own dependencies | ||
| contribution/generator/bin/console app:create-tests '<slug>' # generate a test file for an exercise | ||
| composer lint:fix # fix style on the generated file, from repo root | ||
| ``` | ||
|
|
||
| ```shell | ||
| php contribution/checkDeprecatedExercises.php # list exercises that problem-specifications has deprecated | ||
| ``` | ||
|
|
||
| ## Notes | ||
|
|
||
| - The generator is explicitly a PoC ("Let me know what you think" in `generator/README.md`) — treat it as unmaintained/experimental, not a polished tool with guaranteed correctness. | ||
| - Generated test files still need to go through the normal track workflow (write/adjust `.meta/example.php`, `.meta/tests.toml`, `composer lint:fix`, `composer test:run -- <slug>`) described in the root `CLAUDE.md`. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I personally find a lot of issues with LLM outputs quality (and their societal / environmental impacts). I'm not completely against introducing this. BUT:
@iHiDuses Claude though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of LLMs, too. I currently learn to use them (as we all have to), and a project without agent supporting files burns a lot more tokens (energy) than a project with them. Contributors use them anyways already, so let's save some tokens here.
To 1: I know, that Claude does not read AGENTS.md on purpose. That's a shame, but they are current market leaders (people urged to use Copilot for free on GitHub is no market share). I do not have another coding agent at hand to test support (cursor et al.). So, I can only reliably provide Claude information and supporting files.
To 2: Agent files are auto-generated and maintained by the agents. They read the README and code, and write their prose to safe tokens for the future. I do not intend to remove / reduce human first information anywhere.
To 3: gitignoring local agent files is common practice like
.env.local.*already are. Especially with the many CDEs (like GitHub codespaces) global settings are unreliable. They also may contain security information (like tokens, keys for MCPs), as they are personal files.