Skip to content

Commit

Permalink
Merge pull request #39 from AydinHassan/ignore-global-plugin-in-local
Browse files Browse the repository at this point in the history
Ignore the global plugin when updating local projects
  • Loading branch information
Ocramius authored Dec 30, 2016
2 parents 4e22ddf + 0180eab commit ea07d4e
Show file tree
Hide file tree
Showing 4 changed files with 339 additions and 8 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
},
"require-dev": {
"phpunit/phpunit": "^5.4.7",
"composer/composer": "^1.2.0"
"composer/composer": "^1.3",
"ext-zip": "*"
},
"autoload": {
"psr-4": {
Expand Down
18 changes: 12 additions & 6 deletions src/PackageVersions/Installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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...');

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)
);
}

Expand Down
245 changes: 245 additions & 0 deletions test/PackageVersionsTest/E2EInstallerTest.php
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
{
/**
* @var string
*/
private $tempGlobalComposerHome;

/**
* @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);
}

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()
{
$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);
}
}
Loading

0 comments on commit ea07d4e

Please sign in to comment.