First step towards versions in dependencies

Add InstallCommand::calculateMergedDependenciesOfPackages and
InstallCommand::calculateVersionNumberFromDependencyVersion and
corresponding unit tests
This commit is contained in:
Flavio Copes
2016-02-16 15:24:33 +01:00
parent b59cdbfdcf
commit 503ff8d70f
2 changed files with 225 additions and 1 deletions

View File

@@ -14,6 +14,7 @@ use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Yaml\Yaml;
define('GIT_REGEX', '/http[s]?:\/\/(?:.*@)?(github|bitbucket)(?:.org|.com)\/.*\/(.*)/');
define('SECOND_IS_HIGHER', -1);
/**
* Class InstallCommand
@@ -25,18 +26,22 @@ class InstallCommand extends ConsoleCommand
* @var
*/
protected $data;
/**
* @var
*/
protected $gpm;
/**
* @var
*/
protected $destination;
/**
* @var
*/
protected $file;
/**
* @var
*/
@@ -44,7 +49,6 @@ class InstallCommand extends ConsoleCommand
protected $local_config;
/**
*
*/
@@ -153,6 +157,96 @@ class InstallCommand extends ConsoleCommand
$this->clearCache();
}
/**
* Calculates and merges the dependencies of the passed packages
*
* @param array $packages
*
* @return mixed
* @throws \Exception
*/
public function calculateMergedDependenciesOfPackages($packages)
{
foreach ($packages as $data) {
foreach ($data as $package) {
//Check for dependencies
if (isset($package->dependencies_versions)) {
foreach ($package->dependencies_versions as $dependency) {
$current_package_name = $dependency->name;
if (isset($dependency->version)) {
$current_package_version_information = $dependency->version;
}
if (!isset($dependencies[$current_package_name])) { // Dependency added for the first time
if (!isset($current_package_version_information)) {
$dependencies[$current_package_name] = '*';
} else {
$dependencies[$current_package_name] = $current_package_version_information;
}
} else { // Dependency already added by another package
//if this package requires a version higher than the currently stored one, store this requirement instead
if (isset($current_package_version_information) && $current_package_version_information !== '*') {
$currently_stored_version_information = $dependencies[$current_package_name];
$currently_stored_version_number = $this->calculateVersionNumberFromDependencyVersion($currently_stored_version_information);
if (!$currently_stored_version_number) {
$currently_stored_version_number = '*';
}
$current_package_version_number = $this->calculateVersionNumberFromDependencyVersion($current_package_version_information);
if (!$current_package_version_number) {
throw new \Exception('Bad format for package ' . $current_package_name);
}
//If I had stored '*', change right away with the more specific version required
if ($currently_stored_version_number === '*') {
$dependencies[$current_package_name] = $current_package_version_information;
} else {
if (version_compare($currently_stored_version_number, $current_package_version_number) == SECOND_IS_HIGHER) {
$dependencies[$current_package_name] = $current_package_version_information;
}
}
}
}
}
}
}
}
return $dependencies;
}
/**
* Returns the actual version from a dependency version string.
* Examples:
* $versionInformation == '~2.0' => returns '2.0'
* $versionInformation == '>=2.0.2' => returns '2.0.2'
* $versionInformation == '*' => returns null
* $versionInformation == '' => returns null
*
* @param $versionInformation
*
* @return null|string
*/
public function calculateVersionNumberFromDependencyVersion($versionInformation)
{
if (substr($versionInformation, 0, 1) == '~') {
return substr($versionInformation, 1);
} elseif (substr($versionInformation, 0, 2) == '>=') {
return substr($versionInformation, 2);
}
return null;
}
/**
* @param $package
*/

View File

@@ -0,0 +1,130 @@
<?php
use Codeception\Util\Fixtures;
use Grav\Common\Grav;
use Grav\Console\Gpm\InstallCommand;
/**
* Class InstallCommandTest
*/
class InstallCommandTest extends \Codeception\TestCase\Test
{
/** @var Grav $grav */
protected $grav;
protected function _before()
{
$this->grav = Fixtures::get('grav');
$this->installCommand = new InstallCommand();
}
protected function _after()
{
}
public function testTest()
{
//////////////////////////////////////////////////////////////////////////////////////////
//First example
//////////////////////////////////////////////////////////////////////////////////////////
$this->data = [
[
'admin' => (object)[
'dependencies_versions' => [
(object)["name" => "grav", "version" => ">=1.0.10"],
(object)["name" => "form", "version" => "~2.0"],
(object)["name" => "login", "version" => ">=2.0"],
(object)["name" => "errors", "version" => "*"],
(object)["name" => "problems"],
]
],
'test' => (object)[
'dependencies_versions' => [
(object)["name" => "errors", "version" => ">=1.0"]
]
]
]
];
$dependencies = $this->installCommand->calculateMergedDependenciesOfPackages($this->data);
$this->assertTrue(is_array($dependencies));
$this->assertTrue(count($dependencies) == 5);
$this->assertTrue($dependencies['grav'] == '>=1.0.10');
$this->assertTrue($dependencies['errors'] == '>=1.0');
$this->assertFalse($dependencies['errors'] == '*');
$this->assertTrue($dependencies['problems'] == '*');
//////////////////////////////////////////////////////////////////////////////////////////
//Second example
//////////////////////////////////////////////////////////////////////////////////////////
$this->data = [
[
'admin' => (object)[
'dependencies_versions' => [
(object)["name" => "errors", "version" => "*"],
]
],
'test' => (object)[
'dependencies_versions' => [
(object)["name" => "errors", "version" => ">=1.0"]
]
],
'another' => (object)[
'dependencies_versions' => [
(object)["name" => "errors", "version" => ">=3.2"]
]
]
]
];
$dependencies = $this->installCommand->calculateMergedDependenciesOfPackages($this->data);
$this->assertTrue(is_array($dependencies));
$this->assertTrue(count($dependencies) == 1);
$this->assertTrue($dependencies['errors'] == '>=3.2');
//////////////////////////////////////////////////////////////////////////////////////////
//Second example
//////////////////////////////////////////////////////////////////////////////////////////
$this->data = [
[
'admin' => (object)[
'dependencies_versions' => [
(object)["name" => "errors", "version" => ">=4.0"],
]
],
'test' => (object)[
'dependencies_versions' => [
(object)["name" => "errors", "version" => ">=1.0"]
]
],
'another' => (object)[
'dependencies_versions' => [
(object)["name" => "errors", "version" => ">=3.2"]
]
]
]
];
$dependencies = $this->installCommand->calculateMergedDependenciesOfPackages($this->data);
$this->assertTrue(is_array($dependencies));
$this->assertTrue(count($dependencies) == 1);
$this->assertTrue($dependencies['errors'] == '>=4.0');
}
public function testCalculateVersionNumberFromDependencyVersion()
{
$this->assertSame('2.0', $this->installCommand->calculateVersionNumberFromDependencyVersion('>=2.0'));
$this->assertSame('2.0.2', $this->installCommand->calculateVersionNumberFromDependencyVersion('>=2.0.2'));
$this->assertSame('2.0.2', $this->installCommand->calculateVersionNumberFromDependencyVersion('~2.0.2'));
$this->assertSame('1', $this->installCommand->calculateVersionNumberFromDependencyVersion('~1'));
$this->assertSame(null, $this->installCommand->calculateVersionNumberFromDependencyVersion(''));
$this->assertSame(null, $this->installCommand->calculateVersionNumberFromDependencyVersion('*'));
$this->assertSame(null, $this->installCommand->calculateVersionNumberFromDependencyVersion('2.0.2'));
}
}