Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update lifecycle of state and configuration files #1117

Merged
merged 6 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions classes/Commands/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ protected function setupEnvironment(InputInterface $input, OutputInterface $outp
*/
protected function loadConfiguration(?string $configPath): int
{
$updateConfiguration = $this->upgradeContainer->getUpdateConfiguration();
if (!$updateConfiguration->hasAllTheShopConfiguration()) {
$this->upgradeContainer->initPrestaShopCore();
$this->upgradeContainer->getPrestaShopConfiguration()->fillInUpdateConfiguration($updateConfiguration);
}
$this->upgradeContainer->getConfigurationStorage()->save($updateConfiguration);

$controller = new UpdateConfig($this->upgradeContainer);

$configurationData = [];
Expand Down
2 changes: 0 additions & 2 deletions classes/Commands/CheckRequirementsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
use PrestaShop\Module\AutoUpgrade\Exceptions\UpgradeException;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use PrestaShop\Module\AutoUpgrade\Task\ExitCode;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;
use PrestaShop\Module\AutoUpgrade\UpgradeSelfCheck;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand Down Expand Up @@ -88,7 +87,6 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int

$this->upgradeContainer->initPrestaShopAutoloader();
$this->upgradeContainer->initPrestaShopCore();
$this->upgradeContainer->getUpdateState()->initDefault($this->upgradeContainer->getProperty(UpgradeContainer::PS_VERSION), $this->upgradeContainer->getUpgrader()->getDestinationVersion());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the state for the check of requirements.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify why ? The objective is to not have the state anymore outside the actual process.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we go to the UpgradeSelfCheck class and look for occurrences of the state, we can see that this one is used.

The objective is to not have the state anymore outside the actual process

Can you define "process"? Isn't the requirements check a process in itself?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The process running the tasks is a part of the (update) funnel. By having the state outside the process applying changes on the store, we struggle to clean the previous context properly in case of error.

Thanks for the class, I'll have a look at it as well.


$output->writeln('Result of prerequisite checks:');
$this->exitCode = ExitCode::SUCCESS;
Expand Down
1 change: 0 additions & 1 deletion classes/Commands/CreateBackupCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int

$this->loadConfiguration($configPath);

$this->upgradeContainer->getFileStorage()->cleanAllBackupFiles();
$controller = new AllBackupTasks($this->upgradeContainer);
$controller->init();
$exitCode = $controller->run();
Expand Down
1 change: 0 additions & 1 deletion classes/Commands/RestoreCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int
return ExitCode::SUCCESS;
}
}
$this->upgradeContainer->getFileStorage()->cleanAllRestoreFiles();
$controller = new AllRestoreTasks($this->upgradeContainer);
$controller->setOptions([
RestoreConfiguration::BACKUP_NAME => $backup,
Expand Down
11 changes: 9 additions & 2 deletions classes/Commands/UpdateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
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;
Expand Down Expand Up @@ -87,8 +88,7 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int

// if we are in the 1st step of the update, we update the configuration
if ($action === null || $action === TaskName::TASK_UPDATE_INITIALIZATION) {
$this->logger->debug('Cleaning previous state files.');
$this->upgradeContainer->getFileStorage()->cleanAllUpdateFiles();
$this->logger->debug('Cleaning previous configuration file.');
$this->upgradeContainer->getFileStorage()->clean(UpgradeFileNames::UPDATE_CONFIG_FILENAME);

$this->processConsoleInputConfiguration($input);
Expand All @@ -97,6 +97,13 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int
if ($exitCode !== ExitCode::SUCCESS) {
return $exitCode;
}
} else {
$updateState = $this->upgradeContainer->getUpdateState();
// In the special case the user inits the process from a specific task that is not the initialization,
// we need to initialize the state manually.
if (!$updateState->isInitialized()) {
$updateState->initDefault($this->upgradeContainer->getProperty(UpgradeContainer::PS_VERSION), $this->upgradeContainer->getUpgrader(), $this->upgradeContainer->getUpdateConfiguration());
}
}

$this->logger->debug('Configuration loaded successfully.');
Expand Down
31 changes: 31 additions & 0 deletions classes/Parameters/UpgradeConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class UpgradeConfiguration extends ArrayCollection
const ARCHIVE_ZIP = 'archive_zip';
const ARCHIVE_XML = 'archive_xml';
const ARCHIVE_VERSION_NUM = 'archive_version_num';
const BACKUP_COMPLETED = 'backup_completed';
const INSTALLED_LANGUAGES = 'installed_languages';

const CHANNEL_ONLINE = 'online';
const CHANNEL_LOCAL = 'local';
Expand All @@ -72,6 +74,11 @@ class UpgradeConfiguration extends ArrayCollection
self::PS_AUTOUP_REGEN_EMAIL => true,
self::PS_AUTOUP_BACKUP => true,
self::PS_AUTOUP_KEEP_IMAGES => true,
self::BACKUP_COMPLETED => false,
];

const CONFIGURATION_KEYS_ABOUT_SHOP = [
self::INSTALLED_LANGUAGES,
];

const DEFAULT_CHANNEL = self::CHANNEL_ONLINE;
Expand Down Expand Up @@ -147,6 +154,19 @@ public function isChannelOnline(): bool
return $this->getChannelOrDefault() === UpgradeConfiguration::CHANNEL_ONLINE;
}

public function isBackupCompleted(): bool
{
return $this->computeBooleanConfiguration(self::BACKUP_COMPLETED);
}

/**
* @return string[]
*/
public function getInstalledLanguagesIsoCode(): array
{
return $this->get(self::INSTALLED_LANGUAGES);
}

/**
* @return int Number of files to handle in a single call to avoid timeouts
*/
Expand Down Expand Up @@ -265,4 +285,15 @@ public function merge(array $array = []): void
$this->set($key, $value);
}
}

public function hasAllTheShopConfiguration(): bool
{
foreach (self::CONFIGURATION_KEYS_ABOUT_SHOP as $key) {
if ($this->get($key) === null) {
return false;
}
}

return true;
}
}
21 changes: 21 additions & 0 deletions classes/PrestashopConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
namespace PrestaShop\Module\AutoUpgrade;

use Exception;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;

class PrestashopConfiguration
{
Expand Down Expand Up @@ -116,4 +117,24 @@ public function findPrestaShopVersionInFile(string $content): ?string

return null;
}

/**
* Rely on installed languages to merge translations files
*
* @return string[]
*/
public function getInstalledLanguages(): array
{
return array_map(
function ($v) { return $v['iso_code']; },
\Language::getIsoIds(false)
);
}

public function fillInUpdateConfiguration(UpgradeConfiguration $upgradeConfiguration): void
{
$upgradeConfiguration->merge([
UpgradeConfiguration::INSTALLED_LANGUAGES => $this->getInstalledLanguages(),
]);
}
}
6 changes: 6 additions & 0 deletions classes/State/AbstractState.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
use PrestaShop\Module\AutoUpgrade\Parameters\FileStorage;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;

/**
* The State is used to keep track of the remaining operations to do on the shop during a process.
* Its lifespan is strictly linked to a running process, it has no use outside it.
*
* @see PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration to prepare data that will be needed during an update.
*/
abstract class AbstractState
{
/** @var bool */
Expand Down
31 changes: 5 additions & 26 deletions classes/State/UpdateState.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@

namespace PrestaShop\Module\AutoUpgrade\State;

use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\Upgrader;

class UpdateState extends AbstractState
{
Expand All @@ -53,11 +55,6 @@ class UpdateState extends AbstractState
*/
protected $installedLanguagesIso = [];

/**
* @var bool Marks the backup done during the update configuration
*/
protected $backupCompleted = false;

/**
* @var bool Determining if all steps went totally successfully
*
Expand All @@ -70,18 +67,13 @@ protected function getFileNameForPersistentStorage(): string
return UpgradeFileNames::STATE_UPDATE_FILENAME;
}

public function initDefault(string $currentVersion, ?string $destinationVersion): void
public function initDefault(string $currentVersion, Upgrader $upgrader, UpgradeConfiguration $updateConfiguration): void
{
$this->disableSave = true;
// installedLanguagesIso is used to merge translations files
$installedLanguagesIso = array_map(
function ($v) { return $v['iso_code']; },
\Language::getIsoIds(false)
);
$this->setInstalledLanguagesIso($installedLanguagesIso);
$this->setInstalledLanguagesIso($updateConfiguration->getInstalledLanguagesIsoCode());

$this->setCurrentVersion($currentVersion);
$this->setDestinationVersion($destinationVersion);
$this->setDestinationVersion($upgrader->getDestinationVersion());
$this->disableSave = false;
$this->save();
}
Expand Down Expand Up @@ -129,19 +121,6 @@ public function setInstalledLanguagesIso(array $installedLanguagesIso): self
return $this;
}

public function isBackupCompleted(): bool
{
return $this->backupCompleted;
}

public function setBackupCompleted(bool $completed): self
{
$this->backupCompleted = $completed;
$this->save();

return $this;
}

/**
* @deprecated Unused on the UIs from v7
*/
Expand Down
5 changes: 0 additions & 5 deletions classes/Task/AbstractTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,6 @@ protected function setupEnvironment(): void
$archiveXml = $updateConfiguration->getLocalChannelXml();
$this->container->getFileLoader()->addXmlMd5File($this->container->getUpgrader()->getDestinationVersion(), $this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH) . DIRECTORY_SEPARATOR . $archiveXml);
}

