Esempio n. 1
0
 /**
  * @return string|false
  */
 public function getProjectRoot()
 {
     if (!isset(self::$projectRoot)) {
         $this->debug('Finding the project root based on the CWD');
         self::$projectRoot = $this->localProject->getProjectRoot();
         $this->debug(self::$projectRoot ? 'Project root found: ' . self::$projectRoot : 'Project root not found');
     }
     return self::$projectRoot;
 }
 /**
  * Builds Docker Compose YML file.
  *
  * @param $name
  */
 function __construct($name)
 {
     $this->path = LocalProject::getProjectRoot();
     $this->name = $name;
     // Add required containers.
     $this->addPhpFpm();
     $this->addDatabase();
     $this->addWebserver();
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $projectRoot = $this->getProjectRoot();
     if (!$projectRoot) {
         throw new RootNotFoundException();
     }
     $projectConfig = LocalProject::getProjectConfig($projectRoot);
     $current_group = isset($projectConfig['alias-group']) ? $projectConfig['alias-group'] : $projectConfig['id'];
     if ($input->getOption('pipe')) {
         $output->writeln($current_group);
         return 0;
     }
     $project = $this->getCurrentProject();
     $new_group = ltrim($input->getOption('group'), '@');
     $homeDir = $this->getHomeDir();
     $drushHelper = new DrushHelper($output);
     $drushHelper->ensureInstalled();
     $drushHelper->setHomeDir($homeDir);
     $aliases = $drushHelper->getAliases($current_group);
     if ($new_group && $new_group != $current_group || !$aliases || $input->getOption('recreate')) {
         $new_group = $new_group ?: $current_group;
         $this->stdErr->writeln("Creating Drush aliases in the group <info>@{$new_group}</info>");
         $questionHelper = $this->getHelper('question');
         if ($new_group != $current_group) {
             $existing = $drushHelper->getAliases($new_group);
             if ($existing && $new_group != $current_group) {
                 $question = "The Drush alias group <info>@{$new_group}</info> already exists. Overwrite?";
                 if (!$questionHelper->confirm($question, $input, $output, false)) {
                     return 1;
                 }
             }
             LocalProject::writeCurrentProjectConfig('alias-group', $new_group, $projectRoot);
         }
         $environments = $this->getEnvironments($project, true, false);
         $drushHelper->createAliases($project, $projectRoot, $environments, $current_group);
         if ($new_group != $current_group) {
             $drushDir = $homeDir . '/.drush';
             $oldFile = $drushDir . '/' . $current_group . '.aliases.drushrc.php';
             if (file_exists($oldFile)) {
                 if ($questionHelper->confirm("Delete old Drush alias group <info>@{$current_group}</info>?", $input, $this->stdErr)) {
                     unlink($oldFile);
                 }
             }
         }
         // Clear the Drush cache now that the aliases have been updated.
         $drushHelper->clearCache();
         // Read the new aliases.
         $aliases = $drushHelper->getAliases($new_group);
     }
     if ($aliases) {
         $this->stdErr->writeln("Drush aliases for <info>{$project->title}</info> ({$project->id}):");
         foreach (explode("\n", $aliases) as $alias) {
             $output->writeln('    @' . $alias);
         }
     }
     return 0;
 }
 /**
  * @param string $sourceDir
  *
  * @return string
  */
 protected function createDummyProject($sourceDir)
 {
     if (!is_dir($sourceDir)) {
         throw new \InvalidArgumentException("Not a directory: {$sourceDir}");
     }
     $tempDir = self::$root->getName();
     $projectRoot = tempnam($tempDir, '');
     unlink($projectRoot);
     mkdir($projectRoot);
     // Set up the project files.
     $local = new LocalProject();
     $local->createProjectFiles($projectRoot, 'testProjectId');
     // Make a dummy repository.
     $repositoryDir = $projectRoot . '/' . LocalProject::REPOSITORY_DIR;
     mkdir($repositoryDir);
     $fsHelper = new FilesystemHelper();
     $fsHelper->copyAll($sourceDir, $repositoryDir);
     return $projectRoot;
 }
 /**
  * @param string $sourceDir
  *
  * @return string
  */
 protected function createDummyProject($sourceDir)
 {
     if (!is_dir($sourceDir)) {
         throw new \InvalidArgumentException("Not a directory: {$sourceDir}");
     }
     $projectRoot = $this->createTempSubDir('project');
     // Set up the project.
     $fsHelper = new FilesystemHelper();
     $fsHelper->copyAll($sourceDir, $projectRoot);
     // @todo perhaps make some of these steps unnecessary
     $local = new LocalProject();
     $cwd = getcwd();
     chdir($projectRoot);
     exec('git init');
     chdir($cwd);
     $local->ensureGitRemote($projectRoot, 'testProjectId');
     $local->writeCurrentProjectConfig(['id' => 'testProjectId'], $projectRoot);
     return $projectRoot;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $directory = $input->getArgument('directory') ?: getcwd();
     $realPath = realpath($directory);
     if (!$realPath) {
         $this->stdErr->writeln("<error>Directory not found: {$directory}</error>");
         return 1;
     }
     if (!is_dir($realPath . '/.git')) {
         /** @var \Platformsh\Cli\Helper\PlatformQuestionHelper $questionHelper */
         $questionHelper = $this->getHelper('question');
         $question = "The directory is not a Git repository: <comment>{$realPath}</comment>\nInitialize a Git repository?";
         if ($questionHelper->confirm($question, $input, $this->stdErr)) {
             /** @var \Platformsh\Cli\Helper\GitHelper $gitHelper */
             $gitHelper = $this->getHelper('git');
             $gitHelper->ensureInstalled();
             $gitHelper->init($realPath, true);
         }
     }
     $gitUrl = null;
     $projectId = $input->getOption('project') ?: null;
     if ($projectId !== null) {
         $project = $this->getProject($projectId, $input->getOption('host'));
         if (!$project) {
             $this->stdErr->writeln("Project not found: <error>{$projectId}</error>");
             return 1;
         }
         $gitUrl = $project->getGitUrl();
         $projectId = $project->id;
     }
     $inside = strpos(getcwd(), $realPath) === 0;
     $local = new LocalProject();
     $projectRoot = $local->initialize($realPath, $projectId, $gitUrl);
     // Fetch environments to start caching, and to create Drush aliases,
     // etc.
     $this->setProjectRoot($projectRoot);
     $this->getEnvironments($this->getCurrentProject(), true);
     $this->stdErr->writeln("Project initialized in directory: <info>{$projectRoot}</info>");
     if ($inside) {
         $this->stdErr->writeln("<comment>Type 'cd .' to refresh your shell</comment>");
     }
     return 0;
 }
 /**
  * {@inheritdoc}
  *
  * @see PlatformCommand::getCurrentEnvironment()
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $xhpfg = LocalProject::getProjectRoot() . '/docker/xhpfg/xhprof-sample-to-flamegraph-stacks';
     $fg = LocalProject::getProjectRoot() . '/docker/fg/flamegraph.pl';
     $xhprof = LocalProject::getProjectRoot() . '/xhprof';
     $graphName = $input->getArgument('filename');
     $graphDestination = LocalProject::getProjectRoot() . '/' . $graphName . '.svg';
     exec("{$xhpfg} {$xhprof} | {$fg} > {$graphDestination}");
     $url = 'file://' . $graphDestination;
     $this->openUrl($url);
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $directory = $input->getArgument('directory') ?: getcwd();
     $realPath = realpath($directory);
     if (!$realPath) {
         $output->writeln("<error>Directory not found: {$directory}</error>");
         return 1;
     }
     $inside = strpos(getcwd(), $realPath) === 0;
     $local = new LocalProject();
     $projectRoot = $local->initialize($directory);
     // Fetch environments to start caching, and to create Drush aliases,
     // etc.
     $this->setProjectRoot($projectRoot);
     $this->getEnvironments($this->getCurrentProject(), true);
     $output->writeln("Project initialized in directory: <info>{$projectRoot}</info>");
     if ($inside) {
         $output->writeln("<comment>Type 'cd .' to refresh your shell</comment>");
     }
     return 0;
 }
 public function testGetProjectRoot()
 {
     $tempDir = $this->root->getName();
     $testDir = tempnam($tempDir, '');
     unlink($testDir);
     mkdir("{$testDir}/1/2/3/4/5", 0755, true);
     $expectedRoot = "{$testDir}/1";
     touch("{$expectedRoot}/.platform-project");
     chdir($testDir);
     $this->assertFalse(LocalProject::getProjectRoot());
     chdir($expectedRoot);
     $this->assertEquals($expectedRoot, LocalProject::getProjectRoot());
     chdir("{$testDir}/1/2/3/4/5");
     $this->assertEquals($expectedRoot, LocalProject::getProjectRoot());
 }
 /**
  * {@inheritdoc}
  *
  * @see PlatformCommand::getCurrentEnvironment()
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     /** @var ShellHelper $shell */
     $shell = $this->getHelper('shell');
     $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
     $shell->setOutput($output);
     if (!is_dir(LocalProject::getProjectRoot() . '/docker/fg')) {
         $shell->execute(['git', 'clone', 'https://github.com/brendangregg/FlameGraph.git', LocalProject::getProjectRoot() . '/docker/fg']);
     }
     if (!is_dir(LocalProject::getProjectRoot() . '/docker/xhpfg')) {
         $shell->execute(['git', 'clone', 'https://github.com/msonnabaum/xhprof-flamegraphs.git', LocalProject::getProjectRoot() . '/docker/xhpfg']);
     }
     $this->stdOut->writeln("<comment>Patching Drupal for xhprof</comment>");
     $process = new Process('patch -p1 < ' . CLI_ROOT . '/resources/drupal-enable-profiling.patch', Platform::webDir());
     $process->mustRun(null);
 }
 /**
  *
  */
 public function __construct()
 {
     $this->resourcesDir = CLI_ROOT . '/resources';
     $this->projectPath = LocalProject::getProjectRoot();
     $this->fs = new Filesystem();
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $projectId = $input->getArgument('id');
     $environmentOption = $input->getOption('environment');
     $hostOption = $input->getOption('host');
     if (empty($projectId)) {
         if ($input->isInteractive() && ($projects = $this->getProjects(true))) {
             $projectId = $this->offerProjectChoice($projects, $input);
         } else {
             $this->stdErr->writeln("<error>You must specify a project.</error>");
             return 1;
         }
     } else {
         $result = $this->parseProjectId($projectId);
         $projectId = $result['projectId'];
         $hostOption = $hostOption ?: $result['host'];
         $environmentOption = $environmentOption ?: $result['environmentId'];
     }
     $project = $this->getProject($projectId, $hostOption, true);
     if (!$project) {
         $this->stdErr->writeln("<error>Project not found: {$projectId}</error>");
         return 1;
     }
     $environments = $this->getEnvironments($project);
     if ($environmentOption) {
         if (!isset($environments[$environmentOption])) {
             // Reload the environments list.
             $environments = $this->getEnvironments($project, true);
             if (!isset($environments[$environmentOption])) {
                 $this->stdErr->writeln("Environment not found: <error>{$environmentOption}</error>");
             }
             return 1;
         }
         $environment = $environmentOption;
     } elseif (count($environments) === 1) {
         $environment = key($environments);
     } else {
         $environment = 'master';
     }
     /** @var \Platformsh\Cli\Helper\PlatformQuestionHelper $questionHelper */
     $questionHelper = $this->getHelper('question');
     $directory = $input->getArgument('directory');
     if (empty($directory)) {
         $slugify = new Slugify();
         $directory = $project->title ? $slugify->slugify($project->title) : $project->id;
         $directory = $questionHelper->askInput('Directory', $input, $this->stdErr, $directory);
     }
     if ($projectRoot = $this->getProjectRoot()) {
         if (strpos(realpath(dirname($directory)), $projectRoot) === 0) {
             $this->stdErr->writeln("<error>A project cannot be cloned inside another project.</error>");
             return 1;
         }
     }
     /** @var \Platformsh\Cli\Helper\FilesystemHelper $fsHelper */
     $fsHelper = $this->getHelper('fs');
     // Create the directory structure.
     $existed = false;
     if (file_exists($directory)) {
         $existed = true;
         $this->stdErr->writeln("The directory <error>{$directory}</error> already exists");
         if (file_exists($directory . '/' . LocalProject::PROJECT_CONFIG) && $questionHelper->confirm("Overwrite?", $input, $this->stdErr, false)) {
             $fsHelper->remove($directory);
         } else {
             return 1;
         }
     }
     mkdir($directory);
     $projectRoot = realpath($directory);
     if (!$projectRoot) {
         throw new \Exception("Failed to create project directory: {$directory}");
     }
     if ($existed) {
         $this->stdErr->writeln("Re-created project directory: {$directory}");
     } else {
         $this->stdErr->writeln("Created new project directory: {$directory}");
     }
     $cleanUp = function () use($projectRoot, $fsHelper) {
         $fsHelper->remove($projectRoot);
     };
     $local = new LocalProject();
     $hostname = parse_url($project->getUri(), PHP_URL_HOST) ?: null;
     $local->createProjectFiles($projectRoot, $project->id, $hostname);
     // Prepare to talk to the Platform.sh repository.
     $gitUrl = $project->getGitUrl();
     $repositoryDir = $projectRoot . '/' . LocalProject::REPOSITORY_DIR;
     $gitHelper = new GitHelper(new ShellHelper($this->stdErr));
     $gitHelper->ensureInstalled();
     // First check if the repo actually exists.
     $repoHead = $gitHelper->execute(['ls-remote', $gitUrl, 'HEAD'], false);
     if ($repoHead === false) {
         // The ls-remote command failed.
         $cleanUp();
         $this->stdErr->writeln('<error>Failed to connect to the Platform.sh Git server</error>');
         // Suggest SSH key commands.
         $sshKeys = [];
         try {
             $sshKeys = $this->getClient(false)->getSshKeys();
         } catch (\Exception $e) {
             // Ignore exceptions.
         }
         if (!empty($sshKeys)) {
             $this->stdErr->writeln('');
             $this->stdErr->writeln('Please check your SSH credentials');
             $this->stdErr->writeln('You can list your keys with: <comment>platform ssh-keys</comment>');
         } else {
             $this->stdErr->writeln('You probably need to add an SSH key, with: <comment>platform ssh-key:add</comment>');
         }
         return 1;
     } elseif (is_bool($repoHead)) {
         // The repository doesn't have a HEAD, which means it is empty.
         // We need to create the folder, run git init, and attach the remote.
         mkdir($repositoryDir);
         // Initialize the repo and attach our remotes.
         $this->stdErr->writeln("Initializing empty project repository");
         $gitHelper->execute(['init'], $repositoryDir, true);
         $this->stdErr->writeln("Adding Platform.sh Git remote");
         $local->ensureGitRemote($repositoryDir, $gitUrl);
         $this->stdErr->writeln("Your repository has been initialized and connected to <info>Platform.sh</info>!");
         $this->stdErr->writeln("Commit and push to the <info>{$environment}</info> branch and Platform.sh will build your project automatically");
         return 0;
     }
     // We have a repo! Yay. Clone it.
     $cloneArgs = ['--branch', $environment, '--origin', 'platform'];
     $cloned = $gitHelper->cloneRepo($gitUrl, $repositoryDir, $cloneArgs);
     if (!$cloned) {
         // The clone wasn't successful. Clean up the folders we created
         // and then bow out with a message.
         $cleanUp();
         $this->stdErr->writeln('<error>Failed to clone Git repository</error>');
         $this->stdErr->writeln('Please check your SSH credentials or contact Platform.sh support');
         return 1;
     }
     $gitHelper->updateSubmodules(true, $repositoryDir);
     $local->ensureGitRemote($repositoryDir, $gitUrl);
     $this->setProjectRoot($projectRoot);
     $this->stdErr->writeln("\nThe project <info>{$project->title}</info> was successfully downloaded to: <info>{$directory}</info>");
     // Return early if there is no code in the repository.
     if (!glob($repositoryDir . '/*')) {
         return 0;
     }
     // Ensure that Drush aliases are created.
     if (Drupal::isDrupal($projectRoot . '/' . LocalProject::REPOSITORY_DIR)) {
         $this->stdErr->writeln('');
         $this->runOtherCommand('local:drush-aliases', ['--group' => basename($directory)]);
     }
     // Launch the first build.
     $success = true;
     if ($input->getOption('build')) {
         // Launch the first build.
         $this->stdErr->writeln('');
         $this->stdErr->writeln('Building the project locally for the first time. Run <info>platform build</info> to repeat this.');
         $options = ['environmentId' => $environment, 'noClean' => true];
         $builder = new LocalBuild($options, $output);
         $success = $builder->buildProject($projectRoot);
     } else {
         $this->stdErr->writeln("\nYou can build the project with: " . "\n    cd {$directory}" . "\n    platform build");
     }
     return $success ? 0 : 1;
 }
