Merge branch 'feature/gpm_dependency' into develop

This commit is contained in:
Andy Miller
2015-02-15 15:30:25 -07:00
3 changed files with 244 additions and 13 deletions

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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);
}
}