/** * Applies all registered searchAndReplace operations. * * @return void */ protected function applySearchAndReplaceOperations() { foreach (Files::getRecursiveDirectoryGenerator($this->targetPackageData['path'], null, true) as $pathAndFilename) { $pathInfo = pathinfo($pathAndFilename); if (!isset($pathInfo['filename'])) { continue; } if (strpos($pathAndFilename, 'Migrations/Code') !== false) { continue; } foreach ($this->operations['searchAndReplace'] as $operation) { list($search, $replacement, $filter, $regularExpression) = $operation; if (is_array($filter)) { if ($filter !== array() && (!isset($pathInfo['extension']) || !in_array($pathInfo['extension'], $filter, true))) { continue; } } elseif ($pathAndFilename !== $filter) { continue; } Tools::searchAndReplace($search, $replacement, $pathAndFilename, $regularExpression); } } }
/** * Initialize the manager: read package information and register migrations. * * @return void */ protected function initialize() { $this->packagesData = Tools::getPackagesData($this->packagesPath); $this->migrations = array(); foreach ($this->packagesData as $packageKey => $packageData) { $this->registerMigrationFiles(Files::concatenatePaths(array($this->packagesPath, $packageData['category'], $packageKey))); } }
/** * Transfers a Gerrit patch to a Github pull request. * * @param integer $patchId The Gerrit Change-ID * @return void */ public function applyGerritChangeCommand($patchId) { $this->output->ask("Make sure your development collection is set up correctly and that the master branch is clean and synced with upstream master before continuing.\nAlso make sure <b>php-cs-fixer</b> is installed globally.\n\nPress any key to continue."); $this->outputLine(''); $this->outputLine('If anything goes wrong, go to the development collection and checkout a clean master branch.'); $this->outputLine(''); $this->outputLine('Requesting patch details from Gerrit.'); $package = $this->gerritService->getPatchTargetPackage($patchId); $packageKey = $package->getPackageKey(); $packagePath = $package->getPackagePath(); $collectionPath = dirname($packagePath); $this->outputLine(sprintf('Determined <b>%s</b> as the target package key for this change.', $packageKey)); $commitDetails = $this->gerritService->getCommitDetails($patchId); $oldParentCommitId = $commitDetails['parents'][0]['commit']; $newParentCommitId = trim($this->executeCommand(sprintf('git log --grep=%s --pretty=format:%%H', $oldParentCommitId), $collectionPath)); if (!$newParentCommitId) { $this->outputLine('<error>Unable to find old parent commit ID for change in development collection.</error>'); return; } $this->outputLine(sprintf('<success>Found old parent commit ID for change in development collection.</success>', $packageKey)); $this->outputLine(''); $cleanRepository = trim($this->executeCommand('git status --porcelain', $collectionPath)); if ($cleanRepository) { $this->outputLine(sprintf('<error>Development collection "%s" not clean.</error>', $collectionPath)); return; } $this->outputLine(''); $this->outputLine('Creating new branch for change.'); $this->output($this->executeCommand('git checkout master', $collectionPath)); $this->output($this->executeCommand('git pull', $collectionPath)); $this->output($this->executeCommand(sprintf('git branch -f gerrit-%s', $patchId), $collectionPath)); $this->output($this->executeCommand(sprintf('git checkout gerrit-%s', $patchId), $collectionPath)); $this->output($this->executeCommand(sprintf('git reset --hard %s', $newParentCommitId), $collectionPath)); $this->outputLine('<success>Successfully created new branch for change.</success>'); $this->outputLine(''); $this->outputLine('Fetching change from Gerrit.'); $patchPathAndFileName = $this->gerritService->getPatchFromGerrit($patchId); $this->outputLine('<success>Successfully fetched change from Gerrit.</success>'); $this->outputLine(sprintf('The following changes will be applied to package <b>%s</b>', $packageKey)); $this->output($this->executeCommand(sprintf('git apply --directory %s --check %s', $packageKey, $patchPathAndFileName), $collectionPath)); $this->output($this->executeCommand(sprintf('git apply --directory %s --stat %s', $packageKey, $patchPathAndFileName), $collectionPath)); $this->outputLine(''); $this->outputLine('Applying change in new branch.'); $this->output($this->executeCommand(sprintf('git am --directory %s %s', $packageKey, $patchPathAndFileName), $collectionPath)); $this->outputLine(sprintf('<success>Successfully applied patch %1$s in branch "gerrit-%1$s"</success>', $patchId)); $this->outputLine(''); $this->outputLine(sprintf('<b>Converting change to PSR-2 and updating license header</b>', $patchId)); $modifiedFiles = array_filter(explode(PHP_EOL, $this->executeCommand('git diff HEAD~1 --name-only', $collectionPath))); $this->executeCommand('git reset --soft HEAD~1', $collectionPath); foreach ($modifiedFiles as $modifiedFile) { if (pathinfo($modifiedFile, PATHINFO_EXTENSION) === 'php') { $this->output($this->executeCommand(sprintf('php-cs-fixer fix --level=psr2 %s', $modifiedFile), $collectionPath, true)); Tools::searchAndReplace('/\\/\\*{1}([\\s\\S]+?)(script belongs)([\\s\\S]+?)\\*\\//', '/* * This file is part of the ' . $packageKey . ' package. * * (c) Contributors of the Neos Project - www.neos.io * * This package is Open Source Software. For the full copyright and license * information, please view the LICENSE file which was distributed with this * source code. */', $collectionPath . DIRECTORY_SEPARATOR . $modifiedFile, true); } } $this->outputLine(''); $this->outputLine(sprintf('<b>Stashing change, resetting branch top master branch tip and applying change</b>', $patchId)); $this->executeCommand('git stash', $collectionPath); $this->executeCommand('git reset --hard master', $collectionPath); $stashApplyingOutput = trim($this->executeCommand('git stash pop', $collectionPath, true)); $commitMessage = preg_replace('/\\n\\n\\n/', "\n", preg_replace('/(Releases|Change-Id):.+/', '', $commitDetails['message'])); if (strpos($stashApplyingOutput, 'CONFLICT') !== -1) { $this->output('<error>' . $stashApplyingOutput . '</error>'); $this->outputLine(''); $this->outputLine(''); $this->outputLine('<success>Change applied with <error>conflicts</error>.</success>'); $this->outputLine(''); $this->outputLine('<b>Next steps:</b>'); $this->outputLine(''); $this->outputLine(sprintf('<b>1. Go to "%s" where the branch "gerrit-%s" is checked out with the changes applied.</b>', $collectionPath, $patchId)); $this->outputLine(''); $this->outputLine('<b>2. Fix the conflicts and create new commit with the following commit message:</b>'); $this->output($commitMessage); $this->outputLine(''); $this->outputLine('<b>3. Push the new branch to your personal fork and create a new pull request from it.</b>'); } else { $this->outputLine(''); $this->outputLine(''); $this->outputLine('<success>Change applied on master <b>without</b> conflicts.</success>'); $this->outputLine(''); $this->outputLine('<b>Next steps:</b>'); $this->outputLine(''); $this->outputLine(sprintf('<b>1. Go to "%s" where the branch "gerrit-%s" is checked out with the changes applied.</b>', $collectionPath, $patchId)); $this->outputLine(''); $this->outputLine('<b>2. Fix the conflicts and create new commit with the following commit message:</b>'); $this->outputLine(''); $this->outputLine('<b>3. Push the new branch to your personal fork and create a new pull request from it.</b>'); } }
/** * Applies all registered searchAndReplace operations. * * @return void */ protected function applySearchAndReplaceOperations() { $allPathsAndFilenames = Files::readDirectoryRecursively($this->targetPackageData['path'], NULL, TRUE); foreach ($allPathsAndFilenames as $pathAndFilename) { $pathInfo = pathinfo($pathAndFilename); if (!isset($pathInfo['filename'])) { continue; } if (strpos($pathAndFilename, 'Migrations/Code') !== FALSE) { continue; } foreach ($this->operations['searchAndReplace'] as $operation) { list($search, $replacement, $filter, $regularExpression) = $operation; if (is_array($filter)) { if ($filter !== array() && (!isset($pathInfo['extension']) || !in_array($pathInfo['extension'], $filter, TRUE))) { continue; } } elseif ($pathAndFilename !== $filter) { continue; } Tools::searchAndReplace($search, $replacement, $pathAndFilename, $regularExpression); } } }
/** * Applies all registered searchAndReplace and searchAndReplaceRegex operations. * * @return void */ protected function applySearchAndReplaceOperations() { $allPathsAndFilenames = Files::readDirectoryRecursively($this->targetPackageData['path'], NULL, TRUE); foreach ($allPathsAndFilenames as $pathAndFilename) { $pathInfo = pathinfo($pathAndFilename); if (!isset($pathInfo['filename'])) { continue; } if (strpos($pathAndFilename, 'Migrations/Code') !== FALSE) { continue; } foreach ($this->operations['searchAndReplace'] as $operation) { if ($operation[2] !== array()) { if (!isset($pathInfo['extension']) || !in_array($pathInfo['extension'], $operation[2], TRUE)) { continue; } } Tools::searchAndReplace($operation[0], $operation[1], $pathAndFilename); } foreach ($this->operations['searchAndReplaceRegex'] as $operation) { if ($operation[2] !== array()) { if (!isset($pathInfo['extension']) || !in_array($pathInfo['extension'], $operation[2], TRUE)) { continue; } } Tools::searchAndReplace($operation[0], $operation[1], $pathAndFilename, TRUE); } } }