diff --git a/composer.json b/composer.json index 71e1320..3dbf33c 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "contributte/deployer-extension", - "description": "Ftp-Deployment Extension for Nette", + "name": "kubomikita/deployer-extension", + "description": "Fork of Ftp-Deployment Extension for Nette", "type": "library", "license": "BSD-3-Clause", "homepage": "https://github.com/contributte/deployer-extension", @@ -12,13 +12,14 @@ ], "require": { "php": ">=7.1", - "nette/di": "~2.4.13", - "dg/ftp-deployment": "~3.0.1" + "nette/di": "^3.0.2", + "dg/ftp-deployment": "^3.3.1" }, "require-dev": { "ninjify/qa": "^0.8.0", "ninjify/nunjuck": "^0.2.0", - "mockery/mockery": "~1.1.0" + "mockery/mockery": "~1.1.0", + "squizlabs/php_codesniffer": "3.*" }, "autoload": { "psr-4": { diff --git a/src/Config/Section.php b/src/Config/Section.php index a6b9224..e7c57bb 100644 --- a/src/Config/Section.php +++ b/src/Config/Section.php @@ -249,7 +249,7 @@ public function setTestMode(bool $testMode): void public function getFilePermissions(): ?int { - return empty($this->filePermissions) ? null : octdec($this->filePermissions); + return ($this->filePermissions === '') ? null : octdec($this->filePermissions); } public function setFilePermissions(string $mask): void @@ -259,7 +259,7 @@ public function setFilePermissions(string $mask): void public function getDirPermissions(): ?int { - return empty($this->dirPermissions) ? null : octdec($this->dirPermissions); + return ($this->dirPermissions === '') ? null : octdec($this->dirPermissions); } public function setDirPermissions(string $mask): void diff --git a/src/DI/DeployerExtension.php b/src/DI/DeployerExtension.php index 98a566c..501d59a 100644 --- a/src/DI/DeployerExtension.php +++ b/src/DI/DeployerExtension.php @@ -8,6 +8,9 @@ use Contributte\Deployer\Runner; use Nette\DI\CompilerExtension; use Nette\DI\Statement; +use Nette\Schema\Expect; +use Nette\Schema\Processor; +use Nette\Schema\Schema; /** * Deployer Extension @@ -15,60 +18,85 @@ final class DeployerExtension extends CompilerExtension { - /** @var mixed[] */ - private $defaults = [ - 'config' => [ - 'mode' => Config::MODE_TEST, - 'logFile' => '%appDir/../log/deploy.log', - 'tempDir' => '%appDir/../temp', - 'colors' => null, - ], - 'sections' => [], - 'userdata' => [], - 'plugins' => [], - ]; + public function getConfigSchema() : Schema + { + return Expect::structure( + [ + 'config' => Expect::structure( + [ + 'mode' => Expect::string(Config::MODE_TEST), + 'logFile' => Expect::string('%appDir/../log/deploy.log'), + 'tempDir' => Expect::string('%appDir/../temp'), + 'colors' => Expect::bool(), + ] + ), + 'sections' => Expect::array(), + 'userdata' => Expect::array(), + 'plugins' => Expect::array() + ] + ); + } - /** @var mixed[] */ - private $sectionDefaults = [ - 'testMode' => true, - 'deployFile' => null, - 'remote' => null, - 'local' => '%appDir', - 'ignore' => [], - 'allowdelete' => true, - 'before' => [], - 'after' => [], - 'purge' => [], - 'preprocess' => false, - 'passiveMode' => false, - 'filePermissions' => '', - 'dirPermissions' => '', - ]; + /** + * Validates section config + * + * @param array $data Config array of section + * + * @return array + */ + public function validateSectionConfig(array $data): array + { + $schema = Expect::structure( + [ + 'remote' => Expect::string()->required(), + 'local' => Expect::string()->required(), + 'deployFile' => Expect::string('.dep'), + 'ignore' => Expect::array(), + 'purge' => Expect::array(), + 'after' => Expect::array(), + 'before' => Expect::array(), + 'testMode' => Expect::bool(false), + 'preprocess' => Expect::bool(false), + 'allowdelete' => Expect::bool(true), + 'passiveMode' => Expect::bool(false), + 'filePermissions' => Expect::string(''), + 'dirPermissions' => Expect::string(''), + ] + ); - /** - * Processes configuration data. Intended to be overridden by descendant. - */ - public function loadConfiguration(): void - { - // Validate config - $config = $this->validateConfig($this->defaults); + $processor = new Processor(); + return (array) $processor->process($schema, $data); + } - // Get builder - $builder = $this->getContainerBuilder(); + /** + * Processes configuration data. Intended to be overridden by descendant. + * + * @return void + */ + public function loadConfiguration(): void + { + // Validate config + $config = (array) $this->config; + $config['config'] = (array) $this->config->config; - // Process sections - foreach ($config['sections'] as $name => $section) { + // Get builder + $builder = $this->getContainerBuilder(); - // Validate and merge section - $config['sections'][$name] = $this->validateConfig($this->sectionDefaults, $section); - } + // Process sections + foreach ($config['sections'] as $name => $section) { - // Add deploy manager - $builder->addDefinition($this->prefix('manager')) - ->setFactory(Manager::class, [ - new Statement(Runner::class), - new Statement(ConfigFactory::class, [$config]), - ]); - } + // Validate and merge section + $config['sections'][$name] = $this->validateSectionConfig($section); + } + + // Add deploy manager + $builder->addDefinition($this->prefix('manager')) + ->setFactory( + Manager::class, [ + new Statement(Runner::class), + new Statement(ConfigFactory::class, [$config]), + ] + ); + } } diff --git a/src/Runner.php b/src/Runner.php index 158e29a..ecad6c1 100644 --- a/src/Runner.php +++ b/src/Runner.php @@ -19,6 +19,11 @@ class Runner /** @var Logger */ private $logger; + /** + * @param Config $config + * + * @throws \Exception + */ public function run(Config $config): void { // Create logger @@ -38,9 +43,11 @@ public function run(Config $config): void // Get sections and get sections names $sections = $config->getSections(); - $sectionNames = array_map(function (Section $s) { - return $s->getName(); - }, $sections); + $sectionNames = array_map( + function (Section $s) { + return $s->getName(); + }, $sections + ); // Show info $this->logger->log(sprintf('Found sections: %d (%s)', count($sectionNames), implode(',', $sectionNames))); @@ -83,7 +90,11 @@ public function run(Config $config): void } /** - * @throws DeployException + * @param Config $config + * @param Section $section + * + * @return Deployer + * @throws \Exception */ public function createDeployer(Config $config, Section $section): Deployer { @@ -128,32 +139,36 @@ public function createDeployer(Config $config, Section $section): Deployer $deployment->testMode = $section->isTestMode(); // Before callbacks - $bc = [[], []]; - foreach ($section->getBeforeCallbacks() as $cb) { - $bc[is_callable($cb)][] = $cb; - } - $deployment->runBefore = $bc[0]; - $deployment->runBefore[] = function ($server, $logger, $deployer) use ($bc, $config, $section): void { - foreach ($bc[1] as $c) { - call_user_func_array([$c, 'onBefore'], [$config, $section, $server, $logger, $deployer]); + $deployment->runBefore[] = function (Server $server, Logger $logger, Deployer $deployer) use ($config, $section): void { + foreach ($section->getBeforeCallbacks() as $bc) { + if(is_callable($bc)) { + call_user_func_array($bc, [$config, $section, $server, $logger, $deployer]); + } else { + $logger->log('Before callback \'' . get_class($bc[0]) . '::' . $bc[1] . '\' not exists.', 'red'); + } } }; // After callbacks - $ac = [[], []]; - foreach ($section->getAfterCallbacks() as $cb) { - $ac[is_callable($cb)][] = $cb; - } - $deployment->runAfter = $ac[0]; - $deployment->runAfter[] = function ($server, $logger, $deployer) use ($ac, $config, $section): void { - foreach ($ac[1] as $c) { - call_user_func_array([$c, 'onAfter'], [$config, $section, $server, $logger, $deployer]); + $deployment->runAfter[] = function (Server $server, Logger $logger, Deployer $deployer) use ($config, $section): void { + foreach ($section->getAfterCallbacks() as $ac) { + if(is_callable($ac)) { + call_user_func_array($ac, [$config, $section, $server, $logger, $deployer]); + } else { + $logger->log('After callback \'' . get_class($ac[0]) . '::' . $ac[1] . '\' not exists.', 'red'); + } } }; return $deployment; } + /** + * @param Section $section + * + * @return Server + * @throws \Exception + */ protected function createServer(Section $section): Server { return parse_url((string) $section->getRemote(), PHP_URL_SCHEME) === 'sftp'