Replace placeholders in option values and set default values

@param array $options
@param \TYPO3\Surf\Domain\Model\Deployment $deployment
@return array
167252
protected function processOptions(array $options, Deployment $deployment)
    {
        foreach (['tagName', 'description'] as $optionName) {
            $options[$optionName] = str_replace(
                [
                    '{releaseIdentifier}',
                    '{deploymentName}'
                ],
                [
                    $deployment->getReleaseIdentifier(),
                    $deployment->getName()
                ],
                $options[$optionName]
            );
        }

        if (!isset($options['submoduleTagNamePrefix'])) {
            $options['submoduleTagNamePrefix'] = '';
        }

        if (!isset($options['remote'])) {
            $options['remote'] = 'origin';
            return $options;
        }
        return $options;
    }
1168720
public function setOptions($options = [])
    {
        if (!is_array($options)) {
            $options = [];
        }

        $this->options = array_merge($this->getDefaults(), $options);
        return $this;
    }
365939
public function execute(Node $node, Application $application, Deployment $deployment, array $options = [])
    {
        try {
            $options = $this->configureOptions($options);
        } catch (ExceptionInterface $e) {
            return;
        }

        if (empty($options['directories'])) {
            return;
        }

        $baseDirectory = $options['baseDirectory'] ?: $deployment->getApplicationReleasePath($application);

        $commands = array_map(function ($directory) {
            return sprintf('mkdir -p %s', $directory);
        }, $options['directories']);

        array_unshift($commands, sprintf('cd %s', $baseDirectory));

        $this->shell->executeOrSimulate($commands, $node, $deployment);
    }
1202869
protected function fillOptionsWithValues(array $options)
    {
        return array_merge(
            array_map(
                function ($value) {
                    if (false === is_array($value)) {
                        throw new InvalidTypeException(
                            'Supported options of a service must be an array with a value as first entry, and a flag to tell if the option is required in the second entry.',
                            1459249834
                        );
                    }

                    return $value[0];
                },
                $this->supportedOptions
            ),
            $options
        );
    }
452991
protected function getCredentials(Node $node, Deployment $deployment, array $options, Application $application)
    {
        if (empty($options['db']) === true) {
            throw new InvalidConfigurationException('db is not configured', 1429628542);
        }
        if (empty($options['db']['credentialsSource']) === false) {
            switch ($options['db']['credentialsSource']) {
                case 'TYPO3\\CMS':
                    $credentials = $this->getCredentialsFromTypo3Cms($node, $deployment, $options, $application);
                    break;
                default:
                    throw new InvalidConfigurationException('unknown credentialsSource', 1429628543);
            }
        } else {
            $credentials = $options['db'];
        }

        return $credentials;
    }
533800
public function execute(Node $node, Application $application, Deployment $deployment, array $options = [])
    {
        $options = $this->configureOptions($options);

        $host = $options['releaseHost'];
        $login = $options['releaseHostLogin'];
        $changeLogUri = $options['changeLogUri'];
        $sitePath =  $options['releaseHostSitePath'];
        $version = $options['version'];
        $productName = $options['productName'];

        $this->shell->executeOrSimulate(sprintf('ssh %s%s "cd \"%s\" ; ./flow release:release --product-name \"%s\" --version \"%s\" --change-log-uri \"%s\""', ($login ? $login . '@' : ''), $host, $sitePath, $productName, $version, ($changeLogUri ? $changeLogUri : '')), $node, $deployment);
    }
410453
public function execute(Node $node, Application $application, Deployment $deployment, array $options = [])
    {
        if (!isset($options['command'])) {
            throw new InvalidConfigurationException('Missing "command" option for ShellTask', 1311168045);
        }

        $replacePaths = [
            '{deploymentPath}' => escapeshellarg($application->getDeploymentPath()),
            '{sharedPath}' => escapeshellarg($application->getSharedPath()),
            '{releasePath}' => escapeshellarg($deployment->getApplicationReleasePath($application)),
            '{currentPath}' => escapeshellarg($application->getReleasesPath() . '/current'),
            '{previousPath}' => escapeshellarg($application->getReleasesPath() . '/previous')
        ];

        $command = $options['command'];
        $command = str_replace(array_keys($replacePaths), $replacePaths, $command);

        $ignoreErrors = isset($options['ignoreErrors']) && $options['ignoreErrors'] === true;
        $logOutput = !(isset($options['logOutput']) && $options['logOutput'] === false);

        $this->shell->executeOrSimulate($command, $node, $deployment, $ignoreErrors, $logOutput);
    }
