-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[2.7][HttpKernel] Added support for registering Bundle dependencies #13945
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
Conversation
cc118cb
to
99663bf
Compare
One thing to note, with the ability to somewhat control load order it can also mean that people will have less needs to write compiler passes. imho would bring down the barrier for these kinds of things, but I also kind of like that inter-Bundle service configuration is clearly laid out in compiler passes. As for the need of silent ignoring of optional dependencies, indeed this will add overhead but I would imagine that in many cases it will not really be an issue. This leads me to an alternative/complementary idea: Simply a command that outputs the code to paste into the Kernel Bundle register method. |
could somehow work, but that would essentially be like a cache the user needs to manually maintain then. And won't be able to execute the command if bundle dependencies goes away after an composer update :/ |
$dependency = $topMostBundlesMap[$dependencyFQN]; | ||
} else { | ||
if (!class_exists($dependencyFQN)) { | ||
throw new \RuntimeException(sprintf("Could not find Bundle '%s', set as dependency by '%s'", $dependencyFQN, $parent)); |
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'd go for a specific exception here, for clarity sake.
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.
yes, where looking for better examples, open for suggestions.
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.
DependencyMismatchException extends \RuntimeException
? Just to throw something in
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.
Thanks, but something like DependencyNotFoundException
would be even more specific right? or did you have something in mind with the name?
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.
Just thought, that maybe you can reuse it for other dependency issues as well. On the other hand it's just a suggestion 😄
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.
What if the bundle is optional dependency?
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.
That is currently not supported, see comments above. But if it was, it should indeed not throw ;)
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.
Found ClassNotFoundException
in Debug, seems to be the most fitting here.
@kingcrunch What do you think?
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.
Or not, it has hard requirement on previous exception.
I'll go with DependencyMismatchException extends \RuntimeException
😄
Hm.. On one side we are removing magic (twig automatic file handling) on the other we are adding it. Is it really that hard to write one file into the AppKernel. After all you also have to provide configuration for that bundle |
Good point, but you would only need that if defaults are not ok, right? (side note: didn't fully get what twig has to do with this btw) Also in this scenario where root1 depends on dependency2, it might be that root1 makes sure to add own events/tags that are used by dependency2. Root1 might even adjust the defaults of dependency2 to better fit the combined use for these two bundles. Meaning defaults can often be ok. With the goal of simplifying distribution handling and upgrade needs, do you see other features needed around this? For instance on configuration? |
Thanks GOD for this PR... |
99663bf
to
14c4fa5
Compare
14c4fa5
to
242a30e
Compare
c371505
to
d647bad
Compare
d647bad
to
01e7d8d
Compare
Tests and further improvements done, doc in review, so ready for second round of review now. |
|
||
namespace Symfony\Component\HttpKernel\Exception; | ||
|
||
use RuntimeException; |
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.
Should be removed in favor of an inline new \RuntimeException()
in the code.
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.
Hi, you mean removing DependencyMismatchException?
That was the original case before this review thread:
#13945 (diff)
Or did you imply inline extends \RuntimeException
(now the case as of 525bb12)
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.
Good ;)
c001a31
to
525bb12
Compare
it might be a good idea to also offer some debugging tool to help developers understand the dependency tree. though this is imho rather a nice to have that could come via a separate PR. |
public function getBundleDependencies() | ||
{ | ||
return array( | ||
'Symfony\Component\HttpKernel\Tests\Fixtures\BundleDependencies\BundleBDependenciesA', |
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.
if we are to ever add optional support imho it would be better to have an associative array here, where the value would be true for required and false for optional for example. then when doing the class_exists check you would simply not throw an exception for optional dependencies.
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.
Ok, thats a fair point, as we should decide on the format now and not change it later. I was thinking separate method, maybe even on a separate BundleOptionalDependenciesInterface
if this would be done in a followup.
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.
What about
class AcmeBundle extends Bundle implements BundleDependenciesInterface
{
public function getBundleDependencies()
{
return array(
self::REQUIRED => array(
// All values must be FQN strings to avoid bundles being loaded several times
'FOS\HttpCacheBundle\FOSHttpCacheBundle',
// if on php 5.5 and higher
Oneup\FlysystemBundle\OneupFlysystemBundle::CLASS,
),
self::OPTIONAL => array(
// Optional dependencies can not use ::CLASS constant
'FOS\HttpCacheBundle\FOSHttpCacheBundle',
);
}
}
This could be added now, and it could also be added later actually with bc for current format.
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.
sure .. but what would be the advantage? or are you just proposing a possible new format with migration path in case we leave it out today and want to add optional deps later?
just seems like a more complicated structure. plus an assoc array implicitly takes care of duplicates. then again if one ends up having so many dependencies that accidental duplicates are a risk, one might be over using the feature :)
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.
or are you just proposing a possible new format with migration path in case we leave it out today and want to add optional deps later?
y
But we can also go for 'FOS\HttpCacheBundle\FOSHttpCacheBundle' => self::REQUIRED
, but then we would need to do that now imho.
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.
returning to the specifics:
just seems like a more complicated structure. plus an assoc array implicitly takes care of duplicates. then again if one ends up having so many dependencies that accidental duplicates are a risk, one might be over using the feature :)
Was also thinking less typing, implementation can not do a simple array join anyway with your proposed structure, as you always would want REQUIRED to overwrite OPTIONAL. However I'll try out your structure to see here now.
So like |
So quick poll to everyone interested in this feature:
Context: Would be with no (bundle order) caching for now, so it will be doing a uncached class_exists() -> file_exists() lookup for missing dependencies. Unlike existing files, php does not cache the filesystem (stat/..) calls for these. |
…ager (nicolas-grekas) This PR was merged into the 2.8 branch. Discussion ---------- [Security] Add setVoters() on AccessDecisionManager | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | partially symfony#12360 | License | MIT | Doc PR | - Alternative for symfony#14550 Commits ------- 3fd7cea [Security] Add setVoters() on AccessDecisionManager
Issue symfony#11045 For now, the Routing DirectoryLoader requires the type `directory` to be specified so it does not conflict with `AnnotationDirectoryLoader`. However, this could be refactored.
* 2.7: (95 commits) [DependencyInjection] provide better error message when using deprecated configuration options [console][TableCell] get cell width without decoration. Improve the config validation in TwigBundle [VarDumper] Changed tooltip to expand-all keybinding in OS X [Bridge\PhpUnit] Fix composer installed phpunit detection [VarDumper] Fix generic casters calling order [2.7][SecurityBundle] Remove SecurityContext from Compile [WebProfilerBundle][logger] added missing deprecation message. Fix profiler CSS [Security][Acl] enforce string identifiers [FrameworkBundle] make `templating.helper.router` service available again for BC reasons [BrowserKit] Fix bug when uri starts with http. bumped Symfony version to 2.7.1 updated VERSION for 2.7.0 updated CHANGELOG for 2.7.0 bumped Symfony version to 2.6.10 updated VERSION for 2.6.9 updated CHANGELOG for 2.6.9 fixed tests bumped Symfony version to 2.3.31 ... Conflicts: src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig src/Symfony/Component/HttpKernel/Kernel.php src/Symfony/Component/Translation/Loader/JsonFileLoader.php
…ive directory loading (lavoiesl, nicolas-grekas) This PR was merged into the 2.8 branch. Discussion ---------- [DependencyInjection] [Routing] [Config] Recursive directory loading | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#13246, symfony#11045, symfony#11059 | License | MIT | Doc PR | - Commits ------- 60b1c5b Added CHANGELOG entries, cleanups 73f0ee2 [DI][Routing] recursive directory loading
* 2.7: [Security] Update tests after a merge [Console] Remove an unused argument and fix a small cs issue [Translator] avoid serialize unserializable resources.
…re updated (chbruyand) This PR was squashed before being merged into the 2.8 branch (closes symfony#14781). Discussion ---------- [TwigBundle] Reconfigure twig paths when they are updated | Q | A | ------------- | --- | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#14771, symfony#14768, symfony#14262, symfony#14778 | License | MIT Refresh twig paths upon creation and deletion. As we don't care neither about path's modification time nor path's content, a new Resource has been added in the Config Component. Full discussion in symfony#14778. Commits ------- 3cbff05 [TwigBundle] Reconfigure twig paths when they are updated
This PR was merged into the 2.8 branch. Discussion ---------- added missing " Commits ------- 1baf05a added missing "
This PR was squashed before being merged into the 2.8 branch (closes symfony#14904). Discussion ---------- [toolbar] Merged colored icons in toolbar | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | Status icons are doubled without any apparent reason. Token before  Token after  Security before  Security after  Commits ------- 5b67bbd [toolbar] Merged colored icons in toolbar
…from the toolbar (MJBGO) This PR was merged into the 2.8 branch. Discussion ---------- [profiler][request toolbar] Removed route name from the toolbar | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#14744 | License | MIT | Doc PR | The action block takes nearly 1/3 of the bar width which is not good. The controller + action names are useful but the route name less important. Before  After  The route name is shown by hovering the action block  Commits ------- 9004e29 Removed route name from the debugbar.
* 2.7: [Console] SymfonyStyle : Fix blocks wordwrapping [Console] SymfonyStyle : Fix blocks output is broken on windows cmd [Validator] remove partial deprecation annotation Updated UPGRADE-2.4.md [Form] Support DateTimeImmutable in transform() Show the FormType and FormTypeExtension in case of deprecated use of setDefaultOptions [FrameworkBundle] Document form.csrf_provider service deprecation [Form] add test to avoid regression of symfony#14891 without this change allways the legacy code get called [Form] Fix call to removed method (BC broken in 2.3) Fix ask and askHidden methods [HttpFoundation] Get response content as resource several times for PHP >= 5.6 Change error message to reflect SecurityContext deprecation. fixed merge Issue symfony#14815 [Console] SymfonyStyle : fix & automate block gaps. [Console] SymfonyStyle : Improve EOL consistency by relying on output instance Improved duplicated code in FileLocator
…er on a Response (jakzal) This PR was merged into the 2.8 branch. Discussion ---------- [HttpFoundation] Postpone setting the date header on a Response | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#14906 | License | MIT | Doc PR | - The only risk of doing this is if someone called `getDate()` and the date header was not present, the date might be slightly different than the one sent with the headers. `getDate()` could also set the date header first time it's requested (do a lazy initialisation). Commits ------- 2ad3b0d [HttpFoundation] Postpone setting the date header on a Response
* 2.7: Fix test name fixed CS Allow new lines in Messages translated with transchoice() (replacement for symfony#14867) [Form] Swap new ChoiceView constructor arguments to ease migrating from the deprecated one [2.3] Fix tests on Windows [Yaml] remove partial deprecation annotation Silence invasive deprecation warnings, opt-in for warnings Documenting how to keep option value BC - see symfony#14377 Conflicts: src/Symfony/Bridge/Doctrine/composer.json src/Symfony/Bridge/Twig/composer.json
…imler) This PR was merged into the 2.8 branch. Discussion ---------- fix Merge branch '2.7' into 2.8 JsonFileLoader This fix a merge commit see symfony@5593bdd. The `stream_is_local` and `file_exists` checks are all ready done in the parent `FileLoader` class. | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | no | Fixed tickets | none | License | MIT | Doc PR | none Commits ------- 692deff fix Merge branch '2.7' into 2.8 JsonFileLoader
This PR was merged into the 2.8 branch. Discussion ---------- [Profiler][Translation] added filter. | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Fixed tickets | ~ | Tests pass? | yes | License | MIT  Commits ------- 65f9291 [Profiler][Translation] added filter.
For further info on the new function and why it returns class names see BundleDependenciesInterface.
ae35ae0
to
07f86ea
Compare
Closed and reopened against 2.8 as #15011 (now also with env and debug arguments) |
As there are ongoing discussions in both in eZ and Symfony CMF on this topic, agreed with @lsmith77 to open PR to discuss this potential light weight native approach. Alternative if native feature is not wanted is OroPlatform, a custom, still somewhat project specific and heavier approach involving bundles.yml files and caching needs.
What?
Adds possibility for a Bundle to specify other bundles it depends on. This allows root/meta projects to not have to specify dependencies of dependencies, and no need for user to perform manual upgrade work in Kernel file when they change.
A dependency implies two things for the Kernel:
The last point is because we assume a dependency is something we might extend so we always load it before "self".
How
A optional interface is added that bundles can implement, while the method could have been added
to the main interface like getParent(), this approach allows the code to check using instanceof,
keeps full BC, and allows a clear contract on use of this feature.
The approach further explicitly avoids giving bundle writers any control over priority of load ordering other
then "before self", as otherwise it would 1. potential lead to conflicts, and 2. complicate the implementation.
For further info on the new function and why it returns FQN class names, see BundleDependenciesInterface.
Todo
Possible followups
Open request from Symfony-CMF is to be be able to specify optional dependencies, basically dependencies that should be silently ignored if they don't exists, however as this is during boot that would lead to un cached file system calls (PHP does not cache stat calls to non existing files) unless result is cached as mentioned in prior point