Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
meltmedia/meltconsole / src / App / Commands / SyncRemoteEnvironmentsCommand.php
Size: Mime:
<?php

namespace MeltConsole\App\Commands;

use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;

/**
 * Class to sync between remote environments.
 */
class SyncRemoteEnvironmentsCommand extends MeltCommand {

  /**
   * Question helper.
   *
   * @var \Symfony\Component\Console\Helper\QuestionHelper
   */
  private $question;

  /**
   * {@inheritdoc}
   */
  protected function configure() {
    // Initial config for command.
    $this
      ->setName('melt:sync-remote-envs')
      ->setAliases(['melt:sre'])
      ->setDescription('Sync database and/or files.')
      ->setHelp('Syncs database and/or files across remote environments...')
      ->addOption('src', 's', InputOption::VALUE_REQUIRED, 'Source environment')
      ->addOption('target', 't', InputOption::VALUE_REQUIRED, 'Destination environment');
  }

  /**
   * {@inheritdoc}
   */
  protected function interact(InputInterface $input, OutputInterface $output) {
    // TODO: Change the autogenerated stub.
    parent::interact($input, $output);

    $this->question = $this->getHelper('question');

    if (!$input->getOption('src') && !$input->getOption('target')) {
      // Ask the user some stuff.
      $envs = $this->getEnvironmentsFromServer();

      if (empty($envs)) {
        throw new \Exception('There are currently no environments.');
      }
      $srcQuestion = new ChoiceQuestion('Choose environment to sync with: ', $envs);
      $srcEnv = $this->question->ask($input, $output, $srcQuestion);

      // remove src from `$envs` array
      $envs = array_diff($envs, [$srcEnv]);

      $targetQuestion = new ChoiceQuestion('Choose environment to sync to: ', $envs);
      $targetEnv = $this->question->ask($input, $output, $targetQuestion);

      // Ask questions.
      $confirmSyncQuestion = new ConfirmationQuestion(
        "Sync <info>{$srcEnv}</info> to <info>{$targetEnv}</info>? (n/Y) ",
        TRUE
      );
      $confirmSync = $this->question->ask($input, $output, $confirmSyncQuestion);

      if($confirmSync) {
        // Set options based on users answer.
        $input->setOption('src', $srcEnv);
        $input->setOption('target', $targetEnv);
      }

    }
  }

  /**
   * {@inheritdoc}
   */
  protected function execute(InputInterface $input, OutputInterface $output) {

    $srcEnv = $input->getOption('src');
    $targetEnv = $input->getOption('target');
    $srcDir = "{$this->projectName}-{$srcEnv}";
    $destDir = "{$this->projectName}-{$targetEnv}";

    if (!$this->validateEnvironmentExistsOnServer($srcEnv)) {
      throw new \Exception("<info>{$src}</info> environment doesn\'t exist.");
    }

    if (!$this->validateEnvironmentExistsOnServer($targetEnv)) {
      throw new \Exception("<info>{$src}</info> environment doesn\'t exist.");
    }

    $syncOptionsQuestion = new ChoiceQuestion(
      'What resources would you like to sync:',
      ['database', 'files', 'both']
    );

    $syncOptionsQuestion->setValidator(function($answer){
      if(empty($answer)){
        throw new \Exception('Please choose an option.');
      }
      return $answer;
    });

    $syncOptionsQuestion->setMaxAttempts(2);
    $resource = $this->question->ask($input, $output, $syncOptionsQuestion);

    if($resource === 'both' || $resource === 'database') {
      $output->writeln("Syncing database from <info>{$srcDir}</info> to <info>{$destDir}</info> in progress...");
      $this->runServerCommands([
        "cd /{$this->serverRoot}/{$srcDir}",
        "drush sql:dump --result-file=/{$this->serverRoot}/{$destDir}/backup.sql",
        "cd /{$this->serverRoot}/{$destDir}",
        'drush sql-drop -y',
        'drush sqlc < backup.sql',
        'drush cr',
        'rm -f backup.sql'
      ], FALSE);
    }

    if($resource === 'both' || $resource === 'files') {
      $output->write("Syncing files from <info>{$srcDir}</info> to <info>{$destDir}</info> in progress...");
      $this->runServerCommands([
        "cd /{$this->serverRoot}/{$srcDir}",
        "sudo rsync -azh ./docroot/sites/default/files/ /{$this->serverRoot}/{$destDir}/docroot/sites/default/files",
        "drush cr",
      ], FALSE);
    }

    $output->writeln('<info>Syncing complete! Take care now, bye bye then!</info>');
  }

}