Skip to content

[DependencyInjection] [Routing] [Config] Recursive directory loading #13246

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

Closed
wants to merge 4 commits into from
Closed

[DependencyInjection] [Routing] [Config] Recursive directory loading #13246

wants to merge 4 commits into from

Conversation

lavoiesl
Copy link
Contributor

@lavoiesl lavoiesl commented Jan 4, 2015

As asked by @stof, this PR is a remake of #11059 on the 2.7 branch.

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #11045, #11059
License MIT
Doc PR TODO

See those about creating a cookbook for better file organization:
Issue: symfony/symfony-docs#3680
PR: symfony/symfony-docs#3885

This PR allows to specify a directory to load and it will recursively load all files from it, using the LoaderResolver.

Example

# app/config/config.yml
imports:
    - { resource: 'dev/' }
└── app
   ├── config
   │  ├── common
   │  │  └── framework.yml
   │  │  └── assetic.yml
   │  └── config.yml

It also works for routing configuration:

_common:
    resource: "common/"
    type: directory

Advantages

  1. Allows easy separation of configuration files per bundle.
  2. This could eventually allow a bundle installation tool that would automatically install needed configuration files.
  3. Could superseed the AnnotationDirectoryLoader, so it does not duplicate the logic.
  4. Is entirely optional and introduces no BC break.
  5. Files are loaded lexically with scandir, allowing someone to control the load order through a number prefix.
  6. Even if the initial configuration load may be a little bit longer, it does not impact the compiled configuration (production).

Graceful degradation

In FrameworkBundle and HttpKernel, the DirectoryLoader is only added if available. This means you can have FrameworkBundle 2.7 with Routing and DependencyInjection 2.6 and everything will work, except the directory loading. As asked by @stof, the version requirements are now 2.7 for both.

Conflicts

For now, the Routing DirectoryLoader requires the type directory to be specified so it does not conflict with AnnotationDirectoryLoader. However, this could be refactored.

The type declaration requires a patch in AsseticBundle for it to be used on framework.router.resource. The patch is already merged in master, but not in a release yet. Released in 2.5.0. Changing the main router would be like this:

framework:
    router:
        resource: "%kernel.root_dir%/config/routing/common/"
        type: directory

@lavoiesl
Copy link
Contributor Author

lavoiesl commented Jan 4, 2015

As of now, some Travis tests fail for a reason I can’t identify. The tests run fine on my computer.

@nicolas-grekas
Copy link
Member

To reproduce on your local computer:
cd src/Symfony/Component/...
composer up for "high" tests or composer up --prefer-lowest --prefer-stable "low" ones
phpunit

@lavoiesl
Copy link
Contributor Author

lavoiesl commented Jan 4, 2015

@nicolas-grekas And do you know what could be causing the issue? AFAIK, the class is in the proper place. Isn’t the autoloader supposed to do its job?

@lavoiesl
Copy link
Contributor Author

lavoiesl commented Jan 4, 2015

Oh, nevermind, it is actually pretty simple: it downloads the symfony/dependencyinjection which hasn’t the class yet. So this is expected to fail and will be resolved when merged.

@nicolas-grekas
Copy link
Member

You're right for "high" tests. But merging won't solve "low" tests unless you state that ~2.7 is the minimum allowed version (in components that relies on your newly added class). One or more composer.json need an update

*/
public function supports($resource, $type = null)
{
return 'directory' === $type || (!$type && preg_match('/\/$/', $resource) === 1); // ends with a slash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to check is_dir instead of is ended with a slash

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After extensive testing, I had to remove is_dir checks in both loaders because ->supports() is not aware of the current location. Therefore, trailing slash is mandatory. I also updated the tests to reflect this.

@aitboudad
Copy link
Contributor

👍

@lavoiesl
Copy link
Contributor Author

lavoiesl commented Jan 4, 2015

The errors remaining in Travis are not related to this PR.

@nicolas-grekas I added graceful degradation instead of bumping the requirements. See the updated description.

@stof If nobody else has issues with this, I believe this is ready now, thanks for your input.

$loaders[] = new DirectoryLoader($container, $locator);
}

$resolver = new LoaderResolver($loaders);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering why the default set of loaders is written in HttpKernel, shouldn’t there be something like Symfony\Component\DependencyInjection\Loader\LoaderResolver that would contain the set of default loaders? This is out of scope of this PR though.

@@ -30,6 +30,12 @@ public function process(ContainerBuilder $container)

$definition = $container->getDefinition('routing.resolver');

// routing.loader.directory only appears in Routing 2.7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather bump the requirement, so that people using FrameworkBundle 2.7 can be sure about which loaders are supported

lavoiesl and others added 2 commits January 18, 2015 11:16
Issue #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.
@lavoiesl
Copy link
Contributor Author

Errors in Travis not related to my PR.

@webda2l
Copy link

webda2l commented Apr 16, 2015

Too late for 2.7? Will be a nice addition.

@nicolas-grekas
Copy link
Member

Cherry-picked in #14700 thank you @lavoiesl!

fabpot added a commit that referenced this pull request Jun 5, 2015
…ectory 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 | #13246, #11045, #11059
| License       | MIT
| Doc PR        | -

Commits
-------

60b1c5b Added CHANGELOG entries, cleanups
73f0ee2 [DI][Routing] recursive directory loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants