Skip to content

Commit fa17c79

Browse files
committed
Add completion feature on translation pull and push commands
1 parent ee53863 commit fa17c79

File tree

5 files changed

+163
-19
lines changed

5 files changed

+163
-19
lines changed

src/Symfony/Component/Translation/Command/TranslationPullCommand.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Translation\Command;
1313

1414
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Completion\CompletionInput;
16+
use Symfony\Component\Console\Completion\CompletionSuggestions;
1517
use Symfony\Component\Console\Input\InputArgument;
1618
use Symfony\Component\Console\Input\InputInterface;
1719
use Symfony\Component\Console\Input\InputOption;
@@ -52,6 +54,36 @@ public function __construct(TranslationProviderCollection $providerCollection, T
5254
parent::__construct();
5355
}
5456

57+
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
58+
{
59+
if ($input->mustSuggestArgumentValuesFor('provider')) {
60+
$suggestions->suggestValues($this->providerCollection->keys());
61+
62+
return;
63+
}
64+
65+
if ($input->mustSuggestOptionValuesFor('domains')) {
66+
$provider = $this->providerCollection->get($input->getArgument('provider'));
67+
68+
if ($provider && method_exists($provider, 'getDomains')) {
69+
$domains = $provider->getDomains();
70+
$suggestions->suggestValues($domains);
71+
}
72+
73+
return;
74+
}
75+
76+
if ($input->mustSuggestOptionValuesFor('locales')) {
77+
$suggestions->suggestValues($this->enabledLocales);
78+
79+
return;
80+
}
81+
82+
if ($input->mustSuggestOptionValuesFor('format')) {
83+
$suggestions->suggestValues(['php', 'xlf', 'xlf12', 'xlf20', 'po', 'mo', 'yml', 'yaml', 'ts', 'csv', 'json', 'ini', 'res']);
84+
}
85+
}
86+
5587
/**
5688
* {@inheritdoc}
5789
*/

src/Symfony/Component/Translation/Command/TranslationPushCommand.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Translation\Command;
1313

1414
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Completion\CompletionInput;
16+
use Symfony\Component\Console\Completion\CompletionSuggestions;
1517
use Symfony\Component\Console\Exception\InvalidArgumentException;
1618
use Symfony\Component\Console\Input\InputArgument;
1719
use Symfony\Component\Console\Input\InputInterface;
@@ -47,6 +49,30 @@ public function __construct(TranslationProviderCollection $providers, Translatio
4749
parent::__construct();
4850
}
4951

52+
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
53+
{
54+
if ($input->mustSuggestArgumentValuesFor('provider')) {
55+
$suggestions->suggestValues($this->providers->keys());
56+
57+
return;
58+
}
59+
60+
if ($input->mustSuggestOptionValuesFor('domains')) {
61+
$provider = $this->providers->get($input->getArgument('provider'));
62+
63+
if ($provider && method_exists($provider, 'getDomains')) {
64+
$domains = $provider->getDomains();
65+
$suggestions->suggestValues($domains);
66+
}
67+
68+
return;
69+
}
70+
71+
if ($input->mustSuggestOptionValuesFor('locales')) {
72+
$suggestions->suggestValues($this->enabledLocales);
73+
}
74+
}
75+
5076
/**
5177
* {@inheritdoc}
5278
*/

src/Symfony/Component/Translation/Tests/Command/TranslationProviderTestCase.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,15 @@ protected function tearDown(): void
4444
parent::tearDown();
4545
}
4646

47-
protected function getProviderCollection(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages']): TranslationProviderCollection
47+
protected function getProviderCollection(ProviderInterface $provider, array $providerNames = ['loco'], array $locales = ['en'], array $domains = ['messages']): TranslationProviderCollection
4848
{
49-
return new TranslationProviderCollection([
50-
'loco' => new FilteringProvider($provider, $locales, $domains),
51-
]);
49+
$collection = [];
50+
51+
foreach ($providerNames as $providerName) {
52+
$collection[$providerName] = new FilteringProvider($provider, $locales, $domains);
53+
}
54+
55+
return new TranslationProviderCollection($collection);
5256
}
5357

5458
protected function createFile(array $messages = ['note' => 'NOTE'], $targetLanguage = 'en', $fileNamePattern = 'messages.%locale%.xlf', string $xlfVersion = 'xlf12'): string

src/Symfony/Component/Translation/Tests/Command/TranslationPullCommandTest.php

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Translation\Tests\Command;
1313

1414
use Symfony\Component\Console\Application;
15+
use Symfony\Component\Console\Tester\CommandCompletionTester;
1516
use Symfony\Component\Console\Tester\CommandTester;
1617
use Symfony\Component\Translation\Command\TranslationPullCommand;
1718
use Symfony\Component\Translation\Dumper\XliffFileDumper;
@@ -424,24 +425,65 @@ public function testPullMessagesWithDefaultLocale()
424425
, file_get_contents($filenameFr));
425426
}
426427

