Skip to content
Commits on Source (47)
......@@ -57,7 +57,7 @@ script:
--web_group=www-data
--web_disable_url=http://localhost/disabled
--web_maintenance_url=http://localhost/maintenance
--restart_command="sudo apache2ctl graceful"
--restart_command="echo 'Restarting web server...'; sleep 3"
- provision services server_master add db -n
--service_type=mysql
......
#!/usr/bin/env php
<?php
require 'provision.php';
require 'provision-robo.php';
<?php
// We use PWD if available because getcwd() resolves symlinks, which
// could take us outside of the Drupal root, making it impossible to find.
$cwd = empty($_SERVER['PWD']) ? getcwd() : $_SERVER['PWD'];
// Set up autoloader
$loader = false;
if (file_exists($autoloadFile = __DIR__ . '/vendor/autoload.php')
|| file_exists($autoloadFile = __DIR__ . '/../vendor/autoload.php')
|| file_exists($autoloadFile = __DIR__ . '/../autoload.php')
|| file_exists($autoloadFile = __DIR__ . '/../../autoload.php')
) {
$loader = include_once($autoloadFile);
} else {
throw new \Exception("Could not locate autoload.php. cwd is $cwd; __DIR__ is " . __DIR__);
}
use Aegir\Provision\Console\ConsoleOutput;
use Aegir\Provision\Console\Config;
use Drupal\Console\Core\Style\DrupalStyle;
use Robo\Common\TimeKeeper;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Exception\InvalidOptionException;
use Symfony\Component\Console\Exception\CommandNotFoundException;
// Start Timer.
$timer = new TimeKeeper();
$timer->start();
try {
// Create input output objects.
$input = new ArgvInput($argv);
$output = new ConsoleOutput();
$io = new DrupalStyle($input, $output);
// Create a config object.
$config = new Config();
// Create the app.
$app = new \Aegir\Provision\Provision($config, $input, $output);
// Run the app.
$status_code = $app->run($input, $output);
}
catch (InvalidOptionException $e) {
$io->error("There was a problem with your console configuration: " . $e->getMessage(), 1);
$status_code = 1;
}
// Stop timer.
$timer->stop();
if ($output->isVerbose()) {
$output->writeln("<comment>" . $timer->formatDuration($timer->elapsed()) . "</comment> total time elapsed.");
}
exit($status_code);
<?php
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Input\ArrayInput;
use Drupal\Console\Core\Style\DrupalStyle;
use Drupal\Console\Core\Utils\ArgvInputReader;
use Aegir\Provision\Application;
use Aegir\Provision\Console\ConsoleOutput;
set_time_limit(0);
ini_set('display_errors', 1);
......
......@@ -6,6 +6,7 @@
"type": "library",
"license": "GPL-2.0+",
"require": {
"consolidation/Robo": "^1.1",
"consolidation/annotated-command": "~2",
"drupal/console-core": "1.0.2",
"psr/log": "^1.0",
......
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "25f4161ac19dde865bcef9fa9d341b03",
"content-hash": "9fedee2bcebf91f9ab5c9865d6d9f0eb",
"packages": [
{
"name": "consolidation/annotated-command",
......@@ -57,6 +57,102 @@
"description": "Initialize Symfony Console commands from annotated command class methods.",
"time": "2017-10-17T01:48:51+00:00"
},
{
"name": "consolidation/config",
"version": "1.0.7",
"source": {
"type": "git",
"url": "https://github.com/consolidation/config.git",
"reference": "b59a3b9ea750c21397f26a68fd2e04d9580af42e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/consolidation/config/zipball/b59a3b9ea750c21397f26a68fd2e04d9580af42e",
"reference": "b59a3b9ea750c21397f26a68fd2e04d9580af42e",
"shasum": ""
},
"require": {
"dflydev/dot-access-data": "^1.1.0",
"grasmash/yaml-expander": "^1.1",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4",
"satooshi/php-coveralls": "^1.0",
"squizlabs/php_codesniffer": "2.*",
"symfony/console": "^2.5|^3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Consolidation\\Config\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Greg Anderson",
"email": "greg.1.anderson@greenknowe.org"
}
],
"description": "Provide configuration services for a commandline tool.",
"time": "2017-10-25T05:50:10+00:00"
},
{
"name": "consolidation/log",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/consolidation/log.git",
"reference": "74ba81b4edc585616747cc5c5309ce56fec41254"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/consolidation/log/zipball/74ba81b4edc585616747cc5c5309ce56fec41254",
"reference": "74ba81b4edc585616747cc5c5309ce56fec41254",
"shasum": ""
},
"require": {
"php": ">=5.5.0",
"psr/log": "~1.0",
"symfony/console": "~2.5|~3.0"
},
"require-dev": {
"phpunit/phpunit": "4.*",
"squizlabs/php_codesniffer": "2.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Consolidation\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Greg Anderson",
"email": "greg.1.anderson@greenknowe.org"
}
],
"description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.",
"time": "2016-03-23T23:46:42+00:00"
},
{
"name": "consolidation/output-formatters",
"version": "3.1.12",
......@@ -106,6 +202,116 @@
"description": "Format text by applying transformations provided by plug-in formatters.",
"time": "2017-10-12T19:38:03+00:00"
},
{
"name": "consolidation/robo",
"version": "1.1.5",
"source": {
"type": "git",
"url": "https://github.com/consolidation/Robo.git",
"reference": "aea695cebff81d54ed6daf14894738d5dac1c15c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/consolidation/Robo/zipball/aea695cebff81d54ed6daf14894738d5dac1c15c",
"reference": "aea695cebff81d54ed6daf14894738d5dac1c15c",
"shasum": ""
},
"require": {
"consolidation/annotated-command": "^2.8.1",
"consolidation/config": "^1.0.1",
"consolidation/log": "~1",
"consolidation/output-formatters": "^3.1.5",
"league/container": "^2.2",
"php": ">=5.5.0",
"symfony/console": "~2.8|~3.0",
"symfony/event-dispatcher": "~2.5|~3.0",
"symfony/filesystem": "~2.5|~3.0",
"symfony/finder": "~2.5|~3.0",
"symfony/process": "~2.5|~3.0"
},
"replace": {
"codegyre/robo": "< 1.0"
},
"require-dev": {
"codeception/aspect-mock": "~1",
"codeception/base": "^2.2.6",
"codeception/verify": "^0.3.2",
"henrikbjorn/lurker": "~1",
"natxet/cssmin": "3.0.4",
"patchwork/jsqueeze": "~2",
"pear/archive_tar": "^1.4.2",
"phpunit/php-code-coverage": "~2|~4",
"satooshi/php-coveralls": "~1",
"squizlabs/php_codesniffer": "^2.8"
},
"suggest": {
"henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch",
"natxet/CssMin": "For minifying CSS files in taskMinify",
"patchwork/jsqueeze": "For minifying JS files in taskMinify",
"pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively."
},
"bin": [
"robo"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev",
"dev-state": "1.x-dev"
}
},
"autoload": {
"classmap": [
"scripts/composer/ScriptHandler.php"
],
"psr-4": {
"Robo\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Davert",
"email": "davert.php@resend.cc"
}
],
"description": "Modern task runner",
"time": "2017-10-25T20:41:21+00:00"
},
{
"name": "container-interop/container-interop",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/container-interop/container-interop.git",
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
"shasum": ""
},
"require": {
"psr/container": "^1.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Interop\\Container\\": "src/Interop/Container/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
"homepage": "https://github.com/container-interop/container-interop",
"time": "2017-02-14T19:40:03+00:00"
},
{
"name": "dflydev/dot-access-configuration",
"version": "v1.0.2",
......@@ -445,6 +651,53 @@
],
"time": "2017-09-04T05:42:48+00:00"
},
{
"name": "grasmash/yaml-expander",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/grasmash/yaml-expander.git",
"reference": "9ec59ccc7a630eb2637639e8214e70d27675456b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/grasmash/yaml-expander/zipball/9ec59ccc7a630eb2637639e8214e70d27675456b",
"reference": "9ec59ccc7a630eb2637639e8214e70d27675456b",
"shasum": ""
},
"require": {
"dflydev/dot-access-data": "^1.1.0",
"php": ">=5.4",
"symfony/yaml": "^2.8.11|^3"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.5.4",
"satooshi/php-coveralls": "^1.0",
"squizlabs/php_codesniffer": "^2.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Grasmash\\YamlExpander\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Matthew Grasmick"
}
],
"description": "Expands internal property references in a yaml file.",
"time": "2017-09-26T16:57:45+00:00"
},
{
"name": "jakub-onderka/php-console-color",
"version": "0.1",
......@@ -532,18 +785,83 @@
],
"time": "2015-04-20T18:58:01+00:00"
},
{
"name": "league/container",
"version": "2.4.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/container.git",
"reference": "43f35abd03a12977a60ffd7095efd6a7808488c0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/container/zipball/43f35abd03a12977a60ffd7095efd6a7808488c0",
"reference": "43f35abd03a12977a60ffd7095efd6a7808488c0",
"shasum": ""
},
"require": {
"container-interop/container-interop": "^1.2",
"php": "^5.4.0 || ^7.0"
},
"provide": {
"container-interop/container-interop-implementation": "^1.2",
"psr/container-implementation": "^1.0"
},
"replace": {
"orno/di": "~2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-2.x": "2.x-dev",
"dev-1.x": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"League\\Container\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Phil Bennett",
"email": "philipobenito@gmail.com",
"homepage": "http://www.philipobenito.com",
"role": "Developer"
}
],
"description": "A fast and intuitive dependency injection container.",
"homepage": "https://github.com/thephpleague/container",
"keywords": [
"container",
"dependency",
"di",
"injection",
"league",
"provider",
"service"
],
"time": "2017-05-10T09:20:27+00:00"
},
{
"name": "nikic/php-parser",
"version": "v3.1.1",
"version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "a1e8e1a30e1352f118feff1a8481066ddc2f234a"
"reference": "08131e7ff29de6bb9f12275c7d35df71f25f4d89"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a1e8e1a30e1352f118feff1a8481066ddc2f234a",
"reference": "a1e8e1a30e1352f118feff1a8481066ddc2f234a",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/08131e7ff29de6bb9f12275c7d35df71f25f4d89",
"reference": "08131e7ff29de6bb9f12275c7d35df71f25f4d89",
"shasum": ""
},
"require": {
......@@ -581,7 +899,7 @@
"parser",
"php"
],
"time": "2017-09-02T17:10:46+00:00"
"time": "2017-11-04T11:48:34+00:00"
},
{
"name": "psr/container",
......@@ -681,16 +999,16 @@
},
{
"name": "psy/psysh",
"version": "v0.8.11",
"version": "v0.8.15",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
"reference": "b193cd020e8c6b66cea6457826ae005e94e6d2c0"
"reference": "b1d289c2cb03a2f8249912c53e96ced38f879926"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/b193cd020e8c6b66cea6457826ae005e94e6d2c0",
"reference": "b193cd020e8c6b66cea6457826ae005e94e6d2c0",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/b1d289c2cb03a2f8249912c53e96ced38f879926",
"reference": "b1d289c2cb03a2f8249912c53e96ced38f879926",
"shasum": ""
},
"require": {
......@@ -704,7 +1022,7 @@
"require-dev": {
"friendsofphp/php-cs-fixer": "~1.11",
"hoa/console": "~3.16|~1.14",
"phpunit/phpunit": "~4.4|~5.0",
"phpunit/phpunit": "^4.8.35|^5.4.3",
"symfony/finder": "~2.1|~3.0"
},
"suggest": {
......@@ -750,7 +1068,7 @@
"interactive",
"shell"
],
"time": "2017-07-29T19:30:02+00:00"
"time": "2017-11-16T14:29:51+00:00"
},
{
"name": "stecman/symfony-console-completion",
......@@ -799,16 +1117,16 @@
},
{
"name": "symfony/config",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
"reference": "f9f19a39ee178f61bb2190f51ff7c517c2159315"
"reference": "8d2649077dc54dfbaf521d31f217383d82303c5f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/f9f19a39ee178f61bb2190f51ff7c517c2159315",
"reference": "f9f19a39ee178f61bb2190f51ff7c517c2159315",
"url": "https://api.github.com/repos/symfony/config/zipball/8d2649077dc54dfbaf521d31f217383d82303c5f",
"reference": "8d2649077dc54dfbaf521d31f217383d82303c5f",
"shasum": ""
},
"require": {
......@@ -857,20 +1175,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
"time": "2017-09-04T16:28:07+00:00"
"time": "2017-11-07T14:16:22+00:00"
},
{
"name": "symfony/console",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf"
"reference": "099302cc53e57cbb7414fd9f3ace40e5e2767c0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf",
"reference": "a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf",
"url": "https://api.github.com/repos/symfony/console/zipball/099302cc53e57cbb7414fd9f3ace40e5e2767c0b",
"reference": "099302cc53e57cbb7414fd9f3ace40e5e2767c0b",
"shasum": ""
},
"require": {
......@@ -925,20 +1243,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2017-09-06T16:40:18+00:00"
"time": "2017-11-12T16:53:41+00:00"
},
{
"name": "symfony/debug",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "8beb24eec70b345c313640962df933499373a944"
"reference": "74557880e2846b5c84029faa96b834da37e29810"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/8beb24eec70b345c313640962df933499373a944",
"reference": "8beb24eec70b345c313640962df933499373a944",
"url": "https://api.github.com/repos/symfony/debug/zipball/74557880e2846b5c84029faa96b834da37e29810",
"reference": "74557880e2846b5c84029faa96b834da37e29810",
"shasum": ""
},
"require": {
......@@ -981,20 +1299,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2017-09-01T13:23:39+00:00"
"time": "2017-11-10T16:38:39+00:00"
},
{
"name": "symfony/dependency-injection",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "e593f06dd90a81c7b70ac1c49862a061b0ec06d2"
"reference": "4e84f5af2c2d51ee3dee72df40b7fc08f49b4ab8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e593f06dd90a81c7b70ac1c49862a061b0ec06d2",
"reference": "e593f06dd90a81c7b70ac1c49862a061b0ec06d2",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4e84f5af2c2d51ee3dee72df40b7fc08f49b4ab8",
"reference": "4e84f5af2c2d51ee3dee72df40b7fc08f49b4ab8",
"shasum": ""
},
"require": {
......@@ -1051,20 +1369,20 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
"time": "2017-09-05T20:39:38+00:00"
"time": "2017-11-13T18:10:32+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "54ca9520a00386f83bca145819ad3b619aaa2485"
"reference": "271d8c27c3ec5ecee6e2ac06016232e249d638d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/54ca9520a00386f83bca145819ad3b619aaa2485",
"reference": "54ca9520a00386f83bca145819ad3b619aaa2485",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/271d8c27c3ec5ecee6e2ac06016232e249d638d9",
"reference": "271d8c27c3ec5ecee6e2ac06016232e249d638d9",
"shasum": ""
},
"require": {
......@@ -1114,20 +1432,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2017-07-29T21:54:42+00:00"
"time": "2017-11-05T15:47:03+00:00"
},
{
"name": "symfony/filesystem",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "b32a0e5f928d0fa3d1dd03c78d020777e50c10cb"
"reference": "77db266766b54db3ee982fe51868328b887ce15c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/b32a0e5f928d0fa3d1dd03c78d020777e50c10cb",
"reference": "b32a0e5f928d0fa3d1dd03c78d020777e50c10cb",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/77db266766b54db3ee982fe51868328b887ce15c",
"reference": "77db266766b54db3ee982fe51868328b887ce15c",
"shasum": ""
},
"require": {
......@@ -1163,20 +1481,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2017-07-29T21:54:42+00:00"
"time": "2017-11-07T14:12:55+00:00"
},
{
"name": "symfony/finder",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "b2260dbc80f3c4198f903215f91a1ac7fe9fe09e"
"reference": "138af5ec075d4b1d1bd19de08c38a34bb2d7d880"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/b2260dbc80f3c4198f903215f91a1ac7fe9fe09e",
"reference": "b2260dbc80f3c4198f903215f91a1ac7fe9fe09e",
"url": "https://api.github.com/repos/symfony/finder/zipball/138af5ec075d4b1d1bd19de08c38a34bb2d7d880",
"reference": "138af5ec075d4b1d1bd19de08c38a34bb2d7d880",
"shasum": ""
},
"require": {
......@@ -1212,20 +1530,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2017-07-29T21:54:42+00:00"
"time": "2017-11-05T15:47:03+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.5.0",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803"
"reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7c8fae0ac1d216eb54349e6a8baa57d515fe8803",
"reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296",
"reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296",
"shasum": ""
},
"require": {
......@@ -1237,7 +1555,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
"dev-master": "1.6-dev"
}
},
"autoload": {
......@@ -1271,20 +1589,20 @@
"portable",
"shim"
],
"time": "2017-06-14T15:44:48+00:00"
"time": "2017-10-11T12:05:26+00:00"
},
{
"name": "symfony/process",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "b7666e9b438027a1ea0e1ee813ec5042d5d7f6f0"
"reference": "a56a3989fb762d7b19a0cf8e7693ee99a6ffb78d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/b7666e9b438027a1ea0e1ee813ec5042d5d7f6f0",
"reference": "b7666e9b438027a1ea0e1ee813ec5042d5d7f6f0",
"url": "https://api.github.com/repos/symfony/process/zipball/a56a3989fb762d7b19a0cf8e7693ee99a6ffb78d",
"reference": "a56a3989fb762d7b19a0cf8e7693ee99a6ffb78d",
"shasum": ""
},
"require": {
......@@ -1320,20 +1638,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2017-07-29T21:54:42+00:00"
"time": "2017-11-13T15:31:11+00:00"
},
{
"name": "symfony/translation",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "add53753d978f635492dfe8cd6953f6a7361ef90"
"reference": "373e553477e55cd08f8b86b74db766c75b987fdb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/add53753d978f635492dfe8cd6953f6a7361ef90",
"reference": "add53753d978f635492dfe8cd6953f6a7361ef90",
"url": "https://api.github.com/repos/symfony/translation/zipball/373e553477e55cd08f8b86b74db766c75b987fdb",
"reference": "373e553477e55cd08f8b86b74db766c75b987fdb",
"shasum": ""
},
"require": {
......@@ -1385,20 +1703,20 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2017-07-29T21:54:42+00:00"
"time": "2017-11-07T14:12:55+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "89fcb5a73e0ede2be2512234c4e40457bb22b35f"
"reference": "805de6bd6869073e60610df1b14ab7d969c61b01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/89fcb5a73e0ede2be2512234c4e40457bb22b35f",
"reference": "89fcb5a73e0ede2be2512234c4e40457bb22b35f",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/805de6bd6869073e60610df1b14ab7d969c61b01",
"reference": "805de6bd6869073e60610df1b14ab7d969c61b01",
"shasum": ""
},
"require": {
......@@ -1453,20 +1771,20 @@
"debug",
"dump"
],
"time": "2017-08-27T14:52:21+00:00"
"time": "2017-11-07T14:16:22+00:00"
},
{
"name": "symfony/yaml",
"version": "v3.3.9",
"version": "v3.3.12",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "1d8c2a99c80862bdc3af94c1781bf70f86bccac0"
"reference": "0938408c4faa518d95230deabb5f595bf0de31b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/1d8c2a99c80862bdc3af94c1781bf70f86bccac0",
"reference": "1d8c2a99c80862bdc3af94c1781bf70f86bccac0",
"url": "https://api.github.com/repos/symfony/yaml/zipball/0938408c4faa518d95230deabb5f595bf0de31b9",
"reference": "0938408c4faa518d95230deabb5f595bf0de31b9",
"shasum": ""
},
"require": {
......@@ -1508,7 +1826,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2017-07-29T21:54:42+00:00"
"time": "2017-11-10T18:26:04+00:00"
},
{
"name": "twig/twig",
......@@ -1577,16 +1895,16 @@
},
{
"name": "webflo/drupal-finder",
"version": "1.0.0",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/webflo/drupal-finder.git",
"reference": "3216448cc347bc77127fa3bf6497ba9b3c296e9c"
"reference": "8a7886c575d6eaa67a425dceccc84e735c0b9637"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webflo/drupal-finder/zipball/3216448cc347bc77127fa3bf6497ba9b3c296e9c",
"reference": "3216448cc347bc77127fa3bf6497ba9b3c296e9c",
"url": "https://api.github.com/repos/webflo/drupal-finder/zipball/8a7886c575d6eaa67a425dceccc84e735c0b9637",
"reference": "8a7886c575d6eaa67a425dceccc84e735c0b9637",
"shasum": ""
},
"require-dev": {
......@@ -1610,7 +1928,7 @@
}
],
"description": "Helper class to locate a Drupal installation from a given path.",
"time": "2017-08-08T08:31:26+00:00"
"time": "2017-10-24T08:12:11+00:00"
},
{
"name": "webmozart/assert",
......
......@@ -7,8 +7,11 @@ use Aegir\Provision\Command\ServicesCommand;
use Aegir\Provision\Command\ShellCommand;
use Aegir\Provision\Command\StatusCommand;
use Aegir\Provision\Command\VerifyCommand;
use Aegir\Provision\Common\ProvisionAwareTrait;
use Aegir\Provision\Console\Config;
use Aegir\Provision\Console\ConsoleOutput;
use Drupal\Console\Core\Style\DrupalStyle;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Symfony\Component\Console\Command\HelpCommand;
......@@ -19,6 +22,7 @@ use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Logger\ConsoleLogger;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Command\Command as BaseCommand;
//use Symfony\Component\DependencyInjection\ContainerInterface;
//use Drupal\Console\Annotations\DrupalCommandAnnotationReader;
......@@ -33,17 +37,6 @@ use Symfony\Component\Console\Application as BaseApplication;
*/
class Application extends BaseApplication
{
/**
* @var string
*/
const NAME = 'Aegir Provision';
/**
* @var string
*/
const VERSION = '4.x';
/**
* @var string
*/
......@@ -53,97 +46,42 @@ class Application extends BaseApplication
* @var string
*/
const DEFAULT_TIMEZONE = 'America/New_York';
use ProvisionAwareTrait;
use LoggerAwareTrait;
/**
* @var LoggerInterface
*/
public $logger;
/**
* @var DrupalStyle
*/
public $io;
/**
* @var \Symfony\Component\Console\Input\InputInterface
*/
public $input;
/**
* @var \Symfony\Component\Console\Output\OutputInterface
* @var ConsoleOutput
*/
public $output;
public $console;
/**
* Application constructor.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @param \Aegir\Provision\Console\OutputInterface
*
* @throws \Exception
*/
public function __construct(InputInterface $input, OutputInterface $output)
public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
{
// If no timezone is set, set Default.
if (empty(ini_get('date.timezone'))) {
date_default_timezone_set($this::DEFAULT_TIMEZONE);
}
// Load Configs
try {
$this->config = new Config();
}
catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
parent::__construct($this::NAME, $this::VERSION);
}
/**
* Prepare input and output arguments. Use this to extend the Application object so that $input and $output is fully populated.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*/
public function configureIO(InputInterface $input, OutputInterface $output) {
parent::configureIO($input, $output);
$this->io = new DrupalStyle($input, $output);
$this->input = $input;
$this->output = $output;
$this->logger = new ConsoleLogger($output,
[LogLevel::INFO => OutputInterface::VERBOSITY_NORMAL]
);
}
/**
* @var Config
*/
private $config;
/**
* Getter for Configuration.
*
* @return Config
* Configuration object.
*/
public function getConfig()
{
return $this->config;
parent::__construct($name, $version);
}
/**
* Setter for Configuration.
* Make configureIO public so we can run it before ->run()
*
* @param Config $config
* Configuration object.
* @param InputInterface $input
* @param OutputInterface $output
*/
public function setConfig(Config $config)
public function configureIO(InputInterface $input, OutputInterface $output)
{
$this->config = $config;
parent::configureIO($input, $output);
}
/**
......@@ -161,7 +99,29 @@ class Application extends BaseApplication
return $commands;
}
/**
* Interrupts Command execution to add services like provision and logger.
*
* @param \Symfony\Component\Console\Command\Command $command
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*
* @return int
*/
protected function doRunCommand( BaseCommand $command, InputInterface $input, OutputInterface $output)
{
// Only setProvision if the command is using the trait.
if (method_exists($command, 'setProvision')) {
$command
->setProvision($this->getProvision())
->setLogger($this->logger)
;
}
$exitCode = parent::doRunCommand($command, $input, $output);
return $exitCode;
}
/**
* {@inheritdoc}
*
......@@ -181,145 +141,4 @@ class Application extends BaseApplication
return $inputDefinition;
}
/**
* Load all contexts into Context objects.
*
* @return array
*/
static function getAllContexts($name = '', $application = NULL) {
$contexts = [];
$config = new Config();
$context_files = [];
$finder = new \Symfony\Component\Finder\Finder();
$finder->files()->name('*' . $name . '.yml')->in($config->get('config_path') . '/provision');
foreach ($finder as $file) {
list($context_type, $context_name) = explode('.', $file->getFilename());
$context_files[$context_name] = [
'name' => $context_name,
'type' => $context_type,
'file' => $file,
];
}
foreach ($context_files as $context) {
$class = Context::getClassName($context['type']);
$contexts[$context['name']] = new $class($context['name'], $application);
}
if ($name && isset($contexts[$name])) {
return $contexts[$name];
}
elseif ($name && !isset($contexts[$name])) {
return NULL;
}
else {
return $contexts;
}
}
/**
* Load all server contexts.
*
* @param null $service
* @return mixed
* @throws \Exception
*/
static public function getAllServers($service = NULL) {
$servers = [];
$context_files = self::getAllContexts();
if (empty($context_files)) {
throw new \Exception('No server contexts found. Use `provision save` to create one.');
}
foreach ($context_files as $context) {
if ($context->type == 'server') {
$servers[$context->name] = $context;
}
}
return $servers;
}
/**
* Get a simple array of all contexts, for use in an options list.
* @return array
*/
public function getAllContextsOptions($type = NULL) {
$options = [];
foreach ($this->getAllContexts() as $name => $context) {
if ($type) {
if ($context->type == $type) {
$options[$name] = $context->name;
}
}
else {
$options[$name] = $context->type . ' ' . $context->name;
}
}
return $options;
}
/**
* Load the Aegir context with the specified name.
*
* @param $name
*
* @return \Aegir\Provision\Context
* @throws \Exception
*/
static public function getContext($name, Application $application = NULL) {
if (empty($name)) {
throw new \Exception('Context name must not be empty.');
}
if (empty(Application::getAllContexts($name, $application))) {
throw new \Exception('Context not found with name: ' . $name);
}
return Application::getAllContexts($name, $application);
}
/**
* Get a simple array of all servers, optionally specifying the the service_type to filter by ("http", "db" etc.)
* @param string $service_type
* @return array
*/
public function getServerOptions($service_type = '') {
$servers = [];
foreach ($this->getAllServers() as $server) {
if ($service_type && !empty($server->config['services'][$service_type])) {
$servers[$server->name] = $server->name . ': ' . $server->config['services'][$service_type]['type'];
}
elseif ($service_type == '') {
$servers[$server->name] = $server->name . ': ' . $server->config['services'][$service_type]['type'];
}
}
return $servers;
}
/**
* Check that a context type's service requirements are provided by at least 1 server.
*
* @param $type
* @return array
*/
static function checkServiceRequirements($type) {
$class_name = Context::getClassName($type);
// @var $context Context
$service_requirements = $class_name::serviceRequirements();
$services = [];
foreach ($service_requirements as $service) {
try {
if (empty(Application::getAllServers($service))) {
$services[$service] = 0;
}
else {
$services[$service] = 1;
}
} catch (\Exception $e) {
$services[$service] = 0;
}
}
return $services;
}
}
......@@ -2,7 +2,10 @@
namespace Aegir\Provision;
use Aegir\Provision\Common\ProvisionAwareTrait;
use Drupal\Console\Core\Style\DrupalStyle;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Symfony\Component\Console\Command\Command as BaseCommand;
use Drupal\Console\Core\Command\Shared\CommandTrait;
......@@ -19,7 +22,8 @@ abstract class Command extends BaseCommand
{
use CommandTrait;
use ProvisionAwareTrait;
use LoggerAwareTrait;
/**
* @var \Symfony\Component\Console\Input\InputInterface
......@@ -50,7 +54,7 @@ abstract class Command extends BaseCommand
* @var string
*/
public $context_name;
/**
* @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
......@@ -70,7 +74,7 @@ abstract class Command extends BaseCommand
try {
// Load context from context_name argument.
$this->context_name = $this->input->getArgument('context_name');
$this->context = Application::getContext($this->context_name, $this->getApplication());
$this->context = $this->getProvision()->getContext($this->context_name);
}
catch (\Exception $e) {
......@@ -92,7 +96,7 @@ abstract class Command extends BaseCommand
$this->input->setArgument('context_name', $this->context_name);
try {
$this->context = Application::getContext($this->context_name, $this->getApplication());
$this->context = $this->getProvision()->getContext($this->context_name);
}
catch (\Exception $e) {
$this->context = NULL;
......@@ -104,11 +108,11 @@ abstract class Command extends BaseCommand
* Show a list of Contexts to the user for them to choose from.
*/
public function askForContext($question = 'Choose a context') {
if (empty($this->getApplication()->getAllContextsOptions())) {
if (empty($this->getProvision()->getAllContextsOptions())) {
throw new \Exception('No contexts available! use <comment>provision save</comment> to create one.');
}
$this->context_name = $this->io->choice($question, $this->getApplication()->getAllContextsOptions());
$this->context_name = $this->io->choice($question, $this->getProvision()->getAllContextsOptions());
}
/**
......
......@@ -8,6 +8,7 @@ use Aegir\Provision\Context;
use Aegir\Provision\Context\PlatformContext;
use Aegir\Provision\Context\ServerContext;
use Aegir\Provision\Context\SiteContext;
use Aegir\Provision\Provision;
use Aegir\Provision\Service;
use Symfony\Component\Console\Exception\InvalidOptionException;
use Symfony\Component\Console\Input\ArrayInput;
......@@ -152,7 +153,7 @@ class SaveCommand extends Command
// Check for context type service requirements.
$exit = FALSE;
$this->io->comment("Checking service requirements for context type {$context_type}...");
$reqs = Application::checkServiceRequirements($context_type);
$reqs = $this->getProvision()->checkServiceRequirements($context_type);
foreach ($reqs as $service => $available) {
if ($available) {
$this->io->successLite("Service $service: Available");
......@@ -169,9 +170,12 @@ class SaveCommand extends Command
}
$properties = $this->askForContextProperties();
$options = $this->askForContextProperties();
$options['name'] = $this->context_name;
$options['type'] = $this->context_type;
$class = Context::getClassName($this->input->getOption('context_type'));
$this->context = new $class($input->getArgument('context_name'), $this->getApplication(), $properties);
$this->context = new $class($input->getArgument('context_name'), $this->getProvision(), $options);
}
// Delete context config.
......@@ -227,7 +231,7 @@ class SaveCommand extends Command
*/
public function askForContext($question = 'Choose a context')
{
$options = $this->getApplication()->getAllContextsOptions();
$options = $this->getProvision()->getAllContextsOptions();
// If there are options, add "new" to the list.
if (count($options)) {
......@@ -305,7 +309,7 @@ class SaveCommand extends Command
// $context_name = $this->io->ask($all_services[$type]);
// }
// $context = Application::getContext($context_name);
// $context = Provision::getContext($context_name);
$this->io->info("Adding required service $type...");
......@@ -348,7 +352,7 @@ class SaveCommand extends Command
$contexts[$property] = $this->input->getOption($property);
try {
$context = Application::getContext($contexts[$property]);
$context = $this->getProvision()->getContext($contexts[$property]);
}
catch (\Exception $e) {
throw new \Exception("Context set by option --{$property} does not exist.");
......@@ -359,7 +363,7 @@ class SaveCommand extends Command
}
}
else {
$contexts[$property] = $this->io->choice("Select $property context", $this->getApplication()->getAllContextsOptions($context_type));
$contexts[$property] = $this->io->choice("Select $property context", $this->getProvision()->getAllContextsOptions($context_type));
}
}
return $contexts;
......
......@@ -219,16 +219,16 @@ class ServicesCommand extends Command
}
// All other context types are associating with servers that provide the service.
else {
if (empty($this->getApplication()->getServerOptions($service))) {
if (empty($this->getProvision()->getServerOptions($service))) {
throw new \Exception("No servers providing $service service were found. Create one with `provision save` or use `provision services` to add to an existing server.");
}
$server = $this->input->getArgument('server')?
$this->input->getArgument('server'):
$this->io->choice('Which server?', $this->getApplication()->getServerOptions($service));
$this->io->choice('Which server?', $this->getProvision()->getServerOptions($service));
// Then ask for all options.
$server_context = $this->getApplication()->getContext($server);
$server_context = $this->getProvision()->getContext($server);
$properties = $this->askForServiceProperties($service);
$this->io->info("Using $service service from server $server...");
......
......@@ -43,6 +43,7 @@ class StatusCommand extends Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->getProvision();
if ($input->getArgument('context_name')) {
$rows = [['Configuration File', $this->context->config_path]];
......@@ -58,8 +59,9 @@ class StatusCommand extends Command
}
else {
$headers = ['Provision CLI Configuration'];
$rows = [['Configuration File', $this->getApplication()->getConfig()->getConfigPath()]];
$config = $this->getApplication()->getConfig()->all();
$rows = [];
$config = $this->getProvision()->getConfig()->toArray();
unset($config['options']);
foreach ($config as $key => $value) {
$rows[] = [$key, $value];
}
......@@ -67,14 +69,14 @@ class StatusCommand extends Command
// Lookup all contexts
$rows = [];
foreach ($this->getApplication()->getAllContexts() as $context) {
foreach ($this->getProvision()->getAllContexts() as $context) {
$rows[] = [$context->name, $context->type];
}
$headers = ['Contexts'];
$this->io->table($headers, $rows);
// Offer to output a context status.
$options = $this->getApplication()->getAllContextsOptions();
$options = $this->getProvision()->getAllContextsOptions();
$options['none'] = 'none';
$context = $this->io->choiceNoList('Get status for', $options, 'none');
......
......@@ -60,6 +60,11 @@ class VerifyCommand extends Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (empty($this->context)) {
throw new \Exception("You must specify a context to verify.");
}
$this->io->title(strtr("Verify %type: %name", [
'%name' => $this->context_name,
'%type' => $this->context->type,
......@@ -75,8 +80,7 @@ class VerifyCommand extends Command
}
*/
$message = $this->context->verify();
$message = $this->context->verifyCommand();
$this->io->comment($message);
}
}
<?php
namespace Aegir\Provision\Common;
use Aegir\Provision\Context;
trait ContextAwareTrait
{
/**
* @var Context
*/
protected $context = NULL;
/**
* @param Context $context
*
* @return $this
*/
public function setContext(Context $context = NULL)
{
$this->context = $context;
return $this;
}
/**
* @return Context
*/
public function getContext()
{
return $this->context;
}
}
<?php
namespace Aegir\Provision\Common;
use Aegir\Provision\Context;
use Symfony\Component\Process\Process;
use Twig\Node\Expression\Unary\NegUnary;
trait ProcessAwareTrait
{
/**
* @var Process
*/
protected $process = NULL;
// /**
// * @var string
// */
// protected $command;
/**
* @param Process $process
*
* @return $this
*/
protected function setProcess(Process $process = NULL)
{
$this->process = $process;
return $this;
}
/**
* @return Process
*/
public function getProcess()
{
if (is_null($this->process)) {
$this->process = new Process($this->command);
}
return $this->process;
}
/**
* @param $command
*
* @return $this
*/
public function setCommand($command) {
$this->command = $command;
return $this;
}
/**
* @return string
*/
public function getCommand() {
return $this->command;
}
public function execute() {
$this->process->run();
}
}
<?php
namespace Aegir\Provision\Common;
use Aegir\Provision\Provision;
trait ProvisionAwareTrait
{
/**
* @var Provision
*/
protected $provision = NULL;
/**
* @param Provision $provision
*
* @return $this
*/
public function setProvision(Provision $provision = NULL)
{
$this->provision = $provision;
return $this;
}
/**
* @return Provision
*/
public function getProvision()
{
if (is_null($this->provision)) {
return Provision::getProvision();
}
return $this->provision;
}
}
......@@ -2,7 +2,7 @@
namespace Aegir\Provision\ConfigDefinition;
use Aegir\Provision\Application;
use Aegir\Provision\Common\ProvisionAwareTrait;
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
......@@ -28,6 +28,8 @@ use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
*/
class ContextNodeDefinition extends ScalarNodeDefinition
{
use ProvisionAwareTrait;
protected function createNode()
{
/**
......@@ -50,12 +52,13 @@ class ContextNodeDefinition extends ScalarNodeDefinition
*/
public function validateContext($value)
{
$this->setProvision($this->getNode()->getAttribute('provision'));
// No need to do anything else.
// If there is no context named $value, getContext() throws an exception for us.
Application::getContext($value);
// If context_type is specified, Validate that the desired context is the right type.
if ($this->getNode()->getAttribute('context_type') && Application::getContext($value)->type != $this->getNode()->getAttribute('context_type')) {
if ($this->getNode()->getAttribute('context_type') && $this->getProvision()->getContext($value)->type != $this->getNode()->getAttribute('context_type')) {
throw new InvalidConfigurationException(strtr('The context specified for !name must be type !type.', [
'!name' => $this->name,
'!type' => $this->getNode()->getAttribute('context_type'),
......@@ -69,8 +72,8 @@ class ContextNodeDefinition extends ScalarNodeDefinition
$this->getNode()->getAttribute('service_requirement'):
$path[2]
;
Application::getContext($value)->getService($service);
$this->getProvision()->getContext($value)->getService($service);
}
return $value;
}
......
......@@ -2,65 +2,48 @@
namespace Aegir\Provision\Console;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Yaml\Dumper;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\Console\Exception\InvalidOptionException;
/**
* Class Config.
* Class Config
* @package Aegir\Provision\Console
*
* Many thanks to pantheon-systems/terminus. Inspired by DefaultConfig
*/
class Config implements ConfigurationInterface
class Config extends ProvisionConfig
{
/**
* Configuration values array.
*
* @var array
*/
protected $config = [];
/**
* Path to config YML file.
*
* @var string
*/
private $config_path = '';
/**
* Filename of config YML file.
*
* @var string
*/
private $config_filename = '.provision.yml';
const CONFIG_FILENAME = '.provision.yml';
/**
* {@inheritdoc}
* DefaultsConfig constructor.
*/
public function __construct()
{
$this->config_path = $this->getHomeDir().'/'.$this->config_filename;
try {
$processor = new Processor();
$configs = func_get_args();
if (file_exists($this->config_path)) {
$configs[] = Yaml::parse(file_get_contents($this->config_path));
}
$this->config = $processor->processConfiguration($this, $configs);
} catch (\Exception $e) {
throw new Exception(
'There is an error with your configuration: '.$e->getMessage()
);
}
parent::__construct();
$this->set('root', $this->getProvisionRoot());
$this->set('php', $this->getPhpBinary());
$this->set('php_version', PHP_VERSION);
$this->set('php_ini', get_cfg_var('cfg_file_path'));
$this->set('script', $this->getProvisionScript());
$this->set('os_version', php_uname('v'));
$this->set('user_home', $this->getHomeDir());
$this->set('aegir_root', $this->getHomeDir());
$this->set('script_user', $this->getScriptUser());
$this->set('config_path', $this->getHomeDir() . '/config');
$file = $this->get('user_home') . DIRECTORY_SEPARATOR . Config::CONFIG_FILENAME;
$this->set('console_config_file', $file);
$this->extend(new YamlConfig($this->get('user_home') . DIRECTORY_SEPARATOR . Config::CONFIG_FILENAME));
$this->extend(new DotEnvConfig(getcwd()));
$this->extend(new EnvConfig());
$this->validateConfig();
}
/**
* Check configuration values against the current system.
*
......@@ -69,204 +52,108 @@ class Config implements ConfigurationInterface
protected function validateConfig() {
// Check that aegir_root is writable.
// @TODO: Create some kind of Setup functionality.
if (!is_writable($this->config['aegir_root'])) {
throw new \Exception(
"There is an error with your configuration. The folder set to 'aegir_root' ({$this->config['aegir_root']}) is not writable. Fix this or change the aegir_root value in the file {$this->config_path}."
if (!is_writable($this->get('aegir_root'))) {
throw new InvalidOptionException(
"The folder set to 'aegir_root' ({$this->get('aegir_root')}) is not writable. Fix this or change the aegir_root value in the file {$this->get('console_config_file')}"
);
}
// Check that config_path exists and is writable.
if (!file_exists($this->config['config_path'])) {
throw new \Exception(
"There is an error with your configuration. The folder set to 'config_path' ({$this->config['config_path']}) does not exist. Create it or change the config_path value in the file {$this->config_path}."
// If config_path does not exist and we cannot create it...
if (!file_exists($this->get('config_path')) && !mkdir($this->get('config_path'))) {
throw new InvalidOptionException(
"The folder set to 'config_path' ({$this->get('config_path')}) does not exist, and cannot be created. Create it manually or change the 'config_path' value in the file {$this->get('console_config_file')}."
);
}
elseif (!is_writable($this->config['config_path'])) {
throw new \Exception(
"There is an error with your configuration. The folder set to 'config_path' ({$this->config['config_path']}) is not writable. Fix this or change the config_path value in the file {$this->config_path}."
elseif (!is_writable($this->get('config_path'))) {
throw new InvalidOptionException(
"The folder set to 'config_path' ({$this->get('config_path')}) is not writable. Fix this or change the config_path value in the file {$this->get('console_config_file')}."
);
}
elseif (!file_exists($this->config['config_path'] . '/provision')) {
mkdir($this->config['config_path'] . '/provision');
elseif (!file_exists($this->get('config_path') . '/provision')) {
mkdir($this->get('config_path') . '/provision');
}
// Ensure that script_user is the user.
$real_script_user = $this->getScriptUser();
if ($this->config['script_user'] != $real_script_user) {
throw new \Exception(
"There is an error with your configuration. The user set as 'script_user' ({$this->config['script_user']}) is not the currently running user ({$real_script_user}). Change to user {$this->config['script_user']} or change the script_user value in the file {$this->config_path}."
if ($this->get('script_user') != $real_script_user) {
throw new InvalidOptionException(
"The user set as 'script_user' ({$this->get('script_user')}) is not the currently running user ({$real_script_user}). Change to user {$this->config->get('script_user')} or change the script_user value in the file {{$this->get('console_config_file')}}."
);
}
}
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$tree_builder = new TreeBuilder();
$root_node = $tree_builder->root('aegir');
$root_node
->children()
->scalarNode('aegir_root')
->defaultValue(Config::getHomeDir())
->end()
->scalarNode('script_user')
->defaultValue(Config::getScriptUser())
->end()
->scalarNode('config_path')
->defaultValue(Config::getHomeDir() . '/config')
->end()
->end();;
return $tree_builder;
}
/**
* Get a config param value.
*
* @param string $key
* Key of the param to get.
*
* @return mixed|null
* Value of the config param, or NULL if not present.
*/
public function get($key, $name = null)
{
if ($name) {
return array_key_exists(
$name,
$this->config[$key]
) ? $this->config[$key][$name] : null;
} else {
return $this->has($key) ? $this->config[$key] : null;
}
}
/**
* Check if config param is present.
*
* @param string $key
* Key of the param to check.
*
* @return bool
* TRUE if key exists.
*/
public function has($key)
{
return array_key_exists($key, $this->config);
}
/**
* Set a config param value.
*
* @param string $key
* Key of the param to get.
* @param mixed $val
* Value of the param to set.
* Get the name of the source for this configuration object.
*
* @return bool
* @return string
*/
public function set($key, $val)
public function getSourceName()
{
return $this->config[$key] = $val;
return 'Default';
}
/**
* Get all config values.
* Returns location of PHP with which to run Terminus
*
* @return array
* All config galues.
* @return string
*/
public function all()
protected function getPhpBinary()
{
return $this->config;
return defined('PHP_BINARY') ? PHP_BINARY : 'php';
}
/**
* Add a config param value to a config array.
* Finds and returns the root directory of Provision
*
* @param string $key
* Key of the group to set to.
* @param string|array $names
* Name of the new object to set.
* @param mixed $val
* Value of the new object to set.
*
* @return bool
* @param string $current_dir Directory to start searching at
* @return string
* @throws \Exception
*/
public function add($key, $names, $val)
protected function getProvisionRoot($current_dir = null)
{
if (is_array($names)) {
$array_piece = &$this->config[$key];
foreach ($names as $name_key) {
$array_piece = &$array_piece[$name_key];
}
return $array_piece = $val;
} else {
return $this->config[$key][$names] = $val;
if (is_null($current_dir)) {
$current_dir = dirname(__DIR__);
}
}
/**
* Remove a config param from a config array.
*
* @param $key
* @param $name
*
* @return bool
*/
public function remove($key, $name)
{
if (isset($this->config[$key][$name])) {
unset($this->config[$key][$name]);
return true;
} else {
return false;
if (file_exists($current_dir . DIRECTORY_SEPARATOR . 'composer.json')) {
return $current_dir;
}
$dir = explode(DIRECTORY_SEPARATOR, $current_dir);
array_pop($dir);
if (empty($dir)) {
throw new \Exception('Could not locate root to set PROVISION_ROOT.');
}
$dir = implode(DIRECTORY_SEPARATOR, $dir);
$root_dir = $this->getProvisionRoot($dir);
return $root_dir;
}
/**
* Saves the config class to file.
* Finds and returns the name of the script running Terminus functions
*
* @return bool
* @return string
*/
public function save()
protected function getProvisionScript()
{
// Create config folder if it does not exist.
$fs = new Filesystem();
$dumper = new Dumper();
try {
$fs->dumpFile($this->config_path, $dumper->dump($this->config, 10));
return true;
} catch (IOExceptionInterface $e) {
return false;
}
$debug = debug_backtrace();
$script_location = array_pop($debug);
$script_name = str_replace(
$this->getProvisionRoot() . DIRECTORY_SEPARATOR,
'',
$script_location['file']
);
return $script_name;
}
/**
* Determine the user running provision.
*/
static function getScriptUser() {
$real_script_user = posix_getpwuid(posix_geteuid());
return $real_script_user['name'];
}
/**
* Returns the appropriate home directory.
*
* Adapted from Terminus Package Manager by Ed Reel
*
* @author Ed Reel <@uberhacker>
* @url https://github.com/uberhacker/tpm
*
* @return string
*/
static function getHomeDir()
protected function getHomeDir()
{
$home = getenv('HOME');
if (!$home) {
......@@ -278,14 +165,14 @@ class Config implements ConfigurationInterface
$home = getenv('HOMEPATH');
}
}
return $home;
}
/**
* Determine the user running provision.
*/
public function getConfigPath() {
return $this->config_path;
protected function getScriptUser() {
$real_script_user = posix_getpwuid(posix_geteuid());
return $real_script_user['name'];
}
}
<?php
namespace Aegir\Provision\Console;
use BennerInformatics\Spinner\ProcessSpinner;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\Console\Output\ConsoleOutput as BaseConsoleOutput;
use Symfony\Component\Process\Process;
/**
* Class Config.
*/
class ConsoleOutput extends BaseConsoleOutput
{
private $firstRun = true;
protected $process;
protected $spinFrames = ['/', '-', '\\', '|'];
protected $spinInterval = 85000;
/**
* Overwrites a previous message to the output.
*
* @param string $message The message
*/
public function erase($lines = 1)
{
if (!$this->firstRun) {
// Move the cursor to the beginning of the line
$this->write("\x0D");
// Erase the line
$this->write("\x1B[2K");
// Erase previous lines
if ($lines > 0) {
$this->write(str_repeat("\x1B[1A\x1B[2K", $lines));
}
}
$this->firstRun = false;
}
/**
* Inspired by https://github.com/BennerInformatics/php-process-spinner/
* @param $cmd
* @param string $start_message
* @param string $end_message
*
* @return bool
*/
public function exec($cmd, $start_message = 'Running command...') {
$spinPos = 0;
$this->process = new Process($cmd);
$this->process->start();
while ($this->process->isRunning()) {
$this->write(" <comment>{$this->spinFrames[$spinPos]} </comment>{$start_message}\r");
$spinPos = ($spinPos + 1) % count($this->spinFrames);
usleep($this->spinInterval);
}
if ($this->process->isSuccessful()) {
// Move the cursor to the beginning of the line
$this->write("\x0D");
// Erase the line
$this->write("\x1B[2K");
return true;
}
else {
throw new Exception("Running command {$cmd} failed: " . $this->process->getErrorOutput());
}
}
}
<?php
namespace Aegir\Provision\Console;
use Aegir\Provision\Provision;
/**
* Class DotEnvConfig
* @package Pantheon\Terminus\Config
*/
class DotEnvConfig extends ProvisionConfig
{
/**
* @var string
*/
protected $file;
/**
* DotEnvConfig constructor.
*/
public function __construct($dir)
{
parent::__construct();
$file = $dir . '/.env';
$this->setSourceName($file);
// Load environment variables from __DIR__/.env
if (file_exists($file)) {
// Remove comments (which start with '#')
$lines = file($file);
$lines = array_filter($lines, function ($line) {
return strpos(trim($line), '#') !== 0;
});
$info = parse_ini_string(implode($lines, "\n"));
$this->fromArray($info);
}
}
}
<?php
namespace Aegir\Provision\Console;
/**
* Class EnvConfig
* @package Aegir\Provision\Console
*/
class EnvConfig extends ProvisionConfig
{
protected $source_name = 'Environment Variable';
/**
* EnvConfig constructor.
*/
public function __construct()
{
parent::__construct();
// Add all of the environment vars that match our constant.
foreach ([$_SERVER, $_ENV] as $super) {
foreach ($super as $key => $val) {
if ($this->keyIsConstant($key)) {
$this->set($key, $val);
}
}
}
}
}