if ($this::TASK_TYPE !== TaskType::TASK_TYPE_RESTORE && !$this->container->getUpdateState()->isInitialized()) {
$this->container->getUpdateState()->initDefault($this->container->getProperty(UpgradeContainer::PS_VERSION), $this->container->getUpgrader()->getDestinationVersion());
$this->logger->debug($this->translator->trans('Successfully initialized update state.'));
}
}

abstract public function run(): int;
Expand Down
6 changes: 5 additions & 1 deletion classes/Task/Backup/BackupComplete.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

use Exception;
use PrestaShop\Module\AutoUpgrade\Analytics;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use PrestaShop\Module\AutoUpgrade\Task\AbstractTask;
use PrestaShop\Module\AutoUpgrade\Task\ExitCode;
use PrestaShop\Module\AutoUpgrade\Task\TaskName;
Expand All @@ -51,7 +52,10 @@ public function run(): int
$this->next = TaskName::TASK_COMPLETE;

$this->container->getFileStorage()->cleanAllBackupFiles();
$this->container->getUpdateState()->setBackupCompleted(true);
$updateConfiguration = $this->container->getUpdateConfiguration();
$updateConfiguration->merge([UpgradeConfiguration::BACKUP_COMPLETED => true]);
$this->container->getConfigurationStorage()->save($updateConfiguration);

$this->container->getAnalytics()->track('Backup Succeeded', Analytics::WITH_BACKUP_PROPERTIES);

$this->logger->info($this->translator->trans('Backup completed successfully.'));
Expand Down
1 change: 1 addition & 0 deletions classes/Task/Backup/BackupInitialization.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class BackupInitialization extends AbstractTask
*/
public function run(): int
{
$this->container->getFileStorage()->cleanAllBackupFiles();
$this->container->getBackupState()->initDefault(
$this->container->getProperty(UpgradeContainer::PS_VERSION)
);
Expand Down
1 change: 0 additions & 1 deletion classes/Task/Restore/RestoreComplete.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public function run(): int
$this->next = TaskName::TASK_COMPLETE;

$this->container->getFileStorage()->cleanAllRestoreFiles();
$this->container->getFileStorage()->cleanAllUpdateFiles();
$this->container->getAnalytics()->track('Restore Succeeded', Analytics::WITH_RESTORE_PROPERTIES);

$this->container->getRestoreState()->setProgressPercentage(
Expand Down
1 change: 1 addition & 0 deletions classes/Task/Restore/RestoreInitialization.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class RestoreInitialization extends AbstractTask
*/
public function run(): int
{
$this->container->getFileStorage()->cleanAllRestoreFiles();
$restoreConfiguration = $this->container->getRestoreConfiguration();
$state = $this->container->getRestoreState();
$state->initDefault($restoreConfiguration);
Expand Down
8 changes: 8 additions & 0 deletions classes/Task/Update/UpdateInitialization.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use PrestaShop\Module\AutoUpgrade\Task\ExitCode;
use PrestaShop\Module\AutoUpgrade\Task\TaskName;
use PrestaShop\Module\AutoUpgrade\Task\TaskType;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;

/**
* very first step of the upgrade process. The only thing done is the selection
Expand All @@ -49,6 +50,13 @@ class UpdateInitialization extends AbstractTask
public function run(): int
{
$this->logger->info($this->translator->trans('Starting update...'));
$this->container->getFileStorage()->cleanAllUpdateFiles();

$this->container->getUpdateState()->initDefault(
$this->container->getProperty(UpgradeContainer::PS_VERSION),
$this->container->getUpgrader(),
$this->container->getUpdateConfiguration()
);
$this->container->getUpdateState()->setProgressPercentage(
$this->container->getCompletionCalculator()->getBasePercentageOfTask(self::class)
);
Expand Down
4 changes: 2 additions & 2 deletions classes/UpgradeContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -821,15 +821,15 @@ public function getUpgradeSelfCheck(): UpgradeSelfCheck

$this->upgradeSelfCheck = new UpgradeSelfCheck(
$this->getUpgrader(),
$this->getUpdateState(),
$this->getUpdateConfiguration(),
$this->getPrestaShopConfiguration(),
$this->getTranslator(),
$this->getPhpVersionResolverService(),
$this->getChecksumCompare(),
$this->psRootDir,
$this->adminDir,
$this->getProperty(UpgradeContainer::WORKSPACE_PATH)
$this->getProperty(UpgradeContainer::WORKSPACE_PATH),
$this->getProperty(UpgradeContainer::PS_VERSION)
);
}

Expand Down
Loading
Loading