diff --git a/composer.json b/composer.json index 9014dc1..e2adb4c 100644 --- a/composer.json +++ b/composer.json @@ -5,9 +5,10 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "digipolisgent/robo-digipolis-helpers": "^0.2.1", + "digipolisgent/robo-digipolis-helpers": "^1.0@alpha", "symfony/yaml": "~4", - "vlucas/phpdotenv": "^2.5" + "vlucas/phpdotenv": "^2.5", + "digipolisgent/robo-digipolis-code-validation": "^0.1.1" }, "require-dev": { "phpunit/phpunit": "~5|~4.4" diff --git a/src/RoboFileBase.php b/src/RoboFileBase.php index ce3a74a..5546a93 100644 --- a/src/RoboFileBase.php +++ b/src/RoboFileBase.php @@ -4,13 +4,23 @@ use DigipolisGent\Robo\Helpers\AbstractRoboFile; use DigipolisGent\Robo\Task\Deploy\Ssh\Auth\AbstractAuth; -use DigipolisGent\Robo\Task\Deploy\Ssh\Auth\KeyFile; use Dotenv\Dotenv; use Symfony\Component\Finder\Finder; class RoboFileBase extends AbstractRoboFile { use \DigipolisGent\Robo\Task\Package\Utility\NpmFindExecutable; + use \DigipolisGent\Robo\Task\CodeValidation\loadTasks; + use \DigipolisGent\Robo\Helpers\Traits\AbstractCommandTrait; + use \DigipolisGent\Robo\Task\Deploy\Commands\loadCommands; + use \DigipolisGent\Robo\Task\Package\Traits\ThemeCompileTrait; + use \DigipolisGent\Robo\Task\Package\Traits\ThemeCleanTrait; + use Traits\BuildSymfonyTrait; + use Traits\DeploySymfonyTrait; + use Traits\UpdateSymfonyTrait; + use Traits\InstallSymfonyTrait; + use Traits\SyncSymfonyTrait; + /** * Path to the symfony console executable. */ @@ -25,6 +35,9 @@ public function __construct() $this->console = 'bin/console'; } + /** + * {@inheritdoc} + */ protected function isSiteInstalled($worker, AbstractAuth $auth, $remote) { $currentProjectRoot = $this->getCurrentProjectRoot($worker, $auth, $remote); @@ -43,21 +56,21 @@ public function digipolisValidateCode() { $local = $this->getLocalSettings(); $directories = [ - $local['project_root'] . '/src', + $local['project_root'] . '/src', ]; // Check if directories exist. $checks = []; foreach ($directories as $dir) { - if (!file_exists($dir)) { - continue; - } + if (!file_exists($dir)) { + continue; + } - $checks[] = $dir; + $checks[] = $dir; } if (!$checks) { - $this->say('! No custom directories to run checks on.'); - return; + $this->say('! No custom directories to run checks on.'); + return; } $phpcs = $this ->taskPhpCs( @@ -87,6 +100,9 @@ public function digipolisValidateCode() return $collection; } + /** + * {@inheritdoc} + */ protected function preRestoreBackupTask( $worker, AbstractAuth $auth, @@ -114,41 +130,22 @@ protected function preRestoreBackupTask( return $collection; } - protected function installTask($worker, AbstractAuth $auth, $remote, $extra = [], $force = false) - { - $currentProjectRoot = $remote['rootdir'];; - $collection = $this->collectionBuilder(); - $collection->taskSsh($worker, $auth) - ->remoteDirectory($currentProjectRoot, true) - // Install can take a long time. Let's set it to 15 minutes. - ->timeout(900); - if ($force) { - $collection->exec($this->console . ' doctrine:schema:drop --full-database --force'); - } - $collection->exec('vendor/bin/robo digipolis:install-symfony'); - return $collection; - } - - protected function updateTask($server, AbstractAuth $auth, $remote, $extra = []) - { - $currentProjectRoot = $remote['rootdir']; - return $this->taskSsh($server, $auth) - ->remoteDirectory($currentProjectRoot, true) - // Updates can take a long time. Let's set it to 15 minutes. - ->timeout(900) - ->exec('vendor/bin/robo digipolis:update-symfony'); - } - + /** + * {@inheritdoc} + */ protected function clearCacheTask($worker, $auth, $remote) { $currentProjectRoot = $remote['rootdir']; return $this->taskSsh($worker, $auth) - ->remoteDirectory($currentProjectRoot, true) - ->timeout(120) - ->exec($this->console . ' cache:clear') - ->exec($this->console . ' cache:warmup'); + ->remoteDirectory($currentProjectRoot, true) + ->timeout(120) + ->exec($this->console . ' cache:clear') + ->exec($this->console . ' cache:warmup'); } + /** + * {@inheritdoc} + */ protected function buildTask($archivename = null) { $archive = is_null($archivename) ? $this->time . '.tar.gz' : $archivename; @@ -174,301 +171,8 @@ protected function buildTask($archivename = null) } /** - * Build a Symfony site and push it to the servers. - * - * @param array $arguments - * Variable amount of arguments. The last argument is the path to the - * the private key file (ssh), the penultimate is the ssh user. All - * arguments before that are server IP's to deploy to. - * @param array $opts - * The options for this command. - * - * @option app The name of the app we're deploying. Used to determine the - * directory to deploy to. - * @option worker The IP of the worker server. Defaults to the first server - * given in the arguments. - * - * @usage --app=myapp 10.25.2.178 sshuser /home/myuser/.ssh/id_rsa - */ - public function digipolisDeploySymfony( - array $arguments, - $opts = [ - 'app' => 'default', - 'worker' => null, - ] - ) { - return $this->deployTask($arguments, $opts); - } - - /** - * Build a Symfony site and package it. - * - * @param string $archivename - * Name of the archive to create. - * - * @usage test.tar.gz - */ - public function digipolisBuildSymfony($archivename = null) - { - return $this->buildTask($archivename); - } - - /** - * Install or update a Symfony remote site. - * - * @param string $server - * The server to install the site on. - * @param string $user - * The ssh user to use to connect to the server. - * @param string $privateKeyFile - * The path to the private key file to use to connect to the server. - * @param array $opts - * The options for this command. - * - * @option app The name of the app we're deploying. Used to determine the - * directory in which the drupal site can be found. - * - * @usage --app=myapp 10.25.2.178 sshuser /home/myuser/.ssh/id_rsa - */ - public function digipolisInitSymfonyRemote( - $server, - $user, - $privateKeyFile, - $opts = [ - 'app' => 'default', - 'force-install' => false - ] - ) { - $remote = $this->getRemoteSettings($server, $user, $privateKeyFile, $opts['app']); - $auth = new KeyFile($user, $privateKeyFile); - return $this->initRemoteTask($privateKeyFile, $auth, $remote, $opts, $opts['force-install']); - } - - /** - * Executes database updates of the Symfony site in the current folder. - * - * Executes database updates of the Symfony site in the current folder. Sets - * the site in maintenance mode before the update and takes in out of - * maintenance mode after. - */ - public function digipolisUpdateSymfony() - { - $this->readProperties(); - $collection = $this->collectionBuilder(); - $collection - ->taskExecStack() - ->exec($this->console . ' cache:clear') - ->exec($this->console . ' doctrine:migrations:migrate --no-interaction'); - return $collection; - } - - /** - * Install the Symfony site in the current folder. - */ - public function digipolisInstallSymfony() - { - $this->readProperties(); - $collection = $this->collectionBuilder(); - $collection - ->taskExecStack() - ->exec($this->console . ' cache:clear') - ->exec($this->console . ' doctrine:migrations:migrate --no-interaction'); - return $collection; - } - - /** - * Sync the database and files between two Symfony sites. - * - * @param string $sourceUser - * SSH user to connect to the source server. - * @param string $sourceHost - * IP address of the source server. - * @param string $sourceKeyFile - * Private key file to use to connect to the source server. - * @param string $destinationUser - * SSH user to connect to the destination server. - * @param string $destinationHost - * IP address of the destination server. - * @param string $destinationKeyFile - * Private key file to use to connect to the destination server. - * @param string $sourceApp - * The name of the source app we're syncing. Used to determine the - * directory to sync. - * @param string $destinationApp - * The name of the destination app we're syncing. Used to determine the - * directory to sync to. - */ - public function digipolisSyncSymfony( - $sourceUser, - $sourceHost, - $sourceKeyFile, - $destinationUser, - $destinationHost, - $destinationKeyFile, - $sourceApp = 'default', - $destinationApp = 'default', - $opts = ['files' => false, 'data' => false] - ) { - if (!$opts['files'] && !$opts['data']) { - $opts['files'] = true; - $opts['data'] = true; - } - return $this->syncTask( - $sourceUser, - $sourceHost, - $sourceKeyFile, - $destinationUser, - $destinationHost, - $destinationKeyFile, - $sourceApp, - $destinationApp, - $opts - ); - } - - /** - * Create a backup of files (storage folder) and database. - * - * @param string $host - * The server of the website. - * @param string $user - * The ssh user to use to connect to the server. - * @param string $keyFile - * The path to the private key file to use to connect to the server. - * @param array $opts - * The options for this command. - * - * @option app The name of the app we're creating the backup for. - */ - public function digipolisBackupSymfony( - $host, - $user, - $keyFile, - $opts = ['app' => 'default', 'files' => false, 'data' => false] - ) { - if (!$opts['files'] && !$opts['data']) { - $opts['files'] = true; - $opts['data'] = true; - } - $remote = $this->getRemoteSettings($host, $user, $keyFile, $opts['app']); - $auth = new KeyFile($user, $keyFile); - return $this->backupTask($host, $auth, $remote, $opts); - } - - /** - * Restore a backup of files (storage folder) and database. - * - * @param string $host - * The server of the website. - * @param string $user - * The ssh user to use to connect to the server. - * @param string $keyFile - * The path to the private key file to use to connect to the server. - * @param array $opts - * The options for this command. - * - * @option app The name of the app we're restoring the backup for. - * @option timestamp The timestamp when the backup was created. Defaults to - * the current time, which is only useful when syncing between servers. - * - * @see digipolisBackupSymfony - */ - public function digipolisRestoreBackupSymfony( - $host, - $user, - $keyFile, - $opts = [ - 'app' => 'default', - 'timestamp' => null, - 'files' => false, - 'data' => false, - ] - ) { - if (!$opts['files'] && !$opts['data']) { - $opts['files'] = true; - $opts['data'] = true; - } - $remote = $this->getRemoteSettings($host, $user, $keyFile, $opts['app'], $opts['timestamp']); - $auth = new KeyFile($user, $keyFile); - return $this->restoreBackupTask($host, $auth, $remote, $opts); - } - - /** - * Download a backup of files (storage folder) and database. - * - * @param string $host - * The server of the website. - * @param string $user - * The ssh user to use to connect to the server. - * @param string $keyFile - * The path to the private key file to use to connect to the server. - * @param array $opts - * The options for this command. - * - * @option app The name of the app we're downloading the backup for. - * @option timestamp The timestamp when the backup was created. Defaults to - * the current time, which is only useful when syncing between servers. - * - * @see digipolisBackupSymfony - */ - public function digipolisDownloadBackupSymfony( - $host, - $user, - $keyFile, - $opts = [ - 'app' => 'default', - 'timestamp' => null, - 'files' => false, - 'data' => false, - ] - ) { - if (!$opts['files'] && !$opts['data']) { - $opts['files'] = true; - $opts['data'] = true; - } - $remote = $this->getRemoteSettings($host, $user, $keyFile, $opts['app'], $opts['timestamp']); - $auth = new KeyFile($user, $keyFile); - return $this->downloadBackupTask($host, $auth, $remote, $opts); - } - - /** - * Upload a backup of files (storage folder) and database to a server. - * - * @param string $host - * The server of the website. - * @param string $user - * The ssh user to use to connect to the server. - * @param string $keyFile - * The path to the private key file to use to connect to the server. - * @param array $opts - * The options for this command. - * - * @option app The name of the app we're uploading the backup for. - * @option timestamp The timestamp when the backup was created. Defaults to - * the current time, which is only useful when syncing between servers. - * - * @see digipolisBackupSymfony + * {@inheritdoc} */ - public function digipolisUploadBackupSymfony( - $host, - $user, - $keyFile, - $opts = [ - 'app' => 'default', - 'timestamp' => null, - 'files' => false, - 'data' => false, - ] - ) { - if (!$opts['files'] && !$opts['data']) { - $opts['files'] = true; - $opts['data'] = true; - } - $remote = $this->getRemoteSettings($host, $user, $keyFile, $opts['app'], $opts['timestamp']); - $auth = new KeyFile($user, $keyFile); - return $this->uploadBackupTask($host, $auth, $remote, $opts); - } - protected function defaultDbConfig() { $rootDir = $this->getConfig()->get('digipolis.root.project', false); diff --git a/src/Traits/BackupSymfonyTrait.php b/src/Traits/BackupSymfonyTrait.php new file mode 100644 index 0000000..a6f4019 --- /dev/null +++ b/src/Traits/BackupSymfonyTrait.php @@ -0,0 +1,46 @@ + 'default', 'files' => false, 'data' => false] + ) { + if (!$opts['files'] && !$opts['data']) { + $opts['files'] = true; + $opts['data'] = true; + } + $remote = $this->getRemoteSettings($host, $user, $keyFile, $opts['app']); + $auth = new KeyFile($user, $keyFile); + return $this->backupTask($host, $auth, $remote, $opts); + } +} diff --git a/src/Traits/BuildSymfonyTrait.php b/src/Traits/BuildSymfonyTrait.php new file mode 100644 index 0000000..ceef785 --- /dev/null +++ b/src/Traits/BuildSymfonyTrait.php @@ -0,0 +1,29 @@ +buildTask($archivename); + } +} diff --git a/src/Traits/DeploySymfonyTrait.php b/src/Traits/DeploySymfonyTrait.php new file mode 100644 index 0000000..da4cc52 --- /dev/null +++ b/src/Traits/DeploySymfonyTrait.php @@ -0,0 +1,43 @@ + 'default', + 'worker' => null, + ] + ) { + return $this->deploy($arguments, $opts); + } +} diff --git a/src/Traits/InstallSymfonyTrait.php b/src/Traits/InstallSymfonyTrait.php new file mode 100644 index 0000000..ec75fdb --- /dev/null +++ b/src/Traits/InstallSymfonyTrait.php @@ -0,0 +1,46 @@ +collectionBuilder(); + $collection->taskSsh($worker, $auth) + ->remoteDirectory($currentProjectRoot, true) + // Install can take a long time. Let's set it to 15 minutes. + ->timeout(900); + if ($force) { + $collection->exec($this->console . ' doctrine:schema:drop --full-database --force'); + } + $collection->exec('vendor/bin/robo digipolis:install-symfony'); + return $collection; + } + + /** + * Install the Symfony site in the current folder. + */ + public function digipolisInstallSymfony() + { + $this->readProperties(); + $collection = $this->collectionBuilder(); + $collection + ->taskExecStack() + ->exec($this->console . ' cache:clear') + ->exec($this->console . ' doctrine:migrations:migrate --no-interaction'); + return $collection; + } +} diff --git a/src/Traits/RestoreBackupSymfonyTrait.php b/src/Traits/RestoreBackupSymfonyTrait.php new file mode 100644 index 0000000..d9cc8ef --- /dev/null +++ b/src/Traits/RestoreBackupSymfonyTrait.php @@ -0,0 +1,55 @@ + 'default', + 'timestamp' => null, + 'files' => false, + 'data' => false, + ] + ) { + if (!$opts['files'] && !$opts['data']) { + $opts['files'] = true; + $opts['data'] = true; + } + $remote = $this->getRemoteSettings($host, $user, $keyFile, $opts['app'], $opts['timestamp']); + $auth = new KeyFile($user, $keyFile); + return $this->restoreBackupTask($host, $auth, $remote, $opts); + } +} diff --git a/src/Traits/SyncSymfonyTrait.php b/src/Traits/SyncSymfonyTrait.php new file mode 100644 index 0000000..f03e09e --- /dev/null +++ b/src/Traits/SyncSymfonyTrait.php @@ -0,0 +1,66 @@ + false, 'data' => false] + ) { + if (!$opts['files'] && !$opts['data']) { + $opts['files'] = true; + $opts['data'] = true; + } + return $this->sync( + $sourceUser, + $sourceHost, + $sourceKeyFile, + $destinationUser, + $destinationHost, + $destinationKeyFile, + $sourceApp, + $destinationApp, + $opts + ); + } +} diff --git a/src/Traits/UpdateSymfonyTrait.php b/src/Traits/UpdateSymfonyTrait.php new file mode 100644 index 0000000..f814259 --- /dev/null +++ b/src/Traits/UpdateSymfonyTrait.php @@ -0,0 +1,45 @@ +taskSsh($server, $auth) + ->remoteDirectory($currentProjectRoot, true) + // Updates can take a long time. Let's set it to 15 minutes. + ->timeout(900) + ->exec('vendor/bin/robo digipolis:update-symfony'); + } + + /** + * Executes database updates of the Symfony site in the current folder. + * + * Executes database updates of the Symfony site in the current folder. Sets + * the site in maintenance mode before the update and takes in out of + * maintenance mode after. + */ + public function digipolisUpdateSymfony() + { + $this->readProperties(); + $collection = $this->collectionBuilder(); + $collection + ->taskExecStack() + ->exec($this->console . ' cache:clear') + ->exec($this->console . ' doctrine:migrations:migrate --no-interaction'); + return $collection; + } +}