Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d86ff1

Browse files
Fan2Shrekfabpot
authored andcommitted
[TwigBridge] Collect all deprecations with lint:twig command
1 parent 79ea49c commit 2d86ff1

File tree

3 files changed

+62
-31
lines changed

3 files changed

+62
-31
lines changed

src/Symfony/Bridge/Twig/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Add `is_granted_for_user()` Twig function
88
* Add `field_id()` Twig form helper function
99
* Add a `Twig` constraint that validates Twig templates
10+
* Make `lint:twig` collect all deprecations instead of stopping at the first one
1011

1112
7.2
1213
---

src/Symfony/Bridge/Twig/Command/LintCommand.php

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8989
$this->format = $input->getOption('format') ?? (GithubActionReporter::isGithubActionEnvironment() ? 'github' : 'txt');
9090

9191
if (['-'] === $filenames) {
92-
return $this->display($input, $output, $io, [$this->validate(file_get_contents('php://stdin'), 'Standard Input')]);
92+
return $this->display($input, $output, $io, [$this->validate(file_get_contents('php://stdin'), 'Standard Input', $showDeprecations)]);
9393
}
9494

9595
if (!$filenames) {
@@ -107,38 +107,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
107107
}
108108
}
109109

110-
if ($showDeprecations) {
111-
$prevErrorHandler = set_error_handler(static function ($level, $message, $file, $line) use (&$prevErrorHandler) {
112-
if (\E_USER_DEPRECATED === $level) {
113-
$templateLine = 0;
114-
if (preg_match('/ at line (\d+)[ .]/', $message, $matches)) {
115-
$templateLine = $matches[1];
116-
}
117-
118-
throw new Error($message, $templateLine);
119-
}
120-
121-
return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false;
122-
});
123-
}
124-
125-
try {
126-
$filesInfo = $this->getFilesInfo($filenames);
127-
} finally {
128-
if ($showDeprecations) {
129-
restore_error_handler();
130-
}
131-
}
132-
133-
return $this->display($input, $output, $io, $filesInfo);
110+
return $this->display($input, $output, $io, $this->getFilesInfo($filenames, $showDeprecations));
134111
}
135112

136-
private function getFilesInfo(array $filenames): array
113+
private function getFilesInfo(array $filenames, bool $showDeprecations): array
137114
{
138115
$filesInfo = [];
139116
foreach ($filenames as $filename) {
140117
foreach ($this->findFiles($filename) as $file) {
141-
$filesInfo[] = $this->validate(file_get_contents($file), $file);
118+
$filesInfo[] = $this->validate(file_get_contents($file), $file, $showDeprecations);
142119
}
143120
}
144121

@@ -156,8 +133,26 @@ protected function findFiles(string $filename): iterable
156133
throw new RuntimeException(\sprintf('File or directory "%s" is not readable.', $filename));
157134
}
158135

159-
private function validate(string $template, string $file): array
136+
private function validate(string $template, string $file, bool $collectDeprecation): array
160137
{
138+
$deprecations = [];
139+
if ($collectDeprecation) {
140+
$prevErrorHandler = set_error_handler(static function ($level, $message, $fileName, $line) use (&$prevErrorHandler, &$deprecations, $file) {
141+
if (\E_USER_DEPRECATED === $level) {
142+
$templateLine = 0;
143+
if (preg_match('/ at line (\d+)[ .]/', $message, $matches)) {
144+
$templateLine = $matches[1];
145+
}
146+
147+
$deprecations[] = ['message' => $message, 'file' => $file, 'line' => $templateLine];
148+
149+
return true;
150+
}
151+
152+
return $prevErrorHandler ? $prevErrorHandler($level, $message, $fileName, $line) : false;
153+
});
154+
}
155+
161156
$realLoader = $this->twig->getLoader();
162157
try {
163158
$temporaryLoader = new ArrayLoader([$file => $template]);
@@ -169,9 +164,13 @@ private function validate(string $template, string $file): array
169164
$this->twig->setLoader($realLoader);
170165

171166
return ['template' => $template, 'file' => $file, 'line' => $e->getTemplateLine(), 'valid' => false, 'exception' => $e];
167+
} finally {
168+
if ($collectDeprecation) {
169+
restore_error_handler();
170+
}
172171
}
173172

174-
return ['template' => $template, 'file' => $file, 'valid' => true];
173+
return ['template' => $template, 'file' => $file, 'deprecations' => $deprecations, 'valid' => true];
175174
}
176175

