-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[TwigBridge] Added compile-time issues checking in twig:lint command #10843
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
maxromanovsky
commented
May 2, 2014
Q | A |
---|---|
Bug fix? | yes |
New feature? | yes |
BC breaks? | no |
Deprecations? | no |
Tests pass? | yes |
Fixed tickets | #10019 |
License | MIT |
Doc PR | none |
I've also changed the behavior of this command when template content is passed using |
$twig->parse($twig->tokenize($template, $file ? (string) $file : null)); | ||
$loader = $twig->getLoader(); | ||
if ($loader instanceof \Twig_Loader_Filesystem) { | ||
$loader->setPaths(dirname($file)); |
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.
This is wrong. You should not alter the state of the existing loader instance as it might have side effects (for instance when using the console shell to run the command as the same process will continue running, and so the same loader)
Thus, do you really need to use the loader ?
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, I need to use the loader. Otherwise the following exception is being thrown: https://github.com/fabpot/Twig/blob/master/lib/Twig/Loader/Filesystem.php#L191
As a workaround I could try to alter \Symfony\Bridge\Twig\Tests\Command\LintCommandTest::createCommandTester()
method and pass a filename as an argument. Then I'll be able to set a path only in unit tests.
However it would not help with the STDIN
case. In this case I could invoke $loader->getPaths()
, then add a current path, but restore path configuration directly after an invocation.
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.
where is the call to findTemplate
done ?
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.
Exception message: There are no registered paths for namespace "__main__".
Stack trace:
#0 /vagrant/symfony/vendor/twig/twig/lib/Twig/Loader/Filesystem.php(138): Twig_Loader_Filesystem->findTemplate('/tmp/sf-501ERx')
#1 /vagrant/symfony/vendor/twig/twig/lib/Twig/Environment.php(265): Twig_Loader_Filesystem->getCacheKey('/tmp/sf-501ERx')
#2 /vagrant/symfony/vendor/twig/twig/lib/Twig/Node/Module.php(127): Twig_Environment->getTemplateClass('/tmp/sf-501ERx', NULL)
#3 /vagrant/symfony/vendor/twig/twig/lib/Twig/Node/Module.php(51): Twig_Node_Module->compileClassHeader(Object(Twig_Compiler))
#4 /vagrant/symfony/vendor/twig/twig/lib/Twig/Node/Module.php(38): Twig_Node_Module->compileTemplate(Object(Twig_Compiler))
#5 /vagrant/symfony/vendor/twig/twig/lib/Twig/Compiler.php(86): Twig_Node_Module->compile(Object(Twig_Compiler))
#6 /vagrant/symfony/vendor/twig/twig/lib/Twig/Environment.php(543): Twig_Compiler->compile(Object(Twig_Node_Module))
#7 /vagrant/symfony/src/Symfony/Bridge/Twig/Command/LintCommand.php(136): Twig_Environment->compile(Object(Twig_Node_Module))
#8 /vagrant/symfony/src/Symfony/Bridge/Twig/Command/LintCommand.php(110): Symfony\Bridge\Twig\Command\LintCommand->validate(Object(Twig_Environment), '{{ foo }}', '/tmp/sf-501ERx')
#9 /vagrant/symfony/src/Symfony/Component/Console/Command/Command.php(252): Symfony\Bridge\Twig\Command\LintCommand->execute(Object(Symfony\Component\Console\Input\ArrayInput), Object(Symfony\Component\Console\Output\StreamOutput))
#10 /vagrant/symfony/src/Symfony/Component/Console/Tester/CommandTester.php(80): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArrayInput), Object(Symfony\Component\Console\Output\StreamOutput))
#11 /vagrant/symfony/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php(31): Symfony\Component\Console\Tester\CommandTester->execute(Array, Array)
#12 [internal function]: Symfony\Bridge\Twig\Tests\Command\LintCommandTest->testLintCorrectFile()
[...]
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.
ah, this is to get the cache key.
I suggest doing it in a different way: create an ArrayLoader with the template in it (so that getting the cache key works) and set it in Twig. And at the end of the method, reset the original loader in Twig. This way, the original loader is not altered, and you don't need a temporary file
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.
@stof Just to clarify, you suggest to use it in two cases:
LintCommandTest
for all templates used in unit testsLintCommand
just for the case with piped template
Is it correct?
Because it won't work for the most common use case with real templates app/console twig:lint /path/to/files
if templates use inheritance.
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.
it should work. the template inheritance is not resolved at compile time as the parent can be dynamic
@stof Thank you for your advice. I've changed the implementation to use |
Thank you @maxromanovsky. |
…g:lint command (maxromanovsky) This PR was merged into the 2.5-dev branch. Discussion ---------- [TwigBridge] Added compile-time issues checking in twig:lint command | Q | A | ------------- | --- | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #10019 | License | MIT |Doc PR | none Commits ------- 418cea1 [TwigBridge] Added compile-time issues checking in twig:lint command
…put in case of error (GromNaN) This PR was merged into the 7.2 branch. Discussion ---------- [TwigBridge] Remove random file name for `lint:twig` output in case of error | Q | A | ------------- | --- | Branch? | 7.2 | Bug fix? | no | New feature? | no | Deprecations? | no | Issues | Part of #57588 | License | MIT In the `lint:twig`, `uniqid` is used to generate a file name when linting a template from STDIN. - I don't find any reason to use a unique file name. The file name is never stored when the template is tokenized and compiled. The cache is not used. - This meaningless file name is displayed in the output in case of error, which is better replaced by the text "Standard Input". Before: ``` $ bin/console lint:twig - < vendor/symfony/twig-bridge/Resources/views/Email/zurb_2/notification/body.html.twig ERROR in sf_6681e2dd64a2e2.02015003 (line -1) >> The "inky_to_html" filter is part of the InkyExtension, which is not installed/enabled; try running "composer require twig/inky-extra". [WARNING] 0 Twig files have valid syntax and 1 contain errors. ``` After: ``` $ bin/console lint:twig - < vendor/symfony/twig-bridge/Resources/views/Email/zurb_2/notification/body.html.twig ERROR in Standard Input (line -1) >> The "inky_to_html" filter is part of the InkyExtension, which is not installed/enabled; try running "composer require twig/inky-extra". [WARNING] 0 Twig files have valid syntax and 1 contain errors. ``` Note: the `line -1` is due to the lack of context provided to `Twig\Extra\TwigExtraBundle\MissingExtensionSuggestor::suggestFilter()` For reference, this was introduced by #10843 Commits ------- a97acbd Remove random file name for lint:twig output in case of error