Add support for batch notifications

main
Jordi Boggiano 12 years ago
parent c5f3a6febd
commit e868c9706b

@ -182,15 +182,22 @@ class Installer
$this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode); $this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode);
} }
$this->suggestedPackages = array(); try {
if (!$this->doInstall($this->repositoryManager->getLocalRepository(), $installedRepo, $aliases)) { $this->suggestedPackages = array();
return false; if (!$this->doInstall($this->repositoryManager->getLocalRepository(), $installedRepo, $aliases)) {
}
if ($this->devMode) {
if (!$this->doInstall($this->repositoryManager->getLocalDevRepository(), $installedRepo, $aliases, true)) {
return false; return false;
} }
if ($this->devMode) {
if (!$this->doInstall($this->repositoryManager->getLocalDevRepository(), $installedRepo, $aliases, true)) {
return false;
}
}
} catch (\Exception $e) {
$this->installationManager->notifyInstalls();
throw $e;
} }
$this->installationManager->notifyInstalls();
// output suggestions // output suggestions
foreach ($this->suggestedPackages as $suggestion) { foreach ($this->suggestedPackages as $suggestion) {

@ -34,6 +34,12 @@ class InstallationManager
{ {
private $installers = array(); private $installers = array();
private $cache = array(); private $cache = array();
private $notifiablePackages = array();
public function reset()
{
$this->notifiablePackages = array();
}
/** /**
* Adds installer * Adds installer
@ -130,7 +136,7 @@ class InstallationManager
$package = $operation->getPackage(); $package = $operation->getPackage();
$installer = $this->getInstaller($package->getType()); $installer = $this->getInstaller($package->getType());
$installer->install($repo, $package); $installer->install($repo, $package);
$this->notifyInstall($package); $this->markForNotification($package);
} }
/** /**
@ -150,7 +156,7 @@ class InstallationManager
if ($initialType === $targetType) { if ($initialType === $targetType) {
$installer = $this->getInstaller($initialType); $installer = $this->getInstaller($initialType);
$installer->update($repo, $initial, $target); $installer->update($repo, $initial, $target);
$this->notifyInstall($target); $this->markForNotification($target);
} else { } else {
$this->getInstaller($initialType)->uninstall($repo, $initial); $this->getInstaller($initialType)->uninstall($repo, $initial);
$this->getInstaller($targetType)->install($repo, $target); $this->getInstaller($targetType)->install($repo, $target);
@ -211,10 +217,18 @@ class InstallationManager
return $installer->getInstallPath($package); return $installer->getInstallPath($package);
} }
private function notifyInstall(PackageInterface $package) public function notifyInstalls()
{
foreach ($this->notifiablePackages as $packages) {
$repo = reset($packages)->getRepository();
$repo->notifyInstalls($packages);
}
}
private function markForNotification(PackageInterface $package)
{ {
if ($package->getRepository() instanceof NotifiableRepositoryInterface) { if ($package->getRepository() instanceof NotifiableRepositoryInterface) {
$package->getRepository()->notifyInstall($package); $this->notifiablePackages[spl_object_hash($package->getRepository())][$package->getName()] = $package;
} }
} }
} }

@ -22,6 +22,7 @@ use Composer\Cache;
use Composer\Config; use Composer\Config;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Util\RemoteFilesystem; use Composer\Util\RemoteFilesystem;
use Composer\Util\StreamContextFactory;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
@ -79,30 +80,56 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function notifyInstall(PackageInterface $package) public function notifyInstalls(array $packages)
{ {
if (!$this->notifyUrl || !$this->config->get('notify-on-install')) { if (!$this->notifyUrl || !$this->config->get('notify-on-install')) {
return; return;
} }
// TODO use an optional curl_multi pool for all the notifications // non-batch API, deprecated
$url = str_replace('%package%', $package->getPrettyName(), $this->notifyUrl); if (strpos($this->notifyUrl, '%package%')) {
foreach ($packages as $package) {
$url = str_replace('%package%', $package->getPrettyName(), $this->notifyUrl);
$params = array(
'version' => $package->getPrettyVersion(),
'version_normalized' => $package->getVersion(),
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($params, '', '&'),
'timeout' => 3,
)
);
$context = StreamContextFactory::getContext($opts);
@file_get_contents($url, false, $context);
}
return;
}
$postData = array('downloads' => array());
foreach ($packages as $package) {
$postData['downloads'][] = array(
'name' => $package->getPrettyName(),
'version' => $package->getVersion(),
);
}
$params = array(
'version' => $package->getPrettyVersion(),
'version_normalized' => $package->getVersion(),
);
$opts = array('http' => $opts = array('http' =>
array( array(
'method' => 'POST', 'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded', 'header' => 'Content-Type: application/json',
'content' => http_build_query($params, '', '&'), 'content' => json_encode($postData),
'timeout' => 3, 'timeout' => 6,
) )
); );
$context = stream_context_create($opts); $context = StreamContextFactory::getContext($opts);
@file_get_contents($url, false, $context); @file_get_contents($this->notifyUrl, false, $context);
} }
public function setRootAliases(array $rootAliases) public function setRootAliases(array $rootAliases)
@ -340,7 +367,15 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
$data = $this->fetchFile($jsonUrl, 'packages.json'); $data = $this->fetchFile($jsonUrl, 'packages.json');
if (!empty($data['notify'])) { if (!empty($data['notify_batch'])) {
if ('/' === $data['notify_batch'][0]) {
$this->notifyUrl = preg_replace('{(https?://[^/]+).*}i', '$1' . $data['notify_batch'], $this->url);
} else {
$this->notifyUrl = $data['notify_batch'];
}
}
if (!$this->notifyUrl && !empty($data['notify'])) {
if ('/' === $data['notify'][0]) { if ('/' === $data['notify'][0]) {
$this->notifyUrl = preg_replace('{(https?://[^/]+).*}i', '$1' . $data['notify'], $this->url); $this->notifyUrl = preg_replace('{(https?://[^/]+).*}i', '$1' . $data['notify'], $this->url);
} else { } else {

@ -22,7 +22,7 @@ interface NotifiableRepositoryInterface extends RepositoryInterface
/** /**
* Notify this repository about the installation of a package * Notify this repository about the installation of a package
* *
* @param PackageInterface $package Package that is installed * @param PackageInterface[] $packages Packages that were installed
*/ */
public function notifyInstall(PackageInterface $package); public function notifyInstalls(array $packages);
} }

Loading…
Cancel
Save