diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php index 686a48b02165..99f8f4ec6f1f 100644 --- a/src/Composer/Command/SelfUpdateCommand.php +++ b/src/Composer/Command/SelfUpdateCommand.php @@ -104,7 +104,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0]; if ($input->getOption('update-keys')) { - return $this->fetchKeys($io, $config); + $this->fetchKeys($io, $config); + + return 0; } // ensure composer.phar location is accessible @@ -417,7 +419,14 @@ protected function setLocalPhar($localFilename, $newFilename, $backupTarget = nu } try { - rename($newFilename, $localFilename); + if (Platform::isWindows()) { + // use copy to apply permissions from the destination directory + // as rename uses source permissions and may block other users + copy($newFilename, $localFilename); + @unlink($newFilename); + } else { + rename($newFilename, $localFilename); + } return true; } catch (\Exception $e) { @@ -428,6 +437,7 @@ protected function setLocalPhar($localFilename, $newFilename, $backupTarget = nu return $this->tryAsWindowsAdmin($localFilename, $newFilename); } + @unlink($newFilename); $action = 'Composer '.($backupTarget ? 'update' : 'rollback'); throw new FilesystemException($action.' failed: "'.$localFilename.'" could not be written.'.PHP_EOL.$e->getMessage()); } @@ -528,7 +538,7 @@ protected function isWindowsNonAdminUser() /** * Invokes a UAC prompt to update composer.phar as an admin * - * Uses a .vbs script to elevate and run the cmd.exe move command. + * Uses a .vbs script to elevate and run the cmd.exe copy command. * * @param string $localFilename The composer.phar location * @param string $newFilename The downloaded or backup phar @@ -554,13 +564,13 @@ protected function tryAsWindowsAdmin($localFilename, $newFilename) $checksum = hash_file('sha256', $newFilename); - // cmd's internal move is fussy about backslashes + // cmd's internal copy is fussy about backslashes $source = str_replace('/', '\\', $newFilename); $destination = str_replace('/', '\\', $localFilename); $vbs = <<writeError('Operation succeeded.'); + @unlink($newFilename); } else { - $io->writeError('Operation failed (file not written). '.$helpMessage.''); - }; + $io->writeError('Operation failed.'.$helpMessage.''); + } return $result; }