Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit ddb18bf

Browse files
authored
Adding doctor command. (#415)
1 parent 71780c7 commit ddb18bf

File tree

6 files changed

+310
-13
lines changed

6 files changed

+310
-13
lines changed

bin/blt-console

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ $consoleRoot = __DIR__ . '/../';
1111
if (file_exists($consoleRoot . 'vendor/autoload.php')) {
1212
$autoload = include_once $consoleRoot . 'vendor/autoload.php';
1313
}
14+
elseif (file_exists($consoleRoot . '../blt-project/vendor/autoload.php')) {
15+
$autoload = include_once $consoleRoot . '../blt-project/vendor/autoload.php';
16+
}
1417
elseif (file_exists($consoleRoot.'../../autoload.php')) {
1518
$autoload = include_once $consoleRoot . '../../autoload.php';
1619
}

composer.lock

+5-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

drush/blt.drush.inc

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Custom drush commands provided by Bolt.
6+
*/
7+
8+
/**
9+
* Implements hook_drush_command().
10+
*
11+
* In this hook, you specify which commands your
12+
* drush module makes available, what it does and
13+
* description.
14+
*
15+
* Notice how this structure closely resembles how
16+
* you define menu hooks.
17+
*
18+
* See `drush topic docs-commands` for a list of recognized keys.
19+
*/
20+
function blt_drush_command() {
21+
$items = array();
22+
23+
$items['blt-doctor'] = array(
24+
'description' => "Check local settings and configuration to ensure that things are set up properly.",
25+
'aliases' => array('bdr'),
26+
'bootstrap' => DRUSH_BOOTSTRAP_MAX,
27+
);
28+
29+
return $items;
30+
}
31+
32+
/**
33+
* Callback for `blt-doctor` command.
34+
*/
35+
function drush_blt_doctor() {
36+
require_once __DIR__ . '/../src/Drush/Command/BltDoctorCommand.php';
37+
$blt_doctor = new \Acquia\Blt\Drush\Command\BltDoctor();
38+
$blt_doctor->checkAll();
39+
}
40+
41+
/**
42+
* Indents a key-value row.
43+
*
44+
* @param mixed $input
45+
* An array of key-value rows, or a string.
46+
*
47+
* @param $metadata
48+
* The formatting metadata.
49+
*
50+
* @return array|string
51+
* The prefixed output.
52+
*/
53+
function drush_blt_indent_filter($input, $metadata) {
54+
$indent = !empty($metadata['indent']) ? $metadata['indent'] : 2;
55+
$prefix = str_repeat(' ', $indent);
56+
if (is_array($input)) {
57+
foreach ($input as $key => $value) {
58+
$input[$prefix . $key] = $value;
59+
unset($input[$key]);
60+
}
61+
}
62+
else {
63+
$input = $prefix . $input;
64+
}
65+
66+
return $input;
67+
}
68+
69+
/**
70+
* Prints selected rows from the status table.
71+
*
72+
* @param array $status_table
73+
* The status table returned by drush_core_status().
74+
*
75+
* @param array $keys
76+
* An array of keys for the rows to print.
77+
*/
78+
function drush_blt_print_status_rows($status_table, $keys) {
79+
$intersection = array_intersect_key($status_table, array_flip($keys));
80+
$output = drush_format($intersection, array(
81+
'format' => 'key-value',
82+
'formatted-filter' => array(
83+
'drush_blt_indent_filter',
84+
),
85+
'indent' => 2,
86+
));
87+
drush_print($output);
88+
}

phing/phingcludes/DrushTask.php

+9-8
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,9 @@ public function setVerbose($var) {
214214
*/
215215
public function setPassthru($var) {
216216
if (is_string($var)) {
217-
$this->verbose = ($var === 'yes' || $var === 'true');
217+
$this->passthru = ($var === 'yes' || $var === 'true');
218218
} else {
219-
$this->verbose = !!$var;
219+
$this->passthru = !!$var;
220220
}
221221
}
222222

@@ -251,10 +251,6 @@ public function main() {
251251
$command[] = '@' . $this->alias;
252252
}
253253

254-
$option = new DrushOption();
255-
$option->setName('nocolor');
256-
$this->options[] = $option;
257-
258254
if (!empty($this->root)) {
259255
$option = new DrushOption();
260256
$option->setName('root');
@@ -303,22 +299,27 @@ public function main() {
303299
$command[] = $param->getValue();
304300
}
305301

306-
$command = implode(' ', $command);
307302

308303
if (!empty($this->dir)) {
309304
$this->log("Changing working directory to: $this->dir");
310305
chdir($this->dir);
311306
}
312307

313308
// Execute Drush.
314-
$this->log("Executing: $command");
315309
$output = array();
316310
$return = NULL;
317311

318312
if ($this->passthru) {
313+
$command = implode(' ', $command);
314+
$this->log("Executing: $command");
319315
passthru($command, $return);
320316
}
321317
else {
318+
// Redirect sterr to stout for Phing log.
319+
$command[] = '2>&1';
320+
321+
$command = implode(' ', $command);
322+
$this->log("Executing: $command");
322323
exec($command, $output, $return);
323324
// Collect Drush output for display through Phing's log.
324325
foreach ($output as $line) {

phing/tasks/blt.xml

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
<exec dir="${repo.root}" command="git commit -m 'Initial commit.'" logoutput="true" checkreturn="true" level="info" passthru="true"/>
99
</target>
1010

11+
<target name="doctor" description="Inspects your local blt configuration for possible issues.">
12+
<drush command="blt-doctor" verbose="false" uri="">
13+
<option name="include">${blt.root}/drush</option>
14+
</drush>
15+
</target>
16+
1117
<target name="blt:rsync-template">
1218
<echo>Copying files from BLT's template into your project.</echo>
1319
<!-- @todo Do not overwrite structured or executable files. Instead, update them intelligently settings.php, drush.wrapper etc. -->
+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Defines class that powers `drush blt-doctor` command.
6+
*/
7+
8+
namespace Acquia\Blt\Drush\Command;
9+
10+
class BltDoctor {
11+
12+
protected $localSettingsPath;
13+
protected $statusTable;
14+
15+
/**
16+
* BoltDoctor constructor.
17+
*/
18+
public function __construct() {
19+
$this->statusTable = drush_core_status();
20+
$this->localSettingsPath = $this->statusTable['root'] . '/' . $this->statusTable['site'] . '/settings/' . 'local.settings.php';
21+
}
22+
23+
/**
24+
* Performs all checks.
25+
*/
26+
public function checkAll() {
27+
$this->checkLocalSettingsFile();
28+
$this->checkUriResponse();
29+
$this->checkHttps();
30+
$this->checkDbConnection();
31+
$this->checkCachingConfig();
32+
$this->checkNvmExists();
33+
//$this->checkDatabaseUpdates();
34+
35+
// @todo Check if Drupal is installed.
36+
// @todo Check if files directory exists.
37+
// @todo Check error_level.
38+
// @todo Check if theme dependencies have been built.
39+
// @todo Check if composer dependencies have been built.
40+
}
41+
42+
/**
43+
* Checks that local settings file exists.
44+
*/
45+
protected function checkLocalSettingsFile() {
46+
if (!file_exists($this->localSettingsPath)) {
47+
drush_log("Could not find local settings file!", 'error');
48+
drush_print("Your local settings file should exist at $this->localSettingsPath", 2);
49+
}
50+
else {
51+
drush_log("Found your local settings file at:", 'success');
52+
drush_print($this->localSettingsPath, 2);
53+
}
54+
drush_print();
55+
}
56+
57+
/**
58+
* Checks that configured $base_url responds to requests.
59+
*/
60+
protected function checkUriResponse() {
61+
$site_available = drush_shell_exec("curl -I --insecure %s", $this->statusTable['uri']);
62+
if (!$site_available) {
63+
drush_log("Did not get response from $this->statusTable['uri']", 'error');
64+
drush_print("Is your *AMP stack running?", 2);
65+
drush_print("Is your \$base_url set correctly in $this->localSettingsPath?", 2);
66+
}
67+
else {
68+
drush_log("Received response from site:", 'success');
69+
drush_print($this->statusTable['uri'], 2);
70+
}
71+
drush_print();
72+
}
73+
74+
/**
75+
* Checks that SSL cert is valid for $base_url.
76+
*/
77+
protected function checkHttps() {
78+
if (strstr($this->statusTable['uri'], 'https')) {
79+
if (!drush_shell_exec('curl -cacert %s', $this->statusTable['uri'])) {
80+
drush_log('The SSL certificate for your local site appears to be invalid:', 'error');
81+
drush_print($this->statusTable['uri'], 2);
82+
drush_print();
83+
}
84+
}
85+
}
86+
87+
/**
88+
* Checks that drush is able to bootstrap and connect to database.
89+
*/
90+
protected function checkDbConnection() {
91+
if (empty($this->statusTable['bootstrap']) || $this->statusTable['bootstrap'] != 'Successful') {
92+
drush_log('Could not bootstrap Drupal!', 'error');
93+
drush_print("Is your *AMP stack running?", 2);
94+
drush_print('Are your database credentials correct?', 2);
95+
drush_blt_print_status_rows($this->statusTable, array(
96+
'db-driver',
97+
'db-hostname',
98+
'db-username',
99+
'db-password',
100+
'db-name',
101+
'db-port',
102+
));
103+
104+
drush_print('Is the active PHP binary the same one that is associated with your database service?');
105+
drush_blt_print_status_rows($this->statusTable, array(
106+
'php-os',
107+
'php-bin',
108+
'php-conf',
109+
));
110+
111+
drush_print('Are you using the correct site and settings.php file?');
112+
drush_blt_print_status_rows($this->statusTable, array(
113+
'site',
114+
'drupal-settings-file',
115+
));
116+
}
117+
else {
118+
drush_log('Bootstrapped Drupal and connected to database.', 'success');
119+
}
120+
drush_print();
121+
}
122+
123+
/**
124+
* Checks if database updates are pending.
125+
*/
126+
protected function checkDatabaseUpdates() {
127+
drush_include_engine('drupal', 'update');
128+
$pending = update_main();
129+
130+
if ($pending) {
131+
drush_log("There are pending database updates", 'error');
132+
drush_print("Run `drush updb` to execute the updates.", 2);
133+
}
134+
else {
135+
drush_log("There are no pending database updates.", 'success');
136+
}
137+
drush_print();
138+
}
139+
140+
/**
141+
* Checks that nvm exists.
142+
*
143+
* Note that this does not check if `nvm use` has been invoked for the correct
144+
* node version.
145+
*/
146+
protected function checkNvmExists() {
147+
$home = getenv("HOME");
148+
if (!file_exists("$home/.nvm")) {
149+
drush_log('NVM does not exist. Install using the following commands:', 'error');
150+
drush_print('curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash', 2);
151+
drush_print('source ~/.bashrc', 2);
152+
drush_print('nvm install 0.12.7', 2);
153+
drush_print('nvm use 0.12.7', 2);
154+
drush_print();
155+
}
156+
else {
157+
drush_log("NVM exists.", 'success');
158+
}
159+
}
160+
161+
/**
162+
* Checks that caching is configured for local development.
163+
*/
164+
protected function checkCachingConfig() {
165+
if (drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
166+
global $conf;
167+
168+
if ($conf['cache']) {
169+
drush_log('Drupal cache is enabled. It is suggested that you disable this for local development.', 'warning');
170+
}
171+
else {
172+
drush_log('Drupal cache is disabled.', 'success');
173+
}
174+
if ($conf['preprocess_css']) {
175+
drush_log('CSS preprocessing enabled. It is suggested that you disable this for local development.', 'warning');
176+
}
177+
else {
178+
drush_log('CSS preprocessing is disabled.', 'success');
179+
}
180+
if ($conf['preprocess_js']) {
181+
drush_log('JS preprocessing is enabled. It is suggested that you disable this for local development.', 'warning');
182+
}
183+
else {
184+
drush_log('JS preprocessing is disabled.', 'success');
185+
}
186+
}
187+
}
188+
189+
protected function checkContribExists() {
190+
if (!file_exists($this->statusTable['root'] . '/sites/all/modules/contrib')) {
191+
drush_log("Contributed module dependencies are missing.", 'error');
192+
drush_print("Run `./task.sh setup:build:all to build all contributed dependencies.", 2);
193+
drush_print();
194+
}
195+
else {
196+
drush_log("Contributed module dependencies are present.");
197+
}
198+
}
199+
}

0 commit comments

Comments
 (0)