Add update channels support to self-update and diagnose, fixes #4960
parent
653326e215
commit
0db8bbfda3
|
@ -22,7 +22,8 @@ use Composer\Util\ConfigValidator;
|
||||||
use Composer\Util\ProcessExecutor;
|
use Composer\Util\ProcessExecutor;
|
||||||
use Composer\Util\RemoteFilesystem;
|
use Composer\Util\RemoteFilesystem;
|
||||||
use Composer\Util\StreamContextFactory;
|
use Composer\Util\StreamContextFactory;
|
||||||
use Composer\Util\Keys;
|
use Composer\SelfUpdate\Keys;
|
||||||
|
use Composer\SelfUpdate\Versions;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ EOT
|
||||||
$this->outputResult($this->checkPubKeys($config));
|
$this->outputResult($this->checkPubKeys($config));
|
||||||
|
|
||||||
$io->write('Checking composer version: ', false);
|
$io->write('Checking composer version: ', false);
|
||||||
$this->outputResult($this->checkVersion());
|
$this->outputResult($this->checkVersion($config));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->failures;
|
return $this->failures;
|
||||||
|
@ -364,13 +365,13 @@ EOT
|
||||||
return $errors ?: true;
|
return $errors ?: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkVersion()
|
private function checkVersion($config)
|
||||||
{
|
{
|
||||||
$protocol = extension_loaded('openssl') ? 'https' : 'http';
|
$versionsUtil = new Versions($config, $this->rfs);
|
||||||
$latest = trim($this->rfs->getContents('getcomposer.org', $protocol . '://getcomposer.org/version', false));
|
$latest = $versionsUtil->getLatest();
|
||||||
|
|
||||||
if (Composer::VERSION !== $latest && Composer::VERSION !== '@package_version@') {
|
if (Composer::VERSION !== $latest['version'] && Composer::VERSION !== '@package_version@') {
|
||||||
return '<comment>You are not running the latest version, run `composer self-update` to update</comment>';
|
return '<comment>You are not running the latest '.$versionsUtil->getChannel().' version, run `composer self-update` to update ('.Composer::VERSION.' => '.$latest['version'].')</comment>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -16,7 +16,8 @@ use Composer\Composer;
|
||||||
use Composer\Factory;
|
use Composer\Factory;
|
||||||
use Composer\Config;
|
use Composer\Config;
|
||||||
use Composer\Util\Filesystem;
|
use Composer\Util\Filesystem;
|
||||||
use Composer\Util\Keys;
|
use Composer\SelfUpdate\Keys;
|
||||||
|
use Composer\SelfUpdate\Versions;
|
||||||
use Composer\IO\IOInterface;
|
use Composer\IO\IOInterface;
|
||||||
use Composer\Downloader\FilesystemException;
|
use Composer\Downloader\FilesystemException;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
@ -47,6 +48,9 @@ class SelfUpdateCommand extends BaseCommand
|
||||||
new InputArgument('version', InputArgument::OPTIONAL, 'The version to update to'),
|
new InputArgument('version', InputArgument::OPTIONAL, 'The version to update to'),
|
||||||
new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
|
new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
|
||||||
new InputOption('update-keys', null, InputOption::VALUE_NONE, 'Prompt user for a key update'),
|
new InputOption('update-keys', null, InputOption::VALUE_NONE, 'Prompt user for a key update'),
|
||||||
|
new InputOption('stable', null, InputOption::VALUE_NONE, 'Force an update to the stable channel'),
|
||||||
|
new InputOption('preview', null, InputOption::VALUE_NONE, 'Force an update to the preview channel'),
|
||||||
|
new InputOption('snapshot', null, InputOption::VALUE_NONE, 'Force an update to the snapshot channel'),
|
||||||
))
|
))
|
||||||
->setHelp(<<<EOT
|
->setHelp(<<<EOT
|
||||||
The <info>self-update</info> command checks getcomposer.org for newer
|
The <info>self-update</info> command checks getcomposer.org for newer
|
||||||
|
@ -72,6 +76,15 @@ EOT
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
$remoteFilesystem = Factory::createRemoteFilesystem($io, $config);
|
$remoteFilesystem = Factory::createRemoteFilesystem($io, $config);
|
||||||
|
|
||||||
|
$versionsUtil = new Versions($config, $remoteFilesystem);
|
||||||
|
|
||||||
|
// switch channel if requested
|
||||||
|
foreach (array('stable', 'preview', 'snapshot') as $channel) {
|
||||||
|
if ($input->getOption($channel)) {
|
||||||
|
$versionsUtil->setChannel($channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$cacheDir = $config->get('cache-dir');
|
$cacheDir = $config->get('cache-dir');
|
||||||
$rollbackDir = $config->get('data-dir');
|
$rollbackDir = $config->get('data-dir');
|
||||||
$home = $config->get('home');
|
$home = $config->get('home');
|
||||||
|
@ -93,7 +106,8 @@ EOT
|
||||||
return $this->rollback($output, $rollbackDir, $localFilename);
|
return $this->rollback($output, $rollbackDir, $localFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
$latestVersion = trim($remoteFilesystem->getContents(self::HOMEPAGE, $baseUrl. '/version', false));
|
$latest = $versionsUtil->getLatest();
|
||||||
|
$latestVersion = $latest['version'];
|
||||||
$updateVersion = $input->getArgument('version') ?: $latestVersion;
|
$updateVersion = $input->getArgument('version') ?: $latestVersion;
|
||||||
|
|
||||||
if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {
|
if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Composer\Util;
|
namespace Composer\SelfUpdate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\SelfUpdate;
|
||||||
|
|
||||||
|
use Composer\Util\RemoteFilesystem;
|
||||||
|
use Composer\Config;
|
||||||
|
use Composer\Json\JsonFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*/
|
||||||
|
class Versions
|
||||||
|
{
|
||||||
|
private $rfs;
|
||||||
|
private $config;
|
||||||
|
private $channel;
|
||||||
|
|
||||||
|
public function __construct(Config $config, RemoteFilesystem $rfs)
|
||||||
|
{
|
||||||
|
$this->rfs = $rfs;
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChannel()
|
||||||
|
{
|
||||||
|
if ($this->channel) {
|
||||||
|
return $this->channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
$channelFile = $this->config->get('home').'/update-channel';
|
||||||
|
if (file_exists($channelFile)) {
|
||||||
|
$channel = trim(file_get_contents($channelFile));
|
||||||
|
if (in_array($channel, array('stable', 'preview', 'snapshot'), true)) {
|
||||||
|
return $this->channel = $channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->channel = 'stable';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setChannel($channel)
|
||||||
|
{
|
||||||
|
if (!in_array($channel, array('stable', 'preview', 'snapshot'), true)) {
|
||||||
|
throw new \InvalidArgumentException('Invalid channel '.$channel.', must be one of: stable, preview, snapshot');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channelFile = $this->config->get('home').'/update-channel';
|
||||||
|
$this->channel = $channel;
|
||||||
|
file_put_contents($channelFile, $channel.PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLatest()
|
||||||
|
{
|
||||||
|
$protocol = extension_loaded('openssl') ? 'https' : 'http';
|
||||||
|
$versions = JsonFile::parseJson($this->rfs->getContents('getcomposer.org', $protocol . '://getcomposer.org/versions', false));
|
||||||
|
|
||||||
|
foreach ($versions[$this->getChannel()] as $version) {
|
||||||
|
if ($version['min-php'] <= PHP_VERSION_ID) {
|
||||||
|
return $version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \LogicException('There is no version of Composer available for your PHP version ('.PHP_VERSION.')');
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue