protected function execute(InputInterface $input, OutputInterface $output)
 {
     $output->writeln('Hello Terra!');
     // Ask for an app and environment.
     $this->getApp($input, $output);
     $this->getEnvironment($input, $output);
     $environment_factory = new EnvironmentFactory($this->environment, $this->app);
     $environment_factory->getConfig();
     // Run the tests
     // @TODO: Move to factory.
     $output->writeln('<info>TERRA</info> | <comment>Test: Start...</comment>');
     $output->writeln('<info>TERRA</info> | ' . $environment_factory->config['hooks']['test']);
     // Set environment variables for behat tests
     $env = array();
     $env['HOME'] = $_SERVER['HOME'];
     $behat_vars = array('extensions' => array('Behat\\MinkExtension' => array('base_url' => 'http://' . $environment_factory->getUrl())));
     // @TODO: This is NOT WORKING.  We MUST figure out how to override the base_url.
     $env['BEHAT_PARAMS'] = json_encode($behat_vars);
     $process = new Process($environment_factory->config['hooks']['test'], $environment_factory->getSourcePath(), $env);
     $process->run(function ($type, $buffer) {
         if (Process::ERR === $type) {
             echo $buffer;
         } else {
             echo $buffer;
         }
     });
     if (!$process->isSuccessful()) {
         $output->writeln('<info>TERRA</info> | <fg=red>Test Failed</> ' . $hook);
     } else {
         $output->writeln('<info>TERRA</info> | <info>Test Passed: </info> ' . $hook);
     }
     $output->writeln('');
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // Ask for an app and environment.
     $this->getApp($input, $output);
     $this->getEnvironment($input, $output);
     $environment_name = $this->environment->name;
     $app_name = $this->app->name;
     // Attempt to enable the environment.
     $environment_factory = new EnvironmentFactory($this->environment, $this->app);
     if (!$environment_factory->enable()) {
         $output->writeln('<error>Something went wrong, environment not enabled.</error>');
         return;
     }
     // Get new port, set new URL to environment object.
     $port = $environment_factory->getPort();
     $host = $environment_factory->getHost();
     $this->environment->url = "http://{$host}:{$port}";
     // When passing to saveEnvironment, it must have app and name properties (for now).
     $this->environment->app = $app_name;
     $this->environment->name = $environment_name;
     // Save environment metadata.
     $this->getApplication()->getTerra()->getConfig()->saveEnvironment($this->environment);
     if ($this->getApplication()->getTerra()->getConfig()->save()) {
         $output->writeln('<info>Environment enabled!</info>  Available at http://' . $environment_factory->getUrl() . ' and ' . $this->environment->url);
     } else {
         $output->writeln('<error>Environment info not saved.</error>');
     }
     // Write drush alias.
     $drush_alias_file_path = "{$_SERVER['HOME']}/.drush/{$app_name}.aliases.drushrc.php";
     if ($environment_factory->writeDrushAlias()) {
         $output->writeln("<info>Drush alias file created at {$drush_alias_file_path}</info>");
         $output->writeln("Wrote drush alias file to <comment>{$drush_alias_file_path}</comment>");
         $output->writeln("Use <info>drush @{$app_name}.{$environment_name}</info> to access the site.");
     } else {
         $output->writeln('<error>Unable to save drush alias.</error>');
     }
     // Run the enable hooks
     $output->writeln('');
     $output->writeln('Running <comment>ENABLE</comment> app hook...');
     $environment_factory->getConfig();
     // @TODO: Figure out how to only run this hook the first time!
     if (!empty($environment_factory->config['hooks']['enable_first'])) {
         // Output what we are running
         $formatter = $this->getHelper('formatter');
         $errorMessages = array($environment_factory->config['hooks']['enable_first']);
         $formattedBlock = $formatter->formatBlock($errorMessages, 'question');
         $output->writeln($formattedBlock);
         chdir($environment_factory->getSourcePath());
         $process = new Process($environment_factory->config['hooks']['enable_first']);
         $process->setTimeout(null);
         $process->run(function ($type, $buffer) {
             if (Process::ERR === $type) {
                 echo $buffer;
             } else {
                 echo $buffer;
             }
         });
     }
 }
 protected function prepareBehat(InputInterface $input, OutputInterface $output, EnvironmentFactory $environment_factory)
 {
     $output->writeln("I noticed you don't have behat tests for your project.");
     $helper = $this->getHelper('question');
     $question = new ConfirmationQuestion('Would you like to add behat tests? [y\\N] ');
     if ($helper->ask($input, $output, $question)) {
         $question = new Question('Where would you like to add your tests? (tests) ', 'tests');
         $tests_path = $helper->ask($input, $output, $question);
         // Create tests path
         $fs = new Filesystem();
         try {
             $fs->mkdir($environment_factory->getSourcePath() . '/' . $tests_path);
         } catch (IOException $e) {
             throw \Exception($e->getMessage());
         }
         $output->writeln("<info>SUCCESS</info> Created {$tests_path}.");
         // Create composer.json and behat.yml
         $composer_path = $environment_factory->getSourcePath() . '/' . $tests_path . '/composer.json';
         $behat_yml_path = $environment_factory->getSourcePath() . '/' . $tests_path . '/behat.yml';
         try {
             $fs->dumpFile($composer_path, $this->getBehatDrupalComposer());
             $url = "http://{$environment_factory->getHost()}:{$environment_factory->getPort()}";
             $fs->dumpFile($behat_yml_path, $this->getBehatYml($url));
             $output->writeln("<info>SUCCESS</info> Created composer.json and behat.yml.");
         } catch (IOException $e) {
             throw \Exception($e->getMessage());
         }
         $behat_path = $this->environment->path . '/' . $tests_path;
         // Run composer install
         $output->writeln("<info>RUNNING</info> composer install");
         $output->writeln("in: {$behat_path}");
         $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("");
         // Run behat --init
         $output->writeln("<info>RUNNING</info> bin/behat --init");
         $output->writeln("in: {$behat_path}");
         $process = new Process('bin/behat --init', $behat_path);
         $process->run(function ($type, $buffer) {
             if (Process::ERR === $type) {
                 echo $buffer;
             } else {
                 echo $buffer;
             }
         });
         // Set behat_path in .terra.yml
         $output->writeln("<comment>NOTE You should add `behat_path: {$tests_path}` to .terra.yml.</>");
     }
 }
 protected function prepareBehat(InputInterface $input, OutputInterface $output, EnvironmentFactory $environment_factory)
 {
     $output->writeln("I noticed you don't have behat tests for your project.");
     $helper = $this->getHelper('question');
     $question = new ConfirmationQuestion('Would you like to add behat tests? [y\\N] ');
     if ($helper->ask($input, $output, $question)) {
         $question = new Question('Where would you like to add your tests? (tests) ', 'tests');
         $tests_path = $helper->ask($input, $output, $question);
         // Create tests path
         $tests_path = $environment_factory->getSourcePath() . '/' . $tests_path;
         $fs = new Filesystem();
         try {
             $fs->mkdir($environment_factory->getSourcePath() . '/' . $tests_path);
         } catch (IOException $e) {
             throw \Exception($e->getMessage());
         }
         $output->writeln("<info>SUCCESS</info> Created {$tests_path}.");
         // Create composer.json and behat.yml
         $composer_path = $environment_factory->getSourcePath() . '/' . $tests_path . '/composer.json';
         $behat_yml_path = $environment_factory->getSourcePath() . '/' . $tests_path . '/behat.yml';
         try {
             $fs->dumpFile($composer_path, $this->getBehatDrupalComposer());
             $fs->dumpFile($behat_yml_path, $this->getBehatYml($environment_factory->getUrl()));
             $output->writeln("<info>SUCCESS</info> Created composer.json and behat.yml.");
         } catch (IOException $e) {
             throw \Exception($e->getMessage());
         }
         // Run composer install
         $process = new Process('composer install', $tests_path);
         // Run behat --init
         // Set behat_path in .terra.yml
     }
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // If there are no apps, return
     if (count($this->getApplication()->getTerra()->getConfig()->get('apps')) == 0) {
         $output->writeln('<comment>There are no apps to remove!</comment>');
         $output->writeln('Use the command <info>terra app:add</info> to add your first app.');
         return;
     }
     $helper = $this->getHelper('question');
     $app_name = $input->getArgument('app_name');
     $environment_name = $input->getArgument('environment_name');
     // If no name specified provide options
     if (empty($app_name)) {
         $question = new ChoiceQuestion('Which app? ', array_keys($this->getApplication()->getTerra()->getConfig()->get('apps')), null);
         $app_name = $helper->ask($input, $output, $question);
     }
     $app = $this->getApplication()->getTerra()->getConfig()->get('apps', $app_name);
     // If no environments:
     if (count($app['environments']) == 0) {
         $output->writeln("<comment>There are no environments for the app {$app_name}!</comment>");
         $output->writeln('Use the command <info>terra environment:add</info> to add your first environment.');
         return;
     }
     // If no environment name specified provide options
     if (empty($environment_name)) {
         $question = new ChoiceQuestion('Which environment? ', array_keys($app['environments']), null);
         $environment_name = $helper->ask($input, $output, $question);
     }
     $environment = $app['environments'][$environment_name];
     // Attempt to enable the environment.
     $environment_factory = new EnvironmentFactory($environment, $app);
     if (!$environment_factory->enable()) {
         $output->writeln('<error>Something went wrong, environment not enabled.</error>');
         return;
     }
     // Get new port, set new URL to environment object.
     $port = $environment_factory->getPort();
     $host = $environment_factory->getHost();
     $app['environments'][$environment_name]['url'] = "http://{$host}:{$port}";
     // Save environment metadata.
     $this->getApplication()->getTerra()->getConfig()->add('apps', array($app_name, 'environments', $environment_name), $app['environments'][$environment_name]);
     // Save config to files.
     if ($this->getApplication()->getTerra()->getConfig()->save()) {
         $output->writeln('<info>Environment enabled!</info>  Available at http://' . $environment_factory->getUrl() . ' and ' . $app['environments'][$environment_name]['url']);
     } else {
         $output->writeln('<error>Environment info not saved.</error>');
     }
     // Write drush alias.
     $drush_alias_file_path = "{$_SERVER['HOME']}/.drush/{$app_name}.aliases.drushrc.php";
     if ($environment_factory->writeDrushAlias()) {
         $output->writeln("<info>Drush alias file created at {$drush_alias_file_path}</info>");
         $output->writeln("Wrote drush alias file to <comment>{$drush_alias_file_path}</comment>");
         $output->writeln("Use <info>drush @{$app_name}.{$environment_name}</info> to access the site.");
     } else {
         $output->writeln('<error>Unable to save drush alias.</error>');
     }
     // Run the enable hooks
     $output->writeln('');
     $output->writeln('Running <comment>ENABLE</comment> app hook...');
     $environment_factory->getConfig();
     if (!empty($environment_factory->config['hooks']['enable'])) {
         // Output what we are running
         $formatter = $this->getHelper('formatter');
         $errorMessages = array($environment_factory->config['hooks']['enable']);
         $formattedBlock = $formatter->formatBlock($errorMessages, 'question');
         $output->writeln($formattedBlock);
         chdir($environment_factory->getSourcePath());
         $process = new Process($environment_factory->config['hooks']['enable']);
         $process->run(function ($type, $buffer) {
             if (Process::ERR === $type) {
                 echo $buffer;
             } else {
                 echo $buffer;
             }
         });
     }
 }
 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('');
     }
 }