Skip to content

Commit

Permalink
Optimize the composer properties sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
kayw-geek committed Aug 21, 2024
1 parent 12fc9fe commit 4e27d48
Show file tree
Hide file tree
Showing 22 changed files with 1,677 additions and 84 deletions.
30 changes: 2 additions & 28 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection;
use Symplify\MonorepoBuilder\Config\MBConfig;
use Symplify\MonorepoBuilder\Console\MonorepoBuilderApplication;
use Symplify\MonorepoBuilder\Merge\JsonSchema;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker;
use Symplify\MonorepoBuilder\ValueObject\Option;
Expand Down Expand Up @@ -38,33 +38,7 @@

$mbConfig->packageAliasFormat('<major>.<minor>-dev');

$mbConfig->composerSectionOrder([
ComposerJsonSection::NAME,
ComposerJsonSection::TYPE,
ComposerJsonSection::DESCRIPTION,
ComposerJsonSection::KEYWORDS,
ComposerJsonSection::HOMEPAGE,
ComposerJsonSection::LICENSE,
ComposerJsonSection::AUTHORS,
ComposerJsonSection::SUPPORT,
ComposerJsonSection::FUNDING,
ComposerJsonSection::BIN,
ComposerJsonSection::REQUIRE,
ComposerJsonSection::REQUIRE_DEV,
ComposerJsonSection::AUTOLOAD,
ComposerJsonSection::AUTOLOAD_DEV,
ComposerJsonSection::REPOSITORIES,
ComposerJsonSection::PROVIDE,
ComposerJsonSection::CONFLICT,
ComposerJsonSection::REPLACE,
ComposerJsonSection::SCRIPTS,
ComposerJsonSection::SCRIPTS_DESCRIPTIONS,
ComposerJsonSection::SUGGEST,
ComposerJsonSection::CONFIG,
ComposerJsonSection::MINIMUM_STABILITY,
ComposerJsonSection::PREFER_STABLE,
ComposerJsonSection::EXTRA,
]);
$mbConfig->composerSectionOrder(JsonSchema::getProperties());

$services = $mbConfig->services();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ private function createComposerJson(): ComposerJson
$composerJsonFactory = $this->getService(ComposerJsonFactory::class);

