11
11
12
12
namespace Symfony \Bridge \Twig \Command ;
13
13
14
+ if (!defined ('JSON_PRETTY_PRINT ' )) {
15
+ define ('JSON_PRETTY_PRINT ' , 128 );
16
+ }
17
+
14
18
use Symfony \Component \Console \Command \Command ;
15
19
use Symfony \Component \Console \Input \InputInterface ;
20
+ use Symfony \Component \Console \Input \InputOption ;
16
21
use Symfony \Component \Console \Output \OutputInterface ;
17
22
use Symfony \Component \Finder \Finder ;
18
23
@@ -56,6 +61,7 @@ protected function configure()
56
61
{
57
62
$ this
58
63
->setDescription ('Lints a template and outputs encountered errors ' )
64
+ ->addOption ('format ' , null , InputOption::VALUE_REQUIRED , 'The output format ' , 'txt ' )
59
65
->addArgument ('filename ' )
60
66
->setHelp (<<<EOF
61
67
The <info>%command.name%</info> command lints a template and outputs to STDOUT
@@ -68,6 +74,7 @@ protected function configure()
68
74
Or of a whole directory:
69
75
70
76
<info>php %command.full_name% dirname</info>
77
+ <info>php %command.full_name% dirname --format=json</info>
71
78
72
79
You can also pass the template contents from STDIN:
73
80
@@ -80,29 +87,27 @@ protected function configure()
80
87
protected function execute (InputInterface $ input , OutputInterface $ output )
81
88
{
82
89
$ twig = $ this ->getTwigEnvironment ();
83
- $ template = null ;
84
90
$ filename = $ input ->getArgument ('filename ' );
85
91
86
92
if (!$ filename ) {
87
93
if (0 !== ftell (STDIN )) {
88
94
throw new \RuntimeException ("Please provide a filename or pipe template content to STDIN. " );
89
95
}
90
96
97
+ $ template = '' ;
91
98
while (!feof (STDIN )) {
92
99
$ template .= fread (STDIN , 1024 );
93
100
}
94
101
95
- return $ this ->validateTemplate ( $ twig , $ output , $ template );
102
+ return $ this ->display ( $ input , $ output , array ( $ this -> validate ( $ twig , $ template)) );
96
103
}
97
104
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 );
103
108
}
104
109
105
- return $ errors > 0 ? 1 : 0 ;
110
+ return $ this -> display ( $ input , $ output , $ filesInfo ) ;
106
111
}
107
112
108
113
protected function findFiles ($ filename )
@@ -116,32 +121,77 @@ protected function findFiles($filename)
116
121
throw new \RuntimeException (sprintf ('File or directory "%s" is not readable ' , $ filename ));
117
122
}
118
123
119
- protected function validateTemplate (\Twig_Environment $ twig, OutputInterface $ output , $ template , $ file = null )
124
+ private function validate (\Twig_Environment $ twig , $ template , $ file = null )
120
125
{
121
126
try {
122
127
$ twig ->parse ($ twig ->tokenize ($ template , $ file ? (string ) $ file : null ));
123
- $ output ->writeln ('<info>OK</info> ' .($ file ? sprintf (' in %s ' , $ file ) : '' ));
124
128
} 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 ;
126
150
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
+ }
128
158
}
129
159
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 );
131
182
}
132
183
133
- protected function renderException (OutputInterface $ output , $ template , \Twig_Error $ exception , $ file = null )
184
+ private function renderException (OutputInterface $ output , $ template , \Twig_Error $ exception , $ file = null )
134
185
{
135
186
$ line = $ exception ->getTemplateLine ();
136
- $ lines = $ this ->getContext ($ template , $ line );
137
187
138
188
if ($ file ) {
139
189
$ output ->writeln (sprintf ("<error>KO</error> in %s (line %s) " , $ file , $ line ));
140
190
} else {
141
191
$ output ->writeln (sprintf ("<error>KO</error> (line %s) " , $ line ));
142
192
}
143
193
144
- foreach ($ lines as $ no => $ code ) {
194
+ foreach ($ this -> getContext ( $ template , $ line ) as $ no => $ code ) {
145
195
$ output ->writeln (sprintf (
146
196
"%s %-6s %s " ,
147
197
$ no == $ line ? '<error>>></error> ' : ' ' ,
@@ -154,7 +204,7 @@ protected function renderException(OutputInterface $output, $template, \Twig_Err
154
204
}
155
205
}
156
206
157
- protected function getContext ($ template , $ line , $ context = 3 )
207
+ private function getContext ($ template , $ line , $ context = 3 )
158
208
{
159
209
$ lines = explode ("\n" , $ template );
160
210
0 commit comments