182239
public function execute(Node $node, Application $application, Deployment $deployment, array $options = [])
    {
        $releaseIdentifier = $deployment->getReleaseIdentifier();
        $releasesPath = $application->getReleasesPath();
        $commands = [
            "mkdir -p $releasesPath/$releaseIdentifier/Data",
            "cd $releasesPath/$releaseIdentifier",
            'ln -sf ../../../shared/Data/Logs ./Data/Logs',
            'ln -sf ../../../shared/Data/Persistent ./Data/Persistent'
        ];
        $this->shell->executeOrSimulate($commands, $node, $deployment);
    }
201760
public function execute(Node $node, Application $application, Deployment $deployment, array $options = [])
    {
        $this->validateOptions($options);
        $options = $this->processOptions($options, $deployment);

        $targetPath = $deployment->getApplicationReleasePath($application);
        $this->shell->executeOrSimulate(sprintf('cd ' . $targetPath . '; git tag -f -a -m %s %s', escapeshellarg($options['description']), escapeshellarg($options['tagName'])), $node, $deployment);
        if (isset($options['recurseIntoSubmodules']) && $options['recurseIntoSubmodules'] === true) {
            $submoduleCommand = escapeshellarg(sprintf('git tag -f -a -m %s %s', escapeshellarg($options['description']), escapeshellarg($options['submoduleTagNamePrefix'] . $options['tagName'])));
            $this->shell->executeOrSimulate(sprintf('cd ' . $targetPath . '; git submodule foreach %s', $submoduleCommand), $node, $deployment);
        }

        if (isset($options['pushTag']) && $options['pushTag'] === true) {
            $this->shell->executeOrSimulate(sprintf('cd ' . $targetPath . '; git push %s %s', escapeshellarg($options['remote']), escapeshellarg($options['tagName'])), $node, $deployment);
            if (isset($options['recurseIntoSubmodules']) && $options['recurseIntoSubmodules'] === true) {
                $submoduleCommand = escapeshellarg(sprintf('git push %s %s', escapeshellarg($options['remote']), escapeshellarg($options['submoduleTagNamePrefix'] . $options['tagName'])));
                $this->shell->executeOrSimulate(sprintf('cd ' . $targetPath . '; git submodule foreach %s', $submoduleCommand), $node, $deployment);
            }
        }
    }
1027077
protected function setOptions(array $options)
    {
        $this->options = array_merge(
            array_map(
                function ($value) {
                    return $value[0];
                },
                $this->supportedOptions
            ),
            $options
        );
    }
1111498
public function setOptions(array $options)
    {
        foreach ($options as $option => $value) {
            $this->setOption($option, $value);
        }

        return $this;
    }
157380
protected function mapValuesToOptions(array $value, array $options)
    {
        $result = [];
        foreach ($value as $key) {
            $result[] = $this->mapValueToOption($key, $options);
        }
        return $result;
    }
