Skip to content
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

Ignore the global plugin when updating local projects #39

Merged
merged 18 commits into from
Dec 30, 2016

Conversation

AydinHassan
Copy link
Contributor

@AydinHassan AydinHassan commented Oct 26, 2016

I had to refactor a little to reduce repeating code, anyway this fixes #38.

However, I've had a think and I don't know how we can provide an e2e test. We could provide some project assets but we'd have to mess with the systems global composer project, which I don't think we can do safely.

I've also had to modify existing tests, I wasn't sure how to get them working now that we need ocramius/package-versions to be present in the locker.

Thoughts @Ocramius ?

@AydinHassan AydinHassan force-pushed the ignore-global-plugin-in-local branch from 89d18a5 to 1389111 Compare October 26, 2016 16:48
@AydinHassan
Copy link
Contributor Author

AydinHassan commented Oct 26, 2016

This patch also has the added benefit of fixing another crash. After removing ocramius/package-versions the plugin still runs an attempts to generate the version file, but the folder does not exist anymore.

Running: composer remove ocramius/package-versions (before this patch) results in:

Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Removing ocramius/package-versions (1.1.1)
Package guzzle/guzzle is abandoned, you should avoid using it. Use guzzlehttp/guzzle instead.
Writing lock file
Generating autoload files
ocramius/package-versions:  Generating version class...

Removal failed, reverting ./composer.json to its original content.


  [ErrorException]                                                                                                                                                               
  file_put_contents(/Users/aydin/projects/package-versions-test/vendor/ocramius/package-versions/src/PackageVersions/Versions.php): failed to open stream: No such file or directory  


remove [--dev] [--no-progress] [--no-update] [--no-scripts] [--update-no-dev] [--update-with-dependencies] [--no-update-with-dependencies] [--ignore-platform-reqs] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--] [<packages>]...

Admittedly this can be circumvented using --no-plugins but I think this is slightly more elegant and provides the consumer with no surprises.

@AydinHassan
Copy link
Contributor Author

@Ocramius managed to get an E2E test working - it's a bit gross so I'd appreciate any pointers for it 😄

@Ocramius Ocramius added the bug label Oct 26, 2016
@Ocramius Ocramius added this to the 1.1.2 milestone Oct 26, 2016

$composer = $composerEvent->getComposer();
$io = $composerEvent->getIO();
$io->write('<info>ocramius/package-versions:</info> Generating version class...');
Copy link
Owner

Choose a reason for hiding this comment

The 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.

/**
* @author Aydin Hassan <aydin@hotmail.co.uk>
*/
class E2EInstaller extends PHPUnit_Framework_TestCase
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to rename/move this class around. Also will add @coversNothing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing - wasn't really sure how to name it

