Skip to content

Commit 6207cd1

Browse files
committed
Add completion feature on translation pull and push commands
1 parent 9c44920 commit 6207cd1

File tree

5 files changed

+160
-24
lines changed

5 files changed

+160
-24
lines changed

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

+32
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

+31-5
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;
@@ -32,27 +34,51 @@ final class TranslationPushCommand extends Command
3234
protected static $defaultName = 'translation:push';
3335
protected static $defaultDescription = 'Push translations to a given provider.';
3436

35-
private $providers;
37+
private $providerCollection;
3638
private $reader;
3739
private $transPaths;
3840
private $enabledLocales;
3941

40-
public function __construct(TranslationProviderCollection $providers, TranslationReaderInterface $reader, array $transPaths = [], array $enabledLocales = [])
42+
public function __construct(TranslationProviderCollection $providerCollection, TranslationReaderInterface $reader, array $transPaths = [], array $enabledLocales = [])
4143
{
42-
$this->providers = $providers;
44+
$this->providerCollection = $providerCollection;
4345
$this->reader = $reader;
4446
$this->transPaths = $transPaths;
4547
$this->enabledLocales = $enabledLocales;
4648

4749
parent::__construct();
4850
}
4951

52+
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
53+
{
54+
if ($input->mustSuggestArgumentValuesFor('provider')) {
55+
$suggestions->suggestValues($this->providerCollection->keys());
56+
57+
return;
58+
}
59+
60+
if ($input->mustSuggestOptionValuesFor('domains')) {
61+
$provider = $this->providerCollection->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
*/
5379
protected function configure()
5480
{
55-
$keys = $this->providers->keys();
81+
$keys = $this->providerCollection->keys();
5682
$defaultProvider = 1 === \count($keys) ? $keys[0] : null;
5783

5884
$this
@@ -92,7 +118,7 @@ protected function configure()
92118
*/
93119
protected function execute(InputInterface $input, OutputInterface $output): int
94120
{
95-
$provider = $this->providers->get($input->getArgument('provider'));
121+
$provider = $this->providerCollection->get($input->getArgument('provider'));
96122

97123
if (!$this->enabledLocales) {
98124
throw new InvalidArgumentException(sprintf('You must define "framework.translator.enabled_locales" or "framework.translator.providers.%s.locales" config key in order to work with translation providers.', parse_url($provider, \PHP_URL_SCHEME)));

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

+8-4
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

+45-7
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,61 @@ 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+
$application = new Application();
434+
$application->add($this->createCommand($this->createMock(ProviderInterface::class), ['en', 'fr', 'it'], ['messages', 'validators'], 'en', ['loco', 'crowdin', 'lokalise']));
435+
436+
$tester = new CommandCompletionTester($application->get('translation:pull'));
437+
$suggestions = $tester->complete($input);
438+
$this->assertSame($expectedSuggestions, $suggestions);
439+
}
440+
441+
public function provideCompletionSuggestions(): \Generator
442+
{
443+
yield 'provider' => [
444+
[''],
445+
['loco', 'crowdin', 'lokalise'],
446+
];
447+
448+
yield '--domains' => [
449+
['loco', '--domains'],
450+
['messages', 'validators'],
451+
];
452+
453+
yield '--locales' => [
454+
['loco', '--locales'],
455+
['en', 'fr', 'it'],
456+
];
457+
}
458+
427459
private function createCommandTester(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages'], $defaultLocale = 'en'): CommandTester
460+
{
461+
$command = $this->createCommand($provider, $locales, $domains, $defaultLocale);
462+
$application = new Application();
463+
$application->add($command);
464+
465+
return new CommandTester($application->find('translation:pull'));
466+
}
467+
468+
private function createCommand(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages'], $defaultLocale = 'en', array $providerNames = ['loco']): TranslationPullCommand
428469
{
429470
$writer = new TranslationWriter();
430471
$writer->addDumper('xlf', new XliffFileDumper());
431472

432473
$reader = new TranslationReader();
433474
$reader->addLoader('xlf', new XliffFileLoader());
434475

435-
$command = new TranslationPullCommand(
436-
$this->getProviderCollection($provider, $locales, $domains),
476+
return new TranslationPullCommand(
477+
$this->getProviderCollection($provider, $providerNames, $locales, $domains),
437478
$writer,
438479
$reader,
439480
$defaultLocale,
440-
[$this->translationAppDir.'/translations']
481+
[$this->translationAppDir.'/translations'],
482+
$locales
441483
);
442-
$application = new Application();
443-
$application->add($command);
444-
445-
return new CommandTester($application->find('translation:pull'));
446484
}
447485
}

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

+44-8
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,56 @@ 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+
$application = new Application();
258+
$application->add($this->createCommand($this->createMock(ProviderInterface::class), ['en', 'fr', 'it'], ['messages', 'validators'], ['loco', 'crowdin', 'lokalise']));
259+
260+
$tester = new CommandCompletionTester($application->get('translation:push'));
261+
$suggestions = $tester->complete($input);
262+
$this->assertSame($expectedSuggestions, $suggestions);
263+
}
264+
265+
public function provideCompletionSuggestions(): \Generator
266+
{
267+
yield 'provider' => [
268+
[''],
269+
['loco', 'crowdin', 'lokalise'],
270+
];
271+
272+
yield '--domains' => [
273+
['loco', '--domains'],
274+
['messages', 'validators'],
275+
];
276+
277+
yield '--locales' => [
278+
['loco', '--locales'],
279+
['en', 'fr', 'it'],
280+
];
281+
}
282+
252283
private function createCommandTester(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages']): CommandTester
284+
{
285+
$command = $this->createCommand($provider, $locales, $domains);
286+
$application = new Application();
287+
$application->add($command);
288+
289+
return new CommandTester($application->find('translation:push'));
290+
}
291+
292+
private function createCommand(ProviderInterface $provider, array $locales = ['en'], array $domains = ['messages'], array $providerNames = ['loco']): TranslationPushCommand
253293
{
254294
$reader = new TranslationReader();
255295
$reader->addLoader('xlf', new XliffFileLoader());
256296

257-
$command = new TranslationPushCommand(
258-
$this->getProviderCollection($provider, $locales, $domains),
297+
return new TranslationPushCommand(
298+
$this->getProviderCollection($provider, $providerNames, $locales, $domains),
259299
$reader,
260300
[$this->translationAppDir.'/translations'],
261301
$locales
262302
);
263-
$application = new Application();
264-
$application->add($command);
265-
266-
return new CommandTester($application->find('translation:push'));
267303
}
268304
}

0 commit comments

Comments
 (0)