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;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
@ -19,6 +20,7 @@ use Symfony\Component\HttpKernel\KernelInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
|
||||
|
||||
class DetectTranslationDuplicatesCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'app:detect-duplicate-translations';
|
||||
@ -32,12 +34,16 @@ class DetectTranslationDuplicatesCommand extends Command
|
||||
{
|
||||
$this
|
||||
->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
|
||||
{
|
||||
$locale = $input->getOption('locale');
|
||||
$excludedNamespaces = $input->getOption('exclude-namespaces');
|
||||
$expectedHash = $input->getArgument('verify-hash');
|
||||
|
||||
// Loop through all bundles and get the translation directories
|
||||
foreach ($this->kernel->getBundles() as $bundle) {
|
||||
@ -58,6 +64,9 @@ class DetectTranslationDuplicatesCommand extends Command
|
||||
// Iterate through each domain in the catalogue
|
||||
foreach ($catalogue->all() as $domain => $translations) {
|
||||
foreach ($translations as $key => $value) {
|
||||
if ($this->isExcludedNamespace("$domain.$key", $excludedNamespaces)) {
|
||||
continue;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
$this->flattenTranslation($value, "$domain.$key", $allTranslations);
|
||||
} else {
|
||||
@ -74,25 +83,27 @@ class DetectTranslationDuplicatesCommand extends Command
|
||||
return count($keys) > 1;
|
||||
});
|
||||
|
||||
if (empty($duplicates)) {
|
||||
$output->writeln("<info>No duplicate translations found for locale '$locale'.</info>");
|
||||
} else {
|
||||
$output->writeln("<comment>Duplicate translations found for locale '$locale':</comment>");
|
||||
$duplicatesHash = $this->generateDuplicatesHash($duplicates);
|
||||
|
||||
// Display the duplicates in a table
|
||||
$table = new Table($output);
|
||||
$table->setHeaders(['Translation', 'Used in Keys']);
|
||||
if ($expectedHash) {
|
||||
if ($duplicatesHash === $expectedHash) {
|
||||
$output->writeln('<info>Translations are consistent with the expected hash.</info>');
|
||||
|
||||
foreach ($duplicates as $translation => $keys) {
|
||||
$wrappedTranslation = $this->wrapText($translation, 40);
|
||||
$wrappedKeys = $this->wrapText(implode(', ', $keys), 80);
|
||||
$output->writeln("<info>Current duplicate hash: $duplicatesHash</info>");
|
||||
return Command::SUCCESS;
|
||||
} 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;
|
||||
}
|
||||
|
||||
@ -126,4 +137,44 @@ class DetectTranslationDuplicatesCommand extends Command
|
||||
{
|
||||
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