mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 18:03:17 +00:00
Add plugin:list command
This commit is contained in:
@@ -16,6 +16,7 @@ namespace KonsoleKommander;
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
use Alchemy\Phrasea\Command\Plugin\ListPlugin;
|
||||
use Alchemy\Phrasea\Core\Version;
|
||||
use Alchemy\Phrasea\Command\BuildMissingSubdefs;
|
||||
use Alchemy\Phrasea\Command\CreateCollection;
|
||||
@@ -94,6 +95,7 @@ $cli->command(new RescanTechnicalDatas('records:rescan-technical-datas'));
|
||||
$cli->command(new BuildMissingSubdefs('records:build-missing-subdefs'));
|
||||
|
||||
$cli->command(new AddPlugin());
|
||||
$cli->command(new ListPlugin());
|
||||
$cli->command(new RemovePlugin());
|
||||
$cli->command(new Configuration());
|
||||
$cli->command(new XSendFileConfigurationDumper());
|
||||
|
48
lib/Alchemy/Phrasea/Command/Plugin/ListPlugin.php
Normal file
48
lib/Alchemy/Phrasea/Command/Plugin/ListPlugin.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Command\Plugin;
|
||||
|
||||
use Alchemy\Phrasea\Plugin\Plugin;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ListPlugin extends AbstractPluginCommand
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('plugins:list');
|
||||
|
||||
$this
|
||||
->setDescription('Lists installed plugins');
|
||||
}
|
||||
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$plugins = array_map(function (Plugin $plugin) {
|
||||
if ($plugin->isErroneous()) {
|
||||
return array('<error>'.$plugin->getName().'</error>', '<error>Error : '.$plugin->getError()->getMessage().'</error>', '');
|
||||
}
|
||||
|
||||
return array($plugin->getName(), $plugin->getManifest()->getVersion(), $plugin->getManifest()->getDescription());
|
||||
}, $this->container['plugins.manager']->listPlugins());
|
||||
|
||||
$table = $this->getHelperSet()->get('table');
|
||||
$table
|
||||
->setHeaders(array('Name', 'Version', 'Description'))
|
||||
->setRows($plugins)
|
||||
;
|
||||
|
||||
$table->render($output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Core\CLIProvider;
|
||||
|
||||
use Alchemy\Phrasea\Plugin\PluginManager;
|
||||
use Alchemy\Phrasea\Plugin\Schema\ManifestValidator;
|
||||
use Alchemy\Phrasea\Plugin\Management\PluginsExplorer;
|
||||
use Alchemy\Phrasea\Plugin\Management\ComposerInstaller;
|
||||
@@ -31,6 +32,10 @@ class PluginServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
$app['plugins.schema'] = realpath(__DIR__ . '/../../../../conf.d/plugin-schema.json');
|
||||
|
||||
$app['plugins.manager'] = $app->share(function (Application $app) {
|
||||
return new PluginManager($app['plugins.directory'], $app['plugins.plugins-validator']);
|
||||
});
|
||||
|
||||
$app['plugins.json-validator'] = $app->share(function (Application $app) {
|
||||
return new JsonValidator();
|
||||
});
|
||||
|
65
lib/Alchemy/Phrasea/Plugin/Plugin.php
Normal file
65
lib/Alchemy/Phrasea/Plugin/Plugin.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Plugin;
|
||||
|
||||
use Alchemy\Phrasea\Plugin\Exception\PluginValidationException;
|
||||
use Alchemy\Phrasea\Plugin\Schema\Manifest;
|
||||
|
||||
class Plugin
|
||||
{
|
||||
private $error;
|
||||
private $manifest;
|
||||
private $name;
|
||||
|
||||
public function __construct($name, Manifest $manifest = null, PluginValidationException $error = null)
|
||||
{
|
||||
if ($manifest === $error || (null !== $manifest && null !== $error)) {
|
||||
throw new \LogicException('A plugin is either installed (with a stable manifest) or on error (given its error).');
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
$this->manifest = $manifest;
|
||||
$this->error = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isErroneous()
|
||||
{
|
||||
return null !== $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Manifest
|
||||
*/
|
||||
public function getManifest()
|
||||
{
|
||||
return $this->manifest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PluginValidationException
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
}
|
64
lib/Alchemy/Phrasea/Plugin/PluginManager.php
Normal file
64
lib/Alchemy/Phrasea/Plugin/PluginManager.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Plugin;
|
||||
|
||||
use Alchemy\Phrasea\Plugin\Schema\PluginValidator;
|
||||
use Alchemy\Phrasea\Plugin\Exception\PluginValidationException;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
class PluginManager
|
||||
{
|
||||
private $pluginDir;
|
||||
private $validator;
|
||||
|
||||
public function __construct($pluginDir, PluginValidator $validator)
|
||||
{
|
||||
$this->pluginDir = $pluginDir;
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Plugin[] An array containing plugins
|
||||
*/
|
||||
public function listPlugins()
|
||||
{
|
||||
$finder = new Finder();
|
||||
$finder
|
||||
->depth(0)
|
||||
->in($this->pluginDir)
|
||||
->directories();
|
||||
|
||||
$plugins = array();
|
||||
|
||||
foreach ($finder as $pluginDir) {
|
||||
$manifest = $error = null;
|
||||
$name = $pluginDir->getBasename();
|
||||
|
||||
try {
|
||||
$manifest = $this->validator->validatePlugin((string) $pluginDir);
|
||||
} catch (PluginValidationException $e) {
|
||||
$error = $e;
|
||||
}
|
||||
|
||||
$plugins[$name] = new Plugin($name, $manifest, $error);
|
||||
}
|
||||
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
public function hasPlugin($name)
|
||||
{
|
||||
$plugins = $this->listPlugins();
|
||||
|
||||
return isset($plugins[$name]);
|
||||
}
|
||||
}
|
@@ -11,8 +11,6 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Plugin\Schema;
|
||||
|
||||
use Alchemy\Phrasea\Plugin\Schema\ManifestValidator;
|
||||
use Alchemy\Phrasea\Plugin\Schema\Manifest;
|
||||
use Alchemy\Phrasea\Plugin\Exception\PluginValidationException;
|
||||
use Alchemy\Phrasea\Plugin\Exception\JsonValidationException;
|
||||
|
||||
|
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Command\Plugin;
|
||||
|
||||
use Alchemy\Phrasea\Command\Plugin\ListPlugin;
|
||||
|
||||
class ListPluginTest extends PluginCommandTestCase
|
||||
{
|
||||
public function testExecute()
|
||||
{
|
||||
$input = $this->getMock('Symfony\Component\Console\Input\InputInterface');
|
||||
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
|
||||
|
||||
$table = $this->getMockBuilder('Symfony\Component\Console\Helper\TableHelper')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$table->expects($this->once())
|
||||
->method('setHeaders')
|
||||
->will($this->returnSelf());
|
||||
|
||||
$helperSet = $this->getMockBuilder('Symfony\Component\Console\Helper\HelperSet')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$helperSet->expects($this->once())
|
||||
->method('get')
|
||||
->will($this->returnValue($table));
|
||||
|
||||
$command = new ListPlugin();
|
||||
$command->setContainer(self::$DI['cli']);
|
||||
$command->setHelperSet($helperSet);
|
||||
|
||||
$result = $command->execute($input, $output);
|
||||
|
||||
$this->assertSame(0, $result);
|
||||
}
|
||||
}
|
@@ -18,6 +18,11 @@ class PluginServiceProvidertest extends ServiceProviderTestCase
|
||||
'plugins.json-validator',
|
||||
'JsonSchema\Validator'
|
||||
),
|
||||
array(
|
||||
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
|
||||
'plugins.manager',
|
||||
'Alchemy\Phrasea\Plugin\PluginManager'
|
||||
),
|
||||
array(
|
||||
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
|
||||
'plugins.plugins-validator',
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Plugin\Management;
|
||||
|
||||
use Alchemy\Phrasea\Plugin\Management\ComposerInstaller;
|
||||
use Alchemy\Phrasea\Utilities\ComposerSetup;
|
||||
use Guzzle\Http\Client as Guzzle;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
|
43
tests/Alchemy/Tests/Phrasea/Plugin/PluginManagerTest.php
Normal file
43
tests/Alchemy/Tests/Phrasea/Plugin/PluginManagerTest.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Plugin;
|
||||
|
||||
use Alchemy\Phrasea\Plugin\PluginManager;
|
||||
use Alchemy\Phrasea\Plugin\Schema\PluginValidator;
|
||||
|
||||
class PluginManagerTest extends PluginTestCase
|
||||
{
|
||||
public function testListGoodPlugins()
|
||||
{
|
||||
$manager = new PluginManager(__DIR__ . '/Fixtures/PluginDirInstalled', self::$DI['cli']['plugins.plugins-validator']);
|
||||
$plugins = $manager->listPlugins();
|
||||
$this->assertCount(1, $plugins);
|
||||
$plugin = array_pop($plugins);
|
||||
|
||||
$this->assertFalse($plugin->isErroneous());
|
||||
}
|
||||
|
||||
public function testListWrongPlugins()
|
||||
{
|
||||
$manager = new PluginManager(__DIR__ . '/Fixtures/WrongPlugins', self::$DI['cli']['plugins.plugins-validator']);
|
||||
$plugins = $manager->listPlugins();
|
||||
$this->assertCount(8, $plugins);
|
||||
$plugin = array_pop($plugins);
|
||||
|
||||
$this->assertTrue($plugin->isErroneous());
|
||||
}
|
||||
|
||||
public function testHasPlugin()
|
||||
{
|
||||
$manager = new PluginManager(__DIR__ . '/Fixtures/PluginDirInstalled', self::$DI['cli']['plugins.plugins-validator']);
|
||||
$this->assertTrue($manager->hasPlugin('test-plugin'));
|
||||
$this->assertFalse($manager->hasPlugin('test-plugin2'));
|
||||
}
|
||||
|
||||
private function createValidatorMock()
|
||||
{
|
||||
return $this->getMockBuilder('Alchemy\Phrasea\Plugin\Schema\PluginValidator')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
}
|
45
tests/Alchemy/Tests/Phrasea/Plugin/PluginTest.php
Normal file
45
tests/Alchemy/Tests/Phrasea/Plugin/PluginTest.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Plugin;
|
||||
|
||||
use Alchemy\Phrasea\Plugin\Plugin;
|
||||
|
||||
class PluginTest extends PluginTestCase
|
||||
{
|
||||
public function testGetters()
|
||||
{
|
||||
$manifest = $this->createManifestMock();
|
||||
$error = $this->getMock('Alchemy\Phrasea\Plugin\Exception\PluginValidationException');
|
||||
|
||||
$plugin = new Plugin('toto', $manifest, null);
|
||||
$this->assertSame('toto', $plugin->getName());
|
||||
$this->assertSame($manifest, $plugin->getManifest());
|
||||
$this->assertNull($plugin->getError());
|
||||
$this->assertFalse($plugin->isErroneous());
|
||||
|
||||
$plugin = new Plugin('toto', null, $error);
|
||||
$this->assertSame('toto', $plugin->getName());
|
||||
$this->assertNull($plugin->getManifest());
|
||||
$this->assertSame($error, $plugin->getError());
|
||||
$this->assertTrue($plugin->isErroneous());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testBothNull()
|
||||
{
|
||||
new Plugin('toto', null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testBothNotNull()
|
||||
{
|
||||
$manifest = $this->createManifestMock();
|
||||
$error = $this->getMock('Alchemy\Phrasea\Plugin\Exception\PluginValidationException');
|
||||
|
||||
new Plugin('toto', $manifest, $error);
|
||||
}
|
||||
}
|
@@ -30,4 +30,11 @@ class PluginTestCase extends \PhraseanetPHPUnitAbstract
|
||||
{
|
||||
return __DIR__ . '/../../../../../lib/conf.d/plugin-schema.json';
|
||||
}
|
||||
|
||||
protected function createManifestMock()
|
||||
{
|
||||
return $this->getMockBuilder('Alchemy\Phrasea\Plugin\Schema\Manifest')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user