aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2025-04-01 14:02:25 +0200
committerChristoph Wurst <christoph@winzerhof-wurst.at>2025-04-01 14:02:25 +0200
commitc66df4e22f914bdf3ade58099f8bd7f8521ea3a1 (patch)
tree8e79ea666900676e8f12b5a362beb6413fa9371a
parentb03ffab5f0f39139c71cb2b8c370ca3f3d1ad391 (diff)
downloadnextcloud-server-feat/occ/command-events.tar.gz
nextcloud-server-feat/occ/command-events.zip
feat(occ): Emit events for command executionfeat/occ/command-events
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
-rw-r--r--lib/composer/composer/autoload_classmap.php2
-rw-r--r--lib/composer/composer/autoload_static.php2
-rw-r--r--lib/private/Console/Application.php52
-rw-r--r--lib/public/Command/Events/BeforeCommandExecutedEvent.php37
-rw-r--r--lib/public/Command/Events/CommandExecutedEvent.php37
-rw-r--r--lib/public/Command/Events/CommandFailedEvent.php37
6 files changed, 166 insertions, 1 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 52e3075e413..769da8d0278 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -248,6 +248,8 @@ return array(
'OCP\\Collaboration\\Resources\\LoadAdditionalScriptsEvent' => $baseDir . '/lib/public/Collaboration/Resources/LoadAdditionalScriptsEvent.php',
'OCP\\Collaboration\\Resources\\ResourceException' => $baseDir . '/lib/public/Collaboration/Resources/ResourceException.php',
'OCP\\Color' => $baseDir . '/lib/public/Color.php',
+ 'OCP\\Command\\Events\\BeforeCommandExecutedEvent' => $baseDir . '/lib/public/Command/Events/BeforeCommandExecutedEvent.php',
+ 'OCP\\Command\\Events\\CommandExecutedEvent' => $baseDir . '/lib/public/Command/Events/CommandExecutedEvent.php',
'OCP\\Command\\IBus' => $baseDir . '/lib/public/Command/IBus.php',
'OCP\\Command\\ICommand' => $baseDir . '/lib/public/Command/ICommand.php',
'OCP\\Comments\\CommentsEntityEvent' => $baseDir . '/lib/public/Comments/CommentsEntityEvent.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index e98bc3e1aaa..ac32433d9dc 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -297,6 +297,8 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Collaboration\\Resources\\LoadAdditionalScriptsEvent' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Resources/LoadAdditionalScriptsEvent.php',
'OCP\\Collaboration\\Resources\\ResourceException' => __DIR__ . '/../../..' . '/lib/public/Collaboration/Resources/ResourceException.php',
'OCP\\Color' => __DIR__ . '/../../..' . '/lib/public/Color.php',
+ 'OCP\\Command\\Events\\BeforeCommandExecutedEvent' => __DIR__ . '/../../..' . '/lib/public/Command/Events/BeforeCommandExecutedEvent.php',
+ 'OCP\\Command\\Events\\CommandExecutedEvent' => __DIR__ . '/../../..' . '/lib/public/Command/Events/CommandExecutedEvent.php',
'OCP\\Command\\IBus' => __DIR__ . '/../../..' . '/lib/public/Command/IBus.php',
'OCP\\Command\\ICommand' => __DIR__ . '/../../..' . '/lib/public/Command/ICommand.php',
'OCP\\Comments\\CommentsEntityEvent' => __DIR__ . '/../../..' . '/lib/public/Comments/CommentsEntityEvent.php',
diff --git a/lib/private/Console/Application.php b/lib/private/Console/Application.php
index f896c0abebe..69c862df832 100644
--- a/lib/private/Console/Application.php
+++ b/lib/private/Console/Application.php
@@ -8,11 +8,15 @@
namespace OC\Console;
use ArgumentCountError;
+use OC\EventDispatcher\EventDispatcher;
use OC\MemoryInfo;
use OC\NeedsUpdateException;
use OC\SystemConfig;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
+use OCP\Command\Events\BeforeCommandExecutedEvent;
+use OCP\Command\Events\CommandExecutedEvent;
+use OCP\Command\Events\CommandFailedEvent;
use OCP\Console\ConsoleEvent;
use OCP\Defaults;
use OCP\EventDispatcher\IEventDispatcher;
@@ -23,25 +27,71 @@ use OCP\ServerVersion;
use Psr\Container\ContainerExceptionInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Application as SymfonyApplication;
+use Symfony\Component\Console\Event\ConsoleCommandEvent;
+use Symfony\Component\Console\Event\ConsoleErrorEvent;
+use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Application {
+ private IEventDispatcher $dispatcher;
private SymfonyApplication $application;
public function __construct(
ServerVersion $serverVersion,
private IConfig $config,
- private IEventDispatcher $dispatcher,
+ EventDispatcher $dispatcher,
private IRequest $request,
private LoggerInterface $logger,
private MemoryInfo $memoryInfo,
private IAppManager $appManager,
private Defaults $defaults,
) {
+ $this->dispatcher = $dispatcher;
$this->application = new SymfonyApplication($defaults->getName(), $serverVersion->getVersionString());
+ $symfonyDispatcher = $dispatcher->getSymfonyDispatcher();
+ $symfonyDispatcher->addListener(\Symfony\Component\Console\ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) use ($dispatcher) {
+ $command = $event->getCommand();
+ $name = $command?->getName();
+ if ($name === null) {
+ // Ignore unnamed events
+ return;
+ }
+ $dispatcher->dispatchTyped(
+ new BeforeCommandExecutedEvent(
+ $name,
+ )
+ );
+ });
+ $symfonyDispatcher->addListener(\Symfony\Component\Console\ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event) use ($dispatcher) {
+ $command = $event->getCommand();
+ $name = $command?->getName();
+ if ($name === null) {
+ // Ignore unnamed events
+ return;
+ }
+ $dispatcher->dispatchTyped(
+ new CommandExecutedEvent(
+ $name,
+ )
+ );
+ });
+ $symfonyDispatcher->addListener(\Symfony\Component\Console\ConsoleEvents::ERROR, function (ConsoleErrorEvent $event) use ($dispatcher) {
+ $command = $event->getCommand();
+ $name = $command?->getName();
+ if ($name === null) {
+ // Ignore unnamed events
+ return;
+ }
+ $dispatcher->dispatchTyped(
+ new CommandFailedEvent(
+ $name,
+ )
+ );
+ });
+ $this->application->setDispatcher($symfonyDispatcher);
}
/**
diff --git a/lib/public/Command/Events/BeforeCommandExecutedEvent.php b/lib/public/Command/Events/BeforeCommandExecutedEvent.php
new file mode 100644
index 00000000000..1d81540648e
--- /dev/null
+++ b/lib/public/Command/Events/BeforeCommandExecutedEvent.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace OCP\Command\Events;
+
+use OCP\EventDispatcher\Event;
+
+/**
+ * Dispatched before an occ command is executed
+ *
+ * @since 32.0.0
+ */
+class BeforeCommandExecutedEvent extends Event {
+ /**
+ * @since 32.0.0
+ * @internal instances are created by Nextcloud server
+ */
+ public function __construct(
+ private string $command,
+ ) {
+ parent::__construct();
+ }
+
+ /**
+ * @since 32.0.0
+ */
+ public function getCommand(): string {
+ return $this->command;
+ }
+
+}
diff --git a/lib/public/Command/Events/CommandExecutedEvent.php b/lib/public/Command/Events/CommandExecutedEvent.php
new file mode 100644
index 00000000000..224994e4e82
--- /dev/null
+++ b/lib/public/Command/Events/CommandExecutedEvent.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace OCP\Command\Events;
+
+use OCP\EventDispatcher\Event;
+
+/**
+ * Dispatched after an occ command is executed
+ *
+ * @since 32.0.0
+ */
+class CommandExecutedEvent extends Event {
+ /**
+ * @since 32.0.0
+ * @internal instances are created by Nextcloud server
+ */
+ public function __construct(
+ private string $command,
+ ) {
+ parent::__construct();
+ }
+
+ /**
+ * @since 32.0.0
+ */
+ public function getCommand(): string {
+ return $this->command;
+ }
+
+}
diff --git a/lib/public/Command/Events/CommandFailedEvent.php b/lib/public/Command/Events/CommandFailedEvent.php
new file mode 100644
index 00000000000..0c35e08f591
--- /dev/null
+++ b/lib/public/Command/Events/CommandFailedEvent.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace OCP\Command\Events;
+
+use OCP\EventDispatcher\Event;
+
+/**
+ * Dispatched when an occ command failed
+ *
+ * @since 32.0.0
+ */
+class CommandFailedEvent extends Event {
+ /**
+ * @since 32.0.0
+ * @internal instances are created by Nextcloud server
+ */
+ public function __construct(
+ private string $command,
+ ) {
+ parent::__construct();
+ }
+
+ /**
+ * @since 32.0.0
+ */
+ public function getCommand(): string {
+ return $this->command;
+ }
+
+}