Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ReleaseChooser.php 4.05 KiB
<?php
namespace Drupal\automatic_updates;
use Composer\Semver\Semver;
use Drupal\automatic_updates\Validator\UpdateVersionValidator;
use Drupal\automatic_updates_9_3_shim\ProjectRelease;
use Drupal\Core\Extension\ExtensionVersion;
/**
* Defines a class to choose a release of Drupal core to update to.
*/
class ReleaseChooser {
use VersionParsingTrait;
/**
* The version validator service.
*
* @var \Drupal\automatic_updates\Validator\UpdateVersionValidator
*/
protected $versionValidator;
/**
* The project information fetcher.
*
* @var \Drupal\automatic_updates\ProjectInfo
*/
protected $projectInfo;
/**
* Constructs an ReleaseChooser object.
*
* @param \Drupal\automatic_updates\Validator\UpdateVersionValidator $version_validator
* The version validator.
*/
public function __construct(UpdateVersionValidator $version_validator) {
$this->versionValidator = $version_validator;
$this->projectInfo = new ProjectInfo('drupal');
}
/**
* Returns the releases that are installable.
*
* @return \Drupal\automatic_updates_9_3_shim\ProjectRelease[]
* The releases that are installable according to the version validator
* service.
*/
protected function getInstallableReleases(): array {
return array_filter(
$this->projectInfo->getInstallableReleases(),
[$this->versionValidator, 'isValidVersion'],
ARRAY_FILTER_USE_KEY
);
}
/**
* Gets the most recent release in the same minor as a specified version.
*
* @param string $version
* The full semantic version number, which must include a patch version.
*
* @return \Drupal\automatic_updates_9_3_shim\ProjectRelease|null
* The most recent release in the minor if available, otherwise NULL.
*
* @throws \InvalidArgumentException
* If the given semantic version number does not contain a patch version.
*/
protected function getMostRecentReleaseInMinor(string $version): ?ProjectRelease {
if (static::getPatchVersion($version) === NULL) {
throw new \InvalidArgumentException("The version number $version does not contain a patch version");
}
$releases = $this->getInstallableReleases();
foreach ($releases as $release) {
// Checks if the release is in the same minor as the currently installed
// version. For example, if the current version is 9.8.0 then the
// constraint ~9.8.0 (equivalent to >=9.8.0 && <9.9.0) will be used to
// check if the release is in the same minor.
if (Semver::satisfies($release->getVersion(), "~$version")) {
return $release;
}
}
return NULL;
}
/**
* Gets the installed version of Drupal core.
*
* @return string
* The installed version of Drupal core.
*/
protected function getInstalledVersion(): string {
return $this->projectInfo->getInstalledVersion();
}
/**
* Gets the latest release in the currently installed minor.
*
* This will only return a release if it passes the ::isValidVersion() method
* of the version validator service injected into this class.
*
* @return \Drupal\automatic_updates_9_3_shim\ProjectRelease|null
* The latest release in the currently installed minor, if any, otherwise
* NULL.
*/
public function getLatestInInstalledMinor(): ?ProjectRelease {
return $this->getMostRecentReleaseInMinor($this->getInstalledVersion());
}
/**
* Gets the latest release in the next minor.
*
* This will only return a release if it passes the ::isValidVersion() method
* of the version validator service injected into this class.
*
* @return \Drupal\automatic_updates_9_3_shim\ProjectRelease|null
* The latest release in the next minor, if any, otherwise NULL.
*/
public function getLatestInNextMinor(): ?ProjectRelease {
$installed_version = ExtensionVersion::createFromVersionString($this->getInstalledVersion());
$next_minor = $installed_version->getMajorVersion() . '.' . (((int) $installed_version->getMinorVersion()) + 1) . '.0';
return $this->getMostRecentReleaseInMinor($next_minor);
}
}