diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 975282702..fe2a8787b 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -32,6 +32,7 @@ use Composer\Semver\Constraint\ConstraintInterface; use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\EmptyConstraint; use Composer\Util\Http\Response; +use Composer\Util\MetadataMinifier; /** * @author Jordi Boggiano @@ -631,30 +632,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $versions = $response['packages'][$realName]; if (isset($response['minified']) && $response['minified'] === 'composer/2.0') { - // TODO extract in other method - $expanded = array(); - $expandedVersion = null; - foreach ($versions as $versionData) { - if (!$expandedVersion) { - $expandedVersion = $versionData; - $expanded[] = $expandedVersion; - continue; - } - - // add any changes from the previous version to the expanded one - foreach ($versionData as $key => $val) { - if ($val === '__unset') { - unset($expandedVersion[$key]); - } else { - $expandedVersion[$key] = $val; - } - } - - $expanded[] = $expandedVersion; - } - - $versions = $expanded; - unset($expanded, $expandedVersion, $versionData); + $versions = MetadataMinifier::expand($versions); } $versionsToLoad = array(); diff --git a/src/Composer/Util/MetadataMinifier.php b/src/Composer/Util/MetadataMinifier.php new file mode 100644 index 000000000..669dab54b --- /dev/null +++ b/src/Composer/Util/MetadataMinifier.php @@ -0,0 +1,78 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Util; + +class MetadataMinifier +{ + public static function expand(array $versions) + { + $expanded = array(); + $expandedVersion = null; + foreach ($versions as $versionData) { + if (!$expandedVersion) { + $expandedVersion = $versionData; + $expanded[] = $expandedVersion; + continue; + } + + // add any changes from the previous version to the expanded one + foreach ($versionData as $key => $val) { + if ($val === '__unset') { + unset($expandedVersion[$key]); + } else { + $expandedVersion[$key] = $val; + } + } + + $expanded[] = $expandedVersion; + } + + return $expanded; + } + + public static function minify(array $versions) + { + $minifiedVersions = array(); + + $lastKnownVersionData = null; + foreach ($versions as $version) { + if (!$lastKnownVersionData) { + $lastKnownVersionData = $version; + $minifiedVersions[] = $version; + continue; + } + + $minifiedVersion = []; + + // add any changes from the previous version + foreach ($version as $key => $val) { + if (!isset($lastKnownVersionData[$key]) || $lastKnownVersionData[$key] !== $val) { + $minifiedVersion[$key] = $val; + $lastKnownVersionData[$key] = $val; + } + } + + // store any deletions from the previous version for keys missing in current one + foreach ($lastKnownVersionData as $key => $val) { + if (!isset($version[$key])) { + $minifiedVersion[$key] = "__unset"; + unset($lastKnownVersionData[$key]); + } + } + + $minifiedVersions[] = $minifiedVersion; + } + + return $minifiedVersions; + } +} diff --git a/tests/Composer/Test/Util/MetadataMinifierTest.php b/tests/Composer/Test/Util/MetadataMinifierTest.php new file mode 100644 index 000000000..ad8d3abad --- /dev/null +++ b/tests/Composer/Test/Util/MetadataMinifierTest.php @@ -0,0 +1,45 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Util; + +use Composer\Util\MetadataMinifier; +use Composer\Package\CompletePackage; +use Composer\Package\Dumper\ArrayDumper; +use PHPUnit\Framework\TestCase; + +class MetadataMinifierTest extends TestCase +{ + public function testMinifyExpand() + { + $package1 = new CompletePackage('foo/bar', '2.0.0.0', '2.0.0'); + $package1->setScripts(array('foo' => 'bar')); + $package1->setLicense(array('MIT')); + $package2 = new CompletePackage('foo/bar', '1.2.0.0', '1.2.0'); + $package2->setLicense(array('GPL')); + $package2->setHomepage('https://example.org'); + $package3 = new CompletePackage('foo/bar', '1.0.0.0', '1.0.0'); + $package3->setLicense(array('GPL')); + $dumper = new ArrayDumper(); + + $minified = array( + array('name' => 'foo/bar', 'version' => '2.0.0', 'version_normalized' => '2.0.0.0', 'type' => 'library', 'scripts' => array('foo' => 'bar'), 'license' => array('MIT')), + array('version' => '1.2.0', 'version_normalized' => '1.2.0.0', 'license' => array('GPL'), 'homepage' => 'https://example.org', 'scripts' => '__unset'), + array('version' => '1.0.0', 'version_normalized' => '1.0.0.0', 'homepage' => '__unset'), + ); + + $source = array($dumper->dump($package1), $dumper->dump($package2), $dumper->dump($package3)); + + $this->assertSame($minified, MetadataMinifier::minify($source)); + $this->assertSame($source, MetadataMinifier::expand($minified)); + } +}