mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Expand detection of duplicates in translations command
Added functionality to specify key namespaces that should be exluded from duplicate detection Added functionality to check the accidental creation of duplicates based on an md5 hash of translation duplicates.
This commit is contained in:
parent
611261c863
commit
41f13e29e0
@ -12,6 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\MainBundle\Command;
|
namespace Chill\MainBundle\Command;
|
||||||
|
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
@ -19,6 +20,7 @@ use Symfony\Component\HttpKernel\KernelInterface;
|
|||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
use Symfony\Component\Console\Helper\Table;
|
use Symfony\Component\Console\Helper\Table;
|
||||||
|
|
||||||
|
|
||||||
class DetectTranslationDuplicatesCommand extends Command
|
class DetectTranslationDuplicatesCommand extends Command
|
||||||
{
|
{
|
||||||
protected static $defaultName = 'app:detect-duplicate-translations';
|
protected static $defaultName = 'app:detect-duplicate-translations';
|
||||||
@ -32,12 +34,16 @@ class DetectTranslationDuplicatesCommand extends Command
|
|||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setDescription('Detects duplicate translations in YAML files.')
|
->setDescription('Detects duplicate translations in YAML files.')
|
||||||
->addOption('locale', null, InputOption::VALUE_REQUIRED, 'Locale to check for duplicate translations', 'en');
|
->addOption('locale', null, InputOption::VALUE_REQUIRED, 'Locale to check for duplicate translations', 'en')
|
||||||
|
->addOption('exclude-namespaces', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'Namespaces to exclude from duplicate detection', [])
|
||||||
|
->addArgument('verify-hash', InputArgument::OPTIONAL, 'The expected hash to verify translation integrity');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
{
|
{
|
||||||
$locale = $input->getOption('locale');
|
$locale = $input->getOption('locale');
|
||||||
|
$excludedNamespaces = $input->getOption('exclude-namespaces');
|
||||||
|
$expectedHash = $input->getArgument('verify-hash');
|
||||||
|
|
||||||
// Loop through all bundles and get the translation directories
|
// Loop through all bundles and get the translation directories
|
||||||
foreach ($this->kernel->getBundles() as $bundle) {
|
foreach ($this->kernel->getBundles() as $bundle) {
|
||||||
@ -58,6 +64,9 @@ class DetectTranslationDuplicatesCommand extends Command
|
|||||||
// Iterate through each domain in the catalogue
|
// Iterate through each domain in the catalogue
|
||||||
foreach ($catalogue->all() as $domain => $translations) {
|
foreach ($catalogue->all() as $domain => $translations) {
|
||||||
foreach ($translations as $key => $value) {
|
foreach ($translations as $key => $value) {
|
||||||
|
if ($this->isExcludedNamespace("$domain.$key", $excludedNamespaces)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$this->flattenTranslation($value, "$domain.$key", $allTranslations);
|
$this->flattenTranslation($value, "$domain.$key", $allTranslations);
|
||||||
} else {
|
} else {
|
||||||
@ -74,25 +83,27 @@ class DetectTranslationDuplicatesCommand extends Command
|
|||||||
return count($keys) > 1;
|
return count($keys) > 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (empty($duplicates)) {
|
$duplicatesHash = $this->generateDuplicatesHash($duplicates);
|
||||||
$output->writeln("<info>No duplicate translations found for locale '$locale'.</info>");
|
|
||||||
} else {
|
|
||||||
$output->writeln("<comment>Duplicate translations found for locale '$locale':</comment>");
|
|
||||||
|
|
||||||
// Display the duplicates in a table
|
if ($expectedHash) {
|
||||||
$table = new Table($output);
|
if ($duplicatesHash === $expectedHash) {
|
||||||
$table->setHeaders(['Translation', 'Used in Keys']);
|
$output->writeln('<info>Translations are consistent with the expected hash.</info>');
|
||||||
|
|
||||||
foreach ($duplicates as $translation => $keys) {
|
$output->writeln("<info>Current duplicate hash: $duplicatesHash</info>");
|
||||||
$wrappedTranslation = $this->wrapText($translation, 40);
|
return Command::SUCCESS;
|
||||||
$wrappedKeys = $this->wrapText(implode(', ', $keys), 80);
|
} else {
|
||||||
|
$output->writeln('<error>Translation hash mismatch! Potential duplicate added.</error>');
|
||||||
|
$this->renderDuplicatesTable($output, $duplicates, $locale);
|
||||||
|
|
||||||
$table->addRow([$wrappedTranslation, $wrappedKeys]);
|
$output->writeln("<info>Current duplicate hash: $duplicatesHash</info>");
|
||||||
|
return Command::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$table->render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->renderDuplicatesTable($output, $duplicates, $locale);
|
||||||
|
|
||||||
|
$output->writeln("<info>Current duplicate hash: $duplicatesHash</info>");
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,4 +137,44 @@ class DetectTranslationDuplicatesCommand extends Command
|
|||||||
{
|
{
|
||||||
return wordwrap($text, $width, "\n", true);
|
return wordwrap($text, $width, "\n", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function isExcludedNamespace(string $key, array $excludedNamespaces): bool
|
||||||
|
{
|
||||||
|
foreach ($excludedNamespaces as $namespace) {
|
||||||
|
if (str_starts_with($key, $namespace)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateDuplicatesHash(array $duplicates): string
|
||||||
|
{
|
||||||
|
ksort($duplicates);
|
||||||
|
foreach ($duplicates as $translation => $keys) {
|
||||||
|
sort($keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash('md5', serialize($duplicates));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renderDuplicatesTable(OutputInterface $output, array $duplicates, string $locale): void
|
||||||
|
{
|
||||||
|
if (empty($duplicates)) {
|
||||||
|
$output->writeln("<info>No duplicate translations found for locale '$locale'.</info>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$output->writeln("<comment>Duplicate translations found for locale '$locale':</comment>");
|
||||||
|
$table = new Table($output);
|
||||||
|
$table->setHeaders(['Translation', 'Used in Keys']);
|
||||||
|
|
||||||
|
foreach ($duplicates as $translation => $keys) {
|
||||||
|
$wrappedTranslation = $this->wrapText($translation, 40);
|
||||||
|
$wrappedKeys = $this->wrapText(implode(', ', $keys), 80);
|
||||||
|
$table->addRow([$wrappedTranslation, $wrappedKeys]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user