/**
  * 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);
         }
     }
 }