return $composerJsonFactory->createFromArray([
'random-this' => [],
ComposerJsonSection::AUTOLOAD_DEV => [],
ComposerJsonSection::AUTOLOAD => [],
'random-that' => [],
ComposerJsonSection::REQUIRE_DEV => [],
ComposerJsonSection::REQUIRE => [],
'random-this' => ['foo'],
ComposerJsonSection::AUTOLOAD_DEV => ['foo'],
ComposerJsonSection::AUTOLOAD => ['bar'],
'random-that' => ['bar'],
ComposerJsonSection::REQUIRE_DEV => ['bar'],
ComposerJsonSection::REQUIRE => ['foo'],
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use Symplify\MonorepoBuilder\Tests\Merge\ComposerJsonDecorator\AbstractComposerJsonDecorator;
use Symplify\SmartFileSystem\SmartFileInfo;

final class ComposerJsonMerger extends AbstractComposerJsonDecorator
final class ComposerJsonMergerTest extends AbstractComposerJsonDecorator
{
private ComposerJsonMerger $composerJsonMerger;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/**
* @coversDefaultClass \Symplify\MonorepoBuilder\Merge\ComposerKeyMerger\MinimalStabilityKeyMerger
*/
final class MinimalStabilityKeyMerger extends AbstractComposerJsonDecorator
final class MinimalStabilityKeyMergerTest extends AbstractComposerJsonDecorator
{
#[DataProvider('provideData')]
public function testFixture(SmartFileInfo $fixtureFileInfo): void
Expand Down
3 changes: 2 additions & 1 deletion packages-tests/Merge/Package/AbstractMergeCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ protected function doTestDirectoryMergeToFile(
ComposerJson $expectedComposerJson
): void {
$fileInfos = $this->getFileInfosFromDirectory($directoryWithJsonFiles);
$mergedComposerJson = $this->composerJsonMerger->mergeFileInfos($fileInfos);
$mainComposerJson = $this->composerJsonFactory->createFromArray([]);
$mergedComposerJson = $this->composerJsonMerger->mergeFileInfos($mainComposerJson,$fileInfos);

$this->assertComposerJsonEquals($expectedComposerJson, $mergedComposerJson);
}
Expand Down
3 changes: 1 addition & 2 deletions packages/ComposerJsonManipulator/ComposerJsonFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,7 @@ public function createFromArray(array $jsonArray): ComposerJson
$composerJson->setSupport($jsonArray[ComposerJsonSection::SUPPORT]);
}

$orderedKeys = array_keys($jsonArray);
$composerJson->setOrderedKeys($orderedKeys);
$composerJson->setJsonKeys(array_keys($jsonArray));

return $composerJson;
}
Expand Down
44 changes: 18 additions & 26 deletions packages/ComposerJsonManipulator/ValueObject/ComposerJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,29 @@ final class ComposerJson
*/
private array $provide = [];

/**
* @var list<string>
*/
private array $jsonKeys = [];

public function __construct()
{
$this->composerPackageSorter = new ComposerPackageSorter();
}

public function setJsonKeys(array $jsonKeys): void
{
$this->jsonKeys = $jsonKeys;
}

/**
* @return list<string>
*/
public function getJsonKeys():array
{
return $this->jsonKeys;
}

public function setOriginalFileInfo(SmartFileInfo $fileInfo): void
{
$this->fileInfo = $fileInfo;
Expand Down Expand Up @@ -464,12 +482,10 @@ public function getJsonArray(): array

if ($this->minimumStability !== null) {
$array[ComposerJsonSection::MINIMUM_STABILITY] = $this->minimumStability;
$this->moveValueToBack(ComposerJsonSection::MINIMUM_STABILITY);
}

if ($this->preferStable !== null) {
$array[ComposerJsonSection::PREFER_STABLE] = $this->preferStable;
$this->moveValueToBack(ComposerJsonSection::PREFER_STABLE);
}

return $this->sortItemsByOrderedListOfKeys($array, $this->orderedKeys);
Expand Down Expand Up @@ -613,17 +629,6 @@ public function changePackageVersion(string $packageName, string $version): void
}
}

public function movePackageToRequire(string $packageName): void
{
if (! $this->hasRequiredDevPackage($packageName)) {
return;
}

$version = $this->requireDev[$packageName];
$this->removePackage($packageName);
$this->addRequiredPackage($packageName, $version);
}

public function movePackageToRequireDev(string $packageName): void
{
if (! $this->hasRequiredPackage($packageName)) {
Expand Down Expand Up @@ -831,19 +836,6 @@ public function setProvidePackage(string $packageName, string $version): void
$this->provide[$packageName] = $version;
}

/**
* @param ComposerJsonSection::* $valueName
*/
private function moveValueToBack(string $valueName): void
{
$key = array_search($valueName, $this->orderedKeys, true);
if ($key !== false) {
unset($this->orderedKeys[$key]);
}

$this->orderedKeys[] = $valueName;
}

/**
* 2. sort item by prescribed key order
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ public function createFromRootConfigAndPackageFileInfos(
ComposerJson $mainComposerJson,
array $packageFileInfos
): void {
$mergedAndDecoratedComposerJson = $this->mergePackageFileInfosAndDecorate($packageFileInfos);
$mergedAndDecoratedComposerJson = $this->mergePackageFileInfosAndDecorate($mainComposerJson,$packageFileInfos);

$this->composerJsonMerger->mergeJsonToRoot($mainComposerJson, $mergedAndDecoratedComposerJson);
}

/**
* @param SmartFileInfo[] $packageFileInfos
*/
private function mergePackageFileInfosAndDecorate(array $packageFileInfos): ComposerJson
private function mergePackageFileInfosAndDecorate(ComposerJson $mainComposerJson,array $packageFileInfos): ComposerJson
{
$mergedComposerJson = $this->composerJsonMerger->mergeFileInfos($packageFileInfos);
$mergedComposerJson = $this->composerJsonMerger->mergeFileInfos($mainComposerJson,$packageFileInfos);
foreach ($this->composerJsonDecorators as $composerJsonDecorator) {
$composerJsonDecorator->decorate($mergedComposerJson);
}
Expand Down
35 changes: 35 additions & 0 deletions packages/Merge/Arrays/ArraySorter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Symplify\MonorepoBuilder\Merge\Arrays;

use Symplify\MonorepoBuilder\Merge\JsonSchema;

final class ArraySorter
{
/**
Expand Down Expand Up @@ -31,6 +33,39 @@ public function recursiveSort(array $array): array
return $array;
}

/**
* @param mixed[] $orderedProperty
* @param mixed[] $array
* @return mixed[]
*/
public function recursiveSortBySchema(array $orderedProperty,array $array): array
{

if ($array === []) {
return $array;
}

if ($this->isSequential($array)) {
sort($array);
} else {
uksort($array,static function (string $key1, string $key2) use ($orderedProperty) : int {
if (!in_array($key1,$orderedProperty,true)){
return PHP_INT_MAX;
}

return array_search($key1,$orderedProperty,true) <=> array_search($key2,$orderedProperty,true);
});
}

foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = $this->recursiveSort($value);
}
}

return $array;
}

/**
* @param mixed[] $array
*/
Expand Down
28 changes: 23 additions & 5 deletions packages/Merge/Arrays/SortedParameterMerger.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Symplify\MonorepoBuilder\Merge\Arrays;

use Symplify\MonorepoBuilder\Merge\JsonSchema;
use Symplify\PackageBuilder\Yaml\ParametersMerger;

final class SortedParameterMerger
Expand All @@ -15,26 +16,43 @@ public function __construct(
}

/**
* @param string $composerPropertyName
* @param mixed[] $firstArray
* @param mixed[] $secondArray
* @return mixed[]
*/
public function mergeRecursiveAndSort(array $firstArray, array $secondArray): array
public function mergeRecursiveAndSort(string $composerPropertyName,array $firstArray, array $secondArray): array
{
$mergedArray = $this->parametersMerger->mergeWithCombine($firstArray, $secondArray);

return $this->arraySorter->recursiveSort($mergedArray);
return $this->recursiveSortBySchema($composerPropertyName,$mergedArray);
}

/**
* @param string $composerPropertyName
* @param mixed[] $mergedArray
*
* @return mixed[]
*/
private function recursiveSortBySchema(string $composerPropertyName,array $mergedArray): array
{
$propertyDefinitions = JsonSchema::getPropertyDefinitions($composerPropertyName);

if ($propertyDefinitions === []){
return $this->arraySorter->recursiveSort($mergedArray);
}

return $this->arraySorter->recursiveSortBySchema($propertyDefinitions,$mergedArray);
}
/**
* @param string $composerPropertyName
* @param mixed[] $firstArray
* @param mixed[] $secondArray
* @return mixed[]
*/
public function mergeAndSort(array $firstArray, array $secondArray): array
public function mergeAndSort(string $composerPropertyName, array $firstArray, array $secondArray): array
{
$mergedArray = $this->parametersMerger->merge($firstArray, $secondArray);

return $this->arraySorter->recursiveSort($mergedArray);
return $this->recursiveSortBySchema($composerPropertyName,$mergedArray);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function __construct(ParameterProvider $parameterProvider)

public function decorate(ComposerJson $composerJson): void
{
$orderedKeys = $composerJson->getOrderedKeys();
$orderedKeys = $composerJson->getJsonKeys();

usort(
$orderedKeys,
Expand Down
4 changes: 1 addition & 3 deletions packages/Merge/ComposerJsonMerger.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ public function __construct(
/**
* @param SmartFileInfo[] $composerPackagesFileInfos
*/
public function mergeFileInfos(array $composerPackagesFileInfos): ComposerJson
public function mergeFileInfos(ComposerJson $mainComposerJson,array $composerPackagesFileInfos): ComposerJson
{
$mainComposerJson = $this->composerJsonFactory->createFromArray([]);

foreach ($composerPackagesFileInfos as $composerPackageFileInfo) {
$packageComposerJson = $this->composerJsonFactory->createFromFileInfo($composerPackageFileInfo);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Symplify\MonorepoBuilder\Merge\ComposerKeyMerger;

use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJson;
use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection;
use Symplify\MonorepoBuilder\Merge\Arrays\SortedParameterMerger;
use Symplify\MonorepoBuilder\Merge\Contract\ComposerKeyMergerInterface;

Expand All @@ -21,7 +22,7 @@ public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJ
return;
}

$autoload = $this->sortedParameterMerger->mergeRecursiveAndSort(
$autoload = $this->sortedParameterMerger->mergeAndSort(ComposerJsonSection::AUTOLOAD,
$mainComposerJson->getAutoload(),
$newComposerJson->getAutoload()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Symplify\MonorepoBuilder\Merge\ComposerKeyMerger;

use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJson;
use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection;
use Symplify\MonorepoBuilder\Merge\Arrays\SortedParameterMerger;
use Symplify\MonorepoBuilder\Merge\Contract\ComposerKeyMergerInterface;

Expand All @@ -21,7 +22,7 @@ public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJ
return;
}

$autoloadDev = $this->sortedParameterMerger->mergeRecursiveAndSort(
$autoloadDev = $this->sortedParameterMerger->mergeRecursiveAndSort(ComposerJsonSection::AUTOLOAD_DEV,
$mainComposerJson->getAutoloadDev(),
$newComposerJson->getAutoloadDev()
);
Expand Down
3 changes: 2 additions & 1 deletion packages/Merge/ComposerKeyMerger/ExtraComposerKeyMerger.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Symplify\MonorepoBuilder\Merge\ComposerKeyMerger;

use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJson;
use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection;
use Symplify\MonorepoBuilder\Merge\Arrays\SortedParameterMerger;
use Symplify\MonorepoBuilder\Merge\Contract\ComposerKeyMergerInterface;

Expand Down Expand Up @@ -37,7 +38,7 @@ public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJ
}
}

$extra = $this->sortedParameterMerger->mergeRecursiveAndSort($mainComposerJson->getExtra(), $newComposerJsonExtra);
$extra = $this->sortedParameterMerger->mergeRecursiveAndSort(ComposerJsonSection::EXTRA,$mainComposerJson->getExtra(), $newComposerJsonExtra);

// do not merge extra alias as only for local packages
if (isset($extra['branch-alias'])) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJson;
use Symplify\MonorepoBuilder\Merge\Contract\ComposerKeyMergerInterface;

/**
* @see \Symplify\MonorepoBuilder\Tests\Merge\ComposerKeyMerger\MinimalStabilityKeyMergerTest
*/
final class MinimalStabilityKeyMerger implements ComposerKeyMergerInterface
{
public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void
Expand Down
Loading

0 comments on commit 4e27d48

Please sign in to comment.