177176
private function display(InputInterface $input, OutputInterface $output, SymfonyStyle $io, array $files): int
@@ -188,6 +187,11 @@ private function displayTxt(OutputInterface $output, SymfonyStyle $io, array $fi
188187
{
189188
$errors = 0;
190189
$githubReporter = $errorAsGithubAnnotations ? new GithubActionReporter($output) : null;
190+
$deprecations = array_merge(...array_column($filesInfo, 'deprecations'));
191+
192+
foreach ($deprecations as $deprecation) {
193+
$this->renderDeprecation($io, $deprecation['line'], $deprecation['message'], $deprecation['file'], $githubReporter);
194+
}
191195

192196
foreach ($filesInfo as $info) {
193197
if ($info['valid'] && $output->isVerbose()) {
@@ -204,7 +208,7 @@ private function displayTxt(OutputInterface $output, SymfonyStyle $io, array $fi
204208
$io->warning(\sprintf('%d Twig files have valid syntax and %d contain errors.', \count($filesInfo) - $errors, $errors));
205209
}
206210

207-
return min($errors, 1);
211+
return !$deprecations && !$errors ? 0 : 1;
208212
}
209213

210214
private function displayJson(OutputInterface $output, array $filesInfo): int
@@ -226,6 +230,19 @@ private function displayJson(OutputInterface $output, array $filesInfo): int
226230
return min($errors, 1);
227231
}
228232

233+
private function renderDeprecation(SymfonyStyle $output, int $line, string $message, string $file, ?GithubActionReporter $githubReporter): void
234+
{
235+
$githubReporter?->error($message, $file, $line <= 0 ? null : $line);
236+
237+
if ($file) {
238+
$output->text(\sprintf('<info> DEPRECATION </info> in %s (line %s)', $file, $line));
239+
} else {
240+
$output->text(\sprintf('<info> DEPRECATION </info> (line %s)', $line));
241+
}
242+
243+
$output->text(\sprintf('<info> >> %s</info> ', $message));
244+
}
245+
229246
private function renderException(SymfonyStyle $output, string $template, Error $exception, ?string $file = null, ?GithubActionReporter $githubReporter = null): void
230247
{
231248
$line = $exception->getTemplateLine();

src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,20 @@ public function testLintFileWithReportedDeprecation()
9494
$ret = $tester->execute(['filename' => [$filename], '--show-deprecations' => true], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]);
9595

9696
$this->assertEquals(1, $ret, 'Returns 1 in case of error');
97-
$this->assertMatchesRegularExpression('/ERROR in \S+ \(line 1\)/', trim($tester->getDisplay()));
97+
$this->assertMatchesRegularExpression('/DEPRECATION in \S+ \(line 1\)/', trim($tester->getDisplay()));
98+
$this->assertStringContainsString('Filter "deprecated_filter" is deprecated', trim($tester->getDisplay()));
99+
}
100+
101+
public function testLintFileWithMultipleReportedDeprecation()
102+
{
103+
$tester = $this->createCommandTester();
104+
$filename = $this->createFile("{{ foo|deprecated_filter }}\n{{ bar|deprecated_filter }}");
105+
106+
$ret = $tester->execute(['filename' => [$filename], '--show-deprecations' => true], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]);
107+
108+
$this->assertEquals(1, $ret, 'Returns 1 in case of error');
109+
$this->assertMatchesRegularExpression('/DEPRECATION in \S+ \(line 1\)/', trim($tester->getDisplay()));
110+
$this->assertMatchesRegularExpression('/DEPRECATION in \S+ \(line 2\)/', trim($tester->getDisplay()));
98111
$this->assertStringContainsString('Filter "deprecated_filter" is deprecated', trim($tester->getDisplay()));
99112
}
100113

0 commit comments

Comments
 (0)