Skip to content

Instantly share code, notes, and snippets.

@beberlei
Created January 4, 2012 23:33
Show Gist options
  • Save beberlei/1562843 to your computer and use it in GitHub Desktop.
Save beberlei/1562843 to your computer and use it in GitHub Desktop.
Script to generate packages.json of PHPUnit + dependencies
<?php
/**
* Generates a package JSON that allows to install phpunit + dependencies
* from versions 3.5.12 up to now.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
*
* @example
*
* {
* "repositories": {
* "testing": {
* "composer": {
* "url": "http://localhost/"
* }
* },
* "packagist": false
* },
* "require": {
* "phpunit/phpunit": "3.5.15"
* }
* }
*
* Missing: There is no binary support here, since PHPUnit
* relies on the include path by default and I havent implemented
* a way to easily "guess" the shortest autoload path from
* the package.xml yet, you cannot use composers autoload.
*
* A solution would use set_include_path() for all the
* phpunit repos and then include vendor/phpunit/phpunit/phpunit.php
*
* <?php
* $path = __DIR__ . "/vendor/phpunit";
* foreach (scandir($path) as $file) {
* $file = $path . '/' . $file;
* if ($file != "." && $file != ".." && is_dir($file)) {
* set_include_path(get_include_path() . PATH_SEPARATOR . realpath($file));
* }
* }
* require_once $path ."/phpunit/phpunit.php";
*/
$tagsUrl = "https://api.github.com/repos/%s/tags";
$packagesXmlUrl = "https://raw.github.com/%s/%s/package.xml";
$repositoryUrl = "https://github.com/%s";
$downloadUrl = "http://github.com/%s/zipball/%s";
$repositories = array(
"PHPUnit" => "sebastianbergmann/phpunit",
"PHP_CodeCoverage" => "sebastianbergmann/php-code-coverage",
"PHP_Timer" => "sebastianbergmann/php-timer",
"DbUnit" => "sebastianbergmann/dbunit",
"PHP_TokenStream" => "sebastianbergmann/php-token-stream",
"Text_Template" => "sebastianbergmann/php-text-template",
"PHPUnit_MockObject" => "sebastianbergmann/phpunit-mock-objects",
"File_Iterator" => "sebastianbergmann/php-file-iterator",
);
$packages = array();
foreach ($repositories as $packageName => $repository) {
$tagUrl = sprintf($tagsUrl, $repository);
$data = json_decode(file_get_contents($tagUrl), true);
$package = array(
"type" => "library",
"repository" => sprintf($repositoryUrl, $repository),
"name" => 'phpunit/'.strtolower($packageName),
"versions" => array(),
);
foreach ($data as $version) {
$packageXmlUrl = sprintf($packagesXmlUrl, $repository, $version['commit']['sha']);
$versionName = $version['name'];
$xml = file_get_contents($packageXmlUrl);
if ($packageName == "PHPUnit" && version_compare($versionName, "3.5.12") < 0) {
continue;
}
$packageVersion = array(
'name' => 'phpunit/' . strtolower($packageName),
'dist' => array(
'url' => sprintf($downloadUrl, $repository, $versionName),
'type' => 'zip',
),
'type' => 'library',
'version' => $versionName,
);
$dom = new DOMDocument("1.0", "UTF-8");
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$rootNamespace = $dom->lookupNamespaceUri($dom->namespaceURI);
$xpath->registerNamespace('x', $rootNamespace);
foreach ($xpath->evaluate("//x:dependencies/x:required/x:package") as $dependency) {
$dependency = array(
'name' => getSingleSubNodeValue($dependency, 'name'),
'version' => getSingleSubNodeValue($dependency, 'min'),
);
if (isset($repositories[$dependency['name']])) {
$packageVersion['require']['phpunit/'.strtolower($dependency['name'])] = '=' . $dependency['version']; // TODO: Maybe use = instead of >=?
}
}
$package['versions'][] = $packageVersion;
}
$packages["phpunit/".strtolower($packageName)] = $package;
}
echo json_encode($packages);
function getSingleSubNodeValue($el, $name)
{
return $el->getElementsByTagName($name)->item(0)->nodeValue;
}
@beberlei
Copy link
Author

beberlei commented Jan 4, 2012

This is not working yet, just wanted to get it out there.

@edorian
Copy link

edorian commented Jan 5, 2012

Thanks for sharing. That an a .phar should get rid of pear for pretty much anyone that doesn't want to deal with pear :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment