Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5cd37f5

Browse filesBrowse files
committed
First working state push and pull commands
1 parent 8fac21b commit 5cd37f5
Copy full SHA for 5cd37f5

21 files changed

+381
-282
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Command/TranslationPullCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Command/TranslationPullCommand.php
+60-42Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,48 +12,46 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Command;
1313

1414
use Symfony\Component\Console\Command\Command;
15-
use Symfony\Component\Console\Exception\InvalidArgumentException;
1615
use Symfony\Component\Console\Input\InputArgument;
1716
use Symfony\Component\Console\Input\InputInterface;
1817
use Symfony\Component\Console\Input\InputOption;
1918
use Symfony\Component\Console\Output\OutputInterface;
2019
use Symfony\Component\Console\Style\SymfonyStyle;
21-
use Symfony\Component\HttpKernel\KernelInterface;
22-
use Symfony\Component\Translation\Catalogue\MergeOperation;
2320
use Symfony\Component\Translation\Catalogue\TargetOperation;
24-
use Symfony\Component\Translation\Extractor\ExtractorInterface;
2521
use Symfony\Component\Translation\MessageCatalogue;
26-
use Symfony\Component\Translation\MessageCatalogueInterface;
2722
use Symfony\Component\Translation\Reader\TranslationReaderInterface;
2823
use Symfony\Component\Translation\Remotes;
2924
use Symfony\Component\Translation\Writer\TranslationWriterInterface;
3025