593619
public function execute(Node $node, Application $application, Deployment $deployment, array $options = [])
    {
        $options = $this->configureOptions($options);
        $targetReleasePath = $deployment->getApplicationReleasePath($application);
        $webDirectory = $options['webDirectory'];
        $relativeDataPath = $relativeDataPathFromWeb = '../../shared/Data';
        if ($webDirectory !== '') {
            $relativeDataPathFromWeb = str_repeat('../', substr_count(trim($webDirectory, '/'), '/') + 1) . $relativeDataPath;
        }
        $absoluteWebDirectory = rtrim("$targetReleasePath/$webDirectory", '/');

        $commands[] = 'cd ' . escapeshellarg($targetReleasePath);

        foreach ($options['symlinkDataFolders'] as $directory) {
            $commands[] = sprintf('{ [ -d %1$s ] || mkdir -p %1$s; }', escapeshellarg($relativeDataPath . '/' . $directory));
            $commands[] = sprintf('ln -sf %1$s %2$s', escapeshellarg($relativeDataPathFromWeb . '/' . $directory), escapeshellarg($absoluteWebDirectory . '/' . $directory));
        }

        foreach ($options['directories'] as $directory) {
            $directory = trim($directory, '\\/');
            $targetDirectory = Files::concatenatePaths([$relativeDataPath, $directory]);
            $commands[] = sprintf('{ [ -d %1$s ] || mkdir -p %1$s; }', escapeshellarg($targetDirectory));
            $commands[] = sprintf('ln -sf %1$s %2$s', escapeshellarg(str_repeat('../', substr_count(trim($directory, '/'), '/')) . $targetDirectory), escapeshellarg($directory));
        }
        $this->shell->executeOrSimulate($commands, $node, $deployment);
    }
524393
protected function buildCommands(
        Deployment $deployment,
        Application $application,
        $options = []
    ) {
        $commands = [];
        $command = '';
        $commandProvider = $this->commandProviderService->getDetectedCommandProvider($deployment, $application);
        switch ($commandProvider) {
            case CommandProviderService::COMMAND_PROVIDER_COREAPI:
                $command = $this->buildCoreapiCommand($deployment, $application, $options);
                break;
            case CommandProviderService::COMMAND_PROVIDER_TYPO3_CONSOLE:
                $command = $this->buildTypo3ConsoleCommand($options);
                break;
            default:
                // Do nothing
        }

        if ($command === '') {
            throw new CommandProviderException('The used Provider (' . $commandProvider . ') has no implementation for this task.', 1494672441);
        }

        $commands[] = 'cd ' . escapeshellarg($deployment->getApplicationReleasePath($application));
        if (!empty($options['context'])) {
            $commands[] = 'export TYPO3_CONTEXT=' . escapeshellarg($options['context']);
        }
        $commands[] = $command;

        return $commands;
    }
1359615
public function execute(Node $node, Application $application, Deployment $deployment, array $options = [])
    {
        if ($node->isLocalhost()) {
            $deployment->getLogger()->log('node seems not to be a remote node', LOG_DEBUG);
        } else {
            $username = $node->hasOption('username') ? $node->getOption('username') : null;
            if (!empty($username)) {
                $username = $username.'@';
            }

            $hostname = $node->getHostname();

            $sshOptions = ['-A', '-q', '-o BatchMode=yes'];
            if ($node->hasOption('port')) {
                $sshOptions[] = '-p '.escapeshellarg($node->getOption('port'));
            }

            $command = 'ssh '.implode(' ', $sshOptions).' '.escapeshellarg($username.$hostname).' exit;';

            $this->shell->execute($command, $deployment->getNode('localhost'), $deployment);
            $deployment->getLogger()->log('SSH connection successfully established', LOG_DEBUG);
        }
    }
50202
protected function _getOptions(array $options, $count)
    {
        $options = Hash::merge($this->_config, $options);
        return Hash::merge(['messages' => $this->_getDefaultMessages($count)], $options);
    }
900253
public function execute(Node $node, Application $application, Deployment $deployment, array $options = [])
    {
        $options = $this->configureOptions($options);

        if (empty($options['symlinks'])) {
            return;
        }

        $baseDirectory = $options['genericSymlinksBaseDir'] ?: $deployment->getApplicationReleasePath($application);

        $commands = [
            'cd ' . $baseDirectory,
        ];

        foreach ($options['symlinks'] as $linkPath => $sourcePath) {
            $commands[] = sprintf('ln -s %s %s', $sourcePath, $linkPath);
        }

        $this->shell->executeOrSimulate($commands, $node, $deployment);
    }