diff --git a/composer.json b/composer.json index 9e04f2e2b7f87b58588e4a31745d4950b4ea714a..74db1d7e7f9bc97df1daa1bf53bba86b8584b1b2 100644 --- a/composer.json +++ b/composer.json @@ -145,7 +145,8 @@ "@php bin/console doctrine:database:create --if-not-exists --no-interaction --env=dev", "@php bin/console doctrine:migration:migrate --all-or-nothing --no-interaction --env=dev", "@php bin/console doctrine:fixture:load --no-interaction --env=dev" - ] + ], + "update-projects": ["@php bin/console rekall:projects:update"] }, "conflict": { "symfony/symfony": "*" diff --git a/src/Command/UpdateAllProjects.php b/src/Command/UpdateAllProjects.php new file mode 100644 index 0000000000000000000000000000000000000000..92afd8a11dfa06b8e799c47e649a52c76acbba50 --- /dev/null +++ b/src/Command/UpdateAllProjects.php @@ -0,0 +1,151 @@ +<?php + +namespace App\Command; + +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Filesystem\Path; +use Symfony\Component\HttpKernel\KernelInterface; + +#[AsCommand( + name: 'rekall:projects:update', + description: 'Update commons files on projects.', + aliases: ['rekall-update-projects'], + hidden: false +)] +class UpdateAllProjects extends Command +{ + /** + * @var Filesystem $filesystem + */ + private $filesystem; + + /** + * @var KernelInterface $kernel + */ + private $kernel; + + public function __construct(Filesystem $filesystem, KernelInterface $kernel) + { + parent::__construct(); + + // best practices recommend to call the parent constructor first and + // then set your own properties. That wouldn't work in this case + // because configure() needs the properties set in this constructor + $this->filesystem = $filesystem; + $this->kernel = $kernel; + } + + protected function configure(): void + { + $this + // If you don't like using the $defaultDescription static property, + // you can also define the short description using this method: + ->setDescription('Update every project php files and index.html') + + // the command help shown when running the command with the "--help" option + ->setHelp('This command allows update projects common files...'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + if (!$output instanceof ConsoleOutputInterface) { + throw new \LogicException('This command accepts only an instance of "ConsoleOutputInterface".'); + } + + if (!$this->filesystem instanceof Filesystem) { + $output->writeln("filesystem is not defined"); + return Command::INVALID; + } + + ProgressBar::setFormatDefinition( + 'project_update_message', + ' %current%/%max% [%bar%] %percent%% : Updating project :%project% %elapsed%' + ); + $output->writeln("Updating all projects started"); + + $legacy_root = $this->kernel->getProjectDir() . '/legacy'; + $capsule_prototype_root = './capsule-prototype'; + $blackList = array( + 'css', 'create.zip', 'favicon.ico', 'la-page-des-malins.php', 'js', 'php', 'shared', '.', '..' + ); + + $directory_files = scandir($legacy_root); + if (false === $directory_files) { + return Command::FAILURE; + } + + $all_file_in_directory = array_diff($directory_files, $blackList); + + $phpFiles = glob($capsule_prototype_root . '/php/*.php'); + // add +1 for index.html file + $phpFilesCountPerProjects = count($phpFiles ?: []) + 1; + + $allProjectsProgressBar = new ProgressBar($output->section()); + $allProjectsProgressBar->setFormat( + '%current%/%max% [%bar%] %percent%% : Overall project update progressing (%elapsed%)' + ); + $allProjectsProgressBar->SetMessage('Projects update progress'); + $allProjectsProgressBar->start(); + + foreach ($allProjectsProgressBar->iterate($all_file_in_directory) as $value) { + $current_legacy_path = Path::normalize($legacy_root . '/' . $value); + + if (!$this->filesystem->exists($current_legacy_path)) { + continue; + } + + if (!is_dir($current_legacy_path)) { + continue; + } + + if (in_array($value, $blackList)) { + continue; + } + + $progressBar = new ProgressBar($output->section(), $phpFilesCountPerProjects); + $progressBar->setFormat('project_update_message'); + $progressBar->setMessage($current_legacy_path, 'project'); + + $progressBar->start(); + + // override index.html + $this->filesystem->copy( + Path::normalize($capsule_prototype_root . '/index.html'), + Path::normalize($current_legacy_path . '/index.html'), + true + ); + $progressBar->advance(); + + // override php files + $this->filesystem->mirror( + Path::normalize($capsule_prototype_root . '/php'), + Path::normalize($current_legacy_path . '/php'), + null, + ['override' => true, 'delete' => true ] + ); + $progressBar->advance($phpFilesCountPerProjects - 1); + $progressBar->finish(); + $allProjectsProgressBar->advance($phpFilesCountPerProjects); + } + + $allProjectsProgressBar->finish(); + + // return this if there was no problem running the command + // (it's equivalent to returning int(0)) + return Command::SUCCESS; + + // or return this if some error happened during the execution + // (it's equivalent to returning int(1)) + // return Command::FAILURE; + + // or return this to indicate incorrect command usage; e.g. invalid options + // or missing arguments (it's equivalent to returning int(2)) + // return Command::INVALID + } +}