-
-
Notifications
You must be signed in to change notification settings - Fork 73
Ignore the global plugin when updating local projects #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1389111
bb06fb0
c2b19bc
f41e139
e33915c
287fd91
b0e1aae
f12ab08
7ec5c0e
5c62f98
ef6de8c
10e40bd
19da477
3879b3c
c054b5e
c03754c
b0e4201
0180eab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,27 +80,33 @@ public static function getSubscribedEvents() | |
| */ | ||
| public static function dumpVersionsClass(Event $composerEvent) | ||
| { | ||
| $io = $composerEvent->getIO(); | ||
| $composer = $composerEvent->getComposer(); | ||
| $versions = iterator_to_array(self::getVersions($composer->getLocker(), $composer->getPackage())); | ||
|
|
||
| $io->write('<info>ocramius/package-versions:</info> Generating version class...'); | ||
| if (!array_key_exists('ocramius/package-versions', $versions)) { | ||
| //plugin must be globally installed - we only want to generate versions for projects which specifically | ||
| //require ocramius/package-versions | ||
| return; | ||
| } | ||
|
|
||
| $composer = $composerEvent->getComposer(); | ||
| $io = $composerEvent->getIO(); | ||
| $io->write('<info>ocramius/package-versions:</info> Generating version class...'); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll add an info message in the previous block as well. Otherwise, users may get confused on why this isn't running. |
||
|
|
||
| self::writeVersionClassToFile( | ||
| self::generateVersionsClass($composer), | ||
| self::generateVersionsClass($versions), | ||
| $composer->getConfig(), | ||
| $composer->getPackage() | ||
| ); | ||
|
|
||
| $io->write('<info>ocramius/package-versions:</info> ...done generating version class'); | ||
| } | ||
|
|
||
| private static function generateVersionsClass(Composer $composer) : string | ||
| private static function generateVersionsClass(array $versions) : string | ||
| { | ||
| return sprintf( | ||
| self::$generatedClassTemplate, | ||
| 'fin' . 'al ' . 'cla' . 'ss ' . 'Versions', // note: workaround for regex-based code parsers :-( | ||
| var_export(iterator_to_array(self::getVersions($composer->getLocker(), $composer->getPackage())), true) | ||
| var_export($versions, true) | ||
| ); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,245 @@ | ||
| <?php | ||
|
|
||
| namespace PackageVersionsTest; | ||
|
|
||
| use PHPUnit_Framework_TestCase; | ||
| use RecursiveCallbackFilterIterator; | ||
| use RecursiveDirectoryIterator; | ||
| use RecursiveIteratorIterator; | ||
| use SplFileInfo; | ||
| use ZipArchive; | ||
|
|
||
| /** | ||
| * @coversNothing | ||
| */ | ||
| class E2EInstaller extends PHPUnit_Framework_TestCase | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Going to rename/move this class around. Also will add
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure thing - wasn't really sure how to name it |
||
| { | ||
| /** | ||
| * @var string | ||
| */ | ||
| private $tempGlobalComposerHome; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be added: docblocks
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added |
||
|
|
||
| /** | ||
| * @var string | ||
| */ | ||
| private $tempLocalComposerHome; | ||
|
|
||
| /** | ||
| * @var string | ||
| */ | ||
| private $tempArtifact; | ||
|
|
||
| public function setUp() | ||
| { | ||
| $this->tempGlobalComposerHome = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/global'; | ||
| $this->tempLocalComposerHome = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/local'; | ||
| $this->tempArtifact = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/artifacts'; | ||
| mkdir($this->tempGlobalComposerHome, 0700, true); | ||
| mkdir($this->tempLocalComposerHome, 0700, true); | ||
| mkdir($this->tempArtifact, 0700, true); | ||
|
|
||
| putenv('COMPOSER_HOME=' . $this->tempGlobalComposerHome); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This environment variable must be reset in |
||
| } | ||
|
|
||
| public function tearDown() | ||
| { | ||
| $this->rmDir($this->tempGlobalComposerHome); | ||
| $this->rmDir($this->tempLocalComposerHome); | ||
| $this->rmDir($this->tempArtifact); | ||
|
|
||
| putenv('COMPOSER_HOME'); | ||
| } | ||
|
|
||
| public function testGloballyInstalledPluginDoesNotGenerateVersionsForLocalProject() | ||
| { | ||
| $this->createPackageVersionsArtifact(); | ||
|
|
||
| $this->writeComposerJsonFile( | ||
| [ | ||
| 'name' => 'package-versions/e2e-global', | ||
| 'require' => [ | ||
| 'ocramius/package-versions' => '1.0.0' | ||
| ], | ||
| 'repositories' => [ | ||
| [ | ||
| 'packagist' => false, | ||
| ], | ||
| [ | ||
| 'type' => 'artifact', | ||
| 'url' => $this->tempArtifact, | ||
| ] | ||
| ] | ||
| ], | ||
| $this->tempGlobalComposerHome | ||
| ); | ||
|
|
||
| $this->execComposerInDir('global update', $this->tempGlobalComposerHome); | ||
|
|
||
| $this->createArtifact(); | ||
| $this->writeComposerJsonFile( | ||
| [ | ||
| 'name' => 'package-versions/e2e-local', | ||
| 'require' => [ | ||
| 'test/package' => '2.0.0' | ||
| ], | ||
| 'repositories' => [ | ||
| [ | ||
| 'packagist' => false, | ||
| ], | ||
| [ | ||
| 'type' => 'artifact', | ||
| 'url' => $this->tempArtifact, | ||
| ] | ||
| ] | ||
| ], | ||
| $this->tempLocalComposerHome | ||
| ); | ||
|
|
||
| $this->execComposerInDir('update', $this->tempLocalComposerHome); | ||
| $this->assertFileNotExists( | ||
| $this->tempLocalComposerHome . '/vendor/ocramius/package-versions/src/PackageVersions/Versions.php' | ||
| ); | ||
| } | ||
|
|
||
| public function testRemovingPluginDoesNotAttemptToGenerateVersions() | ||
| { | ||
| $this->createPackageVersionsArtifact(); | ||
| $this->createArtifact(); | ||
|
|
||
| $this->writeComposerJsonFile( | ||
| [ | ||
| 'name' => 'package-versions/e2e-local', | ||
| 'require' => [ | ||
| 'test/package' => '2.0.0', | ||
| 'ocramius/package-versions' => '1.0.0' | ||
| ], | ||
| 'repositories' => [ | ||
| [ | ||
| 'packagist' => false, | ||
| ], | ||
| [ | ||
| 'type' => 'artifact', | ||
| 'url' => $this->tempArtifact, | ||
| ] | ||
| ] | ||
| ], | ||
| $this->tempLocalComposerHome | ||
| ); | ||
|
|
||
| $this->execComposerInDir('update', $this->tempLocalComposerHome); | ||
| $this->assertFileExists( | ||
| $this->tempLocalComposerHome . '/vendor/ocramius/package-versions/src/PackageVersions/Versions.php' | ||
| ); | ||
|
|
||
| $this->execComposerInDir('remove ocramius/package-versions', $this->tempLocalComposerHome); | ||
|
|
||
| $this->assertFileNotExists( | ||
| $this->tempLocalComposerHome . '/vendor/ocramius/package-versions/src/PackageVersions/Versions.php' | ||
| ); | ||
| } | ||
|
|
||
| private function createPackageVersionsArtifact() | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this return the path to the generated artifact?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont think so - the path to the zip isn't used for anything, just the folder where they reside |
||
| { | ||
| $zip = new ZipArchive(); | ||
|
|
||
| $zip->open($this->tempArtifact . '/ocramius-package-versions-1.0.0.zip', ZipArchive::CREATE); | ||
|
|
||
| $files = array_filter( | ||
| iterator_to_array(new RecursiveIteratorIterator( | ||
| new RecursiveCallbackFilterIterator( | ||
| new RecursiveDirectoryIterator(realpath(__DIR__ . '/../../'), RecursiveDirectoryIterator::SKIP_DOTS), | ||
| function (SplFileInfo $file, $key, RecursiveDirectoryIterator $iterator) { | ||
| return $iterator->getSubPathname()[0] !== '.' && $iterator->getSubPathname() !== 'vendor'; | ||
| } | ||
| ), | ||
| RecursiveIteratorIterator::LEAVES_ONLY | ||
| )), | ||
| function (SplFileInfo $file) { | ||
| return !$file->isDir(); | ||
| } | ||
| ); | ||
|
|
||
| array_walk( | ||
| $files, | ||
| function (SplFileInfo $file) use ($zip) { | ||
| if ($file->getFilename() === 'composer.json') { | ||
| $contents = json_decode(file_get_contents($file->getRealPath()), true); | ||
| $contents['version'] = '1.0.0'; | ||
|
|
||
| return $zip->addFromString('composer.json', json_encode($contents)); | ||
| } | ||
|
|
||
| $zip->addFile( | ||
| $file->getRealPath(), | ||
| substr($file->getRealPath(), strlen(realpath(__DIR__ . '/../../')) + 1) | ||
| ); | ||
| } | ||
| ); | ||
|
|
||
| $zip->close(); | ||
| } | ||
|
|
||
| private function createArtifact() | ||
| { | ||
| $zip = new ZipArchive(); | ||
|
|
||
| $zip->open($this->tempArtifact . '/test-package-2.0.0.zip', ZipArchive::CREATE); | ||
| $zip->addFromString( | ||
| 'composer.json', | ||
| json_encode( | ||
| [ | ||
| 'name' => 'test/package', | ||
| 'version' => '2.0.0' | ||
| ], | ||
| JSON_PRETTY_PRINT | ||
| ) | ||
| ); | ||
| $zip->close(); | ||
| } | ||
|
|
||
| private function writeComposerJsonFile(array $config, string $directory) | ||
| { | ||
| file_put_contents( | ||
| $directory . '/composer.json', | ||
| json_encode($config, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) | ||
| ); | ||
| } | ||
|
|
||
| private function execComposerInDir(string $command, string $dir) : array | ||
| { | ||
| $currentDir = getcwd(); | ||
| chdir($dir); | ||
| exec(__DIR__ . '/../../vendor/bin/composer ' . $command . ' 2> /dev/null', $output, $exitCode); | ||
| $this->assertEquals(0, $exitCode); | ||
| chdir($currentDir); | ||
| return $output; | ||
| } | ||
|
|
||
| /** | ||
| * @param string $directory | ||
| * | ||
| * @return void | ||
| */ | ||
| private function rmDir(string $directory) | ||
| { | ||
| if (! is_dir($directory)) { | ||
| unlink($directory); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| array_map( | ||
| function ($item) use ($directory) { | ||
| $this->rmDir($directory . '/' . $item); | ||
| }, | ||
| array_filter( | ||
| scandir($directory), | ||
| function (string $dirItem) { | ||
| return ! in_array($dirItem, ['.', '..'], true); | ||
| } | ||
| ) | ||
| ); | ||
|
|
||
| rmdir($directory); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AydinHassan just a doubt, given that there's no real way to know from the code: what about when the package is indirectly depending on
package-versions? Will it still run?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also: what about when we are currently operating in package-versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ocramius will run in both contexts as it would be in the lock file - is that expected?
The first is actually my use case - A globally installed tool depends on
PackageVersions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AydinHassan great, thanks!