/** * @{inheritdoc} * * Set up before every test. * * @throws \Exception */ public function setUp() { $this->tempDirSetUp(); $repository = $this->getRepositoryDir(); if (!is_dir($repository) && !mkdir($repository, 0755, true)) { throw new \Exception("Failed to create directories."); } $this->gitHelper = new GitHelper(); $this->gitHelper->init($repository, true); $this->gitHelper->setDefaultRepositoryDir($repository); chdir($repository); // Ensure we are on the master branch. $this->gitHelper->checkOut('master'); // Add required Git config before committing. shell_exec('git config user.email test@example.com'); shell_exec('git config user.name "Test"'); shell_exec('git config commit.gpgsign false'); // Make a dummy commit so that there is a HEAD. touch($repository . '/README.txt'); shell_exec('git add -A && git commit -qm "Initial commit"'); }
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'); } $specifiedBranch = $input->getArgument('id'); if (empty($specifiedBranch) && $input->isInteractive()) { $environments = $this->getEnvironments($project); $currentEnvironment = $this->getCurrentEnvironment($project); if ($currentEnvironment) { $output->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']; } if (!count($environmentList)) { $output->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)) { $output->writeln("<error>No branch specified.</error>"); return 1; } $projectRoot = $this->getProjectRoot(); $gitHelper = new GitHelper(new ShellHelper($output)); $gitHelper->setDefaultRepositoryDir($projectRoot . '/' . LocalProject::REPOSITORY_DIR); $branch = $this->branchExists($specifiedBranch, $project, $gitHelper); if (!$branch) { $output->writeln("<error>Branch not found: {$specifiedBranch}</error>"); return 1; } if (!$gitHelper->branchExists($branch)) { $gitHelper->execute(array('fetch', 'origin')); } // Check out the branch. $output->writeln("Checking out <info>{$branch}</info>"); return $gitHelper->checkOut($branch) ? 0 : 1; }
/** * Ensure there are appropriate Git remotes in the repository. * * @param string $dir * @param string $url */ public function ensureGitRemote($dir, $url) { if (!file_exists($dir . '/.git')) { throw new \InvalidArgumentException('The directory is not a Git repository'); } $gitHelper = new GitHelper(); $gitHelper->ensureInstalled(); $gitHelper->setDefaultRepositoryDir($dir); $currentUrl = $gitHelper->getConfig("remote." . $this->config->get('detection.git_remote_name') . ".url", $dir); if (!$currentUrl) { $gitHelper->execute(['remote', 'add', $this->config->get('detection.git_remote_name'), $url], $dir, true); } elseif ($currentUrl != $url) { $gitHelper->execute(['remote', 'set-url', $this->config->get('detection.git_remote_name'), $url], $dir, true); } // Add an origin remote too. if ($this->config->get('detection.git_remote_name') !== 'origin' && !$gitHelper->getConfig("remote.origin.url", $dir)) { $gitHelper->execute(['remote', 'add', 'origin', $url]); } }
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; }
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; }
protected function execute(InputInterface $input, OutputInterface $output) { $project = $this->getCurrentProject(); if (!$project) { throw new RootNotFoundException(); } $projectRoot = $this->getProjectRoot(); $repositoryDir = $projectRoot . '/' . LocalProject::REPOSITORY_DIR; $gitHelper = new GitHelper(new ShellHelper($output)); $gitHelper->setDefaultRepositoryDir($repositoryDir); $specifiedEnvironmentId = $input->getArgument('environment'); if ($specifiedEnvironmentId != '0' && !($specifiedEnvironment = $this->getEnvironment($specifiedEnvironmentId, $project))) { $this->stdErr->writeln("Environment not found: <error>{$specifiedEnvironmentId}</error>"); return 1; } $specifiedBranch = $input->getArgument('branch'); if ($specifiedBranch) { if (!$gitHelper->branchExists($specifiedBranch)) { $this->stdErr->writeln("Branch not found: <error>{$specifiedBranch}</error>"); return 1; } } else { $specifiedBranch = $gitHelper->getCurrentBranch(); } // Check whether the branch is mapped by default (its name or its Git // upstream is the same as the remote environment ID). $mappedByDefault = isset($specifiedEnvironment) && $specifiedEnvironment->status != 'inactive' && $specifiedEnvironmentId === $specifiedBranch; if ($specifiedEnvironmentId != '0' && !$mappedByDefault) { $upstream = $gitHelper->getUpstream($specifiedBranch); if (strpos($upstream, '/')) { list(, $upstream) = explode('/', $upstream, 2); } if ($upstream === $specifiedEnvironmentId) { $mappedByDefault = true; } if (!$mappedByDefault && $gitHelper->branchExists($specifiedEnvironmentId)) { $this->stdErr->writeln("A local branch already exists named <comment>{$specifiedEnvironmentId}</comment>"); } } // Perform the mapping or unmapping. $config = $this->getProjectConfig($projectRoot); $config += ['mapping' => []]; if ($mappedByDefault || $specifiedEnvironmentId == '0') { unset($config['mapping'][$specifiedBranch]); $this->setProjectConfig('mapping', $config['mapping'], $projectRoot); } else { if (isset($config['mapping']) && ($current = array_search($specifiedEnvironmentId, $config['mapping'])) !== false) { unset($config['mapping'][$current]); } $config['mapping'][$specifiedBranch] = $specifiedEnvironmentId; $this->setProjectConfig('mapping', $config['mapping'], $projectRoot); } // Check the success of the operation. if (isset($config['mapping'][$specifiedBranch])) { $actualRemoteEnvironment = $config['mapping'][$specifiedBranch]; $this->stdErr->writeln("The local branch <info>{$specifiedBranch}</info> is mapped to the remote environment <info>{$actualRemoteEnvironment}</info>"); } elseif ($mappedByDefault) { $actualRemoteEnvironment = $specifiedBranch; $this->stdErr->writeln("The local branch <info>{$specifiedBranch}</info> is mapped to the default remote environment, <info>{$specifiedBranch}</info>"); } else { $this->stdErr->writeln("The local branch <info>{$specifiedBranch}</info> is not mapped to a remote environment"); } $success = !empty($actualRemoteEnvironment) ? $actualRemoteEnvironment == $specifiedEnvironmentId : $specifiedEnvironmentId == '0'; return $success ? 0 : 1; }
/** * Ensure there are appropriate Git remotes in the repository. * * @param string $dir * @param string $url */ public function ensureGitRemote($dir, $url) { if (!file_exists("{$dir}/.git")) { throw new \InvalidArgumentException('The directory is not a Git repository'); } $gitHelper = new GitHelper(); $gitHelper->ensureInstalled(); $gitHelper->setDefaultRepositoryDir($dir); $platformUrl = $gitHelper->getConfig("remote.platform.url", $dir); if (!$platformUrl) { $gitHelper->execute(array('remote', 'add', 'platform', $url), $dir, true); } elseif ($platformUrl != $url) { $gitHelper->execute(array('remote', 'set-url', 'platform', $url), $dir, true); } // Add an origin remote too. if (!$gitHelper->getConfig("remote.origin.url", $dir)) { $gitHelper->execute(array('remote', 'add', 'origin', $url)); } }
/** * Test GitHelper::checkOutNew(). */ public function testCheckOutNew() { $repository = $this->getRepositoryDir(); $this->gitHelper->setDefaultRepositoryDir($repository); $this->assertTrue($this->gitHelper->checkOutNew('new')); }