Check plugin dependencies at PluginManager

This commit is contained in:
Pig Fang 2019-08-17 10:57:38 +08:00
parent eeec2e0435
commit 42f0135704
6 changed files with 43 additions and 34 deletions

View File

@ -28,11 +28,12 @@ class PluginEnableCommand extends Command
*/
public function handle(PluginManager $plugins)
{
$plugin = $plugins->get($this->argument('name'));
if ($plugin) {
$plugins->enable($this->argument('name'));
$name = $this->argument('name');
$result = $plugins->enable($name);
if ($result === true) {
$plugin = $plugins->get($name);
$this->info(trans('admin.plugins.operations.enabled', ['plugin' => $plugin->title]));
} else {
} elseif ($result === false) {
$this->warn(trans('admin.plugins.operations.not-found'));
}
}

View File

@ -29,9 +29,12 @@ class PluginController extends Controller
switch ($request->get('action')) {
case 'enable':
$requirements = $plugins->getUnsatisfied($plugin);
if ($requirements->isNotEmpty()) {
$reason = $requirements->map(function ($detail, $name) {
$result = $plugins->enable($name);
if ($result === true) {
return json(trans('admin.plugins.operations.enabled', ['plugin' => $plugin->title]), 0);
} else {
$reason = $result['unsatisfied']->map(function ($detail, $name) {
$constraint = $detail['constraint'];
if (! $detail['version']) {
return trans('admin.plugins.operations.unsatisfied.disabled', compact('name'));
@ -43,10 +46,6 @@ class PluginController extends Controller
return json(trans('admin.plugins.operations.unsatisfied.notice'), 1, compact('reason'));
}
$plugins->enable($name);
return json(trans('admin.plugins.operations.enabled', ['plugin' => $plugin->title]), 0);
case 'disable':
$plugins->disable($name);

View File

@ -246,16 +246,28 @@ class PluginManager
return $this->all()->get($name);
}
/**
* @return bool|array Return `true` if succeeded, or return information if failed.
*/
public function enable($plugin)
{
$plugin = is_string($plugin) ? $this->get($plugin) : $plugin;
if ($plugin && ! $plugin->isEnabled()) {
$unsatisfied = $this->getUnsatisfied($plugin);
if ($unsatisfied->isNotEmpty()) {
return compact('unsatisfied');
}
$this->enabled->put($plugin->name, ['version' => $plugin->version]);
$this->saveEnabled();
$plugin->setEnabled(true);
$this->dispatcher->dispatch(new Events\PluginWasEnabled($plugin));
return true;
} else {
return false;
}
}

View File

@ -10,12 +10,12 @@ class PluginEnableCommandTest extends TestCase
public function testEnablePlugin()
{
$this->mock(PluginManager::class, function ($mock) {
$mock->shouldReceive('get')->with('nope')->once()->andReturn(null);
$mock->shouldReceive('get')
->with('my-plugin')
->once()
->andReturn(new Plugin('', ['title' => 'My Plugin']));
$mock->shouldReceive('enable')->with('my-plugin')->once();
$mock->shouldReceive('enable')->with('nope')->once()->andReturn(false);
$mock->shouldReceive('enable')->with('my-plugin')->once()->andReturn(true);
});
$this->artisan('plugin:enable nope')

View File

@ -89,17 +89,15 @@ class PluginControllerTest extends TestCase
->with('fake2')
->once()
->andReturn(new Plugin('', ['name' => 'fake2']));
$mock->shouldReceive('getUnsatisfied')
->withArgs(function ($plugin) {
$this->assertEquals('fake2', $plugin->name);
return true;
})
$mock->shouldReceive('enable')
->with('fake2')
->once()
->andReturn(collect([
'dep' => ['version' => '0.0.0', 'constraint' => '^6.6.6'],
'whatever' => ['version' => null, 'constraint' => '^1.2.3'],
]));
->andReturn([
'unsatisfied' => collect([
'dep' => ['version' => '0.0.0', 'constraint' => '^6.6.6'],
'whatever' => ['version' => null, 'constraint' => '^1.2.3'],
]),
]);
$mock->shouldReceive('get')
->with('fake3')
@ -107,15 +105,8 @@ class PluginControllerTest extends TestCase
->andReturn(new Plugin('', ['name' => 'fake3', 'title' => 'Fake']));
$mock->shouldReceive('enable')
->with('fake3')
->once();
$mock->shouldReceive('getUnsatisfied')
->withArgs(function ($plugin) {
$this->assertEquals('fake3', $plugin->name);
return true;
})
->once()
->andReturn(collect([]));
->andReturn(true);
$mock->shouldReceive('get')
->with('fake4')

View File

@ -401,10 +401,14 @@ class PluginManagerTest extends TestCase
$reflection = new ReflectionClass($manager);
$property = $reflection->getProperty('plugins');
$property->setAccessible(true);
$plugin = new Plugin('', ['name' => 'fake']);
$property->setValue($manager, collect(['fake' => $plugin]));
$property->setValue($manager, collect([
'fake' => new Plugin('', ['name' => 'fake']),
'dep' => new Plugin('', ['name' => 'dep', 'require' => ['a' => '*']]),
]));
$manager->enable('fake');
$this->assertFalse($manager->enable('nope'));
$this->assertTrue($manager->enable('fake'));
Event::assertDispatched(Events\PluginWasEnabled::class, function ($event) {
$this->assertEquals('fake', $event->plugin->name);
@ -415,6 +419,8 @@ class PluginManagerTest extends TestCase
'fake',
json_decode(resolve(\App\Services\Option::class)->get('plugins_enabled'), true)[0]['name']
);
$this->assertTrue($manager->enable('dep')['unsatisfied']->isNotEmpty());
}
public function testDisable()