diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md index 7fe0684061..c0489a73ef 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 0000000000..46b7d338cc --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Command/LintCommand.php @@ -0,0 +1,107 @@ + + * + * 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; +use Symfony\Component\Finder\Finder; + +/** + * 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. + +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. + +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) { + if (0 !== ftell(STDIN)) { + 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"); + } + + $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'); + } + + 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('No syntax error detected.'); + } +} +