Esempio n. 13
0
 /**
  * @return string|false
  */
 public function getProjectRoot()
 {
     if (empty(self::$projectRoot)) {
         self::$projectRoot = LocalProject::getProjectRoot();
     }
     return self::$projectRoot;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $project = $this->getCurrentProject();
     if (!$project) {
         throw new RootNotFoundException();
     }
     $specifiedBranch = $input->getArgument('id');
     if (empty($specifiedBranch) && $input->isInteractive()) {
         $environments = $this->getEnvironments($project);
         $currentEnvironment = $this->getCurrentEnvironment($project);
         if ($currentEnvironment) {
             $this->stdErr->writeln("The current environment is <info>{$currentEnvironment['title']}</info>.");
         }
         $environmentList = array();
         foreach ($environments as $id => $environment) {
             if ($currentEnvironment && $id == $currentEnvironment['id']) {
                 continue;
             }
             $environmentList[$id] = $environment['title'];
         }
         $config = $this->getProjectConfig($this->getProjectRoot());
         if (!empty($config['mapping'])) {
             foreach ($config['mapping'] as $branch => $id) {
                 unset($environmentList[$id]);
                 if ($currentEnvironment && $id == $currentEnvironment['id']) {
                     continue;
                 }
                 if (!isset($environments[$id])) {
                     continue;
                 }
                 $environmentList[$branch] = sprintf('%s (%s)', $environments[$id]->title, $branch);
             }
         }
         if (!count($environmentList)) {
             $this->stdErr->writeln("Use <info>platform branch</info> to create an environment.");
             return 1;
         }
         $chooseEnvironmentText = "Enter a number to check out another environment:";
         $helper = $this->getHelper('question');
         $specifiedBranch = $helper->choose($environmentList, $chooseEnvironmentText, $input, $output);
     } elseif (empty($specifiedBranch)) {
         $this->stdErr->writeln("<error>No branch specified.</error>");
         return 1;
     }
     $projectRoot = $this->getProjectRoot();
     $repositoryDir = $projectRoot . '/' . LocalProject::REPOSITORY_DIR;
     $gitHelper = new GitHelper(new ShellHelper($this->stdErr));
     $gitHelper->setDefaultRepositoryDir($repositoryDir);
     $branch = $this->branchExists($specifiedBranch, $project, $gitHelper);
     if (!$branch) {
         $this->stdErr->writeln("<error>Branch not found: {$specifiedBranch}</error>");
         return 1;
     }
     // If the branch exists locally, check it out directly.
     if ($gitHelper->branchExists($branch)) {
         $this->stdErr->writeln("Checking out <info>{$branch}</info>");
         return $gitHelper->checkOut($branch) ? 0 : 1;
     }
     // Make sure that remotes are set up correctly.
     $localProject = new LocalProject();
     $localProject->ensureGitRemote($repositoryDir, $project->getGitUrl());
     // Determine the correct upstream for the new branch. If there is an
     // 'origin' remote, then it has priority.
     $upstreamRemote = 'platform';
     if ($gitHelper->getConfig('remote.origin.url') && $gitHelper->remoteBranchExists('origin', $branch)) {
         $upstreamRemote = 'origin';
     }
     $this->stdErr->writeln("Creating branch {$branch} based on upstream {$upstreamRemote}/{$branch}");
     // Fetch the branch from the upstream remote.
     $gitHelper->execute(array('fetch', $upstreamRemote, $branch));
     // Create the new branch, and set the correct upstream.
     $success = $gitHelper->checkoutNew($branch, $upstreamRemote . '/' . $branch);
     return $success ? 0 : 1;
 }
 public static function webDir()
 {
     return LocalProject::getProjectRoot() . '/' . LocalProject::WEB_ROOT;
 }
