From fee29168f4010bc2ae3af37b0b3fb3831bbde397 Mon Sep 17 00:00:00 2001 From: Daniel Bannert Date: Fri, 28 Sep 2018 15:03:25 +0200 Subject: [PATCH] removed post-messages from root composer.json (#84) | Q | A | --------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Related tickets | - | License | MIT | Doc PR | - --- src/Automatic/Automatic.php | 112 +++++++++++-------- src/Automatic/ScriptEvents.php | 9 -- src/Security/Audit.php | 2 +- src/Security/SecurityPlugin.php | 149 +------------------------ tests/Automatic/AutomaticTest.php | 40 +++---- tests/Security/SecurityPluginTest.php | 155 ++------------------------ 6 files changed, 93 insertions(+), 374 deletions(-) diff --git a/src/Automatic/Automatic.php b/src/Automatic/Automatic.php index 0862179b..a58b0f01 100644 --- a/src/Automatic/Automatic.php +++ b/src/Automatic/Automatic.php @@ -155,20 +155,24 @@ public static function getSubscribedEvents(): array return [ ScriptEvents::AUTO_SCRIPTS => 'executeAutoScripts', - ScriptEvents::POST_MESSAGES => 'postMessages', InstallerEvents::PRE_DEPENDENCIES_SOLVING => [['onPreDependenciesSolving', \PHP_INT_MAX]], InstallerEvents::POST_DEPENDENCIES_SOLVING => [['populateFilesCacheDir', \PHP_INT_MAX]], PackageEvents::PRE_PACKAGE_INSTALL => [['populateFilesCacheDir', ~\PHP_INT_MAX]], PackageEvents::PRE_PACKAGE_UPDATE => [['populateFilesCacheDir', ~\PHP_INT_MAX]], - PackageEvents::PRE_PACKAGE_UNINSTALL => [['onPreUninstall', \PHP_INT_MAX - 1]], + PackageEvents::PRE_PACKAGE_UNINSTALL => 'onPreUninstall', PackageEvents::POST_PACKAGE_INSTALL => 'record', PackageEvents::POST_PACKAGE_UPDATE => 'record', - PackageEvents::POST_PACKAGE_UNINSTALL => [['onPostUninstall', \PHP_INT_MAX - 1]], + PackageEvents::POST_PACKAGE_UNINSTALL => 'onPostUninstall', PluginEvents::PRE_FILE_DOWNLOAD => 'onFileDownload', + PluginEvents::INIT => 'initAutoScripts', ComposerScriptEvents::POST_AUTOLOAD_DUMP => 'onPostAutoloadDump', - ComposerScriptEvents::POST_INSTALL_CMD => [['onPostInstall', \PHP_INT_MAX - 1]], - ComposerScriptEvents::POST_UPDATE_CMD => [['onPostUpdate', \PHP_INT_MAX - 1]], - ComposerScriptEvents::POST_CREATE_PROJECT_CMD => [['onPostCreateProject', \PHP_INT_MAX], ['runSkeletonGenerator', ~\PHP_INT_MAX]], + ComposerScriptEvents::POST_INSTALL_CMD => 'onPostInstall', + ComposerScriptEvents::POST_UPDATE_CMD => [['onPostUpdate', \PHP_INT_MAX], ['onPostUpdatePostMessages', ~\PHP_INT_MAX + 1]], + ComposerScriptEvents::POST_CREATE_PROJECT_CMD => [ + ['onPostCreateProject', \PHP_INT_MAX], + ['runSkeletonGenerator', \PHP_INT_MAX - 1], + ['initAutoScripts', \PHP_INT_MAX - 2], + ], ]; } @@ -225,16 +229,14 @@ public function activate(Composer $composer, IOInterface $io): void } /** - * Executes on composer post-messages event. + * Executes on composer post-update event. * * @param \Composer\Script\Event $event * * @return void */ - public function postMessages(Event $event): void + public function onPostUpdatePostMessages(Event $event): void { - $event->stopPropagation(); - $this->container->get(IOInterface::class)->write($this->postMessages); } @@ -272,53 +274,42 @@ public function record(PackageEvent $event): void } /** - * Executes on composer create project event. - * - * @param \Composer\Script\Event $event + * Add auto-scripts to root composer.json. * * @throws \Exception + * + * @return void */ - public function onPostCreateProject(Event $event): void + public function initAutoScripts(): void { - /** @var \Composer\Json\JsonFile $json */ - /** @var \Composer\Json\JsonManipulator $manipulator */ - [$json, $manipulator] = Util::getComposerJsonFileAndManipulator(); - - // new projects are most of the time proprietary - $manipulator->addMainKey('license', 'proprietary'); + $scripts = $this->container->get(Composer::class)->getPackage()->getScripts(); - // 'name' and 'description' are only required for public packages - $manipulator->removeProperty('name'); - $manipulator->removeProperty('description'); + $autoScript = '@' . ScriptEvents::AUTO_SCRIPTS; - foreach ($this->container->get('composer-extra') as $key => $value) { - if ($key !== self::COMPOSER_EXTRA_KEY) { - $manipulator->addSubNode('extra', $key, $value); - } + if (isset($scripts[ComposerScriptEvents::POST_INSTALL_CMD], $scripts[ComposerScriptEvents::POST_UPDATE_CMD]) && + \in_array($autoScript, $scripts[ComposerScriptEvents::POST_INSTALL_CMD], true) && + \in_array($autoScript, $scripts[ComposerScriptEvents::POST_UPDATE_CMD], true) + ) { + return; } - $scripts = $this->container->get(Composer::class)->getPackage()->getScripts(); + /** @var \Composer\Json\JsonFile $json */ + /** @var \Composer\Json\JsonManipulator $manipulator */ + [$json, $manipulator] = Util::getComposerJsonFileAndManipulator(); if (\count($scripts) === 0) { $manipulator->addMainKey('scripts', []); } - $manipulator->addSubNode('scripts', ScriptEvents::POST_MESSAGES, 'This key is needed to show messages.'); - - $automaticScripts = [ - '@' . ScriptEvents::AUTO_SCRIPTS, - '@' . ScriptEvents::POST_MESSAGES, - ]; - $manipulator->addSubNode( 'scripts', ComposerScriptEvents::POST_INSTALL_CMD, - \array_merge($scripts[ComposerScriptEvents::POST_INSTALL_CMD] ?? [], [$automaticScripts]) + \array_merge($scripts[ComposerScriptEvents::POST_INSTALL_CMD] ?? [], [$autoScript]) ); $manipulator->addSubNode( 'scripts', ComposerScriptEvents::POST_UPDATE_CMD, - \array_merge($scripts[ComposerScriptEvents::POST_UPDATE_CMD] ?? [], [$automaticScripts]) + \array_merge($scripts[ComposerScriptEvents::POST_UPDATE_CMD] ?? [], [$autoScript]) ); if (! isset($scripts[ScriptEvents::AUTO_SCRIPTS])) { @@ -330,6 +321,37 @@ public function onPostCreateProject(Event $event): void $this->updateComposerLock(); } + /** + * Executes on composer create project event. + * + * @param \Composer\Script\Event $event + * + * @throws \Exception + */ + public function onPostCreateProject(Event $event): void + { + /** @var \Composer\Json\JsonFile $json */ + /** @var \Composer\Json\JsonManipulator $manipulator */ + [$json, $manipulator] = Util::getComposerJsonFileAndManipulator(); + + // new projects are most of the time proprietary + $manipulator->addMainKey('license', 'proprietary'); + + // 'name' and 'description' are only required for public packages + $manipulator->removeProperty('name'); + $manipulator->removeProperty('description'); + + foreach ($this->container->get('composer-extra') as $key => $value) { + if ($key !== self::COMPOSER_EXTRA_KEY) { + $manipulator->addSubNode('extra', $key, $value); + } + } + + \file_put_contents($json->getPath(), $manipulator->getContents()); + + $this->updateComposerLock(); + } + /** * Run found skeleton generators. * @@ -413,7 +435,7 @@ public function onPostUninstall(PackageEvent $event): void if ($operation->getPackage()->getName() === self::PACKAGE_NAME) { $scripts = $this->container->get(Composer::class)->getPackage()->getScripts(); - if (\count($scripts) === 0 || ! isset($scripts[ScriptEvents::POST_MESSAGES])) { + if (\count($scripts) === 0) { return; } @@ -421,12 +443,8 @@ public function onPostUninstall(PackageEvent $event): void /** @var \Composer\Json\JsonManipulator $manipulator */ [$json, $manipulator] = Util::getComposerJsonFileAndManipulator(); - $manipulator->removeSubNode('scripts', ScriptEvents::POST_MESSAGES); - foreach ((array) $scripts[ComposerScriptEvents::POST_INSTALL_CMD] as $key => $script) { - if ($script === '@' . ScriptEvents::POST_MESSAGES) { - unset($scripts[ComposerScriptEvents::POST_INSTALL_CMD][$key]); - } elseif ($script === '@' . ScriptEvents::AUTO_SCRIPTS) { + if ($script === '@' . ScriptEvents::AUTO_SCRIPTS) { unset($scripts[ComposerScriptEvents::POST_INSTALL_CMD][$key]); } } @@ -434,9 +452,7 @@ public function onPostUninstall(PackageEvent $event): void $manipulator->addSubNode('scripts', ComposerScriptEvents::POST_INSTALL_CMD, $scripts[ComposerScriptEvents::POST_INSTALL_CMD]); foreach ((array) $scripts[ComposerScriptEvents::POST_UPDATE_CMD] as $key => $script) { - if ($script === '@' . ScriptEvents::POST_MESSAGES) { - unset($scripts[ComposerScriptEvents::POST_UPDATE_CMD][$key]); - } elseif ($script === '@' . ScriptEvents::AUTO_SCRIPTS) { + if ($script === '@' . ScriptEvents::AUTO_SCRIPTS) { unset($scripts[ComposerScriptEvents::POST_UPDATE_CMD][$key]); } } @@ -576,8 +592,8 @@ public function onPostUpdate(Event $event, array $operations = []): void $install->transform($package); - if ($package->hasConfig(ScriptEvents::POST_MESSAGES)) { - foreach ((array) $package->getConfig(ScriptEvents::POST_MESSAGES) as $line) { + if ($package->hasConfig('post-install-output')) { + foreach ((array) $package->getConfig('post-install-output') as $line) { $this->postMessages[] = self::expandTargetDir($this->container->get('composer-extra'), $line); } diff --git a/src/Automatic/ScriptEvents.php b/src/Automatic/ScriptEvents.php index f4e3793f..2b5895d8 100644 --- a/src/Automatic/ScriptEvents.php +++ b/src/Automatic/ScriptEvents.php @@ -12,13 +12,4 @@ class ScriptEvents * @var string */ public const AUTO_SCRIPTS = 'auto-scripts'; - - /** - * The POST_MESSAGES event occurs after a package is installed or updated. - * - * The event listener method receives a Composer\Script\Event instance. - * - * @var string - */ - public const POST_MESSAGES = 'post-messages'; } diff --git a/src/Security/Audit.php b/src/Security/Audit.php index 6bfecb7b..a2a02ac1 100644 --- a/src/Security/Audit.php +++ b/src/Security/Audit.php @@ -168,7 +168,7 @@ public function getSecurityAdvisories(?IOInterface $io = null): array } if ($io !== null) { - $io->writeError('Downloading the Security Advisories database...'); + $io->writeError('Downloading the Security Advisories database...', true, IOInterface::VERBOSE); } $securityAdvisories = $this->downloader->download(self::SECURITY_ADVISORIES_BASE_URL . self::SECURITY_ADVISORIES); diff --git a/src/Security/SecurityPlugin.php b/src/Security/SecurityPlugin.php index df7d16f6..218baa7a 100644 --- a/src/Security/SecurityPlugin.php +++ b/src/Security/SecurityPlugin.php @@ -6,13 +6,9 @@ use Composer\DependencyResolver\Operation\UninstallOperation; use Composer\DependencyResolver\Operation\UpdateOperation; use Composer\EventDispatcher\EventSubscriberInterface; -use Composer\Factory; use Composer\Installer\PackageEvent; use Composer\Installer\PackageEvents; use Composer\IO\IOInterface; -use Composer\Json\JsonFile; -use Composer\Json\JsonManipulator; -use Composer\Package\Locker; use Composer\Plugin\Capability\CommandProvider as CommandProviderContract; use Composer\Plugin\Capable; use Composer\Plugin\PluginInterface; @@ -94,13 +90,10 @@ public static function getSubscribedEvents(): array } return [ - ScriptEvents::POST_MESSAGES => [['postMessages', \PHP_INT_MAX]], - PackageEvents::POST_PACKAGE_INSTALL => [['auditPackage', \PHP_INT_MAX]], - PackageEvents::POST_PACKAGE_UPDATE => [['auditPackage', \PHP_INT_MAX]], - PackageEvents::POST_PACKAGE_UNINSTALL => 'onPostUninstall', - ComposerScriptEvents::PRE_AUTOLOAD_DUMP => 'initMessage', + PackageEvents::POST_PACKAGE_INSTALL => [['auditPackage', ~\PHP_INT_MAX]], + PackageEvents::POST_PACKAGE_UPDATE => [['auditPackage', ~\PHP_INT_MAX]], ComposerScriptEvents::POST_INSTALL_CMD => [['auditComposerLock', \PHP_INT_MAX]], - ComposerScriptEvents::POST_UPDATE_CMD => [['auditComposerLock', \PHP_INT_MAX]], + ComposerScriptEvents::POST_UPDATE_CMD => [['auditComposerLock', \PHP_INT_MAX], ['onPostUpdatePostMessages', ~\PHP_INT_MAX]], ]; } @@ -112,7 +105,7 @@ public function activate(Composer $composer, IOInterface $io): void if (($errorMessage = $this->getErrorMessage()) !== null) { self::$activated = false; - $io->writeError('Narrowspark Automatic has been disabled. ' . $errorMessage . ''); + $io->writeError('Narrowspark Automatic Security Audit has been disabled. ' . $errorMessage . ''); return; } @@ -156,109 +149,6 @@ public function getCapabilities(): array ]; } - /** - * Execute on composer post-uninstall event. - * - * @param \Composer\Installer\PackageEvent $event - * - * @throws \Exception - * - * @return void - */ - public function onPostUninstall(PackageEvent $event): void - { - /** @var \Composer\DependencyResolver\Operation\UninstallOperation $operation */ - $operation = $event->getOperation(); - - if ($operation->getPackage()->getName() !== self::PACKAGE_NAME) { - return; - } - - $scripts = $this->composer->getPackage()->getScripts(); - - if (\count($scripts) === 0 || ! isset($scripts[ScriptEvents::POST_MESSAGES])) { - return; - } - - $composerFilePath = Factory::getComposerFile(); - $manipulator = new JsonManipulator(\file_get_contents($composerFilePath)); - - $manipulator->removeSubNode('scripts', ScriptEvents::POST_MESSAGES); - - $scriptKey = '@' . ScriptEvents::POST_MESSAGES; - - if (\in_array($scriptKey, $scripts[ComposerScriptEvents::POST_INSTALL_CMD] ?? [], true)) { - foreach ((array) $scripts[ComposerScriptEvents::POST_INSTALL_CMD] as $key => $script) { - if ($script === $scriptKey) { - unset($scripts[ComposerScriptEvents::POST_INSTALL_CMD][$key]); - } - } - - $manipulator->addSubNode('scripts', ComposerScriptEvents::POST_INSTALL_CMD, $scripts[ComposerScriptEvents::POST_INSTALL_CMD]); - } - - if (\in_array($scriptKey, $scripts[ComposerScriptEvents::POST_UPDATE_CMD] ?? [], true)) { - foreach ((array) $scripts[ComposerScriptEvents::POST_UPDATE_CMD] as $key => $script) { - if ($script === $scriptKey) { - unset($scripts[ComposerScriptEvents::POST_UPDATE_CMD][$key]); - } - } - - $manipulator->addSubNode('scripts', ComposerScriptEvents::POST_UPDATE_CMD, $scripts[ComposerScriptEvents::POST_UPDATE_CMD]); - } - - \file_put_contents($composerFilePath, $manipulator->getContents()); - - $this->updateComposerLock(); - } - - /** - * Add post-messages to root composer.json. - * - * @throws \Exception - * - * @return void - */ - public function initMessage(): void - { - $scripts = $this->composer->getPackage()->getScripts(); - - if (isset($scripts[ScriptEvents::POST_MESSAGES])) { - return; - } - - $composerFilePath = Factory::getComposerFile(); - $manipulator = new JsonManipulator(\file_get_contents($composerFilePath)); - - if (\count($scripts) === 0) { - $manipulator->addMainKey('scripts', []); - } - - $manipulator->addSubNode('scripts', ScriptEvents::POST_MESSAGES, 'This key is needed to show messages.'); - - $scriptKey = '@' . ScriptEvents::POST_MESSAGES; - - if (! \in_array($scriptKey, $scripts[ComposerScriptEvents::POST_INSTALL_CMD] ?? [], true)) { - $manipulator->addSubNode( - 'scripts', - ComposerScriptEvents::POST_INSTALL_CMD, - \array_merge($scripts[ComposerScriptEvents::POST_INSTALL_CMD] ?? [], [$scriptKey]) - ); - } - - if (! \in_array($scriptKey, $scripts[ComposerScriptEvents::POST_UPDATE_CMD] ?? [], true)) { - $manipulator->addSubNode( - 'scripts', - ComposerScriptEvents::POST_UPDATE_CMD, - \array_merge($scripts[ComposerScriptEvents::POST_UPDATE_CMD] ?? [], [$scriptKey]) - ); - } - - \file_put_contents($composerFilePath, $manipulator->getContents()); - - $this->updateComposerLock(); - } - /** * Execute on composer post-messages event. * @@ -266,10 +156,8 @@ public function initMessage(): void * * @return void */ - public function postMessages(Event $event): void + public function onPostUpdatePostMessages(Event $event): void { - $event->stopPropagation(); - $count = \count(\array_filter($this->foundVulnerabilities)); if ($count !== 0) { @@ -374,31 +262,4 @@ private static function getComposerVersion(): string throw new RuntimeException('No composer version found.'); } - - /** - * Update composer.lock file with the composer.json change. - * - * @throws \Exception - * - * @return void - */ - private function updateComposerLock(): void - { - $composerLockPath = Util::getComposerLockFile(); - $composerJson = \file_get_contents(Factory::getComposerFile()); - - $lockFile = new JsonFile($composerLockPath, null, $this->io); - $locker = new Locker( - $this->io, - $lockFile, - $this->composer->getRepositoryManager(), - $this->composer->getInstallationManager(), - (string) $composerJson - ); - - $lockData = $locker->getLockData(); - $lockData['content-hash'] = Locker::getContentHash((string) $composerJson); - - $lockFile->write($lockData); - } } diff --git a/tests/Automatic/AutomaticTest.php b/tests/Automatic/AutomaticTest.php index 1830e8f5..75f39566 100644 --- a/tests/Automatic/AutomaticTest.php +++ b/tests/Automatic/AutomaticTest.php @@ -392,26 +392,6 @@ public function testExecuteAutoScriptsWithoutScripts(): void $this->automatic->executeAutoScripts($eventMock); } - public function testPostMessages(): void - { - $eventMock = $this->mock(Event::class); - $eventMock->shouldReceive('stopPropagation') - ->once(); - - $this->ioMock->shouldReceive('write') - ->once() - ->with(['']); - - $containerMock = $this->mock(ContainerContract::class); - $containerMock->shouldReceive('get') - ->once() - ->with(IOInterface::class) - ->andReturn($this->ioMock); - - $this->automatic->setContainer($containerMock); - $this->automatic->postMessages($eventMock); - } - public function testPopulateFilesCacheDir(): void { $event = $this->mock(InstallerEvent::class); @@ -481,13 +461,10 @@ public function testOnPostUninstall(): void $lockfilePath = \mb_substr($filePath, 0, -4) . 'lock'; $scripts = [ - ScriptEvents::POST_MESSAGES => '', ComposerScriptEvents::POST_INSTALL_CMD => [ - '@' . ScriptEvents::POST_MESSAGES, '@' . ScriptEvents::AUTO_SCRIPTS, ], ComposerScriptEvents::POST_UPDATE_CMD => [ - '@' . ScriptEvents::POST_MESSAGES, '@' . ScriptEvents::AUTO_SCRIPTS, ], 'test' => 'this should stay', @@ -535,7 +512,6 @@ public function testOnPostUninstall(): void $jsonData = \json_decode(\file_get_contents($filePath), true); - static::assertArrayNotHasKey(ScriptEvents::POST_MESSAGES, $jsonData['scripts']); static::assertArrayHasKey('test', $jsonData['scripts']); static::assertCount(0, $jsonData['scripts'][ComposerScriptEvents::POST_INSTALL_CMD]); static::assertCount(0, $jsonData['scripts'][ComposerScriptEvents::POST_INSTALL_CMD]); @@ -563,6 +539,22 @@ public function testOnPostUninstallWithWithoutDev(): void $this->automatic->onPostUninstall($event); } + public function testOnPostUpdatePostMessages(): void + { + $this->ioMock->shouldReceive('write') + ->once(); + + $container = $this->mock(ContainerContract::class); + $container->shouldReceive('get') + ->once() + ->with(IOInterface::class) + ->andReturn($this->ioMock); + + $this->automatic->setContainer($container); + + $this->automatic->onPostUpdatePostMessages($this->mock(Event::class)); + } + /** * {@inheritdoc} */ diff --git a/tests/Security/SecurityPluginTest.php b/tests/Security/SecurityPluginTest.php index e222bb31..aa11f16d 100644 --- a/tests/Security/SecurityPluginTest.php +++ b/tests/Security/SecurityPluginTest.php @@ -5,12 +5,10 @@ use Composer\DependencyResolver\Operation\InstallOperation; use Composer\DependencyResolver\Operation\UninstallOperation; use Composer\DependencyResolver\Operation\UpdateOperation; -use Composer\Installer\InstallationManager; use Composer\Installer\PackageEvent; -use Composer\IO\NullIO; +use Composer\IO\IOInterface; use Composer\Package\PackageInterface; use Composer\Plugin\Capability\CommandProvider as CommandProviderContract; -use Composer\Repository\RepositoryManager; use Composer\Script\Event; use Narrowspark\Automatic\Security\Audit; use Narrowspark\Automatic\Security\CommandProvider; @@ -75,14 +73,14 @@ public function testActivate(): void $this->ioMock->shouldReceive('writeError') ->once() - ->with('Downloading the Security Advisories database...'); + ->with('Downloading the Security Advisories database...', true, IOInterface::VERBOSE); $this->securityPlugin->activate($this->composerMock, $this->ioMock); } public function testGetSubscribedEvents(): void { - static::assertCount(7, SecurityPlugin::getSubscribedEvents()); + static::assertCount(4, SecurityPlugin::getSubscribedEvents()); NSA::setProperty($this->securityPlugin, 'activated', false); @@ -94,11 +92,9 @@ public function testGetCapabilities(): void static::assertSame([CommandProviderContract::class => CommandProvider::class], $this->securityPlugin->getCapabilities()); } - public function testPostMessages(): void + public function testOnPostUpdatePostMessages(): void { $eventMock = $this->mock(Event::class); - $eventMock->shouldReceive('stopPropagation') - ->once(); $this->ioMock->shouldReceive('write') ->once() @@ -106,14 +102,12 @@ public function testPostMessages(): void NSA::setProperty($this->securityPlugin, 'io', $this->ioMock); - $this->securityPlugin->postMessages($eventMock); + $this->securityPlugin->onPostUpdatePostMessages($eventMock); } - public function testPostMessagesWithVulnerability(): void + public function testOnPostUpdatePostMessagesWithVulnerability(): void { $eventMock = $this->mock(Event::class); - $eventMock->shouldReceive('stopPropagation') - ->once(); NSA::setProperty($this->securityPlugin, 'foundVulnerabilities', ['test']); @@ -123,7 +117,7 @@ public function testPostMessagesWithVulnerability(): void NSA::setProperty($this->securityPlugin, 'io', $this->ioMock); - $this->securityPlugin->postMessages($eventMock); + $this->securityPlugin->onPostUpdatePostMessages($eventMock); } public function testAuditPackage(): void @@ -216,141 +210,6 @@ public function testAuditComposerLock(): void \putenv('COMPOSER'); } - public function testInitMessage(): void - { - $composerJsonPath = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixture' . \DIRECTORY_SEPARATOR . 'composer_on_init.json'; - $composerLockPath = \mb_substr($composerJsonPath, 0, -4) . 'lock'; - - \file_put_contents($composerJsonPath, \json_encode(['test' => []])); - \file_put_contents($composerLockPath, \json_encode(['packages' => []])); - - \putenv('COMPOSER=' . $composerJsonPath); - - $packageMock = $this->mock(PackageInterface::class); - $packageMock->shouldReceive('getScripts') - ->once() - ->andReturn([]); - - $this->composerMock - ->shouldReceive('getPackage') - ->once() - ->andReturn($packageMock); - - $repositoryManagerMock = $this->mock(RepositoryManager::class); - - $this->composerMock->shouldReceive('getRepositoryManager') - ->once() - ->andReturn($repositoryManagerMock); - - $installationManagerMock = $this->mock(InstallationManager::class); - - $this->composerMock->shouldReceive('getInstallationManager') - ->once() - ->andReturn($installationManagerMock); - - NSA::setProperty($this->securityPlugin, 'composer', $this->composerMock); - NSA::setProperty($this->securityPlugin, 'io', new NullIO()); - - $this->securityPlugin->initMessage(); - - $jsonContent = \json_decode(\file_get_contents($composerJsonPath), true); - - static::assertTrue(isset($jsonContent['scripts'])); - static::assertTrue(isset($jsonContent['scripts']['post-messages'])); - static::assertTrue(isset($jsonContent['scripts']['post-install-cmd'])); - static::assertTrue(isset($jsonContent['scripts']['post-update-cmd'])); - static::assertSame('@post-messages', $jsonContent['scripts']['post-install-cmd'][0]); - static::assertSame('@post-messages', $jsonContent['scripts']['post-update-cmd'][0]); - - $lockContent = \json_decode(\file_get_contents($composerLockPath), true); - - static::assertInternalType('string', $lockContent['content-hash']); - - \putenv('COMPOSER='); - \putenv('COMPOSER'); - @\unlink($composerJsonPath); - @\unlink($composerLockPath); - } - - public function testInitMessageWithPostMessages(): void - { - $packageMock = $this->mock(PackageInterface::class); - $packageMock->shouldReceive('getScripts') - ->once() - ->andReturn(['post-messages' => '']); - - $this->composerMock - ->shouldReceive('getPackage') - ->once() - ->andReturn($packageMock); - - NSA::setProperty($this->securityPlugin, 'composer', $this->composerMock); - - $this->securityPlugin->initMessage(); - } - - public function testOnPostUninstall(): void - { - $composerJsonPath = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixture' . \DIRECTORY_SEPARATOR . 'composer_on_init.json'; - $composerLockPath = \mb_substr($composerJsonPath, 0, -4) . 'lock'; - - $scripts = ['post-messages' => 'test', 'post-install-cmd' => ['@post-messages', 'foo'], 'post-update-cmd' => ['@post-messages', 'bar']]; - - \file_put_contents($composerJsonPath, \json_encode(['name' => 'test', 'scripts' => $scripts])); - \file_put_contents($composerLockPath, \json_encode(['packages' => []])); - - \putenv('COMPOSER=' . $composerJsonPath); - - $packageMock = $this->mock(PackageInterface::class); - $packageMock->shouldReceive('getScripts') - ->once() - ->andReturn($scripts); - - $this->composerMock - ->shouldReceive('getPackage') - ->once() - ->andReturn($packageMock); - - $repositoryManagerMock = $this->mock(RepositoryManager::class); - - $this->composerMock->shouldReceive('getRepositoryManager') - ->once() - ->andReturn($repositoryManagerMock); - - $installationManagerMock = $this->mock(InstallationManager::class); - - $this->composerMock->shouldReceive('getInstallationManager') - ->once() - ->andReturn($installationManagerMock); - - NSA::setProperty($this->securityPlugin, 'io', new NullIO()); - NSA::setProperty($this->securityPlugin, 'composer', $this->composerMock); - - $event = $this->mock(PackageEvent::class); - $event->shouldReceive('getOperation->getPackage->getName') - ->andReturn(SecurityPlugin::PACKAGE_NAME); - - $this->securityPlugin->onPostUninstall($event); - - $jsonContent = \json_decode(\file_get_contents($composerJsonPath), true); - - static::assertTrue(isset($jsonContent['scripts'])); - static::assertFalse(isset($jsonContent['scripts']['post-messages'])); - static::assertTrue(isset($jsonContent['scripts']['post-install-cmd'])); - static::assertTrue(isset($jsonContent['scripts']['post-update-cmd'])); - static::assertCount(1, $jsonContent['scripts']['post-install-cmd']); - static::assertCount(1, $jsonContent['scripts']['post-update-cmd']); - - $lockContent = \json_decode(\file_get_contents($composerLockPath), true); - - static::assertInternalType('string', $lockContent['content-hash']); - - \putenv('COMPOSER='); - \putenv('COMPOSER'); - @\unlink($composerJsonPath); - @\unlink($composerLockPath); - } - /** * {@inheritdoc} */