123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- <?php
- /**
- * @package Grav\Console\Gpm
- *
- * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
- * @license MIT License; see LICENSE file for details.
- */
- namespace Grav\Console\Gpm;
- use Grav\Common\GPM\Remote\Package;
- use Grav\Common\GPM\GPM;
- use Grav\Common\GPM\Remote\Packages;
- use Grav\Common\Utils;
- use Grav\Console\ConsoleCommand;
- use League\CLImate\CLImate;
- use Symfony\Component\Console\Input\InputOption;
- class IndexCommand extends ConsoleCommand
- {
- /** @var array */
- protected $data;
- /** @var GPM */
- protected $gpm;
- /** @var array */
- protected $options;
- /** @var array */
- protected $sortKeys = ['name', 'slug', 'author', 'date'];
- protected function configure()
- {
- $this
- ->setName('index')
- ->addOption(
- 'force',
- 'f',
- InputOption::VALUE_NONE,
- 'Force re-fetching the data from remote'
- )
- ->addOption(
- 'filter',
- 'F',
- InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
- 'Allows to limit the results based on one or multiple filters input. This can be either portion of a name/slug or a regex'
- )
- ->addOption(
- 'themes-only',
- 'T',
- InputOption::VALUE_NONE,
- 'Filters the results to only Themes'
- )
- ->addOption(
- 'plugins-only',
- 'P',
- InputOption::VALUE_NONE,
- 'Filters the results to only Plugins'
- )
- ->addOption(
- 'updates-only',
- 'U',
- InputOption::VALUE_NONE,
- 'Filters the results to Updatable Themes and Plugins only'
- )
- ->addOption(
- 'installed-only',
- 'I',
- InputOption::VALUE_NONE,
- 'Filters the results to only the Themes and Plugins you have installed'
- )
- ->addOption(
- 'sort',
- 's',
- InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
- 'Allows to sort (ASC) the results based on one or multiple keys. SORT can be either "name", "slug", "author", "date"',
- ['date']
- )
- ->addOption(
- 'desc',
- 'D',
- InputOption::VALUE_NONE,
- 'Reverses the order of the output.'
- )
- ->setDescription('Lists the plugins and themes available for installation')
- ->setHelp('The <info>index</info> command lists the plugins and themes available for installation')
- ;
- }
- protected function serve()
- {
- $this->options = $this->input->getOptions();
- $this->gpm = new GPM($this->options['force']);
- $this->displayGPMRelease();
- $this->data = $this->gpm->getRepository();
- $data = $this->filter($this->data);
- $climate = new CLImate;
- $climate->extend('Grav\Console\TerminalObjects\Table');
- if (!$data) {
- $this->output->writeln('No data was found in the GPM repository stored locally.');
- $this->output->writeln('Please try clearing cache and running the <green>bin/gpm index -f</green> command again');
- $this->output->writeln('If this doesn\'t work try tweaking your GPM system settings.');
- $this->output->writeln('');
- $this->output->writeln('For more help go to:');
- $this->output->writeln(' -> <yellow>https://learn.getgrav.org/troubleshooting/common-problems#cannot-connect-to-the-gpm</yellow>');
- die;
- }
- foreach ($data as $type => $packages) {
- $this->output->writeln('<green>' . strtoupper($type) . '</green> [ ' . \count($packages) . ' ]');
- $packages = $this->sort($packages);
- if (!empty($packages)) {
- $table = [];
- $index = 0;
- foreach ($packages as $slug => $package) {
- $row = [
- 'Count' => $index++ + 1,
- 'Name' => '<cyan>' . Utils::truncate($package->name, 20, false, ' ', '...') . '</cyan> ',
- 'Slug' => $slug,
- 'Version'=> $this->version($package),
- 'Installed' => $this->installed($package)
- ];
- $table[] = $row;
- }
- $climate->table($table);
- }
- $this->output->writeln('');
- }
- $this->output->writeln('You can either get more informations about a package by typing:');
- $this->output->writeln(" <green>{$this->argv} info <cyan><package></cyan></green>");
- $this->output->writeln('');
- $this->output->writeln('Or you can install a package by typing:');
- $this->output->writeln(" <green>{$this->argv} install <cyan><package></cyan></green>");
- $this->output->writeln('');
- }
- /**
- * @param Package $package
- *
- * @return string
- */
- private function version($package)
- {
- $list = $this->gpm->{'getUpdatable' . ucfirst($package->package_type)}();
- $package = $list[$package->slug] ?? $package;
- $type = ucfirst(preg_replace('/s$/', '', $package->package_type));
- $updatable = $this->gpm->{'is' . $type . 'Updatable'}($package->slug);
- $installed = $this->gpm->{'is' . $type . 'Installed'}($package->slug);
- $local = $this->gpm->{'getInstalled' . $type}($package->slug);
- if (!$installed || !$updatable) {
- $version = $installed ? $local->version : $package->version;
- return "v<green>{$version}</green>";
- }
- if ($updatable) {
- return "v<red>{$package->version}</red> <cyan>-></cyan> v<green>{$package->available}</green>";
- }
- return '';
- }
- /**
- * @param Package $package
- *
- * @return string
- */
- private function installed($package)
- {
- $package = $list[$package->slug] ?? $package;
- $type = ucfirst(preg_replace('/s$/', '', $package->package_type));
- $method = 'is' . $type . 'Installed';
- $installed = $this->gpm->{$method}($package->slug);
- return !$installed ? '<magenta>not installed</magenta>' : '<cyan>installed</cyan>';
- }
- /**
- * @param array $data
- *
- * @return mixed
- */
- public function filter($data)
- {
- // filtering and sorting
- if ($this->options['plugins-only']) {
- unset($data['themes']);
- }
- if ($this->options['themes-only']) {
- unset($data['plugins']);
- }
- $filter = [
- $this->options['filter'],
- $this->options['installed-only'],
- $this->options['updates-only'],
- $this->options['desc']
- ];
- if (\count(array_filter($filter))) {
- foreach ($data as $type => $packages) {
- foreach ($packages as $slug => $package) {
- $filter = true;
- // Filtering by string
- if ($this->options['filter']) {
- $filter = preg_grep('/(' . implode('|', $this->options['filter']) . ')/i', [$slug, $package->name]);
- }
- // Filtering updatables only
- if ($filter && $this->options['installed-only']) {
- $method = ucfirst(preg_replace('/s$/', '', $package->package_type));
- $function = 'is' . $method . 'Installed';
- $filter = $this->gpm->{$function}($package->slug);
- }
- // Filtering updatables only
- if ($filter && $this->options['updates-only']) {
- $method = ucfirst(preg_replace('/s$/', '', $package->package_type));
- $function = 'is' . $method . 'Updatable';
- $filter = $this->gpm->{$function}($package->slug);
- }
- if (!$filter) {
- unset($data[$type][$slug]);
- }
- }
- }
- }
- return $data;
- }
- /**
- * @param Packages $packages
- */
- public function sort($packages)
- {
- foreach ($this->options['sort'] as $key) {
- $packages = $packages->sort(function ($a, $b) use ($key) {
- switch ($key) {
- case 'author':
- return strcmp($a->{$key}['name'], $b->{$key}['name']);
- break;
- default:
- return strcmp($a->$key, $b->$key);
- }
- }, $this->options['desc'] ? true : false);
- }
- return $packages;
- }
- }
|