diff --git a/CommonLogic/AppInstallers/AbstractServerInstaller.php b/CommonLogic/AppInstallers/AbstractServerInstaller.php index 86fcd84df..a2ec8b51e 100644 --- a/CommonLogic/AppInstallers/AbstractServerInstaller.php +++ b/CommonLogic/AppInstallers/AbstractServerInstaller.php @@ -57,8 +57,13 @@ protected abstract function getConfigTemplatePathRelative() : string; * @return string */ protected abstract function stringToComment(string $comment) : string; - + /** + * @return string + */ + protected abstract function ServerSoftwareFamilyDefault() : string; + + /** * * {@inheritDoc} * @see \exface\Core\Interfaces\InstallerInterface::backup() @@ -87,10 +92,15 @@ public function install(string $source_absolute_path): \Iterator { $indentOuter = $this->getOutputIndentation(); $indent = $indentOuter . $indentOuter; - $serverType = ServerSoftwareDataType::getServerSoftwareFamily() ?? 'UNKNOWN SERVER SOFTWARE'; - $serverVersion = ServerSoftwareDataType::getServerSoftwareVersion() ?? 'UNKNOWN VERSION'; - yield $indentOuter . "Server configuration for {$serverType} {$serverVersion}:" . PHP_EOL; + $serverType = ServerSoftwareDataType::getServerSoftwareFamily() ?? + $this->ServerSoftwareFamilyDefault() ?? + 'UNKNOWN SERVER SOFTWARE'; + + $serverVersion = ServerSoftwareDataType::getServerSoftwareVersion() ?? + 'with unknown version'; + + yield $indentOuter . "Loading server configuration for \"{$serverType}\" {$serverVersion}:" . PHP_EOL; $this->configInstaller->setOutputIndentation($indent); yield $indent . "Using \"{$this->getConfigTemplatePathRelative()}\" template for {$serverType}." . PHP_EOL; diff --git a/CommonLogic/AppInstallers/ApacheServerInstaller.php b/CommonLogic/AppInstallers/ApacheServerInstaller.php index 48cd4f3a1..de0db424d 100644 --- a/CommonLogic/AppInstallers/ApacheServerInstaller.php +++ b/CommonLogic/AppInstallers/ApacheServerInstaller.php @@ -97,4 +97,12 @@ protected function stringToComment(string $comment): string { return "# {$comment}"; } + + /** + * @inheritDoc + */ + protected function ServerSoftwareFamilyDefault(): string + { + return 'Apache'; + } } \ No newline at end of file diff --git a/CommonLogic/AppInstallers/AppInstallerContainer.php b/CommonLogic/AppInstallers/AppInstallerContainer.php index e69225254..3e52a633d 100644 --- a/CommonLogic/AppInstallers/AppInstallerContainer.php +++ b/CommonLogic/AppInstallers/AppInstallerContainer.php @@ -3,6 +3,7 @@ use exface\Core\DataTypes\DateTimeDataType; use exface\Core\Interfaces\AppInstallerInterface; +use exface\Core\Interfaces\IAmSilentInterface; use exface\Core\Interfaces\InstallerInterface; use exface\Core\Interfaces\InstallerContainerInterface; use exface\Core\Events\Installer\OnBeforeInstallEvent; @@ -44,6 +45,11 @@ public final function install(string $source_absolute_path) : \Iterator $eventMgr = $this->getWorkbench()->eventManager(); foreach ($this->getInstallers() as $installer) { + if($installer instanceof IAmSilentInterface) { + yield from $installer->install($source_absolute_path); + continue; + } + $eventMgr->dispatch(new OnBeforeInstallEvent($installer, $source_absolute_path)); yield from $installer->install($source_absolute_path); $eventMgr->dispatch(new OnInstallEvent($installer, $source_absolute_path)); @@ -93,6 +99,11 @@ public final function backup(string $destination_absolute_path) : \Iterator $eventMgr = $this->getWorkbench()->eventManager(); foreach ($this->getInstallers() as $installer) { + if($installer instanceof IAmSilentInterface) { + yield from $installer->backup($destination_absolute_path); + continue; + } + $eventMgr->dispatch(new OnBeforeBackupEvent($installer, $destination_absolute_path)); yield from $installer->backup($destination_absolute_path); $eventMgr->dispatch(new OnBackupEvent($installer, $destination_absolute_path)); @@ -117,6 +128,11 @@ public final function uninstall() : \Iterator // TODO disable mutations here too??? $eventMgr = $this->getWorkbench()->eventManager(); foreach (array_reverse($this->getInstallers()) as $installer) { + if($installer instanceof IAmSilentInterface) { + yield from $installer->uninstall(); + continue; + } + $eventMgr->dispatch(new OnBeforeUninstallEvent($installer)); yield from $installer->uninstall(); $eventMgr->dispatch(new OnUninstallEvent($installer)); @@ -161,4 +177,16 @@ public function extract(callable $filterCallback) : InstallerContainerInterface } return $container; } + + /** + * @inheritDoc + */ + public function addMessage(string $message, bool $insertAtBeginning = false) : InstallerContainerInterface + { + if($message !== '') { + $this->addInstaller(new DebugInstaller($this->getWorkbench(), $message), $insertAtBeginning); + } + + return $this; + } } \ No newline at end of file diff --git a/CommonLogic/AppInstallers/DebugInstaller.php b/CommonLogic/AppInstallers/DebugInstaller.php new file mode 100644 index 000000000..3522e9a0f --- /dev/null +++ b/CommonLogic/AppInstallers/DebugInstaller.php @@ -0,0 +1,95 @@ +workbench = $workbench; + $this->indent = $indent; + $this->message = str_ends_with($message, PHP_EOL) ? $message : $message . PHP_EOL; + } + + /** + * @inheritDoc + */ + public function install(string $source_absolute_path): \Iterator + { + yield $this->getMessage() ?? new \EmptyIterator(); + } + + /** + * @inheritDoc + */ + public function backup(string $absolute_path): \Iterator + { + yield $this->getMessage() ?? new \EmptyIterator(); + } + + /** + * @inheritDoc + */ + public function uninstall(): \Iterator + { + yield $this->getMessage() ?? new \EmptyIterator(); + } + + /** + * STUB! Do not use. + * @deprecated + */ + public function getWorkbench() : WorkbenchInterface + { + return $this->workbench; + } + + /** + * @return string + */ + public function getOutputIndentation() : string + { + return $this->indent; + } + + /** + * @param string $value + * @return $this + */ + public function setOutputIndentation(string $value) : DebugInstaller + { + $this->indent = $value; + return $this; + } + + /** + * @param bool $withIndentation + * @return string|null + */ + public function getMessage(bool $withIndentation = true) : ?string + { + if($this->message === null) { + return null; + } + + return $this->getOutputIndentation() . $this->message; + } +} \ No newline at end of file diff --git a/CommonLogic/AppInstallers/IISServerInstaller.php b/CommonLogic/AppInstallers/IISServerInstaller.php index 2ae2c1ba9..6b3988245 100644 --- a/CommonLogic/AppInstallers/IISServerInstaller.php +++ b/CommonLogic/AppInstallers/IISServerInstaller.php @@ -82,4 +82,12 @@ protected function stringToComment(string $comment): string { return ""; } + + /** + * @inheritDoc + */ + protected function ServerSoftwareFamilyDefault(): string + { + return 'Microsoft-IIS'; + } } \ No newline at end of file diff --git a/CommonLogic/AppInstallers/NginxServerInstaller.php b/CommonLogic/AppInstallers/NginxServerInstaller.php index 8f7a1b50e..71aea4326 100644 --- a/CommonLogic/AppInstallers/NginxServerInstaller.php +++ b/CommonLogic/AppInstallers/NginxServerInstaller.php @@ -87,4 +87,12 @@ protected function stringToComment(string $comment): string { return "# {$comment}"; } + + /** + * @inheritDoc + */ + protected function ServerSoftwareFamilyDefault(): string + { + return 'nginx'; + } } \ No newline at end of file diff --git a/CoreApp.php b/CoreApp.php index 2ef31b6c1..927363180 100644 --- a/CoreApp.php +++ b/CoreApp.php @@ -3,8 +3,8 @@ use exface\Core\CommonLogic\AppInstallers\ApacheServerInstaller; use exface\Core\CommonLogic\AppInstallers\AppDocsInstaller; +use exface\Core\CommonLogic\AppInstallers\AppInstallerContainer; use exface\Core\CommonLogic\AppInstallers\NginxServerInstaller; -use exface\Core\Exceptions\Installers\InstallerRuntimeError; use exface\Core\Facades\PermalinkFacade; use exface\Core\Interfaces\InstallerInterface; use exface\Core\Factories\ConfigurationFactory; @@ -106,17 +106,14 @@ public function getInstaller(InstallerInterface $injected_installer = null) $installer->addInstaller($tplInstaller); // Server installer. - $serverInstallerClass = $this->getServerInstallerClass(); + $serverInstallerClass = $this->getServerInstallerClass($installer); if ($serverInstallerClass !== null) { $serverInstaller = new $serverInstallerClass($this->getSelector()); $installer->addInstaller($serverInstaller); } else { - $msg = 'Could not determine server installer class! Consider defining the server installer class ' . - 'explicitly by setting "' . self::CONFIG_SERVER_INSTALLER . '" in "System.config.json".'; - - throw new InstallerRuntimeError( - $installer, - $msg + $installer->addMessage('FAILED - Could not determine server installer class! Consider defining the' . + ' server installer class explicitly by setting "' . self::CONFIG_SERVER_INSTALLER . + '" in "System.config.json".' ); } @@ -134,18 +131,28 @@ public function getInstaller(InstallerInterface $injected_installer = null) } /** + * @param AppInstallerContainer $installer * @return string|null */ - protected function getServerInstallerClass() : string|null + protected function getServerInstallerClass(AppInstallerContainer $installer) : string|null { + $installer->addMessage('Determining server installer class:'); + $indent = ' '; + // From config option. $cfg = $this->getWorkbench()->getConfig(); if($cfg->hasOption(self::CONFIG_SERVER_INSTALLER)) { $configOption = $this->getWorkbench()->getConfig()->getOption(self::CONFIG_SERVER_INSTALLER); - - if(!empty($configOption)) { + + // Valid-ish config option. + if(class_exists($configOption)) { + $installer->addMessage($indent . 'Found installer class in config: "' . $configOption . '".'); return $configOption; - } + } + + // Invalid config option. + $installer->addMessage($indent . 'Value "' . $configOption . '" for config option "' . + self::CONFIG_SERVER_INSTALLER . '" is not a valid class name.'); } // Read from PHP constant. @@ -155,6 +162,9 @@ protected function getServerInstallerClass() : string|null // Future installations should have a manually defined `` if(empty($softwareFamily)) { $path = $this->getWorkbench()->getInstallationPath(); + $installer->addMessage($indent . 'Deducing server software from installation path "' . $path . + '" under "' . php_uname('s') . '".'); + $softwareFamily = match (true) { // Microsoft IIS runs on windows and has its files mostly in c:\inetpub\wwwroot ServerSoftwareDataType::isOsWindows() && preg_match('/[Cc]:\\\\inetpub\\\\wwwroot\\\\/', $path) === 1 => ServerSoftwareDataType::SERVER_SOFTWARE_IIS, @@ -165,18 +175,31 @@ protected function getServerInstallerClass() : string|null ServerSoftwareDataType::isOsLinux() && preg_match("/\/www\//", $path) === 1 => ServerSoftwareDataType::SERVER_SOFTWARE_APACHE, default => null }; - + if(empty($softwareFamily)) { + $installer->addMessage($indent . 'Could not determine server software.'); return null; + } else { + $installer->addMessage($indent . 'Server software from folder structure: "' . $softwareFamily . '".'); } + } else { + $installer->addMessage($indent . 'Server software from PHP constant: "' . $softwareFamily . '".'); } - return match ($softwareFamily) { + $class = match ($softwareFamily) { ServerSoftwareDataType::SERVER_SOFTWARE_APACHE => '\\' . ltrim(ApacheServerInstaller::class, "\\"), ServerSoftwareDataType::SERVER_SOFTWARE_IIS => '\\' . ltrim(IISServerInstaller::class, "\\"), ServerSoftwareDataType::SERVER_SOFTWARE_NGINX => '\\' . ltrim(NginxServerInstaller::class, "\\"), default => null }; + + if($class !== null) { + $installer->addMessage($indent . 'Deduced installer class from server software: "' . $class . '".'); + } else { + $installer->addMessage($indent . 'Could not deduce server installer class.'); + } + + return $class; } /** diff --git a/Interfaces/IAmSilentInterface.php b/Interfaces/IAmSilentInterface.php new file mode 100644 index 000000000..0a4157562 --- /dev/null +++ b/Interfaces/IAmSilentInterface.php @@ -0,0 +1,18 @@ +