From 1d7e9d975390b42dc73cb9138c6dd09df085be1b Mon Sep 17 00:00:00 2001 From: "marc.weistroff" Date: Fri, 6 Apr 2012 15:38:50 +0200 Subject: [PATCH 1/2] Adds a linter command for templates --- CHANGELOG-2.1.md | 1 + .../Bundle/TwigBundle/Command/LintCommand.php | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/Symfony/Bundle/TwigBundle/Command/LintCommand.php diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md index 6bbec4b0937f4..779f93be69c9e 100644 --- a/CHANGELOG-2.1.md +++ b/CHANGELOG-2.1.md @@ -148,6 +148,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c ### TwigBundle * added the real template name when an error occurs in a Twig template + * added the twig:lint command that will validate a Twig template syntax. ### WebProfilerBundle diff --git a/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php b/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php new file mode 100644 index 0000000000000..8ed303829bbbc --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\TwigBundle\Command; + +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Command that will validate your template syntax and output encountered errors. + * + * @author Marc Weistroff + */ +class LintCommand extends ContainerAwareCommand +{ + protected function configure() + { + $this + ->setName('twig:lint') + ->setDescription('Lints a template and outputs eventual errors.') + ->addArgument('filename') + ->setHelp(<<%command.name% command lints a template and outputs to stdout +the first encountered syntax error. + +php %command.full_name% filename + +The command will get the contents of "filename" and will validates its syntax. + +cat filename | php %command.full_name% + +The command will get the template contents from stdin and will validates its syntax. + +This command will return these error codes: + - 1 if template is invalid + - 2 if file doesn't exists or stdin is empty. +EOF + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $twig = $this->getContainer()->get('twig'); + $template = null; + $filename = $input->getArgument('filename'); + + if ($filename && !is_readable($filename)) { + $output->writeln(sprintf('File %s is not readable', $filename)); + + return 2; + } + + if ($filename) { + $template = file_get_contents($filename); + } else { + if (0 !== ftell(STDIN)) { + $output->writeln(sprintf('Please provide a filename or pipe template content to stdin.')); + + return 2; + } + while (!feof(STDIN)) { + $template .= fread(STDIN, 1024); + } + } + + try { + $twig->parse($twig->tokenize($template)); + } catch(\Twig_Error_Syntax $e) { + $output->writeln($e->getMessage()); + + return 1; + } + + $output->writeln("Template's syntax is valid."); + } +} + From 8726ade31036904b5c6f8778b816ec622882b73b Mon Sep 17 00:00:00 2001 From: "marc.weistroff" Date: Sun, 8 Apr 2012 11:14:51 +0200 Subject: [PATCH 2/2] Adds more features to twig:lint command --- .../Bundle/TwigBundle/Command/LintCommand.php | 56 +++++++++++++------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php b/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php index 8ed303829bbbc..46b7d338ccea2 100644 --- a/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php +++ b/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php @@ -14,6 +14,7 @@ use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Finder\Finder; /** * Command that will validate your template syntax and output encountered errors. @@ -36,6 +37,16 @@ protected function configure() The command will get the contents of "filename" and will validates its syntax. +php %command.full_name% dirname + +The command will find all twig templates in dirname and will validate the syntax +of each Twig template. + +php %command.full_name% @AcmeMyBundle + +The command will find all twig templates in bundle AcmeMyBundle and will validate +the syntax of each one. + cat filename | php %command.full_name% The command will get the template contents from stdin and will validates its syntax. @@ -54,34 +65,43 @@ protected function execute(InputInterface $input, OutputInterface $output) $template = null; $filename = $input->getArgument('filename'); - if ($filename && !is_readable($filename)) { - $output->writeln(sprintf('File %s is not readable', $filename)); - - return 2; - } - - if ($filename) { - $template = file_get_contents($filename); - } else { + if (!$filename) { if (0 !== ftell(STDIN)) { - $output->writeln(sprintf('Please provide a filename or pipe template content to stdin.')); - - return 2; + throw new \RuntimeException("Please provide a filename or pipe template content to stdin."); } + while (!feof(STDIN)) { $template .= fread(STDIN, 1024); } + + return $twig->parse($twig->tokenize($template)); + } + + if (0 !== strpos($filename, '@') && !is_readable($filename)) { + throw new \RuntimeException("File or directory '%s' is not readable"); } - try { - $twig->parse($twig->tokenize($template)); - } catch(\Twig_Error_Syntax $e) { - $output->writeln($e->getMessage()); + $files = array(); + if (is_file($filename)) { + $files = array($filename); + } elseif (is_dir($filename)) { + $files = Finder::create()->files()->in($filename)->name('*.twig'); + } else { + $dir = $this->getApplication()->getKernel()->locateResource($filename); + $files = Finder::create()->files()->in($dir)->name('*.twig'); + } - return 1; + foreach ($files as $file) { + try { + $twig->parse($twig->tokenize(file_get_contents($file))); + } catch (\Exception $e) { + $output->writeln(sprintf('Syntax error in %s', $file)); + + throw $e; + } } - $output->writeln("Template's syntax is valid."); + $output->writeln('No syntax error detected.'); } }