Esempio n. 16
0
 /**
  * Create Drush aliases for the provided project and environments.
  *
  * @param Project       $project      The project
  * @param string        $projectRoot  The project root
  * @param Environment[] $environments The environments
  * @param string        $original     The original group name
  * @param bool          $merge        Whether to merge existing alias settings
  *
  * @throws \Exception
  *
  * @return bool Whether any aliases have been created.
  */
 public function createAliases(Project $project, $projectRoot, $environments, $original = null, $merge = true)
 {
     $config = LocalProject::getProjectConfig($projectRoot);
     $group = !empty($config['alias-group']) ? $config['alias-group'] : $project['id'];
     // Ensure the existence of the .drush directory.
     $drushDir = $this->homeDir . '/.drush';
     if (!is_dir($drushDir)) {
         mkdir($drushDir);
     }
     $filename = $drushDir . '/' . $group . '.aliases.drushrc.php';
     if (!is_writable($drushDir) || file_exists($filename) && !is_writable($filename)) {
         throw new \Exception("Drush alias file not writable: {$filename}");
     }
     // Include the previous alias file(s) so that the user's own
     // modifications can be merged. This may create a PHP parse error for
     // invalid syntax, but in that case the user could not run Drush anyway.
     $aliases = [];
     $originalFiles = [$filename];
     if ($original) {
         array_unshift($originalFiles, $drushDir . '/' . $original . '.aliases.drushrc.php');
     }
     if ($merge) {
         foreach ($originalFiles as $originalFile) {
             if (file_exists($originalFile)) {
                 include $originalFile;
             }
         }
     }
     // Gather applications.
     $apps = LocalApplication::getApplications($projectRoot . '/' . LocalProject::REPOSITORY_DIR);
     $drupalApps = $apps;
     $multiApp = false;
     if (count($apps) > 1) {
         $multiApp = true;
         // Remove non-Drupal applications.
         foreach ($drupalApps as $key => $app) {
             if (!Drupal::isDrupal($app->getRoot())) {
                 unset($drupalApps[$key]);
             }
         }
     }
     // Generate aliases for the remote environments and applications.
     $autoGenerated = '';
     foreach ($environments as $environment) {
         foreach ($drupalApps as $app) {
             $newAlias = $this->generateRemoteAlias($environment, $app, $multiApp);
             if (!$newAlias) {
                 continue;
             }
             $aliasName = $environment->id;
             if (count($drupalApps) > 1) {
                 $aliasName .= '--' . $app->getId();
             }
             // If the alias already exists, recursively replace existing
             // settings with new ones.
             if (isset($aliases[$aliasName])) {
                 $newAlias = array_replace_recursive($aliases[$aliasName], $newAlias);
                 unset($aliases[$aliasName]);
             }
             $autoGenerated .= sprintf("\n// Automatically generated alias for the environment \"%s\", application \"%s\".\n", $environment->title, $app->getId());
             $autoGenerated .= $this->exportAlias($aliasName, $newAlias);
         }
     }
     // Generate an alias for the local environment, for each app.
     $localAlias = '';
     foreach ($drupalApps as $app) {
         $appId = $app->getId();
         $localAliasName = '_local';
         $webRoot = $projectRoot . '/' . LocalProject::WEB_ROOT;
         if (count($drupalApps) > 1) {
             $localAliasName .= '--' . $appId;
         }
         if ($multiApp) {
             $webRoot .= '/' . $appId;
         }
         $local = ['root' => $webRoot, self::AUTO_REMOVE_KEY => true];
         if (isset($aliases[$localAliasName])) {
             $local = array_replace_recursive($aliases[$localAliasName], $local);
             unset($aliases[$localAliasName]);
         }
         $localAlias .= sprintf("\n// Automatically generated alias for the local environment, application \"%s\".\n", $appId) . $this->exportAlias($localAliasName, $local);
     }
     // Add any user-defined (pre-existing) aliases.
     $userDefined = '';
     foreach ($aliases as $name => $alias) {
         if (!empty($alias[self::AUTO_REMOVE_KEY])) {
             // This is probably for a deleted Platform.sh environment.
             continue;
         }
         $userDefined .= $this->exportAlias($name, $alias) . "\n";
     }
     if ($userDefined) {
         $userDefined = "\n// User-defined aliases.\n" . $userDefined;
     }
     $header = "<?php\n" . "/**\n * @file" . "\n * Drush aliases for the Platform.sh project \"{$project->title}\"." . "\n *" . "\n * This file is auto-generated by the Platform.sh CLI." . "\n *" . "\n * WARNING" . "\n * This file may be regenerated at any time." . "\n * - User-defined aliases will be preserved." . "\n * - Aliases for active environments (including any custom additions) will be preserved." . "\n * - Aliases for deleted or inactive environments will be deleted." . "\n * - All other information will be deleted." . "\n */\n\n";
     $export = $header . $userDefined . $localAlias . $autoGenerated;
     $this->writeAliasFile($filename, $export);
     return true;
 }
 /**
  * @return string|false
  */
 protected function getProjectRoot()
 {
     return $this->projectRoot ?: LocalProject::getProjectRoot();
 }
