Merge remote branch 'composer/master'
Conflicts: src/Composer/Downloader/FileDownloader.phppull/293/head
commit
2e3eed081a
|
@ -2,4 +2,5 @@
|
|||
/.project
|
||||
/.buildpath
|
||||
/composer.phar
|
||||
/vendor
|
||||
/vendor
|
||||
/nbproject
|
||||
|
|
|
@ -12,8 +12,9 @@ Installation / Usage
|
|||
|
||||
1. Download the [`composer.phar`](http://getcomposer.org/composer.phar) executable or use the installer.
|
||||
|
||||
|
||||
``` sh
|
||||
$ curl -s http://getcomposer.org/installer | php
|
||||
```
|
||||
|
||||
|
||||
2. Create a composer.json defining your dependencies. Note that this example is
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
{
|
||||
"hash": "9c243b2c15fdc7c3e35c5200d704ba53",
|
||||
"packages": [
|
||||
{
|
||||
"package": "symfony\/process",
|
||||
"version": "2.1.0-dev"
|
||||
},
|
||||
{
|
||||
"package": "symfony\/finder",
|
||||
"version": "2.1.0-dev"
|
||||
|
@ -8,10 +12,6 @@
|
|||
{
|
||||
"package": "symfony\/console",
|
||||
"version": "2.1.0-dev"
|
||||
},
|
||||
{
|
||||
"package": "symfony\/process",
|
||||
"version": "2.1.0-dev"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -46,7 +46,7 @@ class InstallCommand extends Command
|
|||
->setName('install')
|
||||
->setDescription('Parses the composer.json file and downloads the needed dependencies.')
|
||||
->setDefinition(array(
|
||||
new InputOption('dev', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
||||
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
||||
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
|
||||
new InputOption('no-install-recommends', null, InputOption::VALUE_NONE, 'Do not install recommended packages (ignored when installing from an existing lock file).'),
|
||||
new InputOption('install-suggests', null, InputOption::VALUE_NONE, 'Also install suggested packages (ignored when installing from an existing lock file).'),
|
||||
|
@ -73,7 +73,7 @@ EOT
|
|||
$io,
|
||||
$composer,
|
||||
$eventDispatcher,
|
||||
(Boolean)$input->getOption('dev'),
|
||||
(Boolean)$input->getOption('prefer-source'),
|
||||
(Boolean)$input->getOption('dry-run'),
|
||||
(Boolean)$input->getOption('verbose'),
|
||||
(Boolean)$input->getOption('no-install-recommends'),
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
namespace Composer\Command;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Util\StreamContextFactory;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
|
@ -39,7 +40,9 @@ EOT
|
|||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$latest = trim(file_get_contents('http://getcomposer.org/version'));
|
||||
$ctx = StreamContextFactory::getContext();
|
||||
|
||||
$latest = trim(file_get_contents('http://getcomposer.org/version'), false, $ctx);
|
||||
|
||||
if (Composer::VERSION !== $latest) {
|
||||
$output->writeln(sprintf("Updating to version <info>%s</info>.", $latest));
|
||||
|
@ -47,7 +50,7 @@ EOT
|
|||
$remoteFilename = 'http://getcomposer.org/composer.phar';
|
||||
$localFilename = $_SERVER['argv'][0];
|
||||
|
||||
file_put_contents($localFilename, file_get_contents($remoteFilename));
|
||||
copy($remoteFilename, $localFilename, $ctx);
|
||||
} else {
|
||||
$output->writeln("<info>You are using the latest composer version.</info>");
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class UpdateCommand extends Command
|
|||
->setName('update')
|
||||
->setDescription('Updates your dependencies to the latest version, and updates the composer.lock file.')
|
||||
->setDefinition(array(
|
||||
new InputOption('dev', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
||||
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
||||
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
|
||||
new InputOption('no-install-recommends', null, InputOption::VALUE_NONE, 'Do not install recommended packages.'),
|
||||
new InputOption('install-suggests', null, InputOption::VALUE_NONE, 'Also install suggested packages.'),
|
||||
|
@ -63,7 +63,7 @@ EOT
|
|||
$io,
|
||||
$composer,
|
||||
$eventDispatcher,
|
||||
(Boolean)$input->getOption('dev'),
|
||||
(Boolean)$input->getOption('prefer-source'),
|
||||
(Boolean)$input->getOption('dry-run'),
|
||||
(Boolean)$input->getOption('verbose'),
|
||||
(Boolean)$input->getOption('no-install-recommends'),
|
||||
|
|
|
@ -79,7 +79,8 @@ class Compiler
|
|||
|
||||
$phar->stopBuffering();
|
||||
|
||||
$phar->compressFiles(\Phar::GZ);
|
||||
// disabled for interoperability with systems without gzip ext
|
||||
// $phar->compressFiles(\Phar::GZ);
|
||||
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../LICENSE'), false);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Composer\Json;
|
|||
|
||||
use Composer\Repository\RepositoryManager;
|
||||
use Composer\Composer;
|
||||
use Composer\Util\StreamContextFactory;
|
||||
|
||||
/**
|
||||
* Reads/writes json files.
|
||||
|
@ -59,11 +60,12 @@ class JsonFile
|
|||
*/
|
||||
public function read()
|
||||
{
|
||||
$context = stream_context_create(array(
|
||||
'http' => array('header' => 'User-Agent: Composer/'.Composer::VERSION."\r\n")
|
||||
));
|
||||
$ctx = StreamContextFactory::getContext(array(
|
||||
'http' => array(
|
||||
'header' => 'User-Agent: Composer/'.Composer::VERSION."\r\n"
|
||||
)));
|
||||
|
||||
$json = file_get_contents($this->path, false, $context);
|
||||
$json = file_get_contents($this->path, false, $ctx);
|
||||
if (!$json) {
|
||||
throw new \RuntimeException('Could not read '.$this->path.', you are probably offline');
|
||||
}
|
||||
|
@ -76,8 +78,9 @@ class JsonFile
|
|||
*
|
||||
* @param array $hash writes hash into json file
|
||||
* @param Boolean $prettyPrint If true, output is pretty-printed
|
||||
* @param Boolean $unescapeUnicode If true, unicode chars in output are unescaped
|
||||
*/
|
||||
public function write(array $hash, $prettyPrint = true)
|
||||
public function write(array $hash, $prettyPrint = true, $unescapeUnicode = true)
|
||||
{
|
||||
$dir = dirname($this->path);
|
||||
if (!is_dir($dir)) {
|
||||
|
@ -92,7 +95,7 @@ class JsonFile
|
|||
);
|
||||
}
|
||||
}
|
||||
file_put_contents($this->path, static::encode($hash, $prettyPrint));
|
||||
file_put_contents($this->path, static::encode($hash, $prettyPrint, $unescapeUnicode));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,17 +106,23 @@ class JsonFile
|
|||
*
|
||||
* @param array $hash Data to encode into a formatted JSON string
|
||||
* @param Boolean $prettyPrint If true, output is pretty-printed
|
||||
* @param Boolean $unescapeUnicode If true, unicode chars in output are unescaped
|
||||
* @return string Indented version of the original JSON string
|
||||
*/
|
||||
static public function encode(array $hash, $prettyPrint = true)
|
||||
static public function encode(array $hash, $prettyPrint = true, $unescapeUnicode = true)
|
||||
{
|
||||
if ($prettyPrint && defined('JSON_PRETTY_PRINT')) {
|
||||
return json_encode($hash, JSON_PRETTY_PRINT);
|
||||
if (version_compare(PHP_VERSION, '5.4', '>=')) {
|
||||
$options = $prettyPrint ? JSON_PRETTY_PRINT : 0;
|
||||
if ($unescapeUnicode) {
|
||||
$options |= JSON_UNESCAPED_UNICODE;
|
||||
}
|
||||
|
||||
return json_encode($hash, $options);
|
||||
}
|
||||
|
||||
$json = json_encode($hash);
|
||||
|
||||
if (!$prettyPrint) {
|
||||
if (!$prettyPrint && !$unescapeUnicode) {
|
||||
return $json;
|
||||
}
|
||||
|
||||
|
@ -122,21 +131,43 @@ class JsonFile
|
|||
$strLen = strlen($json);
|
||||
$indentStr = ' ';
|
||||
$newLine = "\n";
|
||||
$prevChar = '';
|
||||
$outOfQuotes = true;
|
||||
$buffer = '';
|
||||
$noescape = true;
|
||||
|
||||
for ($i = 0; $i <= $strLen; $i++) {
|
||||
// Grab the next character in the string
|
||||
$char = substr($json, $i, 1);
|
||||
|
||||
// Are we inside a quoted string?
|
||||
if ('"' === $char && ('\\' !== $prevChar || '\\\\' === substr($json, $i-2, 2))) {
|
||||
if ('"' === $char && $noescape) {
|
||||
$outOfQuotes = !$outOfQuotes;
|
||||
} elseif (':' === $char && $outOfQuotes) {
|
||||
}
|
||||
|
||||
if (!$outOfQuotes) {
|
||||
$buffer .= $char;
|
||||
$noescape = '\\' === $char ? !$noescape : true;
|
||||
continue;
|
||||
} elseif ('' !== $buffer) {
|
||||
if ($unescapeUnicode && function_exists('mb_convert_encoding')) {
|
||||
// http://stackoverflow.com/questions/2934563/how-to-decode-unicode-escape-sequences-like-u00ed-to-proper-utf-8-encoded-cha
|
||||
$result .= preg_replace_callback('/\\\\u([0-9a-f]{4})/i', function($match) {
|
||||
return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
|
||||
}, $buffer.$char);
|
||||
} else {
|
||||
$result .= $buffer.$char;
|
||||
}
|
||||
|
||||
$buffer = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (':' === $char) {
|
||||
// Add a space after the : character
|
||||
$char .= ' ';
|
||||
} elseif (('}' === $char || ']' === $char) && $outOfQuotes) {
|
||||
} elseif (('}' === $char || ']' === $char)) {
|
||||
$pos--;
|
||||
$prevChar = substr($json, $i - 1, 1);
|
||||
|
||||
if ('{' !== $prevChar && '[' !== $prevChar) {
|
||||
// If this character is the end of an element,
|
||||
|
@ -151,12 +182,11 @@ class JsonFile
|
|||
}
|
||||
}
|
||||
|
||||
// Add the character to the result string
|
||||
$result .= $char;
|
||||
|
||||
// If the last character was the beginning of an element,
|
||||
// output a new line and indent the next line
|
||||
if ((',' === $char || '{' === $char || '[' === $char) && $outOfQuotes) {
|
||||
if (',' === $char || '{' === $char || '[' === $char) {
|
||||
$result .= $newLine;
|
||||
|
||||
if ('{' === $char || '[' === $char) {
|
||||
|
@ -167,8 +197,6 @@ class JsonFile
|
|||
$result .= $indentStr;
|
||||
}
|
||||
}
|
||||
|
||||
$prevChar = $char;
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
|
|
@ -24,11 +24,16 @@ class ArrayDumper
|
|||
{
|
||||
$keys = array(
|
||||
'binaries' => 'bin',
|
||||
'scripts',
|
||||
'type',
|
||||
'names',
|
||||
'extra',
|
||||
'installationSource' => 'installation-source',
|
||||
'license',
|
||||
'authors',
|
||||
'description',
|
||||
'homepage',
|
||||
'keywords',
|
||||
'autoload',
|
||||
'repositories',
|
||||
);
|
||||
|
@ -41,6 +46,10 @@ class ArrayDumper
|
|||
$data['target-dir'] = $package->getTargetDir();
|
||||
}
|
||||
|
||||
if ($package->getReleaseDate()) {
|
||||
$data['time'] = $package->getReleaseDate()->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
if ($package->getSourceType()) {
|
||||
$data['source']['type'] = $package->getSourceType();
|
||||
$data['source']['url'] = $package->getSourceUrl();
|
||||
|
|
|
@ -438,7 +438,7 @@ class MemoryPackage extends BasePackage
|
|||
*
|
||||
* @param DateTime $releaseDate
|
||||
*/
|
||||
public function setReleasedate(\DateTime $releaseDate)
|
||||
public function setReleaseDate(\DateTime $releaseDate)
|
||||
{
|
||||
$this->releaseDate = $releaseDate;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
namespace Composer\Repository;
|
||||
|
||||
use Composer\Package\Loader\ArrayLoader;
|
||||
use Composer\Util\StreamContextFactory;
|
||||
|
||||
/**
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
|
@ -20,7 +21,8 @@ use Composer\Package\Loader\ArrayLoader;
|
|||
*/
|
||||
class PearRepository extends ArrayRepository
|
||||
{
|
||||
protected $url;
|
||||
private $url;
|
||||
private $streamContext;
|
||||
|
||||
public function __construct(array $config)
|
||||
{
|
||||
|
@ -31,7 +33,7 @@ class PearRepository extends ArrayRepository
|
|||
throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$config['url']);
|
||||
}
|
||||
|
||||
$this->url = $config['url'];
|
||||
$this->url = rtrim($config['url'], '/');
|
||||
}
|
||||
|
||||
protected function initialize()
|
||||
|
@ -41,6 +43,7 @@ class PearRepository extends ArrayRepository
|
|||
set_error_handler(function($severity, $message, $file, $line) {
|
||||
throw new \ErrorException($message, $severity, $severity, $file, $line);
|
||||
});
|
||||
$this->streamContext = StreamContextFactory::getContext();
|
||||
$this->fetchFromServer();
|
||||
restore_error_handler();
|
||||
}
|
||||
|
@ -51,24 +54,62 @@ class PearRepository extends ArrayRepository
|
|||
$categories = $categoryXML->getElementsByTagName("c");
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$categoryLink = $category->getAttribute("xlink:href");
|
||||
$categoryLink = str_replace("info.xml", "packages.xml", $categoryLink);
|
||||
if ('/' !== substr($categoryLink, 0, 1)) {
|
||||
$categoryLink = '/' . $categoryLink;
|
||||
$link = '/' . ltrim($category->getAttribute("xlink:href"), '/');
|
||||
try {
|
||||
$packagesLink = str_replace("info.xml", "packagesinfo.xml", $link);
|
||||
$this->fetchPear2Packages($this->url . $packagesLink);
|
||||
} catch (\ErrorException $e) {
|
||||
if (false === strpos($e->getMessage(), '404')) {
|
||||
throw $e;
|
||||
}
|
||||
$categoryLink = str_replace("info.xml", "packages.xml", $link);
|
||||
$this->fetchPearPackages($this->url . $categoryLink);
|
||||
}
|
||||
$packagesXML = $this->requestXml($this->url . $categoryLink);
|
||||
|
||||
$packages = $packagesXML->getElementsByTagName('p');
|
||||
$loader = new ArrayLoader();
|
||||
foreach ($packages as $package) {
|
||||
$packageName = $package->nodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
$packageLink = $package->getAttribute('xlink:href');
|
||||
$releaseLink = $this->url . str_replace("/rest/p/", "/rest/r/", $packageLink);
|
||||
$allReleasesLink = $releaseLink . "/allreleases2.xml";
|
||||
/**
|
||||
* @param string $categoryLink
|
||||
* @throws ErrorException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function fetchPearPackages($categoryLink)
|
||||
{
|
||||
$packagesXML = $this->requestXml($categoryLink);
|
||||
$packages = $packagesXML->getElementsByTagName('p');
|
||||
$loader = new ArrayLoader();
|
||||
foreach ($packages as $package) {
|
||||
$packageName = $package->nodeValue;
|
||||
|
||||
$packageLink = $package->getAttribute('xlink:href');
|
||||
$releaseLink = $this->url . str_replace("/rest/p/", "/rest/r/", $packageLink);
|
||||
$allReleasesLink = $releaseLink . "/allreleases2.xml";
|
||||
|
||||
try {
|
||||
$releasesXML = $this->requestXml($allReleasesLink);
|
||||
} catch (\ErrorException $e) {
|
||||
if (strpos($e->getMessage(), '404')) {
|
||||
continue;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$releases = $releasesXML->getElementsByTagName('r');
|
||||
|
||||
foreach ($releases as $release) {
|
||||
/* @var $release \DOMElement */
|
||||
$pearVersion = $release->getElementsByTagName('v')->item(0)->nodeValue;
|
||||
|
||||
$packageData = array(
|
||||
'name' => $packageName,
|
||||
'type' => 'library',
|
||||
'dist' => array('type' => 'pear', 'url' => $this->url.'/get/'.$packageName.'-'.$pearVersion.".tgz"),
|
||||
'version' => $pearVersion,
|
||||
);
|
||||
|
||||
try {
|
||||
$releasesXML = $this->requestXml($allReleasesLink);
|
||||
$deps = file_get_contents($releaseLink . "/deps.".$pearVersion.".txt", false, $this->streamContext);
|
||||
} catch (\ErrorException $e) {
|
||||
if (strpos($e->getMessage(), '404')) {
|
||||
continue;
|
||||
|
@ -76,54 +117,155 @@ class PearRepository extends ArrayRepository
|
|||
throw $e;
|
||||
}
|
||||
|
||||
$releases = $releasesXML->getElementsByTagName('r');
|
||||
$packageData += $this->parseDependencies($deps);
|
||||
|
||||
foreach ($releases as $release) {
|
||||
/* @var $release DOMElement */
|
||||
$pearVersion = $release->getElementsByTagName('v')->item(0)->nodeValue;
|
||||
try {
|
||||
$this->addPackage($loader->load($packageData));
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$packageData = array(
|
||||
'name' => $packageName,
|
||||
'type' => 'library',
|
||||
'dist' => array('type' => 'pear', 'url' => $this->url.'/get/'.$packageName.'-'.$pearVersion.".tgz"),
|
||||
'version' => $pearVersion,
|
||||
/**
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
private function parseVersion(array $data)
|
||||
{
|
||||
if (!isset($data['min']) && !isset($data['max'])) {
|
||||
return '*';
|
||||
}
|
||||
$versions = array();
|
||||
if (isset($data['min'])) {
|
||||
$versions[] = '>=' . $data['min'];
|
||||
}
|
||||
if (isset($data['max'])) {
|
||||
$versions[] = '<=' . $data['max'];
|
||||
}
|
||||
return implode(',', $versions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Improve dependencies resolution of pear packages.
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
private function parseDependenciesOptions(array $depsOptions)
|
||||
{
|
||||
$data = array();
|
||||
foreach ($depsOptions as $name => $options) {
|
||||
// make sure single deps are wrapped in an array
|
||||
if (isset($options['name'])) {
|
||||
$options = array($options);
|
||||
}
|
||||
if ('php' == $name) {
|
||||
$data[$name] = $this->parseVersion($options);
|
||||
} elseif ('package' == $name) {
|
||||
foreach ($options as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$dataKey = $value['name'];
|
||||
$data[$dataKey] = $this->parseVersion($value);
|
||||
}
|
||||
}
|
||||
} elseif ('extension' == $name) {
|
||||
foreach ($options as $key => $value) {
|
||||
$dataKey = 'ext-' . $value['name'];
|
||||
$data[$dataKey] = $this->parseVersion($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $deps
|
||||
* @return array
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function parseDependencies($deps)
|
||||
{
|
||||
if (preg_match('((O:([0-9])+:"([^"]+)"))', $deps, $matches)) {
|
||||
if (strlen($matches[3]) == $matches[2]) {
|
||||
throw new \InvalidArgumentException("Invalid dependency data, it contains serialized objects.");
|
||||
}
|
||||
}
|
||||
$deps = (array) @unserialize($deps);
|
||||
unset($deps['required']['pearinstaller']);
|
||||
|
||||
$depsData = array();
|
||||
if (!empty($deps['required'])) {
|
||||
$depsData['require'] = $this->parseDependenciesOptions($deps['required']);
|
||||
}
|
||||
|
||||
if (!empty($deps['optional'])) {
|
||||
$depsData['suggest'] = $this->parseDependenciesOptions($deps['optional']);
|
||||
}
|
||||
|
||||
return $depsData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packagesLink
|
||||
* @return void
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function fetchPear2Packages($packagesLink)
|
||||
{
|
||||
$loader = new ArrayLoader();
|
||||
$packagesXml = $this->requestXml($packagesLink);
|
||||
$informations = $packagesXml->getElementsByTagName('pi');
|
||||
foreach ($informations as $information) {
|
||||
$package = $information->getElementsByTagName('p')->item(0);
|
||||
|
||||
$packageName = $package->getElementsByTagName('n')->item(0)->nodeValue;
|
||||
$packageData = array(
|
||||
'name' => $packageName,
|
||||
'type' => 'library'
|
||||
);
|
||||
$packageKeys = array('l' => 'license', 'd' => 'description');
|
||||
foreach ($packageKeys as $pear => $composer) {
|
||||
if ($package->getElementsByTagName($pear)->length > 0
|
||||
&& ($pear = $package->getElementsByTagName($pear)->item(0)->nodeValue)) {
|
||||
$packageData[$composer] = $pear;
|
||||
}
|
||||
}
|
||||
|
||||
$depsData = array();
|
||||
foreach ($information->getElementsByTagName('deps') as $depElement) {
|
||||
$depsVersion = $depElement->getElementsByTagName('v')->item(0)->nodeValue;
|
||||
$depsData[$depsVersion] = $this->parseDependencies(
|
||||
$depElement->getElementsByTagName('d')->item(0)->nodeValue
|
||||
);
|
||||
}
|
||||
|
||||
$releases = $information->getElementsByTagName('a')->item(0);
|
||||
if (!$releases) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$releases = $releases->getElementsByTagName('r');
|
||||
$packageUrl = $this->url . '/get/' . $packageName;
|
||||
foreach ($releases as $release) {
|
||||
$version = $release->getElementsByTagName('v')->item(0)->nodeValue;
|
||||
$releaseData = array(
|
||||
'dist' => array(
|
||||
'type' => 'pear',
|
||||
'url' => $packageUrl . '-' . $version . '.tgz'
|
||||
),
|
||||
'version' => $version
|
||||
);
|
||||
if (isset($depsData[$version])) {
|
||||
$releaseData += $depsData[$version];
|
||||
}
|
||||
|
||||
try {
|
||||
$this->addPackage(
|
||||
$loader->load($packageData + $releaseData)
|
||||
);
|
||||
|
||||
try {
|
||||
$deps = file_get_contents($releaseLink . "/deps.".$pearVersion.".txt");
|
||||
} catch (\ErrorException $e) {
|
||||
if (strpos($e->getMessage(), '404')) {
|
||||
continue;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (preg_match('((O:([0-9])+:"([^"]+)"))', $deps, $matches)) {
|
||||
if (strlen($matches[3]) == $matches[2]) {
|
||||
throw new \InvalidArgumentException("Invalid dependency data, it contains serialized objects.");
|
||||
}
|
||||
}
|
||||
$deps = unserialize($deps);
|
||||
if (isset($deps['required']['package'])) {
|
||||
|
||||
if (isset($deps['required']['package']['name'])) {
|
||||
$deps['required']['package'] = array($deps['required']['package']);
|
||||
}
|
||||
|
||||
foreach ($deps['required']['package'] as $dependency) {
|
||||
if (isset($dependency['min'])) {
|
||||
$packageData['require'][$dependency['name']] = '>='.$dependency['min'];
|
||||
} else {
|
||||
$packageData['require'][$dependency['name']] = '>=0.0.0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->addPackage($loader->load($packageData));
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
continue;
|
||||
}
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +277,7 @@ class PearRepository extends ArrayRepository
|
|||
*/
|
||||
private function requestXml($url)
|
||||
{
|
||||
$content = file_get_contents($url);
|
||||
$content = file_get_contents($url, false, $this->streamContext);
|
||||
if (!$content) {
|
||||
throw new \UnexpectedValueException('The PEAR channel at '.$url.' did not respond.');
|
||||
}
|
||||
|
|
|
@ -87,37 +87,20 @@ class RemoteFilesystem
|
|||
$this->fileName = $fileName;
|
||||
$this->progress = $progess;
|
||||
|
||||
// Handle system proxy
|
||||
$params = array('http' => array());
|
||||
|
||||
if (isset($_SERVER['HTTP_PROXY'])) {
|
||||
// http(s):// is not supported in proxy
|
||||
$proxy = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $_SERVER['HTTP_PROXY']);
|
||||
|
||||
if (0 === strpos($proxy, 'ssl:') && !extension_loaded('openssl')) {
|
||||
throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
|
||||
}
|
||||
|
||||
$params['http'] = array(
|
||||
'proxy' => $proxy,
|
||||
'request_fulluri' => true,
|
||||
);
|
||||
}
|
||||
|
||||
// add authorization in context
|
||||
$options = array();
|
||||
if ($this->io->hasAuthorization($originUrl)) {
|
||||
$auth = $this->io->getAuthorization($originUrl);
|
||||
$authStr = base64_encode($auth['username'] . ':' . $auth['password']);
|
||||
$params['http'] = array_merge($params['http'], array('header' => "Authorization: Basic $authStr\r\n"));
|
||||
$auth = $this->io->getAuthorization($originUrl);
|
||||
$authStr = base64_encode($auth['username'] . ':' . $auth['password']);
|
||||
$options['http']['header'] = "Authorization: Basic $authStr\r\n";
|
||||
|
||||
} else if (null !== $this->io->getLastUsername()) {
|
||||
$authStr = base64_encode($this->io->getLastUsername() . ':' . $this->io->getLastPassword());
|
||||
$params['http'] = array('header' => "Authorization: Basic $authStr\r\n");
|
||||
$options['http'] = array('header' => "Authorization: Basic $authStr\r\n");
|
||||
$this->io->setAuthorization($originUrl, $this->io->getLastUsername(), $this->io->getLastPassword());
|
||||
}
|
||||
|
||||
$ctx = stream_context_create($params);
|
||||
stream_context_set_params($ctx, array("notification" => array($this, 'callbackGet')));
|
||||
$ctx = StreamContextFactory::getContext($options, array('notification' => array($this, 'callbackGet')));
|
||||
|
||||
if ($this->progress) {
|
||||
$this->io->overwrite(" Downloading: <comment>connection...</comment>", false);
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Util;
|
||||
|
||||
/**
|
||||
* Allows the creation of a basic context supporting http proxy
|
||||
*
|
||||
* @author Jordan Alliot <jordan.alliot@gmail.com>
|
||||
*/
|
||||
final class StreamContextFactory
|
||||
{
|
||||
/**
|
||||
* Creates a context supporting HTTP proxies
|
||||
*
|
||||
* @param array $defaultOptions Options to merge with the default
|
||||
* @param array $defaultParams Parameters to specify on the context
|
||||
* @return resource Default context
|
||||
* @throws \RuntimeException if https proxy required and OpenSSL uninstalled
|
||||
*/
|
||||
static public function getContext(array $defaultOptions = array(), array $defaultParams = array())
|
||||
{
|
||||
$options = array('http' => array());
|
||||
|
||||
// Handle system proxy
|
||||
if (isset($_SERVER['HTTP_PROXY']) || isset($_SERVER['http_proxy'])) {
|
||||
// Some systems seem to rely on a lowercased version instead...
|
||||
$proxy = isset($_SERVER['HTTP_PROXY']) ? $_SERVER['HTTP_PROXY'] : $_SERVER['http_proxy'];
|
||||
|
||||
// http(s):// is not supported in proxy
|
||||
$proxy = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxy);
|
||||
|
||||
if (0 === strpos($proxy, 'ssl:') && !extension_loaded('openssl')) {
|
||||
throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
|
||||
}
|
||||
|
||||
$options['http'] = array(
|
||||
'proxy' => $proxy,
|
||||
'request_fulluri' => true,
|
||||
);
|
||||
}
|
||||
|
||||
$options = array_merge_recursive($options, $defaultOptions);
|
||||
|
||||
return stream_context_create($options, $defaultParams);
|
||||
}
|
||||
}
|
|
@ -121,6 +121,26 @@ class JsonFileTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertJsonFormat($json, $data);
|
||||
}
|
||||
|
||||
public function testEscape()
|
||||
{
|
||||
$data = array("Metadata\\\"" => 'src/');
|
||||
$json = '{
|
||||
"Metadata\\\\\\"": "src\/"
|
||||
}';
|
||||
|
||||
$this->assertJsonFormat($json, $data);
|
||||
}
|
||||
|
||||
public function testUnicode()
|
||||
{
|
||||
$data = array("Žluťoučký \" kůň" => "úpěl ďábelské ódy za €");
|
||||
$json = '{
|
||||
"Žluťoučký \" kůň": "úpěl ďábelské ódy za €"
|
||||
}';
|
||||
|
||||
$this->assertJsonFormat($json, $data);
|
||||
}
|
||||
|
||||
private function expectParseException($text, $json)
|
||||
{
|
||||
try {
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Test\Package\Dumper;
|
||||
|
||||
use Composer\Package\Dumper\ArrayDumper;
|
||||
use Composer\Package\MemoryPackage;
|
||||
|
||||
class ArrayDumperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->dumper = new ArrayDumper();
|
||||
}
|
||||
|
||||
public function testRequiredInformations()
|
||||
{
|
||||
$package = new MemoryPackage('foo', '1.0.0.0', '1.0');
|
||||
|
||||
$config = $this->dumper->dump($package);
|
||||
$this->assertEquals(array('name', 'version', 'version_normalized', 'type', 'names'), array_keys($config));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getKeys
|
||||
*/
|
||||
public function testKeys($key, $value, $expectedValue = null, $method = null)
|
||||
{
|
||||
$package = new MemoryPackage('foo', '1.0.0.0', '1.0');
|
||||
|
||||
$setter = 'set'.ucfirst($method ?: $key);
|
||||
$package->$setter($value);
|
||||
|
||||
$config = $this->dumper->dump($package);
|
||||
$this->assertArrayHasKey($key, $config);
|
||||
|
||||
$expectedValue = $expectedValue ?: $value;
|
||||
$this->assertSame($expectedValue, $config[$key]);
|
||||
}
|
||||
|
||||
public function getKeys()
|
||||
{
|
||||
return array(
|
||||
array('time', new \DateTime('2012-02-01'), '2012-02-01 00:00:00', 'ReleaseDate'),
|
||||
array('authors', array('Nils Adermann <naderman@naderman.de>', 'Jordi Boggiano <j.boggiano@seld.be>')),
|
||||
array('homepage', 'http://getcomposer.org'),
|
||||
array('description', 'Package Manager'),
|
||||
array('keywords', array('package', 'dependency', 'autoload')),
|
||||
array('bin', array('bin/composer'), null, 'binaries'),
|
||||
array('license', array('MIT')),
|
||||
array('autoload', array('psr-0' => array('Composer' => 'src/'))),
|
||||
array('repositories', array('packagist' => false)),
|
||||
array('scripts', array('post-update-cmd' => 'MyVendor\\MyClass::postUpdate')),
|
||||
array('extra', array('class' => 'MyVendor\\Installer')),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue