Skip to content

Commit

Permalink
Merge pull request #247 from lemberg/issue/220-status-not-preserved
Browse files Browse the repository at this point in the history
Store last applied update in the vm-settings.yml file instead of composer.lock
  • Loading branch information
T2L committed Sep 23, 2021
2 parents 097d2c6 + 52051df commit b9f7082
Show file tree
Hide file tree
Showing 24 changed files with 190 additions and 518 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Draft Environment (Unreleased)

- [GH-220](https://github.com/lemberg/draft-environment/pull/220) - Store last applied update in the vm-settings.yml file instead of composer.lock
- [GH-245](https://github.com/lemberg/draft-environment/pull/245) - Fix MySQL fail to install due to incorrect configuration of the SQL mode ('~' is not a valid configuration)

## Draft Environment 3.4.0 (2021-08-05)
Expand Down
4 changes: 4 additions & 0 deletions default.vm-settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
# If there is a need to override any value, create file vm-settings.local.yml
# and put it there. Local settings should not be committed to the repository.

# DO NOT MODIFY THESE SETTINGS MANUALLY.
draft:
last_applied_update: 0

# Vagrant configuration.
vagrant:
# Box to use. At the moment Debian-based distributions are supported only.
Expand Down
63 changes: 3 additions & 60 deletions src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
use Composer\Installer\PackageEvent;
use Composer\Installer\PackageEvents;
use Composer\IO\IOInterface;
use Composer\Script\Event as ScriptEvent;
use Composer\Script\ScriptEvents;
use Lemberg\Draft\Environment\Config\Manager\InstallManagerInterface;
use Lemberg\Draft\Environment\Config\Manager\UpdateManagerInterface;

Expand All @@ -24,7 +22,7 @@ final class App {

public const PACKAGE_NAME = 'lemberg/draft-environment';

public const LAST_AVAILABLE_UPDATE_WEIGHT = 11;
public const LAST_AVAILABLE_UPDATE = 12;

/**
* @var \Composer\Composer
Expand All @@ -46,20 +44,6 @@ final class App {
*/
private $configUpdateManager;

/**
* Boolean indicating whether the installation process should run.
*
* @var bool
*/
private $shouldRunInstallation = FALSE;

/**
* Boolean indicating whether the update process should run.
*
* @var bool
*/
private $shouldRunUpdate = FALSE;

/**
* Draft Environment app constructor.
*
Expand All @@ -84,9 +68,6 @@ public function handleEvent(Event $event): void {
if ($event instanceof PackageEvent) {
$this->handlePackageEvent($event);
}
elseif ($event instanceof ScriptEvent) {
$this->handleScriptEvent($event);
}
}

/**
Expand Down Expand Up @@ -114,9 +95,7 @@ private function handlePackageEvent(PackageEvent $event): void {
private function onPostPackageInstall(InstallOperation $operation): void {
// Clean up Draft Environment config files upon package uninstallation.
if ($operation->getPackage()->getName() === self::PACKAGE_NAME) {
// Run installation later (during post command phase) in order to have
// nice console output.
$this->shouldRunInstallation = TRUE;
$this->configInstallManager->install();
}
}

Expand All @@ -135,9 +114,7 @@ private function onPostPackageUpdate(UpdateOperation $operation): void {
$targetReleaseDate = $operation->getTargetPackage()->getReleaseDate() ?? $now;
// Package downgrading is not supported by the update manager.
if ($targetReleaseDate >= $initialReleaseDate) {
// Run update later (during post command phase) in order to have
// dependencies autoloaded.
$this->shouldRunUpdate = TRUE;
$this->configUpdateManager->update();
}
}
}
Expand All @@ -154,38 +131,4 @@ private function onPrePackageUninstall(UninstallOperation $operation): void {
}
}

/**
* Composer script events handler.
*
* @param \Composer\Script\Event $event
*/
private function handleScriptEvent(ScriptEvent $event): void {
if ($event->getName() === ScriptEvents::POST_AUTOLOAD_DUMP) {
$this->onPostAutoloadDumpCommand($event);
}
}

/**
* Post autoload dump command event handler.
*
* @param \Composer\Script\Event $event
*/
private function onPostAutoloadDumpCommand(ScriptEvent $event): void {
if ($this->shouldRunInstallation) {
$this->configInstallManager->install();
$this->shouldRunInstallation = FALSE;
}

if ($this->shouldRunUpdate) {
$this->configUpdateManager->update();
$this->shouldRunUpdate = FALSE;
}

// Mark the package as already installed.
$this->configInstallManager->setAsAlreadyInstalled();
// Mark all available updates as already applied.
$lastAvailableWeight = $this->configUpdateManager->getLastAvailableUpdateWeight();
$this->configUpdateManager->setLastAppliedUpdateWeight($lastAvailableWeight);
}

}
2 changes: 0 additions & 2 deletions src/Composer/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use Composer\Installer\PackageEvents;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Script\ScriptEvents;
use Lemberg\Draft\Environment\App;
use Lemberg\Draft\Environment\Config\Config;
use Lemberg\Draft\Environment\Config\Manager\InstallManager;
Expand Down Expand Up @@ -71,7 +70,6 @@ public static function getSubscribedEvents(): array {
PackageEvents::POST_PACKAGE_INSTALL => 'onComposerEvent',
PackageEvents::POST_PACKAGE_UPDATE => 'onComposerEvent',
PackageEvents::PRE_PACKAGE_UNINSTALL => 'onComposerEvent',
ScriptEvents::POST_AUTOLOAD_DUMP => 'onComposerEvent',
];
}

Expand Down
2 changes: 1 addition & 1 deletion src/Config/Install/InstallConfigStepInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface InstallConfigStepInterface extends AbstractStepInterface {
/**
* Contains installation step business logic.
*
* @param array[] $config
* @param array<int|string,mixed> $config
* Draft Environment configuration nested array.
*/
public function install(array &$config): void;
Expand Down
83 changes: 48 additions & 35 deletions src/Config/Manager/AbstractConfigManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
use Composer\Autoload\ClassLoader;
use Composer\Autoload\ClassMapGenerator;
use Composer\Composer;
use Composer\Factory;
use Composer\IO\IOInterface;
use Composer\Json\JsonFile;
use Lemberg\Draft\Environment\App;
use Lemberg\Draft\Environment\Config\AbstractStepInterface;
use Lemberg\Draft\Environment\Config\Config;
use Lemberg\Draft\Environment\Config\ConfigAwareTrait;
use Lemberg\Draft\Environment\Utility\Filesystem;
use Lemberg\Draft\Environment\Utility\FilesystemAwareTrait;
use Nette\Loaders\RobotLoader;

/**
Expand All @@ -22,6 +22,7 @@
abstract class AbstractConfigManager implements ManagerInterface {

use ConfigAwareTrait;
use FilesystemAwareTrait;

/**
* @var \Composer\Composer
Expand All @@ -45,6 +46,7 @@ final public function __construct(Composer $composer, IOInterface $io, Config $c
$this->composer = $composer;
$this->io = $io;
$this->setConfig($config);
$this->setFilesystem(new Filesystem());

// This code is running in Composer context, newly added packages might
// not be autoloaded.
Expand All @@ -53,6 +55,29 @@ final public function __construct(Composer $composer, IOInterface $io, Config $c
}
}

/**
* Reads configuration from the target config file.
*
* @return array<int|string,mixed> $config
*/
final protected function readConfig(): array {
$configObject = $this->getConfig();
$targetConfigFilepath = $configObject->getTargetConfigFilepath(Config::TARGET_CONFIG_FILENAME);
return $configObject->readAndParseConfigFromTheFile($targetConfigFilepath);
}

/**
* Writes given configuration to the target config file.
*
* @param array<int|string,mixed> $config
* Draft Environment configuration nested array.
*/
final protected function writeConfig(array $config): void {
$configObject = $this->getConfig();
$targetConfigFilepath = $configObject->getTargetConfigFilepath(Config::TARGET_CONFIG_FILENAME);
$configObject->writeConfigToTheFile($targetConfigFilepath, $targetConfigFilepath, $config);
}

/**
* Looks for classes implementing a given interface.
*/
Expand Down Expand Up @@ -85,45 +110,33 @@ final protected function sortSteps(): void {
}

/**
* @return array<mixed>
* Get the last update weight from the local repository.
*
* @param array<int|string,mixed> $config
*
* @return int
*/
final protected function getPackageExtra(): array {
$localRepository = $this->composer->getRepositoryManager()->getLocalRepository();
/** @var \Composer\Package\Package|NULL $localPackage */
$localPackage = $localRepository->findPackage(App::PACKAGE_NAME, '*');
return !is_null($localPackage) ? $localPackage->getExtra() : [];
final protected function getLastAppliedUpdateWeight(array $config): int {
return $config['draft']['last_applied_update'] ?? 0;
}

/**
* @param array<mixed> $extra
* Set the last update weight in the local repository.
*
* @param array<int|string,mixed> $config
* @param int $weight
*/
final protected function setPackageExtra(array $extra): void {
$localRepository = $this->composer->getRepositoryManager()->getLocalRepository();
/** @var \Composer\Package\Package|NULL $localPackage */
$localPackage = $localRepository->findPackage(App::PACKAGE_NAME, '*');
if (!is_null($localPackage)) {
$localPackage->setExtra($extra);
}
final protected function setLastAppliedUpdateWeight(array &$config, int $weight): void {
$config['draft']['last_applied_update'] = $weight;
}

// This code might run after Composer has written the lock file.
$composerFile = Factory::getComposerFile();
$lockFile = 'json' === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
if ($this->getConfig()->getFilesystem()->exists($lockFile)) {
$json = new JsonFile($lockFile);
$content = $json->read();
$content += [
'packages' => [],
'packages-dev' => [],
];

foreach (['packages', 'packages-dev'] as $type) {
$key = array_search(App::PACKAGE_NAME, array_column($content[$type], 'name'), TRUE);
if ($key !== FALSE) {
$content[$type][$key]['extra'] = $extra;
$json->write($content);
}
}
}
/**
* Get the weight of the last available step.
*
* @return int
*/
final protected function getLastAvailableUpdateWeight(): int {
return App::LAST_AVAILABLE_UPDATE;
}

/**
Expand Down
30 changes: 7 additions & 23 deletions src/Config/Manager/InstallManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,13 @@ final class InstallManager extends AbstractConfigManager implements InstallManag
* {@inheritdoc}
*/
public function install(): void {
if (!$this->hasBeenAlreadyInstalled()) {
$targetConfigFilepath = $this->getConfig()->getTargetConfigFilepath(Config::TARGET_CONFIG_FILENAME);
if (!$this->getFilesystem()->exists($targetConfigFilepath)) {
$this->installInitPhase();
$this->installConfigPhase();
$this->setAsAlreadyInstalled();
}
}

/**
* {@inheritdoc}
*/
public function hasBeenAlreadyInstalled(): bool {
$extra = $this->getPackageExtra();
return $extra['draft-environment']['already-installed'] ?? FALSE;
}

/**
* {@inheritdoc}
*/
public function setAsAlreadyInstalled(): void {
$extra = $this->getPackageExtra();
$extra['draft-environment']['already-installed'] = TRUE;
$this->setPackageExtra($extra);
}

/**
* {@inheritdoc}
*/
Expand All @@ -62,6 +45,7 @@ private function installInitPhase(): void {
$this->writeMessage('<info>Welcome to the Draft Environment interactive installer</info>');
$this->discoverSteps(InstallInitStepInterface::class, __DIR__ . '/../Install');
$this->sortSteps();

/** @var \Lemberg\Draft\Environment\Config\Install\InstallInitStepInterface $step */
foreach ($this->steps as $step) {
$step->install();
Expand All @@ -73,19 +57,19 @@ private function installInitPhase(): void {
* Executes the configuration setup phase of the installation process.
*/
private function installConfigPhase(): void {
$config = $this->readConfig();
$this->writeMessage('<info>Please answer to a few questions:</info>');

$config = $this->getConfig()->readAndParseConfigFromTheFile($this->getConfig()->getTargetConfigFilepath(Config::TARGET_CONFIG_FILENAME));

$this->discoverSteps(InstallConfigStepInterface::class, __DIR__ . '/../Install');
$this->sortSteps();

/** @var \Lemberg\Draft\Environment\Config\Install\InstallConfigStepInterface $step */
foreach ($this->steps as $step) {
$step->install($config);
$this->writeMessage($step->getMessages());
}

$this->getConfig()->writeConfigToTheFile($this->getConfig()->getTargetConfigFilepath(Config::TARGET_CONFIG_FILENAME), $this->getConfig()->getTargetConfigFilepath(Config::TARGET_CONFIG_FILENAME), $config);
$this->setLastAppliedUpdateWeight($config, $this->getLastAvailableUpdateWeight());
$this->writeConfig($config);

$message = <<<HERE
<info>Unfortunately, the interactive installer has quite limited functionality at the moment</info>
Expand Down
10 changes: 0 additions & 10 deletions src/Config/Manager/InstallManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,4 @@ public function install(): void;
*/
public function uninstall(): void;

/**
* Check whether Draft Environment has been already installed.
*/
public function hasBeenAlreadyInstalled(): bool;

/**
* Set Draft Environment as already installed.
*/
public function setAsAlreadyInstalled(): void;

}

0 comments on commit b9f7082

Please sign in to comment.