428+
/**
429+
* @dataProvider provideCompletionSuggestions
430+
*/
431+
public function testComplete(array $input, array $expectedSuggestions)
432+
{
433+
if (!class_exists(CommandCompletionTester::class)) {
434+
$this->markTestSkipped('Test command completion requires symfony/console 5.4+.');
435+
}
436+
437+
$application = new Application();
438+
$application->add($this->createCommand($this->createMock(ProviderInterface::class), ['en', 'fr', 'it'], ['messages', 'validators'], 'en', ['loco', 'crowdin', 'lokalise']));
439+
440+
$tester = new CommandCompletionTester($application->get('translation:pull'));
441+
$suggestions = $tester->complete($input);
442+
$this->assertSame($expectedSuggestions, $suggestions);
443+
}
444+
445+
public function provideCompletionSuggestions(): \Generator
446+
{
447+
yield 'provider' => [
448+
[''],
449+
['loco', 'crowdin', 'lokalise'],
450+
];
451+
452+
yield '--domains' => [
453+
['loco', '--domains'],
454+
['messages', 'validators'],
455+
];
456+
457+
yield '--locales' => [
458+
['loco', '--locales'],
459+
['en', 'fr', 'it'],
460+
];
461+
}
462+
427463
private function createCommandTester(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages'], $defaultLocale = 'en'): CommandTester
464+
{
465+
$command = $this->createCommand($provider, $locales, $domains, $defaultLocale);
466+
$application = new Application();
467+
$application->add($command);
468+
469+
return new CommandTester($application->find('translation:pull'));
470+
}
471+
472+
private function createCommand(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages'], $defaultLocale = 'en', array $providerNames = ['loco']): TranslationPullCommand
428473
{
429474
$writer = new TranslationWriter();
430475
$writer->addDumper('xlf', new XliffFileDumper());
431476

432477
$reader = new TranslationReader();
433478
$reader->addLoader('xlf', new XliffFileLoader());
434479

435-
$command = new TranslationPullCommand(
436-
$this->getProviderCollection($provider, $locales, $domains),
480+
return new TranslationPullCommand(
481+
$this->getProviderCollection($provider, $providerNames, $locales, $domains),
437482
$writer,
438483
$reader,
439484
$defaultLocale,
440-
[$this->translationAppDir.'/translations']
485+
[$this->translationAppDir.'/translations'],
486+
$locales
441487
);
442-
$application = new Application();
443-
$application->add($command);
444-
445-
return new CommandTester($application->find('translation:pull'));
446488
}
447489
}

src/Symfony/Component/Translation/Tests/Command/TranslationPushCommandTest.php

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Bundle\FrameworkBundle\Tests\Command;
12+
namespace Symfony\Component\Translation\Tests\Command;
1313

1414
use Symfony\Component\Console\Application;
15+
use Symfony\Component\Console\Tester\CommandCompletionTester;
1516
use Symfony\Component\Console\Tester\CommandTester;
1617
use Symfony\Component\Translation\Command\TranslationPushCommand;
1718
use Symfony\Component\Translation\Loader\ArrayLoader;
1819
use Symfony\Component\Translation\Loader\XliffFileLoader;
1920
use Symfony\Component\Translation\Provider\ProviderInterface;
2021
use Symfony\Component\Translation\Reader\TranslationReader;
21-
use Symfony\Component\Translation\Tests\Command\TranslationProviderTestCase;
2222
use Symfony\Component\Translation\TranslatorBag;
2323

2424
/**
@@ -249,20 +249,60 @@ public function testPushForceAndDeleteMissingMessages()
249249
$this->assertStringContainsString('[OK] All local translations has been sent to "null" (for "en, fr" locale(s), and "messages" domain(s)).', trim($tester->getDisplay()));
250250
}
251251

252+
/**
253+
* @dataProvider provideCompletionSuggestions
254+
*/
255+
public function testComplete(array $input, array $expectedSuggestions)
256+
{
257+
if (!class_exists(CommandCompletionTester::class)) {
258+
$this->markTestSkipped('Test command completion requires symfony/console 5.4+.');
259+
}
260+
261+
$application = new Application();
262+
$application->add($this->createCommand($this->createMock(ProviderInterface::class), ['en', 'fr', 'it'], ['messages', 'validators'], ['loco', 'crowdin', 'lokalise']));
263+
264+
$tester = new CommandCompletionTester($application->get('translation:push'));
265+
$suggestions = $tester->complete($input);
266+
$this->assertSame($expectedSuggestions, $suggestions);
267+
}
268+
269+
public function provideCompletionSuggestions(): \Generator
270+
{
271+
yield 'provider' => [
272+
[''],
273+
['loco', 'crowdin', 'lokalise'],
274+
];
275+
276+
yield '--domains' => [
277+
['loco', '--domains'],
278+
['messages', 'validators'],
279+
];
280+
281+
yield '--locales' => [
282+
['loco', '--locales'],
283+
['en', 'fr', 'it'],
284+
];
285+
}
286+
252287
private function createCommandTester(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages']): CommandTester
288+
{
289+
$command = $this->createCommand($provider, $locales, $domains);
290+
$application = new Application();
291+
$application->add($command);
292+
293+
return new CommandTester($application->find('translation:push'));
294+
}
295+
296+
private function createCommand(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages'], array $providerNames = ['loco']): TranslationPushCommand
253297
{
254298
$reader = new TranslationReader();
255299
$reader->addLoader('xlf', new XliffFileLoader());
256300

257-
$command = new TranslationPushCommand(
258-
$this->getProviderCollection($provider, $locales, $domains),
301+
return new TranslationPushCommand(
302+
$this->getProviderCollection($provider, $providerNames, $locales, $domains),
259303
$reader,
260304
[$this->translationAppDir.'/translations'],
261305
$locales
262306
);
263-
$application = new Application();
264-
$application->add($command);
265-
266-
return new CommandTester($application->find('translation:push'));
267307
}
268308
}

0 commit comments

Comments
 (0)