<p dir="auto">If you want to declare another AppKernel a more lightweight version that only uses Doctrine\Bundle\DoctrineBundle\DoctrineBundle(), along with others of my own, you must include Symfony\Bundle\FrameworkBundle\FrameworkBundle() because annotation reader is declared in FrameworkBundle() but the classes for the annotation reader are from Doctrine, and that is strange because the Symfony Framework IMHO should have its own implementation(that implies duplicate code in a way, but its independent). My question is why did you make this decision? I don't see how Symfony will work without Doctrine, and IMHO its a very tight coupling.</p>
<p dir="auto"><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="229569074" data-permission-text="Title is private" data-url="https://github.com/symfony/symfony/issues/22742" data-hovercard-type="pull_request" data-hovercard-url="/symfony/symfony/pull/22742/hovercard" href="https://github.com/symfony/symfony/pull/22742">#22742</a> changed the constraints in the 3.4 branch to allow 4.0.x version of the other components. After that, I had a lengthy discussion with <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/nicolas-grekas/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/nicolas-grekas">@nicolas-grekas</a> on Slack challenging it. We now think it is time to share our thoughts outside the core team (and with core team members not connected at this time) to involve the whole community.</p>
<blockquote>
<p dir="auto">Note: for the whole discussion, I will talk about components, but this also applies to bridges and bundles developed in the symfony/symfony repo. It is just shorter than repeating <code class="notranslate">components, bridges and bundles</code> all the time.</p>
</blockquote>
<p dir="auto">The whole point of this discussion is to decide how the requirements of the of inter-component dependencies should look like in the 3.4 branch. There is 3 possible options:</p>
<ol dir="auto">
<li><code class="notranslate">^3.2</code>, not allowing any usage of 4.x dependencies</li>
<li><code class="notranslate">^3.2 || ~4.0.0</code>, allowing only the 4.0.x versions of deps, but not 4.1+ (what <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="229569074" data-permission-text="Title is private" data-url="https://github.com/symfony/symfony/issues/22742" data-hovercard-type="pull_request" data-hovercard-url="/symfony/symfony/pull/22742/hovercard" href="https://github.com/symfony/symfony/pull/22742">#22742</a> did, and what we did for 2.8 as well)</li>
<li><code class="notranslate">^3.2 || ^4.0</code>, allowing the whole 4.x releases, relying on the BC promise of 4.x</li>
</ol>
<blockquote>
<p dir="auto">Note: example above assume that the lowest bound of the existing 3.3 constraint is <code class="notranslate">3.2</code>. It can be something else for each requirement, so things should be adapted above accordingly.</p>
</blockquote>
<p dir="auto">The third option was rejected by <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/nicolas-grekas/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/nicolas-grekas">@nicolas-grekas</a> because it hurts our promise that the Symfony code will never trigger deprecations by itself (i.e. calling a non-deprecated API from your own code does not make Symfony call a deprecated API internally on its own), as it precisely relies on BC layers.</p>
<p dir="auto">I'm arguing that we should stick with the first option, because of the way Composer works and because of our ecosystem change with Flex.</p>
<p dir="auto">Regarding Composer, what you need to remember is how it chooses the installed version: it always selects the highest version available which matches your constraints. So if you require <code class="notranslate">^3.2 || ~4.0.0</code>, it will always try to use a 4.0.x release first. This has 2 drawbacks:</p>
<ul dir="auto">
<li>4.0 brings BC breaks (this is why it is named 4)</li>
<li>4.0.x is not a LTS version, meaning it will go unmaintained much before 3.4</li>
</ul>
<p dir="auto">Regarding the ecosystem change, the big difference is what Symfony users will tell Composer when they want to use our 3.4 LTS version (because they have not yet migrated their code to 4.x APIs for instance):</p>
<ul dir="auto">
<li>in the symfony-standard way, they would tell "Give me Symfony 3.4" (i.e. <code class="notranslate">composer require symfony/symfony ^3.4</code>), and they would get the 3.4 version of the whole Symfony code</li>
<li>in the flex way, they would tell "Give me FrameworkBundle 3.4" (i.e. <code class="notranslate">composer require symfony/framework-bundle ^3.4</code>), and they would <em>expect</em> to get 3.4 version of Symfony. But the options above may break this assumption.</li>
</ul>
<p dir="auto">What is important to remember is that people using <code class="notranslate">symfony/framework-bundle</code> as a dependency actually spend most of their time interacting with transitive dependencies brought in by FrameworkBundle:</p>
<ul dir="auto">
<li>they write route definitions (<code class="notranslate">symfony/router</code>)</li>
<li>they write controllers (<code class="notranslate">symfony/http-kernel</code>)</li>
<li>they handle requests and responses in their controller (<code class="notranslate">symfony/http-foundation</code>)</li>
<li>they write service definitions (<code class="notranslate">symfony/dependency-injection</code>)</li>
<li>they trigger or listen to events (<code class="notranslate">symfony/event-dispatcher</code>)</li>
<li>...</li>
</ul>
<p dir="auto">If we go with the option 2, a new Symfony 3.4 project would automatically get the 4.0 version of all the components I listed just above (and a few others), until another rule forbids to use version 4. and this is very bad, because it means people will <em>not</em> receive BC layers anymore, which basically breaks our BC promise.</p>
<blockquote>
<p dir="auto">Note: FrameworkBundle is not the only package having mandatory requirements on other Symfony packages, but it was the best example for this case as it is the entry point of using Symfony in Flex.</p>
</blockquote>
<p dir="auto">This could also affect external projects relying on Symfony components, as they could also be relying on transitive deps (<code class="notranslate">symfony/http-kernel</code> bringing in <code class="notranslate">symfony/http-foundation</code>).</p>
<blockquote>
<p dir="auto">Note: Things can become even worse if <code class="notranslate">symfony/framework-bundle</code> removes the explicit require on <code class="notranslate">symfony/http-foundation</code> and relies on <code class="notranslate">symfony/http-kernel</code> bring it to the user instead, as bring in 4.0.x for HttpKernel then allows bring in any 4.x version for HttpFoundation, which goes to option 3.</p>
</blockquote>
<p dir="auto">I only see 2 ways to avoid this issue:</p>
<ul dir="auto">
<li>stick to option 1, meaning that a dependency between Symfony components cannot require a higher major version than the current one (allowing <em>lower</em> major versions of them is fine, and 4.x components should actually all allow 3.4 version of their deps as the 3.4 version will have all the features they need)</li>
<li>teach people to never rely on transitive deps for the packages they directly use in their project, which means that the Symfony skeleton should list much more packages by default (duplicating the FrameworkBundle deps without allowing 4.0.x).</li>
</ul>
<p dir="auto">Due to the effect on DX, I strongly suggest sticking to option 1. But the call is now on the community, to decide about option 1, 2 or 3 above.</p>
<p dir="auto">Note that for <em>dev</em> requirements, we should allow bringing in 4.0 versions, unless we also have a conflict rule forbidding them, because this helps ensuring that users don't end up in non-working cases (as optional deps cannot be enforced to stay on 3.x if we don't have conflict rules forbidding them, as we don't control the requirement bringing them in).</p>