Skip to content

Commit bf98cb7

Browse files
committed
Merge branch 'dependencies'
2 parents c5e42fd + 880d663 commit bf98cb7

8 files changed

Lines changed: 388 additions & 272 deletions

File tree

AGENTS-Symfony.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# AGENTS.md
2+
3+
This is a Symfony project. Check `composer.json` for the exact Symfony/PHP version
4+
in use, and read `symfony.lock` to see which recipes ran. Don't assume Doctrine,
5+
Twig, API Platform, Messenger, or Lock are installed unless one of those says so.
6+
7+
## Ask before generating
8+
9+
If the task doesn't specify, ask rather than guess:
10+
11+
- Persistence: Doctrine ORM, Doctrine ODM, or none?
12+
- Interface: server-rendered (Twig), API (Serializer, maybe API Platform), or both?
13+
- Auth: SecurityBundle, and which authenticator?
14+
15+
If you can't ask (no interactive channel), state the assumption you're making and
16+
pick the smallest option (e.g. no persistence layer) rather than scaffolding a
17+
full stack nobody asked for.
18+
19+
## Adding features: Flex, not hand-wiring
20+
21+
Install new capabilities with `composer require <package>` (e.g. `symfony/lock`,
22+
`symfony/messenger`, `orm-pack`) and let the Flex recipe register the bundle and
23+
generate its config. Don't hand-edit `config/bundles.php` or hand-write a bundle's
24+
base config; that's what the recipe is for. Don't skip a good-fit component just
25+
because it isn't installed yet; installing it is one command.
26+
27+
## Conventions
28+
29+
Follow https://symfony.com/doc/current/best_practices.html to write idiomatic
30+
Symfony:
31+
32+
- Use PHP attributes for framework metadata, and not only on controllers:
33+
`#[Route]`, `#[MapRequestPayload]`, `#[IsGranted]` on actions, `#[Assert\...]`
34+
on properties, `#[AsCommand]`, `#[AsEventListener]`, `#[AsMessageHandler]`, and
35+
`#[AsAlias]` / `#[AsTaggedItem]` / `#[Autoconfigure]` on services. No YAML or
36+
XML routing.
37+
- Rely on autowiring and autoconfiguration. Type-hint constructor arguments and
38+
let the container resolve them. Where a type-hint can't express it, stay in the
39+
class with `#[Autowire]` (parameters, env vars, expressions) or `#[Target]` (one
40+
of several implementations of an interface). A YAML service definition is the
41+
last resort, not the first.
42+
- Controllers extend `AbstractController`, stay thin, and delegate to services.
43+
- Use the framework for what it already does: Form for server-rendered forms,
44+
Validator for validation, Serializer for JSON, Messenger for async work,
45+
Security (voters, authenticators) for access control, Twig `path()`/`url()`
46+
instead of hardcoded URLs.
47+
- Before hand-writing infrastructure (locks, queues, caches, HTTP clients,
48+
mailers, schedulers) or reaching for a third-party library, check whether a
49+
Symfony component covers it. It usually does.
50+
51+
Three specifics worth spelling out, because they are easy to get wrong:
52+
53+
- Bind request data with `#[MapRequestPayload]` / `#[MapQueryString]` on action
54+
arguments, which wires up Serializer and Validator for you, instead of calling
55+
`json_decode()` or `SerializerInterface` by hand. If neither package is
56+
installed yet, `composer require` them rather than falling back to manual
57+
parsing.
58+
- Use constructor property promotion, and `readonly` for DTOs and value objects.
59+
Don't mark a service `readonly` if it might become `lazy: true`: a lazy proxy
60+
can't extend a `readonly` class.
61+
- Use `symfony/lock` (`LockFactory`) for mutual exclusion. A hand-built flag or
62+
lock file looks fine in review and is usually wrong under concurrency.
63+
64+
## Everyday workflow
65+
66+
- Run the app with `symfony serve -d`, and commands with `symfony console ...`
67+
(or `bin/console` when the Symfony CLI isn't available).
68+
- When something fails, read `var/log/dev.log` and the web profiler
69+
(`/_profiler`) before changing code.
70+
- If `maker-bundle` is installed, prefer `bin/console make:*` with every argument
71+
passed up front and `--no-interaction` where supported: makers prompt on a
72+
terminal by default, which hangs a non-interactive shell. If a maker still
73+
needs interactive input, hand-write the code instead.
74+
- If Doctrine ORM is installed, schema changes go through migrations
75+
(`bin/console make:migration`, then `doctrine:migrations:migrate`), never
76+
`doctrine:schema:update` or hand-written SQL.
77+
- `.env` is committed and holds defaults only. Real secrets belong in `.env.local`
78+
(git-ignored) or the secrets vault (`bin/console secrets:set`), read via
79+
`%env(...)%`.
80+
81+
## Testing
82+
83+
Install `symfony/test-pack` if it isn't already. Functional/HTTP tests extend
84+
`WebTestCase`; service-level tests extend `KernelTestCase`. Run
85+
`php bin/phpunit` (falls back to `vendor/bin/phpunit`). A feature isn't done
86+
until it has a test that exercises it the way a caller would, an HTTP request for
87+
a controller or a service call for a service, not just "it didn't throw."
88+
89+
## Code style
90+
91+
Symfony's coding standard, the `@Symfony` php-cs-fixer ruleset (a PSR-12-derived
92+
superset). Run `vendor/bin/php-cs-fixer fix` if `friendsofphp/php-cs-fixer` is
93+
installed; it isn't part of the skeleton by default.
94+
95+
## Discover, don't guess
96+
97+
Framework APIs change between versions and your training data may be stale. Look
98+
things up in the project instead of relying on memory:
99+
100+
- `bin/console about`: versions, environment, paths.
101+
- `bin/console debug:router`, `debug:container`, `debug:autowiring <name>`,
102+
`debug:config <bundle>`, `config:dump-reference <bundle>`: what exists and how
103+
it is configured.
104+
- `bin/console lint:container`, plus `lint:twig templates/` and
105+
`lint:yaml config/` where those packages are installed: validate before running.
106+
- Read the installed source and docblocks under `vendor/`.
107+
- Docs: https://symfony.com/doc/current/ (switch to the version matching
108+
`composer.json` if it differs).

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Dirigent is a free and open package registry for Composer, the PHP package manag
44

