Merge pull request #9628 from creative-commoners/pulls/4/version-provider

NEW Additional logic for VersionProvider
This commit is contained in:
Garion Herman 2020-08-21 14:25:23 +12:00 committed by GitHub
commit c143941e44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 246 additions and 30 deletions

View File

@ -25,6 +25,7 @@ use SilverStripe\Core\Injector\Injector;
*/ */
class VersionProvider class VersionProvider
{ {
use Configurable; use Configurable;
/** /**
@ -41,32 +42,74 @@ class VersionProvider
{ {
$modules = $this->getModules(); $modules = $this->getModules();
$lockModules = $this->getModuleVersionFromComposer(array_keys($modules)); $lockModules = $this->getModuleVersionFromComposer(array_keys($modules));
$output = []; $moduleVersions = [];
foreach ($modules as $module => $title) { foreach ($modules as $module => $title) {
$version = isset($lockModules[$module]) if (!array_key_exists($module, $lockModules)) {
? $lockModules[$module] continue;
: _t(__CLASS__ . '.VERSIONUNKNOWN', 'Unknown'); }
$output[] = $title . ': ' . $version; $version = $lockModules[$module];
$moduleVersions[$module] = [$title, $version];
} }
return implode(', ', $output); $moduleVersions = $this->filterModules($moduleVersions);
$ret = [];
foreach ($moduleVersions as $module => $value) {
list($title, $version) = $value;
$ret[] = "$title: $version";
}
return implode(', ', $ret);
} }
/** /**
* Gets the configured core modules to use for the SilverStripe application version. Filtering * Filter modules to only use the last module from a git repo, for example
* is used to ensure that modules can turn the result off for other modules, e.g. CMS can disable Framework. *
* [
* silverstripe/framework => ['Framework', 1.1.1'],
* silverstripe/cms => ['CMS', 2.2.2'],
* silverstripe/recipe-cms => ['CMS Recipe', '3.3.3'],
* cwp/cwp-core => ['CWP', '4.4.4']
* ]
* =>
* [
* silverstripe/recipe-cms => ['CMS Recipe', '3.3.3'],
* cwp/cwp-core => ['CWP', '4.4.4']
* ]
*
* @param array $modules
* @return array
*/
private function filterModules(array $modules)
{
$accountModule = [];
foreach ($modules as $module => $value) {
if (!preg_match('#^([a-z0-9\-]+)/([a-z0-9\-]+)$#', $module, $m)) {
continue;
}
$account = $m[1];
$accountModule[$account] = [$module, $value];
}
$ret = [];
foreach ($accountModule as $account => $arr) {
list($module, $value) = $arr;
$ret[$module] = $value;
}
return $ret;
}
/**
* Gets the configured core modules to use for the SilverStripe application version
* *
* @return array * @return array
*/ */
public function getModules() public function getModules()
{ {
$modules = Config::inst()->get(self::class, 'modules'); $modules = Config::inst()->get(self::class, 'modules');
return $modules ? array_filter($modules) : []; return !empty($modules) ? $modules : ['silverstripe/framework' => 'Framework'];
} }
/** /**
* Tries to obtain version number from composer.lock if it exists * Tries to obtain version number from composer.lock if it exists
* *
* @param array $modules * @param array $modules
* @return array * @return array
*/ */
public function getModuleVersionFromComposer($modules = []) public function getModuleVersionFromComposer($modules = [])
@ -86,12 +129,12 @@ class VersionProvider
/** /**
* Load composer.lock's contents and return it * Load composer.lock's contents and return it
* *
* @param bool $cache * @param bool $cache
* @return array * @return array
*/ */
protected function getComposerLock($cache = true) protected function getComposerLock($cache = true)
{ {
$composerLockPath = BASE_PATH . '/composer.lock'; $composerLockPath = $this->getComposerLockPath();
if (!file_exists($composerLockPath)) { if (!file_exists($composerLockPath)) {
return []; return [];
} }
@ -117,4 +160,12 @@ class VersionProvider
return $lockData; return $lockData;
} }
/**
* @return string
*/
protected function getComposerLockPath(): string
{
return BASE_PATH . '/composer.lock';
}
} }

View File

