Refactor plugin system (part 6)

This commit is contained in:
Pig Fang 2019-08-12 17:37:52 +08:00
parent fb0dcd4ad3
commit 3071ece7ba
3 changed files with 99 additions and 4 deletions

View File

@ -85,6 +85,11 @@ class Plugin
return Arr::get($this->packageInfo, $name);
}
public function getManifest()
{
return $this->packageInfo;
}
public function assets(string $relativeUri): string
{
$baseUrl = config('plugins.url') ?: url('plugins');

View File

@ -62,6 +62,7 @@ class PluginManager
$this->option = $option;
$this->dispatcher = $dispatcher;
$this->filesystem = $filesystem;
$this->enabled = collect();
}
/**
@ -95,6 +96,10 @@ class PluginManager
}
$plugin = new Plugin($directory, $manifest);
$plugins->put($name, $plugin);
if ($this->getUnsatisfied($plugin)->isNotEmpty()) {
$this->disable($plugin);
}
if ($this->enabled->contains('name', $name)) {
$plugin->setEnabled(true);
if (Comparator::notEqualTo(
@ -104,11 +109,8 @@ class PluginManager
$this->dispatcher->dispatch(new Events\PluginVersionChanged($plugin));
}
}
$plugins->put($name, $plugin);
});
// disable unsatisfied here
$enabled = $plugins->filter(function ($plugin) {
return $plugin->isEnabled();
});
@ -484,6 +486,35 @@ class PluginManager
return in_array($pluginName, $this->getEnabled());
}
/**
* @param Plugin $plugin
* @return Collection
*/
public function getUnsatisfied(Plugin $plugin)
{
return collect(Arr::get($plugin->getManifest(), 'require', []))
->mapWithKeys(function ($constraint, $name) {
if ($name == 'blessing-skin-server') {
$version = config('app.version');
return (! Semver::satisfies($version, $constraint))
? [$name => compact('version', 'constraint')]
: [];
} elseif ($name == 'php') {
$version = PHP_VERSION;
return (! Semver::satisfies($version, $constraint))
? [$name => compact('version', 'constraint')]
: [];
} elseif (! $this->enabled->contains('name', $name)) {
return [$name => ['version' => null, 'constraint' => $constraint]];
} else {
$version = $this->enabled->firstWhere('name', $name)['version'];
return (! Semver::satisfies($version, $constraint))
? [$name => compact('version', 'constraint')]
: [];
}
});
}
/**
* Get the unsatisfied requirements of plugin.
*

View File

@ -31,7 +31,7 @@ class PluginManagerTest extends TestCase
app('plugins')->boot();
}
public function testDoNotLoadDisabled()
public function testNotLoadDisabled()
{
$dir = config('plugins.directory');
config(['plugins.directory' => storage_path('mocks')]);
@ -42,6 +42,34 @@ class PluginManagerTest extends TestCase
config(['plugins.directory' => $dir]);
}
public function testNotLoadUnsatisfied()
{
$this->mock(Filesystem::class, function ($mock) {
$mock->shouldReceive('directories')
->with(base_path('plugins'))
->once()
->andReturn(collect(['/nano']));
$mock->shouldReceive('exists')
->with('/nano'.DIRECTORY_SEPARATOR.'package.json')
->once()
->andReturn(true);
$mock->shouldReceive('get')
->with('/nano'.DIRECTORY_SEPARATOR.'package.json')
->once()
->andReturn(json_encode([
'name' => 'fake',
'version' => '0.0.0',
'require' => ['blessing-skin-server' => '0.0.0'],
]));
$mock->shouldNotReceive('getRequire');
});
$manager = $this->rebootPluginManager(app('plugins'));
}
public function testReportDuplicatedPlugins()
{
$this->mock(Filesystem::class, function ($mock) {
@ -316,4 +344,35 @@ class PluginManagerTest extends TestCase
config(['plugins.directory' => $dir]);
option(['plugins_enabled' => '[]']);
}
public function testGetUnsatisfied()
{
$manager = app('plugins');
$plugin = new Plugin('', ['require' => ['blessing-skin-server' => '^0.0.0']]);
$info = $manager->getUnsatisfied($plugin)->get('blessing-skin-server');
$this->assertEquals(config('app.version'), $info['version']);
$this->assertEquals('^0.0.0', $info['constraint']);
$plugin = new Plugin('', ['require' => ['php' => '^0.0.0']]);
$info = $manager->getUnsatisfied($plugin)->get('php');
$this->assertEquals(PHP_VERSION, $info['version']);
$this->assertEquals('^0.0.0', $info['constraint']);
$plugin = new Plugin('', ['require' => ['another-plugin' => '0.0.*']]);
$info = $manager->getUnsatisfied($plugin)->get('another-plugin');
$this->assertNull($info['version']);
$this->assertEquals('0.0.*', $info['constraint']);
$reflection = new ReflectionClass($manager);
$property = $reflection->getProperty('enabled');
$property->setAccessible(true);
$property->setValue($manager, collect([['name' => 'another-plugin', 'version' => '1.2.3']]));
$info = $manager->getUnsatisfied($plugin)->get('another-plugin');
$this->assertEquals('1.2.3', $info['version']);
$this->assertEquals('0.0.*', $info['constraint']);
$plugin = new Plugin('', ['require' => ['another-plugin' => '^1.0.0']]);
$this->assertFalse($manager->getUnsatisfied($plugin)->has('another-plugin'));
}
}