mirror of
https://github.com/getgrav/grav.git
synced 2026-07-05 08:49:21 +02:00
Merge branch 'feature/gpm_dependency' into develop
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
<?php
|
||||
namespace Grav\Common\GPM;
|
||||
|
||||
use Grav\Common\Inflector;
|
||||
use Grav\Common\Iterator;
|
||||
use Grav\Common\Utils;
|
||||
|
||||
class GPM extends Iterator
|
||||
{
|
||||
@@ -28,6 +30,8 @@ class GPM extends Iterator
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
protected $install_paths = ['plugins' => 'user/plugins/%name%', 'themes' => 'user/themes/%name%', 'skeletons' => 'user/'];
|
||||
|
||||
/**
|
||||
* Creates a new GPM instance with Local and Remote packages available
|
||||
* @param boolean $refresh Applies to Remote Packages only and forces a refetch of data
|
||||
@@ -347,7 +351,20 @@ class GPM extends Iterator
|
||||
$packages = ['total' => 0, 'not_found' => []];
|
||||
|
||||
foreach ($searches as $search) {
|
||||
$repository = '';
|
||||
// if this is an object, get the search data from the key
|
||||
if (is_object($search)) {
|
||||
$search = (array) $search;
|
||||
$key = key($search);
|
||||
$repository = $search[$key];
|
||||
$search = $key;
|
||||
}
|
||||
|
||||
if ($found = $this->findPackage($search)) {
|
||||
// set override respository if provided
|
||||
if ($repository) {
|
||||
$found->override_repository = $repository;
|
||||
}
|
||||
if (!isset($packages[$found->package_type])) {
|
||||
$packages[$found->package_type] = [];
|
||||
}
|
||||
@@ -355,7 +372,19 @@ class GPM extends Iterator
|
||||
$packages[$found->package_type][$found->slug] = $found;
|
||||
$packages['total']++;
|
||||
} else {
|
||||
$packages['not_found'][] = $search;
|
||||
// make a best guess at the type based on the repo URL
|
||||
if (Utils::contains($repository, '-theme')) {
|
||||
$type = 'themes';
|
||||
} else {
|
||||
$type = 'plugins';
|
||||
}
|
||||
|
||||
$not_found = new \stdClass();
|
||||
$not_found->name = Inflector::camelize($search);
|
||||
$not_found->slug = $search;
|
||||
$not_found->install_path = str_replace('%name%', $search, $this->install_paths[$type]);
|
||||
$not_found->override_repository = $repository;
|
||||
$packages['not_found'][$search] = $not_found;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ class Plugins extends Iterator
|
||||
|
||||
$filePath = $this->grav['locator']('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT);
|
||||
if (!is_file($filePath)) {
|
||||
throw new \RuntimeException(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin));
|
||||
$this->grav['log']->addWarning(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin));
|
||||
continue;
|
||||
}
|
||||
|
||||
require_once $filePath;
|
||||
|
||||
@@ -5,6 +5,8 @@ use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\GPM\GPM;
|
||||
use Grav\Common\GPM\Installer;
|
||||
use Grav\Common\GPM\Response;
|
||||
use Grav\Common\Inflector;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
@@ -12,6 +14,10 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
define('GIT_REGEX', '/http[s]?:\/\/(?:.*@)?(github|bitbucket)(?:.org|.com)\/.*\/(.*)/');
|
||||
|
||||
/**
|
||||
* Class InstallCommand
|
||||
@@ -42,6 +48,9 @@ class InstallCommand extends Command
|
||||
*/
|
||||
protected $tmp;
|
||||
|
||||
protected $local_config;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -93,6 +102,11 @@ class InstallCommand extends Command
|
||||
$packages = array_map('strtolower', $this->input->getArgument('package'));
|
||||
$this->data = $this->gpm->findPackages($packages);
|
||||
|
||||
$local_config_file = exec('eval echo ~/.grav/config');
|
||||
if (file_exists($local_config_file)) {
|
||||
$this->local_config = Yaml::parse($local_config_file);
|
||||
}
|
||||
|
||||
if (
|
||||
!Installer::isGravInstance($this->destination) ||
|
||||
!Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK])
|
||||
@@ -111,7 +125,7 @@ class InstallCommand extends Command
|
||||
|
||||
if (count($this->data['not_found'])) {
|
||||
$this->output->writeln("These packages were not found on Grav: <red>" . implode('</red>, <red>',
|
||||
$this->data['not_found']) . "</red>");
|
||||
array_keys($this->data['not_found'])) . "</red>");
|
||||
}
|
||||
|
||||
unset($this->data['not_found']);
|
||||
@@ -119,11 +133,131 @@ class InstallCommand extends Command
|
||||
|
||||
foreach ($this->data as $data) {
|
||||
foreach ($data as $package) {
|
||||
$version = isset($package->available) ? $package->available : $package->version;
|
||||
$this->output->writeln("Preparing to install <cyan>" . $package->name . "</cyan> [v" . $version . "]");
|
||||
|
||||
$this->output->write(" |- Downloading package... 0%");
|
||||
$this->file = $this->downloadPackage($package);
|
||||
//Check for dependencies
|
||||
if (isset($package->dependencies)) {
|
||||
$this->output->writeln("Package <cyan>" . $package->name . "</cyan> has ". count($package->dependencies) . " required dependencies that must be installed first...");
|
||||
$this->output->writeln('');
|
||||
|
||||
$dependency_data = $this->gpm->findPackages($package->dependencies);
|
||||
|
||||
if (!$dependency_data['total']) {
|
||||
$this->output->writeln("No dependencies found...");
|
||||
$this->output->writeln('');
|
||||
} else {
|
||||
unset($dependency_data['total']);
|
||||
|
||||
foreach($dependency_data as $type => $dep_data) {
|
||||
foreach($dep_data as $name => $dep_package) {
|
||||
|
||||
$this->processPackage($dep_package);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->processPackage($package);
|
||||
}
|
||||
}
|
||||
|
||||
// clear cache after successful upgrade
|
||||
$this->clearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $package
|
||||
*/
|
||||
private function processPackage($package)
|
||||
{
|
||||
$install_options = ['GPM'];
|
||||
|
||||
// if no name, not found in GPM
|
||||
if (!isset($package->version)) {
|
||||
unset($install_options[0]);
|
||||
}
|
||||
// if local config found symlink is a valid option
|
||||
if (isset($this->local_config)) {
|
||||
$install_options[] = 'Symlink';
|
||||
}
|
||||
// if override set, can install via git
|
||||
if (isset($package->override_repository)) {
|
||||
$install_options[] = 'Git';
|
||||
}
|
||||
|
||||
// reindex list
|
||||
$install_options = array_values($install_options);
|
||||
|
||||
if (count($install_options) == 0) {
|
||||
// no valid install options - error and return
|
||||
$this->output->writeln("<red>not valid installation methods found!</red>");
|
||||
return;
|
||||
} elseif (count($install_options) == 1) {
|
||||
// only one option, use it...
|
||||
$method = $install_options[0];
|
||||
} else {
|
||||
$helper = $this->getHelper('question');
|
||||
$question = new ChoiceQuestion(
|
||||
'Please select installation method for <cyan>' . $package->name . '</cyan> (<magenta>'.$install_options[0].' is default</magenta>)', array_values($install_options), 0
|
||||
);
|
||||
$question->setErrorMessage('Method %s is invalid');
|
||||
$method = $helper->ask($this->input, $this->output, $question);
|
||||
}
|
||||
|
||||
$this->output->writeln('');
|
||||
|
||||
$method_name = 'process'.$method;
|
||||
|
||||
$this->$method_name($package);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $package
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getGitRegexMatches($package)
|
||||
{
|
||||
if (isset($package->override_repository)) {
|
||||
$repository = $package->override_repository;
|
||||
} elseif (isset($package->repository)) {
|
||||
$repository = $package->repository;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
preg_match(GIT_REGEX, $repository, $matches);
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $package
|
||||
*/
|
||||
private function processSymlink($package)
|
||||
{
|
||||
|
||||
exec('cd ' . $this->destination);
|
||||
|
||||
$to = $this->destination . DS . $package->install_path;
|
||||
|
||||
$matches = $this->getGitRegexMatches($package);
|
||||
|
||||
$this->output->writeln("Preparing to Symlink <cyan>" . $package->name . "</cyan>");
|
||||
$this->output->write(" |- Checking source... ");
|
||||
|
||||
foreach ($this->local_config as $path) {
|
||||
|
||||
if (Utils::endsWith($matches[2], '.git')) {
|
||||
$repo_dir = preg_replace('/\.git$/', '', $matches[2]);
|
||||
} else {
|
||||
$repo_dir = $matches[2];
|
||||
}
|
||||
|
||||
$from = rtrim($path, '/') . '/' . $repo_dir;
|
||||
|
||||
if (file_exists($from)) {
|
||||
|
||||
$this->output->writeln("<green>ok</green>");
|
||||
|
||||
$this->output->write(" |- Checking destination... ");
|
||||
$checks = $this->checkDestination($package);
|
||||
@@ -132,21 +266,86 @@ class InstallCommand extends Command
|
||||
$this->output->writeln(" '- <red>Installation failed or aborted.</red>");
|
||||
$this->output->writeln('');
|
||||
} else {
|
||||
$this->output->write(" |- Installing package... ");
|
||||
$installation = $this->installPackage($package);
|
||||
if (!$installation) {
|
||||
$this->output->writeln(" '- <red>Installation failed or aborted.</red>");
|
||||
if (file_exists($to)) {
|
||||
$this->output->writeln(" '- <red>Symlink cannot overwrite an existing package, please remove first</red>");
|
||||
$this->output->writeln('');
|
||||
} else {
|
||||
symlink($from, $to);
|
||||
|
||||
// extra white spaces to clear out the buffer properly
|
||||
$this->output->writeln(" |- Symlinking package... <green>ok</green> ");
|
||||
|
||||
$this->output->writeln(" '- <green>Success!</green> ");
|
||||
$this->output->writeln('');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->output->writeln("<red>not found!</red>");
|
||||
$this->output->writeln(" '- <red>Installation failed or aborted.</red>");
|
||||
}
|
||||
|
||||
// clear cache after successful upgrade
|
||||
$this->clearCache();
|
||||
/**
|
||||
* @param $package
|
||||
*/
|
||||
private function processGit($package)
|
||||
{
|
||||
$matches = $this->getGitRegexMatches($package);
|
||||
|
||||
$to = $this->destination . DS . $package->install_path;
|
||||
|
||||
$this->output->writeln("Preparing to Git clone <cyan>" . $package->name . "</cyan> from " . $matches[0]);
|
||||
|
||||
$this->output->write(" |- Checking destination... ");
|
||||
$checks = $this->checkDestination($package);
|
||||
|
||||
if (!$checks) {
|
||||
$this->output->writeln(" '- <red>Installation failed or aborted.</red>");
|
||||
$this->output->writeln('');
|
||||
} else {
|
||||
$cmd = 'cd ' . $this->destination . ' && git clone ' . $matches[0] . ' ' . $package->install_path;
|
||||
exec($cmd);
|
||||
|
||||
// extra white spaces to clear out the buffer properly
|
||||
$this->output->writeln(" |- Cloning package... <green>ok</green> ");
|
||||
|
||||
$this->output->writeln(" '- <green>Success!</green> ");
|
||||
$this->output->writeln('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $package
|
||||
*/
|
||||
private function processGPM($package)
|
||||
{
|
||||
$version = isset($package->available) ? $package->available : $package->version;
|
||||
|
||||
$this->output->writeln("Preparing to install <cyan>" . $package->name . "</cyan> [v" . $version . "]");
|
||||
|
||||
$this->output->write(" |- Downloading package... 0%");
|
||||
$this->file = $this->downloadPackage($package);
|
||||
|
||||
$this->output->write(" |- Checking destination... ");
|
||||
$checks = $this->checkDestination($package);
|
||||
|
||||
if (!$checks) {
|
||||
$this->output->writeln(" '- <red>Installation failed or aborted.</red>");
|
||||
$this->output->writeln('');
|
||||
} else {
|
||||
$this->output->write(" |- Installing package... ");
|
||||
$installation = $this->installPackage($package);
|
||||
if (!$installation) {
|
||||
$this->output->writeln(" '- <red>Installation failed or aborted.</red>");
|
||||
$this->output->writeln('');
|
||||
} else {
|
||||
$this->output->writeln(" '- <green>Success!</green> ");
|
||||
$this->output->writeln('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,6 +417,8 @@ class InstallCommand extends Command
|
||||
$this->output->writeln(" | '- <red>You decided to not delete the symlink automatically.</red>");
|
||||
|
||||
return false;
|
||||
} else {
|
||||
unlink($this->destination . DS . $package->install_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user