Skip to content

Commit 255a07d

Browse files
jawiranicolas-grekas
authored andcommitted
[FrameworkBundle] Add --no-fill option to translation:extract command
1 parent 74fd832 commit 255a07d

File tree

3 files changed

+60
-6
lines changed

3 files changed

+60
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ CHANGELOG
2020
* Add the ability to use an existing service as a lock/semaphore resource
2121
* Add support for configuring multiple serializer instances via the configuration
2222
* Add support for `SYMFONY_TRUSTED_PROXIES`, `SYMFONY_TRUSTED_HEADERS`, `SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER` and `SYMFONY_TRUSTED_HOSTS` env vars
23+
* Add `--no-fill` option to `translation:extract` command
2324

2425
7.1
2526
---

Command/TranslationUpdateCommand.php

+19-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use Symfony\Component\Console\Input\InputArgument;
2020
use Symfony\Component\Console\Input\InputInterface;
2121
use Symfony\Component\Console\Input\InputOption;
22-
use Symfony\Component\Console\Output\ConsoleOutputInterface;
2322
use Symfony\Component\Console\Output\OutputInterface;
2423
use Symfony\Component\Console\Style\SymfonyStyle;
2524
use Symfony\Component\HttpKernel\KernelInterface;
@@ -49,6 +48,7 @@ class TranslationUpdateCommand extends Command
4948
'xlf12' => ['xlf', '1.2'],
5049
'xlf20' => ['xlf', '2.0'],
5150
];
51+
private const NO_FILL_PREFIX = "\0NoFill\0";
5252

5353
public function __construct(
5454
private TranslationWriterInterface $writer,
@@ -71,6 +71,7 @@ protected function configure(): void
7171
new InputArgument('locale', InputArgument::REQUIRED, 'The locale'),
7272
new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'),
7373
new InputOption('prefix', null, InputOption::VALUE_OPTIONAL, 'Override the default prefix', '__'),
74+
new InputOption('no-fill', null, InputOption::VALUE_NONE, 'Extract translation keys without filling in values'),
7475
new InputOption('format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf12'),
7576
new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'),
7677
new InputOption('force', null, InputOption::VALUE_NONE, 'Should the extract be done'),
@@ -85,7 +86,8 @@ protected function configure(): void
8586
the new ones into the translation files.
8687
8788
When new translation strings are found it can automatically add a prefix to the translation
88-
message.
89+
message. However, if the <comment>--no-fill</comment> option is used, the <comment>--prefix</comment>
90+
option has no effect, since the translation values are left empty.
8991
9092
Example running against a Bundle (AcmeBundle)
9193
@@ -113,9 +115,6 @@ protected function configure(): void
113115

114116
protected function execute(InputInterface $input, OutputInterface $output): int
115117
{
116-
$io = new SymfonyStyle($input, $output);
117-
$errorIo = $output instanceof ConsoleOutputInterface ? new SymfonyStyle($input, $output->getErrorOutput()) : $io;
118-
119118
$io = new SymfonyStyle($input, $output);
120119
$errorIo = $io->getErrorStyle();
121120

@@ -181,7 +180,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
181180
$io->comment(\sprintf('Generating "<info>%s</info>" translation files for "<info>%s</info>"', $input->getArgument('locale'), $currentName));
182181

183182
$io->comment('Parsing templates...');
184-
$extractedCatalogue = $this->extractMessages($input->getArgument('locale'), $codePaths, $input->getOption('prefix'));
183+
$prefix = $input->getOption('no-fill') ? self::NO_FILL_PREFIX : $input->getOption('prefix');
184+
$extractedCatalogue = $this->extractMessages($input->getArgument('locale'), $codePaths, $prefix);
185185

186186
$io->comment('Loading translation files...');
187187
$currentCatalogue = $this->loadCurrentMessages($input->getArgument('locale'), $transPaths);
@@ -271,6 +271,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
271271
$operationResult = $this->sortCatalogue($operationResult, $sort);
272272
}
273273

274+
if (true === $input->getOption('no-fill')) {
275+
$this->removeNoFillTranslations($operationResult);
276+
}
277+
274278
$this->writer->write($operationResult, $format, ['path' => $bundleTransPath, 'default_locale' => $this->defaultLocale, 'xliff_version' => $xliffVersion, 'as_tree' => $input->getOption('as-tree'), 'inline' => $input->getOption('as-tree') ?? 0]);
275279

276280
if (true === $input->getOption('dump-messages')) {
@@ -485,4 +489,13 @@ private function getRootCodePaths(KernelInterface $kernel): array
485489

486490
return $codePaths;
487491
}
492+
493+
private function removeNoFillTranslations(MessageCatalogueInterface $operation): void
494+
{
495+
foreach ($operation->all('messages') as $key => $message) {
496+
if (str_starts_with($message, self::NO_FILL_PREFIX)) {
497+
$operation->set($key, '', 'messages');
498+
}
499+
}
500+
}
488501
}

Tests/Command/TranslationUpdateCommandTest.php

+40
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\HttpKernel\KernelInterface;
2222
use Symfony\Component\Translation\Extractor\ExtractorInterface;
2323
use Symfony\Component\Translation\MessageCatalogue;
24+
use Symfony\Component\Translation\MessageCatalogueInterface;
2425
use Symfony\Component\Translation\Reader\TranslationReader;
2526
use Symfony\Component\Translation\Translator;
2627
use Symfony\Component\Translation\Writer\TranslationWriter;
@@ -176,6 +177,45 @@ public function testFilterDuplicateTransPaths()
176177
$this->assertEquals($expectedPaths, $filteredTransPaths);
177178
}
178179

180+
/**
181+
* @dataProvider removeNoFillProvider
182+
*/
183+
public function testRemoveNoFillTranslationsMethod($noFillCounter, $messages)
184+
{
185+
// Preparing mock
186+
$operation = $this->createMock(MessageCatalogueInterface::class);
187+
$operation
188+
->method('all')
189+
->with('messages')
190+
->willReturn($messages);
191+
$operation
192+
->expects($this->exactly($noFillCounter))
193+
->method('set');
194+
195+
// Calling private method
196+
$translationUpdate = $this->createMock(TranslationUpdateCommand::class);
197+
$reflection = new \ReflectionObject($translationUpdate);
198+
$method = $reflection->getMethod('removeNoFillTranslations');
199+
$method->invokeArgs($translationUpdate, [$operation]);
200+
}
201+
202+
public function removeNoFillProvider(): array
203+
{
204+
return [
205+
[0, []],
206+
[0, ['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz']],
207+
[0, ['foo' => "\0foo"]],
208+
[0, ['foo' => "foo\0NoFill\0"]],
209+
[0, ['foo' => "f\0NoFill\000"]],
210+
[0, ['foo' => 'foo', 'bar' => 'bar']],
211+
[1, ['foo' => "\0NoFill\0foo"]],
212+
[1, ['foo' => "\0NoFill\0foo", 'bar' => 'bar']],
213+
[1, ['foo' => 'foo', 'bar' => "\0NoFill\0bar"]],
214+
[2, ['foo' => "\0NoFill\0foo", 'bar' => "\0NoFill\0bar"]],
215+
[3, ['foo' => "\0NoFill\0foo", 'bar' => "\0NoFill\0bar", 'baz' => "\0NoFill\0baz"]],
216+
];
217+
}
218+
179219
protected function setUp(): void
180220
{
181221
$this->fs = new Filesystem();

0 commit comments

Comments
 (0)