286 lines
9.0 KiB
PHP
286 lines
9.0 KiB
PHP
<?php
|
|
/**
|
|
* @package Grav.Console
|
|
*
|
|
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
|
* @license MIT License; see LICENSE file for details.
|
|
*/
|
|
|
|
namespace Grav\Console\Gpm;
|
|
|
|
use Grav\Common\GPM\GPM;
|
|
use Grav\Common\GPM\Installer;
|
|
use Grav\Console\ConsoleCommand;
|
|
use Grav\Common\GPM\Upgrader;
|
|
use Symfony\Component\Console\Input\ArrayInput;
|
|
use Symfony\Component\Console\Input\InputArgument;
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
|
|
|
class UpdateCommand extends ConsoleCommand
|
|
{
|
|
/**
|
|
* @var
|
|
*/
|
|
protected $data;
|
|
/**
|
|
* @var
|
|
*/
|
|
protected $extensions;
|
|
/**
|
|
* @var
|
|
*/
|
|
protected $updatable;
|
|
/**
|
|
* @var
|
|
*/
|
|
protected $destination;
|
|
/**
|
|
* @var
|
|
*/
|
|
protected $file;
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $types = ['plugins', 'themes'];
|
|
/**
|
|
* @var GPM $gpm
|
|
*/
|
|
protected $gpm;
|
|
|
|
protected $all_yes;
|
|
|
|
protected $overwrite;
|
|
|
|
/**
|
|
* @var Upgrader
|
|
*/
|
|
protected $upgrader;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
protected function configure()
|
|
{
|
|
$this
|
|
->setName("update")
|
|
->addOption(
|
|
'force',
|
|
'f',
|
|
InputOption::VALUE_NONE,
|
|
'Force re-fetching the data from remote'
|
|
)
|
|
->addOption(
|
|
'destination',
|
|
'd',
|
|
InputOption::VALUE_OPTIONAL,
|
|
'The grav instance location where the updates should be applied to. By default this would be where the grav cli has been launched from',
|
|
GRAV_ROOT
|
|
)
|
|
->addOption(
|
|
'all-yes',
|
|
'y',
|
|
InputOption::VALUE_NONE,
|
|
'Assumes yes (or best approach) instead of prompting'
|
|
)
|
|
->addOption(
|
|
'overwrite',
|
|
'o',
|
|
InputOption::VALUE_NONE,
|
|
'Option to overwrite packages if they already exist'
|
|
)
|
|
->addOption(
|
|
'plugins',
|
|
'p',
|
|
InputOption::VALUE_NONE,
|
|
'Update only plugins'
|
|
)
|
|
->addOption(
|
|
'themes',
|
|
't',
|
|
InputOption::VALUE_NONE,
|
|
'Update only themes'
|
|
)
|
|
->addArgument(
|
|
'package',
|
|
InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
|
|
'The package or packages that is desired to update. By default all available updates will be applied.'
|
|
)
|
|
->setDescription("Detects and performs an update of plugins and themes when available")
|
|
->setHelp('The <info>update</info> command updates plugins and themes when a new version is available');
|
|
}
|
|
|
|
/**
|
|
* @return int|null|void
|
|
*/
|
|
protected function serve()
|
|
{
|
|
$this->upgrader = new Upgrader($this->input->getOption('force'));
|
|
$local = $this->upgrader->getLocalVersion();
|
|
$remote = $this->upgrader->getRemoteVersion();
|
|
if ($local !== $remote) {
|
|
$this->output->writeln("<yellow>WARNING</yellow>: A new version of Grav is available. You should update Grav before updating plugins and themes. If you continue without updating Grav, some plugins or themes may stop working.");
|
|
$this->output->writeln("");
|
|
$questionHelper = $this->getHelper('question');
|
|
$question = new ConfirmationQuestion("Continue with the update process? [Y|n] ", true);
|
|
$answer = $questionHelper->ask($this->input, $this->output, $question);
|
|
|
|
if (!$answer) {
|
|
$this->output->writeln("<red>Update aborted. Exiting...</red>");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
$this->gpm = new GPM($this->input->getOption('force'));
|
|
|
|
$this->all_yes = $this->input->getOption('all-yes');
|
|
$this->overwrite = $this->input->getOption('overwrite');
|
|
|
|
$this->displayGPMRelease();
|
|
|
|
$this->destination = realpath($this->input->getOption('destination'));
|
|
|
|
if (!Installer::isGravInstance($this->destination)) {
|
|
$this->output->writeln("<red>ERROR</red>: " . Installer::lastErrorMsg());
|
|
exit;
|
|
}
|
|
if ($this->input->getOption('plugins') === false && $this->input->getOption('themes') === false) {
|
|
$list_type = ['plugins' => true, 'themes' => true];
|
|
} else {
|
|
$list_type['plugins'] = $this->input->getOption('plugins');
|
|
$list_type['themes'] = $this->input->getOption('themes');
|
|
}
|
|
|
|
if ($this->overwrite) {
|
|
$this->data = $this->gpm->getInstallable($list_type);
|
|
$description = " can be overwritten";
|
|
} else {
|
|
$this->data = $this->gpm->getUpdatable($list_type);
|
|
$description = " need updating";
|
|
}
|
|
|
|
$only_packages = array_map('strtolower', $this->input->getArgument('package'));
|
|
|
|
if (!$this->overwrite && !$this->data['total']) {
|
|
$this->output->writeln("Nothing to update.");
|
|
exit;
|
|
}
|
|
|
|
$this->output->write("Found <green>" . $this->gpm->countInstalled() . "</green> packages installed of which <magenta>" . $this->data['total'] . "</magenta>" . $description);
|
|
|
|
$limit_to = $this->userInputPackages($only_packages);
|
|
|
|
$this->output->writeln('');
|
|
|
|
unset($this->data['total']);
|
|
unset($limit_to['total']);
|
|
|
|
|
|
// updates review
|
|
$slugs = [];
|
|
|
|
$index = 0;
|
|
foreach ($this->data as $packages) {
|
|
foreach ($packages as $slug => $package) {
|
|
if (count($only_packages) && !array_key_exists($slug, $limit_to)) {
|
|
continue;
|
|
}
|
|
|
|
if (!$package->available) {
|
|
$package->available = $package->version;
|
|
}
|
|
|
|
$this->output->writeln(
|
|
// index
|
|
str_pad($index++ + 1, 2, '0', STR_PAD_LEFT) . ". " .
|
|
// name
|
|
"<cyan>" . str_pad($package->name, 15) . "</cyan> " .
|
|
// version
|
|
"[v<magenta>" . $package->version . "</magenta> -> v<green>" . $package->available . "</green>]"
|
|
);
|
|
$slugs[] = $slug;
|
|
}
|
|
}
|
|
|
|
if (!$this->all_yes) {
|
|
// prompt to continue
|
|
$this->output->writeln("");
|
|
$questionHelper = $this->getHelper('question');
|
|
$question = new ConfirmationQuestion("Continue with the update process? [Y|n] ", true);
|
|
$answer = $questionHelper->ask($this->input, $this->output, $question);
|
|
|
|
if (!$answer) {
|
|
$this->output->writeln("<red>Update aborted. Exiting...</red>");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// finally update
|
|
$install_command = $this->getApplication()->find('install');
|
|
|
|
$args = new ArrayInput([
|
|
'command' => 'install',
|
|
'package' => $slugs,
|
|
'-f' => $this->input->getOption('force'),
|
|
'-d' => $this->destination,
|
|
'-y' => true
|
|
]);
|
|
$command_exec = $install_command->run($args, $this->output);
|
|
|
|
if ($command_exec != 0) {
|
|
$this->output->writeln("<red>Error:</red> An error occurred while trying to install the packages");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $only_packages
|
|
*
|
|
* @return array
|
|
*/
|
|
private function userInputPackages($only_packages)
|
|
{
|
|
$found = ['total' => 0];
|
|
$ignore = [];
|
|
|
|
if (!count($only_packages)) {
|
|
$this->output->writeln('');
|
|
} else {
|
|
foreach ($only_packages as $only_package) {
|
|
$find = $this->gpm->findPackage($only_package);
|
|
|
|
if (!$find || (!$this->overwrite && !$this->gpm->isUpdatable($find->slug))) {
|
|
$name = isset($find->slug) ? $find->slug : $only_package;
|
|
$ignore[$name] = $name;
|
|
} else {
|
|
$found[$find->slug] = $find;
|
|
$found['total']++;
|
|
}
|
|
}
|
|
|
|
if ($found['total']) {
|
|
$list = $found;
|
|
unset($list['total']);
|
|
$list = array_keys($list);
|
|
|
|
if ($found['total'] !== $this->data['total']) {
|
|
$this->output->write(", only <magenta>" . $found['total'] . "</magenta> will be updated");
|
|
}
|
|
|
|
$this->output->writeln('');
|
|
$this->output->writeln("Limiting updates for only <cyan>" . implode('</cyan>, <cyan>',
|
|
$list) . "</cyan>");
|
|
}
|
|
|
|
if (count($ignore)) {
|
|
$this->output->writeln('');
|
|
$this->output->writeln("Packages not found or not requiring updates: <red>" . implode('</red>, <red>',
|
|
$ignore) . "</red>");
|
|
|
|
}
|
|
}
|
|
|
|
return $found;
|
|
}
|
|
}
|