From 27b6181611cce23369b98fc5ef7c919e51684c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFck=20Piera?= Date: Mon, 26 Feb 2024 19:13:47 +0100 Subject: [PATCH] Cache requirements to avoid running composer all the time --- src/Remote/Composer.php | 67 ++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/src/Remote/Composer.php b/src/Remote/Composer.php index a6fa3471..dcd55b03 100644 --- a/src/Remote/Composer.php +++ b/src/Remote/Composer.php @@ -10,6 +10,7 @@ class Composer { public const VENDOR_DIR = '/.castor/vendor/'; + public const PATH_CASTOR_REQUIREMENTS = self::VENDOR_DIR . 'castor-requirements.json'; public function __construct( private readonly LoggerInterface $logger, @@ -21,19 +22,7 @@ public function __construct( */ public function getConfiguration(): array { - $path = PathHelper::getRoot() . self::VENDOR_DIR . 'composer.json'; - - if (!file_exists($path)) { - return []; - } - - $json = file_get_contents($path); - - if (!$json) { - return []; - } - - return json_decode($json, true, flags: \JSON_THROW_ON_ERROR); + return $this->readJsonFile(PathHelper::getRoot() . self::VENDOR_DIR . 'composer.json'); } /** @@ -52,12 +41,36 @@ public function setConfiguration(array $configuration): void } file_put_contents($dir . '.gitignore', "*\n"); - file_put_contents($dir . 'composer.json', json_encode($configuration, \JSON_PRETTY_PRINT | \JSON_THROW_ON_ERROR)); + + $this->writeJsonFile($dir . 'composer.json', $configuration); } public function require(string $package, string $version): void { + $requirements = $this->readJsonFile(PathHelper::getRoot() . self::PATH_CASTOR_REQUIREMENTS); + + if (isset($requirements[$package]) && $requirements[$package] === $version) { + $this->logger->debug('The package is already required, no need to run Composer.', [ + 'package' => $package, + 'version' => $version, + ]); + + return; + } + + if (isset($requirements[$package]) && $version !== $requirements[$package]) { + $this->logger->debug('The package is already required but in another version, let\'s empty requirements cache to force Composer re-installation of every package.', [ + 'package' => $package, + 'version' => $version, + ]); + $requirements = []; + } + $this->run('require', $package . ':' . $version); + + $requirements[$package] = $version; + + $this->writeJsonFile(PathHelper::getRoot() . self::PATH_CASTOR_REQUIREMENTS, $requirements); } private function run(string ...$args): void @@ -83,4 +96,30 @@ private function run(string ...$args): void 'output' => $process->getOutput(), ]); } + + /** + * @return array + */ + private function readJsonFile(string $path): array + { + if (!file_exists($path)) { + return []; + } + + $json = file_get_contents($path); + + if (!$json) { + return []; + } + + return json_decode($json, true, flags: \JSON_THROW_ON_ERROR); + } + + /** + * @param array $json + */ + private function writeJsonFile(string $path, array $json): void + { + file_put_contents($path, json_encode($json, \JSON_PRETTY_PRINT | \JSON_THROW_ON_ERROR)); + } }