/**
  * @param string          $property
  * @param string          $value
  * @param Environment     $environment
  *
  * @return int
  */
 protected function setProperty($property, $value, Environment $environment)
 {
     if (!$this->validateValue($property, $value)) {
         return 1;
     }
     $type = $this->getType($property);
     if ($type === 'boolean' && $value === 'false') {
         $value = false;
     }
     settype($value, $type);
     $currentValue = $environment->getProperty($property, false);
     if ($currentValue === $value) {
         $this->stdErr->writeln("Property <info>{$property}</info> already set as: " . $this->formatter->format($environment->getProperty($property, false), $property));
         return 0;
     }
     $environment->update(array($property => $value));
     $this->stdErr->writeln("Property <info>{$property}</info> set to: " . $this->formatter->format($environment[$property], $property));
     $rebuildProperties = array('enable_smtp', 'restrict_robots');
     if (in_array($property, $rebuildProperties) && !$environment->getLastActivity()) {
         $this->rebuildWarning();
     }
     // Refresh the stored environments.
     $this->getEnvironments($this->getSelectedProject(), true);
     return 0;
 }
 /**
  * @param string      $property
  * @param string      $value
  * @param Environment $environment
  * @param bool        $noWait
  *
  * @return int
  */
 protected function setProperty($property, $value, Environment $environment, $noWait)
 {
     if (!$this->validateValue($property, $value)) {
         return 1;
     }
     $type = $this->getType($property);
     if ($type === 'boolean' && $value === 'false') {
         $value = false;
     }
     settype($value, $type);
     $currentValue = $environment->getProperty($property, false);
     if ($currentValue === $value) {
         $this->stdErr->writeln("Property <info>{$property}</info> already set as: " . $this->formatter->format($environment->getProperty($property, false), $property));
         return 0;
     }
     $result = $environment->update([$property => $value]);
     $this->stdErr->writeln("Property <info>{$property}</info> set to: " . $this->formatter->format($environment->{$property}, $property));
     $this->clearEnvironmentsCache();
     $rebuildProperties = ['enable_smtp', 'restrict_robots'];
     $success = true;
     if ($result->countActivities() && !$noWait) {
         $success = ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr);
     } elseif (!$result->countActivities() && in_array($property, $rebuildProperties)) {
         $this->rebuildWarning();
     }
     return $success ? 0 : 1;
 }
 /**
  * @param string          $property
  * @param string          $value
  * @param Environment     $environment
  *
  * @return int
  */
 protected function setProperty($property, $value, Environment $environment)
 {
     if (!$this->validateValue($property, $value)) {
         return 1;
     }
     $type = $this->getType($property);
     if ($type === 'boolean' && $value === 'false') {
         $value = false;
     }
     settype($value, $type);
     $currentValue = $environment->getProperty($property, false);
     if ($currentValue === $value) {
         $this->stdErr->writeln("Property <info>{$property}</info> already set as: " . $environment->getProperty($property, false));
         return 0;
     }
     $environment->update(array($property => $value));
     $this->stdErr->writeln("Property <info>{$property}</info> set to: " . $environment[$property]);
     if ($property === 'enable_smtp' && !$environment->getLastActivity()) {
         $this->rebuildWarning();
     }
     return 0;
 }
 /**
  * Check whether a branch exists, locally in Git or on the remote.
  *
  * @param string    $branch
  * @param Project   $project
  * @param GitHelper $gitHelper
  *
  * @return string|false
  */
 protected function branchExists($branch, Project $project, GitHelper $gitHelper)
 {
     // Check if the Git branch exists locally.
     $candidates = array_unique(array(Environment::sanitizeId($branch), $branch));
     foreach ($candidates as $candidate) {
         if ($gitHelper->branchExists($candidate)) {
             return $candidate;
         }
     }
     // Check if the environment exists by title or ID. This is usually faster
     // than running 'git ls-remote'.
     $environments = $this->getEnvironments($project);
     foreach ($environments as $environment) {
         if ($environment['title'] == $branch || $environment['id'] == $branch) {
             return $environment['id'];
         }
     }
     return false;
 }
 /**
  * Get the current environment if the user is in a project directory.
  *
  * @param Project $expectedProject The expected project.
  *
  * @return Environment|false The current environment.
  */
 public function getCurrentEnvironment(Project $expectedProject = null)
 {
     if (!($projectRoot = $this->getProjectRoot()) || !($project = $this->getCurrentProject()) || $expectedProject !== null && $expectedProject->id !== $project->id) {
         return false;
     }
     $gitHelper = $this->getHelper('git');
     $gitHelper->setDefaultRepositoryDir($this->getProjectRoot() . '/' . LocalProject::REPOSITORY_DIR);
     $currentBranch = $gitHelper->getCurrentBranch();
     // Check if there is a manual mapping set for the current branch.
     if ($currentBranch) {
         $config = $this->getProjectConfig($projectRoot);
         if (!empty($config['mapping'][$currentBranch])) {
             $environment = $this->getEnvironment($config['mapping'][$currentBranch], $project);
             if ($environment) {
                 $this->debug('Found mapped environment for branch ' . $currentBranch . ': ' . $environment->id);
                 return $environment;
             } else {
                 unset($config['mapping'][$currentBranch]);
                 $this->setProjectConfig('mapping', $config['mapping'], $projectRoot);
             }
         }
     }
     // Check whether the user has a Git upstream set to a Platform
     // environment ID.
     $upstream = $gitHelper->getUpstream();
     if ($upstream && strpos($upstream, '/') !== false) {
         list(, $potentialEnvironment) = explode('/', $upstream, 2);
         $environment = $this->getEnvironment($potentialEnvironment, $project);
         if ($environment) {
             $this->debug('Selected environment ' . $potentialEnvironment . ', based on Git upstream: ' . $upstream);
             return $environment;
         }
     }
     // There is no Git remote set, or it's set to a non-Platform URL.
     // Fall back to trying the current branch name.
     if ($currentBranch) {
         $currentBranchSanitized = Environment::sanitizeId($currentBranch);
         $environment = $this->getEnvironment($currentBranchSanitized, $project);
         if ($environment) {
             $this->debug('Selected environment ' . $currentBranchSanitized . ', based on branch name:' . $currentBranch);
             return $environment;
         }
     }
     return false;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->envArgName = 'parent';
     $this->validateInput($input, true);
     $selectedProject = $this->getSelectedProject();
     $branchName = $input->getArgument('name');
     if (empty($branchName)) {
         if ($input->isInteractive()) {
             // List environments.
             return $this->runOtherCommand('environments', array('--project' => $selectedProject->id));
         }
         $this->stdErr->writeln("<error>You must specify the name of the new branch.</error>");
         return 1;
     }
     $machineName = Environment::sanitizeId($branchName);
     $environmentId = $this->getSelectedEnvironment()['id'];
     if ($machineName == $environmentId) {
         $this->stdErr->writeln("<comment>Already on {$machineName}</comment>");
         return 1;
     }
     if ($environment = $this->getEnvironment($machineName, $selectedProject)) {
         $checkout = $this->getHelper('question')->confirm("The environment <comment>{$machineName}</comment> already exists. Check out?", $input, $this->stdErr);
         if ($checkout) {
             return $this->runOtherCommand('environment:checkout', array('id' => $environment->id));
         }
         return 1;
     }
     if (!$this->getSelectedEnvironment()->operationAvailable('branch')) {
         $this->stdErr->writeln("Operation not available: The environment <error>{$environmentId}</error> can't be branched.");
         return 1;
     }
     $force = $input->getOption('force');
     $projectRoot = $this->getProjectRoot();
     if (!$projectRoot && $force) {
         $this->stdErr->writeln("<comment>This command was run from outside your local project root, the new Platform.sh branch cannot be checked out in your local Git repository." . " Make sure to run 'platform checkout' or 'git checkout' in your repository directory to switch to the branch you are expecting.</comment>");
         $local_error = true;
     } elseif (!$projectRoot) {
         $this->stdErr->writeln("<error>You must run this command inside the project root, or specify --force.</error>");
         return 1;
     }
     $selectedEnvironment = $this->getSelectedEnvironment();
     $this->stdErr->writeln("Creating a new environment <info>{$branchName}</info>, branched from <info>{$selectedEnvironment['title']}</info>");
     $activity = $selectedEnvironment->branch($branchName, $machineName);
     // Clear the environments cache, as branching has started.
     $this->clearEnvironmentsCache($selectedProject);
     if ($projectRoot) {
         $gitHelper = new GitHelper(new ShellHelper($this->stdErr));
         $gitHelper->setDefaultRepositoryDir($projectRoot . '/' . LocalProject::REPOSITORY_DIR);
         // If the Git branch already exists locally, just check it out.
         $existsLocally = $gitHelper->branchExists($machineName);
         if ($existsLocally) {
             $this->stdErr->writeln("Checking out <info>{$machineName}</info> locally");
             if (!$gitHelper->checkOut($machineName)) {
                 $this->stdErr->writeln('<error>Failed to check out branch locally: ' . $machineName . '</error>');
                 $local_error = true;
                 if (!$force) {
                     return 1;
                 }
             }
         } else {
             // Create a new branch, using the current or specified environment as the parent if it exists locally.
             $parent = $this->getSelectedEnvironment()['id'];
             if (!$gitHelper->branchExists($parent)) {
                 $parent = null;
             }
             $this->stdErr->writeln("Creating local branch <info>{$machineName}</info>");
             if (!$gitHelper->checkOutNew($machineName, $parent)) {
                 $this->stdErr->writeln('<error>Failed to create branch locally: ' . $machineName . '</error>');
                 $local_error = true;
                 if (!$force) {
                     return 1;
                 }
             }
         }
     }
     $remoteSuccess = true;
     if (!$input->getOption('no-wait')) {
         $remoteSuccess = ActivityUtil::waitAndLog($activity, $this->stdErr, "The environment <info>{$branchName}</info> has been branched.", '<error>Branching failed</error>');
         // Clear the environments cache again.
         $this->clearEnvironmentsCache($selectedProject);
     }
     $build = $input->getOption('build');
     if (empty($local_error) && $build && $projectRoot) {
         // Build the new branch.
         try {
             $buildSettings = array('environmentId' => $machineName, 'verbosity' => $output->getVerbosity());
             $builder = new LocalBuild($buildSettings, $output);
             $builder->buildProject($projectRoot);
         } catch (\Exception $e) {
             $this->stdErr->writeln("<comment>The new branch could not be built: \n" . $e->getMessage() . "</comment>");
             return 1;
         }
     }
     $this->clearEnvironmentsCache();
     return $remoteSuccess ? 0 : 1;
 }
 /**
  * Return the user's environments.
  *
  * @param Project $project       The project.
  * @param bool    $refresh       Whether to refresh the list.
  * @param bool    $updateAliases Whether to update Drush aliases if the list changes.
  *
  * @return Environment[] The user's environments.
  */
 public function getEnvironments(Project $project = null, $refresh = false, $updateAliases = true)
 {
     $project = $project ?: $this->getSelectedProject();
     $projectId = $project->getProperty('id');
     $this->loadCache();
     $cached = !empty(self::$cache['environments'][$projectId]);
     $stale = isset(self::$cache['environmentsRefreshed'][$projectId]) && time() - self::$cache['environmentsRefreshed'][$projectId] > $this->environmentsTtl;
     if ($refresh || !$cached || $stale) {
         self::$cache['environments'][$projectId] = array();
         $environments = array();
         $toCache = array();
         foreach ($project->getEnvironments() as $environment) {
             $environments[$environment['id']] = $environment;
             $toCache[$environment['id']] = $environment->getData();
         }
         // Recreate the aliases if the list of environments has changed.
         if ($updateAliases && array_diff_key($environments, self::$cache['environments'])) {
             $this->updateDrushAliases($project, $environments);
         }
         self::$cache['environments'][$projectId] = $toCache;
         self::$cache['environmentsRefreshed'][$projectId] = time();
     } else {
         $environments = array();
         $connector = $this->getClient(false)->getConnector();
         $endpoint = $project->hasLink('self') ? $project->getLink('self', true) : $project['endpoint'];
         $client = $connector->getClient();
         foreach (self::$cache['environments'][$projectId] as $id => $data) {
             $environments[$id] = Environment::wrap($data, $endpoint, $client);
         }
     }
     return $environments;
 }
 /**
  * Return the user's environments.
  *
  * @param Project $project       The project.
  * @param bool    $refresh       Whether to refresh the list.
  * @param bool    $updateAliases Whether to update Drush aliases if the list changes.
  *
  * @return Environment[] The user's environments.
  */
 public function getEnvironments(Project $project = null, $refresh = false, $updateAliases = true)
 {
     $project = $project ?: $this->getSelectedProject();
     $projectId = $project->getProperty('id');
     $cacheKey = 'environments:' . $projectId;
     $cached = self::$cache->contains($cacheKey);
     if ($refresh || !$cached) {
         $environments = array();
         $toCache = array();
         foreach ($project->getEnvironments() as $environment) {
             $environments[$environment['id']] = $environment;
             $toCache[$environment['id']] = $environment->getData();
         }
         // Recreate the aliases if the list of environments has changed.
         if ($updateAliases && (!$cached || array_diff_key($environments, self::$cache->fetch($cacheKey)))) {
             $this->updateDrushAliases($project, $environments);
         }
         self::$cache->save($cacheKey, $toCache, $this->environmentsTtl);
     } else {
         $environments = array();
         $connector = $this->getClient(false)->getConnector();
         $endpoint = $project->hasLink('self') ? $project->getLink('self', true) : $project['endpoint'];
         $client = $connector->getClient();
         foreach ((array) self::$cache->fetch($cacheKey) as $id => $data) {
             $environments[$id] = Environment::wrap($data, $endpoint, $client);
         }
     }
     return $environments;
 }
 /**
  * Get the current environment if the user is in a project directory.
  *
  * @param Project $expectedProject The expected project.
  * @param bool|null $refresh Whether to refresh the environments or projects
  *                           cache.
  *
  * @return Environment|false The current environment.
  */
 public function getCurrentEnvironment(Project $expectedProject = null, $refresh = null)
 {
     if (!($projectRoot = $this->getProjectRoot()) || !($project = $this->getCurrentProject()) || $expectedProject !== null && $expectedProject->id !== $project->id) {
         return false;
     }
     $gitHelper = $this->getHelper('git');
     $gitHelper->setDefaultRepositoryDir($this->getProjectRoot());
     $config = $this->localProject->getProjectConfig($projectRoot);
     // Check if there is a manual mapping set for the current branch.
     if (!empty($config['mapping']) && ($currentBranch = $gitHelper->getCurrentBranch()) && !empty($config['mapping'][$currentBranch])) {
         $environment = $this->api()->getEnvironment($config['mapping'][$currentBranch], $project, $refresh);
         if ($environment) {
             $this->debug('Found mapped environment for branch ' . $currentBranch . ': ' . $environment->id);
             return $environment;
         } else {
             unset($config['mapping'][$currentBranch]);
             $this->localProject->writeCurrentProjectConfig($config, $projectRoot);
         }
     }
     // Check whether the user has a Git upstream set to a remote environment
     // ID.
     $upstream = $gitHelper->getUpstream();
     if ($upstream && strpos($upstream, '/') !== false) {
         list(, $potentialEnvironment) = explode('/', $upstream, 2);
         $environment = $this->api()->getEnvironment($potentialEnvironment, $project, $refresh);
         if ($environment) {
             $this->debug('Selected environment ' . $potentialEnvironment . ', based on Git upstream: ' . $upstream);
             return $environment;
         }
     }
     // There is no Git remote set. Fall back to trying the current branch
     // name.
     if (!empty($currentBranch) || ($currentBranch = $gitHelper->getCurrentBranch())) {
         $environment = $this->api()->getEnvironment($currentBranch, $project, $refresh);
         if (!$environment) {
             // Try a sanitized version of the branch name too.
             $currentBranchSanitized = Environment::sanitizeId($currentBranch);
             $environment = $this->api()->getEnvironment($currentBranchSanitized, $project, $refresh);
         }
         if ($environment) {
             $this->debug('Selected environment ' . $environment->id . ' based on branch name: ' . $currentBranch);
             return $environment;
         }
     }
     return false;
 }
 /**
  * @param Environment $environment
  *
  * @return array|false
  */
 protected function generateRemoteAlias($environment)
 {
     if (!$environment->hasLink('ssh')) {
         return false;
     }
     $sshUrl = parse_url($environment->getLink('ssh'));
     if (!$sshUrl) {
         return false;
     }
     return array('uri' => $environment->getLink('public-url'), 'remote-host' => $sshUrl['host'], 'remote-user' => $sshUrl['user'], 'root' => '/app/public', self::AUTO_REMOVE_KEY => true);
 }
