Skip to content

Commit

Permalink
Convert asset manager version into composer version for comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
francoispluchino committed Aug 14, 2021
1 parent 7e3eadb commit 7d3d824
Show file tree
Hide file tree
Showing 5 changed files with 375 additions and 7 deletions.
24 changes: 17 additions & 7 deletions Asset/AbstractAssetManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Composer\Util\Platform;
use Composer\Util\ProcessExecutor;
use Foxy\Config\Config;
use Foxy\Converter\SemverConverter;
use Foxy\Converter\VersionConverterInterface;
use Foxy\Exception\RuntimeException;
use Foxy\Fallback\FallbackInterface;
use Foxy\Json\JsonFile;
Expand Down Expand Up @@ -51,6 +53,11 @@ abstract class AbstractAssetManager implements AssetManagerInterface
*/
protected $fs;

/**
* @var VersionConverterInterface
*/
protected $versionConverter;

/**
* @var null|FallbackInterface
*/
Expand All @@ -69,24 +76,27 @@ abstract class AbstractAssetManager implements AssetManagerInterface
/**
* Constructor.
*
* @param IOInterface $io The IO
* @param Config $config The config
* @param ProcessExecutor $executor The process
* @param Filesystem $fs The filesystem
* @param FallbackInterface $fallback The asset fallback
* @param IOInterface $io The IO
* @param Config $config The config
* @param ProcessExecutor $executor The process
* @param Filesystem $fs The filesystem
* @param null|FallbackInterface $fallback The asset fallback
* @param null|VersionConverterInterface $versionConverter The version converter
*/
public function __construct(
IOInterface $io,
Config $config,
ProcessExecutor $executor,
Filesystem $fs,
FallbackInterface $fallback = null
FallbackInterface $fallback = null,
?VersionConverterInterface $versionConverter = null
) {
$this->io = $io;
$this->config = $config;
$this->executor = $executor;
$this->fs = $fs;
$this->fallback = $fallback;
$this->versionConverter = null !== $versionConverter ? $versionConverter : new SemverConverter();
}

/**
Expand Down Expand Up @@ -258,7 +268,7 @@ protected function getVersion()
{
if ('' === $this->version) {
$this->executor->execute($this->getVersionCommand(), $version);
$this->version = '' !== trim($version) ? trim($version) : null;
$this->version = '' !== trim($version) ? $this->versionConverter->convertVersion(trim($version)) : null;
}

return $this->version;
Expand Down
35 changes: 35 additions & 0 deletions Converter/SemverConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the Foxy package.
*
* (c) François Pluchino <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Foxy\Converter;

/**
* Converter for Semver syntax version to composer syntax version.
*
* @author François Pluchino <[email protected]>
*/
class SemverConverter implements VersionConverterInterface
{
public function convertVersion($version)
{
if (\in_array($version, array(null, '', 'latest'), true)) {
return ('latest' === $version ? 'default || ' : '').'*';
}

$version = str_replace('', '-', $version);
$prefix = preg_match('/^[a-z]/', $version) && 0 !== strpos($version, 'dev-') ? substr($version, 0, 1) : '';
$version = substr($version, \strlen($prefix));
$version = SemverUtil::convertVersionMetadata($version);
$version = SemverUtil::convertDateVersion($version);

return $prefix.$version;
}
}
187 changes: 187 additions & 0 deletions Converter/SemverUtil.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<?php

/*
* This file is part of the Foxy package.
*
* (c) François Pluchino <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Foxy\Converter;

use Composer\Package\Version\VersionParser;

/**
* Utils for semver converter.
*
* @author François Pluchino <[email protected]>
*/
abstract class SemverUtil
{
/**
* Converts the date or datetime version.
*
* @param string $version The version
*
* @return string
*/
public static function convertDateVersion($version)
{
if (preg_match('/^\d{7,}\./', $version)) {
$pos = strpos($version, '.');
$version = substr($version, 0, $pos).self::convertDateMinorVersion(substr($version, $pos + 1));
}

return $version;
}

/**
* Converts the version metadata.
*
* @param string $version
*
* @return string
*/
public static function convertVersionMetadata($version)
{
if (preg_match_all(
self::createPattern('([a-zA-Z]+|(\-|\+)[a-zA-Z]+|(\-|\+)[0-9]+)'),
$version,
$matches,
PREG_OFFSET_CAPTURE
)) {
list($type, $version, $end) = self::cleanVersion(strtolower($version), $matches);
list($version, $patchVersion) = self::matchVersion($version, $type);

$matches = array();
$hasPatchNumber = preg_match('/[0-9]+\.[0-9]+|[0-9]+|\.[0-9]+$/', $end, $matches);
$end = $hasPatchNumber ? $matches[0] : '1';

if ($patchVersion) {
$version .= $end;
}
}

return static::cleanWildcard($version);
}

/**
* Creates a pattern with the version prefix pattern.
*
* @param string $pattern The pattern without '/'
*
* @return string The full pattern with '/'
*/
public static function createPattern($pattern)
{
$numVer = '([0-9]+|x|\*)';
$numVer2 = '('.$numVer.'\.'.$numVer.')';
$numVer3 = '('.$numVer.'\.'.$numVer.'\.'.$numVer.')';

return '/^'.'('.$numVer.'|'.$numVer2.'|'.$numVer3.')'.$pattern.'/';
}

/**
* Clean the wildcard in version.
*
* @param string $version The version
*
* @return string The cleaned version
*/
private static function cleanWildcard($version)
{
while (false !== strpos($version, '.x.x')) {
$version = str_replace('.x.x', '.x', $version);
}

return $version;
}

/**
* Clean the raw version.
*
* @param string $version The version
* @param array $matches The match of pattern asset version
*
* @return array The list of $type, $version and $end
*/
private static function cleanVersion($version, array $matches)
{
$end = substr($version, \strlen($matches[1][0][0]));
$version = $matches[1][0][0].'-';

$matches = array();
if (preg_match('/^([-+])/', $end, $matches)) {
$end = substr($end, 1);
}

$matches = array();
preg_match('/^[a-z]+/', $end, $matches);
$type = isset($matches[0]) ? VersionParser::normalizeStability($matches[0]) : null;
$end = substr($end, \strlen($type));

return array($type, $version, $end);
}

/**
* Match the version.
*
* @param string $version
* @param string $type
*
* @return array The list of $version and $patchVersion
*/
private static function matchVersion($version, $type)
{
$patchVersion = true;

switch ($type) {
case 'dev':
case 'snapshot':
$type = 'dev';
$patchVersion = false;

break;

case 'a':
$type = 'alpha';

break;

case 'b':
case 'pre':
$type = 'beta';

break;

default:
if (!\in_array($type, array('alpha', 'beta', 'RC'), true)) {
$type = 'patch';
}

break;
}

$version .= $type;

return array($version, $patchVersion);
}

/**
* Convert the minor version of date.
*
* @param string $minor The minor version
*
* @return string
*/
private static function convertDateMinorVersion($minor)
{
$split = explode('.', $minor);
$minor = (int) $split[0];
$revision = isset($split[1]) ? (int) $split[1] : 0;

return '.'.sprintf('%03d', $minor).sprintf('%03d', $revision);
}
}
29 changes: 29 additions & 0 deletions Converter/VersionConverterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/*
* This file is part of the Foxy package.
*
* (c) François Pluchino <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Foxy\Converter;

/**
* Interface for the converter for asset syntax version to composer syntax version.
*
* @author François Pluchino <[email protected]>
*/
interface VersionConverterInterface
{
/**
* Converts the asset version to composer version.
*
* @param string $version The asset version
*
* @return string The composer version
*/
public function convertVersion($version);
}
Loading

0 comments on commit 7d3d824

Please sign in to comment.