From d940a9461101ce95ad80a9e3628695b86f927a9b Mon Sep 17 00:00:00 2001 From: Christopher Vagnetoft Date: Thu, 9 Dec 2021 00:12:37 +0100 Subject: [PATCH] Plugin manager, misc fixes * Fixed an error when trying to create nonexisting resource type * Updated the init-command to create plugins and scipts directories * Added a basic installer function --- CHANGELOG.md | 8 ++++ bin/spark | 5 ++ src/Commands/InitCommand.php | 6 ++- src/Commands/PluginsCommand.php | 79 ++++++++++++++++++++++++++++++++ src/Resource/ResourceManager.php | 3 ++ src/SparkApplication.php | 4 ++ src/install | 78 +++++++++++++++++++++++++++++++ 7 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 src/Commands/PluginsCommand.php create mode 100644 src/install diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8290c7d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## 0.1.0 + +- Initial beta release version. +- Plugin manager: If `SPARK_PLUGINS` envvar is set, the `plugins` command will be + available to manage symlinks to the globally installed plugins. + diff --git a/bin/spark b/bin/spark index 15fa8d8..2a871a8 100755 --- a/bin/spark +++ b/bin/spark @@ -9,5 +9,10 @@ else { require_once __DIR__."/../vendor/autoload.php"; +if ($argc == 2 && $argv[1] === "install") { + require_once __DIR__."/../src/install"; + exit(0); +} + $app = new Spark\SparkApplication(); $app->run(); diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 2dee991..d5e9a30 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -26,12 +26,14 @@ class InitCommand extends Command mkdir($configDir); mkdir($configDir."/plugins"); + mkdir($configDir."/scripts"); file_put_contents($configDir."/spark.json", json_encode([ 'preload' => [ - './.spark/plugins/*' + './.spark/plugins/*', + './.spark/scripts/*' ], 'scripts' => [ - 'hello' => "echo 'Hello World\n'" + 'hello' => "echo 'Hello World'" ] ], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)); diff --git a/src/Commands/PluginsCommand.php b/src/Commands/PluginsCommand.php new file mode 100644 index 0000000..371164a --- /dev/null +++ b/src/Commands/PluginsCommand.php @@ -0,0 +1,79 @@ +addOption("enable", null, InputOption::VALUE_REQUIRED, "Enable (symlink) a plugin"); + $this->addOption("disable", null, InputOption::VALUE_REQUIRED, "Disable (remove) a plugin"); + $this->addOption("force", "f", InputOption::VALUE_NONE, "Remove a plugin even if not a symlink"); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $env = $this->getEnvironment(); + $app = $this->getApplication(); + + $globalPlugins = getenv("SPARK_PLUGINS"); + $localPlugins = $env->getConfigDirectory()."/plugins"; + + $globalPluginList = glob($globalPlugins."/*"); + $globalBasePluginList = array_map("basename", $globalPluginList); + $localPluginList = array_map("basename", glob($localPlugins."/*")); + + if ($plugin = $input->getOption("enable")) { + if (in_array($plugin, $localPluginList)) { + $output->writeln("Plugin {$plugin} already enabled!"); + return Command::SUCCESS; + } + if (!in_array($plugin, $globalBasePluginList)) { + $output->writeln("No such plugin {$plugin}"); + return Command::FAILURE; + } + symlink($globalPlugins."/".$plugin, $localPlugins."/".$plugin); + $output->writeln("Enabled plugin {$plugin}!"); + return Command::SUCCESS; + } elseif ($plugin = $input->getOption("disable")) { + $force = $input->getOption("force"); + if (!in_array($plugin, $localPluginList)) { + $output->writeln("Plugin {$plugin} not enabled!"); + return Command::FAILURE; + } + if (!is_link($localPlugins."/".$plugin) && !$force) { + $output->writeln("Plugin is not a symlink and --force not specified"); + return Command::FAILURE; + } elseif (is_link($localPlugins."/".$plugin)) { + unlink($localPlugins."/".$plugin); + $output->writeln("Disabled plugin {$plugin}!"); + return Command::SUCCESS; + } + } + + foreach ($globalPluginList as $plugin) { + if (!is_dir($plugin)) continue; + if (!file_exists($plugin."/sparkplug.php")) continue; + $head = (file($plugin."/sparkplug.php", FILE_IGNORE_NEW_LINES)[0])??null; + if (str_contains($head, "//")) { + $json = "{" . substr($head, strpos($head, "//") + 3) . "}"; + $info = json_decode($json)??object(); + } else { + $info = object(); + } + $installed = in_array(basename($plugin), $localPluginList); + $badge = ($installed)?"\u{2714}":"\u{27f3}"; + $output->writeln(sprintf(" %s %-20s %s", $badge, basename($plugin), $info->name??null)); + } + + return Command::SUCCESS; + } +} \ No newline at end of file diff --git a/src/Resource/ResourceManager.php b/src/Resource/ResourceManager.php index 75171a5..1adfa80 100644 --- a/src/Resource/ResourceManager.php +++ b/src/Resource/ResourceManager.php @@ -18,6 +18,9 @@ class ResourceManager public function createResource(string $type, array $options) { + if (!array_key_exists($type, $this->resourceTypes)) { + return null; + } $resource = new $this->resourceTypes[$type]($options); return $resource; } diff --git a/src/SparkApplication.php b/src/SparkApplication.php index 2bea94c..31813a9 100644 --- a/src/SparkApplication.php +++ b/src/SparkApplication.php @@ -39,6 +39,10 @@ class SparkApplication extends Application $this->add(new Commands\ReplCommand()); $this->add(new Commands\InitCommand()); + if (getenv("SPARK_PLUGINS")) { + $this->add(new Commands\PluginsCommand()); + } + } public function getPluginManager(): PluginManager diff --git a/src/install b/src/install new file mode 100644 index 0000000..1569206 --- /dev/null +++ b/src/install @@ -0,0 +1,78 @@ +