55
## Architecture
66

7+
@AGENTS-Symfony.md
78
@ARCHITECTURE.md
89

910
- Make sure the information in ARCHITECTURE.md is up to date and accurate.

composer.json

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"doctrine/doctrine-bundle": "^3.3.2",
1818
"doctrine/doctrine-fixtures-bundle": "^4.3.1",
1919
"doctrine/doctrine-migrations-bundle": "^4.0.1",
20-
"doctrine/orm": "^3.7.0",
20+
"doctrine/orm": "^3.7.1",
2121
"easycorp/easyadmin-bundle": "^5.5.1",
2222
"endroid/qr-code": "^6.1.3",
2323
"league/commonmark": "^2.10.1",
@@ -26,29 +26,29 @@
2626
"scheb/2fa-totp": "^8.6.1",
2727
"sentry/sentry-symfony": "^5.13",
2828
"symfony/asset": "^8.1.0",
29-
"symfony/console": "^8.1.6",
30-
"symfony/doctrine-messenger": "^8.1.6",
29+
"symfony/console": "^8.1.7",
30+
"symfony/doctrine-messenger": "^8.1.7",
3131
"symfony/dotenv": "^8.1.6",
3232
"symfony/expression-language": "^8.1.6",
3333
"symfony/flex": "^2.11",
34-
"symfony/form": "^8.1.6",
35-
"symfony/framework-bundle": "^8.1.6",
36-
"symfony/http-client": "^8.1.6",
34+
"symfony/form": "^8.1.7",
35+
"symfony/framework-bundle": "^8.1.7",
36+
"symfony/http-client": "^8.1.7",
3737
"symfony/intl": "^8.1.5",
38-
"symfony/mailer": "^8.1.5",
39-
"symfony/mime": "^8.1.6",
40-
"symfony/monolog-bundle": "^4.0.2",
41-
"symfony/process": "^8.1.6",
38+
"symfony/mailer": "^8.1.7",
39+
"symfony/mime": "^8.1.7",
40+
"symfony/monolog-bundle": "^4.1.0",
41+
"symfony/process": "^8.1.7",
4242
"symfony/property-access": "^8.1.4",
43-
"symfony/property-info": "^8.1.6",
43+
"symfony/property-info": "^8.1.7",
4444
"symfony/runtime": "^8.1.0",
45-
"symfony/scheduler": "^8.1.5",
46-
"symfony/security-bundle": "^8.1.6",
47-
"symfony/serializer": "^8.1.6",
45+
"symfony/scheduler": "^8.1.7",
46+
"symfony/security-bundle": "^8.1.7",
47+
"symfony/serializer": "^8.1.7",
4848
"symfony/stimulus-bundle": "^3.4",
49-
"symfony/string": "^8.1.2",
50-
"symfony/twig-bundle": "^8.1.2",
51-
"symfony/validator": "^8.1.6",
49+
"symfony/string": "^8.1.7",
50+
"symfony/twig-bundle": "^8.1.7",
51+
"symfony/validator": "^8.1.7",
5252
"symfony/web-link": "^8.1.0",
5353
"symfony/webpack-encore-bundle": "^2.4.1",
5454
"symfony/yaml": "^8.1.6",
@@ -58,21 +58,19 @@
5858
"twig/twig": "^3.28.0"
5959
},
6060
"require-dev": {
61-
"beluga-php/docker-php": "1.45.6",
62-
"beluga-php/docker-php-api": "7.1.45.4",
6361
"dama/doctrine-test-bundle": "^8.6",
6462
"friendsofphp/php-cs-fixer": "^3.95.25",
65-
"phpstan/phpstan": "^2.2.13",
66-
"phpunit/phpunit": "^13.3.3",
67-
"rector/rector": "^2.6.6",
63+
"phpstan/phpstan": "^2.2.14",
64+
"phpunit/phpunit": "^13.3.4",
65+
"rector/rector": "^2.6.7",
6866
"symfony/browser-kit": "^8.1.5",
6967
"symfony/css-selector": "^8.1.6",
7068
"symfony/debug-bundle": "^8.1.0",
71-
"symfony/maker-bundle": "^1.67",
69+
"symfony/maker-bundle": "^1.68",
7270
"symfony/phpunit-bridge": "^8.1.6",
7371
"symfony/stopwatch": "^8.1.0",
74-
"symfony/web-profiler-bundle": "^8.1.5",
75-
"testcontainers/testcontainers": "^1.0.10"
72+
"symfony/web-profiler-bundle": "^8.1.7",
73+
"testcontainers/testcontainers": "^1.1.0"
7674
},
7775
"conflict": {
7876
"symfony/symfony": "*"

0 commit comments

Comments
 (0)