From 1e69510e023f7c684efc6a22186509bd7550bb25 Mon Sep 17 00:00:00 2001 From: Morgan Pichat Date: Wed, 23 Oct 2024 16:10:25 +0200 Subject: [PATCH] Rework UpdateFiles warmup --- classes/Commands/AbstractCommand.php | 10 ++-- classes/Commands/UpdateCommand.php | 39 +++++++++++++- classes/Parameters/UpgradeFileNames.php | 10 ---- .../Task/Miscellaneous/CompareReleases.php | 4 +- classes/Task/Miscellaneous/UpdateConfig.php | 3 -- classes/Task/Update/UpdateFiles.php | 51 ++++++++++--------- classes/UpgradeContainer.php | 22 +++++--- .../CoreUpgrader/CoreUpgrader80.php | 1 - 8 files changed, 83 insertions(+), 57 deletions(-) diff --git a/classes/Commands/AbstractCommand.php b/classes/Commands/AbstractCommand.php index 35247c37f..db22cccbb 100644 --- a/classes/Commands/AbstractCommand.php +++ b/classes/Commands/AbstractCommand.php @@ -28,10 +28,10 @@ namespace PrestaShop\Module\AutoUpgrade\Commands; use Exception; +use http\Exception\InvalidArgumentException; use PrestaShop\Module\AutoUpgrade\ErrorHandler; use PrestaShop\Module\AutoUpgrade\Log\CliLogger; use PrestaShop\Module\AutoUpgrade\Log\Logger; -use PrestaShop\Module\AutoUpgrade\Task\ExitCode; use PrestaShop\Module\AutoUpgrade\Task\Miscellaneous\UpdateConfig; use PrestaShop\Module\AutoUpgrade\UpgradeContainer; use Symfony\Component\Console\Command\Command; @@ -94,17 +94,13 @@ protected function loadConfiguration(?string $configPath, UpgradeContainer $upgr $this->logger->debug('Loading configuration from ' . $configPath); $configFile = file_get_contents($configPath); if (!$configFile) { - $this->logger->error('Configuration file not found a location ' . $configPath); - - return ExitCode::FAIL; + throw new InvalidArgumentException('Configuration file not found a location ' . $configPath); } $inputData = json_decode($configFile, true); if (!$inputData) { - $this->logger->error('An error occurred during the json decode process, please check the content and syntax of the file content'); - - return ExitCode::FAIL; + throw new InvalidArgumentException('An error occurred during the json decode process, please check the content and syntax of the file content'); } $this->logger->debug('Configuration file content: ' . json_encode($inputData)); diff --git a/classes/Commands/UpdateCommand.php b/classes/Commands/UpdateCommand.php index 46d963df1..55f37eac7 100644 --- a/classes/Commands/UpdateCommand.php +++ b/classes/Commands/UpdateCommand.php @@ -29,8 +29,11 @@ use Exception; use PrestaShop\Module\AutoUpgrade\DeveloperDocumentation; +use PrestaShop\Module\AutoUpgrade\Exceptions\UpgradeException; use PrestaShop\Module\AutoUpgrade\Task\ExitCode; use PrestaShop\Module\AutoUpgrade\Task\Runner\AllUpdateTasks; +use PrestaShop\Module\AutoUpgrade\Task\TaskName; +use PrestaShop\Module\AutoUpgrade\UpgradeContainer; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -89,10 +92,16 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int $this->logger->debug('Configuration loaded successfully.'); $this->logger->debug('Starting the update process.'); + $action = $input->getOption('action'); + + if ($action && $this->shouldClearCoreCache($action)) { + $this->clearCoreCache(); + } + $controller = new AllUpdateTasks($this->upgradeContainer); $controller->setOptions([ 'data' => $input->getOption('data'), - 'action' => $input->getOption('action'), + 'action' => $action, 'channel' => $input->getOption('channel'), ]); $controller->init(); @@ -146,4 +155,32 @@ private function chainCommand(OutputInterface $output): int return ExitCode::SUCCESS; } + + /** + * @throws Exception + */ + private function shouldClearCoreCache(string $action): bool + { + $destinationVersion = $this->upgradeContainer->getState()->getInstallVersion(); + + return $action === TaskName::TASK_UPDATE_DATABASE && version_compare($destinationVersion, '9.0.0') >= 0; + } + + /** + * @throws Exception + */ + private function clearCoreCache(): void + { + $rootPath = $this->upgradeContainer->getProperty(UpgradeContainer::PS_ROOT_PATH); + $command = 'php ' . $rootPath . '/bin/console cache:warmup --env=prod'; + $output = []; + $resultCode = 0; + + exec($command, $output, $resultCode); + + if ($resultCode !== 0) { + throw new UpgradeException("An error was raised when clearing the core cache: \n" . implode("\n", $output)); + } + $this->logger->debug('Core cache has been cleared to avoid dependency conflicts.'); + } } diff --git a/classes/Parameters/UpgradeFileNames.php b/classes/Parameters/UpgradeFileNames.php index a3573cd7d..a18371724 100644 --- a/classes/Parameters/UpgradeFileNames.php +++ b/classes/Parameters/UpgradeFileNames.php @@ -66,15 +66,6 @@ class UpgradeFileNames */ const MODULES_TO_UPGRADE_LIST = 'modulesToUpgrade.list'; - /** - * during upgradeFiles process, - * this files contains the list of files left to upgrade in a serialized array. - * (this file is deleted in init() method if you reload the page). - * - * @var string - */ - const FILES_DIFF_LIST = 'filesDiff.list'; - /** * during backupFiles process, * this files contains the list of files left to save in a serialized array. @@ -157,7 +148,6 @@ class UpgradeFileNames public static $tmp_files = [ 'QUERIES_TO_UPGRADE_LIST', // used ? 'FILES_TO_UPGRADE_LIST', - 'FILES_DIFF_LIST', 'FILES_TO_BACKUP_LIST', 'DB_TABLES_TO_BACKUP_LIST', 'QUERIES_TO_RESTORE_LIST', diff --git a/classes/Task/Miscellaneous/CompareReleases.php b/classes/Task/Miscellaneous/CompareReleases.php index 2e3f3cf9d..def386310 100644 --- a/classes/Task/Miscellaneous/CompareReleases.php +++ b/classes/Task/Miscellaneous/CompareReleases.php @@ -28,7 +28,6 @@ namespace PrestaShop\Module\AutoUpgrade\Task\Miscellaneous; use Exception; -use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames; use PrestaShop\Module\AutoUpgrade\Task\AbstractTask; use PrestaShop\Module\AutoUpgrade\Task\ExitCode; use PrestaShop\Module\AutoUpgrade\Task\TaskName; @@ -36,6 +35,8 @@ /** * This class gets the list of all modified and deleted files between current version * and target version (according to channel configuration). + * + * TODO Task to remove after removing the old UI */ class CompareReleases extends AbstractTask { @@ -57,7 +58,6 @@ public function run(): int $this->nextParams['status'] = 'error'; $this->nextParams['msg'] = sprintf('Unable to generate diff file list between %1$s and %2$s.', _PS_VERSION_, $version); } else { - $this->container->getFileConfigurationStorage()->save($diffFileList, UpgradeFileNames::FILES_DIFF_LIST); $this->nextParams['msg'] = $this->translator->trans( '%modifiedfiles% files will be modified, %deletedfiles% files will be deleted (if they are found).', [ diff --git a/classes/Task/Miscellaneous/UpdateConfig.php b/classes/Task/Miscellaneous/UpdateConfig.php index 613938efc..106e20941 100644 --- a/classes/Task/Miscellaneous/UpdateConfig.php +++ b/classes/Task/Miscellaneous/UpdateConfig.php @@ -134,9 +134,6 @@ public function run(): int return ExitCode::FAIL; } - $this->container->getState()->setInstallVersion($this->container->getUpgrader()->getDestinationVersion()); - $this->container->getState()->setOriginVersion($this->container->getProperty(UpgradeContainer::PS_VERSION)); - return ExitCode::SUCCESS; } diff --git a/classes/Task/Update/UpdateFiles.php b/classes/Task/Update/UpdateFiles.php index 2bfa26a26..3968477fd 100644 --- a/classes/Task/Update/UpdateFiles.php +++ b/classes/Task/Update/UpdateFiles.php @@ -224,30 +224,31 @@ protected function warmUp(): int rename($newReleasePath . DIRECTORY_SEPARATOR . 'install-dev', $newReleasePath . DIRECTORY_SEPARATOR . 'install'); } - // Now, we will get the list of changed and removed files between the versions. This was generated previously by - // CompareReleases task. - $filepath_list_diff = $this->container->getProperty(UpgradeContainer::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . UpgradeFileNames::FILES_DIFF_LIST; - $list_files_diff = []; - - // We check if that file exists first and load it - if (file_exists($filepath_list_diff)) { - $list_files_diff = $this->container->getFileConfigurationStorage()->load(UpgradeFileNames::FILES_DIFF_LIST); - // $list_files_diff now contains an array with a list of changed and deleted files. - // We only keep list of files to delete. The modified files will be listed in list_files_to_upgrade below. - $list_files_diff = $list_files_diff['deleted']; - - // Admin folder name in this deleted files list is standard /admin/. - // We will need to change it to our own admin folder name. - $admin_dir = trim(str_replace($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH), '', $this->container->getProperty(UpgradeContainer::PS_ADMIN_PATH)), DIRECTORY_SEPARATOR); - foreach ($list_files_diff as $k => $path) { - if (preg_match('#autoupgrade#', $path)) { - unset($list_files_diff[$k]); - } elseif (substr($path, 0, 6) === '/admin') { - // Please make sure that the condition to check if the string starts with /admin stays here, because it was replacing - // admin even in the middle of a path, not deleting some files as a result. - // Also, do not use DIRECTORY_SEPARATOR, keep forward slash, because the path come from the XML standardized. - $list_files_diff[$k] = '/' . $admin_dir . substr($path, 6); - } + $destinationVersion = $this->container->getState()->getInstallVersion(); + $originVersion = $this->container->getState()->getOriginVersion(); + $this->logger->debug(sprintf('Generate diff file list between %s and %s.', $originVersion, $destinationVersion)); + $diffFileList = $this->container->getChecksumCompare()->getFilesDiffBetweenVersions($originVersion, $destinationVersion); + if (!is_array($diffFileList)) { + $this->logger->error($this->translator->trans('Unable to generate diff file list between %s and %s.', [$originVersion, $destinationVersion])); + $this->next = TaskName::TASK_ERROR; + + return ExitCode::FAIL; + } + // $diffFileList now contains an array with a list of changed and deleted files. + // We only keep list of files to delete. The modified files will be listed in list_files_to_upgrade below. + $diffFileList = $diffFileList['deleted']; + + // Admin folder name in this deleted files list is standard /admin/. + // We will need to change it to our own admin folder name. + $admin_dir = trim(str_replace($this->container->getProperty(UpgradeContainer::PS_ROOT_PATH), '', $this->container->getProperty(UpgradeContainer::PS_ADMIN_PATH)), DIRECTORY_SEPARATOR); + foreach ($diffFileList as $k => $path) { + if (preg_match('#autoupgrade#', $path)) { + unset($diffFileList[$k]); + } elseif (substr($path, 0, 6) === '/admin') { + // Please make sure that the condition to check if the string starts with /admin stays here, because it was replacing + // admin even in the middle of a path, not deleting some files as a result. + // Also, do not use DIRECTORY_SEPARATOR, keep forward slash, because the path come from the XML standardized. + $diffFileList[$k] = '/' . $admin_dir . substr($path, 6); } } @@ -257,7 +258,7 @@ protected function warmUp(): int ); // Add our previously created list of deleted files - $list_files_to_upgrade = array_reverse(array_merge($list_files_diff, $list_files_to_upgrade)); + $list_files_to_upgrade = array_reverse(array_merge($diffFileList, $list_files_to_upgrade)); $total_files_to_upgrade = count($list_files_to_upgrade); $this->container->getFileConfigurationStorage()->save( diff --git a/classes/UpgradeContainer.php b/classes/UpgradeContainer.php index 627268bcb..8080b78a7 100644 --- a/classes/UpgradeContainer.php +++ b/classes/UpgradeContainer.php @@ -435,14 +435,6 @@ public function getUpgrader(): Upgrader $currentPrestashopVersion ); - $this->getState()->setInstallVersion($upgrader->getDestinationVersion()); - $this->getState()->setOriginVersion($this->getProperty(self::PS_VERSION)); - - if ($upgrader->getChannel() === Upgrader::CHANNEL_LOCAL) { - $archiveXml = $this->getUpgradeConfiguration()->getLocalChannelXml(); - $this->fileLoader->addXmlMd5File($upgrader->getDestinationVersion(), $this->getProperty(self::DOWNLOAD_PATH) . DIRECTORY_SEPARATOR . $archiveXml); - } - $this->upgrader = $upgrader; return $this->upgrader; @@ -481,6 +473,10 @@ public function getFileLoader(): FileLoader } $this->fileLoader = new FileLoader(); + if ($this->getUpgrader()->getChannel() === Upgrader::CHANNEL_LOCAL) { + $archiveXml = $this->getUpgradeConfiguration()->getLocalChannelXml(); + $this->fileLoader->addXmlMd5File($this->getUpgrader()->getDestinationVersion(), $this->getProperty(self::DOWNLOAD_PATH) . DIRECTORY_SEPARATOR . $archiveXml); + } return $this->fileLoader; } @@ -557,6 +553,8 @@ public function getCompletionCalculator(): CompletionCalculator /** * @return State + * + * @throws Exception */ public function getState(): State { @@ -566,6 +564,14 @@ public function getState(): State $this->state = new State(); + if (!$this->state->getOriginVersion()) { + $this->state->setOriginVersion($this->getProperty(self::PS_VERSION)); + } + + if (!$this->state->getInstallVersion()) { + $this->state->setInstallVersion($this->getUpgrader()->getDestinationVersion()); + } + return $this->state; } diff --git a/classes/UpgradeTools/CoreUpgrader/CoreUpgrader80.php b/classes/UpgradeTools/CoreUpgrader/CoreUpgrader80.php index 6b393bbfe..59c413d9f 100644 --- a/classes/UpgradeTools/CoreUpgrader/CoreUpgrader80.php +++ b/classes/UpgradeTools/CoreUpgrader/CoreUpgrader80.php @@ -41,7 +41,6 @@ protected function initConstants(): void { $this->forceRemovingFiles(); parent::initConstants(); - // Container may be needed to run upgrade scripts $this->container->getSymfonyAdapter()->initKernel(); }