From df0a2cdd0aa61ccd50c5fcd4bea7f495a8118554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ph=C3=A9na=20Proxima?= Date: Thu, 8 Apr 2021 11:08:13 -0400 Subject: [PATCH 1/3] Fire POST_FILE_DOWNLOAD event for metadata fetched by ComposerRepository. --- src/Composer/Plugin/PostFileDownloadEvent.php | 53 +++++++++++++++---- .../Repository/ComposerRepository.php | 19 ++++++- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/Composer/Plugin/PostFileDownloadEvent.php b/src/Composer/Plugin/PostFileDownloadEvent.php index 370f58cd4..0ec8eddde 100644 --- a/src/Composer/Plugin/PostFileDownloadEvent.php +++ b/src/Composer/Plugin/PostFileDownloadEvent.php @@ -38,32 +38,41 @@ class PostFileDownloadEvent extends Event private $url; /** - * @var \Composer\Package\PackageInterface + * @var mixed */ - private $package; + private $context; + + /** + * @var string + */ + private $type; /** * Constructor. * * @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 $url The processed url - * @param PackageInterface $package The package. + * @param mixed $context Additional context for the download. + * @param string $type The type (package or metadata). */ - public function __construct($name, $fileName, $checksum, $url, PackageInterface $package) + public function __construct($name, $fileName, $checksum, $url, $context = null, $type = 'package') { parent::__construct($name); $this->fileName = $fileName; $this->checksum = $checksum; $this->url = $url; - $this->package = $package; + $this->context = $context; + $this->type = $type; } /** * Retrieves the target file name location. * - * @return string + * If this download is of type metadata, null is returned. + * + * @return string|null */ public function getFileName() { @@ -90,13 +99,39 @@ class PostFileDownloadEvent extends Event 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, the HTTP response is returned. + * + * @return mixed + */ + public function getContext() + { + return $this->context; + } + /** * 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. */ public function getPackage() { - return $this->package; + $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; } } diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 5d238c713..3554d5656 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -22,6 +22,7 @@ use Composer\Json\JsonFile; use Composer\Cache; use Composer\Config; use Composer\IO\IOInterface; +use Composer\Plugin\PostFileDownloadEvent; use Composer\Semver\CompilingMatcher; use Composer\Util\HttpDownloader; use Composer\Util\Loop; @@ -1110,6 +1111,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.'); } + if ($this->eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, $response, 'metadata'); + $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($this->io, $this->url, $data); @@ -1188,6 +1194,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito return true; } + if ($this->eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, $response, 'metadata'); + $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($this->io, $this->url, $data); @@ -1258,9 +1269,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $url = $this->url; $cache = $this->cache; $degradedMode = &$this->degradedMode; + $eventDispatcher = $this->eventDispatcher; $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 if ($response->getStatusCode() === 404) { $repo->packagesNotFoundCache[$filename] = true; @@ -1275,6 +1287,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito return true; } + if ($eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $url, $response, 'metadata'); + $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($io, $url, $data); From 7dd95a768bc1dd8c6f296ee0081f41ffa1444bbe Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 9 Apr 2021 11:00:49 +0200 Subject: [PATCH 2/3] Clean stuff up and deprecate old usages for PostFileDownloadEvent --- src/Composer/Downloader/FileDownloader.php | 2 +- src/Composer/Plugin/PluginInterface.php | 2 +- src/Composer/Plugin/PostFileDownloadEvent.php | 13 +++++++++++-- src/Composer/Repository/ComposerRepository.php | 6 +++--- .../Test/Plugin/Fixtures/plugin-v8/composer.json | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 0c84276de..238a3462b 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -192,7 +192,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface } 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); } diff --git a/src/Composer/Plugin/PluginInterface.php b/src/Composer/Plugin/PluginInterface.php index f18799e7b..305a784bc 100644 --- a/src/Composer/Plugin/PluginInterface.php +++ b/src/Composer/Plugin/PluginInterface.php @@ -32,7 +32,7 @@ interface PluginInterface * * @var string */ - const PLUGIN_API_VERSION = '2.0.0'; + const PLUGIN_API_VERSION = '2.1.0'; /** * Apply plugin modifications to Composer diff --git a/src/Composer/Plugin/PostFileDownloadEvent.php b/src/Composer/Plugin/PostFileDownloadEvent.php index 0ec8eddde..d08f336d6 100644 --- a/src/Composer/Plugin/PostFileDownloadEvent.php +++ b/src/Composer/Plugin/PostFileDownloadEvent.php @@ -54,11 +54,17 @@ class PostFileDownloadEvent extends Event * @param string|null $fileName The file name * @param string|null $checksum The checksum * @param string $url The processed url - * @param mixed $context Additional context for the download. * @param string $type The type (package or metadata). + * @param mixed $context Additional context for the download. */ - public function __construct($name, $fileName, $checksum, $url, $context = null, $type = '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); $this->fileName = $fileName; $this->checksum = $checksum; @@ -118,10 +124,13 @@ class PostFileDownloadEvent extends Event * If this download is of type metadata, null is returned. * * @return \Composer\Package\PackageInterface|null The package. + * @deprecated Use getContext instead */ public function getPackage() { + 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; } diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 3554d5656..2449526cf 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -1112,7 +1112,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } if ($this->eventDispatcher) { - $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, $response, 'metadata'); + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, 'metadata', $response); $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); } @@ -1195,7 +1195,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } if ($this->eventDispatcher) { - $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, $response, 'metadata'); + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, 'metadata', $response); $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); } @@ -1288,7 +1288,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } if ($eventDispatcher) { - $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $url, $response, 'metadata'); + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $url, 'metadata', $response); $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); } diff --git a/tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json b/tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json index aa44b5a3d..c2a347a51 100644 --- a/tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json +++ b/tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json @@ -9,6 +9,6 @@ ] }, "require": { - "composer-plugin-api": "2.0.0" + "composer-plugin-api": "^2.0.0" } } From 9a9c738f2383dc8881b6ee6f8b0db975202dafcc Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 9 Apr 2021 11:20:21 +0200 Subject: [PATCH 3/3] Add repository instance to Pre/PostFileDownloadEvent metadata --- src/Composer/Plugin/PostFileDownloadEvent.php | 2 +- src/Composer/Plugin/PreFileDownloadEvent.php | 1 + src/Composer/Repository/ComposerRepository.php | 12 ++++++------ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Composer/Plugin/PostFileDownloadEvent.php b/src/Composer/Plugin/PostFileDownloadEvent.php index d08f336d6..665bce128 100644 --- a/src/Composer/Plugin/PostFileDownloadEvent.php +++ b/src/Composer/Plugin/PostFileDownloadEvent.php @@ -109,7 +109,7 @@ class PostFileDownloadEvent extends Event * 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, the HTTP response is returned. + * this download is of type metadata, an array{response: Response, repository: RepositoryInterface} is returned. * * @return mixed */ diff --git a/src/Composer/Plugin/PreFileDownloadEvent.php b/src/Composer/Plugin/PreFileDownloadEvent.php index b741d4646..4372bedd6 100644 --- a/src/Composer/Plugin/PreFileDownloadEvent.php +++ b/src/Composer/Plugin/PreFileDownloadEvent.php @@ -127,6 +127,7 @@ class PreFileDownloadEvent extends Event * Returns the context of this download, if any. * * 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 */ diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 2449526cf..5ab2e3546 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -1086,7 +1086,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito while ($retries--) { try { 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); $filename = $preFileDownloadEvent->getProcessedUrl(); } @@ -1112,7 +1112,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } if ($this->eventDispatcher) { - $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, 'metadata', $response); + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, 'metadata', array('response' => $response, 'repository' => $this)); $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); } @@ -1178,7 +1178,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito while ($retries--) { try { 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); $filename = $preFileDownloadEvent->getProcessedUrl(); } @@ -1195,7 +1195,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } if ($this->eventDispatcher) { - $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, 'metadata', $response); + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, 'metadata', array('response' => $response, 'repository' => $this)); $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); } @@ -1252,7 +1252,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $httpDownloader = $this->httpDownloader; 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); $filename = $preFileDownloadEvent->getProcessedUrl(); } @@ -1288,7 +1288,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } if ($eventDispatcher) { - $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $url, 'metadata', $response); + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $url, 'metadata', array('response' => $response, 'repository' => $repo)); $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); }