1
0
Fork 0

Merge pull request #2188 from Danack/GetRootComposerJson

Find root composer.json in zip artifact more reliably.
pull/2737/head
Jordi Boggiano 2014-02-21 11:33:01 +01:00
commit eb3384445b
5 changed files with 86 additions and 1 deletions

View File

@ -74,6 +74,48 @@ class ArtifactRepository extends ArrayRepository
} }
} }
/**
* Find a file by name, returning the one that has the shortest path.
*
* @param \ZipArchive $zip
* @param $filename
* @return bool|int
*/
private function locateFile(\ZipArchive $zip, $filename) {
$indexOfShortestMatch = false;
$lengthOfShortestMatch = -1;
for ($i = 0; $i < $zip->numFiles; $i++ ){
$stat = $zip->statIndex($i);
if (strcmp(basename($stat['name']), $filename) === 0){
$directoryName = dirname($stat['name']);
if ($directoryName == '.') {
//if composer.json is in root directory
//it has to be the one to use.
return $i;
}
if(strpos($directoryName, '\\') !== false ||
strpos($directoryName, '/') !== false) {
//composer.json files below first directory are rejected
continue;
}
$length = strlen($stat['name']);
if ($indexOfShortestMatch == false || $length < $lengthOfShortestMatch) {
//Check it's not a directory.
$contents = $zip->getFromIndex($i);
if ($contents !== false) {
$indexOfShortestMatch = $i;
$lengthOfShortestMatch = $length;
}
}
}
}
return $indexOfShortestMatch;
}
private function getComposerInformation(\SplFileInfo $file) private function getComposerInformation(\SplFileInfo $file)
{ {
$zip = new \ZipArchive(); $zip = new \ZipArchive();
@ -83,7 +125,7 @@ class ArtifactRepository extends ArrayRepository
return false; return false;
} }
$foundFileIndex = $zip->locateName('composer.json', \ZipArchive::FL_NODIR); $foundFileIndex = $this->locateFile($zip, 'composer.json');
if (false === $foundFileIndex) { if (false === $foundFileIndex) {
return false; return false;
} }

View File

@ -26,6 +26,10 @@ class ArtifactRepositoryTest extends TestCase
'composer/composer-1.0.0-alpha6', 'composer/composer-1.0.0-alpha6',
'vendor1/package2-4.3.2', 'vendor1/package2-4.3.2',
'vendor3/package1-5.4.3', 'vendor3/package1-5.4.3',
'test/jsonInRoot-1.0.0',
'test/jsonInFirstLevel-1.0.0',
//The files not-an-artifact.zip and jsonSecondLevel are not valid
//artifacts and do not get detected.
); );
$coordinates = array('type' => 'artifact', 'url' => __DIR__ . '/Fixtures/artifacts'); $coordinates = array('type' => 'artifact', 'url' => __DIR__ . '/Fixtures/artifacts');
@ -41,3 +45,42 @@ class ArtifactRepositoryTest extends TestCase
$this->assertSame($expectedPackages, $foundPackages); $this->assertSame($expectedPackages, $foundPackages);
} }
} }
//Files jsonInFirstLevel.zip, jsonInRoot.zip and jsonInSecondLevel.zip were generated with:
//
//$archivesToCreate = array(
// 'jsonInRoot' => array(
// "extra.txt" => "Testing testing testing",
// "composer.json" => '{ "name": "test/jsonInRoot", "version": "1.0.0" }',
// "subdir/extra.txt" => "Testing testing testing",
// "subdir/extra2.txt" => "Testing testing testing",
// ),
//
// 'jsonInFirstLevel' => array(
// "extra.txt" => "Testing testing testing",
// "subdir/composer.json" => '{ "name": "test/jsonInFirstLevel", "version": "1.0.0" }',
// "subdir/extra.txt" => "Testing testing testing",
// "subdir/extra2.txt" => "Testing testing testing",
// ),
//
// 'jsonInSecondLevel' => array(
// "extra.txt" => "Testing testing testing",
// "subdir/extra1.txt" => "Testing testing testing",
// "subdir/foo/composer.json" => '{ "name": "test/jsonInSecondLevel", "version": "1.0.0" }',
// "subdir/foo/extra1.txt" => "Testing testing testing",
// "subdir/extra2.txt" => "Testing testing testing",
// "subdir/extra3.txt" => "Testing testing testing",
// ),
//);
//
//foreach($archivesToCreate as $archiveName => $fileDetails) {
// $zipFile = new ZipArchive();
// $zipFile->open("$archiveName.zip", ZIPARCHIVE::CREATE);
//
// foreach ($fileDetails as $filename => $fileContents) {
// $zipFile->addFromString($filename, $fileContents);
// }
//
// $zipFile->close();
//}