EE-283: Add Symfony 7.4 support - #19
vinayak-iyer-paysera wants to merge 43 commits into
Conversation
…le uses framework-bundle, security-bundle and validator (and yaml in require-dev) now allow ^7.4. The code also uses config, dependency-injection, http-foundation, http-kernel, routing, security-core and property-access directly, but composer.json did not name them. They arrived through other packages with no limit, so on PHP 8.3 an install next to the 6.4 bundles took routing, http-foundation and security-core 7.4, and 144 of the 259 tests failed. They are now required at the same constraint as the bundles. psr/log also allows ^3.0. The doctrine/orm dev floor moves to 2.6.3: with the lowest dependencies on PHP 7.4, 2.6.0 failed 140 tests with "continue targeting switch is equivalent to break". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Symfony axis gains 7.*, excluded on PHP 7.1 to 8.1 because Symfony 7 needs PHP 8.2, so PHP 8.2 and 8.3 each get one Symfony 7 job with the highest dependencies. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Symfony 7 reads no Doctrine annotations and dropped two settings the test application used, so on 7.4 the suite could not boot. Each line now gets what it accepts: - The fixture entities are mapped in Doctrine XML (one mapping for every Doctrine version) instead of @Orm docblocks. - The routes defined in XML move to explicit_routing.xml. Symfony 7 imports that file and the attribute controllers only (sf7_routing.yml); the two docblock-routed controllers that other tests rely on get attribute twins with the same paths. The docblock half of FunctionalAnnotationsTest is skipped on Symfony 7. - The Symfony 7 security settings omit enable_authenticator_manager (removed in 7.0). - The fixture bundle's Configuration declares its TreeBuilder return type. - HttpKernelHelper looked for the constant "…HttpKernelInterfaceMAIN_REQUEST" (no "::"), so it always fell back to MASTER_REQUEST, which Symfony 7 removed. - EntityValidatorTest no longer marks three cases as asserting nothing: they expect the validator to be called once. With PHPUnit 7.5 and Mockery 1.3 those cases were reported as risky because Mockery counted its expectations as assertions. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Configuration::getConfigTreeBuilder() now returns TreeBuilder: Symfony 7's ConfigurationInterface declares that type, and without it the bundle cannot be loaded on Symfony 7 (fatal "must be compatible"). PayseraApiExtension::load() now returns void, which Symfony 8 requires; Symfony 7.4 only reports the missing type as a deprecation. A subclass that overrides either method without the type stops compiling. No such subclass exists in the applications that use the bundle. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The locale listener asked Request::getPreferredLanguage() to choose between a placeholder
"default" and the configured locales, and treated "default" as no match. Symfony 7.1 rewrote
that method to match by prefix, so "default" now wins whenever a request asks for German
("default" starts with "de"), and it also ranks the languages differently (en-US now matches
"en" before a de-CH;q=0.9 matches "de").
The listener now matches the header itself with the rule Symfony 3.4 to 7.0 apply: the first
header language, in the client's order of preference, that is a configured locale, where a
regional variant also offers its primary language unless the header lists it. The results are
unchanged below Symfony 7.1. The existing eight test cases stay as they were; five cases are
added, three of which fail on Symfony 7.4 with the old listener.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Symfony 7 gives the route loader no Doctrine annotation reader, so on Symfony 7 a controller routed with #[Route] but configured with the bundle's docblock annotations (@Body, @query, @PathAttribute, @ResponseNormalization, @RequiredPermissions, @Validation, @BodyContentType) was loaded with none of those options, without any error: an endpoint protected by @RequiredPermissions would have answered everyone. Where the route loader has no annotation reader (Symfony 7 and later), loading such a route now fails with a ConfigurationException that names the controller method, the annotations it uses and the attributes to use instead (the #[...] attributes exist since 1.8.0). The annotations are found without an annotation reader: DocblockAnnotationFinder resolves each docblock tag through the use imports of the file that declares it. Symfony 4.4 to 6.4 are unchanged: the reader still applies the annotations there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Eleven parameters in nine files were written "Type $x = null", which PHP 8.4 reports as a deprecated implicit nullable type. They are now "?Type $x = null": the same type on every PHP version the bundle supports (7.1 and later), so no caller or subclass is affected. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The attribute's first parameter is the options array, so a positional list made the test fixture fail with a TypeError on Symfony 7.4. The bundle's own fixtures and the one application using the attribute pass it as permissions: [...]. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Tests only. The suite executed 910 of the 1,027 executable lines in src/ (88.6 %); the largest gap was ErrorBuilder, which builds every error response and had no test (30 of 84 lines). - ErrorBuilderTest: the error code, status and message for each kind of exception the builder maps, with the codes the bundle configures, and the API exception's details. - The guards that were never reached: reading an option before it is set, an unknown path attribute resolver type, validation without the validator service, a path attribute or query whose type cannot be guessed, explicit arguments winning over the signature. - RestResponseListener on a request that is not a REST request and on a controller returning nothing; RestRequestHelper for a controller with no identifier. - Two request-body errors in the functional suite: a body without Content-Type where the endpoint restricts content types, and a JSON body that does not decode. - RoutingAttributeLoader on Symfony 6.4 when the application disabled annotations: the docblock options stay ignored there, as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…test QueryResolverOptions starts with validation options set, so the guard is only reached once they are removed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Only internal classes have no file, and they carry no docblocks, so readImports() never met one; the guard was a line no test could reach. The file name check stays, inside the expression. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…der found them
The Symfony 7 guard missed five forms that Doctrine's reader applies on Symfony 4.4 to 6.4, so
on Symfony 7 such a route still loaded with its options silently dropped: a group import
(use ...\Annotation\{Body, RequiredPermissions}), a comma-separated import, an import on the
namespace line, a full class name without the leading backslash, and an action that comes from
a trait whose file imports the annotation. The finder now reads the use statements in all
these forms, merges the imports of the file that declares the method with the declaring
class's (as Doctrine does for traits), and resolves a name through an import, then the
namespace, then as a fully qualified name.
It also counts an @ only where Doctrine's lexer counts a top-level annotation (at the start of
the docblock text, after whitespace or *), so {@inheritdoc}-style inline tags, e-mail
addresses and annotations nested in another annotation's arguments are no longer reported.
Each file's imports are read once per route loading.
The error message no longer claims the endpoint would run without options when an attribute
is also present, writes the attribute class with its leading backslash, and names the
attribute interface for an application's own annotation class instead of an attribute that
does not exist.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The locale listener still took the header's languages from Request::getLanguages(). Symfony 7.1
rewrote that method too (it lowercases and reformats the tags), so on 7.1 and later a client
sending "DE" got German where every earlier line kept the default, and "EN,de" got English
instead of German. On http-foundation releases that build that list from the header's array keys
(3.4, 4.4.0 to 4.4.45, 5.4.0 to 5.4.12, 6.0.0 to 6.0.12, 6.1.0 to 6.1.4) a numeric tag came back as
an int and the listener's strpos() threw a TypeError under strict types, where the old listener
returned a locale.
The listener now reads the header through AcceptHeader, whose order is the same on every line,
and writes the tags the way getLanguages() did up to 7.0 ("de-CH" becomes "de_CH", a tag without
a region keeps its case). Five cases are added: "DE" and "EN,de" fail on Symfony 7.4 with the
previous listener, "1" and "de, 1" throw on http-foundation 4.4.0 with it, and "i-cherokee" runs
the i- branch.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…supports The test application picked its Symfony 7 configuration by the http-kernel major, while the bundle decides by what symfony/routing supports. Composer can install routing 7.4 next to framework-bundle 6.4 (framework-bundle 6.4 allows it), and there the application kept importing its controllers with the "annotation" route type that routing 7 no longer loads: 144 tests failed, on master as well. It now asks routing whether its attribute loader still has an annotation reader, the question the bundle's own loader asks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…test setup framework-bundle 6.4 installs next to validator 7.4, and it still configures the Email validator with the "loose" mode validator 7 removed, so every request validating an e-mail failed with "The defaultMode parameter value is not valid". The Symfony 7 test configuration now names html5, validator 7's own default: the five validation tests pass on that mix, and nothing changes on a pure Symfony 7 install. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ach their guards - ErrorBuilderTest builds paysera_api.error_builder from the bundle's own services.xml instead of repeating its eight configureError() calls, so a change to the configured error codes shows up. - The duplicate-annotation test passed on an earlier exception (its first annotation could not guess a type) and never reached the guard it is named after; both annotations now name their type, and the test expects the guard's message. - Element types on the new data providers, an imported RuntimeException, and the eight implicitly nullable test parameters PHP 8.4 reports written ?Type. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… found them The Symfony 7 check still missed annotations that Doctrine's reader applies on Symfony 4.4 to 6.4, so those routes loaded on Symfony 7 with their options dropped, and it reported text that Doctrine never read as an annotation. - Imports: the use statements are read with the PHP tokenizer, as Doctrine's TokenParser does, from the class's file up to the class and from the class's namespace declaration on. Comments inside use statements, several statements on one line and braced or repeated namespace blocks now count as Doctrine counts them; a commented-out import, a trait used in the class body and another namespace's import no longer do. A method from a trait also gets the imports of the trait's file, as in Doctrine's getMethodImports(). - Docblocks: reading starts at the first "@" after a space, a tab or "*"; after that an annotation starts at an "@" after whitespace (a no-break space too) or "*"; a quoted string is text; a name followed by "-" is not an annotation; the arguments of an annotation are skipped, so an annotation nested in them is not reported as the method's own. On 19 sample controllers the check now reports what Doctrine's AnnotationReader reports, with doctrine/lexer 2 and 3; with lexer 1 the no-break space case differs, because lexer 1 does not read it as whitespace. On 207 controller files of Paysera applications (688 docblocks) the imports and the annotations found are the same as Doctrine's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nguage item http-foundation 3.4 gives null for an item that is only ";" and false for a lone quote, and the listener passed that to strpos() under strict types: "Accept-Language: '" ended in a TypeError where 1.8.2 kept the locale. The value is read as a string again, as it was before the listener read the header itself. Two test cases cover a malformed item alone and next to a language. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ErrorBuilderTest covered six of the eight codes in services.xml. It now also checks invalid_parameters (with its configured message), invalid_state and not_acceptable, so a change to any configured status or message fails a test. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… across Symfony lines The comments said the listener picks the same locale on every Symfony line. It applies the same rule and tag format on every line; for some malformed headers the releases' own parsing of Accept-Language still differs (for example "de;q=, en"), as it did before this change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s reader Six rules of the check ran in the suite without a test that fails when they break, or did not run at all. Each new case gives the result Doctrine's AnnotationReader gives (checked with doctrine/lexer 2 and 3), and each fails when its rule is taken out: - a `use function` or `use const` import with an annotation's short name does not replace the class import (the statement ends at `function` / `const`); - a method a class declares over its trait's method resolves through the class file's imports only, not the trait file's; - the parentheses after a class that is not an annotation are read, so an annotation in them counts, as in Doctrine; - reading starts at the first "@" after a space, a tab or "*": an annotation at the start of a line before it is skipped, and one after a tab starts the reading; - a class declared in evaluated code, such as a test double, has no file and gives no imports. The no-break space fixture moves into WhitespaceBeforeAnnotationController with the tab case. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…keeps a name The quoted-string pattern was written in two regular expressions; it is now one constant. The class comment said a name followed by "-" is never an annotation, but a "-" that starts a number keeps it, in Doctrine and in the code. A comment line in the locale listener is rewrapped to the line length. No behaviour changes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On http-foundation 3.4 such an item gives null, which the listener must read as no language; the existing lone-quote cases cover only false. http-foundation 4.4 fails on an empty item itself, as with 1.8.2, so the test is skipped where Symfony's own parser throws. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n it On http-foundation 4.4 the parser reads a value that is not there before it throws its TypeError, and PHP 7.4 reports that as a notice, PHP 8 as a warning. PHPUnit turns either into an error first, so the test errored on Symfony 4.4 with PHP 7.4 and later instead of being skipped. It now skips on any failure of Symfony's own parser. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…he rest of its rules Two inputs made the Symfony 7 check miss an annotation that Doctrine's reader applies on Symfony 4.4 to 6.4: - `@Target( @RequiredPermissions(...) )` where `Target` is an application's annotation class found through the namespace: Doctrine ignores tag names such as Target and Required unless they are imported or written in full, and then reads what the parentheses hold as top-level annotations. The check now skips an annotation's arguments only when its name was imported or written in full, where Doctrine always reads them. - an "@" right after a quote (`see "the notes"@RequiredPermissions(...)`): Doctrine's lexer measures a string without its quotes, so the "@" is not glued to it. New cases pin rules no test protected before, each checked against Doctrine's reader and each failing when its rule is taken out: an "@" right after a star, a one-letter alias, aliases in a comma list, an import written with a leading backslash, an alias two namespace levels up, an import on the class's own line, a docblock comment inside an import, arguments after a space, a parenthesis inside a quoted argument, an annotation without arguments before another, a ":" or a negative number after a name, a class docblock resolved in its own namespace and file, two classes in one file with their own namespace blocks, and a trait whose import wins over the class's for the trait's method. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ErrorBuilder falls back to a hard-coded 500 for other exceptions, so no test read the status configured for internal_server_error. A data set with that code now does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The guard skipped on any failure of Symfony's parser, so a later release that broke on ";" would have skipped the test instead of failing it. Only http-foundation 4.4 fails on an empty item (3.4, 5.4, 6.4 and 7.4 parse it), so the test now skips on Symfony 4 and runs everywhere else. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…lves them Four more inputs where the Symfony 7 check and Doctrine's reader (Symfony 4.4 to 6.4) differed: - a name written on both sides of a "\" with whitespace, a line break or "*" between them (`@REST\ RequiredPermissions`): Doctrine joins the parts, so the check now does too; - a name with two leading backslashes: Doctrine strips them all; - a bundle annotation written in another case after an alias (`@REST\requiredPermissions`): Doctrine found it once an earlier route had loaded the class, but on Symfony 7 nothing may have loaded it, and the autoloader looks for a file in the written case. The check now loads the bundle's own annotation classes before resolving names; - a name with a namespace that is not imported (`@Paysera\...\Query(... @Validation ...)`): Doctrine never ignores such a name, so its arguments are skipped again, as for imported names. The first three made the check miss an annotation Doctrine applies; the fourth made it report a nested one. New cases also pin that reading does not start at an "@" glued to a quote, and that a class docblock resolves in the route class's own namespace when the method is inherited. Each case gives Doctrine's result and fails when its rule is taken out. The class comment now says which arguments are skipped and in which direction the check can still differ from Doctrine. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…of the same name Doctrine tries the controller's namespace before the global name, and so does the check; no test held that order. An application annotation named Directory, like PHP's own \Directory class, now pins it: tried in the other order, the check finds PHP's class and drops the annotation. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…joining rules 7bf10ab skipped the arguments of every name with a namespace, on the grounds that Doctrine never ignores one. It does when a class lists the name with @IgnoreAnnotation, and then reads what the parentheses hold as top-level annotations, so the check missed an annotation Doctrine applies. Arguments are again skipped only after an imported name or one written in full, where Doctrine reads them in every case; after any other name the check reads on and can only report more. The bundle's annotation classes are listed with scandir() instead of glob(), which reads brackets in the install path as a pattern. New cases pin a name joined across two separators, a no-break space after a separator, a name that does not take the next line's words, three leading backslashes, and a name the class tells Doctrine to ignore. Each gives Doctrine's result and fails when its rule is taken out. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sion The skip checked http-kernel's major version, but the failure is http-foundation's, and the two can be installed at different majors. The test now skips exactly when Symfony's own parser fails on ";" (http-foundation 4.4, as with 1.8.2), and runs everywhere else. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The lowest supported doctrine/lexer, 1.0, differs from 1.2 and later in two ways. It does not read a no-break space as whitespace, so a parenthesis after one is not an annotation's arguments. It reads a docblock that is not valid UTF-8 byte by byte, where the later versions read no annotations in it at all. The finder followed the later versions only. On lexer 1.0 it skipped an annotation Doctrine applied (the one inside a parenthesis after a no-break space), and a route would have loaded without it. It now takes only ASCII whitespace before arguments and reads a docblock that is not UTF-8 byte by byte: on every lexer version, the reading that reports more. The class comment also states the ignored-name rule as it is: Doctrine passes over such a name unless it names an annotation class through an import or in full. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… its path The finder lists the bundle's Annotation directory with scandir rather than glob, because glob reads "[" and "]" in the path as a pattern and would then find nothing. A test now copies the bundle's source under a directory named with brackets and checks that a name written in another case still resolves from there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Repeated tests become one test with a data provider, several getter checks become one assertion per case, and the pull request adds no comments; the reasons they gave are in the pull request description. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Following your note on lib-dependency-injection#8, every job here also runs with lowest dependencies where that combination can run (a11829b): 38 jobs, the 24 highest plus 14 lowest. I ran all 24 lowest combinations locally with the workflow's own commands. 14 pass with 389 tests each. The other 10 fail inside
The two Symfony 7 lowest jobs pass locally with the three dependency candidates. On GitHub they fail at install, like the Symfony 7 highest jobs, until those releases are out. As on lib-normalization-bundle#10, raising the floors would let more lowest jobs run on PHP 8, but it changes the package's requirements, so I left it out of this pull request. |
The matrix gains dependency lowest next to highest, and the single PHP 7.1 lowest entry became one of those jobs. Eight exclude entries take out the 10 lowest combinations whose oldest allowed dependencies cannot run together or on PHP 8: Symfony 4's routing annotation loader on PHP 8 (it misreads class names), lib-object-wrapper 0.3.0 on PHP 8.1 and later (ArrayAccess return types), and DoctrineBundle's lowest release against Symfony 6.0's Doctrine bridge. The 14 lowest jobs that remain pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… a reader The routing loader test no longer expects a refusal on Symfony 7. Without an annotation reader, on Symfony 7 or where an application disabled annotations before it, the bundle's docblock annotations are ignored and the route loads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The docblock annotation finder and the refusal built on it are removed: RoutingAttributeLoader is back to master's code, which skips the bundle's docblock annotations when there is no annotation reader, as on Symfony 7. The finder's test and the 40 fixtures only it used go with it. CHANGELOG and README say that the annotations have no effect on Symfony 7 and that the attributes of the same name configure those routes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The new test files for classes the pull request does not change are removed (ErrorBuilder, RestResponseListener, PathAttributeResolverRegistry, the option entities, attribute parameter resolution, RoutingAttributeLoader and its two fixtures), and the RestRequestHelper and EntityValidator tests are back to master's. They were added to raise line coverage, not to test this change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… docblock annotations Symfony 7 reads no docblock annotations, so a leftover @RequiredPermissions would leave its endpoint without the permission check. Loading such a route must fail and name the attributes to use. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On Symfony 7 the route loader has no annotation reader, so a leftover @RequiredPermissions would leave its endpoint without the permission check. If the method or class docblock of a route names one of the bundle's seven annotations, loading the route now fails with a ConfigurationException that names them and points to the attributes of the same name. This replaces the Doctrine-rules reader removed two commits earlier with a match on names only, to keep the pull request at the size of the fix. Symfony 4.4 to 6.4 keep reading the annotations as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
I cut this pull request back to what Symfony 7 support needs (ee37629..9f13c4c): 91 files became 41.
The suite, 277 tests, passes locally in 8 of the workflow's jobs, from PHP 7.1 to 8.3 and Symfony 3.4 to 7.4. |
Opens as a draft: it needs the Symfony 7 releases of paysera/lib-dependency-injection (paysera/lib-dependency-injection#8),
paysera/lib-pagination (paysera/lib-pagination#18) and paysera/lib-normalization-bundle (paysera/lib-normalization-bundle#10) first; their current releases stop at Symfony 6.
Summary
I make the bundle install and run on Symfony 7.4 and keep Symfony 3.4 to 6.4 working as they do. I propose releasing it as
1.9.0.
Why
^6.0, and Symfony 7 requiresgetConfigTreeBuilder(): TreeBuilder.composer.json, so a PHP 8.3 install can mix routing, http-foundation andsecurity-core 7.4 into a 6.4 install; 144 of the 259 tests then fail.
Request::getPreferredLanguage(): the listener's"default"placeholder now wins for German ("de").dropped
@RequiredPermissionsleaves an endpoint without its permission check.Changes
composer.json:^7.4onframework-bundle,security-bundle,validatorand devyaml;config,dependency-injection,http-foundation,http-kernel,property-access,routing,security-corerequired at the same constraint;psr/log^3.0allowed; devdoctrine/ormfloor^2.6.3(2.6.0 fails on PHP 7.3+).getConfigTreeBuilder(): TreeBuilder,PayseraApiExtension::load(): void,?Type $x = nullon 11 parameters.LocaleListenerreadsAccept-Languageitself and applies the Symfony 3.4 to 7.0 rule on every line: the first entry,in the client's order, that is a configured locale; a regional tag (
de_CH) also offers its primary language (de)unless the header lists it.
alias or in full) fails to load with a
ConfigurationExceptionpointing to the attribute of the same name. It matchesnames only. Symfony 4.4 to 6.4 are unchanged.
sf7_common.ymland attribute twins of the docblockcontrollers); tests for the locale rule and the Symfony 7 refusal.
7.*on PHP 8.2 and 8.3 (EE-283: Update actions/checkout to v7 #20, merged, moved it toactions/checkoutv7), and, after the secondreview, every job also with lowest dependencies, as asked on lib-dependency-injection#8 (38 jobs: 24 highest, 14 lowest).
The 10 excluded lowest combinations fail inside
vendor/: Symfony 4's routing annotation loader on PHP 8,lib-object-wrapper0.3.0 on PHP 8.1 and later, and DoctrineBundle's lowest release with Symfony 6.0.CHANGELOG.md1.9.0 and a README note.Backward compatibility
A minor: nothing is removed, PHP 7.1+ and Symfony 3.4+ stay allowed. A check from 1.8.2 lists 2 changes, the two return types;
they break only a subclass overriding either method without the type, as the CHANGELOG says. One behaviour change on every
line:
Accept-Language: default, denow givesde(defaultwas the listener's placeholder).Test plan
(Symfony 7.4, with the three dependency candidates): all pass.
src/line coverage 85.9 % on Symfony 6.4 (master:47.2 %).
every attribute route without a refusal.
the Symfony 7 check was simplified; that code does not run on Symfony 6.4).
the released versions of the three dependencies stop at Symfony 6; they pass once those releases are out.
Known gap
testAnItemOfOnlyASemicolonIsNotALanguageis skipped wherever Symfony's own parser throws on the header;. Today onlyhttp-foundation 4.4 does that, and 1.8.2 throws there as well. If a later http-foundation release broke on
;, the testwould be skipped instead of failing.
🤖 Generated with Claude Code