8000 feature #29139 [FrameworkBundle][TranslationDebug] Return non-zero ex… · symfony/symfony@94efc95 · GitHub
[go: up one dir, main page]

Skip to content

Commit 94efc95

Browse files
committed
feature #29139 [FrameworkBundle][TranslationDebug] Return non-zero exit code on failure (DAcodedBEAT)
This PR was squashed before being merged into the 5.1-dev branch (closes #29139). Discussion ---------- [FrameworkBundle][TranslationDebug] Return non-zero exit code on failure | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | TBD This PR introduces non-zero exit codes upon failure for the `debug:translations` command. The addition can be useful for projects which wish to determine results easily in CI. The exit code returned can be interpreted as a bit array and to determine what failed, one could Bitwise AND the returned exit code to determine what failed. Exit Codes: | Failure Reason | bit array | integer | | ---------------- | --------- | --------- | | General Failure (i.e no translations at all) | `1000000` | 64 | | Missing Translations | `1000001` | 65 | | Unused Translations | `1000010` | 66 | | Fallback Translations | `1000100` | 68 | Example: Given there are missing and unused translations, the expected status code would be `TranslationDebugCommand::EXIT_CODE_MISSING | TranslationDebugCommand::EXIT_CODE_UNUSED`, which would be evaluated to `67`. Commits ------- 0baafd8 [FrameworkBundle][TranslationDebug] Return non-zero exit code on failure
2 parents 81abb4e + 0baafd8 commit 94efc95

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
*/
3939
class TranslationDebugCommand extends Command
4040
{
41+
const EXIT_CODE_GENERAL_ERROR = 64;
42+
const EXIT_CODE_MISSING = 65;
43+
const EXIT_CODE_UNUSED = 66;
44+
const EXIT_CODE_FALLBACK = 68;
4145
const MESSAGE_MISSING = 0;
4246
const MESSAGE_UNUSED = 1;
4347
const MESSAGE_EQUALS_FALLBACK = 2;
@@ -123,6 +127,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
123127

124128
$locale = $input->getArgument('locale');
125129
$domain = $input->getOption('domain');
130+
131+
$exitCode = 0;
132+
126133
/** @var KernelInterface $kernel */
127134
$kernel = $this->getApplication()->getKernel();
128135

@@ -191,7 +198,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
191198

192199
$io->getErrorStyle()->warning($outputMessage);
193200

194-
return 0;
201+
return self::EXIT_CODE_GENERAL_ERROR;
195202
}
196203

197204
// Load the fallback catalogues
@@ -212,9 +219,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int
212219
if ($extractedCatalogue->defines($messageId, $domain)) {
213220
if (!$currentCatalogue->defines($messageId, $domain)) {
214221
$states[] = self::MESSAGE_MISSING;
222+
223+
$exitCode = $exitCode | self::EXIT_CODE_MISSING;
215224
}
216225
} elseif ($currentCatalogue->defines($messageId, $domain)) {
217226
$states[] = self::MESSAGE_UNUSED;
227+
228+
$exitCode = $exitCode | self::EXIT_CODE_UNUSED;
218229
}
219230

220231
if (!\in_array(self::MESSAGE_UNUSED, $states) && true === $input->getOption('only-unused')
@@ -226,6 +237,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
226237
if ($fallbackCatalogue->defines($messageId, $domain) && $value === $fallbackCatalogue->get($messageId, $domain)) {
227238
$states[] = self::MESSAGE_EQUALS_FALLBACK;
228239

240+
$exitCode = $exitCode | self::EXIT_CODE_FALLBACK;
241+
229242
break;
230243
}
231244
}
@@ -241,7 +254,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
241254

242255
$io->table($headers, $rows);
243256

244-
return 0;
257+
return $exitCode;
245258
}
246259

247260
private function formatState(int $state): string

src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,42 +26,48 @@ class TranslationDebugCommandTest extends TestCase
2626
public function testDebugMissingMessages()
2727
{
2828
$tester = $this->createCommandTester(['foo' => 'foo']);
29-
$tester->execute(['locale' => 'en', 'bundle' => 'foo']);
29+
$res = $tester->execute(['locale' => 'en', 'bundle' => 'foo']);
3030

3131
$this->assertRegExp('/missing/', $tester->getDisplay());
32+
$this->assertEquals(TranslationDebugCommand::EXIT_CODE_MISSING, $res);
3233
}
3334

3435
public function testDebugUnusedMessages()
3536
{
3637
$tester = $this->createCommandTester([], ['foo' => 'foo']);
37-
$tester->execute(['locale' => 'en', 'bundle' => 'foo']);
38+
$res = $tester->execute(['locale' => 'en', 'bundle' => 'foo']);
3839

3940
$this->assertRegExp('/unused/', $tester->getDisplay());
41+
$this->assertEquals(TranslationDebugCommand::EXIT_CODE_UNUSED, $res);
4042
}
4143