*/
class E2EInstaller extends PHPUnit_Framework_TestCase
{
private $tempGlobalComposerHome;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be added: docblocks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

{
$this->createPackageVersionsArtifact();

file_put_contents($this->tempGlobalComposerHome . '/composer.json', json_encode([
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This alignment is not PSR-2 compliant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed up - I introduced a method to write

$this->exec(__DIR__ . '/../../vendor/bin/composer global update');

$this->createArtifact();
file_put_contents($this->tempLocalComposerHome . '/composer.json', json_encode([
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

$filePath = substr($file->getRealPath(), strlen(realpath(__DIR__ . '/../../')) + 1);

if (substr($filePath, 0, 4) === '.git'
|| substr($filePath, 0, 5) === '.idea'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply skip anything that starts with .

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's something in the recursive directory iterator for that, btw

Copy link
Contributor Author

@AydinHassan AydinHassan Oct 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You got a link? I couldn't find anything other than SKIP_DOTS which doesn't consider anything other than .. & . I've simplified it now anyway - so should be better

function (SplFileInfo $file) {
$filePath = substr($file->getRealPath(), strlen(realpath(__DIR__ . '/../../')) + 1);

if (substr($filePath, 0, 4) === '.git'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block is a negated boolean expression, not an if/else block

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've simplified this a little

$zip->addFromString('composer.json', json_encode([
'name' => 'test/package',
'version' => '2.0.0',
], JSON_PRETTY_PRINT)).
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alignment broken here too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

);
}

private function createPackageVersionsArtifact()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this return the path to the generated artifact?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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


private function exec(string $command) : array
{
exec($command . ' 2> /dev/null', $output);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to assert that the exit code is 0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an assertion in

@AydinHassan
Copy link
Contributor Author

Seems to be failing on lowest deps - trying to figure out now

@AydinHassan
Copy link
Contributor Author

AydinHassan commented Oct 30, 2016

Hmm - the composer exec output seems to print errors such as

Fatal error: Uncaught Error: Class 'Symfony\Component\Process\ProcessUtils' not found in /Users/aydin/projects/PackageVersions/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php on line 124

On further investigation I would say this is a bug with Composer:

\Composer\Util\ProcessExecutor uses Symfony\Component\Process\ProcessUtils from symfony/process. Composer constraint on symfony/process is "^2.1 || ^3.0" but it seems ProcessUtils was only introduced in 2.3

@Ocramius
Copy link
Owner

On further investigation I would say this is a bug with Composer:

We should then report it in composer and bump the required version there, I suppose...

@AydinHassan
Copy link
Contributor Author

I've filed composer/composer#5828 & created composer/composer#5831 to fix it (maybe). I've bumped the minimum in here to ^2.3 also - should get the tests running.

@@ -16,7 +16,8 @@
"require-dev": {
"phpunit/phpunit": "^5.4.7",
"composer/composer": "^1.2.0",
"ext-zip": "*"
"ext-zip": "*",
"symfony/process": "^2.3"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this required should be pushed into composer

@AydinHassan
Copy link
Contributor Author

OK composer/composer#5831 is merged now - guessing you want to wait for a tag before we pursue this?

@AydinHassan
Copy link
Contributor Author

hey @Ocramius composer 1.3 has been released with the necessary fixes. Tests are passing now 😄 .

@Ocramius
Copy link
Owner

@AydinHassan looking good! Going through a quick sweep of the code, then merging :-)


$io->write('<info>ocramius/package-versions:</info> Generating version class...');
if (!isset($versions['ocramius/package-versions'])) {
//plugin must be globally installed - we only want to generate versions for projects which specifically
Copy link
Owner

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?

Copy link
Owner

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?

Copy link
Contributor Author

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.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AydinHassan great, thanks!


$io->write('<info>ocramius/package-versions:</info> Generating version class...');
if (!isset($versions['ocramius/package-versions'])) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be an array_key_exists() at this point - don't trust the value below it

mkdir($this->tempLocalComposerHome, 0777, true);
mkdir($this->tempArtifact, 0777, true);

putenv('COMPOSER_HOME=' . $this->tempGlobalComposerHome);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This environment variable must be reset in tearDown

$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, 0777, true);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use 0700 for test runs

$this->tempLocalComposerHome = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/local';
$this->tempArtifact = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/artifacts';
mkdir($this->tempGlobalComposerHome, 0777, true);
mkdir($this->tempLocalComposerHome, 0777, true);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use 0700 for test runs

$this->tempArtifact = sys_get_temp_dir() . '/' . uniqid('InstallerTest', true) . '/artifacts';
mkdir($this->tempGlobalComposerHome, 0777, true);
mkdir($this->tempLocalComposerHome, 0777, true);
mkdir($this->tempArtifact, 0777, true);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use 0700 for test runs

@Ocramius
Copy link
Owner

LGTM! \o/

@Ocramius Ocramius merged commit ea07d4e into Ocramius:master Dec 30, 2016
@AydinHassan AydinHassan deleted the ignore-global-plugin-in-local branch January 2, 2017 21:32
@weirdan
Copy link

weirdan commented Nov 11, 2017

@samsonasik are there chances this will get backported to your fork? There's no way to report issues on forks, unfortunately.

@samsonasik
Copy link
Contributor

@weirdan I tried backport but it seems needs very long time to get it work as I state at samsonasik#3 (comment) . Pull Request open if you can invest a time to patch ;)

@Ocramius
Copy link
Owner

I know @samsonasik did the backport with good intentions, but if you want to talk about older PHP versions support here, I'm gonna lock the thread: just upgrade your installation to a contemporary PHP binary.

@weirdan
Copy link

weirdan commented Nov 12, 2017

Oh, we were merely talking about porting changes from upstream to the fork. And I'm running 7.1, which, last time I checked, was pretty contemporary.

@Ocramius
Copy link
Owner

Then you don't need the fork ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Interferes with other projects when installed globally
4 participants