Skip to content

[DI] Add ContainerBuilder::fileExists() for checking/tracking resource existence #21408

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

Merged
merged 1 commit into from
Feb 2, 2017

Conversation

chalasr
Copy link
Member

@chalasr chalasr commented Jan 25, 2017

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #20189, #20189 (comment)
License MIT
Doc PR n/a

Finishes #20189 Adds a convenient ContainerBuilder::fileExists() method as suggested by Nicolas and use it to track resources in the FrameworkExtension, adding some missing ones.

@chalasr chalasr changed the title Missing existence resource [Config][FrameworkBundle] Add missing class/directory/file existence resource Jan 25, 2017
@chalasr chalasr force-pushed the missing-existence-resource branch 2 times, most recently from 772970b to 9328b37 Compare January 25, 2017 18:02
@ogizanagi
Copy link
Contributor

According to #20189 (comment), it seems the DirectoryExistenceResource implementation should allow to detect new files in the directory. Not only check if the dir exists (which already worked with the FileExistenceResource but here you ensure it's a dir).

@@ -900,6 +915,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
// Register translation resources
if ($dirs) {
foreach ($dirs as $dir) {
$container->addResource(new DirectoryExistenceResource($dir));
Copy link
Member

Choose a reason for hiding this comment

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

this is wrong. It must be done earlier, because the directories are not added in $dirs if they don't exist, and this is precisely the case where we need the DirectoryExistenceResource

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed

$files['yml'][] = $file;
$container->addResource(new FileResource($file));
}

if (is_file($file = $dirname.'/Resources/config/validation.xml')) {
$container->addResource(new FileExistenceResource($file = $dirname.'/Resources/config/validation.xml'));
Copy link
Member

Choose a reason for hiding this comment

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

We could optimize things by adding it only when the file does not exist (as we already have a FileResource when it exists, and removing the file will also invalidate the FileResource).
Or we should remove the FileResource if the content of the file does not impact the container itself (which may well be the case for this particular case)

Copy link
Member Author

Choose a reason for hiding this comment

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

These paths being all passed to a definition through a method call, don't they impact it?

Copy link
Member

Choose a reason for hiding this comment

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

well, if the paths are passed, the content of the file does not impact the container definition (it cannot impact it if you never read the content during the container building). So a FileResource is useless. Only FileExistenceResource is needed.

And it avoids invalidating the container cache when adding a new validation constraint while the container does not care about them and so would rebuild exactly the same one

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the explanation.

@stof
Copy link
Member

stof commented Jan 25, 2017

@ogizanagi no. If you need to detect the addition of new files inside a directory, you must use DirectoryResource. This is exactly what it does.

And IIRC, we used FileExistenceResource to account for cases checking for directory existence in the past (the only case where it would fail is if you replace a file with a directory with the same name, but this is weird)

@ogizanagi
Copy link
Contributor

ogizanagi commented Jan 25, 2017

@stof : You're right. Thanks for the head up. I misinterpreted @fabpot comment and didn't even realized I was talking about the existing DirectoryResource implementation... -.-'

@chalasr
Copy link
Member Author

chalasr commented Jan 25, 2017

And IIRC, we used FileExistenceResource to account for cases checking for directory existence in the past (the only case where it would fail is if you replace a file with a directory with the same name, but this is weird)

@stof Sure, FileExistenceResource would work except for the edge case you mentioned. IMHO the distinction is not bad to have, but I'll revert if you think it's not worth it.

Btw, I updated the places you're talking about for make them use DirectoryExistenceResource instead.

@chalasr chalasr force-pushed the missing-existence-resource branch 2 times, most recently from cfc5524 to f901285 Compare January 25, 2017 20:40
@chalasr chalasr changed the title [Config][FrameworkBundle] Add missing class/directory/file existence resource [FrameworkBundle] Add missing class/directory/file existence resource Jan 25, 2017
@chalasr
Copy link
Member Author

chalasr commented Jan 25, 2017

Comments addressed

@@ -105,15 +114,16 @@ public function load(array $configs, ContainerBuilder $container)
// default in the Form and Validator component). If disabled, an identity
// translator will be used and everything will still work as expected.
if ($this->isConfigEnabled($container, $config['translator']) || $this->isConfigEnabled($container, $config['form']) || $this->isConfigEnabled($container, $config['validation'])) {
if (!class_exists('Symfony\Component\Translation\Translator') && $this->isConfigEnabled($container, $config['translator'])) {
$container->addResource(new ClassExistenceResource(Translator::class));
Copy link
Member

Choose a reason for hiding this comment

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

Why should we track classes for throwing cases? Isn't the container not dumped when an exception is thrown? Thus there is nothing to track? (same below)

Copy link
Member Author

Choose a reason for hiding this comment

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

I think you're right. Removed

if (is_dir($dir)) {
$dirs[] = $dir;
} else {
throw new \UnexpectedValueException(sprintf('%s defined in translator.paths does not exist or is not a directory', $dir));
}
}

if (is_dir($dir = $rootDir.'/Resources/translations')) {
$container->addResource(new FileExistenceResource($dir = $rootDir.'/Resources/translations'));
Copy link
Member

Choose a reason for hiding this comment

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

this is already tracked a few lines below

Copy link
Member

Choose a reason for hiding this comment

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

maybe not when the dir is not found in fact - then should be added in an "else" case of the following "if", isn't it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed, moved in a else

}

if (is_file($file = $dirname.'/Resources/config/validation.xml')) {
$container->addResource(new FileExistenceResource($file = $dirname.'/Resources/config/validation.xml'));
Copy link
Member

Choose a reason for hiding this comment

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

FileExistence is not enoug when the file is found - FileResource is needed then

Copy link
Member Author

Choose a reason for hiding this comment

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

Please see #21408 (comment) from @stof

@chalasr chalasr force-pushed the missing-existence-resource branch 7 times, most recently from ad9b26f to 0026c67 Compare January 29, 2017 14:59
@@ -105,15 +112,15 @@ public function load(array $configs, ContainerBuilder $container)
// default in the Form and Validator component). If disabled, an identity
// translator will be used and everything will still work as expected.
if ($this->isConfigEnabled($container, $config['translator']) || $this->isConfigEnabled($container, $config['form']) || $this->isConfigEnabled($container, $config['validation'])) {
if (!class_exists('Symfony\Component\Translation\Translator') && $this->isConfigEnabled($container, $config['translator'])) {
if (!class_exists(Translator::class) && $this->isConfigEnabled($container, $config['translator'])) {
Copy link
Member

Choose a reason for hiding this comment

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

as usual, all these should be reverted: they only create merge conflicts with no practical benefit

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, done

@chalasr chalasr force-pushed the missing-existence-resource branch from 0026c67 to f6122ea Compare January 29, 2017 15:10
if ($this->isConfigEnabled($container, $config['form'])) {
$this->formConfigEnabled = true;
$this->registerFormConfiguration($config, $container, $loader);
$config['validation']['enabled'] = true;

if (!class_exists('Symfony\Component\Validator\Validation')) {
if (!class_exists(Validation::class)) {
Copy link
Member

Choose a reason for hiding this comment

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

all 'Foo\Bar' => Bar::class changes in this PR should be reverted :)

Copy link
Member Author

Choose a reason for hiding this comment

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

There was 2 chances :) I'm ok to revert, but fabpot started like this (see https://github.com/symfony/symfony/pull/20189/files) and IMHO it's a good opportunity to make the code more readable

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Jan 29, 2017

Note that this PR might be superseded by #21452
So maybe better to submit a PR on my fork if you see anything missing there?
Or keep here only the parts that are not already covered in #21452?

@chalasr
Copy link
Member Author

chalasr commented Jan 30, 2017

Status: needs work

@chalasr chalasr force-pushed the missing-existence-resource branch 2 times, most recently from d7ee7d6 to 5877987 Compare January 30, 2017 12:45
@chalasr
Copy link
Member Author

chalasr commented Jan 30, 2017

@nicolas-grekas Updated TwigExtension and DoctrineValidationPass, other places do not seem relevant (either they are about RouteCollection::addResource() or do not look for the resource existence).

Status: needs review

@chalasr chalasr force-pushed the missing-existence-resource branch 2 times, most recently from 9b39dca to cfe850b Compare January 30, 2017 12:55
if ($trackContents) {
if (is_file($path)) {
$this->addResource(new FileResource($path));
} elseif (is_dir($path)) {
Copy link
Member

Choose a reason for hiding this comment

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

what but just an "else" here? otherwise, it looks strange to has a potential case were we don't do anything (the implicit else here)

Copy link
Member Author

Choose a reason for hiding this comment

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

agreed, done

@chalasr chalasr force-pushed the missing-existence-resource branch 4 times, most recently from 2e4ced3 to cece6d4 Compare January 30, 2017 19:58
@chalasr chalasr force-pushed the missing-existence-resource branch from 076dec5 to 6b556b8 Compare February 2, 2017 10:26
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

👍

@@ -1006,19 +1001,16 @@ private function getValidatorMappingFiles(ContainerBuilder $container, array &$f
foreach ($container->getParameter('kernel.bundles_metadata') as $bundle) {
$dirname = $bundle['path'];

if (is_file($file = $dirname.'/Resources/config/validation.yml')) {
if ($container->fileExists($file = $dirname.'/Resources/config/validation.yml', false)) {
Copy link
Member

Choose a reason for hiding this comment

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

Why did you pass false here (same for similar cases below)?

Copy link
Member Author

Choose a reason for hiding this comment

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

These files do not impact the container (see #21408 (comment))

Copy link
Member

Choose a reason for hiding this comment

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

Ah yeah, just found the hidden discussion too.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should open a PR for older branches to make use of the FileExistenceResource there.

Copy link
Member

@xabbuh xabbuh left a comment

Choose a reason for hiding this comment

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

👍

@nicolas-grekas
Copy link
Member

Thank you @chalasr.

@nicolas-grekas nicolas-grekas merged commit 6b556b8 into symfony:master Feb 2, 2017
nicolas-grekas added a commit that referenced this pull request Feb 2, 2017
…racking resource existence (chalasr)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[DI] Add ContainerBuilder::fileExists() for checking/tracking resource existence

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #20189, #20189 (comment)
| License       | MIT
| Doc PR        | n/a

~~Finishes #20189 Adds a convenient `ContainerBuilder::fileExists()` method as suggested by Nicolas and use it to track resources in the FrameworkExtension, adding some missing ones.

Commits
-------

6b556b8 [DI] Add ContainerBuilder::fileExists()
@chalasr chalasr deleted the missing-existence-resource branch February 2, 2017 13:16
*
* @final
*/
public function fileExists($path, $trackContents = true)
Copy link
Contributor

Choose a reason for hiding this comment

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

I know I'm late to the party, but this name doesn't suggest any side effects. The method actually adds resources and could be better named to reflect this fact.

Copy link
Member Author

Choose a reason for hiding this comment

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

@jakzal This follows up #21452 (comment) which gives the arguments against the need for reflecting the tracking effect in the method name.

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.

8 participants