Esempio n. 18
0
 /**
  * Create Drush aliases for the provided project and environments.
  *
  * @param Project       $project      The project
  * @param string        $projectRoot  The project root
  * @param Environment[] $environments The environments
  * @param bool          $merge        Whether to merge existing alias settings.
  *
  * @throws \Exception
  *
  * @return bool Whether any aliases have been created.
  */
 public function createAliases(Project $project, $projectRoot, $environments, $merge = true)
 {
     $config = LocalProject::getProjectConfig($projectRoot);
     $group = !empty($config['alias-group']) ? $config['alias-group'] : $project['id'];
     // Ensure the existence of the .drush directory.
     $drushDir = $this->homeDir . '/.drush';
     if (!is_dir($drushDir)) {
         mkdir($drushDir);
     }
     $filename = $drushDir . '/' . $group . '.aliases.drushrc.php';
     if (!is_writable($drushDir) || file_exists($filename) && !is_writable($filename)) {
         throw new \Exception("Drush alias file not writable: {$filename}");
     }
     // Include the alias file so that the user's own modifications can be
     // merged.
     $aliases = array();
     if (file_exists($filename) && $merge) {
         // This may create a PHP parse error for invalid syntax, but in
         // that case the user could not run Drush anyway.
         include $filename;
     }
     // Generate aliases for the remote environments.
     $numValidEnvironments = 0;
     $autoGenerated = '';
     foreach ($environments as $environment) {
         $newAlias = $this->generateRemoteAlias($environment);
         if (!$newAlias) {
             continue;
         }
         // If the alias already exists, recursively replace existing
         // settings with new ones.
         if (isset($aliases[$environment['id']])) {
             $newAlias = array_replace_recursive($aliases[$environment['id']], $newAlias);
             unset($aliases[$environment['id']]);
         }
         $autoGenerated .= "\n// Automatically generated alias for the environment \"" . $environment['title'] . "\".\n";
         $autoGenerated .= $this->exportAlias($environment['id'], $newAlias);
         $numValidEnvironments++;
     }
     // Generate an alias for the local environment.
     $localAliasName = '_local';
     $local = array('root' => $projectRoot . '/' . LocalProject::WEB_ROOT, self::AUTO_REMOVE_KEY => true);
     if (isset($aliases[$localAliasName])) {
         $local = array_replace_recursive($aliases[$localAliasName], $local);
         unset($aliases[$localAliasName]);
     }
     $localAlias = "\n// Automatically generated alias for the local environment.\n" . $this->exportAlias($localAliasName, $local);
     // Add any user-defined (pre-existing) aliases.
     $userDefined = '';
     foreach ($aliases as $name => $alias) {
         if (!empty($alias[self::AUTO_REMOVE_KEY])) {
             // This is probably for a deleted Platform.sh environment.
             continue;
         }
         $userDefined .= $this->exportAlias($name, $alias) . "\n";
     }
     if ($userDefined) {
         $userDefined = "\n// User-defined aliases.\n" . $userDefined;
     }
     $header = "<?php\n" . "/**\n * @file" . "\n * Drush aliases for the Platform.sh project \"{$project['title']}\"." . "\n *" . "\n * This file is auto-generated by the Platform.sh CLI." . "\n *" . "\n * WARNING" . "\n * This file may be regenerated at any time." . "\n * - User-defined aliases will be preserved." . "\n * - Aliases for active environments (including any custom additions) will be preserved." . "\n * - Aliases for deleted or inactive environments will be deleted." . "\n * - All other information will be deleted." . "\n */\n\n";
     $export = $header . $userDefined . $localAlias . $autoGenerated;
     $this->writeAliasFile($filename, $export);
     return true;
 }
 /**
  * Returns current project's Platform.sh config.
  *
  * @throws \Exception
  */
 protected function getProjectConfig()
 {
     $this->platformConfig = LocalProject::getProjectConfig();
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $projectId = $input->getArgument('id');
     if (empty($projectId)) {
         if ($input->isInteractive() && ($projects = $this->getProjects(true))) {
             $projectId = $this->offerProjectChoice($projects, $input);
         } else {
             $this->stdErr->writeln("<error>You must specify a project.</error>");
             return 1;
         }
     }
     $project = $this->getProject($projectId, $input->getOption('host'));
     if (!$project) {
         $this->stdErr->writeln("<error>Project not found: {$projectId}</error>");
         return 1;
     }
     /** @var \Platformsh\Cli\Helper\PlatformQuestionHelper $questionHelper */
     $questionHelper = $this->getHelper('question');
     $directoryName = $input->getArgument('directory-name');
     if (empty($directoryName)) {
         $slugify = new Slugify();
         $directoryName = $project->title ? $slugify->slugify($project->title) : $project->id;
         $directoryName = $questionHelper->askInput('Directory name', $input, $this->stdErr, $directoryName);
     }
     if ($projectRoot = $this->getProjectRoot()) {
         if (strpos(realpath(dirname($directoryName)), $projectRoot) === 0) {
             $this->stdErr->writeln("<error>A project cannot be cloned inside another project.</error>");
             return 1;
         }
     }
     /** @var \Platformsh\Cli\Helper\FilesystemHelper $fsHelper */
     $fsHelper = $this->getHelper('fs');
     // Create the directory structure.
     $existed = false;
     if (file_exists($directoryName)) {
         $existed = true;
         $this->stdErr->writeln("The directory <error>{$directoryName}</error> already exists");
         if ($questionHelper->confirm("Overwrite?", $input, $this->stdErr, false)) {
             $fsHelper->remove($directoryName);
         } else {
             return 1;
         }
     }
     mkdir($directoryName);
     $projectRoot = realpath($directoryName);
     if (!$projectRoot) {
         throw new \Exception("Failed to create project directory: {$directoryName}");
     }
     if ($existed) {
         $this->stdErr->writeln("Re-created project directory: <info>{$directoryName}</info>");
     } else {
         $this->stdErr->writeln("Created new project directory: <info>{$directoryName}</info>");
     }
     $local = new LocalProject();
     $hostname = parse_url($project->getUri(), PHP_URL_HOST) ?: null;
     $local->createProjectFiles($projectRoot, $project->id, $hostname);
     $environments = $this->getEnvironments($project, true);
     $environmentOption = $input->getOption('environment');
     if ($environmentOption) {
         if (!isset($environments[$environmentOption])) {
             $this->stdErr->writeln("Environment not found: <error>{$environmentOption}</error>");
             return 1;
         }
         $environment = $environmentOption;
     } elseif (count($environments) === 1) {
         $environment = key($environments);
     } elseif ($environments && $input->isInteractive()) {
         $environment = $this->offerEnvironmentChoice($environments, $input);
     } else {
         $environment = 'master';
     }
     // Prepare to talk to the Platform.sh repository.
     $gitUrl = $project->getGitUrl();
     $repositoryDir = $directoryName . '/' . LocalProject::REPOSITORY_DIR;
     $gitHelper = new GitHelper(new ShellHelper($this->stdErr));
     $gitHelper->ensureInstalled();
     // First check if the repo actually exists.
     $repoHead = $gitHelper->execute(array('ls-remote', $gitUrl, 'HEAD'), false);
     if ($repoHead === false) {
         // The ls-remote command failed.
         $fsHelper->rmdir($projectRoot);
         $this->stdErr->writeln('<error>Failed to connect to the Platform.sh Git server</error>');
         $this->stdErr->writeln('Please check your SSH credentials or contact Platform.sh support');
         return 1;
     } elseif (is_bool($repoHead)) {
         // The repository doesn't have a HEAD, which means it is empty.
         // We need to create the folder, run git init, and attach the remote.
         mkdir($repositoryDir);
         // Initialize the repo and attach our remotes.
         $this->stdErr->writeln("Initializing empty project repository");
         $gitHelper->execute(array('init'), $repositoryDir, true);
         $this->stdErr->writeln("Adding Platform.sh Git remote");
         $local->ensureGitRemote($repositoryDir, $gitUrl);
         $this->stdErr->writeln("Your repository has been initialized and connected to <info>Platform.sh</info>!");
         $this->stdErr->writeln("Commit and push to the <info>{$environment}</info> branch and Platform.sh will build your project automatically");
         return 0;
     }
     // We have a repo! Yay. Clone it.
     $cloneArgs = array('--branch', $environment, '--origin', 'platform');
     $cloned = $gitHelper->cloneRepo($gitUrl, $repositoryDir, $cloneArgs);
     if (!$cloned) {
         // The clone wasn't successful. Clean up the folders we created
         // and then bow out with a message.
         $fsHelper->rmdir($projectRoot);
         $this->stdErr->writeln('<error>Failed to clone Git repository</error>');
         $this->stdErr->writeln('Please check your SSH credentials or contact Platform.sh support');
         return 1;
     }
     $local->ensureGitRemote($repositoryDir, $gitUrl);
     $this->setProjectRoot($projectRoot);
     $this->stdErr->writeln('');
     $this->stdErr->writeln("The project <info>{$project->title}</info> was successfully downloaded to: <info>{$directoryName}</info>");
     // Ensure that Drush aliases are created.
     if (Drupal::isDrupal($projectRoot . '/' . LocalProject::REPOSITORY_DIR)) {
         $this->stdErr->writeln('');
         $this->runOtherCommand('local:drush-aliases', array('--group' => $directoryName), $input);
     }
     // Allow the build to be skipped.
     if ($input->getOption('no-build')) {
         return 0;
     }
     // Always skip the build if the cloned repository is empty ('.', '..',
     // '.git' being the only found items)
     if (count(scandir($repositoryDir)) <= 3) {
         return 0;
     }
     // Launch the first build.
     $this->stdErr->writeln('');
     $this->stdErr->writeln('Building the project locally for the first time. Run <info>platform build</info> to repeat this.');
     $builder = new LocalBuild(array('environmentId' => $environment), $output);
     $success = $builder->buildProject($projectRoot);
     return $success ? 0 : 1;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $projectId = $input->getArgument('id');
     if (empty($projectId)) {
         if ($input->isInteractive() && ($projects = $this->getProjects(true))) {
             $projectId = $this->offerProjectChoice($projects, $input, $output);
         } else {
             $output->writeln("<error>You must specify a project.</error>");
             return 1;
         }
     }
     $project = $this->getProject($projectId);
     if (!$project) {
         $output->writeln("<error>Project not found: {$projectId}</error>");
         return 1;
     }
     $directoryName = $input->getArgument('directory-name');
     if (empty($directoryName)) {
         $directoryName = $projectId;
     }
     if (file_exists($directoryName)) {
         $output->writeln("<error>The project directory '{$directoryName}' already exists.</error>");
         return 1;
     }
     if ($projectRoot = $this->getProjectRoot()) {
         if (strpos(realpath(dirname($directoryName)), $projectRoot) === 0) {
             $output->writeln("<error>A project cannot be cloned inside another project.</error>");
             return 1;
         }
     }
     // Create the directory structure.
     mkdir($directoryName);
     $projectRoot = realpath($directoryName);
     if (!$projectRoot) {
         throw new \Exception("Failed to create project directory: {$directoryName}");
     }
     $output->writeln("Created project directory: {$directoryName}");
     $local = new LocalProject();
     $local->createProjectFiles($projectRoot, $projectId);
     $environments = $this->getEnvironments($project, true);
     $environmentOption = $input->getOption('environment');
     if ($environmentOption) {
         if (!isset($environments[$environmentOption])) {
             $output->writeln("<error>Environment not found: {$environmentOption}</error>");
             return 1;
         }
         $environment = $environmentOption;
     } elseif (count($environments) === 1) {
         $environment = key($environments);
     } elseif ($environments && $input->isInteractive()) {
         $environment = $this->offerEnvironmentChoice($environments, $input, $output);
     } else {
         $environment = 'master';
     }
     /** @var \Platformsh\Cli\Helper\FilesystemHelper $fsHelper */
     $fsHelper = $this->getHelper('fs');
     // Prepare to talk to the Platform.sh repository.
     if (isset($project['repository'])) {
         $gitUrl = $project['repository']['url'];
     } else {
         $projectUriParts = explode('/', str_replace(array('http://', 'https://'), '', $project['uri']));
         $cluster = $projectUriParts[0];
         $gitUrl = "{$projectId}@git.{$cluster}:{$projectId}.git";
     }
     $repositoryDir = $directoryName . '/' . LocalProject::REPOSITORY_DIR;
     $gitHelper = new GitHelper(new ShellHelper($output));
     // First check if the repo actually exists.
     $repoHead = $gitHelper->execute(array('ls-remote', $gitUrl, 'HEAD'), false);
     if ($repoHead === false) {
         // The ls-remote command failed.
         $fsHelper->rmdir($projectRoot);
         $output->writeln('<error>Failed to connect to the Platform.sh Git server</error>');
         $output->writeln('Please check your SSH credentials or contact Platform.sh support');
         return 1;
     } elseif (is_bool($repoHead)) {
         // The repository doesn't have a HEAD, which means it is empty.
         // We need to create the folder, run git init, and attach the remote.
         mkdir($repositoryDir);
         // Initialize the repo and attach our remotes.
         $output->writeln("<info>Initializing empty project repository...</info>");
         $gitHelper->execute(array('init'), $repositoryDir, true);
         $output->writeln("<info>Adding Platform.sh remote endpoint to Git...</info>");
         $gitHelper->execute(array('remote', 'add', '-m', 'master', 'origin', $gitUrl), $repositoryDir, true);
         $output->writeln("<info>Your repository has been initialized and connected to Platform.sh!</info>");
         $output->writeln("<info>Commit and push to the {$environment} branch and Platform.sh will build your project automatically.</info>");
         return 0;
     }
     // We have a repo! Yay. Clone it.
     if (!$gitHelper->cloneRepo($gitUrl, $repositoryDir, $environment)) {
         // The clone wasn't successful. Clean up the folders we created
         // and then bow out with a message.
         $fsHelper->rmdir($projectRoot);
         $output->writeln('<error>Failed to clone Git repository</error>');
         $output->writeln('Please check your SSH credentials or contact Platform.sh support');
         return 1;
     }
     $output->writeln("The project <info>{$project['name']}</info> was successfully downloaded to: <info>{$directoryName}</info>");
     // Ensure that Drush aliases are created.
     $this->setProjectRoot($projectRoot);
     $this->updateDrushAliases($project, $environments);
     // Allow the build to be skipped.
     if ($input->getOption('no-build')) {
         return 0;
     }
     // Always skip the build if the cloned repository is empty ('.', '..',
     // '.git' being the only found items)
     if (count(scandir($repositoryDir)) <= 3) {
         return 0;
     }
     // Launch the first build.
     try {
         $builder = new LocalBuild(array('environmentId' => $environment), $output);
         $builder->buildProject($projectRoot);
     } catch (\Exception $e) {
         $output->writeln("<comment>The build failed with an error</comment>");
         $formattedMessage = $this->getHelper('formatter')->formatBlock($e->getMessage(), 'comment');
         $output->writeln($formattedMessage);
     }
     return 0;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $project = $this->getCurrentProject();
     if (!$project) {
         throw new \Exception('This can only be run from inside a project directory');
     }
     $projectRoot = $this->getProjectRoot();
     $projectConfig = LocalProject::getProjectConfig($projectRoot);
     $current_group = isset($projectConfig['alias-group']) ? $projectConfig['alias-group'] : $project['id'];
     if ($input->getOption('pipe') || !$this->isTerminal($output)) {
         $output->writeln($current_group);
         return 0;
     }
     $new_group = ltrim($input->getOption('group'), '@');
     $homeDir = $this->getHelper('fs')->getHomeDirectory();
     $drushHelper = new DrushHelper($output);
     $drushHelper->ensureInstalled();
     $drushHelper->setHomeDir($homeDir);
     if ($new_group && $new_group != $current_group) {
         $questionHelper = $this->getHelper('question');
         $existing = $drushHelper->getAliases($new_group);
         if ($existing) {
             if (!$questionHelper->confirm("The alias group <info>@{$new_group}</info> already exists. Overwrite?", $input, $output, false)) {
                 return 1;
             }
         }
         $project['alias-group'] = $new_group;
         LocalProject::writeCurrentProjectConfig('alias-group', $new_group, $projectRoot);
         $output->write("Creating Drush aliases in the group <info>@{$new_group}</info>...");
         $environments = $this->getEnvironments($project, true, false);
         $drushHelper->createAliases($project, $projectRoot, $environments);
         $output->writeln(" done");
         $drushDir = $homeDir . '/.drush';
         $oldFile = $drushDir . '/' . $current_group . '.aliases.drushrc.php';
         if (file_exists($oldFile)) {
             if ($questionHelper->confirm("Delete old alias group <info>@{$current_group}</info>?", $input, $output)) {
                 unlink($oldFile);
             }
         }
         // Clear the Drush cache now that the aliases have been updated.
         $drushHelper->clearCache();
         $current_group = $new_group;
     } elseif ($input->getOption('recreate')) {
         $output->write("Recreating Drush aliases...");
         $environments = $this->getEnvironments($project, true, false);
         $drushHelper->createAliases($project, $projectRoot, $environments);
         $drushHelper->clearCache();
         $output->writeln(' done');
     }
     // Don't run expensive drush calls if they are not needed.
     if ($input->getOption('quiet')) {
         return 0;
     }
     $aliases = $drushHelper->getAliases($current_group);
     if ($aliases) {
         $output->writeln("Aliases for <info>{$project['name']}</info> ({$project['id']}):");
         foreach (explode("\n", $aliases) as $alias) {
             $output->writeln('    @' . $alias);
         }
     }
     return 0;
 }