mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #11157 from lekoala/patch-46
FIX use composer runtime api
This commit is contained in:
commit
4f3282bf2a
@ -23,6 +23,7 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
|
"composer-runtime-api": "^2.0",
|
||||||
"composer/installers": "^2.2",
|
"composer/installers": "^2.2",
|
||||||
"guzzlehttp/guzzle": "^7.5.0",
|
"guzzlehttp/guzzle": "^7.5.0",
|
||||||
"guzzlehttp/psr7": "^2.4.0",
|
"guzzlehttp/psr7": "^2.4.0",
|
||||||
@ -60,6 +61,7 @@
|
|||||||
"ext-xml": "*"
|
"ext-xml": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"composer/semver": "^3.4",
|
||||||
"phpunit/phpunit": "^9.6",
|
"phpunit/phpunit": "^9.6",
|
||||||
"silverstripe/versioned": "^2",
|
"silverstripe/versioned": "^2",
|
||||||
"squizlabs/php_codesniffer": "^3.7",
|
"squizlabs/php_codesniffer": "^3.7",
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
namespace SilverStripe\Core\Manifest;
|
namespace SilverStripe\Core\Manifest;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use SilverStripe\Core\Config\Config;
|
use Composer\InstalledVersions;
|
||||||
|
use SilverStripe\Dev\Deprecation;
|
||||||
use Psr\SimpleCache\CacheInterface;
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\Core\Config\Configurable;
|
use SilverStripe\Core\Config\Configurable;
|
||||||
use SilverStripe\Core\Injector\Injectable;
|
use SilverStripe\Core\Injector\Injectable;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The version provider will look up configured modules and examine the composer.lock file
|
* The version provider will look up configured modules and examine the composer.lock file
|
||||||
@ -30,7 +32,7 @@ class VersionProvider
|
|||||||
use Injectable;
|
use Injectable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array<string,string>
|
||||||
*/
|
*/
|
||||||
private static $modules = [
|
private static $modules = [
|
||||||
'silverstripe/framework' => 'Framework',
|
'silverstripe/framework' => 'Framework',
|
||||||
@ -50,10 +52,10 @@ class VersionProvider
|
|||||||
return $version;
|
return $version;
|
||||||
}
|
}
|
||||||
$modules = $this->getModules();
|
$modules = $this->getModules();
|
||||||
$lockModules = $this->getModuleVersionFromComposer(array_keys($modules ?? []));
|
$lockModules = $this->getModuleVersionFromComposer(array_keys($modules));
|
||||||
$moduleVersions = [];
|
$moduleVersions = [];
|
||||||
foreach ($modules as $module => $title) {
|
foreach ($modules as $module => $title) {
|
||||||
if (!array_key_exists($module, $lockModules ?? [])) {
|
if (!array_key_exists($module, $lockModules)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$version = $lockModules[$module];
|
$version = $lockModules[$module];
|
||||||
@ -145,14 +147,14 @@ class VersionProvider
|
|||||||
* cwp/cwp-core => ['CWP', '4.4.4']
|
* cwp/cwp-core => ['CWP', '4.4.4']
|
||||||
* ]
|
* ]
|
||||||
*
|
*
|
||||||
* @param array $modules
|
* @param array<string,array<int,string>> $modules
|
||||||
* @return array
|
* @return array<string,array<int,string>>
|
||||||
*/
|
*/
|
||||||
private function filterModules(array $modules)
|
private function filterModules(array $modules)
|
||||||
{
|
{
|
||||||
$accountModule = [];
|
$accountModule = [];
|
||||||
foreach ($modules as $module => $value) {
|
foreach ($modules as $module => $value) {
|
||||||
if (!preg_match('#^([a-z0-9\-]+)/([a-z0-9\-]+)$#', $module ?? '', $m)) {
|
if (!preg_match('#^([a-z0-9\-]+)/([a-z0-9\-]+)$#', $module, $m)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$account = $m[1];
|
$account = $m[1];
|
||||||
@ -169,7 +171,7 @@ class VersionProvider
|
|||||||
/**
|
/**
|
||||||
* Gets the configured core modules to use for the SilverStripe application version
|
* Gets the configured core modules to use for the SilverStripe application version
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array<string,string>
|
||||||
*/
|
*/
|
||||||
public function getModules()
|
public function getModules()
|
||||||
{
|
{
|
||||||
@ -180,19 +182,14 @@ class VersionProvider
|
|||||||
/**
|
/**
|
||||||
* 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<string> $modules
|
||||||
* @return array
|
* @return array<string|string>
|
||||||
*/
|
*/
|
||||||
public function getModuleVersionFromComposer($modules = [])
|
public function getModuleVersionFromComposer($modules = [])
|
||||||
{
|
{
|
||||||
$versions = [];
|
$versions = [];
|
||||||
$lockData = $this->getComposerLock();
|
foreach ($modules as $module) {
|
||||||
if ($lockData && !empty($lockData['packages'])) {
|
$versions[$module] = InstalledVersions::getPrettyVersion($module);
|
||||||
foreach ($lockData['packages'] as $package) {
|
|
||||||
if (in_array($package['name'], $modules ?? []) && isset($package['version'])) {
|
|
||||||
$versions[$package['name']] = $package['version'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return $versions;
|
return $versions;
|
||||||
}
|
}
|
||||||
@ -200,35 +197,40 @@ class VersionProvider
|
|||||||
/**
|
/**
|
||||||
* Load composer.lock's contents and return it
|
* Load composer.lock's contents and return it
|
||||||
*
|
*
|
||||||
|
* @deprecated 5.1 Has been replaced by composer-runtime-api
|
||||||
* @param bool $cache
|
* @param bool $cache
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function getComposerLock($cache = true)
|
protected function getComposerLock($cache = true)
|
||||||
{
|
{
|
||||||
|
Deprecation::notice("5.1", "Has been replaced by composer-runtime-api", Deprecation::SCOPE_METHOD);
|
||||||
$composerLockPath = $this->getComposerLockPath();
|
$composerLockPath = $this->getComposerLockPath();
|
||||||
if (!file_exists($composerLockPath ?? '')) {
|
if (!file_exists($composerLockPath)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$lockData = [];
|
$lockData = [];
|
||||||
$jsonData = file_get_contents($composerLockPath ?? '');
|
$jsonData = file_get_contents($composerLockPath);
|
||||||
|
$jsonData = $jsonData ? $jsonData : '';
|
||||||
|
$cacheKey = md5($jsonData);
|
||||||
|
|
||||||
if ($cache) {
|
if ($cache) {
|
||||||
$cache = Injector::inst()->get(CacheInterface::class . '.VersionProvider_composerlock');
|
$cache = Injector::inst()->get(CacheInterface::class . '.VersionProvider_composerlock');
|
||||||
$cacheKey = md5($jsonData ?? '');
|
|
||||||
if ($versions = $cache->get($cacheKey)) {
|
if ($versions = $cache->get($cacheKey)) {
|
||||||
$lockData = json_decode($versions ?? '', true);
|
$lockData = json_decode($versions, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($lockData) && $jsonData) {
|
if (empty($lockData) && $jsonData) {
|
||||||
$lockData = json_decode($jsonData ?? '', true);
|
$lockData = json_decode($jsonData, true);
|
||||||
|
|
||||||
if ($cache) {
|
if ($cache) {
|
||||||
$cache->set($cacheKey, $jsonData);
|
$cache->set($cacheKey, $jsonData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$lockData = $lockData ? $lockData : [];
|
||||||
|
|
||||||
return $lockData;
|
return $lockData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,16 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Core\Tests\Manifest;
|
namespace SilverStripe\Core\Tests\Manifest;
|
||||||
|
|
||||||
|
use SebastianBergmann\Version;
|
||||||
|
use Composer\Semver\VersionParser;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use Psr\SimpleCache\CacheInterface;
|
use Psr\SimpleCache\CacheInterface;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\Core\Manifest\VersionProvider;
|
use SilverStripe\Core\Manifest\VersionProvider;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
|
||||||
|
|
||||||
class VersionProviderTest extends SapphireTest
|
class VersionProviderTest extends SapphireTest
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var VersionProvider
|
* @var VersionProvider
|
||||||
*/
|
*/
|
||||||
@ -22,17 +23,9 @@ class VersionProviderTest extends SapphireTest
|
|||||||
$this->clearCache();
|
$this->clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMockProvider($composerLockPath = '')
|
public function getProvider()
|
||||||
{
|
{
|
||||||
if ($composerLockPath == '') {
|
$provider = Injector::inst()->get(VersionProvider::class);
|
||||||
// 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;
|
return $provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +37,7 @@ class VersionProviderTest extends SapphireTest
|
|||||||
'silverstripe/another' => 'Another',
|
'silverstripe/another' => 'Another',
|
||||||
'cwp/cwp-something' => 'CWP something',
|
'cwp/cwp-something' => 'CWP something',
|
||||||
]);
|
]);
|
||||||
$result = $this->getMockProvider()->getModules();
|
$result = $this->getProvider()->getModules();
|
||||||
$this->assertArrayHasKey('silverstripe/mypackage', $result);
|
$this->assertArrayHasKey('silverstripe/mypackage', $result);
|
||||||
$this->assertArrayHasKey('silverstripe/somepackage', $result);
|
$this->assertArrayHasKey('silverstripe/somepackage', $result);
|
||||||
$this->assertArrayHasKey('silverstripe/another', $result);
|
$this->assertArrayHasKey('silverstripe/another', $result);
|
||||||
@ -56,7 +49,7 @@ class VersionProviderTest extends SapphireTest
|
|||||||
Config::modify()->set(VersionProvider::class, 'modules', []);
|
Config::modify()->set(VersionProvider::class, 'modules', []);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
['silverstripe/framework' => 'Framework'],
|
['silverstripe/framework' => 'Framework'],
|
||||||
$this->getMockProvider()->getModules()
|
$this->getProvider()->getModules()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +58,7 @@ class VersionProviderTest extends SapphireTest
|
|||||||
Config::modify()->remove(VersionProvider::class, 'modules');
|
Config::modify()->remove(VersionProvider::class, 'modules');
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
['silverstripe/framework' => 'Framework'],
|
['silverstripe/framework' => 'Framework'],
|
||||||
$this->getMockProvider()->getModules()
|
$this->getProvider()->getModules()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +69,7 @@ class VersionProviderTest extends SapphireTest
|
|||||||
'silverstripe/framework' => 'Framework',
|
'silverstripe/framework' => 'Framework',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$result = $this->getMockProvider()->getModules(['silverstripe/framework']);
|
$result = $this->getProvider()->getModules(['silverstripe/framework']);
|
||||||
$this->assertArrayHasKey('silverstripe/framework', $result);
|
$this->assertArrayHasKey('silverstripe/framework', $result);
|
||||||
$this->assertNotEmpty($result['silverstripe/framework']);
|
$this->assertNotEmpty($result['silverstripe/framework']);
|
||||||
}
|
}
|
||||||
@ -87,131 +80,23 @@ class VersionProviderTest extends SapphireTest
|
|||||||
'silverstripe/siteconfig' => 'SiteConfig',
|
'silverstripe/siteconfig' => 'SiteConfig',
|
||||||
'silverstripe/framework' => 'Framework'
|
'silverstripe/framework' => 'Framework'
|
||||||
]);
|
]);
|
||||||
$result = $this->getMockProvider()->getVersion();
|
$result = $this->getProvider()->getVersion();
|
||||||
$this->assertStringNotContainsString('SiteConfig: ', $result);
|
$this->assertStringNotContainsString('SiteConfig: ', $result);
|
||||||
$this->assertStringContainsString('Framework: ', $result);
|
$this->assertStringContainsString('Framework: ', $result);
|
||||||
$this->assertStringNotContainsString(', ', $result);
|
$this->assertStringNotContainsString(', ', $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->assertStringContainsString('Framework: 1.2.3', $result);
|
|
||||||
|
|
||||||
$this->clearCache();
|
|
||||||
|
|
||||||
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->assertStringNotContainsString('Framework: 1.2.3', $result);
|
|
||||||
$this->assertStringContainsString('CMS: 4.5.6', $result);
|
|
||||||
$this->assertStringNotContainsString('Core Recipe: 7.7.7', $result);
|
|
||||||
$this->assertStringNotContainsString('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->assertStringNotContainsString('Framework: 1.2.3', $result);
|
|
||||||
$this->assertStringNotContainsString('Core Recipe: 7.7.7', $result);
|
|
||||||
$this->assertStringContainsString('CMS: 4.5.6', $result);
|
|
||||||
$this->assertStringNotContainsString('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->assertStringNotContainsString('Framework: 1.2.3', $result);
|
|
||||||
$this->assertStringNotContainsString('CMS: 4.5.6', $result);
|
|
||||||
$this->assertStringNotContainsString('Core Recipe: 7.7.7', $result);
|
|
||||||
$this->assertStringContainsString('CMS Recipe: 8.8.8', $result);
|
|
||||||
$this->assertStringNotContainsString('CWP: 9.9.9', $result);
|
|
||||||
|
|
||||||
$this->clearCache();
|
|
||||||
|
|
||||||
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->assertStringNotContainsString('Framework: 1.2.3', $result);
|
|
||||||
$this->assertStringNotContainsString('CMS: 4.5.6', $result);
|
|
||||||
$this->assertStringNotContainsString('Core Recipe: 7.7.7', $result);
|
|
||||||
$this->assertStringContainsString('CMS Recipe:', $result);
|
|
||||||
$this->assertStringContainsString('CWP: 9.9.9', $result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetModulesFromComposerLock()
|
|
||||||
{
|
|
||||||
$mock = $this->getMockBuilder(VersionProvider::class)
|
|
||||||
->setMethods(['getComposerLock'])
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$mock->expects($this->exactly(1))
|
|
||||||
->method('getComposerLock')
|
|
||||||
->will($this->returnValue([
|
|
||||||
'packages' => [
|
|
||||||
[
|
|
||||||
'name' => 'silverstripe/somepackage',
|
|
||||||
'version' => '1.2.3'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'name' => 'silverstripe/another',
|
|
||||||
'version' => '2.3.4'
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]));
|
|
||||||
|
|
||||||
Config::modify()->set(VersionProvider::class, 'modules', [
|
|
||||||
'silverstripe/somepackage' => 'Some Package'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$result = $mock->getVersion();
|
|
||||||
$this->assertStringContainsString('Some Package: 1.2.3', $result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetModuleVersion()
|
public function testGetModuleVersion()
|
||||||
{
|
{
|
||||||
$provider = $this->getMockProvider(__DIR__ . '/fixtures/VersionProviderTest/composer.recipe-core.testlock');
|
$provider = $this->getProvider();
|
||||||
Config::modify()->set(VersionProvider::class, 'modules', [
|
Config::modify()->set(VersionProvider::class, 'modules', [
|
||||||
'silverstripe/framework' => 'Framework',
|
'silverstripe/framework' => 'Framework',
|
||||||
'silverstripe/recipe-core' => 'Core Recipe'
|
|
||||||
]);
|
]);
|
||||||
$this->assertSame('1.2.3', $provider->getModuleVersion('silverstripe/framework'));
|
$moduleVersion = $provider->getModuleVersion('silverstripe/framework');
|
||||||
// assert that the temporary config changes in getModuleVersion() had no side-effects
|
$parser = new VersionParser();
|
||||||
|
$this->assertIsString($parser->normalize($moduleVersion), "Expected a valid semver but got $moduleVersion");
|
||||||
$result = $provider->getVersion();
|
$result = $provider->getVersion();
|
||||||
$this->assertStringNotContainsString('Framework: 1.2.3', $result);
|
$this->assertStringNotContainsString('Framework: 1.2.3', $result);
|
||||||
$this->assertStringContainsString('Core Recipe: 7.7.7', $result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function clearCache()
|
private function clearCache()
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"_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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"_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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"_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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user