@ -2,46 +2,74 @@
namespace SilverStripe\Core\Tests\Manifest; namespace SilverStripe\Core\Tests\Manifest;
use SebastianBergmann\Version;
use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Manifest\VersionProvider; use SilverStripe\Core\Manifest\VersionProvider;
use SilverStripe\Dev\SapphireTest; use SilverStripe\Dev\SapphireTest;
class VersionProviderTest extends SapphireTest class VersionProviderTest extends SapphireTest
{ {
/** /**
* @var VersionProvider * @var VersionProvider
*/ */
protected $provider; protected $provider;
public function setUp() public function getMockProvider($composerLockPath = '')
{ {
parent::setUp(); if ($composerLockPath == '') {
$this->provider = new VersionProvider; // composer.lock file without silverstripe/recipe-core or silverstripe/recipe-cms
$composerLockPath = __DIR__ . '/fixtures/VersionProviderTest/composer.no-recipe.testlock';
}
/** @var VersionProvider $provider */
$provider = $this->getMockBuilder(VersionProvider::class)
->setMethods(['getComposerLockPath'])
->getMock();
$provider->method('getComposerLockPath')->willReturn($composerLockPath);
return $provider;
} }
public function testGetModules() public function testGetModules()
{ {
Config::modify()->set(VersionProvider::class, 'modules', [ Config::modify()->set(VersionProvider::class, 'modules', [
'silverstripe/mypackage' => 'My Package',
'silverstripe/somepackage' => 'Some Package', 'silverstripe/somepackage' => 'Some Package',
'silverstripe/hidden' => '', 'silverstripe/another' => 'Another',
'silverstripe/another' => 'Another' 'cwp/cwp-something' => 'CWP something',
]); ]);
$result = $this->getMockProvider()->getModules();
$result = $this->provider->getModules(); $this->assertArrayHasKey('silverstripe/mypackage', $result);
$this->assertArrayHasKey('silverstripe/somepackage', $result); $this->assertArrayHasKey('silverstripe/somepackage', $result);
$this->assertSame('Some Package', $result['silverstripe/somepackage']);
$this->assertArrayHasKey('silverstripe/another', $result); $this->assertArrayHasKey('silverstripe/another', $result);
$this->assertArrayNotHasKey('silverstripe/hidden', $result); $this->assertArrayHasKey('cwp/cwp-something', $result);
}
public function testGetModulesEmpty()
{
Config::modify()->set(VersionProvider::class, 'modules', []);
$this->assertEquals(
['silverstripe/framework' => 'Framework'],
$this->getMockProvider()->getModules()
);
}
public function testGetModulesNone()
{
Config::modify()->remove(VersionProvider::class, 'modules');
$this->assertEquals(
['silverstripe/framework' => 'Framework'],
$this->getMockProvider()->getModules()
);
} }
public function testGetModuleVersionFromComposer() public function testGetModuleVersionFromComposer()
{ {
Config::modify()->set(VersionProvider::class, 'modules', [ Config::modify()->set(VersionProvider::class, 'modules', [
'silverstripe/siteconfig' => 'SiteConfig',
'silverstripe/framework' => 'Framework', 'silverstripe/framework' => 'Framework',
'silverstripe/siteconfig' => 'SiteConfig'
]); ]);
$result = $this->provider->getModules(['silverstripe/framework']); $result = $this->getMockProvider()->getModules(['silverstripe/framework']);
$this->assertArrayHasKey('silverstripe/framework', $result); $this->assertArrayHasKey('silverstripe/framework', $result);
$this->assertNotEmpty($result['silverstripe/framework']); $this->assertNotEmpty($result['silverstripe/framework']);
} }
@ -49,14 +77,87 @@ class VersionProviderTest extends SapphireTest
public function testGetVersion() public function testGetVersion()
{ {
Config::modify()->set(VersionProvider::class, 'modules', [ Config::modify()->set(VersionProvider::class, 'modules', [
'silverstripe/framework' => 'Framework', 'silverstripe/siteconfig' => 'SiteConfig',
'silverstripe/siteconfig' => 'SiteConfig' 'silverstripe/framework' => 'Framework'
]); ]);
$result = $this->getMockProvider()->getVersion();
$result = $this->provider->getVersion(); $this->assertNotContains('SiteConfig: ', $result);
$this->assertContains('SiteConfig: ', $result);
$this->assertContains('Framework: ', $result); $this->assertContains('Framework: ', $result);
$this->assertContains(', ', $result); $this->assertNotContains(', ', $result);
}
public function testGetVersionNoRecipe()
{
// composer.lock file without silverstripe/recipe-core or silverstripe/recipe-cms
$provider = $this->getMockProvider(__DIR__ . '/fixtures/VersionProviderTest/composer.no-recipe.testlock');
Config::modify()->set(VersionProvider::class, 'modules', []);
$result = $provider->getVersion();
$this->assertContains('Framework: 1.2.3', $result);
Config::modify()->set(VersionProvider::class, 'modules', [
'silverstripe/framework' => 'Framework',
'silverstripe/recipe-core' => 'Core Recipe',
'silverstripe/cms' => 'CMS',
'silverstripe/recipe-cms' => 'CMS Recipe',
]);
$result = $provider->getVersion();
$this->assertNotContains('Framework: 1.2.3', $result);
$this->assertContains('CMS: 4.5.6', $result);
$this->assertNotContains('Core Recipe: 7.7.7', $result);
$this->assertNotContains('CMS Recipe: 8.8.8', $result);
}
public function testGetVersionRecipeCore()
{
// composer.lock file with silverstripe/recipe-core but not silverstripe/recipe-cms
$provider = $this->getMockProvider(__DIR__ . '/fixtures/VersionProviderTest/composer.recipe-core.testlock');
Config::modify()->set(VersionProvider::class, 'modules', [
'silverstripe/framework' => 'Framework',
'silverstripe/recipe-core' => 'Core Recipe',
'silverstripe/cms' => 'CMS',
'silverstripe/recipe-cms' => 'CMS Recipe',
]);
$result = $provider->getVersion();
$this->assertNotContains('Framework: 1.2.3', $result);
$this->assertNotContains('Core Recipe: 7.7.7', $result);
$this->assertContains('CMS: 4.5.6', $result);
$this->assertNotContains('CMS Recipe: 8.8.8', $result);
}
public function testGetVersionRecipeCmsCore()
{
// composer.lock file with silverstripe/recipe-core and silverstripe/recipe-cms
$path = __DIR__ . '/fixtures/VersionProviderTest/composer.recipe-cms-core-and-cwpcore.testlock';
$provider = $this->getMockProvider($path);
Config::modify()->set(VersionProvider::class, 'modules', [
'silverstripe/framework' => 'Framework',
'silverstripe/recipe-core' => 'Core Recipe',
'silverstripe/cms' => 'CMS',
'silverstripe/recipe-cms' => 'CMS Recipe',
]);
$result = $provider->getVersion();
$this->assertNotContains('Framework: 1.2.3', $result);
$this->assertNotContains('CMS: 4.5.6', $result);
$this->assertNotContains('Core Recipe: 7.7.7', $result);
$this->assertContains('CMS Recipe: 8.8.8', $result);
$this->assertNotContains('CWP: 9.9.9', $result);
Config::modify()->set(VersionProvider::class, 'modules', [
'silverstripe/framework' => 'Framework',
'silverstripe/recipe-core' => 'Core Recipe',
'silverstripe/cms' => 'CMS',
'silverstripe/recipe-cms' => 'CMS Recipe',
'cwp/cwp-core' => 'CWP',
]);
$result = $provider->getVersion();
$this->assertNotContains('Framework: 1.2.3', $result);
$this->assertNotContains('CMS: 4.5.6', $result);
$this->assertNotContains('Core Recipe: 7.7.7', $result);
$this->assertContains('CMS Recipe:', $result);
$this->assertContains('CWP: 9.9.9', $result);
} }
public function testGetModulesFromComposerLock() public function testGetModulesFromComposerLock()
@ -65,7 +166,7 @@ class VersionProviderTest extends SapphireTest
->setMethods(['getComposerLock']) ->setMethods(['getComposerLock'])
->getMock(); ->getMock();
$mock->expects($this->once()) $mock->expects($this->exactly(1))
->method('getComposerLock') ->method('getComposerLock')
->will($this->returnValue([ ->will($this->returnValue([
'packages' => [ 'packages' => [

View File

@ -0,0 +1,16 @@
{
"_readme": [
"This is a fixture file for unit tests"
],
"content-hash": "abc123",
"packages": [
{
"name": "silverstripe/framework",
"version": "1.2.3"
},
{
"name": "silverstripe/cms",
"version": "4.5.6"
}
]
}

View File

@ -0,0 +1,28 @@
{
"_readme": [
"This is a fixture file for unit tests"
],
"content-hash": "abc888",
"packages": [
{
"name": "silverstripe/framework",
"version": "1.2.3"
},
{
"name": "silverstripe/cms",
"version": "4.5.6"
},
{
"name": "silverstripe/recipe-core",
"version": "7.7.7"
},
{
"name": "silverstripe/recipe-cms",
"version": "8.8.8"
},
{
"name": "cwp/cwp-core",
"version": "9.9.9"
}
]
}

View File

@ -0,0 +1,20 @@
{
"_readme": [
"This is a fixture file for unit tests"
],
"content-hash": "abc777",
"packages": [
{
"name": "silverstripe/framework",
"version": "1.2.3"
},
{
"name": "silverstripe/cms",
"version": "4.5.6"
},
{
"name": "silverstripe/recipe-core",
"version": "7.7.7"
}
]
}