4244
public function testDebugFallbackMessages()
4345
{
44-
$tester = $this->createCommandTester([], ['foo' => 'foo']);
45-
$tester->execute(['locale' => 'fr', 'bundle' => 'foo']);
46+
$tester = $this->createCommandTester(['foo' => 'foo'], ['foo' => 'foo']);
47+
$res = $tester->execute(['locale' => 'fr', 'bundle' => 'foo']);
4648

4749
$this->assertRegExp('/fallback/', $tester->getDisplay());
50+
$this->assertEquals(TranslationDebugCommand::EXIT_CODE_FALLBACK, $res);
4851
}
4952

5053
public function testNoDefinedMessages()
5154
{
5255
$tester = $this->createCommandTester();
53-
$tester->execute(['locale' => 'fr', 'bundle' => 'test']);
56+
$res = $tester->execute(['locale' => 'fr', 'bundle' => 'test']);
5457

5558
$this->assertRegExp('/No defined or extracted messages for locale "fr"/', $tester->getDisplay());
59+
$this->assertEquals(TranslationDebugCommand::EXIT_CODE_GENERAL_ERROR, $res);
5660
}
5761

5862
public function testDebugDefaultDirectory()
5963
{
6064
$tester = $this->createCommandTester(['foo' => 'foo'], ['bar' => 'bar']);
61-
$tester->execute(['locale' => 'en']);
65+
$res = $tester->execute(['locale' => 'en']);
66+
$expectedExitStatus = TranslationDebugCommand::EXIT_CODE_MISSING | TranslationDebugCommand::EXIT_CODE_UNUSED;
6267

6368
$this->assertRegExp('/missing/', $tester->getDisplay());
6469
$this->assertRegExp('/unused/', $tester->getDisplay());
70+
$this->assertEquals($expectedExitStatus, $res);
6571
}
6672

6773
public function testDebugDefaultRootDirectory()
@@ -72,11 +78,14 @@ public function testDebugDefaultRootDirectory()
7278
$this->fs->mkdir($this->translationDir.'/translations');
7379
$this->fs->mkdir($this->translationDir.'/templates');
7480

81+
$expectedExitStatus = TranslationDebugCommand::EXIT_CODE_MISSING | TranslationDebugCommand::EXIT_CODE_UNUSED;
82+
7583
$tester = $this->createCommandTester(['foo' => 'foo'], ['bar' => 'bar'], null, [$this->translationDir.'/trans'], [$this->translationDir.'/views']);
76-
$tester->execute(['locale' => 'en']);
84+
$res = $tester->execute(['locale' => 'en']);
7785

7886
$this->assertRegExp('/missing/', $tester->getDisplay());
7987
$this->assertRegExp('/unused/', $tester->getDisplay());
88+
$this->assertEquals($expectedExitStatus, $res);
8089
}
8190

8291
public function testDebugCustomDirectory()
@@ -89,11 +98,14 @@ public function testDebugCustomDirectory()
8998
->with($this->equalTo($this->translationDir.'/customDir'))
9099
->willThrowException(new \InvalidArgumentException());
91100

101+
$expectedExitStatus = TranslationDebugCommand::EXIT_CODE_MISSING | TranslationDebugCommand::EXIT_CODE_UNUSED;
102+
92103
$tester = $this->createCommandTester(['foo' => 'foo'], ['bar' => 'bar'], $kernel);
93-
$tester->execute(['locale' => 'en', 'bundle' => $this->translationDir.'/customDir']);
104+
$res = $tester->execute(['locale' => 'en', 'bundle' => $this->translationDir.'/customDir']);
94105

95106
$this->assertRegExp('/missing/', $tester->getDisplay());
96107
$this->assertRegExp('/unused/', $tester->getDisplay());
108+
$this->assertEquals($expectedExitStatus, $res);
97109
}
98110

99111
public function testDebugInvalidDirectory()

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/TranslationDebugCommandTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
1313

14+
use Symfony\Bundle\FrameworkBundle\Command\TranslationDebugCommand;
1415
use Symfony\Bundle\FrameworkBundle\Console\Application;
1516
use Symfony\Component\Console\Tester\CommandTester;
1617

@@ -32,7 +33,11 @@ public function testDumpAllTrans()
3233
$tester = $this->createCommandTester();
3334
$ret = $tester->execute(['locale' => 'en']);
3435

35-
$this->assertSame(0, $ret, 'Returns 0 in case of success');
36+
$this->assertSame(
37+
TranslationDebugCommand::EXIT_CODE_MISSING | TranslationDebugCommand::EXIT_CODE_UNUSED,
38+
$ret,
39+
'Returns appropriate exit code in the event of error'
40+
);
3641
$this->assertStringContainsString('missing messages hello_from_construct_arg_service', $tester->getDisplay());
3742
$this->assertStringContainsString('missing messages hello_from_subscriber_service', $tester->getDisplay());
3843
$this->assertStringContainsString('missing messages hello_from_property_service', $tester->getDisplay());

0 commit comments

Comments
 (0)
0