Skip to content

Commit

Permalink
Merge pull request #23 from kamazee/fix_self_update
Browse files Browse the repository at this point in the history
Run self update in a subprocess
  • Loading branch information
kamazee committed Mar 3, 2021
2 parents 6e5831d + 1423f65 commit 307a62d
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 20 deletions.
62 changes: 50 additions & 12 deletions composer
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* If it breaks, check out newer version or report an issue at
* https://github.com/kamazee/composer-wrapper
*
* @version 1.2.0
* @version 1.2.1
*/
if (!class_exists('ComposerWrapper')) {
class ComposerWrapperParams {
Expand Down Expand Up @@ -397,12 +397,8 @@ if (!class_exists('ComposerWrapper')) {

protected function selfUpdate($filename)
{
$selfUpdateCommand = \sprintf('%s self-update', \escapeshellarg($filename));
$selfUpdateCommand .= $this->getSelfUpdateFlags($filename);
$this->passthru(
$selfUpdateCommand,
$exitCode
);
$arguments = array_merge(array('self-update'), $this->getSelfUpdateFlags($filename));
$exitCode = $this->runByRealComposerSubprocess($filename, $arguments);

// composer exits both when self-update downloaded a new version
// and when no new version was available (and everything went OK)
Expand All @@ -414,10 +410,26 @@ if (!class_exists('ComposerWrapper')) {
}
}

public function runByRealComposerSubprocess($filename, array $arguments)
{
$command = \escapeshellarg($filename);

if (count($arguments) > 0) {
$command .= ' ' . implode(' ', array_map('escapeshellarg', $arguments));
}

$this->passthru(
$command,
$exitCode
);

return $exitCode;
}

private function getSelfUpdateFlags($filename)
{
$forceVersionRequested = $this->params->getForceMajorVersion();
$flags = '';
$flags = array();
if (null === $forceVersionRequested) {
return $flags;
}
Expand All @@ -432,10 +444,10 @@ if (!class_exists('ComposerWrapper')) {
$command = implode(' ', $commandParts);

if ($this->supportsForceVersionFlag($command, $forceVersionRequested)) {
$flags .= " --$forceVersionRequested";
$flags[] = "--$forceVersionRequested";
} elseif (1 == $forceVersionRequested) {
// 1.10.5 supports flags, so should be a good intermediate version
$flags .= ' 1.10.5';
$flags[] = '1.10.5';
} else {
$this->showError(
"Forcing version $forceVersionRequested is requested but current composer version doesn't support --$forceVersionRequested flag, so nothing will be forced."
Expand Down Expand Up @@ -489,16 +501,39 @@ if (!class_exists('ComposerWrapper')) {
\fwrite(STDERR, $text . "\n");
}

protected function isSelfUpdate($cliArguments)
{
foreach ($cliArguments as $cliArgument) {
if ('-' === \substr($cliArgument, 0, 1)) {
continue;
}

// If the first argument that is not a CLI option (i.e. not starts with dash, '-'),
// and it's self-update, it should be run in a subprocess rather than delegated
// because otherwise wrapper will be replaced
if ('self-update' === $cliArgument || 'selfupdate' === $cliArgument) {
return true;
}
}

return false;
}

/**
* @throws Exception
*/
public function run()
public function run($cliArguments)
{
$this->params->loadReal();
$composerPathName = "{$this->params->getComposerDir()}/composer.phar";

$this->ensureInstalled($composerPathName);
$this->ensureExecutable($composerPathName);

if ($this->isSelfUpdate($cliArguments)) {
return $this->runByRealComposerSubprocess($composerPathName, $cliArguments);
}

$this->ensureUpToDate($composerPathName);
$this->delegate($composerPathName);
}
Expand All @@ -509,7 +544,10 @@ if ('cli' === \PHP_SAPI && @\realpath($_SERVER['argv'][0]) === __FILE__) {
$runner = new ComposerWrapper();

try {
$runner->run();
$exitCode = $runner->run(\array_slice($_SERVER['argv'], 1));
if (null !== $exitCode) {
exit($exitCode);
}
} catch (Exception $e) {
$runner->showError('ERROR: ' . $e->getMessage());
exit($e->getCode());
Expand Down
54 changes: 46 additions & 8 deletions tests/ComposerWrapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ public function selfUpdateWorks()
->getMock();
$wrapper->expects($this->once())
->method('passthru')
->with("'{$file->url()}' self-update", $this->anything())
->with("'{$file->url()}' 'self-update'", $this->anything())
->willReturnCallback(function ($command, &$exitCode) { $exitCode = 0; });

self::callNonPublic($wrapper, 'selfUpdate', array($file->url()));
Expand Down Expand Up @@ -462,7 +462,7 @@ public function addsForceVersionFlag($version, $supportsFlags, $flag, $expectErr
$wrapper->expects($this->once())->method('passthru')->with()
->willReturnCallback(
function($command, &$exitCode) use ($self, $flag) {
$self->assertStringEndsWith(' self-update' . (null === $flag ? '' : " $flag"), $command);
$self->assertStringEndsWith(" 'self-update'" . (null === $flag ? '' : " '$flag'"), $command);
$exitCode = 0;
}
);
Expand Down Expand Up @@ -495,7 +495,7 @@ public function printsWarningWhenUpdateFailsToSelfUpdate()
->getMock();
$wrapper->expects($this->once())
->method('passthru')
->with("'$file' self-update", $this->anything())
->with("'$file' 'self-update'", $this->anything())
->willReturnCallback(function ($command, &$exitCode) { $exitCode = 1; });
$wrapper->expects($this->once())
->method('showError')
Expand Down Expand Up @@ -543,7 +543,7 @@ public function runCallsAllRequiredMethods($expectedComposerDir, $mockDelegate =
->willReturn(null);
}

$runnerMock->run();
$runnerMock->run(array());
}

/**
Expand All @@ -569,6 +569,48 @@ public function passThroughWrapperWorksWithReferences()
$this->assertEquals(1, $exitCode);
}

/**
* @test
* @dataProvider detectSelfUpdateDataProvider
* @param array $arguments
* @param bool $expected
*/
public function detectsSelfUpdate($arguments, $expected)
{
$wrapper = new ComposerWrapper();
$actual = self::callNonPublic($wrapper, 'isSelfUpdate', array($arguments));
self::assertSame($expected, $actual);
}

public static function detectSelfUpdateDataProvider()
{
return array(
'selfupdate' => array(array('selfupdate'), true),
'self-update' => array(array('self-update'), true),
'-v selfupdate' => array(array('-v', 'selfupdate'), true),
'-v self-update' => array(array('-v', 'self-update'), true),
'no arguments' => array(array(), false),
'install' => array(array('install'), false),
'-v install' => array(array('-v', 'install'), false),
);
}

/**
* @test
*/
public function passesThruOnSelfUpdate()
{
$mock = $this->getMockBuilder('ComposerWrapper')
->setMethods(array('runByRealComposerSubprocess', 'delegate', 'ensureInstalled', 'ensureExecutable'))
->getMock();
$mock->expects(self::once())->method('ensureInstalled')->willReturn(true);
$mock->expects(self::once())->method('ensureExecutable')->willReturn(true);
$mock->expects(self::never())->method('delegate');
$mock->expects(self::once())->method('runByRealComposerSubprocess')->willReturn(0);
$exitCode = $mock->run(array('self-update'));
self::assertSame(0, $exitCode);
}

/**
* @test
* @dataProvider selfUpdateHelpProvider
Expand Down Expand Up @@ -629,8 +671,4 @@ public static function selfUpdateHelpProvider()
)
);
}




}

0 comments on commit 307a62d

Please sign in to comment.