Skip to content

Commit

Permalink
Merge branch 'release/3.0.10'
Browse files Browse the repository at this point in the history
  • Loading branch information
stmh committed May 19, 2019
2 parents 9c04e91 + 7b90f4d commit 93d15c8
Show file tree
Hide file tree
Showing 10 changed files with 358 additions and 32 deletions.
19 changes: 19 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## 3.0.10 / 2019-05-19

### Added

* Add new inheritFromBlueprint config, so a host-config can inherit from a blueprinted config

hosts:
local:
inheritFromBlueprint:
config: <config-which-contains-blueprint>
variant: <the-variant>
Thats roughly the same as calling `phab --config=<config-which-contains-blueprint> --blueprint=<the-variant>` but using it in the fabfile allows you to override the config if needed.
* Introduce deprecated-flag for inherited data. Will display a warning, when found inside data
* Enhance output-command to support output of docker-, host- and applied blueprint config, and also of all global data.

phab -clocal output --what host # will output the complete host-config
phab -cremote output --what docker # will output the complete docker-host config
phab output --what global # will output all global settings

## 3.0.9 / 2019-05-11

### Fixed
Expand Down
13 changes: 13 additions & 0 deletions docs/docs/available-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ blueprints:

will create 4 new configurations using the blueprint-config `mbb`.

**Note**

You can even create a new host-config from a blueprint and override some of its setting:

```
hosts:
myHost:
inheritFromBluePrint:
config: my-blueprint-config
variant: my-variable
otherSettings...
```

## list

```shell
Expand Down
15 changes: 14 additions & 1 deletion docs/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ This will print all host configuration for the host `staging`.
* `local`: all commands are run locally
* `ssh`: all commands are run via a ssh-shell
* `docker-exec` all commands are run via docker-exec.
* `inheritFromBlueprint` this will apply the blueprint to the current configuration. This makes it easy to base the common configuration on a blueprint and just override some parts of it.
* `config` this is the blueprint-configuration used as a base.
* `variant` this is the variant to pass to the blueprint

#### Configuration for the local-method

Expand Down Expand Up @@ -423,7 +426,7 @@ You can even reference external files to inherit from:
hosts:
fileExample:
inheritsFrom: ./path/to/config/file.yaml
httpExapme:
httpExample:
inheritsFrom: http://my.tld/path/to/config_file.yaml
```

