diff --git a/.travis.yml b/.travis.yml
index 7f5a8efcc..2a7de8c14 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -87,14 +87,19 @@ script:
- blt acsf:init
# Deploy build artifact.
- blt deploy:build
+ # Ensure that the doctor doesn't report any problems at this point.
+ # We must temporarily move acquia/blt to require to appease the Doctor. It must then be removed so deploy cannot resolve the symlink later.
+ - composer remove acquia/blt --no-update --dev
+ - composer require acquia/blt --no-update
+ - composer global require "hirak/prestissimo:^0.3"
+ - blt doctor
+ - composer remove acquia/blt --no-update
# Add Drupal VM config to repo.
- blt vm:init
# Switch back to 'blt' directory.
- cd ../blt
# Run 'blt' phpunit tests, excluding deploy-push tests.
- phpunit tests/phpunit --group blt --exclude-group deploy-push
- # Execute 'blt update' just to ensure that there isn't a non-zero exit code.
- # - blt update
deploy:
provider: script
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2c5f842c1..00a290bb8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,13 +2,12 @@
Please feel free to contribute to the project or file issues via the GitHub issue queue. When doing so, please keep the following points in mind:
+
* BLT is distributed under the GPLv2 license; WITHOUT ANY WARRANTY.
* The project maintainers make no commitment to respond to support requests,
feature requests, or pull requests.
* All contributions to BLT will be reviewed for compliance with Drupal Coding
Standards and best practices as defined by the project maintainer.
-* Feature that are part of the [Road Map](https://github.com/acquia/blt/wiki/Road-Map)
- will be prioritized for inclusion.
BLT work is currently being tracked in the [BLT GitHub issue queue](https://github.com/acquia/blt/issues) and organized via a [Waffle.io Kanban Board](https://waffle.io/acquia/blt).
@@ -26,8 +25,6 @@ cd blt-project
git init
composer install
./vendor/bin/blt install-alias
-blt init
-blt configure
rm -rf vendor
composer update
git add -A
diff --git a/composer.json b/composer.json
index eeaaf0b7d..bdc81be1a 100644
--- a/composer.json
+++ b/composer.json
@@ -13,7 +13,8 @@
"symfony/console": "~2",
"symfony/twig-bridge": "~2",
"php": ">=5.6",
- "composer-plugin-api": "^1.0.0"
+ "composer-plugin-api": "^1.0.0",
+ "dflydev/dot-access-data": "^1.0"
},
"autoload": {
"psr-4": {
diff --git a/composer.lock b/composer.lock
index f0d1ccbc5..25e6fd7fd 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "de6f11ac98767d7792617f93306f9f95",
- "content-hash": "c8ec97172ce549b9d70b47e626d0453a",
+ "hash": "d6fb083a9a345b61a1ead6b26b1f1d85",
+ "content-hash": "535430afdcc8784fa1178cf93357df0e",
"packages": [
{
"name": "alchemy/zippy",
@@ -176,6 +176,60 @@
],
"time": "2016-08-13 20:53:52"
},
+ {
+ "name": "dflydev/dot-access-data",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/dflydev/dflydev-dot-access-data.git",
+ "reference": "7a0960d088119818ce7687d200c363b01d183cbe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/7a0960d088119818ce7687d200c363b01d183cbe",
+ "reference": "7a0960d088119818ce7687d200c363b01d183cbe",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Dflydev\\DotAccessData": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Dragonfly Development Inc.",
+ "email": "info@dflydev.com",
+ "homepage": "http://dflydev.com"
+ },
+ {
+ "name": "Beau Simensen",
+ "email": "beau@dflydev.com",
+ "homepage": "http://beausimensen.com"
+ }
+ ],
+ "description": "Given a deep data structure, access data by dot notation.",
+ "homepage": "https://github.com/dflydev/dflydev-dot-access-data",
+ "keywords": [
+ "access",
+ "data",
+ "dot",
+ "notation"
+ ],
+ "time": "2015-08-13 03:51:18"
+ },
{
"name": "dflydev/placeholder-resolver",
"version": "v1.0.2",
diff --git a/mkdocs.yml b/mkdocs.yml
index 15f82c1b5..c516dc9bc 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -36,5 +36,6 @@ pages:
- Release notes: 'scripts/release-notes/README.md'
- Setting up continuous integration: 'readme/ci.md'
- Open source contribution: 'readme/os-contribution.md'
+ - Troubleshooting & Support: 'readme/support.md'
- Extending / Overriding BLT: 'readme/extending-blt.md'
- Contributing: 'CONTRIBUTING.md'
diff --git a/phing/tasks/deploy.xml b/phing/tasks/deploy.xml
index 93c407e59..d557fcb1c 100644
--- a/phing/tasks/deploy.xml
+++ b/phing/tasks/deploy.xml
@@ -13,6 +13,7 @@
+
diff --git a/readme/support.md b/readme/support.md
new file mode 100644
index 000000000..8fc751ca4
--- /dev/null
+++ b/readme/support.md
@@ -0,0 +1,14 @@
+If you experience issues with a local BLT build, try using Dr. BLT to diagnose your problem:
+
+ blt doctor
+
+If that isn't helpful, please post an issue on the [GitHub issue queue](https://github.com/acquia/blt/issues) including the following information:
+
+- Your version of BLT, `composer info acquia/blt`
+- Your operating system
+- The full log output of your BLT command, wrapped in a [codeblock](https://help.github.com/articles/basic-writing-and-formatting-syntax/#quoting-code).
+
+In seeking help, please keep the following points in mind:
+
+* BLT is distributed under the GPLv2 license; WITHOUT ANY WARRANTY.
+* The project maintainers are under no obligation to respond to support requests, feature requests, or pull requests.
diff --git a/scripts/blt/alias b/scripts/blt/alias
index bae4ac926..29c5d558a 100644
--- a/scripts/blt/alias
+++ b/scripts/blt/alias
@@ -10,5 +10,6 @@ function blt() {
$GIT_ROOT/vendor/bin/blt "$@"
else
echo "You must run this command from within a BLT-generated project repository."
+ exit 1
fi
}
diff --git a/scripts/blt/ignore-existing.txt b/scripts/blt/ignore-existing.txt
index 5391d51e8..7722442a4 100644
--- a/scripts/blt/ignore-existing.txt
+++ b/scripts/blt/ignore-existing.txt
@@ -1,7 +1,6 @@
# These files from template dir will be included if they do not yet exist. They will not overwrite
# existing files.
.gitattributes
-.travis.yml
project.yml
composer.json
README.md
diff --git a/src/Drush/Command/BltDoctorCommand.php b/src/Drush/Command/BltDoctorCommand.php
index 30c13b02f..7f2633dd4 100644
--- a/src/Drush/Command/BltDoctorCommand.php
+++ b/src/Drush/Command/BltDoctorCommand.php
@@ -7,36 +7,169 @@
namespace Acquia\Blt\Drush\Command;
+use Dflydev\DotAccessData\Data;
+use Symfony\Component\Yaml\Yaml;
+use Drupal\Core\Installer\Exception\AlreadyInstalledException;
+
class BltDoctor {
+ /** @var string */
protected $localSettingsPath;
- protected $statusTable;
+ /** @var array */
+ protected $statusTable = [];
+ /** @var bool */
+ protected $ciEnabled = FALSE;
+ /** @var array */
+ protected $composerJson = [];
+ /** @var bool */
+ protected $drupalVmEnabled = FALSE;
+ /** @var bool */
+ protected $devDesktopEnabled = FALSE;
+ /** @var array */
+ protected $config = [];
/**
* BoltDoctor constructor.
*/
public function __construct() {
- $this->statusTable = drush_core_status();
- $this->localSettingsPath = $this->statusTable['root'] . '/' . $this->statusTable['site'] . '/settings/' . 'local.settings.php';
+ $this->setStatusTable();
+ $this->docroot = $this->statusTable['root'];
+ $this->repoRoot = $this->statusTable['root'] . '/../';
+
+ if (!$this->coreExists()) {
+ return FALSE;
+ }
+
+ $this->siteRoot = $this->docroot . '/' . $this->statusTable['site'];
+ $this->uri = $this->getUri();
+ $this->localSettingsPath = $this->siteRoot . '/settings/' . 'local.settings.php';
+ $this->localDrushRcPath = $this->siteRoot . '/local.drushrc.php';
+ $this->setProjectConfig();
+ $this->setCiEnabled();
+ $this->setStacksEnabled();
+ $this->setComposerJson();
+ }
+
+ /**
+ * Sets $this->statusTable using drush internals.
+ *
+ * @return array
+ */
+ public function setStatusTable() {
+ $status_table = drush_core_status();
+ $status_table['php-mysql'] = ini_get('pdo_mysql.default_socket');
+ $this->statusTable = $status_table;
+
+ return $status_table;
+ }
+
+ /**
+ * Sets $this->config from project.yml.
+ *
+ * @return array|bool|mixed
+ */
+ protected function setProjectConfig() {
+ $filepath = $this->repoRoot . '/project.yml';
+ if (!file_exists($filepath)) {
+ drush_set_error("project.yml is missing from the repository root directory!");
+
+ return [];
+ }
+
+ $this->config = Yaml::parse(file_get_contents($filepath));
+
+ return $this->config;
+ }
+
+ /**
+ * Sets $this->composerJson using root composer.json file.
+ *
+ * @return array
+ */
+ protected function setComposerJson() {
+ if (file_exists($this->repoRoot . '/composer.json')) {
+ $composer_json = json_decode(file_get_contents($this->repoRoot . '/composer.json'), TRUE);
+ $this->composerJson = $composer_json;
+
+ return $composer_json;
+ }
+
+ return [];
+ }
+
+ /**
+ * Gets site URI from drush status table.
+ *
+ * @return mixed|null
+ */
+ public function getUri() {
+ if (!empty($this->statusTable['uri'])) {
+ return $this->statusTable['uri'];
+ }
+ return NULL;
+ }
+
+ /**
+ * Sets which local *AMP stacks are initialized.
+ */
+ protected function setStacksEnabled() {
+ $file_contents = file_get_contents($this->docroot . '/sites/default/settings.php');
+ if (strstr($file_contents, 'DDSETTINGS')) {
+ $this->devDesktopEnabled = TRUE;
+ }
+
+ if (file_exists($this->repoRoot . '/Vagrantfile')) {
+ $this->drupalVmEnabled = TRUE;
+ }
+ }
+
+ /**
+ * Sets which CI solutions are initialized.
+ */
+ protected function setCiEnabled() {
+ if (file_exists($this->repoRoot . '/.travis.yml')) {
+ $this->travisCiEnabled = TRUE;
+ $this->ciEnabled = TRUE;
+ }
+ if (file_exists($this->repoRoot . '/acquia-pipelines.yml') || file_exists($this->repoRoot . '/acquia-pipelines.yaml')) {
+ $this->pipelinesEnabled = TRUE;
+ $this->ciEnabled = TRUE;
+ }
}
/**
* Performs all checks.
*/
public function checkAll() {
+ $this->checkCoreExists();
+ if (!$this->coreExists()) {
+ return FALSE;
+ }
+
+ $this->checkSettingsFile();
$this->checkLocalSettingsFile();
+ $this->checkLocalDrushFile();
$this->checkUriResponse();
$this->checkHttps();
+ $this->checkFileSystem();
$this->checkDbConnection();
+ $this->checkDrupalBootstrapped();
+ $this->checkDrupalInstalled();
+ //$this->checkDatabaseUpdates();
$this->checkCachingConfig();
$this->checkNvmExists();
- //$this->checkDatabaseUpdates();
+ $this->checkDevDesktopConfig();
+ $this->checkCiConfig();
+ $this->checkComposerConfig();
+ $this->checkBehatConfig();
+ $this->checkProjectYml();
- // @todo Check if Drupal is installed.
- // @todo Check if files directory exists.
// @todo Check error_level.
// @todo Check if theme dependencies have been built.
- // @todo Check if composer dependencies have been built.
+ // @todo Check that if drupal/acsf is in composer.json, acsf is initialized.
+ // @todo If using lightning, check lightning.extend.yml exists, check for $config['profile'] = 'lighting';
+ // @todo Check for existence of deprecated BLT files.
+ // @todo Check is PhantomJS bin matches OS.
}
/**
@@ -44,7 +177,7 @@ public function checkAll() {
*/
protected function checkLocalSettingsFile() {
if (!file_exists($this->localSettingsPath)) {
- drush_log("Could not find local settings file!", 'error');
+ drush_set_error("Could not find local settings file!");
drush_print("Your local settings file should exist at $this->localSettingsPath", 2);
}
else {
@@ -55,29 +188,75 @@ protected function checkLocalSettingsFile() {
}
/**
- * Checks that configured $base_url responds to requests.
+ * Checks active settings.php file.
+ */
+ protected function checkSettingsFile() {
+ if (!file_exists($this->statusTable['drupal-settings-file'])) {
+ drush_set_error("Could not find settings.php for this site!");
+ }
+
+ $settings_file_path = $this->docroot . '/' . $this->statusTable['drupal-settings-file'];
+ $settings_file_contents = file_get_contents($settings_file_path);
+ if (strstr($settings_file_contents, '/../vendor/acquia/blt/settings/blt.settings.php')) {
+ drush_log("BLT settings are included in settings file:", 'success');
+ drush_print($settings_file_path, 2);
+ }
+ if (strstr($settings_file_contents, '/sites/default/settings/blt.settings.php')) {
+ drush_set_error("Your settings file contains a deprecated statement for including BLT settings.");
+ drush_print("Please remove the line containing \"/sites/default/settings/blt.settings.php\" in $settings_file_path.", 2);
+ }
+ drush_print();
+ }
+
+ /**
+ * Checks local.drushrc.php file.
+ */
+ protected function checkLocalDrushFile() {
+ if (!file_exists($this->localDrushRcPath)) {
+ drush_set_error("$this->localDrushRcPath does not exist");
+ drush_print("Run `blt setup:drush` to generate it automatically.", 2);
+ }
+ else {
+ drush_log("Found your local drush settings file at:", 'success');
+ drush_print($this->localDrushRcPath, 2);
+ }
+ drush_print();
+ }
+
+ /**
+ * Checks that configured URI responds to requests.
*/
protected function checkUriResponse() {
- $site_available = drush_shell_exec("curl -I --insecure %s", $this->statusTable['uri']);
+ if (!$this->uri) {
+ drush_set_error("Site URI is not set");
+ drush_print("Is \$options['uri'] set correctly in $this->localDrushRcPath?", 2);
+
+ return FALSE;
+ }
+
+ $site_available = drush_shell_exec("curl -I --insecure %s", $this->uri);
if (!$site_available) {
- drush_log("Did not get response from $this->statusTable['uri']", 'error');
+ drush_set_error("Did not get a response from $this->uri");
drush_print("Is your *AMP stack running?", 2);
- drush_print("Is your \$base_url set correctly in $this->localSettingsPath?", 2);
+ drush_print("Is your web server configured to serve this URI from $this->docroot?", 2);
+ drush_print("Is \$options['uri'] set correctly in $this->localDrushRcPath?", 2);
+ drush_print();
+ drush_print("To generate settings files and install Drupal, run `blt local:setup`", 2);
}
else {
- drush_log("Received response from site:", 'success');
+ drush_log("Received a response from site:", 'success');
drush_print($this->statusTable['uri'], 2);
}
drush_print();
}
/**
- * Checks that SSL cert is valid for $base_url.
+ * Checks that SSL cert is valid for configured URI.
*/
protected function checkHttps() {
if (strstr($this->statusTable['uri'], 'https')) {
if (!drush_shell_exec('curl -cacert %s', $this->statusTable['uri'])) {
- drush_log('The SSL certificate for your local site appears to be invalid:', 'error');
+ drush_set_error('The SSL certificate for your local site appears to be invalid:');
drush_print($this->statusTable['uri'], 2);
drush_print();
}
@@ -85,38 +264,52 @@ protected function checkHttps() {
}
/**
- * Checks that drush is able to bootstrap and connect to database.
+ * Checks that drush is able to connect to database.
*/
protected function checkDbConnection() {
- if (empty($this->statusTable['bootstrap']) || $this->statusTable['bootstrap'] != 'Successful') {
- drush_log('Could not bootstrap Drupal!', 'error');
- drush_print("Is your *AMP stack running?", 2);
- drush_print('Are your database credentials correct?', 2);
- drush_blt_print_status_rows($this->statusTable, array(
- 'db-driver',
- 'db-hostname',
- 'db-username',
- 'db-password',
- 'db-name',
- 'db-port',
- ));
-
- drush_print('Is the active PHP binary the same one that is associated with your database service?');
- drush_blt_print_status_rows($this->statusTable, array(
- 'php-os',
- 'php-bin',
- 'php-conf',
- ));
-
- drush_print('Are you using the correct site and settings.php file?');
- drush_blt_print_status_rows($this->statusTable, array(
- 'site',
- 'drupal-settings-file',
- ));
+
+ $connection = @mysqli_connect($this->statusTable['db-hostname'], $this->statusTable['db-username'], $this->statusTable['db-password'], $this->statusTable['db-database'], $this->statusTable['db-port']);
+ if ($connection) {
+ mysqli_close($connection);
+ drush_log('Connected to database.', 'success');
+
+ return TRUE;
}
- else {
- drush_log('Bootstrapped Drupal and connected to database.', 'success');
+
+ drush_set_error('Could not connect to MySQL database.');
+ drush_print("Is your *AMP stack running?", 2);
+ drush_print('Are your database credentials correct?', 2);
+ drush_blt_print_status_rows($this->statusTable, array(
+ 'db-driver',
+ 'db-hostname',
+ 'db-username',
+ 'db-password',
+ 'db-name',
+ 'db-port',
+ ));
+
+ if ($this->statusTable['db-driver'] == 'mysql') {
+ drush_print("To verify your mysql credentials, run `mysql -u {$this->statusTable['db-username']} -h {$this->statusTable['db-hostname']} -p{$this->statusTable['db-password']} -P {$this->statusTable['db-port']}`", 2);
+ drush_print();
}
+
+ drush_print('Are you using the correct PHP binary?', 2);
+ drush_print('Is PHP using the correct MySQL socket?', 2);
+ drush_blt_print_status_rows($this->statusTable, array(
+ 'php-os',
+ 'php-bin',
+ 'php-conf',
+ 'php-mysql'
+ ));
+ drush_print("To verify, run `drush sqlc`", 2);
+ drush_print();
+
+ drush_print('Are you using the correct site and settings.php file?');
+ drush_blt_print_status_rows($this->statusTable, array(
+ 'site',
+ 'drupal-settings-file',
+ ));
+
drush_print();
}
@@ -128,7 +321,7 @@ protected function checkDatabaseUpdates() {
$pending = update_main();
if ($pending) {
- drush_log("There are pending database updates", 'error');
+ drush_set_error("There are pending database updates");
drush_print("Run `drush updb` to execute the updates.", 2);
}
else {
@@ -138,7 +331,7 @@ protected function checkDatabaseUpdates() {
}
/**
- * Checks that nvm exists.
+ * Checks that NVM exists.
*
* Note that this does not check if `nvm use` has been invoked for the correct
* node version.
@@ -146,7 +339,7 @@ protected function checkDatabaseUpdates() {
protected function checkNvmExists() {
$home = getenv("HOME");
if (!file_exists("$home/.nvm")) {
- drush_log('NVM does not exist. Install using the following commands:', 'error');
+ drush_log('NVM does not exist. Using NVM will help you manage multiple versions of NodeJS on one machine. Install using the following commands:', 'warning');
drush_print('curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash', 2);
drush_print('source ~/.bashrc', 2);
drush_print('nvm install 0.12.7', 2);
@@ -158,6 +351,202 @@ protected function checkNvmExists() {
}
}
+ /**
+ * Indicates whether Drupal core files exist in the docroot.
+ *
+ * @return bool
+ */
+ protected function coreExists() {
+ return file_exists($this->docroot . '/core/includes/install.core.inc');
+ }
+
+ /**
+ * Checks that Drupal core files exist in the docroot.
+ */
+ protected function checkCoreExists() {
+ if (!$this->coreExists()) {
+ drush_set_error("Drupal core is missing!");
+ drush_print("Check and re-install your composer dependencies.", 2);
+ }
+ else {
+ drush_log("Drupal core exists.", 'success');
+ }
+ }
+
+ /**
+ * Checks that drush is able to bootstrap Drupal Core.
+ *
+ * This is only possible if Drupal is installed.
+ */
+ protected function checkDrupalBootstrapped() {
+ if (empty($this->statusTable['bootstrap']) || $this->statusTable['bootstrap'] != 'Successful') {
+ drush_log('Could not bootstrap Drupal via drush.', 'warning');
+ }
+ else {
+ drush_log('Bootstrapped Drupal via drush.', 'success');
+ }
+ }
+
+ /**
+ * Checks that Drupal is installed.
+ */
+ protected function checkDrupalInstalled() {
+ require $this->docroot . '/core/includes/install.core.inc';
+ require $this->docroot . '/core/includes/install.inc';
+ require $this->docroot . '/core/modules/system/system.install';
+ try {
+ install_verify_database_ready();
+ drush_log("Drupal is not installed.", 'warning');
+ drush_print('Run `blt local:setup` to install Drupal locally.', 2);
+ }
+ catch (AlreadyInstalledException $e) {
+ drush_log("Drupal is installed.", 'success');
+ }
+ catch (\Exception $e) {
+
+ }
+ }
+
+ /**
+ * Checks that configured file system paths exist and are writable.
+ */
+ protected function checkFileSystem() {
+ $paths = [
+ '%files' => 'Public files directory',
+ '%private' => 'Private files directory',
+ '%tmp' => 'Temporary files directory',
+ ];
+
+ foreach ($paths as $key => $title) {
+ $path = $this->statusTable['%paths'][$key];
+ if (substr($path, 0, 1) == '/') {
+ $full_path = $path;
+ }
+ else {
+ $full_path = $this->docroot . "/$path";
+ }
+
+ if (file_exists($full_path)) {
+ drush_log("$title exists.", 'success');
+
+ if (is_writable($full_path)) {
+ drush_log("$title is writable.", 'success');
+ }
+ else {
+ drush_set_error("$title is not writable.");
+ drush_print("Change the permissions on $full_path", 2);
+ }
+ }
+ else {
+ drush_set_error("$title does not exist.");
+ drush_print("Create $full_path", 2);
+ }
+ }
+ }
+
+ /**
+ * Checks that Dev Desktop is configured correctly.
+ */
+ protected function checkDevDesktopConfig() {
+ if ($this->devDesktopEnabled) {
+ if (empty($ENV['DEVDESKTOP_DRUPAL_SETTINGS_DIR'])) {
+ drush_set_error("DevDesktop usage is enabled, but \$DEVDESKTOP_DRUPAL_SETTINGS_DIR is not set in your environmental variables.");
+ drush_print("Add `export DEVDESKTOP_DRUPAL_SETTINGS_DIR=\"\$HOME/.acquia/DevDesktop/DrupalSettings\"` to ~/.bash_profile or equivalent for your system.`", 2);
+ drush_print();
+ }
+ elseif (strstr($ENV['DEVDESKTOP_DRUPAL_SETTINGS_DIR'], '~')) {
+ drush_set_error("\$DEVDESKTOP_DRUPAL_SETTINGS_DIR contains a '~'. This does not always expand to your home directory.");
+ drush_print("Add `export DEVDESKTOP_DRUPAL_SETTINGS_DIR=\"\$HOME/.acquia/DevDesktop/DrupalSettings\"` to ~/.bash_profile or equivalent for your system.`", 2);
+ drush_print();
+ }
+
+ $variables_order = ini_get('variables_order');
+ $php_ini_file = php_ini_loaded_file();
+ if (!strstr($variables_order, 'E')) {
+ drush_set_error("DevDesktop usage is enabled, but variables_order does support environmental variables.");
+ drush_print("Define variables_order = \"EGPCS\" in $php_ini_file", 2);
+ drush_print();
+ }
+ }
+ }
+
+ /**
+ * Checks Drupal VM configuration.
+ */
+ protected function checkDrupalVmConfig() {
+ if ($this->drupalVmEnabled) {
+ // @todo Verify that box directory exists and contains config.
+ // @todo Check config.
+ }
+ }
+
+ /**
+ * Checks Behat configuration in local.yml.
+ *
+ * @return bool
+ */
+ protected function checkBehatConfig() {
+ if (!file_exists($this->repoRoot . '/tests/behat/local.yml')) {
+ drush_set_error("tests/behat/local.yml is missing!");
+
+ drush_print("Run `blt setup:behat` to generate it from example.local.yml.", 2);
+ return FALSE;
+ }
+
+ $this->behatDefaultLocalConfig = Yaml::parse(file_get_contents($this->repoRoot . '/tests/behat/local.yml'));
+ if ($this->drupalVmEnabled) {
+ $behat_drupal_root = $this->behatDefaultLocalConfig['local']['extensions']['Drupal\DrupalExtension']['drupal']['drupal_root'];
+ if (strstr($behat_drupal_root, '/var/www/')) {
+ drush_set_error("You have DrupalVM initialized, but drupal_root in tests/behat/local.yml does not reference the DrupalVM docroot.");
+ }
+ }
+
+ $behat_base_url = $this->behatDefaultLocalConfig['local']['extensions']['Behat\MinkExtension']['base_url'];
+ if ($behat_base_url != $this->getUri()) {
+ drush_set_error("base_url in tests/behat/local.yml does not match the site URI. It is set to \"$behat_base_url\".");
+ drush_print("Set base_url to {$this->getUri()}", 2);
+ }
+ }
+
+
+ /**
+ * Checks TravisCI configuration.
+ */
+ protected function checkTravisCiConfig() {
+ // @todo Check that known hosts is set.
+ // @todo Check that deployment is enabled.
+ }
+
+ /**
+ * Check that general CI configuration is set correctly.
+ */
+ protected function checkCiConfig() {
+ if ($this->ciEnabled) {
+ if (empty($this->config['git']['remotes'])) {
+ drush_set_error("Git repositories are not defined in project.yml.");
+ drush_print("Add values for git.remotes to project.yml to enabled automated deployment.", 2);
+ }
+ }
+ }
+
+ /**
+ * Checks that composer.json is configured correctly.
+ */
+ protected function checkComposerConfig() {
+ if (!empty($this->composerJson['require-dev']['acquia/blt'])) {
+ drush_set_error("acquia/blt is defined as a development dependency in composer.json");
+ drush_print("Move acquia/blt out of the require-dev object and into the require object in composer.json.", 2);
+ drush_print("This is necessary for BLT settings files to be available at runtime in production.", 2);
+ }
+
+ $prestissimo_intalled = drush_shell_exec("composer global show | grep hirak/prestissimo");
+ if (!$prestissimo_intalled) {
+ drush_set_error("prestissimo plugin for composer is not installed.");
+ drush_print("Run `composer global require hirak/prestissimo:^0.3` to install it.", 2);
+ drush_print("This will improve composer install/update performance by parallelizing the download of dependency information.", 2);
+ }
+ }
+
/**
* Checks that caching is configured for local development.
*/
@@ -186,14 +575,37 @@ protected function checkCachingConfig() {
}
}
+ /**
+ * Check that the contributed modules directory exists.
+ */
protected function checkContribExists() {
- if (!file_exists($this->statusTable['root'] . '/sites/all/modules/contrib')) {
- drush_log("Contributed module dependencies are missing.", 'error');
- drush_print("Run `./task.sh setup:build:all to build all contributed dependencies.", 2);
+ if (!file_exists($this->docroot . '/sites/all/modules/contrib')) {
+ drush_set_error("Contributed module dependencies are missing.");
+ drush_print("Run `blt setup:build to build all contributed dependencies.", 2);
drush_print();
}
else {
drush_log("Contributed module dependencies are present.");
}
}
+
+ /**
+ * Checks that is configured correctly at a high level.
+ */
+ protected function checkProjectYml() {
+ $deprecated_keys = [
+ 'project.hash_salt',
+ 'project.profile.contrib',
+ 'project.vendor',
+ 'project.description',
+ 'project.themes',
+ ];
+
+ $config = new Data($this->config);
+ foreach ($deprecated_keys as $deprecated_key) {
+ if ($config->get($deprecated_key)) {
+ drush_log("The $deprecated_key key is deprecated. Please remove it from project.yml.", 'warning');
+ }
+ }
+ }
}
diff --git a/template/.gitignore b/template/.gitignore
index 433c0fc5b..c62def578 100644
--- a/template/.gitignore
+++ b/template/.gitignore
@@ -105,3 +105,8 @@ nbproject/*
# DrupalVM
.vagrant/
+
+#Exports
+*.gz
+*.sql
+*.zip