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(''); } }