Expand All @@ -437,5 +440,15 @@ inheritsFrom:
- ./drupal.yaml
```

### Inherit from a blueprint

You can even inherit from a blueprint configuration for a host-config. This host-config can then override specific parts.

```
host:
demo:
inheritsFromBlueprint:
config: my-blueprint-config
varian: the-variant
```
88 changes: 70 additions & 18 deletions src/Command/OutputCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
namespace Phabalicious\Command;

use Phabalicious\Exception\BlueprintTemplateNotFoundException;
use Phabalicious\Exception\FabfileNotFoundException;
use Phabalicious\Exception\FabfileNotReadableException;
use Phabalicious\Exception\MismatchedVersionException;
use Phabalicious\Exception\MissingDockerHostConfigException;
use Phabalicious\Exception\MissingHostConfigException;
use Phabalicious\Exception\ShellProviderNotFoundException;
use Phabalicious\Exception\ValidationFailedException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Yaml\Dumper;
Expand All @@ -18,46 +26,90 @@ protected function configure()
->setName('output')
->setDescription('Outputs the configurarion as yaml')
->setHelp('Outputs the configuration as yaml');

$this->addOption(
'what',
null,
InputOption::VALUE_REQUIRED,
'What to output: (blueprint|host|docker|global)',
'blueprint'
);

$this->addOption(
'format',
null,
InputOption::VALUE_REQUIRED,
'Format to use for output: (yaml|json)',
'yaml'
);
}

/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int|null
* @throws BlueprintTemplateNotFoundException
* @throws \Phabalicious\Exception\FabfileNotFoundException
* @throws \Phabalicious\Exception\FabfileNotReadableException
* @throws \Phabalicious\Exception\MismatchedVersionException
* @throws \Phabalicious\Exception\MissingDockerHostConfigException
* @throws \Phabalicious\Exception\ShellProviderNotFoundException
* @throws FabfileNotFoundException
* @throws FabfileNotReadableException
* @throws MismatchedVersionException
* @throws MissingDockerHostConfigException
* @throws MissingHostConfigException
* @throws ShellProviderNotFoundException
* @throws ValidationFailedException
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$config = $input->getOption('config');
$blueprint = $input->getOption('blueprint');
if (empty($blueprint)) {
throw new \InvalidArgumentException('The required option --blueprint is not set or is empty');
}
$what = strtolower($input->getOption('what'));

if ($result = parent::execute($input, $output)) {
return $result;
if (!in_array($what, ['blueprint', 'host', 'docker', 'global'])) {
throw new \InvalidArgumentException('Unknown option for `what`');
}

$template = $this->getConfiguration()->getBlueprints()->getTemplate($config);
$data = $template->expand($blueprint);
$data = [
$data['configName'] => $data
];
$this->readConfiguration($input);
$data = [];
$title = '';

$dumper = new Dumper(2);
if ($what == 'blueprint') {
if (empty($blueprint)) {
throw new \InvalidArgumentException('The required option --blueprint is not set or is empty');
}
$template = $this->getConfiguration()->getBlueprints()->getTemplate($config);
$data = $template->expand($blueprint);
$data = [
$data['configName'] => $data
];
$title = 'Output of applied blueprint `' . $config . '`';
} elseif ($what == 'host') {
$data = $this->getConfiguration()->getHostConfig($config)->raw();
$data = [
$data['configName'] => $data
];
$title = 'Output of host-configuration `' . $config . '`';
} elseif ($what == 'docker') {
$data = $this->getConfiguration()->getDockerConfig($config)->raw();
$data = [ $config => $data];
$title = 'Output of docker-configuration `' . $config . '`';
} elseif ($what == 'global') {
$title = 'Output of global configuration `' . $config . '`';
$data = $this->getConfiguration()->getAllSettings();
}

if ($input->getOption('format') == 'json') {
$content = json_encode($data, JSON_PRETTY_PRINT);
} else {
$dumper = new Dumper(2);
$content = $dumper->dump($data, 10, 2);
}

$io = new SymfonyStyle($input, $output);
if ($output->isDecorated()) {
$io->title('Output of applied blueprint `' . $config . '`');
$io->title($title);
}

$io->block(
$dumper->dump($data, 10, 2),
$content,
null,
null,
''
Expand Down
54 changes: 50 additions & 4 deletions src/Configuration/ConfigurationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Phabalicious\Configuration;

use Composer\Semver\Comparator;
use Phabalicious\Exception\BlueprintTemplateNotFoundException;
use Phabalicious\Exception\FabfileNotFoundException;
use Phabalicious\Exception\FabfileNotReadableException;
use Phabalicious\Exception\MismatchedVersionException;
Expand Down Expand Up @@ -81,7 +82,7 @@ public function getLogger(): LoggerInterface
* @throws FabfileNotReadableException
* @throws MismatchedVersionException
* @throws ValidationFailedException
* @throws \Phabalicious\Exception\BlueprintTemplateNotFoundException
* @throws BlueprintTemplateNotFoundException
*/
public function readConfiguration(string $path, string $override = ''): bool
{
Expand Down Expand Up @@ -295,6 +296,14 @@ public function resolveInheritance(array $data, $lookup, $root_folder = false):
$resource
));
}
if (!empty($add_data['deprecated'])) {
$this->logger->warning(sprintf(
'Inherited data from `%s` is deprecated: %s',
$resource,
$add_data['deprecated']
));
unset($add_data['deprecated']);
}
if ($add_data) {
if (isset($add_data['inheritsFrom'])) {
$add_data = $this->resolveInheritance($add_data, $lookup, $root_folder);
Expand Down Expand Up @@ -371,11 +380,12 @@ function ($severity, $message) {
/**
* @param string $config_name
*
* @return \Phabalicious\Configuration\HostConfig
* @return HostConfig
* @throws MismatchedVersionException
* @throws \Phabalicious\Exception\MissingHostConfigException
* @throws \Phabalicious\Exception\ValidationFailedException
* @throws \Phabalicious\Exception\ShellProviderNotFoundException
* @throws BlueprintTemplateNotFoundException
*/
public function getHostConfig(string $config_name)
{
Expand All @@ -390,6 +400,10 @@ public function getHostConfig(string $config_name)
}

$data = $this->hosts[$config_name];

if (isset($data['inheritFromBlueprint'])) {
$data = $this->inheritFromBlueprint($config_name, $data);
}
$data = $this->validateHostConfig($config_name, $data);

$this->cache[$cid] = $data;
Expand All @@ -399,11 +413,11 @@ public function getHostConfig(string $config_name)
/**
* @param string $blueprint
* @param string $identifier
* @return \Phabalicious\Configuration\HostConfig
* @return HostConfig
* @throws MismatchedVersionException
* @throws ShellProviderNotFoundException
* @throws ValidationFailedException
* @throws \Phabalicious\Exception\BlueprintTemplateNotFoundException
* @throws BlueprintTemplateNotFoundException
*/
public function getHostConfigFromBlueprint(string $blueprint, string $identifier)
{
Expand Down Expand Up @@ -664,4 +678,36 @@ public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}

/**
* @param string $config_name
* @param $data
* @return array
* @throws MismatchedVersionException
* @throws ShellProviderNotFoundException
* @throws ValidationFailedException
* @throws BlueprintTemplateNotFoundException
*/
protected function inheritFromBlueprint(string $config_name, $data): array
{
$errors = new ValidationErrorBag();
$validation = new ValidationService($data['inheritFromBlueprint'], $errors, 'inheritFromBlueprint');
$validation->hasKeys([
'config' => 'The inheritFromBlueprint needs to know which blueprint config to use.',
'variant' => 'The inheritFromBlueprint needs a variant',
]);
if ($errors->hasErrors()) {
throw new ValidationFailedException($errors);
}
$add_data = $this->getHostConfigFromBlueprint(
$data['inheritFromBlueprint']['config'],
$data['inheritFromBlueprint']['variant']
);
unset($data['inheritFromBlueprint']);

$data = $this->mergeData($add_data->raw(), $data);
$data['configName'] = $config_name;

return $data;
}
}
Loading

0 comments on commit 93d15c8

Please sign in to comment.