addOption('dir', null, InputOption::VALUE_REQUIRED, 'Directory with filled workbooks', 'migrations/solutiongroups_xlsx_in'); $this->addOption('only', null, InputOption::VALUE_REQUIRED, 'Only files whose name contains this substring'); $this->addOption('apply', null, InputOption::VALUE_NONE, 'Write changes (default: dry run)'); } protected function execute(InputInterface $input, OutputInterface $output): int { Bootstrap::initializeBackendAuthentication(); $apply = (bool)$input->getOption('apply'); $only = mb_strtolower((string)($input->getOption('only') ?? '')); $dir = rtrim((string)$input->getOption('dir'), '/'); if (!is_dir($dir)) { $output->writeln('Directory not found: ' . $dir . ''); return Command::FAILURE; } $files = []; $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)); foreach ($iterator as $fileInfo) { $name = $fileInfo->getFilename(); if ($fileInfo->isFile() && str_ends_with($name, '.xlsx') && !str_starts_with($name, '~$')) { if ($only === '' || str_contains(mb_strtolower($name), $only)) { $files[] = $fileInfo->getPathname(); } } } sort($files); if ($files === []) { $output->writeln('No workbooks found in ' . $dir); return Command::SUCCESS; } $output->writeln(count($files) . ' workbook(s) · ' . ($apply ? 'APPLY' : 'DRY-RUN')); $errors = 0; foreach ($files as $file) { try { $result = $this->importer->importFile($file, $apply); $output->writeln(sprintf("\n%s (group: %s)", $result['file'], $result['group'])); foreach ($result['report'] as $line) { $output->writeln(' ' . $line . ''); } $output->writeln(sprintf(' page #%d · %d element(s) touched · %s', $result['pageUid'], $result['elements'], $apply ? 'written.' : 'dry run')); } catch (\Throwable $e) { $errors++; $output->writeln('' . basename($file) . ': ' . $e->getMessage() . ''); } } if (!$apply) { $output->writeln("\nDRY RUN - nothing written. Add --apply to write."); } return $errors > 0 ? Command::FAILURE : Command::SUCCESS; } }