Beispiel #11
0
 /**
  * @param Environment $environment
  * @param LocalApplication $app
  * @param bool $multiApp
  *
  * @return array|false
  */
 protected function generateRemoteAlias($environment, $app, $multiApp = false)
 {
     if (!$environment->hasLink('ssh') || !$environment->hasLink('public-url')) {
         return false;
     }
     $sshUrl = parse_url($environment->getLink('ssh'));
     if (!$sshUrl) {
         return false;
     }
     $sshUser = $sshUrl['user'];
     if ($multiApp) {
         $sshUser .= '--' . $app->getName();
     }
     $uri = $environment->getLink('public-url');
     if ($multiApp) {
         $guess = str_replace('http://', 'http://' . $app->getName() . '---', $uri);
         if (in_array($guess, $environment->getRouteUrls())) {
             $uri = $guess;
         }
     }
     $appConfig = $app->getConfig();
     $documentRoot = '/public';
     if (isset($appConfig['web']['document_root']) && $appConfig['web']['document_root'] !== '/') {
         $documentRoot = $appConfig['web']['document_root'];
     }
     return ['uri' => $uri, 'remote-host' => $sshUrl['host'], 'remote-user' => $sshUser, 'root' => '/app/' . ltrim($documentRoot, '/'), self::AUTO_REMOVE_KEY => true, 'command-specific' => ['site-install' => ['sites-subdir' => 'default']]];
 }
 /**
  * @param Environment $environment
  *
  * @return array|false
  */
 protected function generateRemoteAlias($environment)
 {
     if (!$environment->hasLink('ssh')) {
         return false;
     }
     $sshUrl = parse_url($environment->getLink('ssh'));
     if (!$sshUrl) {
         return false;
     }
     return array('uri' => $environment->getLink('public-url'), 'remote-host' => $sshUrl['host'], 'remote-user' => $sshUrl['user'], 'root' => '/app/public', self::AUTO_REMOVE_KEY => true, 'command-specific' => array('site-install' => array('sites-subdir' => 'default')));
 }
 /**
  * @param Environment $environment
  * @param LocalApplication $app
  * @param bool $multiApp
  *
  * @return array|false
  */
 protected function generateRemoteAlias($environment, $app, $multiApp = false)
 {
     if (!$environment->hasLink('ssh') || !$environment->hasLink('public-url')) {
         return false;
     }
     $sshUrl = parse_url($environment->getLink('ssh'));
     if (!$sshUrl) {
         return false;
     }
     $sshUser = $sshUrl['user'];
     if ($multiApp) {
         $sshUser .= '--' . $app->getName();
     }
     $uri = $environment->getLink('public-url');
     if ($multiApp) {
         $guess = str_replace('http://', 'http://' . $app->getName() . '---', $uri);
         if (in_array($guess, $environment->getRouteUrls())) {
             $uri = $guess;
         }
     }
     return ['uri' => $uri, 'remote-host' => $sshUrl['host'], 'remote-user' => $sshUser, 'root' => '/app/' . $app->getDocumentRoot(), $this->getAutoRemoveKey() => true, 'command-specific' => ['site-install' => ['sites-subdir' => 'default']]];
 }