예제 #1
0
 /**
  * Using the config item "behat_path", run composer update and bin/behat in the behat path.
  *
  * @param InputInterface $input
  * @param OutputInterface $output
  */
 protected function executeBehatTests(InputInterface $input, OutputInterface $output)
 {
     $output->writeln('Running Behat Tests...');
     $environment_factory = new EnvironmentFactory($this->environment, $this->app);
     $environment_factory->getConfig();
     // 1. Look for behat.yml
     $behat_path = $this->environment->path . '/' . $environment_factory->config['behat_path'];
     $behat_yml_path = $behat_path . '/behat.yml';
     if (!file_exists($behat_path)) {
         throw new \Exception("Path {$behat_path} not found. Check your app's .terra.yml file.");
     } elseif (!file_exists($behat_yml_path)) {
         throw new \Exception("Behat.yml file not found at {$behat_yml_path}. Check your app's .terra.yml file.");
     }
     $output->writeln('Found behat.yml file at ' . $behat_yml_path);
     // 2. Load it, replace necessary items, and clone it to a temporary file.
     $behat_yml = Yaml::parse(file_get_contents($behat_yml_path));
     // Set Base URL
     $behat_yml['default']['extensions']['Behat\\MinkExtension']['base_url'] = "http://{$environment_factory->getHost()}:{$environment_factory->getPort()}";
     $behat_yml['default']['extensions']['Drupal\\DrupalExtension']['drush']['alias'] = $environment_factory->getDrushAlias();
     // If driver is drupal, add root.
     if ($behat_yml['default']['extensions']['Drupal\\DrupalExtension']['api_driver'] == 'drupal') {
         $behat_yml['default']['extensions']['Drupal\\DrupalExtension']['drupal']['root'] = $environment_factory->getDocumentRoot();
     }
     $behat_yml_new = Yaml::dump($behat_yml, 5, 2);
     $behat_path_new = 'behat.terra.yml';
     $fs = new Filesystem();
     $fs->dumpFile($behat_path_new, $behat_yml_new);
     $output->writeln('Generated new behat.yml file at ' . $behat_path_new);
     // 3. Run `composer install` in behat_path.
     $output->writeln('');
     $output->writeln('<fg=cyan>TERRA</> | <comment>Running: composer install</comment>');
     $process = new Process('composer install', $behat_path);
     $process->setTimeout(NULL);
     $process->run(function ($type, $buffer) {
         if (Process::ERR === $type) {
             echo $buffer;
         } else {
             echo $buffer;
         }
     });
     $output->writeln('');
     $output->writeln('<fg=cyan>TERRA</> | <comment>Behat Tests: Start</comment>');
     // 4. Run `bin/behat --colors --config=$PATH` in behat_path.
     // "expand:true" expands scenario outlines, making them readable.
     $cmd = 'bin/behat --colors --format-settings=\'{"expand": true}\' --config=' . $behat_path_new;
     if ($input->getOption('name')) {
         $cmd .= ' --name=' . $input->getOption('name');
     }
     $output->writeln("Running: {$cmd}");
     $output->writeln("in: {$behat_path}");
     $output->writeln('');
     $process = new Process($cmd, $behat_path);
     $process->setTimeout(NULL);
     $process->run(function ($type, $buffer) {
         if (Process::ERR === $type) {
             echo $buffer;
         } else {
             echo $buffer;
         }
     });
     $output->writeln('');
     if (!$process->isSuccessful()) {
         $output->writeln('<fg=cyan>TERRA</> | <fg=red>Test Failed</> ');
         return 1;
     } else {
         $output->writeln('<fg=cyan>TERRA</> | <info>Test Passed!</info> ');
         return 0;
     }
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // Ask for an app and environment.
     $this->getApp($input, $output);
     $this->getEnvironment($input, $output);
     // Don't continue unless we have an environment.
     if (empty($this->environment)) {
         return;
     }
     // Get Environment and Config
     $environment_factory = new EnvironmentFactory($this->environment, $this->app);
     $environment_factory->getConfig();
     // Get argument override
     $rebuild_source_argument = $input->getOption('source');
     // Check for config
     if (empty($environment_factory->config['rebuild_source'])) {
         if (empty($rebuild_source_argument)) {
             throw new \Exception("To run the 'environment:rebuild' command you must have 'rebuild_source: @drushalias' in your app's .terra.yml file (or specify the source drush alias with 'environment:rebuild --rebuild_source=@alias').");
         }
     } else {
         $rebuild_source_config = $environment_factory->config['rebuild_source'];
         $output->writeln("Found <comment>rebuild_source: {$rebuild_source_config}</comment> in <fg=cyan>.terra.yml</> file...");
     }
     // Get source and target aliases
     $source_alias = $rebuild_source_argument ? $rebuild_source_argument : $environment_factory->config['rebuild_source'];
     $target_alias = $environment_factory->getDrushAlias();
     // Mention to user where the alias is coming from.
     if ($rebuild_source_argument) {
         $output->writeln("Using terra command option for source alias: <fg=cyan>{$rebuild_source_argument}</>");
     }
     // Check that source doesn't equal target
     if ($source_alias == $target_alias) {
         throw new \Exception("You cannot use the same source and target (Source: {$source_alias} Target:{$target_alias}). Please check your config and try again.");
     }
     // Check ssh & sql access to both.
     $output->writeln('');
     $errors = FALSE;
     foreach (array($source_alias, $target_alias) as $alias) {
         $output->writeln("Checking access to alias <fg=cyan>{$alias}</> ...");
         $cmd = "drush {$alias} ssh 'echo \$SSH_CLIENT'";
         // SSH Check
         $process = new Process($cmd);
         $process->setTimeout(NULL);
         $process->run();
         if ($process->isSuccessful()) {
             $output->writeln("<info>SUCCESS</info> Connected to {$alias} via SSH. <comment>{$cmd}</comment>");
         } else {
             $output->writeln("<error>FAILURE</error> Unable to connect to {$alias} via SSH. <comment>{$cmd}</comment>");
             $errors = TRUE;
         }
         // SQL
         $cmd = "drush {$alias} sql-query 'SHOW TABLES'";
         $process = new Process($cmd);
         $process->setTimeout(NULL);
         $process->run();
         if ($process->isSuccessful()) {
             $output->writeln("<info>SUCCESS</info> Connected to {$alias} via MySQL. <comment>{$cmd}</comment>");
         } else {
             $output->writeln("<error>FAILURE</error> Unable to connect to {$alias} via MySQL. <comment>{$cmd}</comment>");
             $errors = TRUE;
         }
         $output->writeln('');
     }
     // If errors, don't continue
     if ($errors) {
         throw new \Exception('We were unable to connect to both of your environments. Please check your config & try again.');
     }
     // Database Sync Confirmation
     $helper = $this->getHelper('question');
     $question = new ConfirmationQuestion("Are you sure you want to destroy <fg=red>{$target_alias}</> and replace it with data from <fg=cyan>{$source_alias}</>? [y\\N] ", false);
     if (!$helper->ask($input, $output, $question)) {
         $output->writeln('<error>Database sync Cancelled</error>');
     } else {
         // Database Sync
         $cmd = "drush {$source_alias} sql-dump --gzip | gzip -cd | drush {$target_alias} sqlc";
         $output->writeln('');
         $output->writeln('Running...');
         $output->writeln("<comment>{$cmd}</comment>");
         $process = new Process($cmd);
         $process->setTimeout(NULL);
         $process->run();
         if ($process->isSuccessful()) {
             $output->writeln("<info>SUCCESS</info> Database Copied successfully!");
         } else {
             $output->writeln("<error>FAILURE</error> Database Copy Failed!");
         }
     }
     // Files Sync Confirmation
     $helper = $this->getHelper('question');
     $question = new ConfirmationQuestion("Copy files from <fg=cyan>{$source_alias}</> to <fg=red>{$target_alias}</>? Any existing files will be overwritten [y\\N] ", false);
     if (!$helper->ask($input, $output, $question)) {
         $output->writeln('<error>Files sync cancelled</error>');
         return;
     }
     // Files Sync
     // Get Source Path
     $source_files_path = $environment_factory->runDrushCommand('vget file_public_path --format=string', $source_alias);
     $target_files_path = $environment_factory->runDrushCommand('vget file_public_path --format=string');
     // If either variable is blank, assume default
     if (strpos($source_files_path, 'No matching') === 0) {
         $source_files_path = 'sites/default/files';
     }
     if (strpos($target_files_path, 'No matching') === 0) {
         $target_files_path = 'sites/default/files';
     }
     $default_source = "{$source_alias}:{$source_files_path}/";
     $default_target = $environment_factory->getSourcePath() . '/' . $environment_factory->config['document_root'] . '/' . $target_files_path . '/';
     $source_question = new Question("Source path? [{$default_source}] ", $default_source);
     $destination_question = new Question("Destination path? [{$default_target}] ", $default_target);
     $source = $helper->ask($input, $output, $source_question);
     $target = $helper->ask($input, $output, $destination_question);
     $cmd = "drush -y rsync {$source} {$target}";
     $output->writeln('');
     $output->writeln('Running...');
     $output->writeln("<comment>{$cmd}</comment>");
     $process = new Process($cmd);
     $process->setTimeout(NULL);
     $process->run();
     if ($process->isSuccessful()) {
         $output->writeln("<info>SUCCESS</info> Files copied successfully!");
     } else {
         $output->writeln("<error>FAILURE</error> Files did not copy successfully!");
     }
     // Rebuild Hooks
     if (isset($environment_factory->config['hooks']['rebuild'])) {
         $output->writeln('');
         $output->writeln('Running <fg=cyan>rebuild</> hooks from .terra.yml...');
         $output->writeln("<comment>{$environment_factory->config['hooks']['rebuild']}</comment>");
         $process = new Process($environment_factory->config['hooks']['rebuild'], $environment_factory->getSourcePath());
         $process->setTimeout(NULL);
         $process->run(function ($type, $buffer) {
             if (Process::ERR === $type) {
                 echo $buffer;
             } else {
                 echo $buffer;
             }
         });
         if ($process->isSuccessful()) {
             $output->writeln("<info>SUCCESS</info> Rebuild hooks completed successfully.");
         } else {
             $output->writeln("<error>FAILURE</error> Rebuild hooks did not complete successfully.");
         }
         $output->writeln('');
     }
 }