3126
/**
32-
* A command that parses templates to extract translation messages and adds them
33-
* into the translation files.
34-
*
3527
* @final
3628
*/
3729
class TranslationPullCommand extends Command
3830
{
31+
use TranslationTrait;
32+
3933
protected static $defaultName = 'translation:pull';
4034

4135
private $remotes;
4236
private $writer;
4337
private $reader;
4438
private $defaultLocale;
45-
private $defaultTransPath;
39+
private $transPaths;
4640
private $enabledLocales;
4741

48-
public function __construct(Remotes $remotes, TranslationWriterInterface $writer, TranslationReaderInterface $reader, string $defaultLocale, string $defaultTransPath = null, array $enabledLocales = [])
42+
public function __construct(Remotes $remotes, TranslationWriterInterface $writer, TranslationReaderInterface $reader, string $defaultLocale, string $defaultTransPath = null, array $transPaths = [], array $enabledLocales = [])
4943
{
5044
$this->remotes = $remotes;
5145
$this->writer = $writer;
5246
$this->reader = $reader;
5347
$this->defaultLocale = $defaultLocale;
54-
$this->defaultTransPath = $defaultTransPath;
48+
$this->transPaths = $transPaths;
5549
$this->enabledLocales = $enabledLocales;
5650

51+
if (null !== $defaultTransPath) {
52+
$this->transPaths[] = $defaultTransPath;
53+
}
54+
5755
parent::__construct();
5856
}
5957

@@ -63,17 +61,17 @@ public function __construct(Remotes $remotes, TranslationWriterInterface $writer
6361
protected function configure()
6462
{
6563
$keys = $this->remotes->keys();
66-
$defaultRemote = 1 === count($keys) ? $keys[0] : null;
64+
$defaultRemote = 1 === \count($keys) ? $keys[0] : null;
6765

6866
$this
6967
->setDefinition([
7068
new InputArgument('remote', null !== $defaultRemote ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The remote to pull translations from.', $defaultRemote),
71-
new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with updated ones'),
72-
new InputOption('delete-obsolete', null, InputOption::VALUE_NONE, 'Delete translations available locally but not on remote'),
73-
new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to pull'),
74-
new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locels to pull'),
75-
new InputOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf'),
76-
new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version', '1.2'),
69+
new InputOption('force', null, InputOption::VALUE_NONE, 'Override *all* local translations (including new and not pushed ones) with distant translations.'),
70+
new InputOption('delete-obsolete', null, InputOption::VALUE_NONE, 'Delete translations available locally but not on remote.'),
71+
new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to pull. (Do not forget +intl-icu suffix if nedded).'),
72+
new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locales to pull.'),
73+
new InputOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format.', 'xlf'),
74+
new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version.', '1.2'),
7775
])
7876
->setDescription('Pull translations from a given remote.')
7977
->setHelp(<<<'EOF'
@@ -106,50 +104,70 @@ protected function configure()
106104
*/
107105
protected function execute(InputInterface $input, OutputInterface $output): int
108106
{
109-
$remoteStorage = $this->remotes->get($input->getArgument('remote'));
107+
$io = new SymfonyStyle($input, $output);
110108

111-
$locales = $input->getOption('locales');
109+
$remoteStorage = $this->remotes->get($remote = $input->getArgument('remote'));
110+
$locales = $input->getOption('locales') ?: $this->enabledLocales;
112111
$domains = $input->getOption('domains');
113112
$force = $input->getOption('force');
114113
$deleteObsolete = $input->getOption('delete-obsolete');
115114

116-
$remoteTranslations = $remoteStorage->read($domains, $locales);
115+
$writeOptions = [
116+
'path' => end($this->transPaths),
117+
];
117118

118-
if ($deleteObsolete && $force) {
119-
foreach ($locales as $locale) {
120-
$options = [];
119+
if ($input->getOption('xliff-version')) {
120+
$writeOptions['xliff_version'] = $input->getOption('xliff-version');
121+
}
122+
123+
$remoteTranslations = $remoteStorage->read($domains, $locales);
121124

122-
if ($input->getOption('xliff-version')) {
123-
$options['xliff_version'] = $input->getOption('xliff-version');
124-
}
125+
if ($force) {
126+
if ($deleteObsolete) {
127+
$io->note('The --delete-obsolete option is ineffective with --force');
128+
}
125129

126-
$this->writer->write($remoteTranslations->getCatalogue($locale), $input->getOption('output-format'), $options);
130+
foreach ($remoteTranslations->getCatalogues() as $catalogue) {
131+
$operation = new TargetOperation((new MessageCatalogue($catalogue->getLocale())), $catalogue);
132+
$operation->moveMessagesToIntlDomainsIfPossible();
133+
$this->writer->write($operation->getResult(), $input->getOption('output-format'), $writeOptions);
127134
}
128135

136+
$io->success(sprintf(
137+
'Local translations are up to date with %s (for [%s] locale(s), and [%s] domain(s)).',
138+
$remote,
139+
implode(', ', $locales),
140+
implode(', ', $domains)
141+
));
142+
129143
return 0;
130144
}
131145

132-
if ($force) {
133-
// merge all messages from remote to local ones
146+
$localTranslations = $this->readLocalTranslations($locales, $domains, $this->transPaths);
134147

135-
return 0;
136-
} else {
137-
// merge only new messages from remote to local ones
148+
if ($deleteObsolete) {
149+
$obsoleteTranslations = $localTranslations->diff($remoteTranslations);
150+
$translationsWithoutObsoleteToWrite = $localTranslations->diff($obsoleteTranslations);
138151

139-
return 0;
152+
foreach ($translationsWithoutObsoleteToWrite->getCatalogues() as $catalogue) {
153+
$this->writer->write($catalogue, $input->getOption('output-format'), $writeOptions);
154+
}
155+
156+
$io->success('Obsolete translations are locally removed.');
140157
}
141158

142-
if ($deleteObsolete) {
143-
// remove diff between local messages and remote ones
159+
$translationsToWrite = $remoteTranslations->diff($localTranslations);
144160

145-
return 0;
161+
foreach ($translationsToWrite->getCatalogues() as $catalogue) {
162+
$this->writer->write($catalogue, $input->getOption('output-format'), $writeOptions);
146163
}
147164

148-
//$this->writer->write($operation->getResult(), $input->getOption('output-format'), [
149-
//'path' => $bundleTransPath,
150-
//'default_locale' => $this->defaultLocale,
151-
//'xliff_version' => $input->getOption('xliff-version')
152-
//]);
165+
$io->success(sprintf(
166+
'New remote translations from %s are written locally (for [%s] locale(s), and [%s] domain(s)).',
167+
$remote,
168+
implode(', ', $locales),
169+
implode(', ', $domains)
170+
));
153171

154172
return 0;
155173
}

‎src/Symfony/Bundle/FrameworkBundle/Command/TranslationPushCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Command/TranslationPushCommand.php
+46-66Lines changed: 46 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,21 @@
1818
use Symfony\Component\Console\Input\InputOption;
1919
use Symfony\Component\Console\Output\OutputInterface;
2020
use Symfony\Component\Console\Style\SymfonyStyle;
21-
use Symfony\Component\HttpKernel\KernelInterface;
22-
use Symfony\Component\Translation\Catalogue\MergeOperation;
23-
use Symfony\Component\Translation\Catalogue\TargetOperation;
24-
use Symfony\Component\Translation\Extractor\ExtractorInterface;
2521
use Symfony\Component\Translation\Loader\ArrayLoader;
26-
use Symfony\Component\Translation\MessageCatalogue;
27-
use Symfony\Component\Translation\MessageCatalogueInterface;
2822
use Symfony\Component\Translation\Reader\TranslationReaderInterface;
2923
use Symfony\Component\Translation\Remotes;
30-
use Symfony\Component\Translation\TranslatorBag;
31-
use Symfony\Component\Translation\Writer\TranslationWriterInterface;
3224

3325
/**
3426
* @final
3527
*/
3628
class TranslationPushCommand extends Command
3729
{
30+
use TranslationTrait;
31+
3832
protected static $defaultName = 'translation:push';
3933

4034
private $remotes;
4135
private $reader;
42-
private $defaultTransPath;
4336
private $transPaths;
4437
private $enabledLocales;
4538
private $arrayLoader;
@@ -48,11 +41,14 @@ public function __construct(Remotes $remotes, TranslationReaderInterface $reader
4841
{
4942
$this->remotes = $remotes;
5043
$this->reader = $reader;
51-
$this->defaultTransPath = $defaultTransPath;
5244
$this->transPaths = $transPaths;
5345
$this->enabledLocales = $enabledLocales;
5446
$this->arrayLoader = new ArrayLoader();
5547

48+
if (null !== $defaultTransPath) {
49+
$this->transPaths[] = $defaultTransPath;
50+
}
51+
5652
parent::__construct();
5753
}
5854

@@ -62,17 +58,17 @@ public function __construct(Remotes $remotes, TranslationReaderInterface $reader
6258
protected function configure()
6359
{
6460
$keys = $this->remotes->keys();
65-
$defaultRemote = 1 === count($keys) ? $keys[0] : null;
61+
$defaultRemote = 1 === \count($keys) ? $keys[0] : null;
6662

6763
$this
6864
->setDefinition([
6965
new InputArgument('remote', null !== $defaultRemote ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The remote to pull translations from.', $defaultRemote),
70-
new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with updated ones'),
71-
new InputOption('delete-obsolete', null, InputOption::VALUE_NONE, 'Delete translations available locally but not on remote'),
72-
new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to pull'),
73-
new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locels to pull', $this->enabledLocales),
74-
new InputOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf'),
75-
new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version', '1.2'),
66+
new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with updated ones.'),
67+
new InputOption('delete-obsolete', null, InputOption::VALUE_NONE, 'Delete translations available locally but not on remote.'),
68+
new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to pull.'),
69+
new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locales to pull.', $this->enabledLocales),
70+
new InputOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format.', 'xlf'),
71+
new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version.', '1.2'),
7672
])
7773
->setDescription('Push translations to a given remote.')
7874
->setHelp(<<<'EOF'
@@ -111,70 +107,54 @@ protected function execute(InputInterface $input, OutputInterface $output): int
111107

112108
$io = new SymfonyStyle($input, $output);
113109

114-
$remoteStorage = $this->remotes->get($input->getArgument('remote'));
115-
110+
$remoteStorage = $this->remotes->get($remote = $input->getArgument('remote'));
111+
$domains = $input->getOption('domains');
116112
$locales = $input->getOption('locales');
117113
$force = $input->getOption('force');
118114
$deleteObsolete = $input->getOption('delete-obsolete');
119115

120-
$transPaths = $this->transPaths;
121-
if ($this->defaultTransPath) {
122-
$transPaths[] = $this->defaultTransPath;
123-
}
124-
125-
/** @var KernelInterface $kernel */
126-
$kernel = $this->getApplication()->getKernel();
116+
$localTranslations = $this->readLocalTranslations($locales, $domains, $this->transPaths);
127117

128-
// Override with provided Bundle info
129-
foreach ($kernel->getBundles() as $bundle) {
130-
$bundleDir = $bundle->getPath();
131-
$transPaths[] = is_dir($bundleDir.'/Resources/translations') ? $bundleDir.'/Resources/translations' : $bundle->getPath().'/translations';
118+
if (!$domains) {
119+
$domains = $localTranslations->getDomains();
132120
}
133121

134-
$localTranslations = new TranslatorBag();
135-
foreach ($locales as $locale) {
136-
$localTranslations->addCatalogue($this->loadCurrentMessages($locale, $transPaths));
137-
}
122+
if (!$deleteObsolete && $force) {
123+
$remoteStorage->write($localTranslations);
138124

139-
$domains = $input->getOption('domains') ?: $localTranslations->getDomains();
125+
return 0;
126+
}
140127

141128
$remoteTranslations = $remoteStorage->read($domains, $locales);
142129

143-
foreach ($locales as $locale) {
144-
$remoteCatalogue = $remoteTranslations->getCatalogue($locale);
145-
$localCatalogue = $localTranslations->getCatalogue($locale);
146-
147-
$operation = new TargetOperation($remoteCatalogue, $localCatalogue);
148-
foreach ($domains as $domain) {
149-
if ($force) {
150-
$messages = $operation->getMessages($domain);
151-
} else {
152-
$messages = $operation->getNewMessages($domain);
153-
}
154-
155-
$bag = new TranslatorBag();
156-
$bag->addCatalogue($this->arrayLoader->load($messages, $locale, $domain));
157-
$remoteStorage->write($bag);
158-
159-
if ($deleteObsolete) {
160-
$obsoleteMessages = $operation->getObsoleteMessages($domain);
161-
$bag = new TranslatorBag();
162-
$bag->addCatalogue($this->arrayLoader->load($obsoleteMessages, $locale, $domain));
163-
$remoteStorage->delete($bag);
164-
}
165-
}
130+
if ($deleteObsolete) {
131+
$obsoleteMessages = $remoteTranslations->diff($localTranslations);
132+
$remoteStorage->delete($obsoleteMessages);
133+
134+
$io->success(sprintf(
135+
'Obsolete translations on %s are deleted (for [%s] locale(s), and [%s] domain(s)).',
136+
$remote,
137+
implode(', ', $locales),
138+
implode(', ', $domains)
139+
));
166140
}
167141

168-
return 0;
169-
}
142+
$translationsToWrite = $localTranslations->diff($remoteTranslations);
170143

171-
private function loadCurrentMessages(string $locale, array $transPaths): MessageCatalogue
172-
{
173-
$currentCatalogue = new MessageCatalogue($locale);
174-
foreach ($transPaths as $path) {
175-
$this->reader->read($path, $currentCatalogue);
144+
if ($force) {
145+
$translationsToWrite->addBag($localTranslations->intersect($remoteTranslations));
176146
}
177147

178-
return $currentCatalogue;
148+
$remoteStorage->write($translationsToWrite);
149+
150+
$io->success(sprintf(
151+
'%s local translations are sent to %s (for [%s] locale(s), and [%s] domain(s)).',
152+
$force ? 'All' : 'New',
153+
$remote,
154+
implode(', ', $locales),
155+
implode(', ', $domains)
156+
));
157+
158+
return 0;
179159
}
180160
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.