1111
1212namespace Symfony \Bridge \Twig \Command ;
1313
14+ if (!defined ('JSON_PRETTY_PRINT ' )) {
15+ define ('JSON_PRETTY_PRINT ' , 128 );
16+ }
17+
1418use Symfony \Component \Console \Command \Command ;
1519use Symfony \Component \Console \Input \InputInterface ;
20+ use Symfony \Component \Console \Input \InputOption ;
1621use Symfony \Component \Console \Output \OutputInterface ;
1722use Symfony \Component \Finder \Finder ;
1823
@@ -56,6 +61,7 @@ protected function configure()
5661 {
5762 $ this
5863 ->setDescription ('Lints a template and outputs encountered errors ' )
64+ ->addOption ('format ' , null , InputOption::VALUE_REQUIRED , 'The output format ' , 'txt ' )
5965 ->addArgument ('filename ' )
6066 ->setHelp (<<<EOF
6167The <info>%command.name%</info> command lints a template and outputs to STDOUT
@@ -68,6 +74,7 @@ protected function configure()
6874Or of a whole directory:
6975
7076<info>php %command.full_name% dirname</info>
77+ <info>php %command.full_name% dirname --format=json</info>
7178
7279You can also pass the template contents from STDIN:
7380
@@ -80,29 +87,27 @@ protected function configure()
8087 protected function execute (InputInterface $ input , OutputInterface $ output )
8188 {
8289 $ twig = $ this ->getTwigEnvironment ();
83- $ template = null ;
8490 $ filename = $ input ->getArgument ('filename ' );
8591
8692 if (!$ filename ) {
8793 if (0 !== ftell (STDIN )) {
8894 throw new \RuntimeException ("Please provide a filename or pipe template content to STDIN. " );
8995 }
9096
97+ $ template = '' ;
9198 while (!feof (STDIN )) {
9299 $ template .= fread (STDIN , 1024 );
93100 }
94101
95- return $ this ->validateTemplate ( $ twig , $ output , $ template );
102+ return $ this ->display ( $ input , $ output , array ( $ this -> validate ( $ twig , $ template)) );
96103 }
97104
98- $ files = $ this ->findFiles ($ filename );
99-
100- $ errors = 0 ;
101- foreach ($ files as $ file ) {
102- $ errors += $ this ->validateTemplate ($ twig , $ output , file_get_contents ($ file ), $ file );
105+ $ filesInfo = array ();
106+ foreach ($ this ->findFiles ($ filename ) as $ file ) {
107+ $ filesInfo [] = $ this ->validate ($ twig , file_get_contents ($ file ), $ file );
103108 }
104109
105- return $ errors > 0 ? 1 : 0 ;
110+ return $ this -> display ( $ input , $ output , $ filesInfo ) ;
106111 }
107112
108113 protected function findFiles ($ filename )
@@ -116,32 +121,77 @@ protected function findFiles($filename)
116121 throw new \RuntimeException (sprintf ('File or directory "%s" is not readable ' , $ filename ));
117122 }
118123
119- protected function validateTemplate (\Twig_Environment $ twig, OutputInterface $ output , $ template , $ file = null )
124+ private function validate (\Twig_Environment $ twig , $ template , $ file = null )
120125 {
121126 try {
122127 $ twig ->parse ($ twig ->tokenize ($ template , $ file ? (string ) $ file : null ));
123- $ output ->writeln ('<info>OK</info> ' .($ file ? sprintf (' in %s ' , $ file ) : '' ));
124128 } catch (\Twig_Error $ e ) {
125- $ this ->renderException ($ output , $ template , $ e , $ file );
129+ return array ('template ' => $ template , 'file ' => $ file , 'valid ' => false , 'exception ' => $ e );
130+ }
131+
132+ return array ('template ' => $ template , 'file ' => $ file , 'valid ' => true );
133+ }
134+
135+ private function display (InputInterface $ input , OutputInterface $ output , $ files )
136+ {
137+ switch ($ input ->getOption ('format ' )) {
138+ case 'txt ' :
139+ return $ this ->displayTxt ($ output , $ files );
140+ case 'json ' :
141+ return $ this ->displayJson ($ output , $ files );
142+ default :
143+ throw new \InvalidArgumentException (sprintf ('The format "%s" is not supported. ' , $ input ->getOption ('format ' )));
144+ }
145+ }
146+
147+ private function displayTxt (OutputInterface $ output , $ filesInfo )
148+ {
149+ $ errors = 0 ;
126150
127- return 1 ;
151+ foreach ($ filesInfo as $ info ) {
152+ if ($ info ['valid ' ] && $ output ->isVerbose ()) {
153+ $ output ->writeln ('<info>OK</info> ' .($ info ['file ' ] ? sprintf (' in %s ' , $ info ['file ' ]) : '' ));
154+ } elseif (!$ info ['valid ' ]) {
155+ $ errors ++;
156+ $ this ->renderException ($ output , $ info ['template ' ], $ info ['exception ' ], $ info ['file ' ]);
157+ }
128158 }
129159
130- return 0 ;
160+ $ output ->writeln (sprintf ('<comment>%d/%d valid files</comment> ' , count ($ filesInfo ) - $ errors , count ($ filesInfo )));
161+
162+ return min ($ errors , 1 );
163+ }
164+
165+ private function displayJson (OutputInterface $ output , $ filesInfo )
166+ {
167+ $ errors = 0 ;
168+
169+ array_walk ($ filesInfo , function (&$ v ) use (&$ errors ) {
170+ $ v ['file ' ] = (string ) $ v ['file ' ];
171+ unset($ v ['template ' ]);
172+ if (!$ v ['valid ' ]) {
173+ $ v ['message ' ] = $ v ['exception ' ]->getMessage ();
174+ unset($ v ['exception ' ]);
175+ $ errors ++;
176+ }
177+ });
178+
179+ $ output ->writeln (json_encode ($ filesInfo , JSON_PRETTY_PRINT ));
180+
181+ return min ($ errors , 1 );
131182 }
132183
133- protected function renderException (OutputInterface $ output , $ template , \Twig_Error $ exception , $ file = null )
184+ private function renderException (OutputInterface $ output , $ template , \Twig_Error $ exception , $ file = null )
134185 {
135186 $ line = $ exception ->getTemplateLine ();
136- $ lines = $ this ->getContext ($ template , $ line );
137187
138188 if ($ file ) {
139189 $ output ->writeln (sprintf ("<error>KO</error> in %s (line %s) " , $ file , $ line ));
140190 } else {
141191 $ output ->writeln (sprintf ("<error>KO</error> (line %s) " , $ line ));
142192 }
143193
144- foreach ($ lines as $ no => $ code ) {
194+ foreach ($ this -> getContext ( $ template , $ line ) as $ no => $ code ) {
145195 $ output ->writeln (sprintf (
146196 "%s %-6s %s " ,
147197 $ no == $ line ? '<error>>></error> ' : ' ' ,
@@ -154,7 +204,7 @@ protected function renderException(OutputInterface $output, $template, \Twig_Err
154204 }
155205 }
156206
157- protected function getContext ($ template , $ line , $ context = 3 )
207+ private function getContext ($ template , $ line , $ context = 3 )
158208 {
159209 $ lines = explode ("\n" , $ template );
160210
0 commit comments