Skip to content

Commit

Permalink
feat: Methods based on RunCommandBaseMethod can use docker-image as r…
Browse files Browse the repository at this point in the history
…un context
  • Loading branch information
stmh committed Aug 14, 2022
1 parent 70c0b80 commit 91b59b6
Showing 1 changed file with 106 additions and 32 deletions.
138 changes: 106 additions & 32 deletions src/Method/RunCommandBaseMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ abstract class RunCommandBaseMethod extends BaseMethod implements MethodInterfac

const HOST_CONTEXT = 'host';
const DOCKER_HOST_CONTEXT = 'dockerHost';
const DOCKER_IMAGE = ScriptExecutionContext::DOCKER_IMAGE;

const RUN_CONTEXT_KEY = 'runContext';
const ROOT_FOLDER_KEY = 'rootFolder';

public function supports(string $method_name): bool
{
Expand All @@ -33,12 +37,7 @@ protected function getConfigPrefix() : string

public function getRootFolderKey(): string
{
return $this->getConfigPrefix() . 'RootFolder';
}

protected function getRunContextKey()
{
return "{$this->getConfigPrefix()}RunContext";
return $this->getConfigPrefix() . '.rootFolder';
}

public function getGlobalSettings(ConfigurationService $configuration): Node
Expand All @@ -59,69 +58,144 @@ public function isRunningAppRequired(HostConfig $host_config, TaskContextInterfa
if ($task !== $this->getName()) {
return false;
}
return $host_config[$this->getRunContextKey()] === self::HOST_CONTEXT;
return $host_config->getProperty($this->getConfigKey(self::RUN_CONTEXT_KEY)) === self::HOST_CONTEXT;
}

public function getDefaultConfig(ConfigurationService $configuration_service, Node $host_config): Node
{
return new Node([
$this->getRootFolderKey() => $host_config['gitRootFolder'] ?? $host_config['rootFolder'],
$this->getRunContextKey() => self::HOST_CONTEXT,
$this->getConfigPrefix() => [
'rootFolder' => $host_config['gitRootFolder'] ?? $host_config['rootFolder'],
'runContext' => self::HOST_CONTEXT,
],
], $this->getName() . ' method defaults');
}

public function getDeprecationMapping(): array
{
$mapping = parent::getDeprecationMapping();
$prefix = $this->getConfigPrefix();
return array_merge($mapping, [
"${prefix}RootFolder" => "${prefix}.rootFolder",
"${prefix}RunContext" => "${prefix}.context",
]);
}

public function validateConfig(Node $config, ValidationErrorBagInterface $errors)
{
$validation = new ValidationService($config, $errors, 'host-config');
$prefix = $this->getConfigPrefix();
$validation->deprecate([
"${prefix}RootFolder" => "please change to `${prefix}.rootFolder`",
"${prefix}RunContext" => "please change to `${prefix}.context`",
]);
$args = $this->getRootFolderKey();
$validation->hasKey($args, sprintf('%s should point to your root folder for %s.', $args, $this->getName()));
$validation->checkForValidFolderName($args);

$runContextKey = $this->getRunContextKey();
$validation->isOneOf($runContextKey, [self::HOST_CONTEXT, self::DOCKER_HOST_CONTEXT]);
$run_context_key = $this->getConfigKey(self::RUN_CONTEXT_KEY);
$validation->isOneOf(
$run_context_key,
[self::HOST_CONTEXT, self::DOCKER_HOST_CONTEXT, self::DOCKER_IMAGE]
);

if ($config[$runContextKey] == self::DOCKER_HOST_CONTEXT && !in_array('docker', $config['needs'])) {
$errors->addError($runContextKey, sprintf(
if ($config->getProperty($run_context_key) == self::DOCKER_HOST_CONTEXT
&& !in_array('docker', $config['needs'])
) {
$errors->addError($run_context_key, sprintf(
'`%s` is set to `%s`, this requires `docker` as part of the hosts needs.',
$runContextKey,
$run_context_key,
self::DOCKER_HOST_CONTEXT
));
}
}

/**
* @throws \Phabalicious\Exception\MismatchedVersionException
* @param \Phabalicious\Configuration\HostConfig $host_config
* @param \Phabalicious\Method\TaskContextInterface $context
* @param string $command
*
* @throws \Phabalicious\Exception\MethodNotFoundException
* @throws \Phabalicious\Exception\ValidationFailedException
* @throws \Phabalicious\Exception\MismatchedVersionException
* @throws \Phabalicious\Exception\MissingDockerHostConfigException
* @throws \Phabalicious\Exception\MissingScriptCallbackImplementation
* @throws \Phabalicious\Exception\UnknownReplacementPatternException
* @throws \Phabalicious\Exception\ValidationFailedException
*/
protected function runCommand(
HostConfig $host_config,
TaskContextInterface $context,
string $command
) {
$command = $this->prepareCommand($host_config, $context, $command);

/** @var ShellProviderInterface $shell */
if ($host_config[$this->getRunContextKey()] == self::DOCKER_HOST_CONTEXT) {
/** @var DockerMethod $docker_method */
$docker_method = $context->getConfigurationService()->getMethodFactory()->getMethod('docker');
$docker_config = $docker_method->getDockerConfig($host_config, $context);
$shell = $docker_config->shell();
$shell->pushWorkingDir($docker_method->getProjectFolder($docker_config, $host_config));
$shell->cd($host_config[$this->getRootFolderKey()]);
} else {
$shell = $this->getShell($host_config, $context);
$shell->pushWorkingDir($host_config[$this->getRootFolderKey()]);
$run_context = $host_config->getProperty($this->getConfigKey(self::RUN_CONTEXT_KEY));

switch ($run_context) {
case self::DOCKER_IMAGE:
// Lets construct a script and set the execution context there.
/** @var \Phabalicious\Method\ScriptMethod $script_method */
$script_method = $context->getConfigurationService()->getMethodFactory()->getMethod('script');
$script_context = clone $context;
$script_context->set(ScriptMethod::SCRIPT_CONTEXT, $run_context);
$script_context->set(
ScriptMethod::SCRIPT_CONTEXT_DATA,
$host_config->getProperty($this->getConfigPrefix())
);
$script_context->setShell($this->getShell($host_config, $context));

$bag = new ScriptDataBag();
$bag->setContext($script_context)
->setCommands([
sprintf('#!%s %s', $this->getExecutableName(), $command)
])
->setRootFolder($this->getConfig($host_config, self::ROOT_FOLDER_KEY));

$result = $script_method->runScriptImpl($bag);
$context->mergeResults($script_context);

$context->setResult('exitCode', $result->getExitCode());
$context->setCommandResult($result);
break;

case self::DOCKER_HOST_CONTEXT:
/** @var DockerMethod $docker_method */
$docker_method = $context->getConfigurationService()->getMethodFactory()->getMethod('docker');
$docker_config = $docker_method->getDockerConfig($host_config, $context);
$shell = $docker_config->shell();
$shell->pushWorkingDir($docker_method->getProjectFolder($docker_config, $host_config));
$shell->cd($this->getConfig($host_config, self::ROOT_FOLDER_KEY));
$result = $shell->run('#!' . $this->getExecutableName(). ' ' . $command);
$context->setResult('exitCode', $result->getExitCode());
$context->setCommandResult($result);
$shell->popWorkingDir();

break;

default:
$shell = $this->getShell($host_config, $context);
$shell->pushWorkingDir($this->getConfig($host_config, self::ROOT_FOLDER_KEY));
$result = $shell->run('#!' . $this->getExecutableName(). ' ' . $command);
$context->setResult('exitCode', $result->getExitCode());
$context->setCommandResult($result);
$shell->popWorkingDir();

break;
}

$result = $shell->run('#!' . $this->getExecutableName(). ' ' . $command);
$context->setResult('exitCode', $result->getExitCode());
$shell->popWorkingDir();
}

protected function prepareCommand(HostConfig $host_config, TaskContextInterface $context, string $command): string
{
return $command;
}

private function getConfigKey(string $key): string
{
return sprintf("%s.%s", $this->getConfigPrefix(), $key);
}

protected function getConfig(HostConfig $host_config, string $key)
{
return $host_config->getProperty($this->getConfigKey($key));
}

}

0 comments on commit 91b59b6

Please sign in to comment.