1
0
Fork 0

Merge pull request #9822 from phenaproxima/post-file-download

Fire POST_FILE_DOWNLOAD event for metadata fetched by ComposerRepository
pull/9828/head
Jordi Boggiano 2021-04-09 14:53:20 +02:00 committed by GitHub
commit d75d79b452
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 16 deletions

View File

@ -195,7 +195,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
} }
if ($eventDispatcher) { if ($eventDispatcher) {
$postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, $fileName, $checksum, $url['processed'], $package); $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, $fileName, $checksum, $url['processed'], 'package', $package);
$eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
} }

View File

@ -32,7 +32,7 @@ interface PluginInterface
* *
* @var string * @var string
*/ */
const PLUGIN_API_VERSION = '2.0.0'; const PLUGIN_API_VERSION = '2.1.0';
/** /**
* Apply plugin modifications to Composer * Apply plugin modifications to Composer

View File

@ -38,32 +38,47 @@ class PostFileDownloadEvent extends Event
private $url; private $url;
/** /**
* @var \Composer\Package\PackageInterface * @var mixed
*/ */
private $package; private $context;
/**
* @var string
*/
private $type;
/** /**
* Constructor. * Constructor.
* *
* @param string $name The event name * @param string $name The event name
* @param string $fileName The file name * @param string|null $fileName The file name
* @param string|null $checksum The checksum * @param string|null $checksum The checksum
* @param string $url The processed url * @param string $url The processed url
* @param PackageInterface $package The package. * @param string $type The type (package or metadata).
* @param mixed $context Additional context for the download.
*/ */
public function __construct($name, $fileName, $checksum, $url, PackageInterface $package) public function __construct($name, $fileName, $checksum, $url, $type, $context = null)
{ {
if ($context === null && $type instanceof PackageInterface) {
$context = $type;
$type = 'package';
trigger_error('PostFileDownloadEvent::__construct should receive a $type=package and the package object in $context since Composer 2.1.', E_USER_DEPRECATED);
}
parent::__construct($name); parent::__construct($name);
$this->fileName = $fileName; $this->fileName = $fileName;
$this->checksum = $checksum; $this->checksum = $checksum;
$this->url = $url; $this->url = $url;
$this->package = $package; $this->context = $context;
$this->type = $type;
} }
/** /**
* Retrieves the target file name location. * Retrieves the target file name location.
* *
* @return string * If this download is of type metadata, null is returned.
*
* @return string|null
*/ */
public function getFileName() public function getFileName()
{ {
@ -90,13 +105,42 @@ class PostFileDownloadEvent extends Event
return $this->url; return $this->url;
} }
/**
* Returns the context of this download, if any.
*
* If this download is of type package, the package object is returned. If
* this download is of type metadata, an array{response: Response, repository: RepositoryInterface} is returned.
*
* @return mixed
*/
public function getContext()
{
return $this->context;
}
/** /**
* Get the package. * Get the package.
* *
* @return \Composer\Package\PackageInterface The package. * If this download is of type metadata, null is returned.
*
* @return \Composer\Package\PackageInterface|null The package.
* @deprecated Use getContext instead
*/ */
public function getPackage() public function getPackage()
{ {
return $this->package; trigger_error('PostFileDownloadEvent::getPackage is deprecated since Composer 2.1, use getContext instead.', E_USER_DEPRECATED);
$context = $this->getContext();
return $context instanceof PackageInterface ? $context : null;
}
/**
* Returns the type of this download (package, metadata).
*
* @return string
*/
public function getType()
{
return $this->type;
} }
} }

View File

@ -127,6 +127,7 @@ class PreFileDownloadEvent extends Event
* Returns the context of this download, if any. * Returns the context of this download, if any.
* *
* If this download is of type package, the package object is returned. * If this download is of type package, the package object is returned.
* If the type is metadata, an array{repository: RepositoryInterface} is returned.
* *
* @return mixed * @return mixed
*/ */

View File

@ -24,6 +24,7 @@ use Composer\Json\JsonFile;
use Composer\Cache; use Composer\Cache;
use Composer\Config; use Composer\Config;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Plugin\PostFileDownloadEvent;
use Composer\Semver\CompilingMatcher; use Composer\Semver\CompilingMatcher;
use Composer\Util\HttpDownloader; use Composer\Util\HttpDownloader;
use Composer\Util\Loop; use Composer\Util\Loop;
@ -1088,7 +1089,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
while ($retries--) { while ($retries--) {
try { try {
if ($this->eventDispatcher) { if ($this->eventDispatcher) {
$preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata'); $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this));
$this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
$filename = $preFileDownloadEvent->getProcessedUrl(); $filename = $preFileDownloadEvent->getProcessedUrl();
} }
@ -1113,6 +1114,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
throw new RepositorySecurityException('The contents of '.$filename.' do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.'); throw new RepositorySecurityException('The contents of '.$filename.' do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.');
} }
if ($this->eventDispatcher) {
$postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, 'metadata', array('response' => $response, 'repository' => $this));
$this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
}
$data = $response->decodeJson(); $data = $response->decodeJson();
HttpDownloader::outputWarnings($this->io, $this->url, $data); HttpDownloader::outputWarnings($this->io, $this->url, $data);
@ -1175,7 +1181,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
while ($retries--) { while ($retries--) {
try { try {
if ($this->eventDispatcher) { if ($this->eventDispatcher) {
$preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata'); $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this));
$this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
$filename = $preFileDownloadEvent->getProcessedUrl(); $filename = $preFileDownloadEvent->getProcessedUrl();
} }
@ -1191,6 +1197,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return true; return true;
} }
if ($this->eventDispatcher) {
$postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, 'metadata', array('response' => $response, 'repository' => $this));
$this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
}
$data = $response->decodeJson(); $data = $response->decodeJson();
HttpDownloader::outputWarnings($this->io, $this->url, $data); HttpDownloader::outputWarnings($this->io, $this->url, $data);
@ -1244,7 +1255,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$httpDownloader = $this->httpDownloader; $httpDownloader = $this->httpDownloader;
if ($this->eventDispatcher) { if ($this->eventDispatcher) {
$preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata'); $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this));
$this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
$filename = $preFileDownloadEvent->getProcessedUrl(); $filename = $preFileDownloadEvent->getProcessedUrl();
} }
@ -1261,9 +1272,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$url = $this->url; $url = $this->url;
$cache = $this->cache; $cache = $this->cache;
$degradedMode = &$this->degradedMode; $degradedMode = &$this->degradedMode;
$eventDispatcher = $this->eventDispatcher;
$repo = $this; $repo = $this;
$accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $repo) { $accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $eventDispatcher, $repo) {
// package not found is acceptable for a v2 protocol repository // package not found is acceptable for a v2 protocol repository
if ($response->getStatusCode() === 404) { if ($response->getStatusCode() === 404) {
$repo->packagesNotFoundCache[$filename] = true; $repo->packagesNotFoundCache[$filename] = true;
@ -1278,6 +1290,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return true; return true;
} }
if ($eventDispatcher) {
$postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $url, 'metadata', array('response' => $response, 'repository' => $repo));
$eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
}
$data = $response->decodeJson(); $data = $response->decodeJson();
HttpDownloader::outputWarnings($io, $url, $data); HttpDownloader::outputWarnings($io, $url, $data);

View File

@ -9,6 +9,6 @@
] ]
}, },
"require": { "require": {
"composer-plugin-api": "2.0.0" "composer-plugin-api": "^2.0.0"
} }
} }